From 6821b67124604da690c5e9276d5370d679c63ac8 Mon Sep 17 00:00:00 2001 From: "Mark A. Hershberger" Date: Wed, 25 Mar 2009 19:39:21 -0400 Subject: Imported Upstream version 5.3.0RC1 --- ext/ereg/php_regex.h | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 ext/ereg/php_regex.h (limited to 'ext/ereg/php_regex.h') diff --git a/ext/ereg/php_regex.h b/ext/ereg/php_regex.h new file mode 100644 index 000000000..810ecafbf --- /dev/null +++ b/ext/ereg/php_regex.h @@ -0,0 +1,65 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2009 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.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: | + +----------------------------------------------------------------------+ +*/ + +/* $Id: php_regex.h,v 1.20.2.4 2008/12/31 11:15:36 sebastian Exp $ */ + +#ifndef PHP_REGEX_H +#define PHP_REGEX_H + +/* + * REGEX means: + * 0.. system regex + * 1.. bundled regex + */ + +#if (REGEX == 1) +/* Define aliases */ +#define regexec php_regexec +#define regerror php_regerror +#define regfree php_regfree +#define regcomp php_regcomp + +#include "ext/ereg/regex/regex.h" + +#undef _PCREPOSIX_H +#define _PCREPOSIX_H 1 + +#ifndef _REGEX_H +#define _REGEX_H 1 /* this should stop Apache from loading the system version of regex.h */ +#endif +#ifndef _REGEX_H_ +#define _REGEX_H_ 1 +#endif +#ifndef _RX_H +#define _RX_H 1 /* Try defining these for Linux to */ +#endif +#ifndef __REGEXP_LIBRARY_H__ +#define __REGEXP_LIBRARY_H__ 1 /* avoid Apache including regex.h */ +#endif +#ifndef _H_REGEX +#define _H_REGEX 1 /* This one is for AIX */ +#endif + +#elif REGEX == 0 +#include +#ifndef _REGEX_H_ +#define _REGEX_H_ 1 +#endif +#endif + +#endif /* PHP_REGEX_H */ -- cgit v1.2.3 From 0fab6db7cac8d2be99579dd049f812a8ff98e74f Mon Sep 17 00:00:00 2001 From: Ondřej Surý Date: Thu, 7 Jan 2010 13:31:53 +0100 Subject: Imported Upstream version 5.3.1 --- .gdbinit | 19 + .project | 11 - CODING_STANDARDS | 6 +- INSTALL | 21 +- Makefile.global | 7 +- NEWS | 248 + README.CVS-RULES | 146 - README.RELEASE_PROCESS | 8 +- README.SELF-CONTAINED-EXTENSIONS | 2 +- README.STREAMS | 2 +- README.SUBMITTING_PATCH | 40 +- README.SVN-RULES | 146 + README.WIN32-BUILD-SYSTEM | 2 +- README.input_filter | 2 +- TSRM/TSRM.dsp | 372 +- TSRM/build.mk | 2 +- TSRM/config.w32 | 2 +- TSRM/configure.in | 2 +- TSRM/tsrm_nw.c | 2 +- TSRM/tsrm_virtual_cwd.c | 167 +- TSRM/tsrm_virtual_cwd.h | 11 +- TSRM/tsrm_win32.c | 248 +- TSRM/tsrm_win32.h | 5 +- UPGRADING | 2 +- Zend/ChangeLog | 4 +- Zend/RFCs/002.txt | 2 +- Zend/RFCs/003.txt | 2 +- Zend/Zend.m4 | 14 +- Zend/acconfig.h | 2 +- Zend/acinclude.m4 | 2 +- Zend/bench.php | 1 + Zend/build.mk | 2 +- Zend/configure.in | 2 +- Zend/header | 2 +- Zend/tests/019.phpt | 23 +- Zend/tests/024.phpt | 8 +- Zend/tests/bug30162.phpt | 4 +- Zend/tests/bug39542/bug39542.php | 14 +- Zend/tests/bug40236.inc | 18 +- Zend/tests/bug46106.phpt | 44 +- Zend/tests/bug47109.phpt | 22 +- Zend/tests/bug48693.phpt | 28 + Zend/tests/bug48770.phpt | 53 + Zend/tests/bug48770_2.phpt | 54 + Zend/tests/bug48770_3.phpt | 51 + Zend/tests/bug48899.phpt | 24 + Zend/tests/bug48912.phpt | 16 + Zend/tests/bug49269.phpt | 26 + Zend/tests/bug49908.phpt | 28 + Zend/tests/call_user_func_001.phpt | 35 + Zend/tests/call_user_func_002.phpt | 29 + Zend/tests/call_user_func_003.phpt | 31 + Zend/tests/closure_034.phpt | 25 + Zend/tests/constants_002.phpt | 6 - Zend/tests/each_003.phpt | 13 - Zend/tests/function_exists_error.phpt | 1 - Zend/tests/get_parent_class_001.phpt | 3 - Zend/tests/get_required_files.phpt | 16 + Zend/tests/globals_001.phpt | 2 +- Zend/tests/globals_002.phpt | 2 +- Zend/tests/globals_003.phpt | 2 +- Zend/tests/globals_004.phpt | 2 +- Zend/tests/ns_022.inc | 12 +- Zend/tests/ns_023.phpt | 2 - Zend/tests/ns_024.phpt | 2 - Zend/tests/ns_028.inc | 30 +- Zend/tests/unexpected_ref_bug.phpt | 18 + Zend/tests/unset_cv07.phpt | 2 - Zend/tests/zend_operators.phpt | 2 +- Zend/zend.c | 14 +- Zend/zend.h | 22 +- Zend/zend_API.c | 18 +- Zend/zend_API.h | 4 +- Zend/zend_alloc.c | 25 +- Zend/zend_alloc.h | 16 +- Zend/zend_builtin_functions.c | 5 +- Zend/zend_builtin_functions.h | 2 +- Zend/zend_closures.c | 81 +- Zend/zend_closures.h | 2 +- Zend/zend_compile.c | 662 +- Zend/zend_compile.h | 2 +- Zend/zend_config.nw.h | 2 +- Zend/zend_config.w32.h | 2 +- Zend/zend_constants.c | 2 +- Zend/zend_constants.h | 2 +- Zend/zend_default_classes.c | 2 +- Zend/zend_dynamic_array.c | 2 +- Zend/zend_dynamic_array.h | 2 +- Zend/zend_errors.h | 2 +- Zend/zend_exceptions.c | 2 +- Zend/zend_exceptions.h | 2 +- Zend/zend_execute.c | 2 +- Zend/zend_execute.h | 65 +- Zend/zend_execute_API.c | 15 +- Zend/zend_extensions.c | 63 +- Zend/zend_extensions.h | 2 +- Zend/zend_fast_cache.h | 2 +- Zend/zend_float.c | 2 +- Zend/zend_float.h | 2 +- Zend/zend_gc.c | 2 +- Zend/zend_gc.h | 2 +- Zend/zend_globals.h | 2 +- Zend/zend_globals_macros.h | 2 +- Zend/zend_hash.c | 2 +- Zend/zend_hash.h | 2 +- Zend/zend_highlight.c | 2 +- Zend/zend_highlight.h | 2 +- Zend/zend_indent.c | 2 +- Zend/zend_indent.h | 2 +- Zend/zend_ini.c | 17 +- Zend/zend_ini.h | 2 +- Zend/zend_ini_parser.c | 2 +- Zend/zend_ini_parser.y | 2 +- Zend/zend_ini_scanner.c | 4274 +- Zend/zend_ini_scanner.h | 2 +- Zend/zend_ini_scanner.l | 94 +- Zend/zend_ini_scanner_defs.h | 2 +- Zend/zend_interfaces.c | 2 +- Zend/zend_interfaces.h | 2 +- Zend/zend_istdiostream.h | 2 +- Zend/zend_iterators.c | 2 +- Zend/zend_iterators.h | 2 +- Zend/zend_language_parser.c | 2 +- Zend/zend_language_parser.y | 2 +- Zend/zend_language_scanner.c | 2 +- Zend/zend_language_scanner.h | 2 +- Zend/zend_language_scanner.l | 2 +- Zend/zend_list.c | 2 +- Zend/zend_list.h | 2 +- Zend/zend_llist.c | 2 +- Zend/zend_llist.h | 2 +- Zend/zend_modules.h | 2 +- Zend/zend_multibyte.c | 2 +- Zend/zend_multibyte.h | 2 +- Zend/zend_multiply.h | 2 +- Zend/zend_object_handlers.c | 2 +- Zend/zend_object_handlers.h | 2 +- Zend/zend_objects.c | 4 +- Zend/zend_objects.h | 2 +- Zend/zend_objects_API.c | 2 +- Zend/zend_objects_API.h | 2 +- Zend/zend_opcode.c | 2 +- Zend/zend_operators.c | 2 +- Zend/zend_operators.h | 2 +- Zend/zend_ptr_stack.c | 2 +- Zend/zend_ptr_stack.h | 2 +- Zend/zend_qsort.c | 2 +- Zend/zend_qsort.h | 2 +- Zend/zend_sprintf.c | 2 +- Zend/zend_stack.c | 2 +- Zend/zend_stack.h | 2 +- Zend/zend_static_allocator.c | 2 +- Zend/zend_static_allocator.h | 2 +- Zend/zend_stream.c | 2 +- Zend/zend_stream.h | 2 +- Zend/zend_strtod.c | 2 +- Zend/zend_strtod.h | 2 +- Zend/zend_ts_hash.c | 2 +- Zend/zend_ts_hash.h | 2 +- Zend/zend_types.h | 2 +- Zend/zend_variables.c | 2 +- Zend/zend_variables.h | 2 +- Zend/zend_vm.h | 2 +- Zend/zend_vm_def.h | 63 +- Zend/zend_vm_execute.h | 173 +- Zend/zend_vm_execute.skl | 10 +- Zend/zend_vm_gen.php | 2 +- acconfig.h | 2 +- acinclude.m4 | 4 +- aclocal.m4 | 4 +- build/build.mk | 30 +- build/build2.mk | 2 +- build/buildcheck.sh | 10 +- build/config-stubs | 2 +- build/genif.sh | 2 +- build/mkdep.awk | 2 +- buildconf | 33 +- configure | 6338 +- configure.in | 44 +- cvsclean | 3 - cvsclean.bat | 2 - ext/bcmath/bcmath.c | 2 +- ext/bcmath/config.m4 | 2 +- ext/bcmath/config.w32 | 2 +- ext/bcmath/php_bcmath.h | 16 +- ext/bcmath/tests/bcdiv_error1.phpt | 14 + ext/bcmath/tests/bcdiv_error2.phpt | 13 + ext/bcmath/tests/bcmod_error1.phpt | 13 + ext/bcmath/tests/bcpowmod_error1.phpt | 13 + ext/bcmath/tests/bcpowmod_error2.phpt | 13 + ext/bcmath/tests/bcpowmod_error3.phpt | 13 + ext/bcmath/tests/bcsqrt_error1.phpt | 13 + ext/bz2/bz2.c | 2 +- ext/bz2/bz2_filter.c | 2 +- ext/bz2/config.m4 | 2 +- ext/bz2/config.w32 | 2 +- ext/bz2/php_bz2.h | 2 +- ext/bz2/tests/bz2_filter_compress.phpt | 2 +- ext/bz2/tests/bz2_filter_decompress.phpt | 2 +- ext/bz2/tests/with_files.phpt | 2 +- ext/bz2/tests/with_strings.phpt | 2 +- ext/calendar/calendar.c | 2 +- ext/calendar/config.m4 | 2 +- ext/calendar/config.w32 | 2 +- ext/com_dotnet/com_com.c | 2 +- ext/com_dotnet/com_dotnet.c | 2 +- ext/com_dotnet/com_extension.c | 2 +- ext/com_dotnet/com_handlers.c | 2 +- ext/com_dotnet/com_iterator.c | 2 +- ext/com_dotnet/com_misc.c | 2 +- ext/com_dotnet/com_olechar.c | 2 +- ext/com_dotnet/com_persist.c | 2 +- ext/com_dotnet/com_saproxy.c | 2 +- ext/com_dotnet/com_typeinfo.c | 4 +- ext/com_dotnet/com_variant.c | 2 +- ext/com_dotnet/com_wrapper.c | 2 +- ext/com_dotnet/config.w32 | 2 +- ext/com_dotnet/php_com_dotnet.h | 2 +- ext/com_dotnet/php_com_dotnet_internal.h | 2 +- ext/com_dotnet/tests/27974.phpt | 2 +- ext/com_dotnet/tests/bug39606.phpt | 2 +- ext/com_dotnet/tests/bug45280.phpt | 19 + ext/com_dotnet/tests/variants.phpt | 2 +- ext/ctype/config.m4 | 2 +- ext/ctype/config.w32 | 2 +- ext/curl/config.m4 | 4 +- ext/curl/config.w32 | 2 +- ext/curl/interface.c | 116 +- ext/curl/multi.c | 2 +- ext/curl/php_curl.h | 5 +- ext/curl/streams.c | 18 +- ext/curl/tests/bug46739.phpt | 3 - ext/curl/tests/bug48207.phpt | 47 + ext/curl/tests/curl_CURLOPT_READDATA.phpt | 44 + ext/curl/tests/curl_close_basic.phpt | 19 + ext/curl/tests/curl_copy_handle_basic.phpt | 30 + ext/curl/tests/curl_copy_handle_basic_001.phpt | 42 + ext/curl/tests/curl_copy_handle_basic_002.phpt | 49 + ext/curl/tests/curl_copy_handle_basic_004.phpt | 44 + ext/curl/tests/curl_copy_handle_basic_005.phpt | 52 + ext/curl/tests/curl_copy_handle_basic_006.phpt | 37 + ext/curl/tests/curl_copy_handle_basic_007.phpt | 45 + ext/curl/tests/curl_copy_handle_variation1.phpt | 32 + ext/curl/tests/curl_copy_handle_variation2.phpt | 44 + ext/curl/tests/curl_error_basic.phpt | 33 + ext/curl/tests/curl_multi_close_basic.phpt | 19 + ext/curl/tests/curl_multi_getcontent_basic3.phpt | 59 + ext/curl/tests/curl_multi_getcontent_error1.phpt | 51 + ext/curl/tests/curl_multi_getcontent_error2.phpt | 51 + ext/curl/tests/curl_multi_getcontent_error3.phpt | 53 + ext/curl/tests/curl_multi_getcontent_error4.phpt | 66 + ext/curl/tests/curl_multi_init_basic.phpt | 31 + ext/curl/tests/curl_multi_select_basic1.phpt | 27 + ...setopt_CURLOPT_FOLLOWLOCATION_open_basedir.phpt | 22 + .../tests/curl_setopt_CURLOPT_READFUNCTION.phpt | 54 + ext/curl/tests/curl_setopt_array_basic.phpt | 55 + ext/curl/tests/curl_setopt_basic001.phpt | 35 + ext/curl/tests/curl_setopt_basic002.phpt | 50 + ext/curl/tests/curl_setopt_basic003.phpt | 43 + ext/curl/tests/curl_setopt_basic004.phpt | 44 + ext/curl/tests/curl_setopt_error.phpt | 44 + ext/curl/tests/curl_testdata1.txt | 1 + ext/curl/tests/curl_testdata2.txt | 1 + ext/curl/tests/curl_version_error.phpt | 32 + ext/curl/tests/curl_version_variation1.phpt | 162 + ext/curl/tests/curl_write_callback.phpt | 36 + ext/curl/tests/curl_write_file.phpt | 38 + ext/curl/tests/curl_write_return.phpt | 33 + ext/curl/tests/curl_write_stdout.phpt | 30 + ext/curl/tests/curl_writeheader_callback.phpt | 30 + ext/curl/tests/responder/get.php | 3 + ext/date/config.w32 | 2 +- ext/date/config0.m4 | 2 +- ext/date/lib/astro.c | 2 +- ext/date/lib/dow.c | 2 +- ext/date/lib/interval.c | 2 +- ext/date/lib/parse_date.c | 20 +- ext/date/lib/parse_date.c.orig | 20 +- ext/date/lib/parse_date.re | 18 +- ext/date/lib/parse_iso_intervals.c | 2 +- ext/date/lib/parse_iso_intervals.re | 2 +- ext/date/lib/parse_tz.c | 2 +- ext/date/lib/timelib.c | 2 +- ext/date/lib/timelib.h | 2 +- ext/date/lib/timelib.m4 | 2 +- ext/date/lib/timelib_config.h.win32 | 2 +- ext/date/lib/timelib_structs.h | 2 +- ext/date/lib/timezonedb.h | 2154 +- ext/date/lib/tm2unixtime.c | 2 +- ext/date/lib/unixtime2tm.c | 2 +- ext/date/php_date.c | 27 +- ext/date/php_date.h | 2 +- ext/date/tests/DatePeriod_wrong_constructor.phpt | 17 + ext/date/tests/bug27719.phpt | 2 +- ext/date/tests/bug45554.phpt | 20 + ext/date/tests/bug48058.phpt | 6 +- .../tests/cal_days_in_month_invalid_calendar.phpt | 16 + ext/date/tests/cal_days_in_month_invalid_date.phpt | 16 + ext/date/tests/date_sunrise_variation5.phpt | 8 +- ext/date/tests/date_sunset_variation5.phpt | 6 +- ext/date/tests/date_timestamp_get.phpt | 20 + ext/date/tests/strtotime_basic.phpt | 12 +- ...imezone_identifiers_list_wrong_constructor.phpt | 15 + ext/date/tests/timezone_location_get.phpt | 24 + ext/dba/config.m4 | 2 +- ext/dba/config.w32 | 2 +- ext/dba/dba.c | 2 +- ext/dba/dba_cdb.c | 2 +- ext/dba/dba_db1.c | 2 +- ext/dba/dba_db2.c | 2 +- ext/dba/dba_db3.c | 2 +- ext/dba/dba_db4.c | 10 +- ext/dba/dba_dbm.c | 2 +- ext/dba/dba_flatfile.c | 2 +- ext/dba/dba_gdbm.c | 2 +- ext/dba/dba_inifile.c | 2 +- ext/dba/dba_ndbm.c | 2 +- ext/dba/dba_qdbm.c | 2 +- ext/dba/install_cdb.sh | 2 +- ext/dba/libcdb/cdb.c | 4 +- ext/dba/libcdb/cdb.h | 2 +- ext/dba/libcdb/cdb_make.c | 4 +- ext/dba/libcdb/cdb_make.h | 2 +- ext/dba/libcdb/uint32.c | 2 +- ext/dba/libcdb/uint32.h | 2 +- ext/dba/libflatfile/flatfile.c | 4 +- ext/dba/libflatfile/flatfile.h | 2 +- ext/dba/libinifile/inifile.c | 4 +- ext/dba/libinifile/inifile.h | 2 +- ext/dba/php_dba.h | 2 +- ext/dba/tests/bug36436.phpt | 4 +- ext/dba/tests/bug48240.phpt | 4 +- ext/dba/tests/bug49125.phpt | 27 + ext/dba/tests/dba001.phpt | 6 +- ext/dba/tests/dba002.phpt | 4 +- ext/dba/tests/dba003.phpt | 4 +- ext/dba/tests/dba004.phpt | 4 +- ext/dba/tests/dba005.phpt | 4 +- ext/dba/tests/dba006.phpt | 6 +- ext/dba/tests/dba007.phpt | 4 +- ext/dba/tests/dba008.phpt | 4 +- ext/dba/tests/dba009.phpt | 4 +- ext/dba/tests/dba_cdb.phpt | 6 +- ext/dba/tests/dba_cdb_make.phpt | 4 +- ext/dba/tests/dba_cdb_read.phpt | 4 +- ext/dba/tests/dba_db1.phpt | 6 +- ext/dba/tests/dba_db2.phpt | 6 +- ext/dba/tests/dba_db3.phpt | 6 +- ext/dba/tests/dba_db4.phpt | 6 +- ext/dba/tests/dba_dbm.phpt | 6 +- ext/dba/tests/dba_flatfile.phpt | 6 +- ext/dba/tests/dba_gdbm.phpt | 6 +- ext/dba/tests/dba_inifile.phpt | 6 +- ext/dba/tests/dba_ndbm.phpt | 6 +- ext/dba/tests/dba_qdbm.phpt | 6 +- ext/dba/tests/test.inc | 4 +- ext/dom/attr.c | 2 +- ext/dom/cdatasection.c | 2 +- ext/dom/characterdata.c | 2 +- ext/dom/comment.c | 2 +- ext/dom/config.m4 | 2 +- ext/dom/config.w32 | 2 +- ext/dom/document.c | 2 +- ext/dom/documentfragment.c | 2 +- ext/dom/documenttype.c | 6 +- ext/dom/dom_ce.h | 2 +- ext/dom/dom_fe.h | 2 +- ext/dom/dom_iterators.c | 2 +- ext/dom/dom_properties.h | 2 +- ext/dom/domconfiguration.c | 2 +- ext/dom/domerror.c | 2 +- ext/dom/domerrorhandler.c | 2 +- ext/dom/domexception.c | 2 +- ext/dom/domimplementation.c | 2 +- ext/dom/domimplementationlist.c | 2 +- ext/dom/domimplementationsource.c | 2 +- ext/dom/domlocator.c | 2 +- ext/dom/domstringlist.c | 2 +- ext/dom/element.c | 2 +- ext/dom/entity.c | 2 +- ext/dom/entityreference.c | 2 +- ext/dom/namednodemap.c | 2 +- ext/dom/namelist.c | 2 +- ext/dom/node.c | 2 +- ext/dom/nodelist.c | 2 +- ext/dom/notation.c | 2 +- ext/dom/php_dom.c | 2 +- ext/dom/php_dom.h | 2 +- ext/dom/processinginstruction.c | 2 +- ext/dom/string_extend.c | 2 +- ext/dom/tests/DOMAttr_value_basic_001.phpt | 11 + ext/dom/tests/DOMCharacterData_data_basic_002.phpt | 28 + .../tests/DOMCharacterData_length_error_001.phpt | 12 + .../DOMCharacterData_substringData_basic_001.phpt | 21 + ext/dom/tests/DOMDocument_config_basic.phpt | 26 + .../DOMDocument_createEntityReference_basic.phpt | 19 + ext/dom/tests/DOMDocument_documentURI_basic.phpt | 39 + ext/dom/tests/DOMDocument_encoding_basic.phpt | 52 + .../DOMDocument_implementationRead_basic.phpt | 21 + .../DOMDocument_preserveWhiteSpace_basic.phpt | 23 + .../DOMDocument_preserveWhiteSpace_variations.phpt | 40 + .../tests/DOMDocument_resolveExternals_basic.phpt | 49 + ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt | 29 + ext/dom/tests/DOMDocument_saveHTMLFile_error1.phpt | 24 + ext/dom/tests/DOMDocument_saveHTMLFile_error2.phpt | 15 + .../DOMDocument_saveHTMLFile_formatOutput.phpt | 33 + .../DOMDocument_saveHTMLFile_invalid_filename.phpt | 25 + ext/dom/tests/DOMDocument_saveHTML_basic.phpt | 24 + ext/dom/tests/DOMDocument_saveHTML_error1.phpt | 24 + ext/dom/tests/DOMDocument_saveHTML_error2.phpt | 15 + .../DOMDocument_schemaValidateSource_basic.phpt | 22 + .../DOMDocument_schemaValidateSource_error1.phpt | 29 + .../DOMDocument_schemaValidateSource_error2.phpt | 23 + .../DOMDocument_schemaValidateSource_error3.phpt | 21 + .../DOMDocument_schemaValidateSource_error4.phpt | 21 + .../tests/DOMDocument_schemaValidate_basic.phpt | 20 + .../tests/DOMDocument_schemaValidate_error1.phpt | 29 + .../tests/DOMDocument_schemaValidate_error2.phpt | 21 + .../tests/DOMDocument_schemaValidate_error3.phpt | 21 + .../tests/DOMDocument_schemaValidate_error4.phpt | 21 + .../tests/DOMDocument_schemaValidate_error5.phpt | 25 + ext/dom/tests/DOMDocument_standalone_basic.phpt | 48 + .../DOMDocument_strictErrorChecking_basic.phpt | 22 + .../DOMDocument_strictErrorChecking_variation.phpt | 59 + ext/dom/tests/DOMDocument_validate_basic.phpt | 31 + ext/dom/tests/DOMDocument_validate_error1.phpt | 16 + ext/dom/tests/DOMDocument_validate_error2.phpt | 15 + .../tests/DOMDocument_validate_external_dtd.phpt | 19 + .../tests/DOMDocument_validate_on_parse_basic.phpt | 38 + .../DOMDocument_validate_on_parse_variation.phpt | 49 + ext/dom/tests/book-non-conforming-schema.xsd | 17 + ext/dom/tests/book-not-a-schema.xsd | 1 + ext/dom/tests/book.xsd | 17 + .../tests/domdocument_createcomment_error_001.phpt | 11 + .../domdocument_createentityreference_001.phpt | 13 + .../domdocument_createentityreference_002.phpt | 12 + ext/dom/text.c | 2 +- ext/dom/typeinfo.c | 2 +- ext/dom/userdatahandler.c | 2 +- ext/dom/xml_common.h | 2 +- ext/dom/xpath.c | 2 +- ext/enchant/config.m4 | 8 +- ext/enchant/config.w32 | 3 +- ext/enchant/docs/examples/example1.php | 2 +- ext/enchant/enchant.c | 126 +- ext/enchant/php_enchant.h | 9 +- ext/ereg/config.w32 | 2 +- ext/ereg/config0.m4 | 2 +- ext/ereg/ereg.c | 2 +- ext/ereg/php_ereg.h | 2 +- ext/ereg/php_regex.h | 2 +- ext/ereg/regex/regex.dsw | 58 +- ext/exif/config.m4 | 2 +- ext/exif/config.w32 | 2 +- ext/exif/example.php | 2 +- ext/exif/exif.c | 26 +- ext/exif/php_exif.h | 2 +- ext/exif/test.txt | 2 +- ext/ext_skel_win32.php | 2 +- ext/fileinfo/config.m4 | 2 +- ext/fileinfo/config.w32 | 2 +- ext/fileinfo/fileinfo.c | 4 +- ext/fileinfo/libmagic/patchlevel.h | 5 +- ext/fileinfo/libmagic/readcdf.c | 5 +- ext/fileinfo/php_fileinfo.h | 2 +- ext/filter/callback_filter.c | 2 +- ext/filter/config.m4 | 2 +- ext/filter/config.w32 | 2 +- ext/filter/docs/filter.txt | 2 +- ext/filter/filter.c | 17 +- ext/filter/filter_private.h | 2 +- ext/filter/logical_filters.c | 15 +- ext/filter/php_filter.h | 2 +- ext/filter/sanitizing_filters.c | 4 +- ext/filter/tests/016.phpt | 14 +- ext/filter/tests/bug42718.phpt | 3 +- ext/filter/tests/bug48762.phpt | 12 + ext/filter/tests/bug49274.phpt | 10 + ext/ftp/config.m4 | 2 +- ext/ftp/config.w32 | 2 +- ext/ftp/ftp.c | 4 +- ext/ftp/ftp.h | 2 +- ext/ftp/php_ftp.c | 2 +- ext/ftp/php_ftp.h | 2 +- ext/ftp/tests/ftp_alloc_basic1.phpt | 21 + ext/ftp/tests/ftp_alloc_basic2.phpt | 23 + ext/ftp/tests/ftp_chmod_basic.phpt | 21 + ext/ftp/tests/ftp_exec_basic.phpt | 21 + ext/ftp/tests/ftp_fget_basic1.phpt | 32 + ext/ftp/tests/ftp_fget_basic2.phpt | 32 + ext/ftp/tests/ftp_fget_basic3.phpt | 32 + ext/ftp/tests/ftp_nb_fget_basic1.phpt | 32 + ext/ftp/tests/ftp_nb_fget_basic2.phpt | 32 + ext/ftp/tests/ftp_nb_fget_basic3.phpt | 32 + ext/ftp/tests/ftp_rawlist_basic2.phpt | 21 + ext/ftp/tests/ftp_rmdir_basic.phpt | 21 + ext/ftp/tests/server.inc | 542 +- ext/gd/config.m4 | 2 +- ext/gd/config.w32 | 2 +- ext/gd/gd.c | 2 +- ext/gd/gd_ctx.c | 2 +- ext/gd/gdcache.c | 2 +- ext/gd/gdcache.h | 2 +- ext/gd/libgd/gd.c | 84 +- ext/gd/libgd/gd_compat.c | 2 +- ext/gd/libgd/gd_compat.h | 2 +- ext/gd/libgd/gd_gd.c | 3 + ext/gd/libgd/gdft.c | 30 +- ext/gd/libgd/xbm.c | 2 +- ext/gd/php_gd.h | 2 +- ext/gd/tests/bug42434.phpt | 26 + ext/gd/tests/bug43073.phpt | 48 + ext/gd/tests/bug48555.phpt | 9 +- ext/gd/tests/bug48732.phpt | 22 + ext/gd/tests/bug48801.phpt | 22 + ext/gd/tests/crafted.gd2 | Bin 0 -> 1039 bytes ext/gd/tests/crafted_gd2.phpt | 16 + ext/gd/tests/gd_info_error.phpt | 74 +- ext/gd/tests/gd_info_variation1.phpt | 98 +- ext/gd/tests/gif.phpt | 2 +- ext/gd/tests/image_type_to_mime_type_error.phpt | 68 +- .../tests/image_type_to_mime_type_variation1.phpt | 302 +- .../tests/image_type_to_mime_type_variation2.phpt | 160 +- ext/gd/tests/imageantialias_error1.phpt | 18 + ext/gd/tests/imageantialias_error2.phpt | 23 + ext/gd/tests/imagearc_basic.phpt | 28 + ext/gd/tests/imagearc_error1.phpt | 29 + ext/gd/tests/imagearc_variation1.phpt | 28 + ext/gd/tests/imagearc_variation2.phpt | 28 + ext/gd/tests/imagechar_basic.phpt | 25 + ext/gd/tests/imagechar_error1.phpt | 17 + ext/gd/tests/imagechar_error2.phpt | 17 + ext/gd/tests/imagechar_error3.phpt | 17 + ext/gd/tests/imagechar_error4.phpt | 17 + ext/gd/tests/imagechar_error5.phpt | 17 + ext/gd/tests/imagechar_error6.phpt | 17 + ext/gd/tests/imagechar_error7.phpt | 17 + ext/gd/tests/imagecharup_basic.phpt | 25 + ext/gd/tests/imagecharup_error1.phpt | 17 + ext/gd/tests/imagecharup_error2.phpt | 17 + ext/gd/tests/imagecharup_error3.phpt | 17 + ext/gd/tests/imagecharup_error4.phpt | 17 + ext/gd/tests/imagecharup_error5.phpt | 17 + ext/gd/tests/imagecharup_error6.phpt | 17 + ext/gd/tests/imagecharup_error7.phpt | 17 + ext/gd/tests/imagecolorallocatealpha_basic.phpt | 30 + ext/gd/tests/imagecolorallocatealpha_error1.phpt | 25 + ext/gd/tests/imagecolorallocatealpha_error2.phpt | 22 + ext/gd/tests/imagecolorallocatealpha_error3.phpt | 22 + ext/gd/tests/imagecolorallocatealpha_error4.phpt | 22 + ext/gd/tests/imagecolorallocatealpha_error5.phpt | 22 + ext/gd/tests/imagecolordeallocate_basic.phpt | 21 + ext/gd/tests/imagecolordeallocate_error1.phpt | 22 + ext/gd/tests/imagecolordeallocate_error2.phpt | 19 + ext/gd/tests/imagecolordeallocate_error3.phpt | 22 + ext/gd/tests/imagecolordeallocate_error4.phpt | 22 + ext/gd/tests/imagecolormatch_basic.phpt | 19 + ext/gd/tests/imagecolormatch_error1.phpt | 18 + ext/gd/tests/imagecolormatch_error2.phpt | 20 + ext/gd/tests/imagecolormatch_error3.phpt | 20 + ext/gd/tests/imagecolormatch_error4.phpt | 20 + ext/gd/tests/imagecolorset_basic.phpt | 35 + ext/gd/tests/imageconvolution_basic.phpt | 33 + ext/gd/tests/imageconvolution_error1.phpt | 27 + ext/gd/tests/imageconvolution_error2.phpt | 26 + ext/gd/tests/imageconvolution_error3.phpt | 27 + ext/gd/tests/imagecopymerge_basic.phpt | 30 + ext/gd/tests/imagecopymerge_error.phpt | 17 + ext/gd/tests/imagecreatetruecolor_basic.phpt | 22 + ext/gd/tests/imagecreatetruecolor_error1.phpt | 18 + ext/gd/tests/imagecreatetruecolor_error2.phpt | 24 + ext/gd/tests/imagecreatetruecolor_error3.phpt | 21 + ext/gd/tests/imageellipse_basic.phpt | 27 + ext/gd/tests/imageellipse_error1.phpt | 21 + ext/gd/tests/imageellipse_error2.phpt | 21 + ext/gd/tests/imageellipse_error3.phpt | 21 + ext/gd/tests/imageellipse_error4.phpt | 21 + ext/gd/tests/imageellipse_error5.phpt | 21 + ext/gd/tests/imageellipse_error6.phpt | 21 + ext/gd/tests/imageellipse_error7.phpt | 20 + ext/gd/tests/imageellipse_error8.phpt | 21 + ext/gd/tests/imagefilledarc_basic.phpt | 28 + ext/gd/tests/imagefilledarc_error1.phpt | 29 + ext/gd/tests/imagefilledarc_variation1.phpt | 28 + ext/gd/tests/imagefilledarc_variation2.phpt | 28 + ext/gd/tests/imagefilltoborder_basic.phpt | 33 + ext/gd/tests/imagefilltoborder_error1.phpt | 26 + ext/gd/tests/imagefilltoborder_error2.phpt | 26 + ext/gd/tests/imagefilltoborder_error3.phpt | 26 + ext/gd/tests/imagefilltoborder_error4.phpt | 26 + ext/gd/tests/imagefilltoborder_error5.phpt | 26 + ext/gd/tests/imagefilltoborder_error6.phpt | 29 + ext/gd/tests/imagefilltoborder_error7.phpt | 26 + ext/gd/tests/imagefilter_error1.phpt | 18 + ext/gd/tests/imagefilter_error10.phpt | 18 + ext/gd/tests/imagefilter_error11.phpt | 18 + ext/gd/tests/imagefilter_error12.phpt | 18 + ext/gd/tests/imagefilter_error13.phpt | 17 + ext/gd/tests/imagefilter_error14.phpt | 18 + ext/gd/tests/imagefilter_error15.phpt | 18 + ext/gd/tests/imagefilter_error16.phpt | 18 + ext/gd/tests/imagefilter_error17.phpt | 18 + ext/gd/tests/imagefilter_error18.phpt | 18 + ext/gd/tests/imagefilter_error19.phpt | 18 + ext/gd/tests/imagefilter_error2.phpt | 18 + ext/gd/tests/imagefilter_error20.phpt | 18 + ext/gd/tests/imagefilter_error3.phpt | 18 + ext/gd/tests/imagefilter_error4.phpt | 18 + ext/gd/tests/imagefilter_error5.phpt | 18 + ext/gd/tests/imagefilter_error6.phpt | 18 + ext/gd/tests/imagefilter_error7.phpt | 18 + ext/gd/tests/imagefilter_error8.phpt | 18 + ext/gd/tests/imagefilter_error9.phpt | 18 + ext/gd/tests/imagefontheight_basic.phpt | 19 + ext/gd/tests/imagefontheight_error1.phpt | 15 + ext/gd/tests/imagefontwidth_basic.phpt | 21 + ext/gd/tests/imagefontwidth_error1.phpt | 15 + ext/gd/tests/imagegammacorrect_basic.phpt | 32 + ext/gd/tests/imagegammacorrect_error1.phpt | 17 + ext/gd/tests/imagegammacorrect_error2.phpt | 17 + ext/gd/tests/imagegammacorrect_error3.phpt | 17 + ext/gd/tests/imagegammacorrect_error4.phpt | 17 + ext/gd/tests/imagegammacorrect_variation1.phpt | 32 + ext/gd/tests/imageinterlace_basic.phpt | 17 + ext/gd/tests/imageinterlace_error1.phpt | 20 + ext/gd/tests/imageinterlace_error2.phpt | 17 + ext/gd/tests/imageinterlace_variation1.phpt | 20 + ext/gd/tests/imageinterlace_variation2.phpt | 24 + ext/gd/tests/imageistruecolor_basic.phpt | 17 + ext/gd/tests/imageistruecolor_error1.phpt | 24 + ext/gd/tests/imagelayereffect_basic.phpt | 27 + ext/gd/tests/imagelayereffect_error1.phpt | 16 + ext/gd/tests/imagelayereffect_error2.phpt | 18 + ext/gd/tests/imagelayereffect_error3.phpt | 17 + ext/gd/tests/imagerectangle_basic.phpt | 27 + ext/gd/tests/imagerectangle_error1.phpt | 19 + ext/gd/tests/imagerectangle_error2.phpt | 19 + ext/gd/tests/imagerectangle_error3.phpt | 19 + ext/gd/tests/imagerectangle_error4.phpt | 19 + ext/gd/tests/imagerectangle_error5.phpt | 19 + ext/gd/tests/imagerectangle_error6.phpt | 19 + ext/gd/tests/imagerectangle_error7.phpt | 19 + ext/gd/tests/imagerectangle_error8.phpt | 19 + ext/gd/tests/imagesetbrush_basic.phpt | 37 + ext/gd/tests/imagesetthickness_basic.phpt | 34 + ext/gd/tests/imagesetthickness_error1.phpt | 22 + ext/gd/tests/imagesetthickness_error2.phpt | 24 + ext/gd/tests/imagestring_basic.phpt | 25 + ext/gd/tests/imagestring_error1.phpt | 17 + ext/gd/tests/imagestring_error2.phpt | 17 + ext/gd/tests/imagestring_error3.phpt | 17 + ext/gd/tests/imagestring_error4.phpt | 17 + ext/gd/tests/imagestring_error5.phpt | 17 + ext/gd/tests/imagestring_error6.phpt | 17 + ext/gd/tests/imagestring_error7.phpt | 17 + ext/gd/tests/imagestringup_basic.phpt | 25 + ext/gd/tests/imagestringup_error1.phpt | 17 + ext/gd/tests/imagestringup_error2.phpt | 17 + ext/gd/tests/imagestringup_error3.phpt | 17 + ext/gd/tests/imagestringup_error4.phpt | 17 + ext/gd/tests/imagestringup_error5.phpt | 17 + ext/gd/tests/imagestringup_error6.phpt | 17 + ext/gd/tests/imagestringup_error7.phpt | 17 + ext/gd/tests/imagetruecolortopalette_basic.phpt | 31 + ext/gd/tests/imagetruecolortopalette_error1.phpt | 26 + ext/gd/tests/imagetruecolortopalette_error2.phpt | 22 + ext/gd/tests/imagetruecolortopalette_error3.phpt | 28 + ext/gd/tests/imagetruecolortopalette_error4.phpt | 21 + ext/gd/tests/jpeg2wbmp_error1.phpt | 42 + ext/gd/tests/jpeg2wbmp_error2.phpt | 31 + ext/gd/tests/jpeg2wbmp_error3.phpt | 43 + ext/gd/tests/png2wbmp_error1.phpt | 42 + ext/gd/tests/png2wbmp_error2.phpt | 31 + ext/gd/tests/png2wbmp_error3.phpt | 43 + ext/gd/tests/test8859.ttf | Bin 10576 -> 10576 bytes ext/gd/tests/truecolor.phpt | 19 - ext/gettext/config.m4 | 2 +- ext/gettext/config.w32 | 2 +- ext/gettext/gettext.c | 2 +- ext/gettext/php_gettext.h | 2 +- ext/gettext/tests/gettext_basic.phpt | 2 +- ext/gettext/tests/gettext_ngettext.phpt | 2 +- .../tests/gettext_textdomain-wrongparams.phpt | 2 +- ext/gmp/config.m4 | 2 +- ext/gmp/config.w32 | 2 +- ext/hash/bench.php | 2 +- ext/hash/config.m4 | 2 +- ext/hash/config.w32 | 2 +- ext/hash/hash.c | 5 +- ext/hash/hash_adler32.c | 10 +- ext/hash/hash_crc32.c | 2 +- ext/hash/hash_gost.c | 2 +- ext/hash/hash_haval.c | 2 +- ext/hash/hash_md.c | 2 +- ext/hash/hash_ripemd.c | 2 +- ext/hash/hash_salsa.c | 2 +- ext/hash/hash_sha.c | 2 +- ext/hash/hash_snefru.c | 2 +- ext/hash/hash_tiger.c | 2 +- ext/hash/hash_whirlpool.c | 2 +- ext/hash/php_hash.h | 2 +- ext/hash/php_hash_adler32.h | 2 +- ext/hash/php_hash_crc32.h | 2 +- ext/hash/php_hash_crc32_tables.h | 2 +- ext/hash/php_hash_gost.h | 2 +- ext/hash/php_hash_haval.h | 2 +- ext/hash/php_hash_md.h | 2 +- ext/hash/php_hash_ripemd.h | 2 +- ext/hash/php_hash_salsa.h | 2 +- ext/hash/php_hash_sha.h | 2 +- ext/hash/php_hash_snefru.h | 2 +- ext/hash/php_hash_snefru_tables.h | 2 +- ext/hash/php_hash_tiger.h | 2 +- ext/hash/php_hash_tiger_tables.h | 2 +- ext/hash/php_hash_types.h | 2 +- ext/hash/php_hash_whirlpool.h | 2 +- ext/hash/php_hash_whirlpool_tables.h | 2 +- ext/hash/tests/adler32.phpt | 14 +- ext/hash/tests/hash_copy_001.phpt | 8 +- ext/hash/tests/hash_file_basic1.phpt | 6 +- ext/hash/tests/hash_hmac_basic.phpt | 6 +- ext/hash/tests/hash_hmac_file_basic.phpt | 6 +- ext/iconv/config.m4 | 2 +- ext/iconv/config.w32 | 2 +- ext/iconv/iconv.c | 2 +- ext/iconv/php_iconv.h | 2 +- ext/iconv/tests/bug16069.phpt | 22 - ext/iconv/tests/iconv_get_encoding_basic.phpt | 76 + ...iconv_handler-charset-length-cve-2007-4840.phpt | 2 + ext/imap/config.m4 | 2 +- ext/imap/config.w32 | 2 +- ext/imap/php_imap.c | 11 +- ext/imap/php_imap.h | 2 +- ext/imap/tests/bug46918.phpt | 6 + ext/imap/tests/imap_body.phpt | 54 +- ext/imap/tests/imap_expunge_error.phpt | 54 +- ext/imap/tests/imap_gc_error.phpt | 56 +- ext/imap/tests/imap_headers.phpt | 56 +- ext/imap/tests/imap_num_msg_error.phpt | 56 +- ext/imap/tests/imap_num_recent_error.phpt | 54 +- ext/imap/tests/imap_open_error.phpt | 84 +- ext/imap/tests/imap_ping_error.phpt | 54 +- ext/interbase/config.m4 | 2 +- ext/interbase/config.w32 | 2 +- ext/interbase/ibase_blobs.c | 2 +- ext/interbase/ibase_events.c | 2 +- ext/interbase/ibase_query.c | 5 +- ext/interbase/ibase_service.c | 2 +- ext/interbase/interbase.c | 6 +- ext/interbase/interbase.rc | 162 +- ext/interbase/php_ibase_includes.h | 2 +- ext/interbase/php_ibase_udf.c | 2 +- ext/interbase/php_interbase.h | 2 +- ext/interbase/tests/002.phpt | 2 +- ext/interbase/tests/003.phpt | 2 +- ext/interbase/tests/004.phpt | 2 +- ext/interbase/tests/005.phpt | 2 +- ext/interbase/tests/006.phpt | 2 +- ext/interbase/tests/007.phpt | 2 +- ext/interbase/tests/008.phpt | 2 +- ext/interbase/tests/interbase.inc | 2 +- ext/interbase/tests/skipif.inc | 2 +- ext/intl/config.w32 | 2 +- ext/intl/doc/collator_api.php | 1 - ext/intl/doc/common_api.php | 2 - ext/intl/doc/datefmt_api.php | 3 - ext/intl/doc/formatter_api.php | 2 - ext/intl/doc/locale_api.php | 52 +- ext/intl/idn/idn.c | 12 +- ext/intl/idn/idn.h | 2 +- ext/intl/intl_error.c | 3 + ext/intl/locale/locale.c | 2 +- ext/intl/locale/locale.h | 2 +- ext/intl/locale/locale_class.c | 2 +- ext/intl/locale/locale_class.h | 2 +- ext/intl/locale/locale_methods.c | 274 +- ext/intl/locale/locale_methods.h | 2 +- ext/intl/php_intl.c | 1 + ext/intl/php_intl.h | 1 + ext/intl/tests/bug48227.phpt | 2 + ext/intl/tests/idn.phpt | 18 + ext/intl/tests/locale_lookup.phpt | 10 +- ext/intl/tests/ut_common.inc | 776 +- ext/json/JSON_parser.h | 1 + ext/json/config.m4 | 2 +- ext/json/config.w32 | 2 +- ext/json/json.c | 8 +- ext/json/php_json.h | 12 +- ext/ldap/config.m4 | 2 +- ext/ldap/config.w32 | 2 +- ext/ldap/ldap.c | 114 +- ext/ldap/php_ldap.h | 2 +- ext/ldap/tests/README | 53 + ext/ldap/tests/bug48696.phpt | 5 + ext/ldap/tests/ldap_add_basic.phpt | 83 + ext/ldap/tests/ldap_add_error.phpt | 136 + ext/ldap/tests/ldap_bind_basic.phpt | 19 + ext/ldap/tests/ldap_bind_error.phpt | 35 + ext/ldap/tests/ldap_bind_variation.phpt | 19 + ext/ldap/tests/ldap_compare_basic.phpt | 31 + ext/ldap/tests/ldap_compare_error.phpt | 55 + ext/ldap/tests/ldap_connect_basic.phpt | 18 + ext/ldap/tests/ldap_connect_error.phpt | 31 + ext/ldap/tests/ldap_connect_variation.phpt | 39 + ext/ldap/tests/ldap_count_entries_basic.phpt | 28 + ext/ldap/tests/ldap_count_entries_error.phpt | 23 + ext/ldap/tests/ldap_delete_basic.phpt | 40 + ext/ldap/tests/ldap_delete_error.phpt | 62 + ext/ldap/tests/ldap_err2str_basic.phpt | 15 + ext/ldap/tests/ldap_err2str_error.phpt | 28 + ext/ldap/tests/ldap_errno_basic.phpt | 30 + ext/ldap/tests/ldap_errno_error.phpt | 23 + ext/ldap/tests/ldap_error_basic.phpt | 30 + ext/ldap/tests/ldap_error_error.phpt | 23 + ext/ldap/tests/ldap_first_attribute_basic.phpt | 31 + ext/ldap/tests/ldap_first_attribute_error.phpt | 23 + ext/ldap/tests/ldap_first_entry_basic.phpt | 37 + ext/ldap/tests/ldap_first_entry_error.phpt | 27 + ext/ldap/tests/ldap_first_reference_basic.phpt | 43 + ext/ldap/tests/ldap_first_reference_error.phpt | 27 + ext/ldap/tests/ldap_free_result_basic.phpt | 28 + ext/ldap/tests/ldap_free_result_error.phpt | 23 + ext/ldap/tests/ldap_get_attributes_basic.phpt | 65 + ext/ldap/tests/ldap_get_attributes_error.phpt | 23 + ext/ldap/tests/ldap_get_dn_basic.phpt | 31 + ext/ldap/tests/ldap_get_dn_error.phpt | 23 + ext/ldap/tests/ldap_get_entries_basic.phpt | 74 + ext/ldap/tests/ldap_get_entries_error.phpt | 33 + ext/ldap/tests/ldap_get_entries_variation.phpt | 33 + ext/ldap/tests/ldap_get_option_basic.phpt | 25 + ext/ldap/tests/ldap_get_option_error.phpt | 40 + ext/ldap/tests/ldap_get_option_variation.phpt | 66 + ext/ldap/tests/ldap_get_values_len_basic.phpt | 36 + ext/ldap/tests/ldap_get_values_len_error.phpt | 45 + ext/ldap/tests/ldap_list_basic.phpt | 150 + ext/ldap/tests/ldap_list_error.phpt | 35 + ext/ldap/tests/ldap_mod_add_basic.phpt | 90 + ext/ldap/tests/ldap_mod_add_error.phpt | 83 + ext/ldap/tests/ldap_mod_del_basic.phpt | 40 + ext/ldap/tests/ldap_mod_del_error.phpt | 62 + ext/ldap/tests/ldap_mod_replace_basic.phpt | 59 + ext/ldap/tests/ldap_mod_replace_error.phpt | 62 + ext/ldap/tests/ldap_modify_basic.phpt | 96 + ext/ldap/tests/ldap_modify_error.phpt | 83 + ext/ldap/tests/ldap_next_attribute_basic.phpt | 36 + ext/ldap/tests/ldap_next_attribute_error.phpt | 40 + ext/ldap/tests/ldap_next_entry_basic.phpt | 40 + ext/ldap/tests/ldap_next_entry_error.phpt | 27 + ext/ldap/tests/ldap_next_reference_basic.phpt | 49 + ext/ldap/tests/ldap_next_reference_error.phpt | 27 + ext/ldap/tests/ldap_parse_reference_basic.phpt | 45 + ext/ldap/tests/ldap_parse_reference_error.phpt | 31 + ext/ldap/tests/ldap_parse_result_basic.phpt | 47 + ext/ldap/tests/ldap_parse_result_error.phpt | 17 + ext/ldap/tests/ldap_read_basic.phpt | 75 + ext/ldap/tests/ldap_read_error.phpt | 35 + ext/ldap/tests/ldap_rename_basic.phpt | 62 + ext/ldap/tests/ldap_rename_error.phpt | 21 + ext/ldap/tests/ldap_sasl_bind_basic.phpt | 20 + ext/ldap/tests/ldap_sasl_bind_error.phpt | 53 + ext/ldap/tests/ldap_search_basic.phpt | 194 + ext/ldap/tests/ldap_search_error.phpt | 62 + ext/ldap/tests/ldap_search_variation1.phpt | 56 + ext/ldap/tests/ldap_search_variation2.phpt | 80 + ext/ldap/tests/ldap_search_variation3.phpt | 108 + ext/ldap/tests/ldap_search_variation4.phpt | 55 + ext/ldap/tests/ldap_search_variation5.phpt | 105 + ext/ldap/tests/ldap_search_variation6.phpt | 230 + ext/ldap/tests/ldap_set_option_basic.phpt | 23 + ext/ldap/tests/ldap_set_option_error.phpt | 66 + ext/ldap/tests/ldap_set_option_variation.phpt | 84 + ext/ldap/tests/ldap_set_rebind_proc_basic.phpt | 34 + ext/ldap/tests/ldap_set_rebind_proc_error.phpt | 40 + ext/ldap/tests/ldap_sort_basic.phpt | 200 + ext/ldap/tests/ldap_sort_error.phpt | 35 + ext/ldap/tests/ldap_sort_variation.phpt | 200 + ext/ldap/tests/ldap_start_tls_basic.phpt | 19 + ext/ldap/tests/ldap_start_tls_error.phpt | 27 + ext/ldap/tests/ldap_unbind_basic.phpt | 20 + ext/ldap/tests/ldap_unbind_error.phpt | 42 + ext/ldap/tests/ldap_unbind_variation.phpt | 34 + ext/libxml/config.w32 | 2 +- ext/libxml/config0.m4 | 2 +- ext/libxml/libxml.c | 2 +- ext/libxml/php_libxml.h | 2 +- ext/mbstring/config.m4 | 2 +- ext/mbstring/config.w32 | 2 +- ext/mbstring/libmbfl/README | 2 +- ext/mbstring/libmbfl/filters/mbfilter_htmlent.c | 52 +- ext/mbstring/libmbfl/filters/mk_sb_tbl.awk | 2 +- ext/mbstring/libmbfl/mbfl.rc | 2 +- ext/mbstring/libmbfl/mbfl/mk_eaw_tbl.awk | 2 +- ext/mbstring/mb_gpc.c | 4 +- ext/mbstring/mb_gpc.h | 2 +- ext/mbstring/mbstring.c | 2 +- ext/mbstring/mbstring.h | 2 +- ext/mbstring/php_mbregex.c | 2 +- ext/mbstring/php_mbregex.h | 2 +- ext/mbstring/tests/bug46806.phpt | 16 + ext/mbstring/tests/bug48645.phpt | 162 + ext/mbstring/tests/mb_convert_kana.phpt | 60 + ext/mbstring/tests/mb_decode_numericentity.phpt | 21 + ext/mbstring/tests/mb_encode_numericentity.phpt | 22 + ext/mbstring/tests/mb_ereg3.phpt | 44 + ext/mbstring/tests/mb_ereg4.phpt | 44 + ext/mbstring/tests/mb_ereg_search.phpt | 39 + ext/mbstring/tests/mb_ereg_search_pos.phpt | 31 + ext/mbstring/tests/mb_ereg_search_regs.phpt | 28 + ext/mbstring/tests/mb_eregi.phpt | 20 + ext/mbstring/tests/mb_eregi_invalid_arguments.phpt | 20 + ext/mbstring/tests/mb_eregi_replace.phpt | 37 + ext/mcrypt/TODO | 2 +- ext/mcrypt/config.m4 | 2 +- ext/mcrypt/config.w32 | 2 +- ext/mcrypt/mcrypt.c | 3 +- ext/mcrypt/php_mcrypt.h | 2 +- ext/mcrypt/tests/bug49738.phpt | 13 + ext/mssql/config.m4 | 2 +- ext/mssql/config.w32 | 2 +- ext/mssql/php_mssql.c | 13 +- ext/mssql/php_mssql.h | 2 +- ext/mysql/config.m4 | 2 +- ext/mysql/config.w32 | 2 +- ext/mysql/php_mysql.c | 25 +- ext/mysql/php_mysql.h | 2 +- ext/mysql/php_mysql_structs.h | 2 +- ext/mysql/tests/001.phpt | 7 +- ext/mysql/tests/002.phpt | 51 +- ext/mysql/tests/003.phpt | 59 +- ext/mysql/tests/bug47438.phpt | 16 +- ext/mysql/tests/bug48754.phpt | 92 + ext/mysql/tests/clean_table.inc | 15 + ext/mysql/tests/connect.inc | 8 +- ext/mysql/tests/mysql_affected_rows.phpt | 15 +- ext/mysql/tests/mysql_client_encoding.phpt | 2 +- ext/mysql/tests/mysql_connect.phpt | 41 +- ext/mysql/tests/mysql_create_db.phpt | 12 + ext/mysql/tests/mysql_data_seek.phpt | 4 + ext/mysql/tests/mysql_db_name.phpt | 2 +- ext/mysql/tests/mysql_db_query.phpt | 8 +- ext/mysql/tests/mysql_drop_db.phpt | 12 + ext/mysql/tests/mysql_errno.phpt | 4 + ext/mysql/tests/mysql_error.phpt | 6 +- ext/mysql/tests/mysql_escape_string.phpt | 23 +- ext/mysql/tests/mysql_fetch_array.phpt | 162 +- ext/mysql/tests/mysql_fetch_assoc.phpt | 87 +- ext/mysql/tests/mysql_fetch_field.phpt | 277 +- ext/mysql/tests/mysql_fetch_lengths.phpt | 8 +- ext/mysql/tests/mysql_fetch_object.phpt | 135 +- ext/mysql/tests/mysql_fetch_row.phpt | 28 +- ext/mysql/tests/mysql_field_flags.phpt | 20 +- ext/mysql/tests/mysql_field_len.phpt | 8 +- ext/mysql/tests/mysql_field_name.phpt | 21 +- ext/mysql/tests/mysql_field_seek.phpt | 207 +- ext/mysql/tests/mysql_field_table.phpt | 21 +- ext/mysql/tests/mysql_field_type.phpt | 21 +- ext/mysql/tests/mysql_free_result.phpt | 8 +- ext/mysql/tests/mysql_get_client_info.phpt | 2 +- ext/mysql/tests/mysql_get_host_info.phpt | 10 +- ext/mysql/tests/mysql_get_proto_info.phpt | 8 +- ext/mysql/tests/mysql_get_server_info.phpt | 6 +- ext/mysql/tests/mysql_info.phpt | 16 +- ext/mysql/tests/mysql_insert_id.phpt | 13 +- ext/mysql/tests/mysql_list_dbs.phpt | 10 +- ext/mysql/tests/mysql_list_fields.phpt | 68 +- ext/mysql/tests/mysql_list_processes.phpt | 8 +- ext/mysql/tests/mysql_list_tables.phpt | 8 +- ext/mysql/tests/mysql_max_persistent.phpt | 24 +- .../tests/mysql_mysqlnd_read_timeout_long.phpt | 37 + ext/mysql/tests/mysql_num_fields.phpt | 8 +- ext/mysql/tests/mysql_num_rows.phpt | 8 +- ext/mysql/tests/mysql_pconn_disable.phpt | 4 + ext/mysql/tests/mysql_pconn_kill.phpt | 16 +- ext/mysql/tests/mysql_pconn_max_links.phpt | 116 +- ext/mysql/tests/mysql_phpinfo.phpt | 2 +- ext/mysql/tests/mysql_ping.phpt | 8 +- ext/mysql/tests/mysql_query.phpt | 55 +- .../tests/mysql_query_load_data_openbasedir.phpt | 2 +- ext/mysql/tests/mysql_real_escape_string.phpt | 27 +- ext/mysql/tests/mysql_result.phpt | 66 +- ext/mysql/tests/mysql_select_db.phpt | 12 +- ext/mysql/tests/mysql_set_charset.phpt | 10 +- ext/mysql/tests/mysql_stat.phpt | 6 +- ext/mysql/tests/mysql_tablename.phpt | 17 +- ext/mysql/tests/mysql_trace_mode.phpt | 11 +- ext/mysql/tests/mysql_unbuffered_query.phpt | 47 +- ext/mysql/tests/skipifconnectfailure.inc | 2 +- ext/mysql/tests/skipifdefaultconnectfailure.inc | 11 + ext/mysql/tests/table.inc | 6 +- ext/mysqli/config.m4 | 4 +- ext/mysqli/config.w32 | 2 +- ext/mysqli/mysqli.c | 49 +- ext/mysqli/mysqli_api.c | 63 +- ext/mysqli/mysqli_fe.c | 2 +- ext/mysqli/mysqli_nonapi.c | 10 +- ext/mysqli/mysqli_prop.c | 2 +- ext/mysqli/mysqli_report.c | 2 +- ext/mysqli/mysqli_report.h | 2 +- ext/mysqli/php_mysqli.h | 2 +- ext/mysqli/php_mysqli_structs.h | 5 +- ext/mysqli/tests/001.phpt | 16 +- ext/mysqli/tests/002.phpt | 13 +- ext/mysqli/tests/003.phpt | 13 +- ext/mysqli/tests/004.phpt | 13 +- ext/mysqli/tests/005.phpt | 16 +- ext/mysqli/tests/006.phpt | 13 +- ext/mysqli/tests/007.phpt | 13 +- ext/mysqli/tests/008.phpt | 13 +- ext/mysqli/tests/009.phpt | 15 +- ext/mysqli/tests/010.phpt | 13 +- ext/mysqli/tests/011.phpt | 13 +- ext/mysqli/tests/012.phpt | 13 +- ext/mysqli/tests/013.phpt | 13 +- ext/mysqli/tests/014.phpt | 8 +- ext/mysqli/tests/015.phpt | 8 +- ext/mysqli/tests/016.phpt | 2 +- ext/mysqli/tests/017.phpt | 2 +- ext/mysqli/tests/018.phpt | 6 +- ext/mysqli/tests/019.phpt | 13 +- ext/mysqli/tests/020.phpt | 13 +- ext/mysqli/tests/021.phpt | 13 +- ext/mysqli/tests/022.phpt | 13 +- ext/mysqli/tests/023.phpt | 13 +- ext/mysqli/tests/024.phpt | 13 +- ext/mysqli/tests/025.phpt | 13 +- ext/mysqli/tests/026.phpt | 14 +- ext/mysqli/tests/027.phpt | 6 +- ext/mysqli/tests/028.phpt | 2 +- ext/mysqli/tests/029.phpt | 17 +- ext/mysqli/tests/030.phpt | 2 +- ext/mysqli/tests/031.phpt | 2 +- ext/mysqli/tests/032.phpt | 13 +- ext/mysqli/tests/033.phpt | 2 +- ext/mysqli/tests/034.phpt | 6 +- ext/mysqli/tests/035.phpt | 6 +- ext/mysqli/tests/036.phpt | 13 +- ext/mysqli/tests/037.phpt | 13 +- ext/mysqli/tests/038.phpt | 13 +- ext/mysqli/tests/039.phpt | 2 +- ext/mysqli/tests/040.phpt | 13 +- ext/mysqli/tests/041.phpt | 17 +- ext/mysqli/tests/042.phpt | 13 +- ext/mysqli/tests/043.phpt | 13 +- ext/mysqli/tests/044.phpt | 6 +- ext/mysqli/tests/045.phpt | 6 +- ext/mysqli/tests/046.phpt | 13 +- ext/mysqli/tests/047.phpt | 13 +- ext/mysqli/tests/048.phpt | 13 +- ext/mysqli/tests/049.phpt | 4 +- ext/mysqli/tests/050.phpt | 6 +- ext/mysqli/tests/051.phpt | 6 +- ext/mysqli/tests/052.phpt | 10 +- ext/mysqli/tests/053.phpt | 12 +- ext/mysqli/tests/054.phpt | 12 +- ext/mysqli/tests/055.phpt | 12 +- ext/mysqli/tests/057.phpt | 13 +- ext/mysqli/tests/058.phpt | 13 +- ext/mysqli/tests/059.phpt | 13 +- ext/mysqli/tests/060.phpt | 13 +- ext/mysqli/tests/061.phpt | 17 +- ext/mysqli/tests/062.phpt | 2 +- ext/mysqli/tests/063.phpt | 2 +- ext/mysqli/tests/064.phpt | 8 +- ext/mysqli/tests/065.phpt | 2 +- ext/mysqli/tests/066.phpt | 17 +- ext/mysqli/tests/067.phpt | 17 +- ext/mysqli/tests/069.phpt | 2 +- ext/mysqli/tests/070.phpt | 6 +- ext/mysqli/tests/071.phpt | 8 +- ext/mysqli/tests/072.phpt | 2 +- ext/mysqli/tests/074.phpt | 2 +- ext/mysqli/tests/bug31668.phpt | 4 +- ext/mysqli/tests/bug32405.phpt | 19 +- ext/mysqli/tests/bug33090.phpt | 8 +- ext/mysqli/tests/bug34785.phpt | 6 +- ext/mysqli/tests/bug34810.phpt | 15 +- ext/mysqli/tests/bug35103.phpt | 19 +- ext/mysqli/tests/bug35517.phpt | 13 +- ext/mysqli/tests/bug35759.phpt | 23 +- ext/mysqli/tests/bug36420.phpt | 8 +- ext/mysqli/tests/bug36745.phpt | 17 +- ext/mysqli/tests/bug36802.phpt | 11 +- ext/mysqli/tests/bug36949.phpt | 15 +- ext/mysqli/tests/bug37090.phpt | 4 +- ext/mysqli/tests/bug38710.phpt | 8 +- ext/mysqli/tests/bug42378.phpt | 6 +- ext/mysqli/tests/bug42548.phpt | 12 +- ext/mysqli/tests/bug44897.phpt | 16 +- ext/mysqli/tests/bug45019.phpt | 115 +- ext/mysqli/tests/bug45289.phpt | 29 +- ext/mysqli/tests/bug46614.phpt | 30 + ext/mysqli/tests/bug47050.phpt | 2 +- ext/mysqli/tests/bug48909.phpt | 39 + ext/mysqli/tests/bug49027.phpt | 62 + ext/mysqli/tests/bug49442.phpt | 119 + ext/mysqli/tests/clean_table.inc | 14 + ext/mysqli/tests/connect.inc | 73 +- ext/mysqli/tests/mysqli_affected_rows.phpt | 6 +- ext/mysqli/tests/mysqli_affected_rows_oo.phpt | 6 +- ext/mysqli/tests/mysqli_autocommit.phpt | 8 +- ext/mysqli/tests/mysqli_autocommit_oo.phpt | 8 +- ext/mysqli/tests/mysqli_change_user.phpt | 4 +- ext/mysqli/tests/mysqli_change_user_get_lock.phpt | 6 +- ext/mysqli/tests/mysqli_change_user_insert_id.phpt | 8 +- .../tests/mysqli_change_user_locks_temporary.phpt | 6 +- ext/mysqli/tests/mysqli_change_user_oo.phpt | 2 +- .../mysqli_change_user_prepared_statements.phpt | 2 +- ext/mysqli/tests/mysqli_change_user_rollback.phpt | 6 +- ext/mysqli/tests/mysqli_change_user_set_names.phpt | 4 +- ext/mysqli/tests/mysqli_character_set.phpt | 6 +- ext/mysqli/tests/mysqli_character_set_name.phpt | 6 +- ext/mysqli/tests/mysqli_character_set_name_oo.phpt | 4 +- .../mysqli_class_mysqli_driver_reflection.phpt | 2 - .../tests/mysqli_class_mysqli_interface.phpt | 4 +- .../tests/mysqli_class_mysqli_reflection.phpt | 55 +- .../mysqli_class_mysqli_result_interface.phpt | 4 +- .../mysqli_class_mysqli_result_reflection.phpt | 4 +- .../tests/mysqli_class_mysqli_stmt_interface.phpt | 4 +- ext/mysqli/tests/mysqli_class_mysqli_warning.phpt | 8 +- .../mysqli_class_mysqli_warning_reflection.phpt | 4 +- ext/mysqli/tests/mysqli_close.phpt | 8 +- ext/mysqli/tests/mysqli_close_oo.phpt | 8 +- ext/mysqli/tests/mysqli_commit.phpt | 14 +- ext/mysqli/tests/mysqli_commit_oo.phpt | 14 +- ext/mysqli/tests/mysqli_connect_errno.phpt | 12 +- ext/mysqli/tests/mysqli_connect_error.phpt | 10 +- ext/mysqli/tests/mysqli_connect_twice.phpt | 6 +- ext/mysqli/tests/mysqli_constants_categories.phpt | 8 +- ext/mysqli/tests/mysqli_data_seek.phpt | 4 + ext/mysqli/tests/mysqli_data_seek_oo.phpt | 4 + ext/mysqli/tests/mysqli_debug.phpt | 4 + ext/mysqli/tests/mysqli_debug_append.phpt | 4 + ext/mysqli/tests/mysqli_debug_ini.phpt | 4 +- .../tests/mysqli_debug_mysqlnd_control_string.phpt | 4 + ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt | 6 +- .../tests/mysqli_disable_reads_from_master.phpt | 6 +- ext/mysqli/tests/mysqli_driver.phpt | 6 +- ext/mysqli/tests/mysqli_dump_debug_info.phpt | 2 +- .../tests/mysqli_enable_reads_from_master.phpt | 6 +- ext/mysqli/tests/mysqli_errno.phpt | 6 +- ext/mysqli/tests/mysqli_errno_oo.phpt | 4 +- ext/mysqli/tests/mysqli_error.phpt | 6 +- ext/mysqli/tests/mysqli_error_unicode.phpt | 2 +- ext/mysqli/tests/mysqli_explain_metadata.phpt | 4 + ext/mysqli/tests/mysqli_fetch_all.phpt | 4 + ext/mysqli/tests/mysqli_fetch_all_oo.phpt | 6 +- ext/mysqli/tests/mysqli_fetch_array_assoc.phpt | 4 + ext/mysqli/tests/mysqli_fetch_array_large.phpt | 150 + ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt | 4 + ext/mysqli/tests/mysqli_fetch_array_oo.phpt | 6 +- ext/mysqli/tests/mysqli_fetch_assoc.phpt | 4 + ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt | 6 +- ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt | 6 +- ext/mysqli/tests/mysqli_fetch_assoc_zerofill.phpt | 4 + ext/mysqli/tests/mysqli_fetch_field.phpt | 4 + ext/mysqli/tests/mysqli_fetch_field_direct.phpt | 4 + ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt | 6 +- ext/mysqli/tests/mysqli_fetch_field_flags.phpt | 8 +- ext/mysqli/tests/mysqli_fetch_field_oo.phpt | 4 + ext/mysqli/tests/mysqli_fetch_field_types.phpt | 4 + ext/mysqli/tests/mysqli_fetch_fields.phpt | 4 + ext/mysqli/tests/mysqli_fetch_lengths.phpt | 4 + ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt | 9 +- ext/mysqli/tests/mysqli_fetch_object.phpt | 4 + .../tests/mysqli_fetch_object_no_constructor.phpt | 4 + .../tests/mysqli_fetch_object_no_object.phpt | 4 + ext/mysqli/tests/mysqli_fetch_object_oo.phpt | 6 +- ext/mysqli/tests/mysqli_fetch_row.phpt | 4 + ext/mysqli/tests/mysqli_field_count.phpt | 4 + ext/mysqli/tests/mysqli_field_seek.phpt | 4 + ext/mysqli/tests/mysqli_field_tell.phpt | 4 + ext/mysqli/tests/mysqli_fork.phpt | 24 +- ext/mysqli/tests/mysqli_free_result.phpt | 4 + ext/mysqli/tests/mysqli_get_cache_stats.phpt | 13 +- .../mysqli_get_cache_stats_free_buffered.phpt | 9 + ext/mysqli/tests/mysqli_get_cache_stats_off.phpt | 64 + ext/mysqli/tests/mysqli_get_charset.phpt | 4 + ext/mysqli/tests/mysqli_get_client_stats.phpt | 42 +- .../mysqli_get_client_stats_implicit_free.phpt | 4 + ext/mysqli/tests/mysqli_get_client_stats_off.phpt | 16 +- ext/mysqli/tests/mysqli_get_client_stats_ps.phpt | 4 + .../tests/mysqli_get_client_stats_skipped.phpt | 3 + ext/mysqli/tests/mysqli_get_connection_stats.phpt | 30 +- .../tests/mysqli_get_connection_stats_off.phpt | 53 + ext/mysqli/tests/mysqli_get_host_info.phpt | 10 +- ext/mysqli/tests/mysqli_get_server_info.phpt | 8 +- ext/mysqli/tests/mysqli_get_warnings.phpt | 23 +- ext/mysqli/tests/mysqli_info.phpt | 6 +- ext/mysqli/tests/mysqli_insert_id.phpt | 4 + ext/mysqli/tests/mysqli_insert_id_variation.phpt | 17 +- ext/mysqli/tests/mysqli_kill.phpt | 8 +- ext/mysqli/tests/mysqli_max_links.phpt | 16 +- ext/mysqli/tests/mysqli_more_results.phpt | 8 +- ext/mysqli/tests/mysqli_multi_query.phpt | 8 +- .../tests/mysqli_mysqli_result_invalid_mode.phpt | 8 +- ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt | 36 + .../tests/mysqli_mysqlnd_read_timeout_long.phpt | 37 + .../tests/mysqli_mysqlnd_read_timeout_zero.phpt | 36 + ext/mysqli/tests/mysqli_next_result.phpt | 8 +- ext/mysqli/tests/mysqli_no_reconnect.phpt | 4 +- ext/mysqli/tests/mysqli_num_fields.phpt | 8 +- ext/mysqli/tests/mysqli_num_rows.phpt | 8 +- ext/mysqli/tests/mysqli_options.phpt | 20 +- ext/mysqli/tests/mysqli_options_init_command.phpt | 69 +- ext/mysqli/tests/mysqli_options_openbasedir.phpt | 2 +- ext/mysqli/tests/mysqli_pconn_disabled.phpt | 8 +- ext/mysqli/tests/mysqli_pconn_kill.phpt | 10 +- ext/mysqli/tests/mysqli_pconn_limits.phpt | 12 +- ext/mysqli/tests/mysqli_pconn_max_links.phpt | 48 +- ext/mysqli/tests/mysqli_pconn_reuse.phpt | 6 +- ext/mysqli/tests/mysqli_pconnect.phpt | 8 +- ext/mysqli/tests/mysqli_ping.phpt | 4 +- ext/mysqli/tests/mysqli_poll.phpt | 41 +- ext/mysqli/tests/mysqli_poll_kill.phpt | 2 +- .../tests/mysqli_poll_mixing_insert_select.phpt | 19 +- ext/mysqli/tests/mysqli_poll_reference.phpt | 7 +- ext/mysqli/tests/mysqli_prepare.phpt | 14 + ext/mysqli/tests/mysqli_prepare_no_object.phpt | 10 +- ext/mysqli/tests/mysqli_ps_select_union.phpt | 275 + ext/mysqli/tests/mysqli_query.phpt | 14 + .../tests/mysqli_query_local_infile_large.phpt | 93 + ext/mysqli/tests/mysqli_query_stored_proc.phpt | 15 +- ext/mysqli/tests/mysqli_query_unicode.phpt | 2 +- ext/mysqli/tests/mysqli_real_connect.phpt | 21 +- ext/mysqli/tests/mysqli_real_connect_pconn.phpt | 4 + ext/mysqli/tests/mysqli_real_query.phpt | 14 + ext/mysqli/tests/mysqli_reconnect.phpt | 2 +- ext/mysqli/tests/mysqli_report.phpt | 22 +- ext/mysqli/tests/mysqli_report_wo_ps.phpt | 12 +- ext/mysqli/tests/mysqli_result_references.phpt | 6 +- .../tests/mysqli_result_references_mysqlnd.phpt | 31 +- ext/mysqli/tests/mysqli_result_unclonable.phpt | 6 +- ext/mysqli/tests/mysqli_rollback.phpt | 8 +- ext/mysqli/tests/mysqli_select_db.phpt | 6 +- ext/mysqli/tests/mysqli_send_query.phpt | 2 +- ext/mysqli/tests/mysqli_set_charset.phpt | 8 +- .../tests/mysqli_set_local_infile_default.phpt | 4 + .../tests/mysqli_set_local_infile_handler.phpt | 6 +- ...qli_set_local_infile_handler_bad_character.phpt | 8 +- ...i_set_local_infile_handler_buffer_overflow.phpt | 6 +- ...mysqli_set_local_infile_handler_close_link.phpt | 6 +- .../mysqli_set_local_infile_handler_closefile.phpt | 6 +- .../mysqli_set_local_infile_handler_closures.phpt | 6 +- .../mysqli_set_local_infile_handler_kill_link.phpt | 6 +- ...sqli_set_local_infile_handler_negative_len.phpt | 6 +- ...ysqli_set_local_infile_handler_nested_call.phpt | 6 +- .../mysqli_set_local_infile_handler_new_query.phpt | 6 +- .../mysqli_set_local_infile_handler_nofileop.phpt | 6 +- ...ysqli_set_local_infile_handler_openbasedir.phpt | 6 +- ...li_set_local_infile_handler_replace_buffer.phpt | 6 +- .../mysqli_set_local_infile_handler_short_len.phpt | 6 +- ...mysqli_set_local_infile_handler_unregister.phpt | 6 +- ext/mysqli/tests/mysqli_set_opt.phpt | 6 +- ...li_set_opt_numeric_and_datetime_as_unicode.phpt | 4 + ext/mysqli/tests/mysqli_sqlstate.phpt | 8 +- ext/mysqli/tests/mysqli_ssl_set.phpt | 8 +- ext/mysqli/tests/mysqli_stmt_affected_rows.phpt | 6 +- ext/mysqli/tests/mysqli_stmt_attr_get.phpt | 4 + .../tests/mysqli_stmt_attr_get_prefetch.phpt | 4 + ext/mysqli/tests/mysqli_stmt_attr_set.phpt | 19 +- ext/mysqli/tests/mysqli_stmt_bind_param.phpt | 6 +- .../mysqli_stmt_bind_param_call_user_func.phpt | 4 + ...sqli_stmt_bind_param_check_param_no_change.phpt | 106 +- .../tests/mysqli_stmt_bind_param_references.phpt | 7 +- .../mysqli_stmt_bind_param_type_juggling.phpt | 4 + ext/mysqli/tests/mysqli_stmt_bind_result.phpt | 12 +- ext/mysqli/tests/mysqli_stmt_bind_result_bit.phpt | 8 +- .../tests/mysqli_stmt_bind_result_format.phpt | 6 +- .../tests/mysqli_stmt_bind_result_references.phpt | 4 + .../tests/mysqli_stmt_bind_result_zerofill.phpt | 4 + ext/mysqli/tests/mysqli_stmt_close.phpt | 4 + ext/mysqli/tests/mysqli_stmt_data_seek.phpt | 4 + ext/mysqli/tests/mysqli_stmt_datatype_change.phpt | 20 +- ext/mysqli/tests/mysqli_stmt_errno.phpt | 4 + ext/mysqli/tests/mysqli_stmt_error.phpt | 4 + ext/mysqli/tests/mysqli_stmt_execute.phpt | 4 + .../tests/mysqli_stmt_execute_stored_proc.phpt | 15 +- ext/mysqli/tests/mysqli_stmt_fetch.phpt | 4 + ext/mysqli/tests/mysqli_stmt_fetch_bit.phpt | 11 +- .../mysqli_stmt_fetch_fields_win32_unicode.phpt | 4 + ext/mysqli/tests/mysqli_stmt_fetch_geom.phpt | 141 + ext/mysqli/tests/mysqli_stmt_field_count.phpt | 4 + ext/mysqli/tests/mysqli_stmt_free_result.phpt | 4 + ext/mysqli/tests/mysqli_stmt_get_result.phpt | 4 + ext/mysqli/tests/mysqli_stmt_get_result2.phpt | 4 + ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt | 6 +- .../tests/mysqli_stmt_get_result_field_count.phpt | 6 +- ext/mysqli/tests/mysqli_stmt_get_result_geom.phpt | 143 + .../tests/mysqli_stmt_get_result_metadata.phpt | 4 + ...ysqli_stmt_get_result_metadata_fetch_field.phpt | 230 +- .../tests/mysqli_stmt_get_result_non_select.phpt | 4 + ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt | 4 + ext/mysqli/tests/mysqli_stmt_get_result_types.phpt | 6 +- ext/mysqli/tests/mysqli_stmt_get_warnings.phpt | 4 + ext/mysqli/tests/mysqli_stmt_init.phpt | 4 + ext/mysqli/tests/mysqli_stmt_insert_id.phpt | 4 + ext/mysqli/tests/mysqli_stmt_num_rows.phpt | 4 + ext/mysqli/tests/mysqli_stmt_param_count.phpt | 4 + ext/mysqli/tests/mysqli_stmt_prepare.phpt | 4 + ext/mysqli/tests/mysqli_stmt_reset.phpt | 4 + ext/mysqli/tests/mysqli_stmt_result_metadata.phpt | 4 + .../mysqli_stmt_result_metadata_sqltests.phpt | 4 + ext/mysqli/tests/mysqli_stmt_send_long_data.phpt | 4 + ...i_stmt_send_long_data_packet_size_libmysql.phpt | 4 + ...li_stmt_send_long_data_packet_size_mysqlnd.phpt | 4 + ext/mysqli/tests/mysqli_stmt_sqlstate.phpt | 4 + ext/mysqli/tests/mysqli_stmt_store_result.phpt | 6 +- ext/mysqli/tests/mysqli_stmt_unclonable.phpt | 2 +- ext/mysqli/tests/mysqli_store_result.phpt | 4 + ext/mysqli/tests/mysqli_thread_id.phpt | 4 + ext/mysqli/tests/mysqli_unclonable.phpt | 2 +- ext/mysqli/tests/mysqli_use_result.phpt | 4 + ext/mysqli/tests/mysqli_warning_count.phpt | 4 + ext/mysqli/tests/mysqli_warning_unclonable.phpt | 6 +- ext/mysqli/tests/skipifconnectfailure.inc | 2 +- ext/mysqli/tests/table.inc | 2 +- ext/mysqlnd/config.w32 | 2 +- ext/mysqlnd/config9.m4 | 11 +- ext/mysqlnd/mysqlnd.c | 159 +- ext/mysqlnd/mysqlnd.h | 15 +- ext/mysqlnd/mysqlnd_alloc.c | 2 +- ext/mysqlnd/mysqlnd_block_alloc.c | 2 +- ext/mysqlnd/mysqlnd_block_alloc.h | 2 +- ext/mysqlnd/mysqlnd_debug.c | 2 +- ext/mysqlnd/mysqlnd_debug.h | 2 +- ext/mysqlnd/mysqlnd_enum_n_def.h | 9 +- ext/mysqlnd/mysqlnd_palloc.c | 12 +- ext/mysqlnd/mysqlnd_palloc.h | 2 +- ext/mysqlnd/mysqlnd_portability.h | 37 +- ext/mysqlnd/mysqlnd_priv.h | 10 +- ext/mysqlnd/mysqlnd_ps.c | 32 +- ext/mysqlnd/mysqlnd_ps_codec.c | 16 +- ext/mysqlnd/mysqlnd_qcache.c | 2 +- ext/mysqlnd/mysqlnd_result.c | 53 +- ext/mysqlnd/mysqlnd_result.h | 2 +- ext/mysqlnd/mysqlnd_result_meta.c | 10 +- ext/mysqlnd/mysqlnd_result_meta.h | 2 +- ext/mysqlnd/mysqlnd_statistics.c | 6 +- ext/mysqlnd/mysqlnd_statistics.h | 2 +- ext/mysqlnd/mysqlnd_structs.h | 11 +- ext/mysqlnd/mysqlnd_wireprotocol.c | 21 +- ext/mysqlnd/mysqlnd_wireprotocol.h | 4 +- ext/mysqlnd/php_mysqlnd.c | 22 +- ext/mysqlnd/php_mysqlnd.h | 2 +- ext/oci8/config.m4 | 2 +- ext/oci8/config.w32 | 2 +- ext/oci8/oci8.c | 10 +- ext/oci8/oci8_collection.c | 2 +- ext/oci8/oci8_interface.c | 2 +- ext/oci8/oci8_lob.c | 2 +- ext/oci8/oci8_statement.c | 2 +- ext/oci8/php_oci8.h | 2 +- ext/oci8/php_oci8_int.h | 2 +- ext/oci8/tests/connect.inc | 12 +- ext/oci8/tests/details.inc | 62 +- ext/oci8/tests/extauth_01.phpt | 56 +- ext/oci8/tests/extauth_02.phpt | 56 +- ext/oci8/tests/extauth_03.phpt | 56 +- ext/oci8/tests/oci8safemode.phpt | 2 + ext/oci8/tests/pecl_bug16842.phpt | 69 + ext/oci8/tests/xmltype_01.phpt | 2 +- ext/odbc/birdstep.c | 2 +- ext/odbc/config.m4 | 2 +- ext/odbc/config.w32 | 2 +- ext/odbc/php_birdstep.h | 2 +- ext/odbc/php_odbc.c | 2 +- ext/odbc/php_odbc.h | 2 +- ext/odbc/php_odbc_includes.h | 2 +- ext/openssl/README | 2 +- ext/openssl/config.w32 | 2 +- ext/openssl/config0.m4 | 2 +- ext/openssl/openssl.c | 38 +- ext/openssl/openssl.mak | 370 +- ext/openssl/php_openssl.h | 2 +- ext/openssl/tests/bug48182.phpt | 92 + ext/openssl/xp_ssl.c | 32 +- ext/pcntl/config.m4 | 2 +- ext/pcntl/pcntl.c | 2 +- ext/pcntl/php_pcntl.h | 2 +- ext/pcntl/php_signal.c | 2 +- ext/pcntl/php_signal.h | 2 +- ext/pcntl/tests/bug47566.phpt | 2 +- ext/pcntl/tests/pcntl_fork_basic.phpt | 27 + ext/pcntl/tests/pcntl_fork_variation.phpt | 48 + ext/pcre/config.w32 | 2 +- ext/pcre/config0.m4 | 4 +- ext/pcre/pcrelib/testdata/grepinput8 | 5 +- ext/pcre/pcrelib/testdata/grepoutput8 | 5 +- ext/pcre/pcrelib/testdata/grepoutputN | 26 +- ext/pcre/php_pcre.c | 4 +- ext/pcre/php_pcre.h | 2 +- ext/pcre/tests/preg_split_basic.phpt | 3 +- ext/pdo/README | 2 +- ext/pdo/TODO | 2 +- ext/pdo/config.m4 | 2 +- ext/pdo/config.w32 | 2 +- ext/pdo/pdo.c | 2 +- ext/pdo/pdo_dbh.c | 4 +- ext/pdo/pdo_sql_parser.c | 2 +- ext/pdo/pdo_sql_parser.c.orig | 2 +- ext/pdo/pdo_sql_parser.re | 2 +- ext/pdo/pdo_sqlstate.c | 2 +- ext/pdo/pdo_stmt.c | 68 +- ext/pdo/php_pdo.h | 2 +- ext/pdo/php_pdo_driver.h | 2 +- ext/pdo/php_pdo_int.h | 2 +- ext/pdo/tests/pdo.inc | 20 +- ext/pdo/tests/pdo_036.phpt | 21 + ext/pdo_dblib/config.m4 | 2 +- ext/pdo_dblib/config.w32 | 2 +- ext/pdo_dblib/dblib_driver.c | 12 +- ext/pdo_dblib/dblib_stmt.c | 2 +- ext/pdo_dblib/pdo_dblib.c | 2 +- ext/pdo_dblib/php_pdo_dblib.h | 2 +- ext/pdo_dblib/php_pdo_dblib_int.h | 2 +- ext/pdo_firebird/config.m4 | 2 +- ext/pdo_firebird/config.w32 | 2 +- ext/pdo_firebird/firebird_driver.c | 2 +- ext/pdo_firebird/firebird_statement.c | 5 +- ext/pdo_firebird/pdo_firebird.c | 17 +- ext/pdo_firebird/php_pdo_firebird.h | 2 +- ext/pdo_firebird/php_pdo_firebird_int.h | 2 +- ext/pdo_firebird/tests/connect.phpt | 2 +- ext/pdo_firebird/tests/ddl.phpt | 2 +- ext/pdo_firebird/tests/execute.phpt | 2 +- ext/pdo_firebird/tests/skipif.inc | 2 +- ext/pdo_firebird/tests/testdb.inc | 2 +- ext/pdo_mysql/config.m4 | 3 +- ext/pdo_mysql/config.w32 | 2 +- ext/pdo_mysql/mysql_driver.c | 11 +- ext/pdo_mysql/mysql_statement.c | 2 +- ext/pdo_mysql/pdo_mysql.c | 4 +- ext/pdo_mysql/php_pdo_mysql.h | 2 +- ext/pdo_mysql/php_pdo_mysql_int.h | 4 +- .../tests/pdo_mysql_attr_init_command.phpt | 21 +- ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt | 2 +- ext/pdo_oci/config.m4 | 2 +- ext/pdo_oci/config.w32 | 2 +- ext/pdo_oci/oci_driver.c | 2 +- ext/pdo_oci/oci_statement.c | 2 +- ext/pdo_oci/pdo_oci.c | 2 +- ext/pdo_oci/php_pdo_oci.h | 2 +- ext/pdo_oci/php_pdo_oci_int.h | 2 +- ext/pdo_oci/tests/bug41996.phpt | 2 +- ext/pdo_odbc/config.m4 | 2 +- ext/pdo_odbc/config.w32 | 2 +- ext/pdo_odbc/odbc_driver.c | 4 +- ext/pdo_odbc/odbc_stmt.c | 6 +- ext/pdo_odbc/pdo_odbc.c | 2 +- ext/pdo_odbc/php_pdo_odbc.h | 2 +- ext/pdo_odbc/php_pdo_odbc_int.h | 2 +- ext/pdo_pgsql/config.m4 | 2 +- ext/pdo_pgsql/config.w32 | 2 +- ext/pdo_pgsql/pdo_pgsql.c | 4 +- ext/pdo_pgsql/pgsql_driver.c | 2 +- ext/pdo_pgsql/pgsql_statement.c | 2 +- ext/pdo_pgsql/php_pdo_pgsql.h | 2 +- ext/pdo_pgsql/php_pdo_pgsql_int.h | 2 +- ext/pdo_sqlite/config.m4 | 2 +- ext/pdo_sqlite/config.w32 | 4 +- ext/pdo_sqlite/pdo_sqlite.c | 2 +- ext/pdo_sqlite/php_pdo_sqlite.h | 2 +- ext/pdo_sqlite/php_pdo_sqlite_int.h | 2 +- ext/pdo_sqlite/sqlite_driver.c | 2 +- ext/pdo_sqlite/sqlite_statement.c | 2 +- ext/pdo_sqlite/tests/bug48773.phpt | 34 + ext/pgsql/config.m4 | 2 +- ext/pgsql/config.w32 | 2 +- ext/pgsql/pgsql.c | 2 +- ext/pgsql/php_pgsql.h | 2 +- ext/phar/Makefile.frag | 5 +- ext/phar/config.m4 | 2 +- ext/phar/config.w32 | 2 +- ext/phar/dirstream.c | 14 + ext/phar/dirstream.h | 2 +- ext/phar/func_interceptors.c | 2 +- ext/phar/func_interceptors.h | 2 +- ext/phar/makestub.php | 2 +- ext/phar/package.php | 29 +- ext/phar/package.xml | 367 +- ext/phar/phar.c | 34 +- ext/phar/phar/directorygraphiterator.inc | 66 +- ext/phar/phar/directorytreeiterator.inc | 106 +- ext/phar/phar/invertedregexiterator.inc | 52 +- ext/phar/phar/pharcommand.inc | 2 +- ext/phar/phar_internal.h | 37 +- ext/phar/phar_object.c | 214 +- ext/phar/phar_path_check.c | 2 +- ext/phar/phar_path_check.re | 2 +- ext/phar/pharzip.h | 3 +- ext/phar/php_phar.h | 4 +- ext/phar/stream.c | 18 + ext/phar/stream.h | 2 +- ext/phar/stub.h | 2 +- ext/phar/tar.c | 86 +- ext/phar/tests/009.phpt | 2 +- ext/phar/tests/016.phpt | 6 +- ext/phar/tests/badparameters.phpt | 6 - ext/phar/tests/bug46032.phpt | 8 +- ext/phar/tests/bug48377.2.phpt | 25 + ext/phar/tests/bug48377.phpt | 29 + ext/phar/tests/cache_list/copyonwrite17.phar.phpt | 2 +- ext/phar/tests/cache_list/copyonwrite19.phar.phpt | 2 +- ext/phar/tests/cache_list/copyonwrite6.phar.phpt | 1 + .../tests/cache_list/files/frontcontroller12.phar | Bin 581 -> 588 bytes .../cache_list/files/frontcontroller12.phar.inc | 14 +- .../tests/cache_list/files/frontcontroller14.phar | Bin 448 -> 450 bytes .../cache_list/files/frontcontroller14.phar.inc | 4 +- .../tests/cache_list/files/frontcontroller3.phar | Bin 446 -> 437 bytes .../cache_list/files/frontcontroller3.phar.inc | 2 +- .../tests/cache_list/files/frontcontroller4.phar | Bin 442 -> 433 bytes .../cache_list/files/frontcontroller4.phar.inc | 2 +- .../tests/cache_list/files/frontcontroller8.phar | Bin 8968 -> 8970 bytes .../cache_list/files/frontcontroller8.phar.inc | 2 +- ext/phar/tests/cache_list/files/write24.phar | Bin 326 -> 327 bytes ext/phar/tests/cache_list/files/write24.phar.inc | 2 +- ext/phar/tests/cache_list/frontcontroller21.phpt | 2 +- ext/phar/tests/cache_list/frontcontroller22.phpt | 4 +- ext/phar/tests/create_new_and_modify.phpt | 6 +- ext/phar/tests/files/frontcontroller12.phar | Bin 581 -> 588 bytes ext/phar/tests/files/frontcontroller12.phar.inc | 14 +- ext/phar/tests/files/frontcontroller14.phar | Bin 448 -> 450 bytes ext/phar/tests/files/frontcontroller14.phar.inc | 4 +- ext/phar/tests/files/frontcontroller3.phar | Bin 446 -> 438 bytes ext/phar/tests/files/frontcontroller3.phar.inc | 2 +- ext/phar/tests/files/frontcontroller4.phar | Bin 442 -> 433 bytes ext/phar/tests/files/frontcontroller4.phar.inc | 2 +- ext/phar/tests/files/frontcontroller8.phar | Bin 8968 -> 8970 bytes ext/phar/tests/files/frontcontroller8.phar.inc | 2 +- ext/phar/tests/fopen_edgecases2.phpt | 7 +- ext/phar/tests/fopen_edgecases2U.phpt | 46 + ext/phar/tests/frontcontroller21.phpt | 2 +- ext/phar/tests/frontcontroller22.phpt | 4 +- ext/phar/tests/ini_set.phpt | 19 +- ext/phar/tests/ini_setU.phpt | 31 - ext/phar/tests/phar_buildfromiterator10.phpt | 1 - ext/phar/tests/phar_buildfromiterator10U.phpt | 101 - ext/phar/tests/phar_bz2.phpt | 5 +- ext/phar/tests/phar_bz2U.phpt | 66 - ext/phar/tests/phar_convert_again.phpt | 6 - ext/phar/tests/phar_ctx_001.phpt | 2 +- ext/phar/tests/phar_magic.phpt | 3 + ext/phar/tests/readfile_edgecases.phpt | 1 + ext/phar/tests/readfile_edgecasesU.phpt | 61 + ext/phar/tests/tar/bignames.phpt | 28 +- ext/phar/tests/tar/bignames_overflow.phpt | 8 +- ext/phar/tests/tar/bug49910.phpt | 50 + ext/phar/tests/tar/files/P1-1.0.0.tgz | Bin 0 -> 1284 bytes ext/phar/tests/tar/files/P1-1.0.0.tgz.pubkey | 9 + .../tests/tar/files/Structures_Graph-1.0.3.tgz | Bin 0 -> 30191 bytes .../tests/tar/files/frontcontroller12.phar.inc | 14 +- .../tests/tar/files/frontcontroller12.phar.tar | Bin 4096 -> 4096 bytes ext/phar/tests/tar/files/frontcontroller3.phar.inc | 2 +- ext/phar/tests/tar/files/frontcontroller3.phar.tar | Bin 6144 -> 6144 bytes ext/phar/tests/tar/files/frontcontroller4.phar.inc | 2 +- ext/phar/tests/tar/files/frontcontroller4.phar.tar | Bin 6144 -> 6144 bytes ext/phar/tests/tar/frontcontroller21.phar.phpt | 2 +- ext/phar/tests/tar/phar_convert_phar4.phpt | 2 +- ext/phar/tests/tar/phar_magic.phpt | 3 + ext/phar/tests/tar/tar_openssl_hash.phpt | 22 + ext/phar/tests/zip/all.phpt | 1 + ext/phar/tests/zip/bug48791.phpt | 15 + ext/phar/tests/zip/files/corrupt_zipmaker.php.inc | 2 +- .../tests/zip/files/frontcontroller12.phar.inc | 14 +- .../tests/zip/files/frontcontroller12.phar.zip | Bin 786 -> 793 bytes ext/phar/tests/zip/files/frontcontroller3.phar.inc | 2 +- ext/phar/tests/zip/files/frontcontroller3.phar.zip | Bin 816 -> 818 bytes ext/phar/tests/zip/files/frontcontroller4.phar.inc | 2 +- ext/phar/tests/zip/files/frontcontroller4.phar.zip | Bin 812 -> 813 bytes ext/phar/tests/zip/files/test.odt | Bin 0 -> 8303 bytes ext/phar/tests/zip/frontcontroller21.phar.phpt | 2 +- ext/phar/tests/zip/phar_magic.phpt | 3 + ext/phar/tests/zip/phar_setsignaturealgo2.phpt | 113 + ext/phar/util.c | 25 +- ext/phar/zip.c | 196 +- ext/posix/config.m4 | 2 +- ext/posix/php_posix.h | 2 +- ext/posix/posix.c | 13 +- ext/posix/tests/posix_ctermid_basic.phpt | 18 + ext/posix/tests/posix_ctermid_error.phpt | 19 + ext/posix/tests/posix_errno_basic.phpt | 22 + ext/posix/tests/posix_errno_error.phpt | 24 + ext/posix/tests/posix_errno_variation1.phpt | 22 + ext/posix/tests/posix_errno_variation2.phpt | 29 + ext/posix/tests/posix_getcwd.phpt | 2 +- ext/posix/tests/posix_geteuid_basic.phpt | 16 + ext/posix/tests/posix_geteuid_error1.phpt | 37 + ext/posix/tests/posix_getgrnam.phpt | 2 +- ext/posix/tests/posix_getpwnam.phpt | 2 +- ext/posix/tests/posix_getrlimit.phpt | 2 +- ext/posix/tests/posix_initgroups.phpt | 2 +- ext/posix/tests/posix_isatty.phpt | 2 +- ext/posix/tests/posix_mknod.phpt | 2 +- ext/posix/tests/posix_seteuid_basic.phpt | 19 + ext/posix/tests/posix_seteuid_error.phpt | 32 + ext/posix/tests/posix_seteuid_error2.phpt | 55 + ext/posix/tests/posix_seteuid_variation1.phpt | 41 + ext/posix/tests/posix_seteuid_variation2.phpt | 36 + ext/posix/tests/posix_seteuid_variation3.phpt | 47 + ext/posix/tests/posix_seteuid_variation4.phpt | 40 + ext/posix/tests/posix_seteuid_variation5.phpt | 34 + ext/posix/tests/posix_seteuid_variation6.phpt | 48 + ext/posix/tests/posix_setgid_basic.phpt | 27 + ext/posix/tests/posix_setgid_error.phpt | 33 + ext/posix/tests/posix_setgid_variation1.phpt | 47 + ext/posix/tests/posix_setgid_variation2.phpt | 39 + ext/posix/tests/posix_setgid_variation3.phpt | 47 + ext/posix/tests/posix_setgid_variation4.phpt | 41 + ext/posix/tests/posix_setgid_variation5.phpt | 37 + ext/posix/tests/posix_setgid_variation6.phpt | 58 + ext/posix/tests/posix_setgid_variation7.phpt | 48 + ext/posix/tests/posix_setuid_basic.phpt | 19 + ext/posix/tests/posix_setuid_error.phpt | 35 + ext/posix/tests/posix_setuid_error2.phpt | 55 + ext/posix/tests/posix_setuid_variation1.phpt | 41 + ext/posix/tests/posix_setuid_variation2.phpt | 36 + ext/posix/tests/posix_setuid_variation3.phpt | 47 + ext/posix/tests/posix_setuid_variation4.phpt | 40 + ext/posix/tests/posix_setuid_variation5.phpt | 34 + ext/posix/tests/posix_setuid_variation6.phpt | 48 + ext/posix/tests/posix_ttyname_error.phpt | 29 + ext/posix/tests/posix_ttyname_variation1.phpt | 35 + ext/posix/tests/posix_ttyname_variation2.phpt | 32 + ext/posix/tests/posix_ttyname_variation3.phpt | 39 + ext/posix/tests/posix_ttyname_variation4.phpt | 34 + ext/posix/tests/posix_ttyname_variation5.phpt | 28 + ext/posix/tests/posix_ttyname_variation6.phpt | 51 + ext/posix/tests/posix_ttyname_variation7.phpt | 36 + ext/pspell/config.m4 | 2 +- ext/pspell/config.w32 | 2 +- ext/pspell/php_pspell.h | 2 +- ext/pspell/pspell.c | 2 +- ext/pspell/tests/001.phpt | 2 +- ext/readline/config.m4 | 12 +- ext/readline/php_readline.h | 2 +- ext/readline/readline.c | 2 +- ext/recode/config.m4 | 2 +- ext/recode/config9.m4 | 2 +- ext/recode/php_recode.h | 2 +- ext/recode/recode.c | 4 +- ext/reflection/config.m4 | 2 +- ext/reflection/config.w32 | 2 +- ext/reflection/php_reflection.c | 73 +- ext/reflection/php_reflection.h | 2 +- .../tests/ReflectionClass_CannotClone_basic.phpt | 15 + .../ReflectionClass_getDefaultProperties_001.phpt | 8 +- ...ReflectionClass_setStaticPropertyValue_001.phpt | 4 +- .../tests/ReflectionFunction_isClosure_basic.phpt | 18 + .../ReflectionFunction_isDeprecated_basic.phpt | 15 + .../tests/ReflectionFunction_isDisabled_basic.phpt | 17 + .../tests/ReflectionMethod_invokeArgs_error3.phpt | 4 +- ext/reflection/tests/bug46064.phpt | 13 +- ext/reflection/tests/bug46064_2.phpt | 12 +- ext/reflection/tests/bug47254.phpt | 42 + ext/reflection/tests/bug48757.phpt | 21 + ext/reflection/tests/bug49074.phpt | 31 + ext/reflection/tests/bug49092.phpt | 12 + ext/session/config.m4 | 3 +- ext/session/config.w32 | 2 +- ext/session/mod_files.c | 2 +- ext/session/mod_files.h | 2 +- ext/session/mod_mm.c | 2 +- ext/session/mod_mm.h | 2 +- ext/session/mod_user.c | 2 +- ext/session/mod_user.h | 2 +- ext/session/php_session.h | 2 +- ext/session/session.c | 28 +- ext/session/tests/031.phpt | 22 + ext/shmop/config.m4 | 2 +- ext/shmop/config.w32 | 2 +- ext/shmop/shmop.c | 2 +- ext/simplexml/config.m4 | 2 +- ext/simplexml/config.w32 | 2 +- ext/simplexml/php_simplexml.h | 2 +- ext/simplexml/php_simplexml_exports.h | 2 +- ext/simplexml/simplexml.c | 4 +- ext/simplexml/sxe.c | 2 +- ext/simplexml/sxe.h | 2 +- ext/simplexml/tests/034.phpt | 1 + ...ement_addAttribute_required_attribute_name.phpt | 18 + ext/simplexml/tests/bug36611.phpt | 6 +- ext/simplexml/tests/bug40451.phpt | 6 +- ext/simplexml/tests/bug41175.phpt | 6 +- ext/simplexml/tests/bug41582.phpt | 6 +- ext/simplexml/tests/bug41861.phpt | 4 + ext/simplexml/tests/bug41867.phpt | 6 +- ext/simplexml/tests/bug41947.phpt | 6 +- ext/simplexml/tests/bug42369.phpt | 6 +- ext/simplexml/tests/bug43221.phpt | 7 +- ext/simplexml/tests/bug44478.phpt | 5 + ext/simplexml/tests/bug45553.phpt | 7 +- ext/simplexml/tests/bug46003.phpt | 7 +- ext/simplexml/tests/bug46047.phpt | 7 +- ext/simplexml/tests/bug46048.phpt | 6 +- ext/skeleton/create_stubs | 2 +- ext/snmp/config.m4 | 2 +- ext/snmp/config.w32 | 2 +- ext/snmp/php_snmp.h | 2 +- ext/snmp/snmp.c | 72 +- ext/soap/TODO | 196 +- ext/soap/TODO.old | 78 +- ext/soap/config.m4 | 2 +- ext/soap/config.w32 | 2 +- ext/soap/interop/client_round2_interop.php | 2 +- ext/soap/interop/client_round2_params.php | 2 +- ext/soap/interop/client_round2_results.php | 2 +- ext/soap/interop/client_round2_run.php | 2 +- ext/soap/interop/server_round2_base.php | 2 +- ext/soap/interop/server_round2_groupB.php | 2 +- ext/soap/interop/server_round2_groupC.php | 2 +- ext/soap/php_encoding.c | 2 +- ext/soap/php_encoding.h | 2 +- ext/soap/php_http.c | 2 +- ext/soap/php_http.h | 2 +- ext/soap/php_packet_soap.c | 2 +- ext/soap/php_packet_soap.h | 2 +- ext/soap/php_schema.c | 5 +- ext/soap/php_schema.h | 2 +- ext/soap/php_sdl.c | 62 +- ext/soap/php_sdl.h | 7 +- ext/soap/php_soap.h | 2 +- ext/soap/php_xml.c | 2 +- ext/soap/php_xml.h | 2 +- ext/soap/readme.html | 1290 +- ext/soap/soap.c | 9 +- ext/soap/tests/bugs/bug47273.phpt | 53 + ext/soap/tests/bugs/xml.xsd | 68 +- ext/soap/tests/schema/test_schema.inc | 154 +- ext/soap/tests/soap12/soap12-test.inc | 262 +- ext/sockets/config.m4 | 2 +- ext/sockets/config.w32 | 2 +- ext/sockets/php_sockets.h | 6 +- ext/sockets/sockets.c | 12 +- ext/sockets/tests/bug46360.phpt | 17 + ext/sockets/tests/socket_bind.phpt | 38 + ext/sockets/tests/socket_bind_params.phpt | 29 + ext/sockets/tests/socket_close_params.phpt | 21 + ext/sockets/tests/socket_connect_error.phpt | 33 + ext/sockets/tests/socket_connect_params.phpt | 33 + ext/sockets/tests/socket_create_listen.phpt | 6 +- ext/sockets/tests/socket_create_listen_params.phpt | 23 + ext/sockets/tests/socket_create_listen_used.phpt | 30 + .../tests/socket_create_pair-wrongparams.phpt | 6 +- ext/sockets/tests/socket_create_params.phpt | 24 + ext/sockets/tests/socket_getpeername.phpt | 33 + ext/sockets/tests/socket_getpeername_ipv4loop.phpt | 59 + ext/sockets/tests/socket_getpeername_ipv6loop.phpt | 59 + ext/sockets/tests/socket_getsockname.phpt | 32 + ext/sockets/tests/socket_listen_params.phpt | 21 + ext/sockets/tests/socket_read_params.phpt | 28 + .../tests/socket_sentto_recvfrom_ipv4_udp.phpt | 2 +- ext/sockets/tests/socket_sentto_recvfrom_unix.phpt | 10 +- ext/sockets/tests/socket_set_block-retval.phpt | 4 +- ext/sockets/tests/socket_set_nonblock-retval.phpt | 4 +- ext/sockets/tests/socket_set_nonblock.phpt | 24 + ext/sockets/tests/socket_strerror.phpt | 154 + ext/sockets/tests/socket_write_params.phpt | 28 + ext/sockets/unix_socket_constants.h | 2 +- ext/sockets/win32_socket_constants.h | 2 +- ext/spl/TODO | 6 +- ext/spl/config.m4 | 2 +- ext/spl/config.w32 | 2 +- ext/spl/examples/autoload.inc | 98 +- ext/spl/examples/cachingrecursiveiterator.inc | 54 +- ext/spl/examples/class_tree.php | 224 +- ext/spl/examples/dba_array.php | 102 +- ext/spl/examples/dba_dump.php | 82 +- ext/spl/examples/dbaarray.inc | 194 +- ext/spl/examples/dbareader.inc | 190 +- ext/spl/examples/directoryfilterdots.inc | 90 +- ext/spl/examples/directorygraphiterator.inc | 66 +- ext/spl/examples/directorytree.inc | 52 +- ext/spl/examples/directorytree.php | 72 +- ext/spl/examples/directorytreeiterator.inc | 106 +- ext/spl/examples/ini_groups.php | 80 +- ext/spl/examples/keyfilter.inc | 126 +- ext/spl/examples/nocvsdir.php | 108 +- ext/spl/examples/searchiterator.inc | 114 +- ext/spl/examples/tree.php | 80 +- ext/spl/php_spl.c | 44 +- ext/spl/spl_array.c | 92 +- ext/spl/spl_array.h | 2 +- ext/spl/spl_directory.c | 125 +- ext/spl/spl_directory.h | 3 +- ext/spl/spl_dllist.c | 92 +- ext/spl/spl_dllist.h | 2 +- ext/spl/spl_engine.h | 2 +- ext/spl/spl_exceptions.c | 2 +- ext/spl/spl_exceptions.h | 2 +- ext/spl/spl_fixedarray.c | 27 +- ext/spl/spl_fixedarray.h | 2 +- ext/spl/spl_functions.c | 2 +- ext/spl/spl_functions.h | 2 +- ext/spl/spl_heap.c | 106 +- ext/spl/spl_heap.h | 2 +- ext/spl/spl_iterators.c | 199 +- ext/spl/spl_iterators.h | 2 +- ext/spl/spl_observer.c | 106 +- ext/spl/spl_observer.h | 2 +- .../ArrayObject_unserialize_empty_string.phpt | 16 + ext/spl/tests/DirectoryIterator_by_reference.phpt | 14 + .../tests/DirectoryIterator_empty_constructor.phpt | 15 + .../DirectoryIterator_getBasename_basic_test.phpt | 46 +- .../DirectoryIterator_getBasename_pass_array.phpt | 46 +- .../tests/DirectoryIterator_getGroup_basic.phpt | 30 + .../tests/DirectoryIterator_getInode_basic.phpt | 29 + .../tests/DirectoryIterator_getInode_error.phpt | 28 + .../tests/DirectoryIterator_getOwner_basic.phpt | 29 + .../SplDoublyLinkedList_bottom_pass_array.phpt | 28 +- .../SplDoublyLinkedList_bottom_pass_float.phpt | 28 +- .../SplDoublyLinkedList_bottom_pass_integer.phpt | 28 +- .../SplDoublyLinkedList_bottom_pass_null.phpt | 28 +- ...LinkedList_count_param_SplDoublyLinkedList.phpt | 20 +- .../tests/SplDoublyLinkedList_current_empty.phpt | 24 +- .../tests/SplDoublyLinkedList_offsetGet_empty.phpt | 26 +- .../SplDoublyLinkedList_offsetGet_param_array.phpt | 34 +- ...SplDoublyLinkedList_offsetGet_param_string.phpt | 34 +- ext/spl/tests/SplDoublyLinkedList_pop_params.phpt | 26 +- ..._setIteratorMode_param_SplDoublyLinkedList.phpt | 20 +- .../tests/SplDoublyLinkedList_shift_noParams.phpt | 15 - .../tests/SplDoublyLinkedList_top_pass_array.phpt | 28 +- .../tests/SplDoublyLinkedList_top_pass_float.phpt | 28 +- .../SplDoublyLinkedList_top_pass_integer.phpt | 28 +- .../tests/SplDoublyLinkedList_top_pass_null.phpt | 28 +- ext/spl/tests/SplFileInfo_getGroup_basic.phpt | 30 + ext/spl/tests/SplFileInfo_getGroup_error.phpt | 28 + ext/spl/tests/SplFileInfo_getInode_basic.phpt | 30 + ext/spl/tests/SplFileInfo_getInode_error.phpt | 28 + ext/spl/tests/SplFileInfo_getOwner_basic.phpt | 30 + ext/spl/tests/SplFileInfo_getOwner_error.phpt | 28 + ext/spl/tests/SplFileInfo_getPerms_basic.phpt | 30 + ext/spl/tests/SplFileInfo_getPerms_error.phpt | 28 + .../SplFixedArray__construct_param_array.phpt | 22 +- .../SplFixedArray__construct_param_float.phpt | 26 +- .../tests/SplFixedArray__construct_param_null.phpt | 30 +- .../SplFixedArray__construct_param_string.phpt | 24 +- ...plFixedArray_construct_param_SplFixedArray.phpt | 24 +- ext/spl/tests/SplFixedArray_count_param_int.phpt | 20 +- ext/spl/tests/SplFixedArray_current_param.phpt | 48 +- ext/spl/tests/SplFixedArray_fromarray_indexes.phpt | 44 +- .../tests/SplFixedArray_fromarray_non_indexes.phpt | 42 +- .../SplFixedArray_fromarray_param_boolean.phpt | 18 +- .../SplFixedArray_fromarray_param_multiarray.phpt | 34 +- .../tests/SplFixedArray_getSize_pass_param.phpt | 24 +- ext/spl/tests/SplFixedArray_key_param.phpt | 48 +- ext/spl/tests/SplFixedArray_key_setsize.phpt | 38 +- ext/spl/tests/SplFixedArray_next_param.phpt | 36 +- ext/spl/tests/SplFixedArray_rewind_param.phpt | 36 +- .../SplFixedArray_setSize_filled_to_smaller.phpt | 42 +- .../tests/SplFixedArray_setSize_param_array.phpt | 36 +- .../tests/SplFixedArray_setSize_param_float.phpt | 38 +- .../tests/SplFixedArray_setSize_param_null.phpt | 26 +- ext/spl/tests/SplFixedArray_setsize_grow.phpt | 58 +- .../tests/SplFixedarray_offsetExists_larger.phpt | 15 - ext/spl/tests/SplObjectStorage_var_dump.phpt | 35 + ext/spl/tests/arrayObject___construct_basic1.phpt | 38 +- ext/spl/tests/arrayObject___construct_basic2.phpt | 98 +- ext/spl/tests/arrayObject___construct_basic3.phpt | 98 +- ext/spl/tests/arrayObject___construct_basic4.phpt | 98 +- ext/spl/tests/arrayObject___construct_basic5.phpt | 98 +- ext/spl/tests/arrayObject___construct_basic6.phpt | 48 +- ext/spl/tests/arrayObject___construct_error1.phpt | 48 +- ext/spl/tests/arrayObject___construct_error2.phpt | 42 +- ext/spl/tests/arrayObject_asort_basic1.phpt | 46 +- ext/spl/tests/arrayObject_asort_basic2.phpt | 54 +- ext/spl/tests/arrayObject_clone_basic1.phpt | 32 +- ext/spl/tests/arrayObject_clone_basic2.phpt | 36 +- ext/spl/tests/arrayObject_clone_basic3.phpt | 48 +- ext/spl/tests/arrayObject_count_basic1.phpt | 158 +- .../tests/arrayObject_exchangeArray_basic3.phpt | 104 +- ext/spl/tests/arrayObject_getFlags_basic1.phpt | 48 +- ext/spl/tests/arrayObject_getFlags_basic2.phpt | 46 +- .../tests/arrayObject_getIteratorClass_basic1.phpt | 122 +- ext/spl/tests/arrayObject_ksort_basic1.phpt | 2 +- ext/spl/tests/arrayObject_ksort_basic2.phpt | 2 +- ext/spl/tests/arrayObject_magicMethods1.phpt | 140 +- ext/spl/tests/arrayObject_magicMethods2.phpt | 140 +- ext/spl/tests/arrayObject_magicMethods3.phpt | 138 +- ext/spl/tests/arrayObject_magicMethods4.phpt | 146 +- ext/spl/tests/arrayObject_magicMethods5.phpt | 146 +- ext/spl/tests/arrayObject_magicMethods6.phpt | 146 +- ext/spl/tests/arrayObject_natcasesort_basic1.phpt | 2 +- ext/spl/tests/arrayObject_natsort_basic1.phpt | 2 +- ext/spl/tests/arrayObject_setFlags_basic1.phpt | 102 +- ext/spl/tests/arrayObject_setFlags_basic2.phpt | 58 +- .../tests/arrayObject_setIteratorClass_error1.phpt | 90 +- ext/spl/tests/arrayObject_uasort_basic1.phpt | 2 +- ext/spl/tests/arrayObject_uasort_error1.phpt | 2 +- ext/spl/tests/arrayObject_uksort_basic1.phpt | 2 +- ext/spl/tests/arrayObject_uksort_error1.phpt | 2 +- ext/spl/tests/array_027.phpt | 24 + ext/spl/tests/bug42364.phpt | 3 +- ext/spl/tests/bug44144.phpt | 27 + ext/spl/tests/countable_class_basic1.phpt | 71 +- ext/spl/tests/countable_count_variation1.phpt | 134 +- ext/spl/tests/dit_002.phpt | 4 +- ext/spl/tests/dllist_012.phpt | 29 + ext/spl/tests/heap_012.phpt | 32 + ext/spl/tests/heap_corruption.phpt | 122 +- ext/spl/tests/heap_current_variation_001.phpt | 42 +- ext/spl/tests/heap_isempty_variation_001.phpt | 32 +- ext/spl/tests/iterator_count.phpt | 52 +- ext/spl/tests/iterator_to_array.phpt | 50 +- .../recursive_tree_iterator_setprefixpart.phpt | 64 +- ext/spl/tests/regexiterator_getpregflags.phpt | 64 +- .../tests/regexiterator_setflags_exception.phpt | 68 +- ext/spl/tests/regexiterator_setpregflags.phpt | 66 +- .../regexiterator_setpregflags_exception.phpt | 70 +- .../tests/splDoublyLinkedList_shift_noParams.phpt | 15 + ext/spl/tests/spl_autoload_013.phpt | 51 + ext/spl/tests/spl_autoload_014.phpt | 47 + ext/spl/tests/spl_autoload_bug48541.phpt | 15 + .../tests/spl_fileinfo_getlinktarget_basic.phpt | 44 +- ext/spl/tests/spl_heap_is_empty_basic.phpt | 62 +- ext/spl/tests/spl_heap_isempty.phpt | 40 +- ext/spl/tests/spl_pq_top_basic.phpt | 82 +- ext/spl/tests/spl_pq_top_error_corrupt.phpt | 45 +- ext/spl/tests/spl_pq_top_error_empty.phpt | 34 +- .../spl_recursive_iterator_iterator_key_case.phpt | 66 +- .../tests/splfixedarray_offsetExists_larger.phpt | 15 + ext/sqlite/config.m4 | 2 +- ext/sqlite/config.w32 | 2 +- ext/sqlite/libsqlite/src/attach.c | 2 +- ext/sqlite/libsqlite/src/auth.c | 2 +- ext/sqlite/libsqlite/src/btree.c | 2 +- ext/sqlite/libsqlite/src/btree.h | 2 +- ext/sqlite/libsqlite/src/btree_rb.c | 2 +- ext/sqlite/libsqlite/src/build.c | 2 +- ext/sqlite/libsqlite/src/copy.c | 2 +- ext/sqlite/libsqlite/src/date.c | 2 +- ext/sqlite/libsqlite/src/delete.c | 2 +- ext/sqlite/libsqlite/src/encode.c | 2 +- ext/sqlite/libsqlite/src/expr.c | 2 +- ext/sqlite/libsqlite/src/func.c | 2 +- ext/sqlite/libsqlite/src/hash.c | 2 +- ext/sqlite/libsqlite/src/hash.h | 2 +- ext/sqlite/libsqlite/src/insert.c | 2 +- ext/sqlite/libsqlite/src/main.c | 2 +- ext/sqlite/libsqlite/src/pager.c | 2 +- ext/sqlite/libsqlite/src/pager.h | 2 +- ext/sqlite/libsqlite/src/parse.y | 2 +- ext/sqlite/libsqlite/src/pragma.c | 2 +- ext/sqlite/libsqlite/src/random.c | 2 +- ext/sqlite/libsqlite/src/select.c | 2 +- ext/sqlite/libsqlite/src/sqlite.h.in | 2 +- ext/sqlite/libsqlite/src/sqlite.w32.h | 2 +- ext/sqlite/libsqlite/src/sqliteInt.h | 2 +- ext/sqlite/libsqlite/src/tokenize.c | 2 +- ext/sqlite/libsqlite/src/update.c | 2 +- ext/sqlite/libsqlite/src/util.c | 2 +- ext/sqlite/libsqlite/src/vacuum.c | 2 +- ext/sqlite/libsqlite/src/vdbe.c | 2 +- ext/sqlite/libsqlite/src/vdbe.h | 2 +- ext/sqlite/libsqlite/src/where.c | 2 +- ext/sqlite/pdo_sqlite2.c | 2 +- ext/sqlite/php_sqlite.h | 2 +- ext/sqlite/sess_sqlite.c | 2 +- ext/sqlite/sqlite.c | 6 +- ext/sqlite/tests/sqlitedatabase_arrayquery.phpt | 23 + ext/sqlite3/CREDITS | 4 +- ext/sqlite3/config.w32 | 2 +- ext/sqlite3/config0.m4 | 2 +- ext/sqlite3/libsqlite/sqlite3.c | 18861 ++-- ext/sqlite3/libsqlite/sqlite3.h | 738 +- ext/sqlite3/libsqlite/sqlite3ext.h | 2 +- ext/sqlite3/php_sqlite3.h | 2 +- ext/sqlite3/php_sqlite3_structs.h | 2 +- ext/sqlite3/sqlite3.c | 2 +- .../sqlite3_32_createAggregate_paramCount.phpt | 2 +- .../sqlite3_33_createAggregate_notcallable.phpt | 2 +- ext/standard/array.c | 55 +- ext/standard/assert.c | 3 +- ext/standard/base64.c | 2 +- ext/standard/base64.h | 2 +- ext/standard/basic_functions.c | 43 +- ext/standard/basic_functions.h | 5 +- ext/standard/browscap.c | 2 +- ext/standard/config.m4 | 17 +- ext/standard/config.w32 | 4 +- ext/standard/crc32.c | 2 +- ext/standard/crc32.h | 2 +- ext/standard/credits.c | 15 +- ext/standard/credits.h | 2 +- ext/standard/crypt.c | 2 +- ext/standard/crypt_blowfish.c | 2 +- ext/standard/crypt_freesec.c | 4 +- ext/standard/crypt_freesec.h | 2 +- ext/standard/css.c | 2 +- ext/standard/css.h | 2 +- ext/standard/cyr_convert.c | 2 +- ext/standard/cyr_convert.h | 2 +- ext/standard/datetime.c | 2 +- ext/standard/datetime.h | 2 +- ext/standard/dir.c | 6 +- ext/standard/dl.c | 8 +- ext/standard/dl.h | 2 +- ext/standard/dns.c | 265 +- ext/standard/dns.h | 71 - ext/standard/dns_win32.c | 49 +- ext/standard/exec.c | 9 +- ext/standard/exec.h | 2 +- ext/standard/file.c | 8 +- ext/standard/file.h | 2 +- ext/standard/filestat.c | 2 +- ext/standard/filters.c | 3 +- ext/standard/flock_compat.c | 2 +- ext/standard/flock_compat.h | 2 +- ext/standard/formatted_print.c | 14 +- ext/standard/fsock.c | 2 +- ext/standard/fsock.h | 2 +- ext/standard/ftok.c | 2 +- ext/standard/ftp_fopen_wrapper.c | 2 +- ext/standard/head.c | 12 +- ext/standard/head.h | 2 +- ext/standard/html.c | 2 +- ext/standard/html.h | 2 +- ext/standard/http.c | 2 +- ext/standard/http_fopen_wrapper.c | 13 +- ext/standard/image.c | 2 +- ext/standard/incomplete_class.c | 2 +- ext/standard/info.c | 27 +- ext/standard/info.h | 2 +- ext/standard/iptc.c | 2 +- ext/standard/lcg.c | 2 +- ext/standard/levenshtein.c | 2 +- ext/standard/link.c | 2 +- ext/standard/link_win32.c | 17 +- ext/standard/mail.c | 2 +- ext/standard/math.c | 2 +- ext/standard/md5.c | 2 +- ext/standard/md5.h | 2 +- ext/standard/metaphone.c | 9 +- ext/standard/microtime.c | 2 +- ext/standard/microtime.h | 2 +- ext/standard/pack.c | 12 +- ext/standard/pack.h | 2 +- ext/standard/pageinfo.c | 2 +- ext/standard/pageinfo.h | 2 +- ext/standard/php_array.h | 2 +- ext/standard/php_assert.h | 2 +- ext/standard/php_browscap.h | 2 +- ext/standard/php_crypt.h | 2 +- ext/standard/php_crypt_r.c | 3 +- ext/standard/php_crypt_r.h | 2 +- ext/standard/php_dir.h | 2 +- ext/standard/php_dns.h | 87 + ext/standard/php_ext_syslog.h | 2 +- ext/standard/php_filestat.h | 2 +- ext/standard/php_fopen_wrapper.c | 67 +- ext/standard/php_fopen_wrappers.h | 2 +- ext/standard/php_ftok.h | 2 +- ext/standard/php_http.h | 2 +- ext/standard/php_image.h | 2 +- ext/standard/php_incomplete_class.h | 2 +- ext/standard/php_iptc.h | 2 +- ext/standard/php_lcg.h | 2 +- ext/standard/php_link.h | 2 +- ext/standard/php_mail.h | 2 +- ext/standard/php_math.h | 2 +- ext/standard/php_metaphone.h | 2 +- ext/standard/php_rand.h | 2 +- ext/standard/php_smart_str.h | 2 +- ext/standard/php_smart_str_public.h | 2 +- ext/standard/php_standard.h | 4 +- ext/standard/php_string.h | 4 +- ext/standard/php_type.h | 2 +- ext/standard/php_uuencode.h | 2 +- ext/standard/php_var.h | 2 +- ext/standard/php_versioning.h | 2 +- ext/standard/proc_open.c | 37 +- ext/standard/proc_open.h | 2 +- ext/standard/quot_print.c | 2 +- ext/standard/quot_print.h | 2 +- ext/standard/rand.c | 2 +- ext/standard/scanf.c | 2 +- ext/standard/scanf.h | 2 +- ext/standard/sha1.c | 2 +- ext/standard/sha1.h | 2 +- ext/standard/soundex.c | 2 +- ext/standard/streamsfuncs.c | 21 +- ext/standard/streamsfuncs.h | 2 +- ext/standard/string.c | 268 +- ext/standard/strnatcmp.c | 24 +- ext/standard/syslog.c | 2 +- ext/standard/tests/array/bug40709.phpt | 1 - ext/standard/tests/array/bug44929.phpt | 8 +- ext/standard/tests/array/bug48854.phpt | 43 + ext/standard/tests/array/key_exists_basic.phpt | 15 + ext/standard/tests/array/key_exists_error.phpt | 23 + .../tests/array/key_exists_variation1.phpt | 15 + .../tests/array/key_exists_variation2.phpt | 72 + ext/standard/tests/array/max_basiclong_64bit.phpt | 35 + ext/standard/tests/array/min_basiclong_64bit.phpt | 35 + .../tests/array/unexpected_array_mod_bug.phpt | 21 + .../class_object/get_class_variation_001.phpt | 8 +- ext/standard/tests/file/005_variation2-win32.phpt | 6 +- ext/standard/tests/file/bug43353-win32.phpt | 23 + ext/standard/tests/file/bug43353.phpt | 5 + ext/standard/tests/file/bug44607.phpt | 3 +- ext/standard/tests/file/bug49047.phpt | 17 + .../tests/file/file_get_contents_basic001.phpt | 21 + .../tests/file/file_get_contents_error001.phpt | 18 + .../tests/file/file_get_contents_error002.phpt | 18 + .../tests/file/file_put_contents_variation5.phpt | 2 +- ext/standard/tests/file/glob_error_002.phpt | 27 - .../tests/file/is_uploaded_file_basic.phpt | 2 - ext/standard/tests/file/lchgrp_basic.phpt | 36 + .../tests/file/mkdir_variation5-win32.phpt | 1 - .../tests/file/move_uploaded_file_basic.phpt | 2 - ext/standard/tests/file/realpath_basic2.phpt | 4 +- .../tests/file/rename_variation6-win32.phpt | 36 + ext/standard/tests/file/rename_variation6.phpt | 3 +- .../tests/file/rename_variation7-win32.phpt | 36 + ext/standard/tests/file/rename_variation7.phpt | 1 + ext/standard/tests/file/stat_variation8-win32.phpt | 2 +- ext/standard/tests/file/touch_basic-win32.phpt | 1 - .../tests/file/touch_variation5-win32.phpt | 45 +- ext/standard/tests/file/touch_variation5.phpt | 4 +- .../tests/file/touch_variation6-win32.phpt | 45 +- .../tests/file/unlink_variation8-win32.phpt | 5 +- ext/standard/tests/file/unlink_variation8.phpt | 6 +- .../tests/file/unlink_variation9-win32.phpt | 15 +- .../tests/file/windows_acls/bug44859_4.phpt | 2 +- .../.getservbyport_basic.phpt.swp | Bin 0 -> 12288 bytes ext/standard/tests/general_functions/bug47859.phpt | 2 +- ext/standard/tests/general_functions/bug48660.phpt | 58 + ext/standard/tests/general_functions/bug48768.phpt | 31 + ext/standard/tests/general_functions/bug49056.phpt | 26 + .../call_user_func_array_variation_001.phpt | 118 +- .../tests/general_functions/get_cfg_var_basic.phpt | 24 + .../tests/general_functions/get_cfg_var_error.phpt | 27 + .../general_functions/get_cfg_var_variation1.phpt | 46 + .../general_functions/get_cfg_var_variation2.phpt | 35 + .../general_functions/get_cfg_var_variation3.phpt | 42 + .../general_functions/get_cfg_var_variation4.phpt | 37 + .../general_functions/get_cfg_var_variation5.phpt | 35 + .../general_functions/get_cfg_var_variation6.phpt | 44 + .../general_functions/get_cfg_var_variation7.phpt | 39 + .../general_functions/get_cfg_var_variation8.phpt | 20 + .../general_functions/get_cfg_var_variation9.phpt | 37 + .../get_defined_constants_basic.phpt | 39 + .../get_defined_constants_error.phpt | 25 + .../get_loaded_extensions_basic.phpt | 23 + .../get_loaded_extensions_error.phpt | 26 + .../general_functions/get_resource_type_basic.phpt | 20 + .../general_functions/get_resource_type_error.phpt | 34 + .../get_resource_type_variation1.phpt | 74 + .../general_functions/getservbyname_basic.phpt | 31 + .../general_functions/getservbyname_error.phpt | 21 + .../getservbyname_variation1.phpt | 40 + .../getservbyname_variation10.phpt | 36 + .../getservbyname_variation11.phpt | 30 + .../getservbyname_variation12.phpt | 29 + .../getservbyname_variation13.phpt | 38 + .../getservbyname_variation14.phpt | 33 + .../getservbyname_variation2.phpt | 29 + .../getservbyname_variation3.phpt | 36 + .../getservbyname_variation4.phpt | 31 + .../getservbyname_variation5.phpt | 29 + .../getservbyname_variation6.phpt | 38 + .../getservbyname_variation7.phpt | 33 + .../getservbyname_variation8.phpt | 40 + .../getservbyname_variation9.phpt | 28 + .../general_functions/getservbyport_basic.phpt | 26 + .../general_functions/getservbyport_error.phpt | 21 + .../getservbyport_variation1.phpt | 40 + .../tests/general_functions/is_resource_basic.phpt | 92 + .../tests/general_functions/is_resource_error.phpt | 34 + .../tests/general_functions/isset_basic1.phpt | 66 + .../tests/general_functions/isset_basic2.phpt | 60 + .../tests/general_functions/phpcredits2.phpt | 2 - ext/standard/tests/general_functions/phpinfo2.phpt | 2 - .../tests/general_functions/proc_nice_basic.phpt | 27 + .../tests/general_functions/proc_nice_error.phpt | 21 + .../general_functions/proc_nice_variation1.phpt | 44 + .../general_functions/proc_nice_variation2.phpt | 33 + .../general_functions/proc_nice_variation3.phpt | 44 + .../general_functions/proc_nice_variation5.phpt | 35 + .../general_functions/proc_nice_variation6.phpt | 52 + .../general_functions/proc_nice_variation7.phpt | 45 + .../tests/general_functions/sleep_basic.phpt | 40 + .../tests/general_functions/sleep_error.phpt | 44 + .../tests/general_functions/uniqid_basic.phpt | 73 + .../tests/general_functions/uniqid_error.phpt | 46 + .../tests/general_functions/usleep_basic.phpt | 39 + .../tests/general_functions/usleep_error.phpt | 45 + .../tests/general_functions/var_dump_64bit.phpt | 6 +- ext/standard/tests/http/bug43510.phpt | 28 + ext/standard/tests/http/bug48929.phpt | 56 + .../tests/image/getimagesize_variation_003.phpt | 138 +- .../tests/image/getimagesize_variation_005.phpt | 74 +- ext/standard/tests/mail/ezmlm_hash_variation1.phpt | 28 +- ext/standard/tests/math/abs.phpt | 2 +- ext/standard/tests/math/bug21523.phpt | 2 +- ext/standard/tests/math/bug24142.phpt | 2 +- ext/standard/tests/math/ceil_basic.phpt | 6 +- ext/standard/tests/math/log.phpt | 2 +- ext/standard/tests/math/pow.phpt | 2 +- ext/standard/tests/math/round.phpt | 2 +- ext/standard/tests/misc/browscap.ini | 33854 +++--- ext/standard/tests/misc/get_browser_basic.phpt | 2 +- ext/standard/tests/misc/get_browser_error.phpt | 2 +- .../tests/misc/get_browser_variation1.phpt | 2 +- ext/standard/tests/misc/time_nanosleep_error4.phpt | 2 +- .../tests/misc/time_sleep_until_basic.phpt | 14 + .../tests/misc/time_sleep_until_error1.phpt | 13 + .../tests/misc/time_sleep_until_error2.phpt | 12 + .../tests/misc/time_sleep_until_error3.phpt | 12 + .../tests/network/gethostbyaddr_basic1.phpt | 18 + .../tests/network/gethostbyname_basic003.phpt | 18 + .../tests/network/gethostbynamel_basic1.phpt | 19 + ext/standard/tests/php_ini_loaded_file.phpt | 13 + ext/standard/tests/php_logo_guid.phpt | 13 + ext/standard/tests/php_real_logo_guid.phpt | 12 + .../tests/serialize/autoload_implements.p5c | 18 +- .../tests/serialize/autoload_interface.p5c | 12 +- ext/standard/tests/streams/stream_is_local.phpt | 17 + ext/standard/tests/strings/006.phpt | 2 +- ext/standard/tests/strings/addslashes_basic.phpt | 3 +- ext/standard/tests/strings/addslashes_error.phpt | 1 - .../tests/strings/addslashes_variation1.phpt | 3 +- .../tests/strings/addslashes_variation2.phpt | 3 +- .../tests/strings/addslashes_variation3.phpt | 1 - ext/standard/tests/strings/bug38770.phpt | 4 + ext/standard/tests/strings/bug47481.phpt | 57 + ext/standard/tests/strings/bug48709.phpt | 31 + ext/standard/tests/strings/bug50052.phpt | 12 + .../tests/strings/chunk_split_variation2.phpt | 55 +- .../tests/strings/chunk_split_variation3.phpt | 24 +- .../tests/strings/chunk_split_variation5.phpt | Bin 2185 -> 2289 bytes .../tests/strings/chunk_split_variation8.phpt | 17 +- ext/standard/tests/strings/explode_variation1.phpt | 28 +- ext/standard/tests/strings/explode_variation2.phpt | 32 +- ext/standard/tests/strings/htmlentities02.phpt | 1 - ext/standard/tests/strings/htmlentities04.phpt | 1 - ext/standard/tests/strings/htmlentities15.phpt | 1 - ext/standard/tests/strings/join_variation6.phpt | Bin 737 -> 729 bytes ext/standard/tests/strings/md5_basic1.phpt | 17 + ext/standard/tests/strings/md5_basic2.phpt | 30 + ext/standard/tests/strings/md5_error.phpt | 35 + .../tests/strings/money_format_basic1.phpt | 64 +- .../tests/strings/money_format_basic2.phpt | 84 - .../tests/strings/money_format_basic3.phpt | 83 - ext/standard/tests/strings/money_format_error.phpt | 4 + .../tests/strings/money_format_variation1.phpt | 60 +- .../tests/strings/money_format_variation2.phpt | 54 +- ext/standard/tests/strings/parse_str_basic3.phpt | 6 +- ext/standard/tests/strings/parse_str_basic4.phpt | 11 + ext/standard/tests/strings/show_source_basic.phpt | 27 + .../tests/strings/show_source_variation1.phpt | 28 + .../tests/strings/show_source_variation2.phpt | 27 + ext/standard/tests/strings/soundex_basic.phpt | 46 + ext/standard/tests/strings/soundex_error.phpt | 34 + ext/standard/tests/strings/str_replace_basic.phpt | 49 + ext/standard/tests/strings/str_replace_error.phpt | 41 + .../tests/strings/str_replace_variation1.phpt | 392 + .../tests/strings/str_replace_variation2.phpt | Bin 0 -> 12679 bytes .../tests/strings/str_replace_variation3.phpt | 227 + ext/standard/tests/strings/str_rot13_basic.phpt | 55 + ext/standard/tests/strings/str_rot13_error.phpt | 32 + .../tests/strings/stripcslashes_variation1.phpt | 1 - ext/standard/tests/strings/stripos_variation1.phpt | 12 +- .../tests/strings/stripos_variation10.phpt | 10 +- .../tests/strings/stripos_variation11.phpt | 4 +- ext/standard/tests/strings/stripos_variation2.phpt | 8 - ext/standard/tests/strings/stristr.phpt | 10 +- ext/standard/tests/strings/stristr_variation1.phpt | 16 +- ext/standard/tests/strings/stristr_variation2.phpt | 10 +- .../tests/strings/strnatcasecmp_error.phpt | 33 + .../tests/strings/strnatcasecmp_variation1.phpt | 2 - ext/standard/tests/strings/strnatcmp_basic.phpt | 80 + ext/standard/tests/strings/strnatcmp_error.phpt | 34 + ext/standard/tests/strings/strpos.phpt | Bin 9992 -> 9990 bytes .../tests/strings/strrchr_variation10.phpt | 14 +- .../tests/strings/strrpos_variation10.phpt | 14 +- ext/standard/tests/strings/strstr.phpt | Bin 10343 -> 10539 bytes ext/standard/tests/strings/ucwords_basic.phpt | 1 - ext/standard/tests/strings/ucwords_error.phpt | 1 - .../tests/strings/wordwrap_variation3.phpt | 1 - ext/standard/tests/url/get_headers_error_001.phpt | 44 + ext/standard/tests/url/get_headers_error_002.phpt | 55 + ext/standard/tests/zend_logo_guid.phpt | 12 + ext/standard/type.c | 2 +- ext/standard/uniqid.c | 2 +- ext/standard/uniqid.h | 2 +- ext/standard/url.c | 2 +- ext/standard/url.h | 2 +- ext/standard/url_scanner.c | 373 - ext/standard/url_scanner.h | 54 - ext/standard/url_scanner_ex.c | 12 +- ext/standard/url_scanner_ex.c.orig | 12 +- ext/standard/url_scanner_ex.h | 17 +- ext/standard/url_scanner_ex.re | 10 +- ext/standard/user_filters.c | 2 +- ext/standard/uuencode.c | 2 +- ext/standard/var.c | 10 +- ext/standard/var_unserializer.c | 2 +- ext/standard/var_unserializer.c.orig | 2 +- ext/standard/var_unserializer.re | 2 +- ext/standard/versioning.c | 2 +- ext/sybase_ct/config.m4 | 2 +- ext/sybase_ct/config.w32 | 2 +- ext/sybase_ct/php_sybase_ct.c | 2 +- ext/sybase_ct/php_sybase_ct.h | 2 +- ext/sybase_ct/tests/bug22403.phpt | 2 +- ext/sybase_ct/tests/bug26407.phpt | 2 +- ext/sybase_ct/tests/bug27843.phpt | 2 +- ext/sybase_ct/tests/bug28354.phpt | 2 +- ext/sybase_ct/tests/bug29064.phpt | 2 +- ext/sybase_ct/tests/bug30312-withfree.phpt | 2 +- ext/sybase_ct/tests/bug30312.phpt | 2 +- ext/sybase_ct/tests/bug43578.phpt | 2 +- ext/sybase_ct/tests/bug6339.phpt | 2 +- ext/sybase_ct/tests/index.php | 216 - ext/sybase_ct/tests/skipif.inc | 2 +- ext/sybase_ct/tests/test.inc | 2 +- ext/sybase_ct/tests/test_appname.phpt | 2 +- ext/sybase_ct/tests/test_close.phpt | 2 +- ext/sybase_ct/tests/test_close_default.phpt | 2 +- ext/sybase_ct/tests/test_close_notopen.phpt | 2 +- ext/sybase_ct/tests/test_connect.phpt | 2 +- ext/sybase_ct/tests/test_connection_caching.phpt | 2 +- .../tests/test_connectionbased_msghandler.phpt | 2 +- ext/sybase_ct/tests/test_fetch_object.phpt | 2 +- ext/sybase_ct/tests/test_fields.phpt | 2 +- ext/sybase_ct/tests/test_long.phpt | 2 +- ext/sybase_ct/tests/test_msghandler.phpt | 2 +- ext/sybase_ct/tests/test_msghandler_handled.phpt | 2 +- ext/sybase_ct/tests/test_query_nostore.phpt | 2 +- ext/sybase_ct/tests/test_types.phpt | 2 +- .../tests/test_unbuffered_no_full_fetch.phpt | 2 +- ext/sybase_ct/tests/test_unbuffered_query.phpt | 2 +- ext/sysvmsg/config.m4 | 2 +- ext/sysvmsg/php_sysvmsg.h | 2 +- ext/sysvmsg/sysvmsg.c | 4 +- ext/sysvsem/config.m4 | 2 +- ext/sysvsem/php_sysvsem.h | 2 +- ext/sysvsem/sysvsem.c | 2 +- ext/sysvshm/config.m4 | 2 +- ext/sysvshm/php_sysvshm.h | 2 +- ext/sysvshm/sysvshm.c | 2 +- ext/tidy/config.m4 | 2 +- ext/tidy/config.w32 | 2 +- ext/tidy/php_tidy.h | 2 +- ext/tidy/tests/030.phpt | 29 + ext/tidy/tests/031.phpt | 18 + ext/tidy/tests/032.phpt | 17 + ext/tidy/tests/033.phpt | 17 + ext/tidy/tests/034.phpt | 20 + ext/tidy/tests/tidy_error1.phpt | 19 + ext/tidy/tidy.c | 4 +- ext/tokenizer/config.m4 | 2 +- ext/tokenizer/config.w32 | 2 +- ext/tokenizer/php_tokenizer.h | 2 +- ext/tokenizer/tokenizer.c | 2 +- ext/tokenizer/tokenizer_data.c | 2 +- ext/tokenizer/tokenizer_data_gen.sh | 2 +- ext/wddx/config.m4 | 2 +- ext/wddx/config.w32 | 2 +- ext/wddx/php_wddx.h | 2 +- ext/wddx/php_wddx_api.h | 2 +- ext/wddx/wddx.c | 2 +- ext/xml/config.m4 | 2 +- ext/xml/config.w32 | 2 +- ext/xml/expat_compat.h | 2 +- ext/xml/php_xml.h | 2 +- ext/xml/xml.c | 4 +- ext/xmlreader/config.m4 | 2 +- ext/xmlreader/config.w32 | 2 +- ext/xmlreader/php_xmlreader.c | 2 +- ext/xmlreader/php_xmlreader.h | 2 +- ext/xmlreader/tests/001.phpt | 2 +- ext/xmlreader/tests/002.phpt | 2 +- ext/xmlreader/tests/003.phpt | 2 +- ext/xmlreader/tests/004.phpt | 2 +- ext/xmlreader/tests/005.phpt | 2 +- ext/xmlreader/tests/006.phpt | 2 +- ext/xmlreader/tests/007.phpt | 2 +- ext/xmlreader/tests/008.phpt | 2 +- ext/xmlreader/tests/009.phpt | 2 +- ext/xmlreader/tests/010.phpt | 2 +- ext/xmlreader/tests/011.phpt | 2 +- ext/xmlreader/tests/012.phpt | 2 +- ext/xmlreader/tests/013.phpt | 2 +- ext/xmlrpc/config.m4 | 2 +- ext/xmlrpc/config.w32 | 2 +- ext/xmlrpc/libxmlrpc/base64.c | 2 +- ext/xmlrpc/libxmlrpc/encodings.c | 2 +- ext/xmlrpc/libxmlrpc/queue.c | 2 +- ext/xmlrpc/libxmlrpc/simplestring.c | 7 +- ext/xmlrpc/libxmlrpc/system_methods.c | 5 +- ext/xmlrpc/libxmlrpc/xml_element.c | 8 +- ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c | 2 +- ext/xmlrpc/libxmlrpc/xmlrpc.c | 9 +- ext/xmlrpc/libxmlrpc/xmlrpc_introspection.c | 5 +- ext/xmlrpc/php_xmlrpc.h | 2 +- ext/xmlrpc/tests/001.phpt | 15 +- ext/xmlrpc/tests/002.phpt | 9 +- ext/xmlrpc/xmlrpc-epi-php.c | 24 +- ext/xmlwriter/config.m4 | 2 +- ext/xmlwriter/config.w32 | 2 +- ext/xmlwriter/php_xmlwriter.c | 2 +- ext/xmlwriter/php_xmlwriter.h | 2 +- ext/xmlwriter/tests/001.phpt | 2 +- ext/xmlwriter/tests/002.phpt | 2 +- ext/xmlwriter/tests/003.phpt | 2 +- ext/xmlwriter/tests/004.phpt | 2 +- ext/xmlwriter/tests/005.phpt | 2 +- ext/xmlwriter/tests/006.phpt | 2 +- ext/xmlwriter/tests/007.phpt | 2 +- ext/xmlwriter/tests/008.phpt | 2 +- ext/xmlwriter/tests/009.phpt | 2 +- ext/xmlwriter/tests/OO_001.phpt | 2 +- ext/xmlwriter/tests/OO_002.phpt | 2 +- ext/xmlwriter/tests/OO_003.phpt | 2 +- ext/xmlwriter/tests/OO_004.phpt | 2 +- ext/xmlwriter/tests/OO_005.phpt | 2 +- ext/xmlwriter/tests/OO_006.phpt | 2 +- ext/xmlwriter/tests/OO_007.phpt | 2 +- ext/xmlwriter/tests/OO_008.phpt | 2 +- ext/xmlwriter/tests/OO_009.phpt | 2 +- ext/xmlwriter/tests/bug48204.phpt | 2 +- .../tests/xmlwriter_open_uri_error_001.phpt | 2 +- .../tests/xmlwriter_open_uri_error_002.phpt | 2 +- .../tests/xmlwriter_open_uri_error_003.phpt | 2 +- .../tests/xmlwriter_open_uri_error_004.phpt | 2 +- .../tests/xmlwriter_open_uri_error_005.phpt | 2 +- .../xmlwriter_set_indent_string_basic_001.phpt | 2 +- .../xmlwriter_set_indent_string_error_001.phpt | 2 +- .../xmlwriter_write_attribute_ns_basic_001.phpt | 2 +- .../xmlwriter_write_attribute_ns_error_001.phpt | 2 +- .../tests/xmlwriter_write_dtd_basic_001.phpt | 2 +- .../tests/xmlwriter_write_dtd_error_001.phpt | 2 +- ext/xsl/config.m4 | 2 +- ext/xsl/config.w32 | 2 +- ext/xsl/php_xsl.c | 2 +- ext/xsl/php_xsl.h | 2 +- ext/xsl/tests/documentxpath.xsl | 2 +- ext/xsl/tests/phpfunc-nostring.xsl | 2 +- ext/xsl/tests/phpfunc-undef.xsl | 2 +- ext/xsl/tests/phpfunc.xsl | 2 +- ext/xsl/tests/streamsinclude.xsl | 2 +- ext/xsl/tests/xslt.xsl | 2 +- ext/xsl/tests/xslt012.xsl | 2 +- ext/xsl/xsl_fe.h | 2 +- ext/xsl/xsltprocessor.c | 4 +- ext/zip/config.m4 | 2 +- ext/zip/config.w32 | 2 +- ext/zip/examples/im.php | 2 +- ext/zip/examples/odt.php | 2 +- ext/zip/lib/zip_close.c | 42 +- ext/zip/lib/zip_fclose.c | 14 +- ext/zip/lib/zip_fread.c | 21 +- ext/zip/lib/zip_get_archive_comment.c | 10 +- ext/zip/lib/zip_open.c | 3 +- ext/zip/php_zip.c | 4 +- ext/zip/php_zip.h | 2 +- ext/zip/tests/bug11216.phpt | 2 +- ext/zip/tests/bug14962.phpt | 2 +- ext/zip/tests/bug38943.phpt | 2 +- ext/zip/tests/bug38943_2.phpt | 2 +- ext/zip/tests/bug47667.phpt | 2 +- ext/zip/tests/bug49072.phpt | 24 + ext/zip/tests/bug49072.zip | Bin 0 -> 162657 bytes ext/zip/tests/bug7214.phpt | 2 +- ext/zip/tests/bug7658.phpt | 2 +- ext/zip/tests/bug8009.phpt | 2 +- ext/zip/tests/bug8700.phpt | 2 +- ext/zip/tests/oo_addemptydir.phpt | 2 +- ext/zip/tests/oo_addfile.phpt | 2 +- ext/zip/tests/oo_close.phpt | 2 +- ext/zip/tests/oo_delete.phpt | 2 +- ext/zip/tests/oo_ext_zip.phpt | 2 +- ext/zip/tests/oo_extract.phpt | 2 +- ext/zip/tests/oo_getcomment.phpt | 2 +- ext/zip/tests/oo_getnameindex.phpt | 2 +- ext/zip/tests/oo_getstatusstring.phpt | 28 + ext/zip/tests/oo_namelocate.phpt | 2 +- ext/zip/tests/oo_open.phpt | 2 +- ext/zip/tests/oo_properties.phpt | 2 +- ext/zip/tests/oo_rename.phpt | 2 +- ext/zip/tests/oo_setcomment.phpt | 2 +- ext/zip/tests/oo_stream.phpt | 2 +- ext/zip/tests/utils.inc | 2 +- ext/zip/tests/zip_close.phpt | 2 +- ext/zip/tests/zip_entry_compressedsize.phpt | 2 +- ext/zip/tests/zip_entry_compressionmethod.phpt | 2 +- ext/zip/tests/zip_entry_filesize.phpt | 2 +- ext/zip/tests/zip_entry_name.phpt | 2 +- ext/zip/tests/zip_entry_open.phpt | 2 +- ext/zip/tests/zip_entry_read.phpt | 2 +- ext/zip/tests/zip_open.phpt | 2 +- ext/zip/tests/zip_open_error.phpt | 28 + ext/zip/tests/zip_read.phpt | 2 +- ext/zip/zip_stream.c | 23 +- ext/zlib/config.w32 | 2 +- ext/zlib/config0.m4 | 2 +- ext/zlib/php_zlib.h | 4 +- ext/zlib/tests/001.phpt | 2 +- ext/zlib/tests/002.phpt | 2 +- ext/zlib/tests/gzfilegzreadfile.phpt | 2 +- ext/zlib/tests/zlib_filter_deflate.phpt | 2 +- ext/zlib/tests/zlib_filter_deflate2.phpt | 16 + ext/zlib/tests/zlib_filter_inflate.phpt | 2 +- ext/zlib/tests/zlib_filter_inflate2.phpt | 2 +- ext/zlib/zlib.c | 15 +- ext/zlib/zlib_filter.c | 31 +- ext/zlib/zlib_fopen_wrapper.c | 2 +- header | 2 +- main/SAPI.c | 42 +- main/SAPI.h | 2 +- main/alloca.c | 2 +- main/build-defs.h.in | 2 +- main/fopen_wrappers.c | 39 +- main/fopen_wrappers.h | 2 +- main/getopt.c | 2 +- main/internal_functions.c.in | 2 +- main/internal_functions_nw.c | 2 +- main/internal_functions_win32.c | 2 +- main/logos.h | 2 +- main/main.c | 87 +- main/mergesort.c | 2 +- main/network.c | 14 +- main/output.c | 10 +- main/php.h | 2 +- main/php3_compat.h | 2 +- main/php_compat.h | 2 +- main/php_config.h.in | 98 +- main/php_content_types.c | 2 +- main/php_content_types.h | 2 +- main/php_getopt.h | 2 +- main/php_globals.h | 4 +- main/php_ini.c | 64 +- main/php_ini.h | 2 +- main/php_logos.c | 2 +- main/php_logos.h | 2 +- main/php_main.h | 2 +- main/php_memory_streams.h | 2 +- main/php_network.h | 2 +- main/php_open_temporary_file.c | 13 +- main/php_open_temporary_file.h | 2 +- main/php_output.h | 2 +- main/php_reentrancy.h | 2 +- main/php_scandir.c | 2 +- main/php_scandir.h | 2 +- main/php_sprintf.c | 2 +- main/php_streams.h | 2 +- main/php_syslog.h | 2 +- main/php_ticks.c | 2 +- main/php_ticks.h | 2 +- main/php_variables.c | 2 +- main/php_variables.h | 2 +- main/php_version.h | 6 +- main/reentrancy.c | 2 +- main/rfc1867.c | 12 +- main/rfc1867.h | 2 +- main/safe_mode.c | 2 +- main/safe_mode.h | 2 +- main/snprintf.c | 2 +- main/snprintf.h | 2 +- main/spprintf.c | 2 +- main/spprintf.h | 2 +- main/streams/cast.c | 2 +- main/streams/filter.c | 2 +- main/streams/glob_wrapper.c | 2 +- main/streams/memory.c | 4 +- main/streams/mmap.c | 2 +- main/streams/php_stream_context.h | 2 +- main/streams/php_stream_filter_api.h | 2 +- main/streams/php_stream_glob_wrapper.h | 2 +- main/streams/php_stream_mmap.h | 2 +- main/streams/php_stream_plain_wrapper.h | 2 +- main/streams/php_stream_transport.h | 2 +- main/streams/php_stream_userspace.h | 2 +- main/streams/php_streams_int.h | 2 +- main/streams/plain_wrapper.c | 6 +- main/streams/streams.c | 2 +- main/streams/transports.c | 2 +- main/streams/userspace.c | 2 +- main/streams/xp_socket.c | 16 +- main/strlcat.c | 2 +- main/strlcpy.c | 2 +- main/win32_internal_function_disabled.h | 2 +- main/win95nt.h | 2 +- makedist | 47 +- pear/Makefile.frag | 4 +- pear/install-pear-nozlib.phar | 105135 +++++++++--------- php.ini-development | 50 +- php.ini-production | 50 +- run-tests.php | 102 +- sapi/aolserver/README | 2 +- sapi/aolserver/aolserver.c | 4 +- sapi/aolserver/config.m4 | 2 +- sapi/aolserver/config.w32 | 2 +- sapi/apache/config.m4 | 2 +- sapi/apache/config.w32 | 2 +- sapi/apache/libpre.c | 2 +- sapi/apache/mod_php5.c | 2 +- sapi/apache/mod_php5.h | 2 +- sapi/apache/php_apache.c | 2 +- sapi/apache/php_apache_http.h | 2 +- sapi/apache/sapi_apache.c | 2 +- sapi/apache2filter/apache_config.c | 2 +- sapi/apache2filter/config.m4 | 2 +- sapi/apache2filter/config.w32 | 2 +- sapi/apache2filter/php_apache.h | 2 +- sapi/apache2filter/php_functions.c | 2 +- sapi/apache2filter/sapi_apache2.c | 2 +- sapi/apache2handler/apache_config.c | 2 +- sapi/apache2handler/config.m4 | 2 +- sapi/apache2handler/config.w32 | 2 +- sapi/apache2handler/mod_php5.c | 2 +- sapi/apache2handler/php_apache.h | 2 +- sapi/apache2handler/php_functions.c | 2 +- sapi/apache2handler/sapi_apache2.c | 2 +- sapi/apache_hooks/config.m4 | 2 +- sapi/apache_hooks/config.w32 | 2 +- sapi/apache_hooks/mod_php5.c | 2 +- sapi/apache_hooks/mod_php5.h | 2 +- sapi/apache_hooks/php_apache.c | 2 +- sapi/apache_hooks/sapi_apache.c | 2 +- sapi/caudium/caudium.c | 4 +- sapi/caudium/config.m4 | 2 +- sapi/cgi/CHANGES | 68 +- sapi/cgi/cgi_main.c | 78 +- sapi/cgi/config.w32 | 2 +- sapi/cgi/config9.m4 | 2 +- sapi/cgi/fastcgi.c | 14 +- sapi/cgi/fastcgi.h | 2 +- sapi/cgi/tests/006.phpt | 4 +- sapi/cli/config.m4 | 2 +- sapi/cli/config.w32 | 2 +- sapi/cli/php_cli.c | 10 +- sapi/cli/php_cli_readline.c | 2 +- sapi/cli/php_cli_readline.h | 2 +- sapi/continuity/capi.c | 2 +- sapi/continuity/config.m4 | 2 +- sapi/embed/config.m4 | 2 +- sapi/embed/config.w32 | 2 +- sapi/embed/php_embed.c | 8 +- sapi/embed/php_embed.h | 14 +- sapi/isapi/config.m4 | 2 +- sapi/isapi/config.w32 | 2 +- sapi/isapi/php5isapi.c | 2 +- sapi/litespeed/README | 450 +- sapi/litespeed/config.m4 | 2 +- sapi/litespeed/lsapi_main.c | 2 +- sapi/litespeed/lsapilib.c | 2 +- sapi/milter/config.m4 | 2 +- sapi/milter/php_milter.c | 2 +- sapi/nsapi/config.m4 | 2 +- sapi/nsapi/config.w32 | 2 +- sapi/nsapi/nsapi-readme.txt | 2 +- sapi/nsapi/nsapi.c | 11 +- sapi/phttpd/config.m4 | 2 +- sapi/pi3web/config.m4 | 2 +- sapi/pi3web/config.w32 | 2 +- sapi/pi3web/pi3web_sapi.c | 4 +- sapi/roxen/config.m4 | 2 +- sapi/roxen/roxen.c | 4 +- sapi/thttpd/README | 2 +- sapi/thttpd/config.m4 | 2 +- sapi/thttpd/thttpd.c | 2 +- sapi/tux/README | 2 +- sapi/tux/config.m4 | 2 +- sapi/webjames/config.m4 | 2 +- scripts/apache/conffix.awk | 2 +- scripts/apache/htaccessfix.awk | 2 +- scripts/dev/check_parameters.php | 2 +- scripts/dev/conv_z_macros | 2 +- svnclean.bat | 2 + tests/basic/002.phpt | 2 - tests/basic/003.phpt | 2 - tests/basic/004.phpt | 2 - tests/basic/005.phpt | 2 - tests/basic/011.phpt | 2 - tests/basic/013.phpt | 2 - tests/basic/014.phpt | 2 - tests/basic/015.phpt | 2 - tests/basic/016.phpt | 2 - tests/basic/017.phpt | 2 - tests/basic/018.phpt | 2 - tests/basic/019.phpt | 2 - tests/basic/020.phpt | 2 - tests/basic/021.phpt | 2 - tests/basic/024.phpt | 2 - tests/basic/025.phpt | 2 - tests/basic/026.phpt | 4 +- tests/basic/027.phpt | 2 - tests/basic/bug45986.phpt | 12 + tests/basic/bug46759.phpt | 2 - tests/basic/php_egg_logo_guid.phpt | 13 + tests/basic/php_logo_guid.phpt | 10 + tests/basic/php_real_logo_guid.phpt | 12 + tests/basic/rfc1867_anonymous_upload.phpt | 2 - tests/basic/rfc1867_array_upload.phpt | 2 - tests/basic/rfc1867_boundary_1.phpt | 2 - tests/basic/rfc1867_boundary_2.phpt | 2 - tests/basic/rfc1867_empty_upload.phpt | 2 - tests/basic/rfc1867_file_upload_disabled.phpt | 2 - tests/basic/rfc1867_garbled_mime_headers.phpt | 2 - tests/basic/rfc1867_invalid_boundary.phpt | 2 - tests/basic/rfc1867_malicious_input.phpt | 2 - tests/basic/rfc1867_max_file_size.phpt | 2 - tests/basic/rfc1867_missing_boundary.phpt | 2 - tests/basic/rfc1867_missing_boundary_2.phpt | 2 - tests/basic/rfc1867_post_max_filesize.phpt | 2 - tests/basic/rfc1867_post_max_size.phpt | 2 - tests/basic/zend_logo_guid.phpt | 13 + tests/classes/arrayobject_001.phpt | 1 - tests/classes/autoload_derived.p5c | 10 +- tests/classes/autoload_implements.p5c | 18 +- tests/classes/autoload_interface.p5c | 12 +- tests/classes/autoload_root.p5c | 18 +- tests/lang/bug24054.phpt | 2 +- tests/lang/bug25145.phpt | 2 - tests/lang/bug38579.inc | 6 +- tests/lang/bug44827.phpt | 14 + tests/lang/engine_assignExecutionOrder_001.phpt | 304 +- tests/lang/engine_assignExecutionOrder_002.phpt | 270 +- tests/lang/engine_assignExecutionOrder_003.phpt | 190 +- tests/lang/engine_assignExecutionOrder_004.phpt | 104 +- tests/lang/engine_assignExecutionOrder_005.phpt | 148 +- tests/lang/engine_assignExecutionOrder_006.phpt | 276 +- tests/lang/engine_assignExecutionOrder_007.phpt | 92 +- tests/lang/engine_assignExecutionOrder_008.phpt | 148 +- tests/lang/engine_assignExecutionOrder_009.phpt | 72 +- tests/lang/execution_order.phpt | 396 +- tests/security/open_basedir_parse_ini_file.phpt | 14 +- vcsclean | 11 + win32/build/Makefile | 4 +- win32/build/block.template.dsw | 30 +- win32/build/buildconf.js | 553 +- win32/build/config.w32 | 4 +- win32/build/config.w32.h.in | 2 +- win32/build/configure.tail | 2 +- win32/build/confutils.js | 3722 +- win32/build/cvsclean.js | 58 +- win32/build/deplister.c | 2 +- win32/build/mkdist.php | 42 +- win32/build/svnclean.js | 120 + win32/build/template.dsw | 126 +- win32/build/template.rc | 2 +- win32/builddef.bat | 2 +- win32/fnmatch.c | 2 +- win32/fnmatch.h | 2 +- win32/glob.c | 2 +- win32/glob.h | 2 +- win32/globals.c | 2 +- win32/grp.h | 2 +- win32/install.txt | 22 +- win32/php5.dsw | 214 +- win32/php5dll.dsp | 8 - win32/php5dllts.dsp | 8 - win32/php5dllts.rc2 | 122 +- win32/php5ts_cli.rc2 | 122 +- win32/php_win32_globals.h | 2 +- win32/readdir.c | 24 +- win32/registry.c | 4 + win32/resource.h | 30 +- win32/select.c | 2 +- win32/select.h | 2 +- win32/sendmail.c | 87 +- win32/sendmail.h | 1 + win32/sockets.c | 2 +- win32/sockets.h | 2 +- win32/syslog.h | 2 +- win32/time.c | 2 +- win32/winutil.c | 2 +- 2769 files changed, 131307 insertions(+), 102270 deletions(-) delete mode 100644 .project delete mode 100644 README.CVS-RULES create mode 100644 README.SVN-RULES create mode 100644 Zend/tests/bug48693.phpt create mode 100644 Zend/tests/bug48770.phpt create mode 100644 Zend/tests/bug48770_2.phpt create mode 100644 Zend/tests/bug48770_3.phpt create mode 100644 Zend/tests/bug48899.phpt create mode 100644 Zend/tests/bug48912.phpt create mode 100644 Zend/tests/bug49269.phpt create mode 100644 Zend/tests/bug49908.phpt create mode 100644 Zend/tests/call_user_func_001.phpt create mode 100644 Zend/tests/call_user_func_002.phpt create mode 100644 Zend/tests/call_user_func_003.phpt create mode 100644 Zend/tests/closure_034.phpt create mode 100644 Zend/tests/get_required_files.phpt create mode 100755 Zend/tests/unexpected_ref_bug.phpt delete mode 100755 cvsclean delete mode 100755 cvsclean.bat create mode 100755 ext/bcmath/tests/bcdiv_error1.phpt create mode 100644 ext/bcmath/tests/bcdiv_error2.phpt create mode 100644 ext/bcmath/tests/bcmod_error1.phpt create mode 100755 ext/bcmath/tests/bcpowmod_error1.phpt create mode 100755 ext/bcmath/tests/bcpowmod_error2.phpt create mode 100644 ext/bcmath/tests/bcpowmod_error3.phpt create mode 100755 ext/bcmath/tests/bcsqrt_error1.phpt create mode 100644 ext/com_dotnet/tests/bug45280.phpt create mode 100644 ext/curl/tests/bug48207.phpt create mode 100644 ext/curl/tests/curl_CURLOPT_READDATA.phpt create mode 100644 ext/curl/tests/curl_close_basic.phpt create mode 100644 ext/curl/tests/curl_copy_handle_basic.phpt create mode 100644 ext/curl/tests/curl_copy_handle_basic_001.phpt create mode 100644 ext/curl/tests/curl_copy_handle_basic_002.phpt create mode 100644 ext/curl/tests/curl_copy_handle_basic_004.phpt create mode 100644 ext/curl/tests/curl_copy_handle_basic_005.phpt create mode 100644 ext/curl/tests/curl_copy_handle_basic_006.phpt create mode 100644 ext/curl/tests/curl_copy_handle_basic_007.phpt create mode 100644 ext/curl/tests/curl_copy_handle_variation1.phpt create mode 100644 ext/curl/tests/curl_copy_handle_variation2.phpt create mode 100644 ext/curl/tests/curl_error_basic.phpt create mode 100644 ext/curl/tests/curl_multi_close_basic.phpt create mode 100644 ext/curl/tests/curl_multi_getcontent_basic3.phpt create mode 100644 ext/curl/tests/curl_multi_getcontent_error1.phpt create mode 100644 ext/curl/tests/curl_multi_getcontent_error2.phpt create mode 100644 ext/curl/tests/curl_multi_getcontent_error3.phpt create mode 100644 ext/curl/tests/curl_multi_getcontent_error4.phpt create mode 100644 ext/curl/tests/curl_multi_init_basic.phpt create mode 100644 ext/curl/tests/curl_multi_select_basic1.phpt create mode 100644 ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION_open_basedir.phpt create mode 100644 ext/curl/tests/curl_setopt_CURLOPT_READFUNCTION.phpt create mode 100644 ext/curl/tests/curl_setopt_array_basic.phpt create mode 100644 ext/curl/tests/curl_setopt_basic001.phpt create mode 100644 ext/curl/tests/curl_setopt_basic002.phpt create mode 100644 ext/curl/tests/curl_setopt_basic003.phpt create mode 100644 ext/curl/tests/curl_setopt_basic004.phpt create mode 100644 ext/curl/tests/curl_setopt_error.phpt create mode 100644 ext/curl/tests/curl_testdata1.txt create mode 100644 ext/curl/tests/curl_testdata2.txt create mode 100644 ext/curl/tests/curl_version_error.phpt create mode 100644 ext/curl/tests/curl_version_variation1.phpt create mode 100644 ext/curl/tests/curl_write_callback.phpt create mode 100644 ext/curl/tests/curl_write_file.phpt create mode 100644 ext/curl/tests/curl_write_return.phpt create mode 100644 ext/curl/tests/curl_write_stdout.phpt create mode 100644 ext/curl/tests/curl_writeheader_callback.phpt create mode 100644 ext/date/tests/DatePeriod_wrong_constructor.phpt create mode 100644 ext/date/tests/bug45554.phpt create mode 100644 ext/date/tests/cal_days_in_month_invalid_calendar.phpt create mode 100644 ext/date/tests/cal_days_in_month_invalid_date.phpt create mode 100644 ext/date/tests/date_timestamp_get.phpt create mode 100644 ext/date/tests/timezone_identifiers_list_wrong_constructor.phpt create mode 100644 ext/date/tests/timezone_location_get.phpt create mode 100644 ext/dba/tests/bug49125.phpt create mode 100755 ext/dom/tests/DOMAttr_value_basic_001.phpt create mode 100644 ext/dom/tests/DOMCharacterData_data_basic_002.phpt create mode 100755 ext/dom/tests/DOMCharacterData_length_error_001.phpt create mode 100644 ext/dom/tests/DOMCharacterData_substringData_basic_001.phpt create mode 100644 ext/dom/tests/DOMDocument_config_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_createEntityReference_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_documentURI_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_encoding_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_implementationRead_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_preserveWhiteSpace_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_preserveWhiteSpace_variations.phpt create mode 100644 ext/dom/tests/DOMDocument_resolveExternals_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_saveHTMLFile_error1.phpt create mode 100644 ext/dom/tests/DOMDocument_saveHTMLFile_error2.phpt create mode 100644 ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput.phpt create mode 100644 ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt create mode 100644 ext/dom/tests/DOMDocument_saveHTML_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_saveHTML_error1.phpt create mode 100644 ext/dom/tests/DOMDocument_saveHTML_error2.phpt create mode 100755 ext/dom/tests/DOMDocument_schemaValidateSource_basic.phpt create mode 100755 ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt create mode 100755 ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt create mode 100755 ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt create mode 100755 ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt create mode 100755 ext/dom/tests/DOMDocument_schemaValidate_basic.phpt create mode 100755 ext/dom/tests/DOMDocument_schemaValidate_error1.phpt create mode 100755 ext/dom/tests/DOMDocument_schemaValidate_error2.phpt create mode 100755 ext/dom/tests/DOMDocument_schemaValidate_error3.phpt create mode 100755 ext/dom/tests/DOMDocument_schemaValidate_error4.phpt create mode 100755 ext/dom/tests/DOMDocument_schemaValidate_error5.phpt create mode 100644 ext/dom/tests/DOMDocument_standalone_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_strictErrorChecking_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt create mode 100644 ext/dom/tests/DOMDocument_validate_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_validate_error1.phpt create mode 100644 ext/dom/tests/DOMDocument_validate_error2.phpt create mode 100644 ext/dom/tests/DOMDocument_validate_external_dtd.phpt create mode 100644 ext/dom/tests/DOMDocument_validate_on_parse_basic.phpt create mode 100644 ext/dom/tests/DOMDocument_validate_on_parse_variation.phpt create mode 100755 ext/dom/tests/book-non-conforming-schema.xsd create mode 100755 ext/dom/tests/book-not-a-schema.xsd create mode 100755 ext/dom/tests/book.xsd create mode 100644 ext/dom/tests/domdocument_createcomment_error_001.phpt create mode 100644 ext/dom/tests/domdocument_createentityreference_001.phpt create mode 100644 ext/dom/tests/domdocument_createentityreference_002.phpt create mode 100644 ext/filter/tests/bug48762.phpt create mode 100644 ext/filter/tests/bug49274.phpt create mode 100755 ext/ftp/tests/ftp_alloc_basic1.phpt create mode 100755 ext/ftp/tests/ftp_alloc_basic2.phpt create mode 100755 ext/ftp/tests/ftp_chmod_basic.phpt create mode 100755 ext/ftp/tests/ftp_exec_basic.phpt create mode 100644 ext/ftp/tests/ftp_fget_basic1.phpt create mode 100644 ext/ftp/tests/ftp_fget_basic2.phpt create mode 100644 ext/ftp/tests/ftp_fget_basic3.phpt create mode 100644 ext/ftp/tests/ftp_nb_fget_basic1.phpt create mode 100644 ext/ftp/tests/ftp_nb_fget_basic2.phpt create mode 100644 ext/ftp/tests/ftp_nb_fget_basic3.phpt create mode 100644 ext/ftp/tests/ftp_rawlist_basic2.phpt create mode 100755 ext/ftp/tests/ftp_rmdir_basic.phpt create mode 100644 ext/gd/tests/bug42434.phpt create mode 100644 ext/gd/tests/bug43073.phpt create mode 100644 ext/gd/tests/bug48732.phpt create mode 100644 ext/gd/tests/bug48801.phpt create mode 100644 ext/gd/tests/crafted.gd2 create mode 100644 ext/gd/tests/crafted_gd2.phpt create mode 100755 ext/gd/tests/imageantialias_error1.phpt create mode 100755 ext/gd/tests/imageantialias_error2.phpt create mode 100755 ext/gd/tests/imagearc_basic.phpt create mode 100755 ext/gd/tests/imagearc_error1.phpt create mode 100755 ext/gd/tests/imagearc_variation1.phpt create mode 100755 ext/gd/tests/imagearc_variation2.phpt create mode 100644 ext/gd/tests/imagechar_basic.phpt create mode 100644 ext/gd/tests/imagechar_error1.phpt create mode 100644 ext/gd/tests/imagechar_error2.phpt create mode 100644 ext/gd/tests/imagechar_error3.phpt create mode 100644 ext/gd/tests/imagechar_error4.phpt create mode 100644 ext/gd/tests/imagechar_error5.phpt create mode 100644 ext/gd/tests/imagechar_error6.phpt create mode 100644 ext/gd/tests/imagechar_error7.phpt create mode 100644 ext/gd/tests/imagecharup_basic.phpt create mode 100644 ext/gd/tests/imagecharup_error1.phpt create mode 100644 ext/gd/tests/imagecharup_error2.phpt create mode 100644 ext/gd/tests/imagecharup_error3.phpt create mode 100644 ext/gd/tests/imagecharup_error4.phpt create mode 100644 ext/gd/tests/imagecharup_error5.phpt create mode 100644 ext/gd/tests/imagecharup_error6.phpt create mode 100644 ext/gd/tests/imagecharup_error7.phpt create mode 100644 ext/gd/tests/imagecolorallocatealpha_basic.phpt create mode 100644 ext/gd/tests/imagecolorallocatealpha_error1.phpt create mode 100644 ext/gd/tests/imagecolorallocatealpha_error2.phpt create mode 100644 ext/gd/tests/imagecolorallocatealpha_error3.phpt create mode 100644 ext/gd/tests/imagecolorallocatealpha_error4.phpt create mode 100644 ext/gd/tests/imagecolorallocatealpha_error5.phpt create mode 100644 ext/gd/tests/imagecolordeallocate_basic.phpt create mode 100644 ext/gd/tests/imagecolordeallocate_error1.phpt create mode 100644 ext/gd/tests/imagecolordeallocate_error2.phpt create mode 100644 ext/gd/tests/imagecolordeallocate_error3.phpt create mode 100644 ext/gd/tests/imagecolordeallocate_error4.phpt create mode 100755 ext/gd/tests/imagecolormatch_basic.phpt create mode 100755 ext/gd/tests/imagecolormatch_error1.phpt create mode 100755 ext/gd/tests/imagecolormatch_error2.phpt create mode 100755 ext/gd/tests/imagecolormatch_error3.phpt create mode 100755 ext/gd/tests/imagecolormatch_error4.phpt create mode 100755 ext/gd/tests/imagecolorset_basic.phpt create mode 100755 ext/gd/tests/imageconvolution_basic.phpt create mode 100755 ext/gd/tests/imageconvolution_error1.phpt create mode 100755 ext/gd/tests/imageconvolution_error2.phpt create mode 100755 ext/gd/tests/imageconvolution_error3.phpt create mode 100755 ext/gd/tests/imagecopymerge_basic.phpt create mode 100755 ext/gd/tests/imagecopymerge_error.phpt create mode 100644 ext/gd/tests/imagecreatetruecolor_basic.phpt create mode 100644 ext/gd/tests/imagecreatetruecolor_error1.phpt create mode 100644 ext/gd/tests/imagecreatetruecolor_error2.phpt create mode 100644 ext/gd/tests/imagecreatetruecolor_error3.phpt create mode 100755 ext/gd/tests/imageellipse_basic.phpt create mode 100755 ext/gd/tests/imageellipse_error1.phpt create mode 100755 ext/gd/tests/imageellipse_error2.phpt create mode 100755 ext/gd/tests/imageellipse_error3.phpt create mode 100755 ext/gd/tests/imageellipse_error4.phpt create mode 100755 ext/gd/tests/imageellipse_error5.phpt create mode 100755 ext/gd/tests/imageellipse_error6.phpt create mode 100755 ext/gd/tests/imageellipse_error7.phpt create mode 100755 ext/gd/tests/imageellipse_error8.phpt create mode 100755 ext/gd/tests/imagefilledarc_basic.phpt create mode 100755 ext/gd/tests/imagefilledarc_error1.phpt create mode 100755 ext/gd/tests/imagefilledarc_variation1.phpt create mode 100755 ext/gd/tests/imagefilledarc_variation2.phpt create mode 100755 ext/gd/tests/imagefilltoborder_basic.phpt create mode 100755 ext/gd/tests/imagefilltoborder_error1.phpt create mode 100755 ext/gd/tests/imagefilltoborder_error2.phpt create mode 100755 ext/gd/tests/imagefilltoborder_error3.phpt create mode 100755 ext/gd/tests/imagefilltoborder_error4.phpt create mode 100755 ext/gd/tests/imagefilltoborder_error5.phpt create mode 100755 ext/gd/tests/imagefilltoborder_error6.phpt create mode 100755 ext/gd/tests/imagefilltoborder_error7.phpt create mode 100755 ext/gd/tests/imagefilter_error1.phpt create mode 100755 ext/gd/tests/imagefilter_error10.phpt create mode 100755 ext/gd/tests/imagefilter_error11.phpt create mode 100755 ext/gd/tests/imagefilter_error12.phpt create mode 100755 ext/gd/tests/imagefilter_error13.phpt create mode 100755 ext/gd/tests/imagefilter_error14.phpt create mode 100755 ext/gd/tests/imagefilter_error15.phpt create mode 100755 ext/gd/tests/imagefilter_error16.phpt create mode 100755 ext/gd/tests/imagefilter_error17.phpt create mode 100755 ext/gd/tests/imagefilter_error18.phpt create mode 100755 ext/gd/tests/imagefilter_error19.phpt create mode 100755 ext/gd/tests/imagefilter_error2.phpt create mode 100755 ext/gd/tests/imagefilter_error20.phpt create mode 100755 ext/gd/tests/imagefilter_error3.phpt create mode 100755 ext/gd/tests/imagefilter_error4.phpt create mode 100755 ext/gd/tests/imagefilter_error5.phpt create mode 100755 ext/gd/tests/imagefilter_error6.phpt create mode 100755 ext/gd/tests/imagefilter_error7.phpt create mode 100755 ext/gd/tests/imagefilter_error8.phpt create mode 100755 ext/gd/tests/imagefilter_error9.phpt create mode 100644 ext/gd/tests/imagefontheight_basic.phpt create mode 100644 ext/gd/tests/imagefontheight_error1.phpt create mode 100644 ext/gd/tests/imagefontwidth_basic.phpt create mode 100644 ext/gd/tests/imagefontwidth_error1.phpt create mode 100644 ext/gd/tests/imagegammacorrect_basic.phpt create mode 100644 ext/gd/tests/imagegammacorrect_error1.phpt create mode 100644 ext/gd/tests/imagegammacorrect_error2.phpt create mode 100644 ext/gd/tests/imagegammacorrect_error3.phpt create mode 100644 ext/gd/tests/imagegammacorrect_error4.phpt create mode 100644 ext/gd/tests/imagegammacorrect_variation1.phpt create mode 100755 ext/gd/tests/imageinterlace_basic.phpt create mode 100755 ext/gd/tests/imageinterlace_error1.phpt create mode 100755 ext/gd/tests/imageinterlace_error2.phpt create mode 100755 ext/gd/tests/imageinterlace_variation1.phpt create mode 100755 ext/gd/tests/imageinterlace_variation2.phpt create mode 100644 ext/gd/tests/imageistruecolor_basic.phpt create mode 100644 ext/gd/tests/imageistruecolor_error1.phpt create mode 100644 ext/gd/tests/imagelayereffect_basic.phpt create mode 100644 ext/gd/tests/imagelayereffect_error1.phpt create mode 100644 ext/gd/tests/imagelayereffect_error2.phpt create mode 100644 ext/gd/tests/imagelayereffect_error3.phpt create mode 100755 ext/gd/tests/imagerectangle_basic.phpt create mode 100755 ext/gd/tests/imagerectangle_error1.phpt create mode 100755 ext/gd/tests/imagerectangle_error2.phpt create mode 100755 ext/gd/tests/imagerectangle_error3.phpt create mode 100755 ext/gd/tests/imagerectangle_error4.phpt create mode 100755 ext/gd/tests/imagerectangle_error5.phpt create mode 100755 ext/gd/tests/imagerectangle_error6.phpt create mode 100755 ext/gd/tests/imagerectangle_error7.phpt create mode 100755 ext/gd/tests/imagerectangle_error8.phpt create mode 100755 ext/gd/tests/imagesetbrush_basic.phpt create mode 100644 ext/gd/tests/imagesetthickness_basic.phpt create mode 100644 ext/gd/tests/imagesetthickness_error1.phpt create mode 100644 ext/gd/tests/imagesetthickness_error2.phpt create mode 100644 ext/gd/tests/imagestring_basic.phpt create mode 100644 ext/gd/tests/imagestring_error1.phpt create mode 100644 ext/gd/tests/imagestring_error2.phpt create mode 100644 ext/gd/tests/imagestring_error3.phpt create mode 100644 ext/gd/tests/imagestring_error4.phpt create mode 100644 ext/gd/tests/imagestring_error5.phpt create mode 100644 ext/gd/tests/imagestring_error6.phpt create mode 100644 ext/gd/tests/imagestring_error7.phpt create mode 100644 ext/gd/tests/imagestringup_basic.phpt create mode 100644 ext/gd/tests/imagestringup_error1.phpt create mode 100644 ext/gd/tests/imagestringup_error2.phpt create mode 100644 ext/gd/tests/imagestringup_error3.phpt create mode 100644 ext/gd/tests/imagestringup_error4.phpt create mode 100644 ext/gd/tests/imagestringup_error5.phpt create mode 100644 ext/gd/tests/imagestringup_error6.phpt create mode 100644 ext/gd/tests/imagestringup_error7.phpt create mode 100644 ext/gd/tests/imagetruecolortopalette_basic.phpt create mode 100644 ext/gd/tests/imagetruecolortopalette_error1.phpt create mode 100644 ext/gd/tests/imagetruecolortopalette_error2.phpt create mode 100644 ext/gd/tests/imagetruecolortopalette_error3.phpt create mode 100644 ext/gd/tests/imagetruecolortopalette_error4.phpt create mode 100755 ext/gd/tests/jpeg2wbmp_error1.phpt create mode 100755 ext/gd/tests/jpeg2wbmp_error2.phpt create mode 100755 ext/gd/tests/jpeg2wbmp_error3.phpt create mode 100755 ext/gd/tests/png2wbmp_error1.phpt create mode 100755 ext/gd/tests/png2wbmp_error2.phpt create mode 100755 ext/gd/tests/png2wbmp_error3.phpt delete mode 100644 ext/gd/tests/truecolor.phpt delete mode 100644 ext/iconv/tests/bug16069.phpt create mode 100644 ext/iconv/tests/iconv_get_encoding_basic.phpt create mode 100755 ext/intl/tests/idn.phpt create mode 100644 ext/ldap/tests/README create mode 100644 ext/ldap/tests/ldap_add_basic.phpt create mode 100644 ext/ldap/tests/ldap_add_error.phpt create mode 100644 ext/ldap/tests/ldap_bind_basic.phpt create mode 100644 ext/ldap/tests/ldap_bind_error.phpt create mode 100644 ext/ldap/tests/ldap_bind_variation.phpt create mode 100644 ext/ldap/tests/ldap_compare_basic.phpt create mode 100644 ext/ldap/tests/ldap_compare_error.phpt create mode 100644 ext/ldap/tests/ldap_connect_basic.phpt create mode 100644 ext/ldap/tests/ldap_connect_error.phpt create mode 100644 ext/ldap/tests/ldap_connect_variation.phpt create mode 100644 ext/ldap/tests/ldap_count_entries_basic.phpt create mode 100644 ext/ldap/tests/ldap_count_entries_error.phpt create mode 100644 ext/ldap/tests/ldap_delete_basic.phpt create mode 100644 ext/ldap/tests/ldap_delete_error.phpt create mode 100644 ext/ldap/tests/ldap_err2str_basic.phpt create mode 100644 ext/ldap/tests/ldap_err2str_error.phpt create mode 100644 ext/ldap/tests/ldap_errno_basic.phpt create mode 100644 ext/ldap/tests/ldap_errno_error.phpt create mode 100644 ext/ldap/tests/ldap_error_basic.phpt create mode 100644 ext/ldap/tests/ldap_error_error.phpt create mode 100644 ext/ldap/tests/ldap_first_attribute_basic.phpt create mode 100644 ext/ldap/tests/ldap_first_attribute_error.phpt create mode 100644 ext/ldap/tests/ldap_first_entry_basic.phpt create mode 100644 ext/ldap/tests/ldap_first_entry_error.phpt create mode 100644 ext/ldap/tests/ldap_first_reference_basic.phpt create mode 100644 ext/ldap/tests/ldap_first_reference_error.phpt create mode 100644 ext/ldap/tests/ldap_free_result_basic.phpt create mode 100644 ext/ldap/tests/ldap_free_result_error.phpt create mode 100644 ext/ldap/tests/ldap_get_attributes_basic.phpt create mode 100644 ext/ldap/tests/ldap_get_attributes_error.phpt create mode 100644 ext/ldap/tests/ldap_get_dn_basic.phpt create mode 100644 ext/ldap/tests/ldap_get_dn_error.phpt create mode 100644 ext/ldap/tests/ldap_get_entries_basic.phpt create mode 100644 ext/ldap/tests/ldap_get_entries_error.phpt create mode 100644 ext/ldap/tests/ldap_get_entries_variation.phpt create mode 100644 ext/ldap/tests/ldap_get_option_basic.phpt create mode 100644 ext/ldap/tests/ldap_get_option_error.phpt create mode 100644 ext/ldap/tests/ldap_get_option_variation.phpt create mode 100644 ext/ldap/tests/ldap_get_values_len_basic.phpt create mode 100644 ext/ldap/tests/ldap_get_values_len_error.phpt create mode 100644 ext/ldap/tests/ldap_list_basic.phpt create mode 100644 ext/ldap/tests/ldap_list_error.phpt create mode 100644 ext/ldap/tests/ldap_mod_add_basic.phpt create mode 100644 ext/ldap/tests/ldap_mod_add_error.phpt create mode 100644 ext/ldap/tests/ldap_mod_del_basic.phpt create mode 100644 ext/ldap/tests/ldap_mod_del_error.phpt create mode 100644 ext/ldap/tests/ldap_mod_replace_basic.phpt create mode 100644 ext/ldap/tests/ldap_mod_replace_error.phpt create mode 100644 ext/ldap/tests/ldap_modify_basic.phpt create mode 100644 ext/ldap/tests/ldap_modify_error.phpt create mode 100644 ext/ldap/tests/ldap_next_attribute_basic.phpt create mode 100644 ext/ldap/tests/ldap_next_attribute_error.phpt create mode 100644 ext/ldap/tests/ldap_next_entry_basic.phpt create mode 100644 ext/ldap/tests/ldap_next_entry_error.phpt create mode 100644 ext/ldap/tests/ldap_next_reference_basic.phpt create mode 100644 ext/ldap/tests/ldap_next_reference_error.phpt create mode 100644 ext/ldap/tests/ldap_parse_reference_basic.phpt create mode 100644 ext/ldap/tests/ldap_parse_reference_error.phpt create mode 100644 ext/ldap/tests/ldap_parse_result_basic.phpt create mode 100644 ext/ldap/tests/ldap_parse_result_error.phpt create mode 100644 ext/ldap/tests/ldap_read_basic.phpt create mode 100644 ext/ldap/tests/ldap_read_error.phpt create mode 100644 ext/ldap/tests/ldap_rename_basic.phpt create mode 100644 ext/ldap/tests/ldap_rename_error.phpt create mode 100644 ext/ldap/tests/ldap_sasl_bind_basic.phpt create mode 100644 ext/ldap/tests/ldap_sasl_bind_error.phpt create mode 100644 ext/ldap/tests/ldap_search_basic.phpt create mode 100644 ext/ldap/tests/ldap_search_error.phpt create mode 100644 ext/ldap/tests/ldap_search_variation1.phpt create mode 100644 ext/ldap/tests/ldap_search_variation2.phpt create mode 100644 ext/ldap/tests/ldap_search_variation3.phpt create mode 100644 ext/ldap/tests/ldap_search_variation4.phpt create mode 100644 ext/ldap/tests/ldap_search_variation5.phpt create mode 100644 ext/ldap/tests/ldap_search_variation6.phpt create mode 100644 ext/ldap/tests/ldap_set_option_basic.phpt create mode 100644 ext/ldap/tests/ldap_set_option_error.phpt create mode 100644 ext/ldap/tests/ldap_set_option_variation.phpt create mode 100644 ext/ldap/tests/ldap_set_rebind_proc_basic.phpt create mode 100644 ext/ldap/tests/ldap_set_rebind_proc_error.phpt create mode 100644 ext/ldap/tests/ldap_sort_basic.phpt create mode 100644 ext/ldap/tests/ldap_sort_error.phpt create mode 100644 ext/ldap/tests/ldap_sort_variation.phpt create mode 100644 ext/ldap/tests/ldap_start_tls_basic.phpt create mode 100644 ext/ldap/tests/ldap_start_tls_error.phpt create mode 100644 ext/ldap/tests/ldap_unbind_basic.phpt create mode 100644 ext/ldap/tests/ldap_unbind_error.phpt create mode 100644 ext/ldap/tests/ldap_unbind_variation.phpt create mode 100644 ext/mbstring/tests/bug46806.phpt create mode 100644 ext/mbstring/tests/bug48645.phpt create mode 100644 ext/mbstring/tests/mb_convert_kana.phpt create mode 100644 ext/mbstring/tests/mb_decode_numericentity.phpt create mode 100644 ext/mbstring/tests/mb_encode_numericentity.phpt create mode 100644 ext/mbstring/tests/mb_ereg3.phpt create mode 100644 ext/mbstring/tests/mb_ereg4.phpt create mode 100755 ext/mbstring/tests/mb_ereg_search.phpt create mode 100644 ext/mbstring/tests/mb_ereg_search_pos.phpt create mode 100644 ext/mbstring/tests/mb_ereg_search_regs.phpt create mode 100644 ext/mbstring/tests/mb_eregi.phpt create mode 100644 ext/mbstring/tests/mb_eregi_invalid_arguments.phpt create mode 100644 ext/mbstring/tests/mb_eregi_replace.phpt create mode 100644 ext/mcrypt/tests/bug49738.phpt create mode 100644 ext/mysql/tests/bug48754.phpt create mode 100644 ext/mysql/tests/clean_table.inc create mode 100644 ext/mysql/tests/mysql_mysqlnd_read_timeout_long.phpt create mode 100755 ext/mysql/tests/skipifdefaultconnectfailure.inc create mode 100644 ext/mysqli/tests/bug46614.phpt create mode 100644 ext/mysqli/tests/bug48909.phpt create mode 100644 ext/mysqli/tests/bug49027.phpt create mode 100644 ext/mysqli/tests/bug49442.phpt create mode 100644 ext/mysqli/tests/clean_table.inc create mode 100644 ext/mysqli/tests/mysqli_fetch_array_large.phpt create mode 100644 ext/mysqli/tests/mysqli_get_cache_stats_off.phpt create mode 100644 ext/mysqli/tests/mysqli_get_connection_stats_off.phpt create mode 100644 ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt create mode 100644 ext/mysqli/tests/mysqli_mysqlnd_read_timeout_long.phpt create mode 100644 ext/mysqli/tests/mysqli_mysqlnd_read_timeout_zero.phpt create mode 100644 ext/mysqli/tests/mysqli_ps_select_union.phpt create mode 100644 ext/mysqli/tests/mysqli_query_local_infile_large.phpt create mode 100644 ext/mysqli/tests/mysqli_stmt_fetch_geom.phpt create mode 100644 ext/mysqli/tests/mysqli_stmt_get_result_geom.phpt create mode 100644 ext/oci8/tests/pecl_bug16842.phpt create mode 100644 ext/openssl/tests/bug48182.phpt create mode 100644 ext/pcntl/tests/pcntl_fork_basic.phpt create mode 100644 ext/pcntl/tests/pcntl_fork_variation.phpt create mode 100644 ext/pdo/tests/pdo_036.phpt create mode 100644 ext/pdo_sqlite/tests/bug48773.phpt create mode 100644 ext/phar/tests/bug48377.2.phpt create mode 100644 ext/phar/tests/bug48377.phpt create mode 100644 ext/phar/tests/fopen_edgecases2U.phpt delete mode 100644 ext/phar/tests/ini_setU.phpt delete mode 100644 ext/phar/tests/phar_buildfromiterator10U.phpt delete mode 100644 ext/phar/tests/phar_bz2U.phpt create mode 100644 ext/phar/tests/readfile_edgecasesU.phpt create mode 100644 ext/phar/tests/tar/bug49910.phpt create mode 100644 ext/phar/tests/tar/files/P1-1.0.0.tgz create mode 100644 ext/phar/tests/tar/files/P1-1.0.0.tgz.pubkey create mode 100644 ext/phar/tests/tar/files/Structures_Graph-1.0.3.tgz create mode 100644 ext/phar/tests/tar/tar_openssl_hash.phpt create mode 100644 ext/phar/tests/zip/bug48791.phpt create mode 100644 ext/phar/tests/zip/files/test.odt create mode 100644 ext/phar/tests/zip/phar_setsignaturealgo2.phpt create mode 100644 ext/posix/tests/posix_ctermid_basic.phpt create mode 100644 ext/posix/tests/posix_ctermid_error.phpt create mode 100644 ext/posix/tests/posix_errno_basic.phpt create mode 100644 ext/posix/tests/posix_errno_error.phpt create mode 100644 ext/posix/tests/posix_errno_variation1.phpt create mode 100644 ext/posix/tests/posix_errno_variation2.phpt create mode 100644 ext/posix/tests/posix_geteuid_basic.phpt create mode 100644 ext/posix/tests/posix_geteuid_error1.phpt create mode 100644 ext/posix/tests/posix_seteuid_basic.phpt create mode 100644 ext/posix/tests/posix_seteuid_error.phpt create mode 100644 ext/posix/tests/posix_seteuid_error2.phpt create mode 100644 ext/posix/tests/posix_seteuid_variation1.phpt create mode 100644 ext/posix/tests/posix_seteuid_variation2.phpt create mode 100644 ext/posix/tests/posix_seteuid_variation3.phpt create mode 100644 ext/posix/tests/posix_seteuid_variation4.phpt create mode 100644 ext/posix/tests/posix_seteuid_variation5.phpt create mode 100644 ext/posix/tests/posix_seteuid_variation6.phpt create mode 100644 ext/posix/tests/posix_setgid_basic.phpt create mode 100644 ext/posix/tests/posix_setgid_error.phpt create mode 100644 ext/posix/tests/posix_setgid_variation1.phpt create mode 100644 ext/posix/tests/posix_setgid_variation2.phpt create mode 100644 ext/posix/tests/posix_setgid_variation3.phpt create mode 100644 ext/posix/tests/posix_setgid_variation4.phpt create mode 100644 ext/posix/tests/posix_setgid_variation5.phpt create mode 100644 ext/posix/tests/posix_setgid_variation6.phpt create mode 100644 ext/posix/tests/posix_setgid_variation7.phpt create mode 100644 ext/posix/tests/posix_setuid_basic.phpt create mode 100644 ext/posix/tests/posix_setuid_error.phpt create mode 100644 ext/posix/tests/posix_setuid_error2.phpt create mode 100644 ext/posix/tests/posix_setuid_variation1.phpt create mode 100644 ext/posix/tests/posix_setuid_variation2.phpt create mode 100644 ext/posix/tests/posix_setuid_variation3.phpt create mode 100644 ext/posix/tests/posix_setuid_variation4.phpt create mode 100644 ext/posix/tests/posix_setuid_variation5.phpt create mode 100644 ext/posix/tests/posix_setuid_variation6.phpt create mode 100644 ext/posix/tests/posix_ttyname_error.phpt create mode 100644 ext/posix/tests/posix_ttyname_variation1.phpt create mode 100644 ext/posix/tests/posix_ttyname_variation2.phpt create mode 100644 ext/posix/tests/posix_ttyname_variation3.phpt create mode 100644 ext/posix/tests/posix_ttyname_variation4.phpt create mode 100644 ext/posix/tests/posix_ttyname_variation5.phpt create mode 100644 ext/posix/tests/posix_ttyname_variation6.phpt create mode 100644 ext/posix/tests/posix_ttyname_variation7.phpt create mode 100644 ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt create mode 100644 ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt create mode 100644 ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt create mode 100644 ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt create mode 100644 ext/reflection/tests/bug47254.phpt create mode 100644 ext/reflection/tests/bug48757.phpt create mode 100644 ext/reflection/tests/bug49074.phpt create mode 100644 ext/reflection/tests/bug49092.phpt create mode 100644 ext/session/tests/031.phpt create mode 100644 ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt create mode 100644 ext/soap/tests/bugs/bug47273.phpt create mode 100644 ext/sockets/tests/bug46360.phpt create mode 100644 ext/sockets/tests/socket_bind.phpt create mode 100644 ext/sockets/tests/socket_bind_params.phpt create mode 100644 ext/sockets/tests/socket_close_params.phpt create mode 100644 ext/sockets/tests/socket_connect_error.phpt create mode 100644 ext/sockets/tests/socket_connect_params.phpt create mode 100644 ext/sockets/tests/socket_create_listen_params.phpt create mode 100644 ext/sockets/tests/socket_create_listen_used.phpt create mode 100644 ext/sockets/tests/socket_create_params.phpt create mode 100644 ext/sockets/tests/socket_getpeername.phpt create mode 100644 ext/sockets/tests/socket_getpeername_ipv4loop.phpt create mode 100644 ext/sockets/tests/socket_getpeername_ipv6loop.phpt create mode 100644 ext/sockets/tests/socket_getsockname.phpt create mode 100644 ext/sockets/tests/socket_listen_params.phpt create mode 100644 ext/sockets/tests/socket_read_params.phpt create mode 100644 ext/sockets/tests/socket_set_nonblock.phpt create mode 100644 ext/sockets/tests/socket_strerror.phpt create mode 100644 ext/sockets/tests/socket_write_params.phpt create mode 100644 ext/spl/tests/ArrayObject_unserialize_empty_string.phpt create mode 100644 ext/spl/tests/DirectoryIterator_by_reference.phpt create mode 100644 ext/spl/tests/DirectoryIterator_empty_constructor.phpt create mode 100644 ext/spl/tests/DirectoryIterator_getGroup_basic.phpt create mode 100644 ext/spl/tests/DirectoryIterator_getInode_basic.phpt create mode 100644 ext/spl/tests/DirectoryIterator_getInode_error.phpt create mode 100644 ext/spl/tests/DirectoryIterator_getOwner_basic.phpt delete mode 100644 ext/spl/tests/SplDoublyLinkedList_shift_noParams.phpt create mode 100644 ext/spl/tests/SplFileInfo_getGroup_basic.phpt create mode 100644 ext/spl/tests/SplFileInfo_getGroup_error.phpt create mode 100644 ext/spl/tests/SplFileInfo_getInode_basic.phpt create mode 100644 ext/spl/tests/SplFileInfo_getInode_error.phpt create mode 100644 ext/spl/tests/SplFileInfo_getOwner_basic.phpt create mode 100644 ext/spl/tests/SplFileInfo_getOwner_error.phpt create mode 100644 ext/spl/tests/SplFileInfo_getPerms_basic.phpt create mode 100644 ext/spl/tests/SplFileInfo_getPerms_error.phpt delete mode 100644 ext/spl/tests/SplFixedarray_offsetExists_larger.phpt create mode 100644 ext/spl/tests/SplObjectStorage_var_dump.phpt create mode 100644 ext/spl/tests/array_027.phpt create mode 100644 ext/spl/tests/bug44144.phpt create mode 100644 ext/spl/tests/dllist_012.phpt create mode 100644 ext/spl/tests/heap_012.phpt create mode 100644 ext/spl/tests/splDoublyLinkedList_shift_noParams.phpt create mode 100644 ext/spl/tests/spl_autoload_013.phpt create mode 100644 ext/spl/tests/spl_autoload_014.phpt create mode 100644 ext/spl/tests/splfixedarray_offsetExists_larger.phpt create mode 100644 ext/sqlite/tests/sqlitedatabase_arrayquery.phpt delete mode 100644 ext/standard/dns.h create mode 100644 ext/standard/php_dns.h create mode 100644 ext/standard/tests/array/bug48854.phpt create mode 100644 ext/standard/tests/array/key_exists_basic.phpt create mode 100644 ext/standard/tests/array/key_exists_error.phpt create mode 100644 ext/standard/tests/array/key_exists_variation1.phpt create mode 100644 ext/standard/tests/array/key_exists_variation2.phpt create mode 100644 ext/standard/tests/array/max_basiclong_64bit.phpt create mode 100644 ext/standard/tests/array/min_basiclong_64bit.phpt create mode 100755 ext/standard/tests/array/unexpected_array_mod_bug.phpt create mode 100644 ext/standard/tests/file/bug43353-win32.phpt create mode 100644 ext/standard/tests/file/bug49047.phpt create mode 100644 ext/standard/tests/file/file_get_contents_basic001.phpt create mode 100644 ext/standard/tests/file/file_get_contents_error001.phpt create mode 100644 ext/standard/tests/file/file_get_contents_error002.phpt delete mode 100644 ext/standard/tests/file/glob_error_002.phpt create mode 100644 ext/standard/tests/file/lchgrp_basic.phpt create mode 100644 ext/standard/tests/file/rename_variation6-win32.phpt create mode 100644 ext/standard/tests/file/rename_variation7-win32.phpt create mode 100644 ext/standard/tests/general_functions/.getservbyport_basic.phpt.swp create mode 100644 ext/standard/tests/general_functions/bug48660.phpt create mode 100644 ext/standard/tests/general_functions/bug48768.phpt create mode 100644 ext/standard/tests/general_functions/bug49056.phpt create mode 100644 ext/standard/tests/general_functions/get_cfg_var_basic.phpt create mode 100644 ext/standard/tests/general_functions/get_cfg_var_error.phpt create mode 100644 ext/standard/tests/general_functions/get_cfg_var_variation1.phpt create mode 100644 ext/standard/tests/general_functions/get_cfg_var_variation2.phpt create mode 100644 ext/standard/tests/general_functions/get_cfg_var_variation3.phpt create mode 100644 ext/standard/tests/general_functions/get_cfg_var_variation4.phpt create mode 100644 ext/standard/tests/general_functions/get_cfg_var_variation5.phpt create mode 100644 ext/standard/tests/general_functions/get_cfg_var_variation6.phpt create mode 100644 ext/standard/tests/general_functions/get_cfg_var_variation7.phpt create mode 100644 ext/standard/tests/general_functions/get_cfg_var_variation8.phpt create mode 100644 ext/standard/tests/general_functions/get_cfg_var_variation9.phpt create mode 100644 ext/standard/tests/general_functions/get_defined_constants_basic.phpt create mode 100644 ext/standard/tests/general_functions/get_defined_constants_error.phpt create mode 100644 ext/standard/tests/general_functions/get_loaded_extensions_basic.phpt create mode 100644 ext/standard/tests/general_functions/get_loaded_extensions_error.phpt create mode 100644 ext/standard/tests/general_functions/get_resource_type_basic.phpt create mode 100644 ext/standard/tests/general_functions/get_resource_type_error.phpt create mode 100644 ext/standard/tests/general_functions/get_resource_type_variation1.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_basic.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_error.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation1.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation10.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation11.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation12.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation13.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation14.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation2.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation3.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation4.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation5.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation6.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation7.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation8.phpt create mode 100755 ext/standard/tests/general_functions/getservbyname_variation9.phpt create mode 100644 ext/standard/tests/general_functions/getservbyport_basic.phpt create mode 100644 ext/standard/tests/general_functions/getservbyport_error.phpt create mode 100644 ext/standard/tests/general_functions/getservbyport_variation1.phpt create mode 100644 ext/standard/tests/general_functions/is_resource_basic.phpt create mode 100644 ext/standard/tests/general_functions/is_resource_error.phpt create mode 100644 ext/standard/tests/general_functions/isset_basic1.phpt create mode 100644 ext/standard/tests/general_functions/isset_basic2.phpt create mode 100644 ext/standard/tests/general_functions/proc_nice_basic.phpt create mode 100644 ext/standard/tests/general_functions/proc_nice_error.phpt create mode 100644 ext/standard/tests/general_functions/proc_nice_variation1.phpt create mode 100644 ext/standard/tests/general_functions/proc_nice_variation2.phpt create mode 100644 ext/standard/tests/general_functions/proc_nice_variation3.phpt create mode 100644 ext/standard/tests/general_functions/proc_nice_variation5.phpt create mode 100644 ext/standard/tests/general_functions/proc_nice_variation6.phpt create mode 100644 ext/standard/tests/general_functions/proc_nice_variation7.phpt create mode 100644 ext/standard/tests/general_functions/sleep_basic.phpt create mode 100644 ext/standard/tests/general_functions/sleep_error.phpt create mode 100644 ext/standard/tests/general_functions/uniqid_basic.phpt create mode 100644 ext/standard/tests/general_functions/uniqid_error.phpt create mode 100644 ext/standard/tests/general_functions/usleep_basic.phpt create mode 100644 ext/standard/tests/general_functions/usleep_error.phpt create mode 100644 ext/standard/tests/http/bug43510.phpt create mode 100644 ext/standard/tests/http/bug48929.phpt create mode 100644 ext/standard/tests/misc/time_sleep_until_basic.phpt create mode 100644 ext/standard/tests/misc/time_sleep_until_error1.phpt create mode 100644 ext/standard/tests/misc/time_sleep_until_error2.phpt create mode 100644 ext/standard/tests/misc/time_sleep_until_error3.phpt create mode 100644 ext/standard/tests/network/gethostbyaddr_basic1.phpt create mode 100644 ext/standard/tests/network/gethostbyname_basic003.phpt create mode 100644 ext/standard/tests/network/gethostbynamel_basic1.phpt create mode 100644 ext/standard/tests/php_ini_loaded_file.phpt create mode 100644 ext/standard/tests/php_logo_guid.phpt create mode 100644 ext/standard/tests/php_real_logo_guid.phpt create mode 100644 ext/standard/tests/streams/stream_is_local.phpt create mode 100644 ext/standard/tests/strings/bug47481.phpt create mode 100644 ext/standard/tests/strings/bug48709.phpt create mode 100644 ext/standard/tests/strings/bug50052.phpt create mode 100644 ext/standard/tests/strings/md5_basic1.phpt create mode 100644 ext/standard/tests/strings/md5_basic2.phpt create mode 100644 ext/standard/tests/strings/md5_error.phpt delete mode 100644 ext/standard/tests/strings/money_format_basic2.phpt delete mode 100644 ext/standard/tests/strings/money_format_basic3.phpt create mode 100644 ext/standard/tests/strings/show_source_basic.phpt create mode 100644 ext/standard/tests/strings/show_source_variation1.phpt create mode 100644 ext/standard/tests/strings/show_source_variation2.phpt create mode 100644 ext/standard/tests/strings/soundex_basic.phpt create mode 100644 ext/standard/tests/strings/soundex_error.phpt create mode 100644 ext/standard/tests/strings/str_replace_basic.phpt create mode 100644 ext/standard/tests/strings/str_replace_error.phpt create mode 100644 ext/standard/tests/strings/str_replace_variation1.phpt create mode 100644 ext/standard/tests/strings/str_replace_variation2.phpt create mode 100644 ext/standard/tests/strings/str_replace_variation3.phpt create mode 100644 ext/standard/tests/strings/str_rot13_basic.phpt create mode 100644 ext/standard/tests/strings/str_rot13_error.phpt create mode 100644 ext/standard/tests/strings/strnatcasecmp_error.phpt create mode 100644 ext/standard/tests/strings/strnatcmp_basic.phpt create mode 100644 ext/standard/tests/strings/strnatcmp_error.phpt create mode 100644 ext/standard/tests/url/get_headers_error_001.phpt create mode 100644 ext/standard/tests/url/get_headers_error_002.phpt create mode 100644 ext/standard/tests/zend_logo_guid.phpt delete mode 100644 ext/standard/url_scanner.c delete mode 100644 ext/standard/url_scanner.h delete mode 100644 ext/sybase_ct/tests/index.php create mode 100644 ext/tidy/tests/030.phpt create mode 100644 ext/tidy/tests/031.phpt create mode 100644 ext/tidy/tests/032.phpt create mode 100644 ext/tidy/tests/033.phpt create mode 100644 ext/tidy/tests/034.phpt create mode 100644 ext/tidy/tests/tidy_error1.phpt create mode 100644 ext/zip/tests/bug49072.phpt create mode 100644 ext/zip/tests/bug49072.zip create mode 100644 ext/zip/tests/oo_getstatusstring.phpt create mode 100644 ext/zip/tests/zip_open_error.phpt create mode 100644 ext/zlib/tests/zlib_filter_deflate2.phpt create mode 100755 svnclean.bat create mode 100644 tests/basic/bug45986.phpt create mode 100644 tests/basic/php_egg_logo_guid.phpt create mode 100644 tests/basic/php_logo_guid.phpt create mode 100644 tests/basic/php_real_logo_guid.phpt create mode 100644 tests/basic/zend_logo_guid.phpt create mode 100644 tests/lang/bug44827.phpt create mode 100755 vcsclean create mode 100644 win32/build/svnclean.js (limited to 'ext/ereg/php_regex.h') diff --git a/.gdbinit b/.gdbinit index 4a17d5089..9d9633169 100644 --- a/.gdbinit +++ b/.gdbinit @@ -15,6 +15,25 @@ document ____executor_globals ZTS detection is automatically based on ext/standard module struct end +define print_cvs + ____executor_globals + set $p = $eg.current_execute_data.CVs + set $c = $eg.current_execute_data.op_array.last_var + set $v = $eg.current_execute_data.op_array.vars + set $i = 0 + + printf "Compiled variables count: %d\n", $c + while $i < $c + printf "%d = %s\n", $i, $v[$i].name + if $p[$i] != 0 + printzv *$p[$i] + else + printf "*uninitialized*\n" + end + set $i = $i + 1 + end +end + define dump_bt set $t = $arg0 while $t diff --git a/.project b/.project deleted file mode 100644 index 01d843e71..000000000 --- a/.project +++ /dev/null @@ -1,11 +0,0 @@ - - - php-5.3 - - - - - - - - diff --git a/CODING_STANDARDS b/CODING_STANDARDS index 5fe00ddd4..ae8ee0419 100644 --- a/CODING_STANDARDS +++ b/CODING_STANDARDS @@ -59,8 +59,8 @@ Exceptions: you're calling. 7. When commenting out code using a #if statement, do NOT use 0 only. Instead - use "_0". For example, #if FOO_0, where FOO is your - cvs user foo. This allows easier tracking of why code was commented out, + use "_0". For example, #if FOO_0, where FOO is your + svn user foo. This allows easier tracking of why code was commented out, especially in bundled libraries. 8. Do not define functions that are not available. For instance, if a @@ -259,7 +259,7 @@ 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. + Ongoing status notes which may not be appropriate for SVN comments. Aliases & Legacy Documentation ----------------------------------- diff --git a/INSTALL b/INSTALL index 053045376..f9c16f6bb 100644 --- a/INSTALL +++ b/INSTALL @@ -391,7 +391,7 @@ Apache 2.0 on Unix systems http://snaps.php.net/php5-latest.tar.gz or download binaries for Windows http://snaps.php.net/win32/php5-win32-latest.zip. * a prerelease version downloadable from http://qa.php.net/. - * you have always the option to obtain PHP through anonymous CVS. + * you have always the option to obtain PHP through SVN. These versions of PHP are compatible to Apache 2.0.40 and later. @@ -1308,8 +1308,8 @@ Introduction to PECL Installations When building PHP modules, it's important to have known-good versions of the required tools (autoconf, automake, libtool, etc.) See the - Anonymous CVS Instructions for details on the required tools, and - required versions. + SVN Instructions for details on the required tools, and required + versions. __________________________________________________________________ Downloading PECL extensions @@ -1325,14 +1325,11 @@ Downloading PECL extensions PECL extensions that have releases listed on the PECL web site are available for download and installation using the pecl command. Specific revisions may also be specified. - * CVS - Most PECL extensions also reside in CVS. A web-based view may be - seen at http://cvs.php.net/pecl/. To download straight from CVS, - the following sequence of commands may be used. Note that phpfi is - the password for user cvsread: + * SVN + All PECL files reside in SVN. A web-based view may be seen at + http://svn.php.net/pecl/. To download straight from SVN, use: -$ cvs -d:pserver:cvsread@cvs.php.net:/repository login -$ cvs -d:pserver:cvsread@cvs.php.net:/repository co pecl/extname +$ svn co http://svn.php.net/repository/pecl//trunk * Windows downloads Windows users may find compiled PECL binaries by downloading the @@ -1380,7 +1377,7 @@ Compiling shared PECL extensions with phpize Sometimes, using the pecl installer is not an option. This could be because you're behind a firewall, or it could be because the extension you want to install is not available as a PECL compatible package, such - as unreleased extensions from CVS. If you need to build such an + as unreleased extensions from SVN. If you need to build such an extension, you can use the lower-level build tools to perform the build manually. @@ -1527,7 +1524,7 @@ The configuration file directives are documented in the manual though. For a complete list of directives available in your PHP version, please read your well commented php.ini file. Alternatively, you may find the the latest - php.ini from CVS helpful too. + php.ini from SVN helpful too. Example 6-1. php.ini example ; any text on a line after an unquoted semicolon (;) is ignored diff --git a/Makefile.global b/Makefile.global index 6a62d7247..36d9e424d 100644 --- a/Makefile.global +++ b/Makefile.global @@ -89,14 +89,14 @@ test: all elif test ! -z "$(SAPI_CLI_PATH)" && test -x "$(SAPI_CLI_PATH)"; then \ INI_FILE=`$(top_builddir)/$(SAPI_CLI_PATH) -d 'display_errors=stderr' -r 'echo php_ini_loaded_file();' 2> /dev/null`; \ if test "$$INI_FILE"; then \ - $(EGREP) -v '^(zend_)?extension(_debug)?(_ts)?[\t\ ]*=' "$$INI_FILE" > $(top_builddir)/tmp-php.ini; \ + $(EGREP) -v '^(magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?)[\t\ ]*=' "$$INI_FILE" > $(top_builddir)/tmp-php.ini; \ else \ echo > $(top_builddir)/tmp-php.ini; \ fi; \ INI_SCANNED_PATH=`$(top_builddir)/$(SAPI_CLI_PATH) -d 'display_errors=stderr' -r '$$a = explode(",\n", trim(php_ini_scanned_files())); echo $$a[0];' 2> /dev/null`; \ if test "$$INI_SCANNED_PATH"; then \ INI_SCANNED_PATH=`$(top_srcdir)/build/shtool path -d $$INI_SCANNED_PATH`; \ - $(EGREP) -h -v '^(zend_)?extension(_debug)?(_ts)?[\t\ ]*=' "$$INI_SCANNED_PATH"/*.ini >> $(top_builddir)/tmp-php.ini; \ + $(EGREP) -h -v '^(magic_quotes_(gpc|runtime|sybase)?|(zend_)?extension(_debug)?(_ts)?)[\t\ ]*=' "$$INI_SCANNED_PATH"/*.ini >> $(top_builddir)/tmp-php.ini; \ fi; \ TEST_PHP_EXECUTABLE=$(top_builddir)/$(SAPI_CLI_PATH) \ TEST_PHP_SRCDIR=$(top_srcdir) \ @@ -115,9 +115,8 @@ clean: rm -f libphp$(PHP_MAJOR_VERSION).la $(SAPI_CLI_PATH) $(OVERALL_TARGET) modules/* libs/* distclean: clean - rm -f config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h stamp-h php5.spec sapi/apache/libphp$(PHP_MAJOR_VERSION).module buildmk.stamp + rm -f Makefile config.cache config.log config.status Makefile.objects Makefile.fragments libtool main/php_config.h stamp-h sapi/apache/libphp$(PHP_MAJOR_VERSION).module buildmk.stamp $(EGREP) define'.*include/php' $(top_srcdir)/configure | $(SED) 's/.*>//'|xargs rm -f - find . -name Makefile | xargs rm -f .PHONY: all clean install distclean test .NOEXPORT: diff --git a/NEWS b/NEWS index 7e55483ac..18ec48211 100644 --- a/NEWS +++ b/NEWS @@ -1,5 +1,253 @@ PHP NEWS ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| +19 Nov 2009, PHP 5.3.1 + +- Added "max_file_uploads" INI directive, which can be set to limit the + number of file uploads per-request to 20 by default, to prevent possible + DOS via temporary file exhaustion. (Ilia) +- Added missing sanity checks around exif processing. (Ilia) +- Added error constant when json_encode() detects an invalid UTF-8 sequence. + (Scott) +- Added support for ACL on Windows for thread safe SAPI (Apache2 for example) + and fix its support on NTS. (Pierre) + +- Upgraded bundled sqlite to version 3.6.19. (Scott) +- Updated timezone database to version 2009.17 (2009q). (Derick) + +- Fixed crash in com_print_typeinfo when an invalid typelib is given. (Pierre) +- Fixed a safe_mode bypass in tempnam() identified by Grzegorz Stachowiak. + (Rasmus) +- Fixed a open_basedir bypass in posix_mkfifo() identified by Grzegorz + Stachowiak. (Rasmus) +- Fixed certificate validation inside php_openssl_apply_verification_policy + (Ryan Sleevi, Ilia) +- Fixed crash in SQLiteDatabase::ArrayQuery() and SQLiteDatabase::SingleQuery() + when calling using Reflection. (Felipe) +- Fixed crash when instantiating PDORow and PDOStatement through Reflection. + (Felipe) +- Fixed sanity check for the color index in imagecolortransparent. (Pierre) +- Fixed scandir/readdir when used mounted points on Windows. (Pierre) +- Fixed zlib.deflate compress filter to actually accept level parameter. (Jani) +- Fixed leak on error in popen/exec (and related functions) on Windows. + (Pierre) +- Fixed possible bad caching of symlinked directories in the realpath cache + on Windows. (Pierre) +- Fixed atime and mtime in stat related functions on Windows. (Pierre) +- Fixed spl_autoload_unregister/spl_autoload_functions wrt. Closures and + Functors. (Christian Seiler) +- Fixed open_basedir circumvention for "mail.log" ini directive. + (Maksymilian Arciemowicz, Stas) +- Fixed signature generation/validation for zip archives in ext/phar. (Greg) +- Fixed memory leak in stream_is_local(). (Felipe, Tony) +- Fixed BC break in mime_content_type(), removes the content encoding. (Scott) + +- Changed ini file directives [PATH=](on Win32) and [HOST=](on all) to be case + insensitive (garretts) +- Restored shebang line check to CGI sapi (not checked by scanner anymore). + (Jani) + +- Improve symbolic, mounted volume and junctions support for realpath on + Windows. (Pierre) +- Improved readlink on Windows, suppress \??\ and use the drive syntax only. + (Pierre) +- Improved dns_get_record() AAAA support on windows. Always available when + IPv6 is support is installed, format is now the same than on unix. (Pierre) +- Improved the DNS functions on OSX to use newer APIs, also use Bind 9 API + where available on other platforms. (Scott) +- Improved shared extension loading on OSX to use the standard Unix dlopen() + API. (Scott) + +- Fixed bug #50063 (safe_mode_include_dir fails). (Johannes, christian at + elmerot dot se) +- Fixed bug #50052 (Different Hashes on Windows and Linux on wrong Salt size). + (Pierre) +- Fixed bug #49910 (no support for ././@LongLink for long filenames in phar + tar support). (Greg) +- Fixed bug #49908 (throwing exception in __autoload crashes when interface + is not defined). (Felipe) +- Fixed bug #49847 (exec() fails to return data inside 2nd parameter, given + output lines >4095 bytes). (Ilia) +- Fixed bug #49809 (time_sleep_until() is not available on OpenSolaris). (Jani) +- Fixed bug #49757 (long2ip() can return wrong value in a multi-threaded + applications). (Ilia, Florian Anderiasch) +- Fixed bug #49738 (calling mcrypt after mcrypt_generic_deinit crashes). + (Sriram Natarajan) +- Fixed bug #49732 (crashes when using fileinfo when timestamp conversion + fails). (Pierre) +- Fixed bug #49698 (Unexpected change in strnatcasecmp()). (Rasmus) +- Fixed bug #49630 (imap_listscan function missing). (Felipe) +- Fixed bug #49572 (use of C++ style comments causes build failure). + (Sriram Natarajan) +- Fixed bug #49531 (CURLOPT_INFILESIZE sometimes causes warning "CURLPROTO_FILE + cannot be set"). (Felipe) +- Fixed bug #49517 (cURL's CURLOPT_FILE prevents file from being deleted after + fclose). (Ilia) +- Fixed bug #49470 (FILTER_SANITIZE_EMAIL allows disallowed characters). + (Ilia) +- Fixed bug #49447 (php engine need to correctly check for socket API + return status on windows). (Sriram Natarajan) +- Fixed bug #49391 (ldap.c utilizing deprecated ldap_modify_s). (Ilia) +- Fixed bug #49361 (wordwrap() wraps incorrectly on end of line boundaries). + (Ilia, code-it at mail dot ru) +- Fixed bug #49372 (segfault in php_curl_option_curl). (Pierre) +- Fixed bug #49306 (inside pdo_mysql default socket settings are ignored). + (Ilia) +- Fixed bug #49289 (bcmath module doesn't compile with phpize configure). + (Jani) +- Fixed bug #49286 (php://input (php_stream_input_read) is broken). (Jani) +- Fixed bug #49269 (Ternary operator fails on Iterator object when used inside + foreach declaration). (Etienne, Dmitry) +- Fixed bug #49236 (Missing PHP_SUBST(PDO_MYSQL_SHARED_LIBADD)). (Jani) +- Fixed bug #49223 (Inconsistency using get_defined_constants). (Garrett) +- Fixed bug #49193 (gdJpegGetVersionString() inside gd_compact identifies + wrong type in declaration). (Ilia) +- Fixed bug #49183 (dns_get_record does not return NAPTR records). (Pierre) +- Fixed bug #49144 (Import of schema from different host transmits original + authentication details). (Dmitry) +- Fixed bug #49142 (crash when exception thrown from __tostring()). + (David Soria Parra) +- Fixed bug #49986 (Missing ICU DLLs on windows package). (Pierre) +- Fixed bug #49132 (posix_times returns false without error). + (phpbugs at gunnu dot us) +- Fixed bug #49125 (Error in dba_exists C code). (jdornan at stanford dot edu) +- Fixed bug #49122 (undefined reference to mysqlnd_stmt_next_result on compile + with --with-mysqli and MySQL 6.0). (Jani) +- Fixed bug #49108 (2nd scan_dir produces segfault). (Felipe) +- Fixed bug #49098 (mysqli segfault on error). (Rasmus) +- Fixed bug #49095 (proc_get_status['exitcode'] fails on win32). (Felipe) +- Fixed bug #49092 (ReflectionFunction fails to work with functions in fully + qualified namespaces). (Kalle, Jani) +- Fixed bug #49074 (private class static fields can be modified by using + reflection). (Jani) +- Fixed bug #49072 (feof never returns true for damaged file in zip). (Pierre) +- Fixed bug #49065 ("disable_functions" php.ini option does not work on + Zend extensions). (Stas) +- Fixed bug #49064 (--enable-session=shared does not work: undefined symbol: + php_url_scanner_reset_vars). (Jani) +- Fixed bug #49056 (parse_ini_file() regression in 5.3.0 when using non-ASCII + strings as option keys). (Jani) +- Fixed bug #49052 (context option headers freed too early when using + --with-curlwrappers). (Jani) +- Fixed bug #49047 (The function touch() fails on directories on Windows). + (Pierre) +- Fixed bug #49032 (SplFileObject::fscanf() variables passed by reference). + (Jani) +- Fixed bug #49027 (mysqli_options() doesn't work when using mysqlnd). (Andrey) +- Fixed bug #49026 (proc_open() can bypass safe_mode_protected_env_vars + restrictions). (Ilia) +- Fixed bug #49012 (phar tar signature algorithm reports as Unknown (0) in + getSignature() call). (Greg) +- Fixed bug #49020 (phar misinterprets ustar long filename standard). + (Greg) +- Fixed bug #49018 (phar tar stores long filenames wit prefix/name reversed). + (Greg) +- Fixed bug #49014 (dechunked filter broken when serving more than 8192 bytes + in a chunk). (andreas dot streichardt at globalpark dot com, Ilia) +- Fixed bug #49000 (PHP CLI in Interactive mode (php -a) crashes + when including files from function). (Stas) +- Fixed bug #48994 (zlib.output_compression does not output HTTP headers when + set to a string value). (Jani) +- Fixed bug #48980 (Crash when compiling with pdo_firebird). (Felipe) +- Fixed bug #48962 (cURL does not upload files with specified filename). + (Ilia) +- Fixed bug #48929 (Double \r\n after HTTP headers when "header" context + option is an array). (David Zülke) +- Fixed bug #48913 (Too long error code strings in pdo_odbc driver). + (naf at altlinux dot ru, Felipe) +- Fixed bug #48912 (Namespace causes unexpected strict behaviour with + extract()). (Dmitry) +- Fixed bug #48909 (Segmentation fault in mysqli_stmt_execute()). (Andrey) +- Fixed bug #48899 (is_callable returns true even if method does not exist in + parent class). (Felipe) +- Fixed bug #48893 (Problems compiling with Curl). (Felipe) +- Fixed bug #48872 (string.c: errors: duplicate case values). (Kalle) +- Fixed bug #48854 (array_merge_recursive modifies arrays after first one). + (Felipe) +- Fixed bug #48805 (IPv6 socket transport is not working). (Ilia) +- Fixed bug #48802 (printf() returns incorrect outputted length). (Jani) +- Fixed bug #48880 (Random Appearing open_basedir problem). (Rasmus, Gwynne) +- Fixed bug #48791 (open office files always reported as corrupted). (Greg) +- Fixed bug #48788 (RecursiveDirectoryIterator doesn't descend into symlinked + directories). (Ilia) +- Fixed bug #48783 (make install will fail saying phar file exists). (Greg) +- Fixed bug #48774 (SIGSEGVs when using curl_copy_handle()). + (Sriram Natarajan) +- Fixed bug #48771 (rename() between volumes fails and reports no error on + Windows). (Pierre) +- Fixed bug #48768 (parse_ini_*() crash with INI_SCANNER_RAW). (Jani) +- Fixed bug #48763 (ZipArchive produces corrupt archive). (dani dot church at + gmail dot com, Pierre) +- Fixed bug #48762 (IPv6 address filter still rejects valid address). (Felipe) +- Fixed bug #48757 (ReflectionFunction::invoke() parameter issues). (Kalle) +- Fixed bug #48754 (mysql_close() crash php when no handle specified). + (Johannes, Andrey) +- Fixed bug #48752 (Crash during date parsing with invalid date). (Pierre) +- Fixed bug #48746 (Unable to browse directories within Junction Points). + (Pierre, Kanwaljeet Singla) +- Fixed bug #48745 (mysqlnd: mysql_num_fields returns wrong column count for + mysql_list_fields). (Andrey) +- Fixed bug #48740 (PHAR install fails when INSTALL_ROOT is not the final + install location). (james dot cohen at digitalwindow dot com, Greg) +- Fixed bug #48733 (CURLOPT_WRITEHEADER|CURLOPT_FILE|CURLOPT_STDERR warns on + files that have been opened with r+). (Ilia) +- Fixed bug #48719 (parse_ini_*(): scanner_mode parameter is not checked for + sanity). (Jani) +- Fixed bug #48718 (FILTER_VALIDATE_EMAIL does not allow numbers in domain + components). (Ilia) +- Fixed bug #48681 (openssl signature verification for tar archives broken). + (Greg) +- Fixed bug #48660 (parse_ini_*(): dollar sign as last character of value + fails). (Jani) +- Fixed bug #48645 (mb_convert_encoding() doesn't understand hexadecimal + html-entities). (Moriyoshi) +- Fixed bug #48637 ("file" fopen wrapper is overwritten when using + --with-curlwrappers). (Jani) +- Fixed bug #48608 (Invalid libreadline version not detected during configure). + (Jani) +- Fixed bug #48400 (imap crashes when closing stream opened with + OP_PROTOTYPE flag). (Jani) +- Fixed bug #48377 (error message unclear on converting phar with existing + file). (Greg) +- Fixed bug #48247 (Infinite loop and possible crash during startup with + errors when errors are logged). (Jani) +- Fixed bug #48198 error: 'MYSQLND_LLU_SPEC' undeclared. Cause for #48780 and + #46952 - both fixed too. (Andrey) +- Fixed bug #48189 (ibase_execute error in return param). (Kalle) +- Fixed bug #48182 (ssl handshake fails during asynchronous socket connection). + (Sriram Natarajan) +- Fixed bug #48116 (Fixed build with Openssl 1.0). (Pierre, + Al dot Smith at aeschi dot ch dot eu dot org) +- Fixed bug #48057 (Only the date fields of the first row are fetched, others + are empty). (info at programmiernutte dot net) +- Fixed bug #47481 (natcasesort() does not sort extended ASCII characters + correctly). (Herman Radtke) +- Fixed bug #47351 (Memory leak in DateTime). (Derick, Tobias John) +- Fixed bug #47273 (Encoding bug in SoapServer->fault). (Dmitry) +- Fixed bug #46682 (touch() afield returns different values on windows). + (Pierre) +- Fixed bug #46614 (Extended MySQLi class gives incorrect empty() result). + (Andrey) +- Fixed bug #46020 (with Sun Java System Web Server 7.0 on HPUX, #define HPUX). + (Uwe Schindler) +- Fixed bug #45905 (imagefilledrectangle() clipping error). + (markril at hotmail dot com, Pierre) +- Fixed bug #45554 (Inconsistent behavior of the u format char). (Derick) +- Fixed bug #45141 (setcookie will output expires years of >4 digits). (Ilia) +- Fixed bug #44683 (popen crashes when an invalid mode is passed). (Pierre) +- Fixed bug #43510 (stream_get_meta_data() does not return same mode as used + in fopen). (Jani) +- Fixed bug #42434 (ImageLine w/ antialias = 1px shorter). (wojjie at gmail dot + com, Kalle) +- Fixed bug #40013 (php_uname() does not return nodename on Netware (Guenter + Knauf) +- Fixed bug #38091 (Mail() does not use FQDN when sending SMTP helo). + (Kalle, Rick Yorgason) +- Fixed bug #28038 (Sent incorrect RCPT TO commands to SMTP server) (Garrett) +- Fixed bug #27051 (Impersonation with FastCGI does not exec process as + impersonated user). (Pierre) +- Fixed PECL bug #16842 (oci_error return false when NO_DATA_FOUND is raised). + (Chris Jones) + 30 Jun 2009, PHP 5.3.0 - Upgraded bundled PCRE to version 7.9. (Nuno) - Upgraded bundled sqlite to version 3.6.15. (Scott) diff --git a/README.CVS-RULES b/README.CVS-RULES deleted file mode 100644 index 9ef3fc233..000000000 --- a/README.CVS-RULES +++ /dev/null @@ -1,146 +0,0 @@ -==================== - CVS Commit Rules -==================== - -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 and get - confirmation from the release manager for the given branch. - - 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. - To do so use "make test". - - 7. For development use the --enable-maintainer-zts switch to ensure your - code handles TSRM correctly and doesn't break for thos who need that. - -Currently we have the following branches in use:: - - HEAD Will become PHP 6.0. This CVS branch is for active development. - - PHP_5_3 Is used to release the PHP 5.3.x series. It still allows for - larger enhancements. - - PHP_5_2 Is used to release the PHP 5.2.x series. Only bugfixes are permitted - on this branch (Consult the releasemaster prior to commit). - - PHP_5_1 This branch is closed. - - PHP_4_4 This branch is closed. - -The next few rules are more of a technical nature:: - - 1. All changes should first go to HEAD and then get merged from HEAD - (aka MFH'ed) to all other relevant branches. - - 2. DO NOT TOUCH ChangeLog! It is automagically updated from the commit - messages every day. Woe be to those who attempt to mess with it. - - 3. All news updates intended for public viewing, such as new features, - bug fixes, improvements, etc., should go into the NEWS file of the - *first* to be released version with the given change. In other words - any NEWS file change only needs to done in one branch. - - NB! Lines, starting with @ will go automagically into NEWS file, but - this is NOT recommended, though. Please, add news entries directly to - NEWS file and don't forget to keep them adjusted and sorted. - - 4. 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. - - 5. 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. - - 6. 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. - - 7. 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. - -Use a - to start a new item in your commit message. - -If a line begins with #, it is taken to be a comment and will not appear -in the ChangeLog. Everything else goes into the ChangeLog. - -It is important to note that if your comment or news logline spans multiple -lines, you have to put # at the beginning of **every** such line. - -Example. Say you modified two files, datetime.c and string.c. In datetime.c you -added a new format option for the date() function, and in string.c you fixed a -memory leak in php_trim(). Don't commit both of these at once. Commit them -separately and try to make sure your commit messages look something like the -following. - -For datetime.c:: - - - Added new 'K' format modifier to date() for printing out number of days - until New Year's Eve. - -For string.c:: - - - Fixed a memory leak in php_trim() resulting from improper use of zval_dtor(). - #- Man, that thing was leaking all over the place! - -The # lines will be omitted from the ChangeLog automagically. - -Use the [DOC] tag in your log message whenever you feel that your changes -imply a documentation modification. The php-doc team will automatically -get notified about your commit through the php-doc mailing list. - -If you fix some bugs, you should note the bug ID numbers in your -commit message. Bug ID should be prefixed by "#" for easier access to -bug report when developers are browsing CVS via LXR or Bonsai. - -Example:: - - Fixed bug #14016 (pgsql notice handler double free crash bug.) - -If you don't see your messages in ChangeLog right away, don't worry! -These files are updated once a day, so your stuff will not show up until -somewhat later. - -When you change the NEWS file for a bug fix, then please keep the bugs -sorted in decreasing order under the fixed version. - -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 diff --git a/README.RELEASE_PROCESS b/README.RELEASE_PROCESS index 25f9ec115..d99c4ff38 100644 --- a/README.RELEASE_PROCESS +++ b/README.RELEASE_PROCESS @@ -210,6 +210,10 @@ f.e. ``ChangeLog-4.php`` from the NEWS file III. ``s/Fixed bug #\([0-9]\+\)//`` + IV. ``s/Fixed PECL bug #\([0-9]\+\)//`` + + V. ``s/FR #\([0-9]\+\)/FR /`` + 4. ``cp releases/4_4_0.php releases/4_4_1.php`` 5. ``cvs add releases/4_4_1.php`` @@ -248,9 +252,8 @@ number, and remove the RC from there. II. For PHP5: Set $CURRENT_QA_RELEASE_5 to false - Re-releasing the same version (or -pl) ------------------------------------- +-------------------------------------- 1. Commit the new binaries to ``phpweb/distributions/`` @@ -281,4 +284,3 @@ to upgrade. 5. Wait an hour or two, then send a mail to php-announce@lists.php.net, php-general@lists.php.net and internals@lists.php.net with a text similar to the news entry. - diff --git a/README.SELF-CONTAINED-EXTENSIONS b/README.SELF-CONTAINED-EXTENSIONS index 02d27ad83..15170915c 100644 --- a/README.SELF-CONTAINED-EXTENSIONS +++ b/README.SELF-CONTAINED-EXTENSIONS @@ -1,4 +1,4 @@ -$Id: README.SELF-CONTAINED-EXTENSIONS,v 1.12 2002/10/23 21:35:17 jon Exp $ +$Id: README.SELF-CONTAINED-EXTENSIONS 242949 2007-09-26 15:44:16Z cvs2svn $ ============================================================================= HOW TO CREATE A SELF-CONTAINED PHP EXTENSION diff --git a/README.STREAMS b/README.STREAMS index bf96f3b0a..e58d7f399 100644 --- a/README.STREAMS +++ b/README.STREAMS @@ -1,6 +1,6 @@ An Overview of the PHP Streams abstraction ========================================== -$Id: README.STREAMS,v 1.11 2003/03/04 21:46:33 iliaa Exp $ +$Id: README.STREAMS 242949 2007-09-26 15:44:16Z cvs2svn $ WARNING: some prototypes in this file are out of date. The information contained here is being integrated into diff --git a/README.SUBMITTING_PATCH b/README.SUBMITTING_PATCH index 04847d79c..8229bf075 100644 --- a/README.SUBMITTING_PATCH +++ b/README.SUBMITTING_PATCH @@ -8,11 +8,11 @@ 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) +We use Subversion (SVN) for revision control. You need to get the +source from SVN in order to create a patch. Read +http://www.php.net/svn.php for help on using SVN. You can check out +older branches, but make sure you get trunk as well and make your +patch work there. Read CODING_STANDARDS file before you start working. @@ -21,7 +21,7 @@ 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. +"svn 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 @@ -41,25 +41,8 @@ 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. +If you are new to SVN (Subversion), visit +http://svnbook.red-bean.com/ for details. Check list for submitting patch @@ -70,10 +53,7 @@ Check list for submitting patch 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 update SVN source before you take final patch? - Did you read the patch again? @@ -118,7 +98,7 @@ these questions: What happens when your patch is applied? ---------------------------------------- -Your name will be included together with your email address in the CVS +Your name will be included together with your email address in the SVN commit log. If your patch affects end-users, a brief description and your name might be added to the NEWS file. diff --git a/README.SVN-RULES b/README.SVN-RULES new file mode 100644 index 000000000..2b3cb8036 --- /dev/null +++ b/README.SVN-RULES @@ -0,0 +1,146 @@ +==================== + SVN Commit Rules +==================== + +This is the first file you should be reading after you get your SVN account. +We'll assume you're basically familiar with SVN, but feel free to post +your questions on the mailing list. Please have a look at +http://svnbook.red-bean.com/ for more detailed information on SVN. + +PHP is developed through the efforts of a large number of people. +Collaboration is a Good Thing(tm), and SVN lets us do this. Thus, following +some basic rules with regards to SVN usage will:: + + a. Make everybody happier, especially those responsible for maintaining + the SVN 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 and get + confirmation from the release manager for the given branch. + + 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. + To do so use "make test". + + 7. For development use the --enable-maintainer-zts switch to ensure your + code handles TSRM correctly and doesn't break for thos who need that. + +Currently we have the following branches in use:: + + trunk Will become PHP 6.0. This CVS branch is for active development. + + branches/PHP_5_3 Is used to release the PHP 5.3.x series. It still allows for + larger enhancements. + + branches/PHP_5_2 Is used to release the PHP 5.2.x series. Only bugfixes are permitted + on this branch (Consult the releasemaster prior to commit). + + branches/PHP_5_1 This branch is closed. + + branches/PHP_4_4 This branch is closed. + +The next few rules are more of a technical nature:: + + 1. All changes should first go to trunk and then get merged from trunk + (aka MFH'ed) to all other relevant branches. + + 2. DO NOT TOUCH ChangeLog! It is automagically updated from the commit + messages every day. Woe be to those who attempt to mess with it. + + 3. All news updates intended for public viewing, such as new features, + bug fixes, improvements, etc., should go into the NEWS file of the + *first* to be released version with the given change. In other words + any NEWS file change only needs to done in one branch. + + NB! Lines, starting with @ will go automagically into NEWS file, but + this is NOT recommended, though. Please, add news entries directly to + NEWS file and don't forget to keep them adjusted and sorted. + + 4. 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. + + 5. 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. + + 6. 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. + + 7. 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. + +Use a - to start a new item in your commit message. + +If a line begins with #, it is taken to be a comment and will not appear +in the ChangeLog. Everything else goes into the ChangeLog. + +It is important to note that if your comment or news logline spans multiple +lines, you have to put # at the beginning of **every** such line. + +Example. Say you modified two files, datetime.c and string.c. In datetime.c you +added a new format option for the date() function, and in string.c you fixed a +memory leak in php_trim(). Don't commit both of these at once. Commit them +separately and try to make sure your commit messages look something like the +following. + +For datetime.c:: + + - Added new 'K' format modifier to date() for printing out number of days + until New Year's Eve. + +For string.c:: + + - Fixed a memory leak in php_trim() resulting from improper use of zval_dtor(). + #- Man, that thing was leaking all over the place! + +The # lines will be omitted from the ChangeLog automagically. + +Use the [DOC] tag in your log message whenever you feel that your changes +imply a documentation modification. The php-doc team will automatically +get notified about your commit through the php-doc mailing list. + +If you fix some bugs, you should note the bug ID numbers in your +commit message. Bug ID should be prefixed by "#" for easier access to +bug report when developers are browsing CVS via LXR or Bonsai. + +Example:: + + Fixed bug #14016 (pgsql notice handler double free crash bug.) + +If you don't see your messages in ChangeLog right away, don't worry! +These files are updated once a day, so your stuff will not show up until +somewhat later. + +When you change the NEWS file for a bug fix, then please keep the bugs +sorted in decreasing order under the fixed version. + +You can use LXR (http://lxr.php.net/) and Bonsai (http://bonsai.php.net/) +to look at PHP SVN 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 diff --git a/README.WIN32-BUILD-SYSTEM b/README.WIN32-BUILD-SYSTEM index a123a81dd..ae864d0b4 100644 --- a/README.WIN32-BUILD-SYSTEM +++ b/README.WIN32-BUILD-SYSTEM @@ -1,5 +1,5 @@ The Win32 Build System. -$Id: README.WIN32-BUILD-SYSTEM,v 1.4 2003/12/23 02:51:18 wez Exp $ +$Id: README.WIN32-BUILD-SYSTEM 242949 2007-09-26 15:44:16Z cvs2svn $ Wez Furlong If you need help with the build system, send mail to diff --git a/README.input_filter b/README.input_filter index 1d4269590..f3ca2ee89 100644 --- a/README.input_filter +++ b/README.input_filter @@ -88,7 +88,7 @@ PHP_MINFO_FUNCTION(my_input_filter) { php_info_print_table_start(); php_info_print_table_row( 2, "My Input Filter Support", "enabled" ); - php_info_print_table_row( 2, "Revision", "$Revision: 1.7.4.1.2.1 $"); + php_info_print_table_row( 2, "Revision", "$Revision: 222526 $"); php_info_print_table_end(); } diff --git a/TSRM/TSRM.dsp b/TSRM/TSRM.dsp index 53bce254f..1a5693f5a 100644 --- a/TSRM/TSRM.dsp +++ b/TSRM/TSRM.dsp @@ -1,186 +1,186 @@ -# 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 +# 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 diff --git a/TSRM/build.mk b/TSRM/build.mk index d62326a94..5cd3aa9a7 100644 --- a/TSRM/build.mk +++ b/TSRM/build.mk @@ -5,7 +5,7 @@ # # Written by Sascha Schumann # -# $Id: build.mk,v 1.2 1999/10/10 02:01:20 sascha Exp $ +# $Id: build.mk 14329 1999-10-10 02:02:13Z sascha $ LT_TARGETS = ltmain.sh ltconfig diff --git a/TSRM/config.w32 b/TSRM/config.w32 index 2f70ced85..0098b0e8f 100644 --- a/TSRM/config.w32 +++ b/TSRM/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.1 2003/12/22 15:01:05 wez Exp $ +// $Id: config.w32 147168 2003-12-22 15:01:05Z wez $ if (CHECK_HEADER_ADD_INCLUDE("NewAPIs.h", "CFLAGS_PHP", php_usual_include_suspects)) { // Need to add the flag directly, since TSRM doesn't include the config diff --git a/TSRM/configure.in b/TSRM/configure.in index fb1a5a6e6..6705f583d 100644 --- a/TSRM/configure.in +++ b/TSRM/configure.in @@ -1,4 +1,4 @@ -dnl $Id: configure.in,v 1.17 2001/08/08 10:26:21 zeev Exp $ +dnl $Id: configure.in 53832 2001-08-08 10:26:21Z zeev $ dnl dnl Minimalistic configure.in for TSRM. dnl diff --git a/TSRM/tsrm_nw.c b/TSRM/tsrm_nw.c index f007e7f99..4a9ccabdd 100644 --- a/TSRM/tsrm_nw.c +++ b/TSRM/tsrm_nw.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_nw.c,v 1.8.2.1.2.1.2.2 2008/12/31 11:15:31 sebastian Exp $ */ +/* $Id: tsrm_nw.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include #include diff --git a/TSRM/tsrm_virtual_cwd.c b/TSRM/tsrm_virtual_cwd.c index 770bf15e2..37b9820ea 100644 --- a/TSRM/tsrm_virtual_cwd.c +++ b/TSRM/tsrm_virtual_cwd.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_virtual_cwd.c,v 1.74.2.9.2.35.2.22 2009/06/26 07:39:42 pajoye Exp $ */ +/* $Id: tsrm_virtual_cwd.c 289780 2009-10-19 23:38:55Z pajoye $ */ #include #include @@ -271,9 +271,6 @@ CWD_API int php_sys_stat(const char *path, struct stat *buf) /* {{{ */ buf->st_atime = FileTimeToUnixTime(data.ftLastAccessTime); buf->st_ctime = FileTimeToUnixTime(data.ftCreationTime); buf->st_mtime = FileTimeToUnixTime(data.ftLastWriteTime); - if (buf->st_mtime != buf->st_atime) { - buf->st_atime = buf->st_mtime; - } return 0; } /* }}} */ @@ -431,6 +428,31 @@ CWD_API char *virtual_getcwd(char *buf, size_t size TSRMLS_DC) /* {{{ */ } /* }}} */ +#ifdef PHP_WIN32 +static inline unsigned long realpath_cache_key(const char *path, int path_len TSRMLS_DC) /* {{{ */ +{ + register unsigned long h; + char *bucket_key = tsrm_win32_get_path_sid_key(path TSRMLS_CC); + char *bucket_key_start = (char *)bucket_key; + const char *e = bucket_key + strlen(bucket_key); + + if (!bucket_key) { + return 0; + } + + for (h = 2166136261U; bucket_key < e;) { + h *= 16777619; + h ^= *bucket_key++; + } + /* if no SID were present the path is returned. Otherwise a Heap + allocated string is returned. */ + if (bucket_key_start != path) { + LocalFree(bucket_key_start); + } + return h; +} +/* }}} */ +#else static inline unsigned long realpath_cache_key(const char *path, int path_len) /* {{{ */ { register unsigned long h; @@ -444,6 +466,7 @@ static inline unsigned long realpath_cache_key(const char *path, int path_len) / return h; } /* }}} */ +#endif /* defined(PHP_WIN32) */ CWD_API void realpath_cache_clean(TSRMLS_D) /* {{{ */ { @@ -464,7 +487,11 @@ CWD_API void realpath_cache_clean(TSRMLS_D) /* {{{ */ CWD_API void realpath_cache_del(const char *path, int path_len TSRMLS_DC) /* {{{ */ { +#ifdef PHP_WIN32 + unsigned long key = realpath_cache_key(path, path_len TSRMLS_CC); +#else unsigned long key = realpath_cache_key(path, path_len); +#endif unsigned long n = key % (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0])); realpath_cache_bucket **bucket = &CWDG(realpath_cache)[n]; @@ -497,8 +524,12 @@ static inline void realpath_cache_add(const char *path, int path_len, const char if (CWDG(realpath_cache_size) + size <= CWDG(realpath_cache_size_limit)) { realpath_cache_bucket *bucket = malloc(size); unsigned long n; - + +#ifdef PHP_WIN32 + bucket->key = realpath_cache_key(path, path_len TSRMLS_CC); +#else bucket->key = realpath_cache_key(path, path_len); +#endif bucket->path = (char*)bucket + sizeof(realpath_cache_bucket); memcpy(bucket->path, path, path_len+1); bucket->path_len = path_len; @@ -527,7 +558,12 @@ static inline void realpath_cache_add(const char *path, int path_len, const char static inline realpath_cache_bucket* realpath_cache_find(const char *path, int path_len, time_t t TSRMLS_DC) /* {{{ */ { +#ifdef PHP_WIN32 + unsigned long key = realpath_cache_key(path, path_len TSRMLS_CC); +#else unsigned long key = realpath_cache_key(path, path_len); +#endif + unsigned long n = key % (sizeof(CWDG(realpath_cache)) / sizeof(CWDG(realpath_cache)[0])); realpath_cache_bucket **bucket = &CWDG(realpath_cache)[n]; @@ -564,13 +600,13 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i #ifdef TSRM_WIN32 WIN32_FIND_DATA data; HANDLE hFind; + TSRM_ALLOCA_FLAG(use_heap_large) #else struct stat st; #endif realpath_cache_bucket *bucket; char *tmp; TSRM_ALLOCA_FLAG(use_heap) - TSRM_ALLOCA_FLAG(use_heap_large) while (1) { if (len <= start) { @@ -670,9 +706,14 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i /* File is a reparse point. Get the target */ HANDLE hLink = NULL; REPARSE_DATA_BUFFER * pbuffer; - unsigned int retlength = 0, rname_off = 0; - int bufindex = 0, rname_len = 0, isabsolute = 0; + unsigned int retlength = 0; + int bufindex = 0, isabsolute = 0; wchar_t * reparsetarget; + BOOL isVolume = FALSE; + char printname[MAX_PATH]; + char substitutename[MAX_PATH]; + int printname_len, substitutename_len; + int substitutename_off = 0; if(++(*ll) > LINK_MAX) { return -1; @@ -693,37 +734,108 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i CloseHandle(hLink); if(pbuffer->ReparseTag == IO_REPARSE_TAG_SYMLINK) { - rname_len = pbuffer->SymbolicLinkReparseBuffer.PrintNameLength/2; - rname_off = pbuffer->SymbolicLinkReparseBuffer.PrintNameOffset/2; reparsetarget = pbuffer->SymbolicLinkReparseBuffer.ReparseTarget; + printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR); isabsolute = (pbuffer->SymbolicLinkReparseBuffer.Flags == 0) ? 1 : 0; + if (!WideCharToMultiByte(CP_THREAD_ACP, 0, + reparsetarget + pbuffer->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR), + printname_len + 1, + printname, MAX_PATH, NULL, NULL + )) { + tsrm_free_alloca(pbuffer, use_heap_large); + return -1; + }; + printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR); + printname[printname_len] = 0; + + substitutename_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR); + if (!WideCharToMultiByte(CP_THREAD_ACP, 0, + reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR), + substitutename_len + 1, + substitutename, MAX_PATH, NULL, NULL + )) { + tsrm_free_alloca(pbuffer, use_heap_large); + return -1; + }; + substitutename[substitutename_len] = 0; } else if(pbuffer->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { - rname_len = pbuffer->MountPointReparseBuffer.PrintNameLength/2; - rname_off = pbuffer->MountPointReparseBuffer.PrintNameOffset/2; - reparsetarget = pbuffer->MountPointReparseBuffer.ReparseTarget; isabsolute = 1; - } - else { + reparsetarget = pbuffer->MountPointReparseBuffer.ReparseTarget; + printname_len = pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR); + if (!WideCharToMultiByte(CP_THREAD_ACP, 0, + reparsetarget + pbuffer->MountPointReparseBuffer.PrintNameOffset / sizeof(WCHAR), + printname_len + 1, + printname, MAX_PATH, NULL, NULL + )) { + tsrm_free_alloca(pbuffer, use_heap_large); + return -1; + }; + printname[pbuffer->MountPointReparseBuffer.PrintNameLength / sizeof(WCHAR)] = 0; + + substitutename_len = pbuffer->MountPointReparseBuffer.SubstituteNameLength / sizeof(WCHAR); + if (!WideCharToMultiByte(CP_THREAD_ACP, 0, + reparsetarget + pbuffer->MountPointReparseBuffer.SubstituteNameOffset / sizeof(WCHAR), + substitutename_len + 1, + substitutename, MAX_PATH, NULL, NULL + )) { + tsrm_free_alloca(pbuffer, use_heap_large); + return -1; + }; + substitutename[substitutename_len] = 0; + } else { tsrm_free_alloca(pbuffer, use_heap_large); return -1; } - /* Convert wide string to narrow string */ - for(bufindex = 0; bufindex < rname_len; bufindex++) { - *(path + bufindex) = (char)(reparsetarget[rname_off + bufindex]); + if(isabsolute && substitutename_len > 4) { + /* Do not resolve volumes (for now). A mounted point can + target a volume without a drive, it is not certain that + all IO functions we use in php and its deps support + path with volume GUID instead of the DOS way, like: + d:\test\mnt\foo + \\?\Volume{62d1c3f8-83b9-11de-b108-806e6f6e6963}\foo + */ + if (strncmp(substitutename, "\\??\\Volume{",11) == 0 + || strncmp(substitutename, "\\\\?\\Volume{",11) == 0) { + isVolume = TRUE; + substitutename_off = 0; + } else + /* do not use the \??\ and \\?\ prefix*/ + if (strncmp(substitutename, "\\??\\", 4) == 0 + || strncmp(substitutename, "\\\\?\\", 4) == 0) { + substitutename_off = 4; + } } - *(path + bufindex) = 0; + if (!isVolume) { + char * tmp = substitutename + substitutename_off; + for(bufindex = 0; bufindex < (substitutename_len - substitutename_off); bufindex++) { + *(path + bufindex) = *(tmp + bufindex); + } + + *(path + bufindex) = 0; + j = bufindex; + } else { + j = len; + } + + +#if VIRTUAL_CWD_DEBUG + fprintf(stderr, "reparse: print: %s ", printname); + fprintf(stderr, "sub: %s ", substitutename); + fprintf(stderr, "resolved: %s ", path); +#endif tsrm_free_alloca(pbuffer, use_heap_large); - j = bufindex; if(isabsolute == 1) { - /* use_realpath is 0 in the call below coz path is absolute*/ - j = tsrm_realpath_r(path, 0, j, ll, t, 0, is_dir, &directory TSRMLS_CC); - if(j < 0) { - tsrm_free_alloca(tmp, use_heap); - return -1; + if (!((j == 3) && (path[1] == ':') && (path[2] == '\\'))) { + /* use_realpath is 0 in the call below coz path is absolute*/ + j = tsrm_realpath_r(path, 0, j, ll, t, 0, is_dir, &directory TSRMLS_CC); + if(j < 0) { + tsrm_free_alloca(tmp, use_heap); + return -1; + } } } else { @@ -741,6 +853,7 @@ static int tsrm_realpath_r(char *path, int start, int len, int *ll, time_t *t, i return -1; } } + directory = (data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY); if(link_is_dir) { *link_is_dir = directory; @@ -1195,7 +1308,7 @@ static void UnixTimeToFileTime(time_t t, LPFILETIME pft) /* {{{ */ } /* }}} */ -static int win32_utime(const char *filename, struct utimbuf *buf) /* {{{ */ +TSRM_API int win32_utime(const char *filename, struct utimbuf *buf) /* {{{ */ { FILETIME mtime, atime; HANDLE hFile; @@ -1371,7 +1484,7 @@ CWD_API int virtual_rename(char *oldname, char *newname TSRMLS_DC) /* {{{ */ /* rename on windows will fail if newname already exists. MoveFileEx has to be used */ #ifdef TSRM_WIN32 - retval = (MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) == 0) ? -1 : 0; + retval = (MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED) == 0) ? -1 : 0; #else retval = rename(oldname, newname); #endif diff --git a/TSRM/tsrm_virtual_cwd.h b/TSRM/tsrm_virtual_cwd.h index 65225f37b..7f612bfec 100644 --- a/TSRM/tsrm_virtual_cwd.h +++ b/TSRM/tsrm_virtual_cwd.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_virtual_cwd.h,v 1.48.2.5.2.8.2.7 2009/06/16 00:07:04 pajoye Exp $ */ +/* $Id: tsrm_virtual_cwd.h 287673 2009-08-25 09:16:53Z pajoye $ */ #ifndef VIRTUAL_CWD_H #define VIRTUAL_CWD_H @@ -288,7 +288,7 @@ CWD_API realpath_cache_bucket* realpath_cache_lookup(const char *path, int path_ /* rename on windows will fail if newname already exists. MoveFileEx has to be used */ #if defined(TSRM_WIN32) -# define VCWD_RENAME(oldname, newname) (MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING) == 0 ? -1 : 0) +# define VCWD_RENAME(oldname, newname) (MoveFileEx(oldname, newname, MOVEFILE_REPLACE_EXISTING|MOVEFILE_COPY_ALLOWED) == 0 ? -1 : 0) #else # define VCWD_RENAME(oldname, newname) rename(oldname, newname) #endif @@ -311,8 +311,13 @@ CWD_API realpath_cache_bucket* realpath_cache_lookup(const char *path, int path_ #define VCWD_REALPATH(path, real_path) tsrm_realpath(path, real_path TSRMLS_CC) #if HAVE_UTIME -#define VCWD_UTIME(path, time) utime(path, time) +# ifdef TSRM_WIN32 +# define VCWD_UTIME(path, time) win32_utime(path, time) +# else +# define VCWD_UTIME(path, time) utime(path, time) +# endif #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) diff --git a/TSRM/tsrm_win32.c b/TSRM/tsrm_win32.c index 7c47fa336..b224d4b10 100644 --- a/TSRM/tsrm_win32.c +++ b/TSRM/tsrm_win32.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_win32.c,v 1.27.2.1.2.7.2.11 2009/06/16 00:07:04 pajoye Exp $ */ +/* $Id: tsrm_win32.c 290166 2009-11-03 10:48:12Z pajoye $ */ #include #include @@ -30,7 +30,7 @@ #include "TSRM.h" #ifdef TSRM_WIN32 - +#include #include "tsrm_win32.h" #include "tsrm_virtual_cwd.h" @@ -42,25 +42,21 @@ static tsrm_win32_globals win32_globals; static void tsrm_win32_ctor(tsrm_win32_globals *globals TSRMLS_DC) { - HANDLE process_token = NULL; - globals->process = NULL; globals->shm = NULL; globals->process_size = 0; globals->shm_size = 0; globals->comspec = _strdup((GetVersion()<0x80000000)?"cmd.exe":"command.com"); - globals->impersonation_token = NULL; - - /* Access check requires impersonation token. Create a duplicate token. */ - if(OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE | TOKEN_QUERY, &process_token)) { - DuplicateToken(process_token, SecurityImpersonation, &globals->impersonation_token); - } - /* impersonation_token will be closed when the process dies */ - if(process_token != NULL) { - CloseHandle(process_token); - process_token = NULL; - } + /* Set it to INVALID_HANDLE_VALUE + * It will be initialized correctly in tsrm_win32_access or set to + * NULL if no impersonation has been done. + * the impersonated token can't be set here as the impersonation + * will happen later, in fcgi_accept_request (or whatever is the + * SAPI being used). + */ + globals->impersonation_token = INVALID_HANDLE_VALUE; + globals->impersonation_token_sid = NULL; } static void tsrm_win32_dtor(tsrm_win32_globals *globals TSRMLS_DC) @@ -83,9 +79,12 @@ static void tsrm_win32_dtor(tsrm_win32_globals *globals TSRMLS_DC) free(globals->comspec); - if(globals->impersonation_token) { + if (globals->impersonation_token && globals->impersonation_token != INVALID_HANDLE_VALUE ) { CloseHandle(globals->impersonation_token); } + if (globals->impersonation_token_sid) { + free(globals->impersonation_token_sid); + } } TSRM_API void tsrm_win32_startup(void) @@ -104,8 +103,97 @@ TSRM_API void tsrm_win32_shutdown(void) #endif } +char * tsrm_win32_get_path_sid_key(const char *pathname TSRMLS_DC) +{ + PSID pSid = TWG(impersonation_token_sid); + DWORD sid_len = pSid ? GetLengthSid(pSid) : 0; + TCHAR *ptcSid = NULL; + char *bucket_key = NULL; + + if (!pSid) { + bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, strlen(pathname) + 1); + if (!bucket_key) { + return NULL; + } + memcpy(bucket_key, pathname, strlen(pathname)); + return bucket_key; + } + + if (!ConvertSidToStringSid(pSid, &ptcSid)) { + return NULL; + } + + bucket_key = (char *)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, strlen(pathname) + strlen(ptcSid) + 1); + if (!bucket_key) { + LocalFree(ptcSid); + return NULL; + } + + memcpy(bucket_key, ptcSid, strlen(ptcSid)); + memcpy(bucket_key + strlen(ptcSid), pathname, strlen(pathname) + 1); + + LocalFree(ptcSid); + return bucket_key; +} + + +PSID tsrm_win32_get_token_sid(HANDLE hToken) +{ + BOOL bSuccess = FALSE; + DWORD dwLength = 0; + PTOKEN_USER pTokenUser = NULL; + PSID sid; + PSID *ppsid = &sid; + DWORD sid_len; + PSID pResultSid = NULL; + + /* Get the actual size of the TokenUser structure */ + if (!GetTokenInformation( + hToken, TokenUser, (LPVOID) pTokenUser, 0, &dwLength)) { + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + goto Finished; + } + + pTokenUser = (PTOKEN_USER)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, dwLength); + if (pTokenUser == NULL) { + goto Finished; + } + } + + /* and fetch it now */ + if (!GetTokenInformation( + hToken, TokenUser, (LPVOID) pTokenUser, dwLength, &dwLength)) { + goto Finished; + } + + sid_len = GetLengthSid(pTokenUser->User.Sid); + + /* ConvertSidToStringSid(pTokenUser->User.Sid, &ptcSidOwner); */ + pResultSid = malloc(sid_len); + if (!pResultSid) { + goto Finished; + } + if (!CopySid(sid_len, pResultSid, pTokenUser->User.Sid)) { + goto Finished; + } + return pResultSid; + +Finished: + if (pResultSid) { + free(pResultSid); + } + /* Free the buffer for the token groups. */ + if (pTokenUser != NULL) { + HeapFree(GetProcessHeap(), 0, (LPVOID)pTokenUser); + } + return NULL; +} + TSRM_API int tsrm_win32_access(const char *pathname, int mode) { + time_t t; + HANDLE thread_token; + PSID token_sid; SECURITY_INFORMATION sec_info = OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION; GENERIC_MAPPING gen_map = { FILE_GENERIC_READ, FILE_GENERIC_WRITE, FILE_GENERIC_EXECUTE, FILE_ALL_ACCESS }; DWORD priv_set_length = sizeof(PRIVILEGE_SET); @@ -114,11 +202,10 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode) DWORD sec_desc_length = 0, desired_access = 0, granted_access = 0; BYTE * psec_desc = NULL; BOOL fAccess = FALSE; - HANDLE process_token = NULL; + BOOL bucket_key_alloc = FALSE; realpath_cache_bucket * bucket = NULL; char * real_path = NULL; - time_t t; TSRMLS_FETCH(); @@ -126,10 +213,6 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode) DWORD type; return GetBinaryType(pathname, &type) ? 0 : -1; } else { - if(access(pathname, mode)) { - return errno; - } - if(!IS_ABSOLUTE_PATH(pathname, strlen(pathname)+1)) { real_path = (char *)malloc(MAX_PATH); if(tsrm_realpath(pathname, real_path TSRMLS_CC) == NULL) { @@ -138,6 +221,58 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode) pathname = real_path; } + if(access(pathname, mode)) { + return errno; + } + + /* If only existence check is made, return now */ + if (mode == 0) { + return 0; + } + +/* Only in NTS when impersonate==1 (aka FastCGI) */ + + /* + AccessCheck() requires an impersonation token. We first get a primary + token and then create a duplicate impersonation token. The + impersonation token is not actually assigned to the thread, but is + used in the call to AccessCheck. Thus, this function itself never + impersonates, but does use the identity of the thread. If the thread + was impersonating already, this function uses that impersonation context. + */ + if(!OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) { + DWORD err = GetLastError(); + if (GetLastError() == ERROR_NO_TOKEN) { + if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &thread_token)) { + TWG(impersonation_token) = NULL; + goto Finished; + } + } + } + + /* token_sid will be freed in tsrmwin32_dtor */ + token_sid = tsrm_win32_get_token_sid(thread_token); + if (!token_sid) { + if (TWG(impersonation_token_sid)) { + free(TWG(impersonation_token_sid)); + } + TWG(impersonation_token_sid) = NULL; + goto Finished; + } + + /* Different identity, we need a new impersontated token as well */ + if (!TWG(impersonation_token_sid) || !EqualSid(token_sid, TWG(impersonation_token_sid))) { + if (TWG(impersonation_token_sid)) { + free(TWG(impersonation_token_sid)); + } + TWG(impersonation_token_sid) = token_sid; + + /* Duplicate the token as impersonated token */ + if (!DuplicateToken(thread_token, SecurityImpersonation, &TWG(impersonation_token))) { + goto Finished; + } + } + if (CWDG(realpath_cache_size_limit)) { t = time(0); bucket = realpath_cache_lookup(pathname, strlen(pathname), t TSRMLS_CC); @@ -151,7 +286,7 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode) } } } - + /* Do a full access check because access() will only check read-only attribute */ if(mode == 0 || mode > 6) { if(bucket != NULL && bucket->is_rvalid) { @@ -164,13 +299,13 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode) fAccess = bucket->is_writable; goto Finished; } - desired_access = FILE_GENERIC_WRITE; + desired_access = FILE_GENERIC_READ | FILE_GENERIC_WRITE; } else if(mode <= 4) { if(bucket != NULL && bucket->is_rvalid) { fAccess = bucket->is_readable; goto Finished; } - desired_access = FILE_GENERIC_READ; + desired_access = FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS; } else { // if(mode <= 6) if(bucket != NULL && bucket->is_rvalid && bucket->is_wvalid) { fAccess = bucket->is_readable & bucket->is_writable; @@ -194,13 +329,15 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode) goto Finished; } + MapGenericMask(&desired_access, &gen_map); + if(!AccessCheck((PSECURITY_DESCRIPTOR)psec_desc, TWG(impersonation_token), desired_access, &gen_map, &privilege_set, &priv_set_length, &granted_access, &fAccess)) { - goto Finished; + goto Finished_Impersonate; } /* Keep the result in realpath_cache */ if(bucket != NULL) { - if(desired_access == FILE_GENERIC_READ) { + if(desired_access == (FILE_GENERIC_READ|FILE_FLAG_BACKUP_SEMANTICS)) { bucket->is_rvalid = 1; bucket->is_readable = fAccess; } @@ -210,12 +347,13 @@ TSRM_API int tsrm_win32_access(const char *pathname, int mode) } } -Finished: +Finished_Impersonate: if(psec_desc != NULL) { free(psec_desc); psec_desc = NULL; } +Finished: if(real_path != NULL) { free(real_path); real_path = NULL; @@ -305,21 +443,45 @@ TSRM_API FILE *popen(const char *command, const char *type) 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; + int fno, type_len = strlen(type), read, mode; STARTUPINFO startup; PROCESS_INFORMATION process; SECURITY_ATTRIBUTES security; HANDLE in, out; DWORD dwCreateFlags = 0; - char *cmd; + BOOL res; process_pair *proc; + char *cmd; + int i; + char *ptype = (char *)type; + HANDLE thread_token = NULL; + HANDLE token_user = NULL; + BOOL asuser = TRUE; + TSRMLS_FETCH(); + if (!type) { + return NULL; + } + + /*The following two checks can be removed once we drop XP support */ + type_len = strlen(type); + if (type_len <1 || type_len > 2) { + return NULL; + } + + for (i=0; i < type_len; i++) { + if (!(*ptype == 'r' || *ptype == 'w' || *ptype == 'b' || *ptype == 't')) { + return NULL; + } + ptype++; + } + security.nLength = sizeof(SECURITY_ATTRIBUTES); security.bInheritHandle = TRUE; security.lpSecurityDescriptor = NULL; - if (!str_len || !CreatePipe(&in, &out, &security, 2048L)) { + if (!type_len || !CreatePipe(&in, &out, &security, 2048L)) { return NULL; } @@ -331,7 +493,7 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, startup.hStdError = GetStdHandle(STD_ERROR_HANDLE); read = (type[0] == 'r') ? TRUE : FALSE; - mode = ((str_len == 2) && (type[1] == 'b')) ? O_BINARY : O_TEXT; + mode = ((type_len == 2) && (type[1] == 'b')) ? O_BINARY : O_TEXT; if (read) { in = dupHandle(in, FALSE); @@ -348,13 +510,31 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, dwCreateFlags |= CREATE_NO_WINDOW; } + /* Get a token with the impersonated user. */ + if(OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, TRUE, &thread_token)) { + DuplicateTokenEx(thread_token, MAXIMUM_ALLOWED, &security, SecurityImpersonation, TokenPrimary, &token_user); + } else { + DWORD err = GetLastError(); + if (err == ERROR_NO_TOKEN) { + asuser = FALSE; + } + + } + cmd = (char*)malloc(strlen(command)+strlen(TWG(comspec))+sizeof(" /c ")+2); sprintf(cmd, "%s /c \"%s\"", TWG(comspec), command); - if (!CreateProcess(NULL, cmd, &security, &security, security.bInheritHandle, dwCreateFlags, env, cwd, &startup, &process)) { - return NULL; + if (asuser) { + res = CreateProcessAsUser(token_user, NULL, cmd, &security, &security, security.bInheritHandle, dwCreateFlags, env, cwd, &startup, &process); + CloseHandle(token_user); + } else { + res = CreateProcess(NULL, cmd, &security, &security, security.bInheritHandle, dwCreateFlags, env, cwd, &startup, &process); } free(cmd); + if (!res) { + return NULL; + } + CloseHandle(process.hThread); proc = process_get(NULL TSRMLS_CC); diff --git a/TSRM/tsrm_win32.h b/TSRM/tsrm_win32.h index 912fac653..7cd966918 100644 --- a/TSRM/tsrm_win32.h +++ b/TSRM/tsrm_win32.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tsrm_win32.h,v 1.19.2.1.2.1.2.3 2009/05/17 19:42:53 pajoye Exp $ */ +/* $Id: tsrm_win32.h 289780 2009-10-19 23:38:55Z pajoye $ */ #ifndef TSRM_WIN32_H #define TSRM_WIN32_H @@ -64,6 +64,7 @@ typedef struct { int shm_size; char *comspec; HANDLE impersonation_token; + PSID impersonation_token_sid; } tsrm_win32_globals; #ifdef ZTS @@ -89,6 +90,7 @@ typedef struct { #define SHM_RND FILE_MAP_WRITE #define SHM_REMAP FILE_MAP_COPY +char * tsrm_win32_get_path_sid_key(const char *pathname TSRMLS_DC); TSRM_API void tsrm_win32_startup(void); TSRM_API void tsrm_win32_shutdown(void); @@ -97,6 +99,7 @@ TSRM_API FILE *popen_ex(const char *command, const char *type, const char *cwd, TSRM_API FILE *popen(const char *command, const char *type); TSRM_API int pclose(FILE *stream); TSRM_API int tsrm_win32_access(const char *pathname, int mode); +TSRM_API int win32_utime(const char *filename, struct utimbuf *buf); TSRM_API int shmget(int key, int size, int flags); TSRM_API void *shmat(int key, const void *shmaddr, int flags); diff --git a/UPGRADING b/UPGRADING index be7980292..9b797a8d5 100755 --- a/UPGRADING +++ b/UPGRADING @@ -1,4 +1,4 @@ -$Id: UPGRADING,v 1.1.2.3.2.1.2.36 2009/06/28 16:14:30 johannes Exp $ +$Id: UPGRADING 282950 2009-06-28 16:14:30Z johannes $ UPGRADE NOTES - PHP 5.3 diff --git a/Zend/ChangeLog b/Zend/ChangeLog index c9ab06e8f..79e345e13 100644 --- a/Zend/ChangeLog +++ b/Zend/ChangeLog @@ -9403,7 +9403,7 @@ 2003-06-10 Jani Taskinen * zend_multiply.h: - - Missing $Id: ChangeLog,v 1.745 2005/08/06 05:37:51 changelog Exp $ tag + - Missing $Id: ChangeLog 242949 2007-09-26 15:44:16Z cvs2svn $ tag 2003-06-10 James Cox @@ -11127,7 +11127,7 @@ zend_types.h zend_variables.c zend_variables.h: - - Added some missing CVS $Id: ChangeLog,v 1.745 2005/08/06 05:37:51 changelog Exp $ tags, headers and footers. + - Added some missing CVS $Id: ChangeLog 242949 2007-09-26 15:44:16Z cvs2svn $ tags, headers and footers. 2003-01-30 Ilia Alshanetsky diff --git a/Zend/RFCs/002.txt b/Zend/RFCs/002.txt index 6b6e0bae2..a013b9118 100644 --- a/Zend/RFCs/002.txt +++ b/Zend/RFCs/002.txt @@ -1,5 +1,5 @@ Title: Zend 2.0 Namespaces -Version: $Revision: 1.4 $ +Version: $Revision: 148341 $ Status: declined Maintainer: Stig S. Bakken Created: 2001-09-08 diff --git a/Zend/RFCs/003.txt b/Zend/RFCs/003.txt index be0b1fae0..ceda72b2c 100644 --- a/Zend/RFCs/003.txt +++ b/Zend/RFCs/003.txt @@ -1,5 +1,5 @@ Title: Loose type requirements for functions -Version: $Revision: 1.1 $ +Version: $Revision: 57685 $ Status: draft Maintainer: Brian Moon Created: 2001-09-17 diff --git a/Zend/Zend.m4 b/Zend/Zend.m4 index f63320469..089dce9d8 100644 --- a/Zend/Zend.m4 +++ b/Zend/Zend.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: Zend.m4,v 1.58.4.4.2.6 2009/06/04 18:20:42 mattwil Exp $ +dnl $Id: Zend.m4 286859 2009-08-06 01:33:54Z scottmac $ dnl dnl This file contains Zend specific autoconf functions. dnl @@ -62,18 +62,6 @@ unix.h \ stdlib.h \ dlfcn.h) -dnl Don't use mach-o/dyld.h on Darwin 8+, dl* is recommended by Apple from there on -dnl See http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachOTopics/Articles/loading_code.html -case $host_alias in -*darwin[[89]]*) - ;; -*) - AC_CHECK_HEADERS([ \ -mach-o/dyld.h -],[],[][]) - ;; -esac - AC_TYPE_SIZE_T AC_TYPE_SIGNAL diff --git a/Zend/acconfig.h b/Zend/acconfig.h index e376a5a52..bb949a6cb 100644 --- a/Zend/acconfig.h +++ b/Zend/acconfig.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: acconfig.h,v 1.40.2.1.2.1.2.3 2008/12/31 11:15:31 sebastian Exp $ */ +/* $Id: acconfig.h 272370 2008-12-31 11:15:49Z sebastian $ */ #if defined(__GNUC__) && __GNUC__ >= 4 # define ZEND_API __attribute__ ((visibility("default"))) diff --git a/Zend/acinclude.m4 b/Zend/acinclude.m4 index 62ff872a2..046950db1 100644 --- a/Zend/acinclude.m4 +++ b/Zend/acinclude.m4 @@ -1,4 +1,4 @@ -dnl $Id: acinclude.m4,v 1.15.2.2.2.2.2.4 2009/02/14 21:08:00 rasmus Exp $ +dnl $Id: acinclude.m4 275828 2009-02-14 21:08:02Z rasmus $ dnl dnl This file contains local autoconf functions. diff --git a/Zend/bench.php b/Zend/bench.php index 5f771803c..42b333fce 100644 --- a/Zend/bench.php +++ b/Zend/bench.php @@ -3,6 +3,7 @@ if (function_exists("date_default_timezone_set")) { date_default_timezone_set("UTC"); } +date_default_timezone_set('UTC'); function simple() { $a = 0; for ($i = 0; $i < 1000000; $i++) diff --git a/Zend/build.mk b/Zend/build.mk index 79d1c5299..0931c3f44 100644 --- a/Zend/build.mk +++ b/Zend/build.mk @@ -5,7 +5,7 @@ # # Written by Sascha Schumann # -# $Id: build.mk,v 1.2 1999/10/10 02:02:13 sascha Exp $ +# $Id: build.mk 242949 2007-09-26 15:44:16Z cvs2svn $ LT_TARGETS = ltmain.sh ltconfig diff --git a/Zend/configure.in b/Zend/configure.in index 1b13ac402..239b21fab 100644 --- a/Zend/configure.in +++ b/Zend/configure.in @@ -1,4 +1,4 @@ -dnl $Id: configure.in,v 1.36.6.1 2008/03/16 21:05:33 helly Exp $ +dnl $Id: configure.in 255174 2008-03-16 21:06:55Z helly $ dnl Process this file with autoconf to produce a configure script. AC_INIT(zend.c) diff --git a/Zend/header b/Zend/header index baa68e23a..68bf97b36 100644 --- a/Zend/header +++ b/Zend/header @@ -16,4 +16,4 @@ +----------------------------------------------------------------------+ */ -/* $Id: header,v 1.1.2.1.4.1 2009/01/02 20:45:41 felipe Exp $ */ +/* $Id: header 272619 2009-01-02 20:45:43Z felipe $ */ diff --git a/Zend/tests/019.phpt b/Zend/tests/019.phpt index 47158771e..70093cd28 100644 --- a/Zend/tests/019.phpt +++ b/Zend/tests/019.phpt @@ -359,7 +359,8 @@ var_dump($global_var); //Note: No error conditions relating to passing arugments can be tested // because these are not functions but statements, it will result in syntax error. -echo "Done\n"; +?> +===DONE=== --EXPECTF-- *** Testing unset(), empty() & isset() with scalar variables *** -- Iteration 1 -- @@ -1185,11 +1186,11 @@ bool(true) *** Testing unset(), emtpy() & isset() with resource variables *** -- Iteration 1 -- -resource(5) of type (stream) +resource(%d) of type (stream) bool(true) bool(false) bool(true) -resource(5) of type (stream) +resource(%d) of type (stream) bool(false) bool(true) bool(false) @@ -1198,11 +1199,11 @@ bool(false) Notice: Undefined variable: resource in %s on line %d NULL -- Iteration 2 -- -resource(6) of type (stream) +resource(%d) of type (stream) bool(true) bool(false) bool(true) -resource(6) of type (stream) +resource(%d) of type (stream) bool(false) bool(true) bool(false) @@ -1217,7 +1218,7 @@ bool(false) bool(true) *** Testing unset(), empty() & isset() with objects *** -object(Point)#1 (3) { +object(Point)#%d (3) { ["x"]=> int(30) ["y"]=> @@ -1239,7 +1240,7 @@ bool(false) Notice: Undefined variable: lable in %s on line %d bool(true) -object(Point)#1 (3) { +object(Point)#%d (3) { ["x"]=> int(30) ["y"]=> @@ -1247,7 +1248,7 @@ object(Point)#1 (3) { ["lable"]=> string(6) "Point1" } -object(Point)#1 (2) { +object(Point)#%d (2) { ["y"]=> int(40) ["lable"]=> @@ -1255,7 +1256,7 @@ object(Point)#1 (2) { } bool(false) bool(true) -object(Point)#1 (0) { +object(Point)#%d (0) { } bool(true) bool(false) @@ -1276,7 +1277,7 @@ array(3) { [2]=> string(9) "testPoint" } -object(Point)#1 (3) { +object(Point)#%d (3) { ["x"]=> int(5) ["y"]=> @@ -1329,4 +1330,4 @@ bool(false) bool(false) bool(true) int(10) -Done +===DONE=== diff --git a/Zend/tests/024.phpt b/Zend/tests/024.phpt index 6fe10201f..ff35a5c89 100644 --- a/Zend/tests/024.phpt +++ b/Zend/tests/024.phpt @@ -18,17 +18,17 @@ var_dump($a->$b->$c[1]); Notice: Undefined variable: a in %s on line %d NULL -Notice: Undefined variable: c in %s on line %d +Notice: Undefined variable: %s in %s on line %d -Notice: Undefined variable: a in %s on line %d +Notice: Undefined variable: %s in %s on line %d NULL Notice: Undefined variable: a in %s on line %d int(1) -Notice: Undefined variable: b in %s on line %d +Notice: Undefined variable: %s in %s on line %d -Notice: Undefined variable: a in %s on line %d +Notice: Undefined variable: %s in %s on line %d int(0) Notice: Undefined variable: a in %s on line %d diff --git a/Zend/tests/bug30162.phpt b/Zend/tests/bug30162.phpt index ae11f8ff8..a011292a1 100755 --- a/Zend/tests/bug30162.phpt +++ b/Zend/tests/bug30162.phpt @@ -41,12 +41,14 @@ $db = new hariCow; var_dump($db); ?> +===DONE=== --EXPECTF-- Notice: Undefined variable: db in %sbug30162.php on line 35 NULL -object(hariCow)#1 (2) { +object(hariCow)#%d (2) { ["x"]=> string(1) "x" ["y"]=> string(1) "y" } +===DONE=== \ No newline at end of file diff --git a/Zend/tests/bug39542/bug39542.php b/Zend/tests/bug39542/bug39542.php index 110951766..90cb36cc6 100755 --- a/Zend/tests/bug39542/bug39542.php +++ b/Zend/tests/bug39542/bug39542.php @@ -1,7 +1,7 @@ - + diff --git a/Zend/tests/bug40236.inc b/Zend/tests/bug40236.inc index 0fbbfc9ff..fc03349f7 100755 --- a/Zend/tests/bug40236.inc +++ b/Zend/tests/bug40236.inc @@ -1,10 +1,10 @@ - \ No newline at end of file diff --git a/Zend/tests/bug46106.phpt b/Zend/tests/bug46106.phpt index 9afb0ef46..f18c25a6c 100644 --- a/Zend/tests/bug46106.phpt +++ b/Zend/tests/bug46106.phpt @@ -1,22 +1,22 @@ ---TEST-- -Bug #46106 (Memory leaks when using global statement) ---FILE-- -invokeArgs(array(0)); -} - -$x = new ReflectionFunction('str_pad'); -test($x); -?> -DONE ---EXPECT-- -DONE +--TEST-- +Bug #46106 (Memory leaks when using global statement) +--FILE-- +invokeArgs(array(0)); +} + +$x = new ReflectionFunction('str_pad'); +test($x); +?> +DONE +--EXPECT-- +DONE diff --git a/Zend/tests/bug47109.phpt b/Zend/tests/bug47109.phpt index b374202be..8f810d7fb 100644 --- a/Zend/tests/bug47109.phpt +++ b/Zend/tests/bug47109.phpt @@ -1,11 +1,11 @@ ---TEST-- -Bug #47109 (Memory leak on $a->{"a"."b"} when $a is not an object) ---FILE-- -{"a"."b"}; -?> ---EXPECTF-- -Notice: Undefined variable: a in %sbug47109.php on line 2 - -Notice: Trying to get property of non-object in %sbug47109.php on line 2 - +--TEST-- +Bug #47109 (Memory leak on $a->{"a"."b"} when $a is not an object) +--FILE-- +{"a"."b"}; +?> +--EXPECTF-- +Notice: Undefined variable: a in %sbug47109.php on line 2 + +Notice: Trying to get property of non-object in %sbug47109.php on line 2 + diff --git a/Zend/tests/bug48693.phpt b/Zend/tests/bug48693.phpt new file mode 100644 index 000000000..e57434602 --- /dev/null +++ b/Zend/tests/bug48693.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #48693 (Double declaration of __lambda_func when lambda wrongly formatted) +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected '}' in %s(%d) : runtime-created function on line 1 + +Parse error: syntax error, unexpected $end in %s(%d) : runtime-created function on line 1 +bool(false) +int(2) +bool(false) +int(3) +bool(true) diff --git a/Zend/tests/bug48770.phpt b/Zend/tests/bug48770.phpt new file mode 100644 index 000000000..40fa84157 --- /dev/null +++ b/Zend/tests/bug48770.phpt @@ -0,0 +1,53 @@ +--TEST-- +Bug #48770 (call_user_func_array() fails to call parent from inheriting class) +--XFAIL-- +See Bug #48770 +--FILE-- +func('This should work!'); + +?> +--EXPECTF-- +%unicode|string%(26) "A::func: This should work!" diff --git a/Zend/tests/bug48770_2.phpt b/Zend/tests/bug48770_2.phpt new file mode 100644 index 000000000..dff54e155 --- /dev/null +++ b/Zend/tests/bug48770_2.phpt @@ -0,0 +1,54 @@ +--TEST-- +Bug #48770 (call_user_func_array() fails to call parent from inheriting class) +--XFAIL-- +See Bug #48770 +--FILE-- +func('This should work!'); + +?> +--EXPECTF-- +%unicode|string%(27) "A::func2: This should work!" +%unicode|string%(27) "A::func3: This should work!" + +Warning: call_user_func_array() expects parameter 1 to be a valid callback, cannot access private method A::func22() in %s on line %d + +Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'A' does not have a method 'inexistent' in %s on line %d diff --git a/Zend/tests/bug48770_3.phpt b/Zend/tests/bug48770_3.phpt new file mode 100644 index 000000000..68fe84314 --- /dev/null +++ b/Zend/tests/bug48770_3.phpt @@ -0,0 +1,51 @@ +--TEST-- +Bug #48770 (call_user_func_array() fails to call parent from inheriting class) +--XFAIL-- +See Bug #48770 +--FILE-- +func('This should work!'); + +?> +--EXPECTF-- +%unicode|string%(27) "B::func2: This should work!" +%unicode|string%(27) "B::func3: This should work!" + +Warning: call_user_func_array() expects parameter 1 to be a valid callback, class 'B' does not have a method 'inexistent' in %s on line %d diff --git a/Zend/tests/bug48899.phpt b/Zend/tests/bug48899.phpt new file mode 100644 index 000000000..ff640543c --- /dev/null +++ b/Zend/tests/bug48899.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #48899 (is_callable returns true even if method does not exist in parent class) +--FILE-- +testIsCallable(); +$child->testIsCallable2(); + +?> +--EXPECT-- +bool(false) +bool(true) diff --git a/Zend/tests/bug48912.phpt b/Zend/tests/bug48912.phpt new file mode 100644 index 000000000..dc021a2ef --- /dev/null +++ b/Zend/tests/bug48912.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #48912 (Namespace causes unexpected strict behaviour with extract()) +--FILE-- + 1)); +echo "ok\n"; +?> +--EXPECT-- +ok diff --git a/Zend/tests/bug49269.phpt b/Zend/tests/bug49269.phpt new file mode 100644 index 000000000..2de29d8b9 --- /dev/null +++ b/Zend/tests/bug49269.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #49269 (Ternary operator fails on Iterator object when used inside foreach declaration). +--FILE-- +n < 3); + } + function current() {return $this->n;} + function next() {$this->n++;} + function key() { } + function rewind() {$this->n = 0;} +} + + +$array_object = new TestObject(); + +foreach ((true ? $array_object : $array_object) as $item) echo "$item\n"; +?> +--EXPECT-- +0 +1 +2 diff --git a/Zend/tests/bug49908.phpt b/Zend/tests/bug49908.phpt new file mode 100644 index 000000000..08d6383d8 --- /dev/null +++ b/Zend/tests/bug49908.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #49908 (throwing exception in __autoload crashes when interface is not defined) +--FILE-- + +--EXPECTF-- +%unicode|string%(3) "Foo" +%unicode|string%(3) "Bar" + +Fatal error: Uncaught exception 'Exception' with message 'Bar' in %s:%d +Stack trace: +#0 %s(7): __autoload('Bar') +#1 %s(13): __autoload('Foo') +#2 {main} + thrown in %s on line %d diff --git a/Zend/tests/call_user_func_001.phpt b/Zend/tests/call_user_func_001.phpt new file mode 100644 index 000000000..e9b35f957 --- /dev/null +++ b/Zend/tests/call_user_func_001.phpt @@ -0,0 +1,35 @@ +--TEST-- +Testing call_user_func inside namespace +--FILE-- + +--EXPECTF-- +%string|unicode%(6) "foobar" + +Warning: call_user_func() expects parameter 1 to be a valid callback, cannot access private method testing\foo::priv() in %s on line %d + +Warning: call_user_func() expects parameter 1 to be a valid callback, cannot access protected method testing\foo::prot() in %s on line %d diff --git a/Zend/tests/call_user_func_002.phpt b/Zend/tests/call_user_func_002.phpt new file mode 100644 index 000000000..e79dd1a75 --- /dev/null +++ b/Zend/tests/call_user_func_002.phpt @@ -0,0 +1,29 @@ +--TEST-- +Testing call_user_func() with autoload and passing invalid params +--FILE-- + +--EXPECTF-- +%unicode|string%(3) "foo" + +Warning: call_user_func() expects parameter 1 to be a valid callback, class 'foo' not found in %s on line %d + +Warning: call_user_func() expects parameter 1 to be a valid callback, class '' not found in %s on line %d + +Notice: Undefined variable: foo in %s on line %d + +Warning: call_user_func() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in %s on line %d + +Notice: Undefined variable: foo in %s on line %d + +Warning: call_user_func() expects parameter 1 to be a valid callback, first array member is not a valid class name or object in %s on line %d diff --git a/Zend/tests/call_user_func_003.phpt b/Zend/tests/call_user_func_003.phpt new file mode 100644 index 000000000..d516584eb --- /dev/null +++ b/Zend/tests/call_user_func_003.phpt @@ -0,0 +1,31 @@ +--TEST-- +Testing call_user_func() with closures +--FILE-- +__invoke()); +var_dump(call_user_func(function() use (&$foo) { return $foo; }, '__invoke')); + +?> +--EXPECTF-- +%unicode|string%(3) "OK!" +object(Closure)#%d (1) { + [%u|b%"static"]=> + array(1) { + [%u|b%"instance"]=> + object(Closure)#%d (0) { + } + } +} diff --git a/Zend/tests/closure_034.phpt b/Zend/tests/closure_034.phpt new file mode 100644 index 000000000..d1356c31d --- /dev/null +++ b/Zend/tests/closure_034.phpt @@ -0,0 +1,25 @@ +--TEST-- +Closure 033: Recursive var_dump on closures +--FILE-- + +===DONE=== +--EXPECTF-- +object(Closure)#1 (1) { + ["static"]=> + array(1) { + ["a"]=> + &object(Closure)#1 (1) { + ["static"]=> + array(1) { + ["a"]=> + *RECURSION* + } + } + } +} +===DONE=== diff --git a/Zend/tests/constants_002.phpt b/Zend/tests/constants_002.phpt index 2e769f5db..5acca981f 100644 --- a/Zend/tests/constants_002.phpt +++ b/Zend/tests/constants_002.phpt @@ -16,9 +16,3 @@ Warning: Constants may only evaluate to scalar values in %s on line %d Notice: Use of undefined constant foo - assumed 'foo' in %s on line %d string(%d) "foo" resource(%d) of type (stream) ---UEXPECTF-- -Warning: Constants may only evaluate to scalar values in %s on line %d - -Notice: Use of undefined constant foo - assumed 'foo' in %s on line %d -unicode(%d) "foo" -resource(%d) of type (stream) diff --git a/Zend/tests/each_003.phpt b/Zend/tests/each_003.phpt index 8c0c32a7f..2361d6a31 100644 --- a/Zend/tests/each_003.phpt +++ b/Zend/tests/each_003.phpt @@ -22,16 +22,3 @@ array(4) { ["key"]=> int(0) } ---UEXPECTF-- -array(4) { - [1]=> - array(0) { - } - [u"value"]=> - array(0) { - } - [0]=> - int(0) - [u"key"]=> - int(0) -} diff --git a/Zend/tests/function_exists_error.phpt b/Zend/tests/function_exists_error.phpt index c95dc0718..cbc3908f1 100644 --- a/Zend/tests/function_exists_error.phpt +++ b/Zend/tests/function_exists_error.phpt @@ -1,6 +1,5 @@ --TEST-- Test function_exists() function : error conditions ---INI-- --FILE-- foo(); --EXPECT-- string(3) "bar" bool(false) ---UEXPECT-- -unicode(3) "bar" -bool(false) diff --git a/Zend/tests/get_required_files.phpt b/Zend/tests/get_required_files.phpt new file mode 100644 index 000000000..c2ba36888 --- /dev/null +++ b/Zend/tests/get_required_files.phpt @@ -0,0 +1,16 @@ +--TEST-- +Check if get_required_files works +--CREDITS-- +Sebastian Schürmann +sschuermann@chip.de +Testfest 2009 Munich +--FILE-- + +--EXPECTF-- +array(1) { + [0]=> + %string|unicode%(%d)%s +} diff --git a/Zend/tests/globals_001.phpt b/Zend/tests/globals_001.phpt index 0f77104ac..8efa71d31 100644 --- a/Zend/tests/globals_001.phpt +++ b/Zend/tests/globals_001.phpt @@ -1,6 +1,6 @@ --TEST-- globals in global scope ---INIT-- +--INI-- variables_order="egpcs" --FILE-- +--EXPECTF-- +Done. diff --git a/Zend/tests/unset_cv07.phpt b/Zend/tests/unset_cv07.phpt index fe16abf75..b7bdb7db5 100644 --- a/Zend/tests/unset_cv07.phpt +++ b/Zend/tests/unset_cv07.phpt @@ -1,7 +1,5 @@ --TEST-- unset() CV 7 (indirect unset() of global variable in import_request_variables()) ---SKIPIF-- - --GET-- x=2 --FILE-- diff --git a/Zend/tests/zend_operators.phpt b/Zend/tests/zend_operators.phpt index 99fdf0217..00546b243 100644 --- a/Zend/tests/zend_operators.phpt +++ b/Zend/tests/zend_operators.phpt @@ -1,7 +1,7 @@ --TEST-- Operator precedence --FILE-- - #endif -#if HAVE_MACH_O_DYLD_H -#include - -/* MH_BUNDLE loading functions for Mac OS X / Darwin */ -void *zend_mh_bundle_load (char* bundle_path); -int zend_mh_bundle_unload (void *bundle_handle); -void *zend_mh_bundle_symbol(void *bundle_handle, const char *symbol_name); -const char *zend_mh_bundle_error(void); - -#endif /* HAVE_MACH_O_DYLD_H */ - -#if defined(HAVE_LIBDL) && !defined(HAVE_MACH_O_DYLD_H) && !defined(ZEND_WIN32) +#if defined(HAVE_LIBDL) && !defined(ZEND_WIN32) # ifndef RTLD_LAZY # define RTLD_LAZY 1 /* Solaris 1, FreeBSD's (2.1.7.1 and older) */ @@ -116,13 +105,6 @@ const char *zend_mh_bundle_error(void); # define DL_ERROR dlerror # define DL_HANDLE void * # define ZEND_EXTENSIONS_SUPPORT 1 -#elif defined(HAVE_MACH_O_DYLD_H) -# define DL_LOAD(libname) zend_mh_bundle_load(libname) -# define DL_UNLOAD zend_mh_bundle_unload -# define DL_FETCH_SYMBOL(h,s) zend_mh_bundle_symbol(h,s) -# define DL_ERROR zend_mh_bundle_error -# define DL_HANDLE void * -# define ZEND_EXTENSIONS_SUPPORT 1 #elif defined(ZEND_WIN32) # define DL_LOAD(libname) LoadLibrary(libname) # define DL_FETCH_SYMBOL GetProcAddress diff --git a/Zend/zend_API.c b/Zend/zend_API.c index 578822979..6a5c5f87a 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_API.c,v 1.296.2.27.2.34.2.64 2009/06/04 18:20:42 mattwil Exp $ */ +/* $Id: zend_API.c 289431 2009-10-09 17:21:20Z pajoye $ */ #include "zend.h" #include "zend_execute.h" @@ -1038,13 +1038,13 @@ ZEND_API void zend_update_class_constants(zend_class_entry *class_type TSRMLS_DC Z_SET_ISREF_PP(q); zend_hash_add(CE_STATIC_MEMBERS(class_type), str_index, str_length, (void**)q, sizeof(zval*), NULL); } else { - zval *q; + zval *r; - ALLOC_ZVAL(q); - *q = **p; - INIT_PZVAL(q); - zval_copy_ctor(q); - zend_hash_add(CE_STATIC_MEMBERS(class_type), str_index, str_length, (void**)&q, sizeof(zval*), NULL); + ALLOC_ZVAL(r); + *r = **p; + INIT_PZVAL(r); + zval_copy_ctor(r); + zend_hash_add(CE_STATIC_MEMBERS(class_type), str_index, str_length, (void**)&r, sizeof(zval*), NULL); } zend_hash_move_forward_ex(&class_type->default_static_members, &pos); } @@ -2114,7 +2114,7 @@ void module_destructor(zend_module_entry *module) /* {{{ */ zend_unregister_functions(module->functions, -1, NULL TSRMLS_CC); } -#if HAVE_LIBDL || defined(HAVE_MACH_O_DYLD_H) +#if HAVE_LIBDL #if !(defined(NETWARE) && defined(APACHE_1_BUILD)) if (module->handle) { DL_UNLOAD(module->handle); @@ -2519,7 +2519,7 @@ static int zend_is_callable_check_func(int check_flags, zval *callable, zend_fca } } else { get_function_via_handler: - if (fcc->object_ptr) { + if (fcc->object_ptr && fcc->calling_scope == ce_org) { if (Z_OBJ_HT_P(fcc->object_ptr)->get_method) { fcc->function_handler = Z_OBJ_HT_P(fcc->object_ptr)->get_method(&fcc->object_ptr, mname, mlen TSRMLS_CC); if (fcc->function_handler) { diff --git a/Zend/zend_API.h b/Zend/zend_API.h index c286f2d8c..032f83017 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_API.h,v 1.207.2.8.2.8.2.24 2008/12/31 11:15:31 sebastian Exp $ */ +/* $Id: zend_API.h 286469 2009-07-28 21:12:42Z jani $ */ #ifndef ZEND_API_H #define ZEND_API_H @@ -90,7 +90,7 @@ typedef struct _zend_fcall_info_cache { #define ZEND_NS_RAW_FENTRY(ns, zend_name, name, arg_info, flags) ZEND_RAW_FENTRY(ZEND_NS_NAME(ns, zend_name), name, arg_info, flags) #define ZEND_NS_RAW_NAMED_FE(ns, zend_name, name, arg_info) ZEND_NS_RAW_FENTRY(ns, #zend_name, name, arg_info, 0) -#define ZEND_NS_NAMED_FE(ns, zend_name, name, arg_info) +#define ZEND_NS_NAMED_FE(ns, zend_name, name, arg_info) ZEND_NS_FENTRY(ns, #zend_name, name, arg_info, 0) #define ZEND_NS_FE(ns, name, arg_info) ZEND_NS_FENTRY(ns, name, ZEND_FN(name), arg_info, 0) #define ZEND_NS_DEP_FE(ns, name, arg_info) ZEND_NS_FENTRY(ns, name, ZEND_FN(name), arg_info, ZEND_ACC_DEPRECATED) #define ZEND_NS_FALIAS(ns, name, alias, arg_info) ZEND_NS_FENTRY(ns, name, ZEND_FN(alias), arg_info, 0) diff --git a/Zend/zend_alloc.c b/Zend/zend_alloc.c index 9eafda448..683ccf960 100644 --- a/Zend/zend_alloc.c +++ b/Zend/zend_alloc.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_alloc.c,v 1.144.2.3.2.43.2.24 2009/05/30 16:42:13 lbarnaud Exp $ */ +/* $Id: zend_alloc.c 287992 2009-09-03 14:33:11Z dmitry $ */ #include "zend.h" #include "zend_alloc.h" @@ -512,20 +512,7 @@ static unsigned int _zend_mm_cookie = 0; /* optimized access */ #define ZEND_MM_FREE_BLOCK_SIZE(b) (b)->info._size -#ifndef ZEND_MM_ALIGNMENT -# define ZEND_MM_ALIGNMENT 8 -# define ZEND_MM_ALIGNMENT_LOG2 3 -#elif ZEND_MM_ALIGNMENT < 4 -# undef ZEND_MM_ALIGNMENT -# undef ZEND_MM_ALIGNMENT_LOG2 -# define ZEND_MM_ALIGNMENT 4 -# define ZEND_MM_ALIGNMENT_LOG2 2 -#endif - -#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1) - /* Aligned header size */ -#define ZEND_MM_ALIGNED_SIZE(size) ((size + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK) #define ZEND_MM_ALIGNED_HEADER_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block)) #define ZEND_MM_ALIGNED_FREE_HEADER_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block)) #define ZEND_MM_MIN_ALLOC_BLOCK_SIZE ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE) @@ -709,12 +696,14 @@ static inline unsigned int zend_mm_low_bit(size_t _size) unsigned int n; unsigned int index = 0; - do { - n = offset[_size & 15]; + n = offset[_size & 15]; + while (n == 4) { _size >>= 4; index += n; - } while (n == 4); - return index; + n = offset[_size & 15]; + } + + return index + n; #endif } diff --git a/Zend/zend_alloc.h b/Zend/zend_alloc.h index daa37c7d0..b1ecab948 100644 --- a/Zend/zend_alloc.h +++ b/Zend/zend_alloc.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_alloc.h,v 1.63.2.2.2.12.2.10 2009/06/28 09:48:48 pajoye Exp $ */ +/* $Id: zend_alloc.h 287992 2009-09-03 14:33:11Z dmitry $ */ #ifndef ZEND_ALLOC_H #define ZEND_ALLOC_H @@ -27,6 +27,20 @@ #include "../TSRM/TSRM.h" #include "zend.h" +#ifndef ZEND_MM_ALIGNMENT +# define ZEND_MM_ALIGNMENT 8 +# define ZEND_MM_ALIGNMENT_LOG2 3 +#elif ZEND_MM_ALIGNMENT < 4 +# undef ZEND_MM_ALIGNMENT +# undef ZEND_MM_ALIGNMENT_LOG2 +# define ZEND_MM_ALIGNMENT 4 +# define ZEND_MM_ALIGNMENT_LOG2 2 +#endif + +#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1) + +#define ZEND_MM_ALIGNED_SIZE(size) (((size) + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK) + typedef struct _zend_leak_info { void *addr; size_t size; diff --git a/Zend/zend_builtin_functions.c b/Zend/zend_builtin_functions.c index e965c5dee..ec29a4934 100644 --- a/Zend/zend_builtin_functions.c +++ b/Zend/zend_builtin_functions.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_builtin_functions.c,v 1.277.2.12.2.25.2.52 2009/06/08 21:27:05 pajoye Exp $ */ +/* $Id: zend_builtin_functions.c 286878 2009-08-06 11:02:25Z jani $ */ #include "zend.h" #include "zend_API.h" @@ -747,7 +747,7 @@ ZEND_FUNCTION(get_class) zend_uint name_len = 0; int dup; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o", &obj) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|o!", &obj) == FAILURE) { RETURN_FALSE; } @@ -1755,6 +1755,7 @@ ZEND_FUNCTION(create_function) zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME)); RETURN_STRINGL(function_name, function_name_length, 0); } else { + zend_hash_del(EG(function_table), LAMBDA_TEMP_FUNCNAME, sizeof(LAMBDA_TEMP_FUNCNAME)); RETURN_FALSE; } } diff --git a/Zend/zend_builtin_functions.h b/Zend/zend_builtin_functions.h index 68175b323..aca6d77e8 100644 --- a/Zend/zend_builtin_functions.h +++ b/Zend/zend_builtin_functions.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_builtin_functions.h,v 1.17.2.2.2.1.2.2 2008/12/31 11:15:31 sebastian Exp $ */ +/* $Id: zend_builtin_functions.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_BUILTIN_FUNCTIONS_H #define ZEND_BUILTIN_FUNCTIONS_H diff --git a/Zend/zend_closures.c b/Zend/zend_closures.c index a28f8ccfd..96fc56748 100644 --- a/Zend/zend_closures.c +++ b/Zend/zend_closures.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_closures.c,v 1.3.2.26 2009/01/26 22:54:18 cseiler Exp $ */ +/* $Id: zend_closures.c 287043 2009-08-10 15:18:13Z colder $ */ #include "zend.h" #include "zend_API.h" @@ -37,6 +37,7 @@ typedef struct _zend_closure { zend_object std; zend_function func; + HashTable *debug_info; } zend_closure; /* non-static since it needs to be referenced */ @@ -179,6 +180,11 @@ static void zend_closure_free_storage(void *object TSRMLS_DC) /* {{{ */ destroy_op_array(&closure->func.op_array TSRMLS_CC); } + if (closure->debug_info != NULL) { + zend_hash_destroy(closure->debug_info); + efree(closure->debug_info); + } + efree(closure); } /* }}} */ @@ -222,48 +228,53 @@ int zend_closure_get_closure(zval *obj, zend_class_entry **ce_ptr, zend_function static HashTable *zend_closure_get_debug_info(zval *object, int *is_temp TSRMLS_DC) /* {{{ */ { zend_closure *closure = (zend_closure *)zend_object_store_get_object(object TSRMLS_CC); - HashTable *rv; zval *val; struct _zend_arg_info *arg_info = closure->func.common.arg_info; - *is_temp = 1; - ALLOC_HASHTABLE(rv); - zend_hash_init(rv, 1, NULL, ZVAL_PTR_DTOR, 0); - if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) { - HashTable *static_variables = closure->func.op_array.static_variables; - MAKE_STD_ZVAL(val); - array_init(val); - zend_hash_copy(Z_ARRVAL_P(val), static_variables, (copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval*)); - zend_symtable_update(rv, "static", sizeof("static"), (void *) &val, sizeof(zval *), NULL); - } + *is_temp = 0; - if (arg_info) { - zend_uint i, required = closure->func.common.required_num_args; - - MAKE_STD_ZVAL(val); - array_init(val); + if (closure->debug_info == NULL) { + ALLOC_HASHTABLE(closure->debug_info); + zend_hash_init(closure->debug_info, 1, NULL, ZVAL_PTR_DTOR, 0); + } + if (closure->debug_info->nApplyCount == 0) { + if (closure->func.type == ZEND_USER_FUNCTION && closure->func.op_array.static_variables) { + HashTable *static_variables = closure->func.op_array.static_variables; + MAKE_STD_ZVAL(val); + array_init(val); + zend_hash_copy(Z_ARRVAL_P(val), static_variables, (copy_ctor_func_t)zval_add_ref, NULL, sizeof(zval*)); + zend_symtable_update(closure->debug_info, "static", sizeof("static"), (void *) &val, sizeof(zval *), NULL); + } - for (i = 0; i < closure->func.common.num_args; i++) { - char *name, *info; - int name_len, info_len; - if (arg_info->name) { - name_len = zend_spprintf(&name, 0, "%s$%s", - arg_info->pass_by_reference ? "&" : "", - arg_info->name); - } else { - name_len = zend_spprintf(&name, 0, "%s$param%d", - arg_info->pass_by_reference ? "&" : "", - i + 1); + if (arg_info) { + zend_uint i, required = closure->func.common.required_num_args; + + MAKE_STD_ZVAL(val); + array_init(val); + + for (i = 0; i < closure->func.common.num_args; i++) { + char *name, *info; + int name_len, info_len; + if (arg_info->name) { + name_len = zend_spprintf(&name, 0, "%s$%s", + arg_info->pass_by_reference ? "&" : "", + arg_info->name); + } else { + name_len = zend_spprintf(&name, 0, "%s$param%d", + arg_info->pass_by_reference ? "&" : "", + i + 1); + } + info_len = zend_spprintf(&info, 0, "%s", + i >= required ? "" : ""); + add_assoc_stringl_ex(val, name, name_len + 1, info, info_len, 0); + efree(name); + arg_info++; } - info_len = zend_spprintf(&info, 0, "%s", - i >= required ? "" : ""); - add_assoc_stringl_ex(val, name, name_len + 1, info, info_len, 0); - efree(name); - arg_info++; + zend_symtable_update(closure->debug_info, "parameter", sizeof("parameter"), (void *) &val, sizeof(zval *), NULL); } - zend_symtable_update(rv, "parameter", sizeof("parameter"), (void *) &val, sizeof(zval *), NULL); } - return rv; + + return closure->debug_info; } /* }}} */ diff --git a/Zend/zend_closures.h b/Zend/zend_closures.h index 79d28f087..64c476b48 100644 --- a/Zend/zend_closures.h +++ b/Zend/zend_closures.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_closures.h,v 1.1.2.8 2009/01/26 22:54:19 cseiler Exp $ */ +/* $Id: zend_closures.h 274683 2009-01-26 22:54:34Z cseiler $ */ #ifndef ZEND_CLOSURES_H #define ZEND_CLOSURES_H diff --git a/Zend/zend_compile.c b/Zend/zend_compile.c index 06608abd0..a02278f27 100644 --- a/Zend/zend_compile.c +++ b/Zend/zend_compile.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.c,v 1.647.2.27.2.41.2.109 2009/06/07 15:46:51 mattwil Exp $ */ +/* $Id: zend_compile.c 289432 2009-10-09 17:23:01Z pajoye $ */ #include #include "zend.h" @@ -40,36 +40,40 @@ ZEND_API zend_compiler_globals compiler_globals; ZEND_API zend_executor_globals executor_globals; #endif -static void zend_duplicate_property_info(zend_property_info *property_info) +static void zend_duplicate_property_info(zend_property_info *property_info) /* {{{ */ { property_info->name = estrndup(property_info->name, property_info->name_length); if (property_info->doc_comment) { property_info->doc_comment = estrndup(property_info->doc_comment, property_info->doc_comment_len); } } +/* }}} */ -static void zend_duplicate_property_info_internal(zend_property_info *property_info) +static void zend_duplicate_property_info_internal(zend_property_info *property_info) /* {{{ */ { property_info->name = zend_strndup(property_info->name, property_info->name_length); } +/* }}} */ -static void zend_destroy_property_info(zend_property_info *property_info) +static void zend_destroy_property_info(zend_property_info *property_info) /* {{{ */ { efree(property_info->name); if (property_info->doc_comment) { efree(property_info->doc_comment); } } +/* }}} */ -static void zend_destroy_property_info_internal(zend_property_info *property_info) +static void zend_destroy_property_info_internal(zend_property_info *property_info) /* {{{ */ { free(property_info->name); } +/* }}} */ -static void build_runtime_defined_function_key(zval *result, const char *name, int name_length TSRMLS_DC) +static void build_runtime_defined_function_key(zval *result, const char *name, int name_length TSRMLS_DC) /* {{{ */ { char char_pos_buf[32]; uint char_pos_len; @@ -95,16 +99,18 @@ static void build_runtime_defined_function_key(zval *result, const char *name, i result->type = IS_STRING; Z_SET_REFCOUNT_P(result, 1); } +/* }}} */ -int zend_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC) +int zend_auto_global_arm(zend_auto_global *auto_global TSRMLS_DC) /* {{{ */ { auto_global->armed = (auto_global->auto_global_callback ? 1 : 0); return 0; } +/* }}} */ -ZEND_API int zend_auto_global_disable_jit(const char *varname, zend_uint varname_length TSRMLS_DC) +ZEND_API int zend_auto_global_disable_jit(const char *varname, zend_uint varname_length TSRMLS_DC) /* {{{ */ { zend_auto_global *auto_global; @@ -114,16 +120,18 @@ ZEND_API int zend_auto_global_disable_jit(const char *varname, zend_uint varname auto_global->armed = 0; return SUCCESS; } +/* }}} */ -static void init_compiler_declarables(TSRMLS_D) +static void init_compiler_declarables(TSRMLS_D) /* {{{ */ { Z_TYPE(CG(declarables).ticks) = IS_LONG; Z_LVAL(CG(declarables).ticks) = 0; } +/* }}} */ -void zend_init_compiler_data_structures(TSRMLS_D) +void zend_init_compiler_data_structures(TSRMLS_D) /* {{{ */ { zend_stack_init(&CG(bp_stack)); zend_stack_init(&CG(function_call_stack)); @@ -155,17 +163,19 @@ void zend_init_compiler_data_structures(TSRMLS_D) CG(encoding_oddlen) = NULL; #endif /* ZEND_MULTIBYTE */ } +/* }}} */ -ZEND_API void file_handle_dtor(zend_file_handle *fh) +ZEND_API void file_handle_dtor(zend_file_handle *fh) /* {{{ */ { TSRMLS_FETCH(); zend_file_handle_dtor(fh TSRMLS_CC); } +/* }}} */ -void init_compiler(TSRMLS_D) +void init_compiler(TSRMLS_D) /* {{{ */ { CG(active_op_array) = NULL; zend_init_compiler_data_structures(TSRMLS_C); @@ -174,9 +184,10 @@ void init_compiler(TSRMLS_D) zend_llist_init(&CG(open_files), sizeof(zend_file_handle), (void (*)(void *)) file_handle_dtor, 0); CG(unclean_shutdown) = 0; } +/* }}} */ -void shutdown_compiler(TSRMLS_D) +void shutdown_compiler(TSRMLS_D) /* {{{ */ { zend_stack_destroy(&CG(bp_stack)); zend_stack_destroy(&CG(function_call_stack)); @@ -195,9 +206,10 @@ void shutdown_compiler(TSRMLS_D) } #endif /* ZEND_MULTIBYTE */ } +/* }}} */ -ZEND_API char *zend_set_compiled_filename(const char *new_compiled_filename TSRMLS_DC) +ZEND_API char *zend_set_compiled_filename(const char *new_compiled_filename TSRMLS_DC) /* {{{ */ { char **pp, *p; int length = strlen(new_compiled_filename); @@ -211,38 +223,44 @@ ZEND_API char *zend_set_compiled_filename(const char *new_compiled_filename TSRM CG(compiled_filename) = p; return p; } +/* }}} */ -ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC) +ZEND_API void zend_restore_compiled_filename(char *original_compiled_filename TSRMLS_DC) /* {{{ */ { CG(compiled_filename) = original_compiled_filename; } +/* }}} */ -ZEND_API char *zend_get_compiled_filename(TSRMLS_D) +ZEND_API char *zend_get_compiled_filename(TSRMLS_D) /* {{{ */ { return CG(compiled_filename); } +/* }}} */ -ZEND_API int zend_get_compiled_lineno(TSRMLS_D) +ZEND_API int zend_get_compiled_lineno(TSRMLS_D) /* {{{ */ { return CG(zend_lineno); } +/* }}} */ -ZEND_API zend_bool zend_is_compiling(TSRMLS_D) +ZEND_API zend_bool zend_is_compiling(TSRMLS_D) /* {{{ */ { return CG(in_compilation); } +/* }}} */ -static zend_uint get_temporary_variable(zend_op_array *op_array) +static zend_uint get_temporary_variable(zend_op_array *op_array) /* {{{ */ { - return (op_array->T)++ * sizeof(temp_variable); + return (op_array->T)++ * ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)); } +/* }}} */ -static int lookup_cv(zend_op_array *op_array, char* name, int name_len) +static int lookup_cv(zend_op_array *op_array, char* name, int name_len) /* {{{ */ { int i = 0; ulong hash_value = zend_inline_hash_func(name, name_len+1); @@ -267,9 +285,10 @@ static int lookup_cv(zend_op_array *op_array, char* name, int name_len) op_array->vars[i].hash_value = hash_value; return i; } +/* }}} */ -void zend_do_binary_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC) +void zend_do_binary_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -280,9 +299,9 @@ void zend_do_binary_op(zend_uchar op, znode *result, const znode *op1, const zno opline->op2 = *op2; *result = opline->result; } +/* }}} */ - -void zend_do_unary_op(zend_uchar op, znode *result, const znode *op1 TSRMLS_DC) +void zend_do_unary_op(zend_uchar op, znode *result, const znode *op1 TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -293,18 +312,20 @@ void zend_do_unary_op(zend_uchar op, znode *result, const znode *op1 TSRMLS_DC) *result = opline->result; SET_UNUSED(opline->op2); } +/* }}} */ #define MAKE_NOP(opline) { opline->opcode = ZEND_NOP; memset(&opline->result,0,sizeof(znode)); memset(&opline->op1,0,sizeof(znode)); memset(&opline->op2,0,sizeof(znode)); opline->result.op_type=opline->op1.op_type=opline->op2.op_type=IS_UNUSED; } -static void zend_do_op_data(zend_op *data_op, const znode *value TSRMLS_DC) +static void zend_do_op_data(zend_op *data_op, const znode *value TSRMLS_DC) /* {{{ */ { data_op->opcode = ZEND_OP_DATA; data_op->op1 = *value; SET_UNUSED(data_op->op2); } +/* }}} */ -void zend_do_binary_assign_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC) +void zend_do_binary_assign_op(zend_uchar op, znode *result, const znode *op1, const znode *op2 TSRMLS_DC) /* {{{ */ { int last_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -345,8 +366,9 @@ void zend_do_binary_assign_op(zend_uchar op, znode *result, const znode *op1, co opline->result.u.var = get_temporary_variable(CG(active_op_array)); *result = opline->result; } +/* }}} */ -void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar op TSRMLS_DC) +void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar op TSRMLS_DC) /* {{{ */ { zend_op opline; zend_op *opline_ptr; @@ -395,14 +417,16 @@ void fetch_simple_variable_ex(znode *result, znode *varname, int bp, zend_uchar zend_llist_add_element(fetch_list_ptr, opline_ptr); } } +/* }}} */ -void fetch_simple_variable(znode *result, znode *varname, int bp TSRMLS_DC) +void fetch_simple_variable(znode *result, znode *varname, int bp TSRMLS_DC) /* {{{ */ { /* the default mode must be Write, since fetch_simple_variable() is used to define function arguments */ fetch_simple_variable_ex(result, varname, bp, ZEND_FETCH_W TSRMLS_CC); } +/* }}} */ -void zend_do_fetch_static_member(znode *result, znode *class_name TSRMLS_DC) +void zend_do_fetch_static_member(znode *result, znode *class_name TSRMLS_DC) /* {{{ */ { znode class_node; zend_llist *fetch_list_ptr; @@ -455,16 +479,17 @@ void zend_do_fetch_static_member(znode *result, znode *class_name TSRMLS_DC) } } } +/* }}} */ -void fetch_array_begin(znode *result, znode *varname, znode *first_dim TSRMLS_DC) +void fetch_array_begin(znode *result, znode *varname, znode *first_dim TSRMLS_DC) /* {{{ */ { fetch_simple_variable(result, varname, 1 TSRMLS_CC); fetch_array_dim(result, result, first_dim TSRMLS_CC); } +/* }}} */ - -void fetch_array_dim(znode *result, const znode *parent, const znode *dim TSRMLS_DC) +void fetch_array_dim(znode *result, const znode *parent, const znode *dim TSRMLS_DC) /* {{{ */ { zend_op opline; zend_llist *fetch_list_ptr; @@ -482,18 +507,15 @@ void fetch_array_dim(znode *result, const znode *parent, const znode *dim TSRMLS zend_stack_top(&CG(bp_stack), (void **) &fetch_list_ptr); zend_llist_add_element(fetch_list_ptr, &opline); } +/* }}} */ - -void fetch_string_offset(znode *result, const znode *parent, const znode *offset TSRMLS_DC) +void fetch_string_offset(znode *result, const znode *parent, const znode *offset TSRMLS_DC) /* {{{ */ { -#ifdef ilia_0 - zend_error(E_DEPRECATED, "Usage of {} to access string offsets is deprecated and will be removed in PHP 6"); -#endif fetch_array_dim(result, parent, offset TSRMLS_CC); } +/* }}} */ - -void zend_do_print(znode *result, const znode *arg TSRMLS_DC) +void zend_do_print(znode *result, const znode *arg TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -504,9 +526,9 @@ void zend_do_print(znode *result, const znode *arg TSRMLS_DC) SET_UNUSED(opline->op2); *result = opline->result; } +/* }}} */ - -void zend_do_echo(const znode *arg TSRMLS_DC) +void zend_do_echo(const znode *arg TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -514,8 +536,9 @@ void zend_do_echo(const znode *arg TSRMLS_DC) opline->op1 = *arg; SET_UNUSED(opline->op2); } +/* }}} */ -void zend_do_abstract_method(const znode *function_name, znode *modifiers, const znode *body TSRMLS_DC) +void zend_do_abstract_method(const znode *function_name, znode *modifiers, const znode *body TSRMLS_DC) /* {{{ */ { char *method_type; @@ -546,8 +569,9 @@ void zend_do_abstract_method(const znode *function_name, znode *modifiers, const } } } +/* }}} */ -static zend_bool opline_is_fetch_this(const zend_op *opline TSRMLS_DC) +static zend_bool opline_is_fetch_this(const zend_op *opline TSRMLS_DC) /* {{{ */ { if ((opline->opcode == ZEND_FETCH_W) && (opline->op1.op_type == IS_CONST) && (opline->op1.u.constant.type == IS_STRING) @@ -558,8 +582,9 @@ static zend_bool opline_is_fetch_this(const zend_op *opline TSRMLS_DC) return 0; } } +/* }}} */ -void zend_do_assign(znode *result, znode *variable, const znode *value TSRMLS_DC) +void zend_do_assign(znode *result, znode *variable, const znode *value TSRMLS_DC) /* {{{ */ { int last_op_number; zend_op *opline; @@ -662,15 +687,17 @@ void zend_do_assign(znode *result, znode *variable, const znode *value TSRMLS_DC opline->result.u.var = get_temporary_variable(CG(active_op_array)); *result = opline->result; } +/* }}} */ -static inline zend_bool zend_is_function_or_method_call(const znode *variable) +static inline zend_bool zend_is_function_or_method_call(const znode *variable) /* {{{ */ { zend_uint type = variable->u.EA.type; return ((type & ZEND_PARSED_METHOD_CALL) || (type == ZEND_PARSED_FUNCTION_CALL)); } +/* }}} */ -void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRMLS_DC) +void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRMLS_DC) /* {{{ */ { zend_op *opline; @@ -710,9 +737,9 @@ void zend_do_assign_ref(znode *result, const znode *lvar, const znode *rvar TSRM opline->op1 = *lvar; opline->op2 = *rvar; } +/* }}} */ - -static inline void do_begin_loop(TSRMLS_D) +static inline void do_begin_loop(TSRMLS_D) /* {{{ */ { zend_brk_cont_element *brk_cont_element; int parent; @@ -723,9 +750,9 @@ static inline void do_begin_loop(TSRMLS_D) brk_cont_element->start = get_next_op_number(CG(active_op_array)); brk_cont_element->parent = parent; } +/* }}} */ - -static inline void do_end_loop(int cont_addr, int has_loop_var TSRMLS_DC) +static inline void do_end_loop(int cont_addr, int has_loop_var TSRMLS_DC) /* {{{ */ { if (!has_loop_var) { /* The start fileld is used to free temporary variables in case of exceptions. @@ -737,9 +764,9 @@ static inline void do_end_loop(int cont_addr, int has_loop_var TSRMLS_DC) CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].brk = get_next_op_number(CG(active_op_array)); CG(active_op_array)->current_brk_cont = CG(active_op_array)->brk_cont_array[CG(active_op_array)->current_brk_cont].parent; } +/* }}} */ - -void zend_do_while_cond(const znode *expr, znode *close_bracket_token TSRMLS_DC) +void zend_do_while_cond(const znode *expr, znode *close_bracket_token TSRMLS_DC) /* {{{ */ { int while_cond_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -752,9 +779,9 @@ void zend_do_while_cond(const znode *expr, znode *close_bracket_token TSRMLS_DC) do_begin_loop(TSRMLS_C); INC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_while_end(const znode *while_token, const znode *close_bracket_token TSRMLS_DC) +void zend_do_while_end(const znode *while_token, const znode *close_bracket_token TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -771,9 +798,9 @@ void zend_do_while_end(const znode *while_token, const znode *close_bracket_toke DEC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_for_cond(const znode *expr, znode *second_semicolon_token TSRMLS_DC) +void zend_do_for_cond(const znode *expr, znode *second_semicolon_token TSRMLS_DC) /* {{{ */ { int for_cond_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -783,9 +810,9 @@ void zend_do_for_cond(const znode *expr, znode *second_semicolon_token TSRMLS_DC second_semicolon_token->u.opline_num = for_cond_op_number; SET_UNUSED(opline->op2); } +/* }}} */ - -void zend_do_for_before_statement(const znode *cond_start, const znode *second_semicolon_token TSRMLS_DC) +void zend_do_for_before_statement(const znode *cond_start, const znode *second_semicolon_token TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -799,9 +826,9 @@ void zend_do_for_before_statement(const znode *cond_start, const znode *second_s INC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_for_end(const znode *second_semicolon_token TSRMLS_DC) +void zend_do_for_end(const znode *second_semicolon_token TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -815,9 +842,9 @@ void zend_do_for_end(const znode *second_semicolon_token TSRMLS_DC) DEC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_pre_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC) +void zend_do_pre_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC) /* {{{ */ { int last_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline; @@ -844,9 +871,9 @@ void zend_do_pre_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC opline->result.u.var = get_temporary_variable(CG(active_op_array)); *result = opline->result; } +/* }}} */ - -void zend_do_post_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC) +void zend_do_post_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_DC) /* {{{ */ { int last_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline; @@ -871,9 +898,9 @@ void zend_do_post_incdec(znode *result, const znode *op1, zend_uchar op TSRMLS_D opline->result.u.var = get_temporary_variable(CG(active_op_array)); *result = opline->result; } +/* }}} */ - -void zend_do_if_cond(const znode *cond, znode *closing_bracket_token TSRMLS_DC) +void zend_do_if_cond(const znode *cond, znode *closing_bracket_token TSRMLS_DC) /* {{{ */ { int if_cond_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -884,9 +911,9 @@ void zend_do_if_cond(const znode *cond, znode *closing_bracket_token TSRMLS_DC) SET_UNUSED(opline->op2); INC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_if_after_statement(const znode *closing_bracket_token, unsigned char initialize TSRMLS_DC) +void zend_do_if_after_statement(const znode *closing_bracket_token, unsigned char initialize TSRMLS_DC) /* {{{ */ { int if_end_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -907,9 +934,9 @@ void zend_do_if_after_statement(const znode *closing_bracket_token, unsigned cha SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); } +/* }}} */ - -void zend_do_if_end(TSRMLS_D) +void zend_do_if_end(TSRMLS_D) /* {{{ */ { int next_op_number = get_next_op_number(CG(active_op_array)); zend_llist *jmp_list_ptr; @@ -923,8 +950,9 @@ void zend_do_if_end(TSRMLS_D) zend_stack_del_top(&CG(bp_stack)); DEC_BPC(CG(active_op_array)); } +/* }}} */ -void zend_check_writable_variable(const znode *variable) +void zend_check_writable_variable(const znode *variable) /* {{{ */ { zend_uint type = variable->u.EA.type; @@ -935,17 +963,18 @@ void zend_check_writable_variable(const znode *variable) zend_error(E_COMPILE_ERROR, "Can't use function return value in write context"); } } +/* }}} */ -void zend_do_begin_variable_parse(TSRMLS_D) +void zend_do_begin_variable_parse(TSRMLS_D) /* {{{ */ { zend_llist fetch_list; zend_llist_init(&fetch_list, sizeof(zend_op), NULL, 0); zend_stack_push(&CG(bp_stack), (void *) &fetch_list, sizeof(zend_llist)); } +/* }}} */ - -void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS_DC) +void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS_DC) /* {{{ */ { zend_llist *fetch_list_ptr; zend_llist_element *le; @@ -1030,9 +1059,9 @@ void zend_do_end_variable_parse(znode *variable, int type, int arg_offset TSRMLS zend_llist_destroy(fetch_list_ptr); zend_stack_del_top(&CG(bp_stack)); } +/* }}} */ - -void zend_do_add_string(znode *result, const znode *op1, znode *op2 TSRMLS_DC) +void zend_do_add_string(znode *result, const znode *op1, znode *op2 TSRMLS_DC) /* {{{ */ { zend_op *opline; @@ -1063,9 +1092,9 @@ void zend_do_add_string(znode *result, const znode *op1, znode *op2 TSRMLS_DC) opline->op2 = *op2; *result = opline->result; } +/* }}} */ - -void zend_do_add_variable(znode *result, const znode *op1, const znode *op2 TSRMLS_DC) +void zend_do_add_variable(znode *result, const znode *op1, const znode *op2 TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -1082,8 +1111,9 @@ void zend_do_add_variable(znode *result, const znode *op1, const znode *op2 TSRM opline->op2 = *op2; *result = opline->result; } +/* }}} */ -void zend_do_free(znode *op1 TSRMLS_DC) +void zend_do_free(znode *op1 TSRMLS_DC) /* {{{ */ { if (op1->op_type==IS_TMP_VAR) { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -1124,9 +1154,9 @@ void zend_do_free(znode *op1 TSRMLS_DC) zval_dtor(&op1->u.constant); } } +/* }}} */ - -int zend_do_verify_access_types(const znode *current_access_type, const znode *new_modifier) +int zend_do_verify_access_types(const znode *current_access_type, const znode *new_modifier) /* {{{ */ { if ((Z_LVAL(current_access_type->u.constant) & ZEND_ACC_PPP_MASK) && (Z_LVAL(new_modifier->u.constant) & ZEND_ACC_PPP_MASK)) { @@ -1149,9 +1179,9 @@ int zend_do_verify_access_types(const znode *current_access_type, const znode *n } return (Z_LVAL(current_access_type->u.constant) | Z_LVAL(new_modifier->u.constant)); } +/* }}} */ - -void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC) +void zend_do_begin_function_declaration(znode *function_token, znode *function_name, int is_method, int return_reference, znode *fn_flags_znode TSRMLS_DC) /* {{{ */ { zend_op_array op_array; char *name = function_name->u.constant.value.str.val; @@ -1379,8 +1409,9 @@ void zend_do_begin_function_declaration(znode *function_token, znode *function_n zend_stack_push(&CG(labels_stack), (void *) &CG(labels), sizeof(HashTable*)); CG(labels) = NULL; } +/* }}} */ -void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference TSRMLS_DC) +void zend_do_begin_lambda_function_declaration(znode *result, znode *function_token, int return_reference TSRMLS_DC) /* {{{ */ { znode function_name; zend_op_array *current_op_array = CG(active_op_array); @@ -1402,9 +1433,9 @@ void zend_do_begin_lambda_function_declaration(znode *result, znode *function_to current_op->result = *result; CG(active_op_array)->fn_flags |= ZEND_ACC_CLOSURE; } +/* }}} */ - -void zend_do_handle_exception(TSRMLS_D) +void zend_do_handle_exception(TSRMLS_D) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -1412,9 +1443,9 @@ void zend_do_handle_exception(TSRMLS_D) SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); } +/* }}} */ - -void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) +void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) /* {{{ */ { char lcname[16]; int name_len; @@ -1446,9 +1477,9 @@ void zend_do_end_function_declaration(const znode *function_token TSRMLS_DC) zend_stack_del_top(&CG(switch_cond_stack)); zend_stack_del_top(&CG(foreach_copy_stack)); } +/* }}} */ - -void zend_do_receive_arg(zend_uchar op, const znode *var, const znode *offset, const znode *initialization, znode *class_type, const znode *varname, zend_uchar pass_by_reference TSRMLS_DC) +void zend_do_receive_arg(zend_uchar op, const znode *var, const znode *offset, const znode *initialization, znode *class_type, const znode *varname, zend_uchar pass_by_reference TSRMLS_DC) /* {{{ */ { zend_op *opline; zend_arg_info *cur_arg_info; @@ -1526,9 +1557,9 @@ void zend_do_receive_arg(zend_uchar op, const znode *var, const znode *offset, c } opline->result.u.EA.type |= EXT_TYPE_UNUSED; } +/* }}} */ - -int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace TSRMLS_DC) +int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace TSRMLS_DC) /* {{{ */ { zend_function *function; char *lcname; @@ -1561,10 +1592,9 @@ int zend_do_begin_function_call(znode *function_name, zend_bool check_namespace zend_do_extended_fcall_begin(TSRMLS_C); return 0; } +/* }}} */ - - -void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) +void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) /* {{{ */ { zend_op *last_op; int last_op_number; @@ -1604,9 +1634,9 @@ void zend_do_begin_method_call(znode *left_bracket TSRMLS_DC) zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *)); zend_do_extended_fcall_begin(TSRMLS_C); } +/* }}} */ - -void zend_do_clone(znode *result, const znode *expr TSRMLS_DC) +void zend_do_clone(znode *result, const znode *expr TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -1617,9 +1647,9 @@ void zend_do_clone(znode *result, const znode *expr TSRMLS_DC) opline->result.u.var = get_temporary_variable(CG(active_op_array)); *result = opline->result; } +/* }}} */ - -void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRMLS_DC) +void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRMLS_DC) /* {{{ */ { unsigned char *ptr = NULL; zend_op *opline, *opline2; @@ -1671,8 +1701,9 @@ void zend_do_begin_dynamic_function_call(znode *function_name, int ns_call TSRML zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(zend_function *)); zend_do_extended_fcall_begin(TSRMLS_C); } +/* }}} */ -void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace TSRMLS_DC) +void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace TSRMLS_DC) /* {{{ */ { znode tmp; int len; @@ -1721,8 +1752,9 @@ void zend_resolve_non_class_name(znode *element_name, zend_bool check_namespace *element_name = tmp; } } +/* }}} */ -void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_name TSRMLS_DC) +void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_name TSRMLS_DC) /* {{{ */ { char *compound; char *lcname; @@ -1794,8 +1826,9 @@ void zend_resolve_class_name(znode *class_name, ulong *fetch_type, int check_ns_ efree(lcname); } } +/* }}} */ -void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) +void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) /* {{{ */ { long fetch_class_op_number; zend_op *opline; @@ -1841,6 +1874,7 @@ void zend_do_fetch_class(znode *result, znode *class_name TSRMLS_DC) opline->result.op_type = IS_VAR; /* FIXME: Hack so that INIT_FCALL_BY_NAME still knows this is a class */ *result = opline->result; } +/* }}} */ void zend_do_label(znode *label TSRMLS_DC) /* {{{ */ { @@ -1947,7 +1981,7 @@ void zend_release_labels(TSRMLS_D) /* {{{ */ } /* }}} */ -void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_class_member TSRMLS_DC) +void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_class_member TSRMLS_DC) /* {{{ */ { zend_uint length; @@ -1973,8 +2007,9 @@ void zend_do_build_full_name(znode *result, znode *prefix, znode *name, int is_c result->u.constant.value.str.len = length; } } +/* }}} */ -int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC) +int zend_do_begin_class_member_function_call(znode *class_name, znode *method_name TSRMLS_DC) /* {{{ */ { znode class_node; unsigned char *ptr = NULL; @@ -2008,9 +2043,9 @@ int zend_do_begin_class_member_function_call(znode *class_name, znode *method_na zend_do_extended_fcall_begin(TSRMLS_C); return 1; /* Dynamic */ } +/* }}} */ - -void zend_do_end_function_call(znode *function_name, znode *result, const znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC) +void zend_do_end_function_call(znode *function_name, znode *result, const znode *argument_list, int is_method, int is_dynamic_fcall TSRMLS_DC) /* {{{ */ { zend_op *opline; @@ -2040,9 +2075,9 @@ void zend_do_end_function_call(znode *function_name, znode *result, const znode zend_stack_del_top(&CG(function_call_stack)); opline->extended_value = Z_LVAL(argument_list->u.constant); } +/* }}} */ - -void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) +void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) /* {{{ */ { zend_op *opline; int original_op=op; @@ -2147,9 +2182,9 @@ void zend_do_pass_param(znode *param, zend_uchar op, int offset TSRMLS_DC) opline->op2.u.opline_num = offset; SET_UNUSED(opline->op2); } +/* }}} */ - -static int generate_free_switch_expr(const zend_switch_entry *switch_entry TSRMLS_DC) +static int generate_free_switch_expr(const zend_switch_entry *switch_entry TSRMLS_DC) /* {{{ */ { zend_op *opline; @@ -2165,8 +2200,9 @@ static int generate_free_switch_expr(const zend_switch_entry *switch_entry TSRML opline->extended_value = 0; return 0; } +/* }}} */ -static int generate_free_foreach_copy(const zend_op *foreach_copy TSRMLS_DC) +static int generate_free_foreach_copy(const zend_op *foreach_copy TSRMLS_DC) /* {{{ */ { zend_op *opline; @@ -2193,8 +2229,9 @@ static int generate_free_foreach_copy(const zend_op *foreach_copy TSRMLS_DC) return 0; } +/* }}} */ -void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) +void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) /* {{{ */ { zend_op *opline; int start_op_number, end_op_number; @@ -2240,9 +2277,9 @@ void zend_do_return(znode *expr, int do_end_vparse TSRMLS_DC) SET_UNUSED(opline->op2); } +/* }}} */ - -static int zend_add_try_element(zend_uint try_op TSRMLS_DC) +static int zend_add_try_element(zend_uint try_op TSRMLS_DC) /* {{{ */ { int try_catch_offset = CG(active_op_array)->last_try_catch++; @@ -2250,20 +2287,21 @@ static int zend_add_try_element(zend_uint try_op TSRMLS_DC) CG(active_op_array)->try_catch_array[try_catch_offset].try_op = try_op; return try_catch_offset; } +/* }}} */ -static void zend_add_catch_element(int offset, zend_uint catch_op TSRMLS_DC) +static void zend_add_catch_element(int offset, zend_uint catch_op TSRMLS_DC) /* {{{ */ { CG(active_op_array)->try_catch_array[offset].catch_op = catch_op; } +/* }}} */ - -void zend_do_first_catch(znode *open_parentheses TSRMLS_DC) +void zend_do_first_catch(znode *open_parentheses TSRMLS_DC) /* {{{ */ { open_parentheses->u.opline_num = get_next_op_number(CG(active_op_array)); } +/* }}} */ - -void zend_initialize_try_catch_element(const znode *try_token TSRMLS_DC) +void zend_initialize_try_catch_element(const znode *try_token TSRMLS_DC) /* {{{ */ { int jmp_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -2282,9 +2320,9 @@ void zend_initialize_try_catch_element(const znode *try_token TSRMLS_DC) zend_add_catch_element(try_token->u.opline_num, get_next_op_number(CG(active_op_array)) TSRMLS_CC); } +/* }}} */ - -void zend_do_mark_last_catch(const znode *first_catch, const znode *last_additional_catch TSRMLS_DC) +void zend_do_mark_last_catch(const znode *first_catch, const znode *last_additional_catch TSRMLS_DC) /* {{{ */ { CG(active_op_array)->last--; zend_do_if_end(TSRMLS_C); @@ -2297,16 +2335,16 @@ void zend_do_mark_last_catch(const znode *first_catch, const znode *last_additio } DEC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_try(znode *try_token TSRMLS_DC) +void zend_do_try(znode *try_token TSRMLS_DC) /* {{{ */ { try_token->u.opline_num = zend_add_try_element(get_next_op_number(CG(active_op_array)) TSRMLS_CC); INC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_begin_catch(znode *try_token, znode *class_name, const znode *catch_var, znode *first_catch TSRMLS_DC) +void zend_do_begin_catch(znode *try_token, znode *class_name, const znode *catch_var, znode *first_catch TSRMLS_DC) /* {{{ */ { long catch_op_number; zend_op *opline; @@ -2337,8 +2375,9 @@ void zend_do_begin_catch(znode *try_token, znode *class_name, const znode *catch try_token->u.opline_num = catch_op_number; } +/* }}} */ -void zend_do_end_catch(const znode *try_token TSRMLS_DC) +void zend_do_end_catch(const znode *try_token TSRMLS_DC) /* {{{ */ { int jmp_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -2354,8 +2393,9 @@ void zend_do_end_catch(const znode *try_token TSRMLS_DC) CG(active_op_array)->opcodes[try_token->u.opline_num].extended_value = get_next_op_number(CG(active_op_array)); } +/* }}} */ -void zend_do_throw(const znode *expr TSRMLS_DC) +void zend_do_throw(const znode *expr TSRMLS_DC) /* {{{ */ { zend_op *opline; @@ -2364,8 +2404,9 @@ void zend_do_throw(const znode *expr TSRMLS_DC) opline->op1 = *expr; SET_UNUSED(opline->op2); } +/* }}} */ -ZEND_API void function_add_ref(zend_function *function) +ZEND_API void function_add_ref(zend_function *function) /* {{{ */ { if (function->type == ZEND_USER_FUNCTION) { zend_op_array *op_array = &function->op_array; @@ -2381,8 +2422,9 @@ ZEND_API void function_add_ref(zend_function *function) } } } +/* }}} */ -static void do_inherit_parent_constructor(zend_class_entry *ce) +static void do_inherit_parent_constructor(zend_class_entry *ce) /* {{{ */ { zend_function *function; @@ -2469,9 +2511,9 @@ static void do_inherit_parent_constructor(zend_class_entry *ce) } ce->constructor = ce->parent->constructor; } +/* }}} */ - -char *zend_visibility_string(zend_uint fn_flags) +char *zend_visibility_string(zend_uint fn_flags) /* {{{ */ { if (fn_flags & ZEND_ACC_PRIVATE) { return "private"; @@ -2484,9 +2526,9 @@ char *zend_visibility_string(zend_uint fn_flags) } return ""; } +/* }}} */ - -static void do_inherit_method(zend_function *function) +static void do_inherit_method(zend_function *function) /* {{{ */ { /* The class entry of the derived function intentionally remains the same * as that of the parent class. That allows us to know in which context @@ -2494,9 +2536,9 @@ static void do_inherit_method(zend_function *function) */ function_add_ref(function); } +/* }}} */ - -static zend_bool zend_do_perform_implementation_check(const zend_function *fe, const zend_function *proto) +static zend_bool zend_do_perform_implementation_check(const zend_function *fe, const zend_function *proto) /* {{{ */ { zend_uint i; @@ -2559,9 +2601,9 @@ static zend_bool zend_do_perform_implementation_check(const zend_function *fe, c } return 1; } +/* }}} */ - -static zend_bool do_inherit_method_check(HashTable *child_function_table, zend_function *parent, const zend_hash_key *hash_key, zend_class_entry *child_ce) +static zend_bool do_inherit_method_check(HashTable *child_function_table, zend_function *parent, const zend_hash_key *hash_key, zend_class_entry *child_ce) /* {{{ */ { zend_uint child_flags; zend_uint parent_flags = parent->common.fn_flags; @@ -2639,9 +2681,9 @@ static zend_bool do_inherit_method_check(HashTable *child_function_table, zend_f return 0; } +/* }}} */ - -static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_property_info *parent_info, const zend_hash_key *hash_key, zend_class_entry *ce) +static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_property_info *parent_info, const zend_hash_key *hash_key, zend_class_entry *ce) /* {{{ */ { zend_property_info *child_info; zend_class_entry *parent_ce = ce->parent; @@ -2718,10 +2760,9 @@ static zend_bool do_inherit_property_access_check(HashTable *target_ht, zend_pro return 1; /* Copy from parent */ } } +/* }}} */ - - -static inline void do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) +static inline void do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) /* {{{ */ { if (!(ce->ce_flags & ZEND_ACC_INTERFACE) && iface->interface_gets_implemented && iface->interface_gets_implemented(iface, ce TSRMLS_CC) == FAILURE) { zend_error(E_CORE_ERROR, "Class %s could not implement interface %s", ce->name, iface->name); @@ -2730,9 +2771,9 @@ static inline void do_implement_interface(zend_class_entry *ce, zend_class_entry zend_error(E_ERROR, "Interface %s cannot implement itself", ce->name); } } +/* }}} */ - -ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_entry *iface TSRMLS_DC) +ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_entry *iface TSRMLS_DC) /* {{{ */ { /* expects interface to be contained in ce's interface list already */ zend_uint i, ce_num, if_num = iface->num_interfaces; @@ -2767,8 +2808,9 @@ ZEND_API void zend_do_inherit_interfaces(zend_class_entry *ce, const zend_class_ do_implement_interface(ce, ce->interfaces[ce_num++] TSRMLS_CC); } } +/* }}} */ -static int inherit_static_prop(zval **p TSRMLS_DC, int num_args, va_list args, const zend_hash_key *key) +static int inherit_static_prop(zval **p TSRMLS_DC, int num_args, va_list args, const zend_hash_key *key) /* {{{ */ { HashTable *target = va_arg(args, HashTable*); @@ -2780,8 +2822,9 @@ static int inherit_static_prop(zval **p TSRMLS_DC, int num_args, va_list args, c } return ZEND_HASH_APPLY_KEEP; } +/* }}} */ -ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce TSRMLS_DC) +ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent_ce TSRMLS_DC) /* {{{ */ { if ((ce->ce_flags & ZEND_ACC_INTERFACE) && !(parent_ce->ce_flags & ZEND_ACC_INTERFACE)) { @@ -2825,9 +2868,9 @@ ZEND_API void zend_do_inheritance(zend_class_entry *ce, zend_class_entry *parent zend_verify_abstract_class(ce TSRMLS_CC); } } +/* }}} */ - -static zend_bool do_inherit_constant_check(HashTable *child_constants_table, const zval **parent_constant, const zend_hash_key *hash_key, const zend_class_entry *iface) +static zend_bool do_inherit_constant_check(HashTable *child_constants_table, const zval **parent_constant, const zend_hash_key *hash_key, const zend_class_entry *iface) /* {{{ */ { zval **old_constant; @@ -2839,9 +2882,9 @@ static zend_bool do_inherit_constant_check(HashTable *child_constants_table, con } return 1; } +/* }}} */ - -ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) +ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry *iface TSRMLS_DC) /* {{{ */ { zend_uint i, ignore = 0; zend_uint current_iface_num = ce->num_interfaces; @@ -2876,9 +2919,9 @@ ZEND_API void zend_do_implement_interface(zend_class_entry *ce, zend_class_entry zend_do_inherit_interfaces(ce, iface TSRMLS_CC); } } +/* }}} */ - -ZEND_API int do_bind_function(zend_op *opline, HashTable *function_table, zend_bool compile_time) +ZEND_API int do_bind_function(zend_op *opline, HashTable *function_table, zend_bool compile_time) /* {{{ */ { zend_function *function; @@ -2904,9 +2947,9 @@ ZEND_API int do_bind_function(zend_op *opline, HashTable *function_table, zend_b return SUCCESS; } } +/* }}} */ - -ZEND_API zend_class_entry *do_bind_class(const zend_op *opline, HashTable *class_table, zend_bool compile_time TSRMLS_DC) +ZEND_API zend_class_entry *do_bind_class(const zend_op *opline, HashTable *class_table, zend_bool compile_time TSRMLS_DC) /* {{{ */ { zend_class_entry *ce, **pce; @@ -2935,9 +2978,9 @@ ZEND_API zend_class_entry *do_bind_class(const zend_op *opline, HashTable *class return ce; } } +/* }}} */ - -ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op *opline, HashTable *class_table, zend_class_entry *parent_ce, zend_bool compile_time TSRMLS_DC) +ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op *opline, HashTable *class_table, zend_class_entry *parent_ce, zend_bool compile_time TSRMLS_DC) /* {{{ */ { zend_class_entry *ce, **pce; int found_ce; @@ -2972,9 +3015,9 @@ ZEND_API zend_class_entry *do_bind_inherited_class(const zend_op *opline, HashTa } return ce; } +/* }}} */ - -void zend_do_early_binding(TSRMLS_D) +void zend_do_early_binding(TSRMLS_D) /* {{{ */ { zend_op *opline = &CG(active_op_array)->opcodes[CG(active_op_array)->last-1]; HashTable *table; @@ -3042,8 +3085,9 @@ void zend_do_early_binding(TSRMLS_D) zval_dtor(&opline->op2.u.constant); MAKE_NOP(opline); } +/* }}} */ -ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array TSRMLS_DC) +ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array TSRMLS_DC) /* {{{ */ { if (op_array->early_binding != -1) { zend_bool orig_in_compilation = CG(in_compilation); @@ -3060,8 +3104,9 @@ ZEND_API void zend_do_delayed_early_binding(const zend_op_array *op_array TSRMLS CG(in_compilation) = orig_in_compilation; } } +/* }}} */ -void zend_do_boolean_or_begin(znode *expr1, znode *op_token TSRMLS_DC) +void zend_do_boolean_or_begin(znode *expr1, znode *op_token TSRMLS_DC) /* {{{ */ { int next_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3080,9 +3125,9 @@ void zend_do_boolean_or_begin(znode *expr1, znode *op_token TSRMLS_DC) *expr1 = opline->result; } +/* }}} */ - -void zend_do_boolean_or_end(znode *result, const znode *expr1, const znode *expr2, znode *op_token TSRMLS_DC) +void zend_do_boolean_or_end(znode *result, const znode *expr1, const znode *expr2, znode *op_token TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3094,9 +3139,9 @@ void zend_do_boolean_or_end(znode *result, const znode *expr1, const znode *expr CG(active_op_array)->opcodes[op_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array)); } +/* }}} */ - -void zend_do_boolean_and_begin(znode *expr1, znode *op_token TSRMLS_DC) +void zend_do_boolean_and_begin(znode *expr1, znode *op_token TSRMLS_DC) /* {{{ */ { int next_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3115,9 +3160,9 @@ void zend_do_boolean_and_begin(znode *expr1, znode *op_token TSRMLS_DC) *expr1 = opline->result; } +/* }}} */ - -void zend_do_boolean_and_end(znode *result, const znode *expr1, const znode *expr2, const znode *op_token TSRMLS_DC) +void zend_do_boolean_and_end(znode *result, const znode *expr1, const znode *expr2, const znode *op_token TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3129,16 +3174,16 @@ void zend_do_boolean_and_end(znode *result, const znode *expr1, const znode *exp CG(active_op_array)->opcodes[op_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array)); } +/* }}} */ - -void zend_do_do_while_begin(TSRMLS_D) +void zend_do_do_while_begin(TSRMLS_D) /* {{{ */ { do_begin_loop(TSRMLS_C); INC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_do_while_end(const znode *do_token, const znode *expr_open_bracket, const znode *expr TSRMLS_DC) +void zend_do_do_while_end(const znode *do_token, const znode *expr_open_bracket, const znode *expr TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3151,9 +3196,9 @@ void zend_do_do_while_end(const znode *do_token, const znode *expr_open_bracket, DEC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_brk_cont(zend_uchar op, const znode *expr TSRMLS_DC) +void zend_do_brk_cont(zend_uchar op, const znode *expr TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3169,9 +3214,9 @@ void zend_do_brk_cont(zend_uchar op, const znode *expr TSRMLS_DC) opline->op2.op_type = IS_CONST; } } +/* }}} */ - -void zend_do_switch_cond(const znode *cond TSRMLS_DC) +void zend_do_switch_cond(const znode *cond TSRMLS_DC) /* {{{ */ { zend_switch_entry switch_entry; @@ -3184,10 +3229,9 @@ void zend_do_switch_cond(const znode *cond TSRMLS_DC) INC_BPC(CG(active_op_array)); } +/* }}} */ - - -void zend_do_switch_end(const znode *case_list TSRMLS_DC) +void zend_do_switch_end(const znode *case_list TSRMLS_DC) /* {{{ */ { zend_op *opline; zend_switch_entry *switch_entry_ptr; @@ -3228,9 +3272,9 @@ void zend_do_switch_end(const znode *case_list TSRMLS_DC) DEC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_case_before_statement(const znode *case_list, znode *case_token, const znode *case_expr TSRMLS_DC) +void zend_do_case_before_statement(const znode *case_list, znode *case_token, const znode *case_expr TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); int next_op_number; @@ -3265,9 +3309,9 @@ void zend_do_case_before_statement(const znode *case_list, znode *case_token, co next_op_number = get_next_op_number(CG(active_op_array)); CG(active_op_array)->opcodes[case_list->u.opline_num].op1.u.opline_num = next_op_number; } +/* }}} */ - -void zend_do_case_after_statement(znode *result, const znode *case_token TSRMLS_DC) +void zend_do_case_after_statement(znode *result, const znode *case_token TSRMLS_DC) /* {{{ */ { int next_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3286,10 +3330,9 @@ void zend_do_case_after_statement(znode *result, const znode *case_token TSRMLS_ break; } } +/* }}} */ - - -void zend_do_default_before_statement(const znode *case_list, znode *default_token TSRMLS_DC) +void zend_do_default_before_statement(const znode *case_list, znode *default_token TSRMLS_DC) /* {{{ */ { int next_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3310,9 +3353,9 @@ void zend_do_default_before_statement(const znode *case_list, znode *default_tok } CG(active_op_array)->opcodes[case_list->u.opline_num].op1.u.opline_num = next_op_number; } +/* }}} */ - -void zend_do_begin_class_declaration(const znode *class_token, znode *class_name, const znode *parent_class_name TSRMLS_DC) +void zend_do_begin_class_declaration(const znode *class_token, znode *class_name, const znode *parent_class_name TSRMLS_DC) /* {{{ */ { zend_op *opline; int doing_inheritance = 0; @@ -3420,9 +3463,9 @@ void zend_do_begin_class_declaration(const znode *class_token, znode *class_name CG(doc_comment_len) = 0; } } +/* }}} */ - -static void do_verify_abstract_class(TSRMLS_D) +static void do_verify_abstract_class(TSRMLS_D) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3430,9 +3473,9 @@ static void do_verify_abstract_class(TSRMLS_D) opline->op1 = CG(implementing_class); SET_UNUSED(opline->op2); } +/* }}} */ - -void zend_do_end_class_declaration(const znode *class_token, const znode *parent_token TSRMLS_DC) +void zend_do_end_class_declaration(const znode *class_token, const znode *parent_token TSRMLS_DC) /* {{{ */ { zend_class_entry *ce = CG(active_class_entry); @@ -3475,9 +3518,9 @@ void zend_do_end_class_declaration(const znode *class_token, const znode *parent } CG(active_class_entry) = NULL; } +/* }}} */ - -void zend_do_implements_interface(znode *interface_name TSRMLS_DC) +void zend_do_implements_interface(znode *interface_name TSRMLS_DC) /* {{{ */ { zend_op *opline; @@ -3499,9 +3542,9 @@ void zend_do_implements_interface(znode *interface_name TSRMLS_DC) opline->op2 = *interface_name; CG(active_class_entry)->num_interfaces++; } +/* }}} */ - -ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, const char *src1, int src1_length, const char *src2, int src2_length, int internal) +ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, const char *src1, int src1_length, const char *src2, int src2_length, int internal) /* {{{ */ { char *prop_name; int prop_name_length; @@ -3515,16 +3558,17 @@ ZEND_API void zend_mangle_property_name(char **dest, int *dest_length, const cha *dest = prop_name; *dest_length = prop_name_length; } +/* }}} */ - -static int zend_strnlen(const char* s, int maxlen) +static int zend_strnlen(const char* s, int maxlen) /* {{{ */ { int len = 0; while (*s++ && maxlen--) len++; return len; } +/* }}} */ -ZEND_API int zend_unmangle_property_name(char *mangled_property, int len, char **class_name, char **prop_name) +ZEND_API int zend_unmangle_property_name(char *mangled_property, int len, char **class_name, char **prop_name) /* {{{ */ { int class_name_len; @@ -3550,8 +3594,9 @@ ZEND_API int zend_unmangle_property_name(char *mangled_property, int len, char * *prop_name = (*class_name)+class_name_len; return SUCCESS; } +/* }}} */ -void zend_do_declare_property(const znode *var_name, const znode *value, zend_uint access_type TSRMLS_DC) +void zend_do_declare_property(const znode *var_name, const znode *value, zend_uint access_type TSRMLS_DC) /* {{{ */ { zval *property; zend_property_info *existing_property_info; @@ -3595,9 +3640,9 @@ void zend_do_declare_property(const znode *var_name, const znode *value, zend_ui zend_declare_property_ex(CG(active_class_entry), var_name->u.constant.value.str.val, var_name->u.constant.value.str.len, property, access_type, comment, comment_len TSRMLS_CC); efree(var_name->u.constant.value.str.val); } +/* }}} */ - -void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_DC) +void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_DC) /* {{{ */ { zval *property; @@ -3614,10 +3659,9 @@ void zend_do_declare_class_constant(znode *var_name, const znode *value TSRMLS_D } FREE_PNODE(var_name); } +/* }}} */ - - -void zend_do_fetch_property(znode *result, znode *object, const znode *property TSRMLS_DC) +void zend_do_fetch_property(znode *result, znode *object, const znode *property TSRMLS_DC) /* {{{ */ { zend_op opline; zend_llist *fetch_list_ptr; @@ -3673,8 +3717,9 @@ void zend_do_fetch_property(znode *result, znode *object, const znode *property zend_llist_add_element(fetch_list_ptr, &opline); } +/* }}} */ -void zend_do_halt_compiler_register(TSRMLS_D) +void zend_do_halt_compiler_register(TSRMLS_D) /* {{{ */ { char *name, *cfilename; char haltoff[] = "__COMPILER_HALT_OFFSET__"; @@ -3685,8 +3730,9 @@ void zend_do_halt_compiler_register(TSRMLS_D) zend_register_long_constant(name, len+1, zend_get_scanned_file_offset(TSRMLS_C), CONST_CS, 0 TSRMLS_CC); pefree(name, 0); } +/* }}} */ -void zend_do_declare_implicit_property(TSRMLS_D) +void zend_do_declare_implicit_property(TSRMLS_D) /* {{{ */ { /* Fixes bug #26182. Not sure why we needed to do this in the first place. Has to be checked with Zeev. @@ -3718,15 +3764,15 @@ void zend_do_declare_implicit_property(TSRMLS_D) } #endif } +/* }}} */ - -void zend_do_push_object(const znode *object TSRMLS_DC) +void zend_do_push_object(const znode *object TSRMLS_DC) /* {{{ */ { zend_stack_push(&CG(object_stack), object, sizeof(znode)); } +/* }}} */ - -void zend_do_pop_object(znode *object TSRMLS_DC) +void zend_do_pop_object(znode *object TSRMLS_DC) /* {{{ */ { if (object) { znode *tmp; @@ -3736,9 +3782,9 @@ void zend_do_pop_object(znode *object TSRMLS_DC) } zend_stack_del_top(&CG(object_stack)); } +/* }}} */ - -void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) +void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) /* {{{ */ { zend_op *opline; unsigned char *ptr = NULL; @@ -3753,9 +3799,9 @@ void zend_do_begin_new_object(znode *new_token, znode *class_type TSRMLS_DC) zend_stack_push(&CG(function_call_stack), (void *) &ptr, sizeof(unsigned char *)); } +/* }}} */ - -void zend_do_end_new_object(znode *result, const znode *new_token, const znode *argument_list TSRMLS_DC) +void zend_do_end_new_object(znode *result, const znode *new_token, const znode *argument_list TSRMLS_DC) /* {{{ */ { znode ctor_result; @@ -3765,6 +3811,7 @@ void zend_do_end_new_object(znode *result, const znode *new_token, const znode * CG(active_op_array)->opcodes[new_token->u.opline_num].op2.u.opline_num = get_next_op_number(CG(active_op_array)); *result = CG(active_op_array)->opcodes[new_token->u.opline_num].result; } +/* }}} */ static zend_constant* zend_get_ct_const(const zval *const_name, int all_internal_constants_substitution TSRMLS_DC) /* {{{ */ { @@ -3912,9 +3959,9 @@ void zend_do_fetch_constant(znode *result, znode *constant_container, znode *con break; } } +/* }}} */ - -void zend_do_shell_exec(znode *result, const znode *cmd TSRMLS_DC) +void zend_do_shell_exec(znode *result, const znode *cmd TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3947,10 +3994,9 @@ void zend_do_shell_exec(znode *result, const znode *cmd TSRMLS_DC) ZVAL_LONG(&opline->op2.u.constant, zend_hash_func("shell_exec", sizeof("shell_exec"))); *result = opline->result; } +/* }}} */ - - -void zend_do_init_array(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC) +void zend_do_init_array(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3971,9 +4017,9 @@ void zend_do_init_array(znode *result, const znode *expr, const znode *offset, z } opline->extended_value = is_ref; } +/* }}} */ - -void zend_do_add_array_element(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC) +void zend_do_add_array_element(znode *result, const znode *expr, const znode *offset, zend_bool is_ref TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -3987,10 +4033,9 @@ void zend_do_add_array_element(znode *result, const znode *expr, const znode *of } opline->extended_value = is_ref; } +/* }}} */ - - -void zend_do_add_static_array_element(znode *result, znode *offset, const znode *expr) +void zend_do_add_static_array_element(znode *result, znode *offset, const znode *expr) /* {{{ */ { zval *element; @@ -4029,9 +4074,9 @@ void zend_do_add_static_array_element(znode *result, znode *offset, const znode zend_hash_next_index_insert(Z_ARRVAL(result->u.constant), &element, sizeof(zval *), NULL); } } +/* }}} */ - -void zend_do_add_list_element(const znode *element TSRMLS_DC) +void zend_do_add_list_element(const znode *element TSRMLS_DC) /* {{{ */ { list_llist_element lle; @@ -4044,23 +4089,23 @@ void zend_do_add_list_element(const znode *element TSRMLS_DC) } (*((int *)CG(dimension_llist).tail->data))++; } +/* }}} */ - -void zend_do_new_list_begin(TSRMLS_D) +void zend_do_new_list_begin(TSRMLS_D) /* {{{ */ { int current_dimension = 0; zend_llist_add_element(&CG(dimension_llist), ¤t_dimension); } +/* }}} */ - -void zend_do_new_list_end(TSRMLS_D) +void zend_do_new_list_end(TSRMLS_D) /* {{{ */ { zend_llist_remove_tail(&CG(dimension_llist)); (*((int *)CG(dimension_llist).tail->data))++; } +/* }}} */ - -void zend_do_list_init(TSRMLS_D) +void zend_do_list_init(TSRMLS_D) /* {{{ */ { zend_stack_push(&CG(list_stack), &CG(list_llist), sizeof(zend_llist)); zend_stack_push(&CG(list_stack), &CG(dimension_llist), sizeof(zend_llist)); @@ -4068,9 +4113,9 @@ void zend_do_list_init(TSRMLS_D) zend_llist_init(&CG(dimension_llist), sizeof(int), NULL, 0); zend_do_new_list_begin(TSRMLS_C); } +/* }}} */ - -void zend_do_list_end(znode *result, znode *expr TSRMLS_DC) +void zend_do_list_end(znode *result, znode *expr TSRMLS_DC) /* {{{ */ { zend_llist_element *le; zend_llist_element *dimension; @@ -4134,8 +4179,9 @@ void zend_do_list_end(znode *result, znode *expr TSRMLS_DC) zend_stack_del_top(&CG(list_stack)); } } +/* }}} */ -void zend_do_fetch_static_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC) +void zend_do_fetch_static_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC) /* {{{ */ { zval *tmp; zend_op *opline; @@ -4189,8 +4235,9 @@ void zend_do_fetch_static_variable(znode *varname, const znode *static_assignmen /* zval_dtor(&varname->u.constant); */ } +/* }}} */ -void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC) +void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC) /* {{{ */ { znode value; @@ -4208,8 +4255,9 @@ void zend_do_fetch_lexical_variable(znode *varname, zend_bool is_ref TSRMLS_DC) zend_do_fetch_static_variable(varname, &value, is_ref ? ZEND_FETCH_STATIC : ZEND_FETCH_LEXICAL TSRMLS_CC); } +/* }}} */ -void zend_do_fetch_global_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC) +void zend_do_fetch_global_variable(znode *varname, const znode *static_assignment, int fetch_type TSRMLS_DC) /* {{{ */ { zend_op *opline; znode lval; @@ -4239,9 +4287,9 @@ void zend_do_fetch_global_variable(znode *varname, const znode *static_assignmen zend_do_assign_ref(NULL, &lval, &result TSRMLS_CC); CG(active_op_array)->opcodes[CG(active_op_array)->last-1].result.u.EA.type |= EXT_TYPE_UNUSED; } +/* }}} */ - -void zend_do_cast(znode *result, const znode *expr, int type TSRMLS_DC) +void zend_do_cast(znode *result, const znode *expr, int type TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -4253,9 +4301,9 @@ void zend_do_cast(znode *result, const znode *expr, int type TSRMLS_DC) opline->extended_value = type; *result = opline->result; } +/* }}} */ - -void zend_do_include_or_eval(int type, znode *result, const znode *op1 TSRMLS_DC) +void zend_do_include_or_eval(int type, znode *result, const znode *op1 TSRMLS_DC) /* {{{ */ { zend_do_extended_fcall_begin(TSRMLS_C); { @@ -4271,9 +4319,9 @@ void zend_do_include_or_eval(int type, znode *result, const znode *op1 TSRMLS_DC } zend_do_extended_fcall_end(TSRMLS_C); } +/* }}} */ - -void zend_do_indirect_references(znode *result, const znode *num_references, znode *variable TSRMLS_DC) +void zend_do_indirect_references(znode *result, const znode *num_references, znode *variable TSRMLS_DC) /* {{{ */ { int i; @@ -4285,9 +4333,9 @@ void zend_do_indirect_references(znode *result, const znode *num_references, zno zend_do_begin_variable_parse(TSRMLS_C); fetch_simple_variable(result, variable, 1 TSRMLS_CC); } +/* }}} */ - -void zend_do_unset(const znode *variable TSRMLS_DC) +void zend_do_unset(const znode *variable TSRMLS_DC) /* {{{ */ { zend_op *last_op; @@ -4318,9 +4366,9 @@ void zend_do_unset(const znode *variable TSRMLS_DC) } } } +/* }}} */ - -void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC) +void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC) /* {{{ */ { zend_op *last_op; @@ -4357,9 +4405,9 @@ void zend_do_isset_or_isempty(int type, znode *result, znode *variable TSRMLS_DC *result = last_op->result; } +/* }}} */ - -void zend_do_instanceof(znode *result, const znode *expr, const znode *class_znode, int type TSRMLS_DC) +void zend_do_instanceof(znode *result, const znode *expr, const znode *class_znode, int type TSRMLS_DC) /* {{{ */ { int last_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline; @@ -4385,9 +4433,9 @@ void zend_do_instanceof(znode *result, const znode *expr, const znode *class_zno *result = opline->result; } +/* }}} */ - -void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, znode *array, znode *as_token, int variable TSRMLS_DC) +void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, znode *array, znode *as_token, int variable TSRMLS_DC) /* {{{ */ { zend_op *opline; zend_bool is_variable; @@ -4457,9 +4505,9 @@ void zend_do_foreach_begin(znode *foreach_token, znode *open_brackets_token, zno SET_UNUSED(opline->op2); SET_UNUSED(opline->result); } +/* }}} */ - -void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token, const znode *as_token, znode *value, znode *key TSRMLS_DC) +void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token, const znode *as_token, znode *value, znode *key TSRMLS_DC) /* {{{ */ { zend_op *opline; znode dummy, value_node; @@ -4536,9 +4584,9 @@ void zend_do_foreach_cont(znode *foreach_token, const znode *open_brackets_token do_begin_loop(TSRMLS_C); INC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_foreach_end(const znode *foreach_token, const znode *as_token TSRMLS_DC) +void zend_do_foreach_end(const znode *foreach_token, const znode *as_token TSRMLS_DC) /* {{{ */ { zend_op *container_ptr; zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -4559,15 +4607,15 @@ void zend_do_foreach_end(const znode *foreach_token, const znode *as_token TSRML DEC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_declare_begin(TSRMLS_D) +void zend_do_declare_begin(TSRMLS_D) /* {{{ */ { zend_stack_push(&CG(declare_stack), &CG(declarables), sizeof(zend_declarables)); } +/* }}} */ - -void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC) +void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC) /* {{{ */ { if (!zend_binary_strcasecmp(var->u.constant.value.str.val, var->u.constant.value.str.len, "ticks", sizeof("ticks")-1)) { convert_to_long(&val->u.constant); @@ -4631,9 +4679,9 @@ void zend_do_declare_stmt(znode *var, znode *val TSRMLS_DC) } zval_dtor(&var->u.constant); } +/* }}} */ - -void zend_do_declare_end(const znode *declare_token TSRMLS_DC) +void zend_do_declare_end(const znode *declare_token TSRMLS_DC) /* {{{ */ { zend_declarables *declarables; @@ -4643,9 +4691,9 @@ void zend_do_declare_end(const znode *declare_token TSRMLS_DC) CG(declarables) = *declarables; } } +/* }}} */ - -void zend_do_exit(znode *result, const znode *message TSRMLS_DC) +void zend_do_exit(znode *result, const znode *message TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -4657,8 +4705,9 @@ void zend_do_exit(znode *result, const znode *message TSRMLS_DC) Z_TYPE(result->u.constant) = IS_BOOL; Z_LVAL(result->u.constant) = 1; } +/* }}} */ -void zend_do_begin_silence(znode *strudel_token TSRMLS_DC) +void zend_do_begin_silence(znode *strudel_token TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -4669,9 +4718,9 @@ void zend_do_begin_silence(znode *strudel_token TSRMLS_DC) SET_UNUSED(opline->op2); *strudel_token = opline->result; } +/* }}} */ - -void zend_do_end_silence(const znode *strudel_token TSRMLS_DC) +void zend_do_end_silence(const znode *strudel_token TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -4679,9 +4728,9 @@ void zend_do_end_silence(const znode *strudel_token TSRMLS_DC) opline->op1 = *strudel_token; SET_UNUSED(opline->op2); } +/* }}} */ - -void zend_do_jmp_set(const znode *value, znode *jmp_token, znode *colon_token TSRMLS_DC) +void zend_do_jmp_set(const znode *value, znode *jmp_token, znode *colon_token TSRMLS_DC) /* {{{ */ { int op_number = get_next_op_number(CG(active_op_array)); zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -4698,9 +4747,9 @@ void zend_do_jmp_set(const znode *value, znode *jmp_token, znode *colon_token TS INC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_jmp_set_else(znode *result, const znode *false_value, const znode *jmp_token, const znode *colon_token TSRMLS_DC) +void zend_do_jmp_set_else(znode *result, const znode *false_value, const znode *jmp_token, const znode *colon_token TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -4716,9 +4765,9 @@ void zend_do_jmp_set_else(znode *result, const znode *false_value, const znode * DEC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_begin_qm_op(const znode *cond, znode *qm_token TSRMLS_DC) +void zend_do_begin_qm_op(const znode *cond, znode *qm_token TSRMLS_DC) /* {{{ */ { int jmpz_op_number = get_next_op_number(CG(active_op_array)); zend_op *opline; @@ -4733,9 +4782,9 @@ void zend_do_begin_qm_op(const znode *cond, znode *qm_token TSRMLS_DC) INC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_qm_true(const znode *true_value, znode *qm_token, znode *colon_token TSRMLS_DC) +void zend_do_qm_true(const znode *true_value, znode *qm_token, znode *colon_token TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -4755,9 +4804,9 @@ void zend_do_qm_true(const znode *true_value, znode *qm_token, znode *colon_toke SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); } +/* }}} */ - -void zend_do_qm_false(znode *result, const znode *false_value, const znode *qm_token, const znode *colon_token TSRMLS_DC) +void zend_do_qm_false(znode *result, const znode *false_value, const znode *qm_token, const znode *colon_token TSRMLS_DC) /* {{{ */ { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -4772,9 +4821,9 @@ void zend_do_qm_false(znode *result, const znode *false_value, const znode *qm_t DEC_BPC(CG(active_op_array)); } +/* }}} */ - -void zend_do_extended_info(TSRMLS_D) +void zend_do_extended_info(TSRMLS_D) /* {{{ */ { zend_op *opline; @@ -4788,9 +4837,9 @@ void zend_do_extended_info(TSRMLS_D) SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); } +/* }}} */ - -void zend_do_extended_fcall_begin(TSRMLS_D) +void zend_do_extended_fcall_begin(TSRMLS_D) /* {{{ */ { zend_op *opline; @@ -4804,9 +4853,9 @@ void zend_do_extended_fcall_begin(TSRMLS_D) SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); } +/* }}} */ - -void zend_do_extended_fcall_end(TSRMLS_D) +void zend_do_extended_fcall_end(TSRMLS_D) /* {{{ */ { zend_op *opline; @@ -4820,9 +4869,9 @@ void zend_do_extended_fcall_end(TSRMLS_D) SET_UNUSED(opline->op1); SET_UNUSED(opline->op2); } +/* }}} */ - -void zend_do_ticks(TSRMLS_D) +void zend_do_ticks(TSRMLS_D) /* {{{ */ { if (Z_LVAL(CG(declarables).ticks)) { zend_op *opline = get_next_op(CG(active_op_array) TSRMLS_CC); @@ -4833,14 +4882,15 @@ void zend_do_ticks(TSRMLS_D) SET_UNUSED(opline->op2); } } +/* }}} */ -void zend_auto_global_dtor(zend_auto_global *auto_global) +void zend_auto_global_dtor(zend_auto_global *auto_global) /* {{{ */ { free(auto_global->name); } +/* }}} */ - -zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC) +zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC) /* {{{ */ { zend_auto_global *auto_global; @@ -4852,9 +4902,9 @@ zend_bool zend_is_auto_global(const char *name, uint name_len TSRMLS_DC) } return 0; } +/* }}} */ - -int zend_register_auto_global(const char *name, uint name_len, zend_auto_global_callback auto_global_callback TSRMLS_DC) +int zend_register_auto_global(const char *name, uint name_len, zend_auto_global_callback auto_global_callback TSRMLS_DC) /* {{{ */ { zend_auto_global auto_global; @@ -4864,9 +4914,9 @@ int zend_register_auto_global(const char *name, uint name_len, zend_auto_global_ return zend_hash_add(CG(auto_globals), name, name_len+1, &auto_global, sizeof(zend_auto_global), NULL); } +/* }}} */ - -int zendlex(znode *zendlval TSRMLS_DC) +int zendlex(znode *zendlval TSRMLS_DC) /* {{{ */ { int retval; @@ -4906,9 +4956,9 @@ again: zendlval->op_type = IS_CONST; return retval; } +/* }}} */ - -ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers TSRMLS_DC) +ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify_handlers TSRMLS_DC) /* {{{ */ { zend_bool persistent_hashes = (ce->type == ZEND_INTERNAL_CLASS) ? 1 : 0; dtor_func_t zval_ptr_dtor_func = ((persistent_hashes) ? ZVAL_INTERNAL_PTR_DTOR : ZVAL_PTR_DTOR); @@ -4971,9 +5021,9 @@ ZEND_API void zend_initialize_class_data(zend_class_entry *ce, zend_bool nullify ce->builtin_functions = NULL; } } +/* }}} */ - -int zend_get_class_fetch_type(const char *class_name, uint class_name_len) +int zend_get_class_fetch_type(const char *class_name, uint class_name_len) /* {{{ */ { if ((class_name_len == sizeof("self")-1) && !memcmp(class_name, "self", sizeof("self")-1)) { @@ -4988,14 +5038,16 @@ int zend_get_class_fetch_type(const char *class_name, uint class_name_len) return ZEND_FETCH_CLASS_DEFAULT; } } +/* }}} */ -ZEND_API char* zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var, int* name_len) +ZEND_API char* zend_get_compiled_variable_name(const zend_op_array *op_array, zend_uint var, int* name_len) /* {{{ */ { if (name_len) { *name_len = op_array->vars[var].name_len; } return op_array->vars[var].name; } +/* }}} */ void zend_do_build_namespace_name(znode *result, znode *prefix, znode *name TSRMLS_DC) /* {{{ */ { @@ -5139,31 +5191,31 @@ void zend_do_use(znode *ns_name, znode *new_name, int is_global TSRMLS_DC) /* {{ if (CG(current_namespace)) { /* Prefix import name with current namespace name to avoid conflicts with classes */ - char *ns_name = emalloc(Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) + 1); + char *c_ns_name = emalloc(Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) + 1); - zend_str_tolower_copy(ns_name, Z_STRVAL_P(CG(current_namespace)), Z_STRLEN_P(CG(current_namespace))); - ns_name[Z_STRLEN_P(CG(current_namespace))] = '\\'; - memcpy(ns_name+Z_STRLEN_P(CG(current_namespace))+1, lcname, Z_STRLEN_P(name)+1); - if (zend_hash_exists(CG(class_table), ns_name, Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name)+1)) { + zend_str_tolower_copy(c_ns_name, Z_STRVAL_P(CG(current_namespace)), Z_STRLEN_P(CG(current_namespace))); + c_ns_name[Z_STRLEN_P(CG(current_namespace))] = '\\'; + memcpy(c_ns_name+Z_STRLEN_P(CG(current_namespace))+1, lcname, Z_STRLEN_P(name)+1); + if (zend_hash_exists(CG(class_table), c_ns_name, Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name)+1)) { char *tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns)); if (Z_STRLEN_P(ns) != Z_STRLEN_P(CG(current_namespace)) + 1 + Z_STRLEN_P(name) || - memcmp(tmp, ns_name, Z_STRLEN_P(ns))) { + memcmp(tmp, c_ns_name, Z_STRLEN_P(ns))) { zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); } efree(tmp); } - efree(ns_name); + efree(c_ns_name); } else if (zend_hash_find(CG(class_table), lcname, Z_STRLEN_P(name)+1, (void**)&pce) == SUCCESS && (*pce)->type == ZEND_USER_CLASS && (*pce)->filename == CG(compiled_filename)) { - char *tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns)); + char *c_tmp = zend_str_tolower_dup(Z_STRVAL_P(ns), Z_STRLEN_P(ns)); if (Z_STRLEN_P(ns) != Z_STRLEN_P(name) || - memcmp(tmp, lcname, Z_STRLEN_P(ns))) { + memcmp(c_tmp, lcname, Z_STRLEN_P(ns))) { zend_error(E_COMPILE_ERROR, "Cannot use %s as %s because the name is already in use", Z_STRVAL_P(ns), Z_STRVAL_P(name)); } - efree(tmp); + efree(c_tmp); } if (zend_hash_add(CG(current_import), lcname, Z_STRLEN_P(name)+1, &ns, sizeof(zval*), NULL) != SUCCESS) { diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h index 1771b5391..3ccd199ba 100644 --- a/Zend/zend_compile.h +++ b/Zend/zend_compile.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_compile.h,v 1.316.2.8.2.12.2.40 2009/06/05 23:20:59 shire Exp $ */ +/* $Id: zend_compile.h 281737 2009-06-05 23:20:59Z shire $ */ #ifndef ZEND_COMPILE_H #define ZEND_COMPILE_H diff --git a/Zend/zend_config.nw.h b/Zend/zend_config.nw.h index 5e734dd50..ce2a49e20 100644 --- a/Zend/zend_config.nw.h +++ b/Zend/zend_config.nw.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_config.nw.h,v 1.8.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_config.nw.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_CONFIG_NW_H #define ZEND_CONFIG_NW_H diff --git a/Zend/zend_config.w32.h b/Zend/zend_config.w32.h index fce122b31..57f08b168 100644 --- a/Zend/zend_config.w32.h +++ b/Zend/zend_config.w32.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_config.w32.h,v 1.39.2.2.2.2.2.3 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_config.w32.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_CONFIG_W32_H #define ZEND_CONFIG_W32_H diff --git a/Zend/zend_constants.c b/Zend/zend_constants.c index 6be167ec8..d7f13de57 100644 --- a/Zend/zend_constants.c +++ b/Zend/zend_constants.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_constants.c,v 1.71.2.5.2.7.2.17 2009/01/12 21:54:37 stas Exp $ */ +/* $Id: zend_constants.c 273405 2009-01-12 21:54:37Z stas $ */ #include "zend.h" #include "zend_constants.h" diff --git a/Zend/zend_constants.h b/Zend/zend_constants.h index 7c932e71e..0ae833783 100644 --- a/Zend/zend_constants.h +++ b/Zend/zend_constants.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_constants.h,v 1.31.2.2.2.3.2.5 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_constants.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_CONSTANTS_H #define ZEND_CONSTANTS_H diff --git a/Zend/zend_default_classes.c b/Zend/zend_default_classes.c index 875c0f080..52c9588a7 100644 --- a/Zend/zend_default_classes.c +++ b/Zend/zend_default_classes.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_default_classes.c,v 1.59.2.2.2.1.2.3 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_default_classes.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "zend.h" #include "zend_API.h" diff --git a/Zend/zend_dynamic_array.c b/Zend/zend_dynamic_array.c index 627bc94d9..3c98ffaae 100644 --- a/Zend/zend_dynamic_array.c +++ b/Zend/zend_dynamic_array.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_dynamic_array.c,v 1.13.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_dynamic_array.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "zend.h" diff --git a/Zend/zend_dynamic_array.h b/Zend/zend_dynamic_array.h index 45ad075a0..b153a3469 100644 --- a/Zend/zend_dynamic_array.h +++ b/Zend/zend_dynamic_array.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_dynamic_array.h,v 1.14.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_dynamic_array.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_DYNAMIC_ARRAY_H #define ZEND_DYNAMIC_ARRAY_H diff --git a/Zend/zend_errors.h b/Zend/zend_errors.h index e8e600994..dbfba460b 100644 --- a/Zend/zend_errors.h +++ b/Zend/zend_errors.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_errors.h,v 1.18.2.1.2.5.2.4 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_errors.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_ERRORS_H #define ZEND_ERRORS_H diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index fc9a744cd..6c3560d05 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_exceptions.c,v 1.79.2.6.2.9.2.22 2009/05/11 15:03:46 felipe Exp $ */ +/* $Id: zend_exceptions.c 280362 2009-05-11 15:03:47Z felipe $ */ #include "zend.h" #include "zend_API.h" diff --git a/Zend/zend_exceptions.h b/Zend/zend_exceptions.h index bb21e734b..28a9be88b 100644 --- a/Zend/zend_exceptions.h +++ b/Zend/zend_exceptions.h @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_exceptions.h,v 1.21.2.1.2.2.2.5 2009/01/02 13:14:49 helly Exp $ */ +/* $Id: zend_exceptions.h 272584 2009-01-02 13:14:49Z helly $ */ #ifndef ZEND_EXCEPTIONS_H #define ZEND_EXCEPTIONS_H diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index bc0000b53..696112f52 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_execute.c,v 1.716.2.12.2.24.2.44 2009/06/04 18:20:42 mattwil Exp $ */ +/* $Id: zend_execute.c 281670 2009-06-04 18:20:45Z mattwil $ */ #define ZEND_INTENSIVE_DEBUGGING 0 diff --git a/Zend/zend_execute.h b/Zend/zend_execute.h index 9f9e5d48a..6a1f06ab3 100644 --- a/Zend/zend_execute.h +++ b/Zend/zend_execute.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_execute.h,v 1.84.2.4.2.8.2.15 2009/06/09 09:26:02 pajoye Exp $ */ +/* $Id: zend_execute.h 287992 2009-09-03 14:33:11Z dmitry $ */ #ifndef ZEND_EXECUTE_H #define ZEND_EXECUTE_H @@ -144,9 +144,11 @@ struct _zend_vm_stack { void **top; void **end; zend_vm_stack prev; - void *elements[1]; }; +#define ZEND_VM_STACK_ELEMETS(stack) \ + ((void**)(((char*)(stack)) + ZEND_MM_ALIGNED_SIZE(sizeof(struct _zend_vm_stack)))) + #define ZEND_VM_STACK_GROW_IF_NEEDED(count) \ do { \ if (UNEXPECTED((count) > \ @@ -156,10 +158,10 @@ struct _zend_vm_stack { } while (0) static inline zend_vm_stack zend_vm_stack_new_page(int count) { - zend_vm_stack page = (zend_vm_stack)emalloc(sizeof(*page)+sizeof(page->elements[0])*(count-1)); + zend_vm_stack page = (zend_vm_stack)emalloc(ZEND_MM_ALIGNED_SIZE(sizeof(*page)) + sizeof(void*) * count); - page->top = page->elements; - page->end = page->elements + count; + page->top = ZEND_VM_STACK_ELEMETS(page); + page->end = page->top + count; page->prev = NULL; return page; } @@ -207,7 +209,7 @@ static inline void *zend_vm_stack_pop(TSRMLS_D) { void *el = *(--EG(argument_stack)->top); - if (UNEXPECTED(EG(argument_stack)->top == EG(argument_stack)->elements)) { + if (UNEXPECTED(EG(argument_stack)->top == ZEND_VM_STACK_ELEMETS(EG(argument_stack)))) { zend_vm_stack p = EG(argument_stack); EG(argument_stack) = p->prev; efree(p); @@ -221,15 +223,32 @@ static inline void *zend_vm_stack_alloc(size_t size TSRMLS_DC) size = (size + (sizeof(void*) - 1)) / sizeof(void*); - ZEND_VM_STACK_GROW_IF_NEEDED((int)size); + /* the following comparison must be optimized out at compile time */ + if (ZEND_MM_ALIGNMENT > sizeof(void*)) { + int extra = (ZEND_MM_ALIGNMENT - ((zend_uintptr_t)EG(argument_stack)->top & (ZEND_MM_ALIGNMENT - 1))) / sizeof(void*); + + if (UNEXPECTED(size + extra + ZEND_MM_ALIGNED_SIZE(sizeof(void*)) / sizeof(void*) > + EG(argument_stack)->end - EG(argument_stack)->top)) { + zend_vm_stack_extend(size TSRMLS_CC); + } else { + void **old_top = EG(argument_stack)->top; + + EG(argument_stack)->top += extra; + /* store old top on the stack */ + *EG(argument_stack)->top = (void*)old_top; + EG(argument_stack)->top += ZEND_MM_ALIGNED_SIZE(sizeof(void*)) / sizeof(void*); + } + } else { + ZEND_VM_STACK_GROW_IF_NEEDED((int)size); + } ret = (void*)EG(argument_stack)->top; EG(argument_stack)->top += size; return ret; } -static inline void zend_vm_stack_free(void *ptr TSRMLS_DC) +static inline void zend_vm_stack_free_int(void *ptr TSRMLS_DC) { - if (UNEXPECTED(EG(argument_stack)->elements == (void**)ptr)) { + if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) { zend_vm_stack p = EG(argument_stack); EG(argument_stack) = p->prev; @@ -239,10 +258,28 @@ static inline void zend_vm_stack_free(void *ptr TSRMLS_DC) } } +static inline void zend_vm_stack_free(void *ptr TSRMLS_DC) +{ + if (UNEXPECTED(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) == (void**)ptr)) { + zend_vm_stack p = EG(argument_stack); + + EG(argument_stack) = p->prev; + efree(p); + } else { + /* the following comparison must be optimized out at compile time */ + if (ZEND_MM_ALIGNMENT > sizeof(void*)) { + ptr = (void*)(((char*)ptr) - ZEND_MM_ALIGNED_SIZE(sizeof(void*))); + EG(argument_stack)->top = *(void***)ptr; + } else { + EG(argument_stack)->top = (void**)ptr; + } + } +} + static inline void** zend_vm_stack_push_args(int count TSRMLS_DC) { - if (UNEXPECTED(EG(argument_stack)->top - EG(argument_stack)->elements < count) || + if (UNEXPECTED(EG(argument_stack)->top - ZEND_VM_STACK_ELEMETS(EG(argument_stack)) < count) || UNEXPECTED(EG(argument_stack)->top == EG(argument_stack)->end)) { zend_vm_stack p = EG(argument_stack); @@ -253,14 +290,14 @@ static inline void** zend_vm_stack_push_args(int count TSRMLS_DC) while (count-- > 0) { void *data = *(--p->top); - if (UNEXPECTED(p->top == p->elements)) { + if (UNEXPECTED(p->top == ZEND_VM_STACK_ELEMETS(p))) { zend_vm_stack r = p; EG(argument_stack)->prev = p->prev; p = p->prev; efree(r); } - *(EG(argument_stack)->elements + count) = data; + *(ZEND_VM_STACK_ELEMETS(EG(argument_stack)) + count) = data; } return EG(argument_stack)->top++; } @@ -278,7 +315,7 @@ static inline void zend_vm_stack_clear_multiple(TSRMLS_D) *p = NULL; zval_ptr_dtor(&q); } - zend_vm_stack_free(p TSRMLS_CC); + zend_vm_stack_free_int(p TSRMLS_CC); } static inline zval** zend_vm_stack_get_arg(int requested_arg TSRMLS_DC) @@ -351,6 +388,8 @@ ZEND_API zval** zend_get_compiled_variable_value(const zend_execute_data *execut #define ZEND_USER_OPCODE_CONTINUE 0 /* execute next opcode */ #define ZEND_USER_OPCODE_RETURN 1 /* exit from executor (return from function) */ #define ZEND_USER_OPCODE_DISPATCH 2 /* call original opcode handler */ +#define ZEND_USER_OPCODE_ENTER 3 /* enter into new op_array without recursion */ +#define ZEND_USER_OPCODE_LEAVE 4 /* return to calling op_array within the same executor */ #define ZEND_USER_OPCODE_DISPATCH_TO 0x100 /* call original handler of returned opcode */ diff --git a/Zend/zend_execute_API.c b/Zend/zend_execute_API.c index 42f5f50e7..88df13e2c 100644 --- a/Zend/zend_execute_API.c +++ b/Zend/zend_execute_API.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_execute_API.c,v 1.331.2.20.2.24.2.78 2009/06/05 18:50:32 mattwil Exp $ */ +/* $Id: zend_execute_API.c 287466 2009-08-18 20:51:49Z stas $ */ #include #include @@ -837,6 +837,12 @@ int zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_cache TS for (i=0; iparam_count; i++) { zval *param; + if(EX(function_state).function->type == ZEND_INTERNAL_FUNCTION + && !ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1) + && PZVAL_IS_REF(*fci->params[i])) { + SEPARATE_ZVAL(fci->params[i]); + } + if (ARG_SHOULD_BE_SENT_BY_REF(EX(function_state).function, i + 1) && !PZVAL_IS_REF(*fci->params[i])) { @@ -1148,6 +1154,7 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s zval *local_retval_ptr=NULL; zval **original_return_value_ptr_ptr = EG(return_value_ptr_ptr); zend_op **original_opline_ptr = EG(opline_ptr); + int orig_interactive = CG(interactive); EG(return_value_ptr_ptr) = &local_retval_ptr; EG(active_op_array) = new_op_array; @@ -1155,9 +1162,11 @@ ZEND_API int zend_eval_stringl(char *str, int str_len, zval *retval_ptr, char *s if (!EG(active_symbol_table)) { zend_rebuild_symbol_table(TSRMLS_C); } + CG(interactive) = 0; zend_execute(new_op_array TSRMLS_CC); + CG(interactive) = orig_interactive; if (local_retval_ptr) { if (retval_ptr) { COPY_PZVAL_TO_ZVAL(*retval_ptr, local_retval_ptr); @@ -1216,6 +1225,7 @@ void execute_new_code(TSRMLS_D) /* {{{ */ { zend_op *opline, *end; zend_op *ret_opline; + int orig_interactive; if (!(CG(active_op_array)->fn_flags & ZEND_ACC_INTERACTIVE) || CG(active_op_array)->backpatch_count>0 @@ -1271,7 +1281,10 @@ void execute_new_code(TSRMLS_D) /* {{{ */ EG(return_value_ptr_ptr) = NULL; EG(active_op_array) = CG(active_op_array); + orig_interactive = CG(interactive); + CG(interactive) = 0; zend_execute(CG(active_op_array) TSRMLS_CC); + CG(interactive) = orig_interactive; if (EG(exception)) { zend_exception_error(EG(exception), E_ERROR TSRMLS_CC); diff --git a/Zend/zend_extensions.c b/Zend/zend_extensions.c index a1a6fcd52..0a15a8cd0 100644 --- a/Zend/zend_extensions.c +++ b/Zend/zend_extensions.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_extensions.c,v 1.48.2.1.2.3.2.6 2009/04/08 13:26:35 mattwil Exp $ */ +/* $Id: zend_extensions.c 286859 2009-08-06 01:33:54Z scottmac $ */ #include "zend_extensions.h" @@ -217,67 +217,6 @@ ZEND_API zend_extension *zend_get_extension(const char *extension_name) return NULL; } -/* - * Support for dynamic loading of MH_BUNDLEs on Darwin / Mac OS X - * - */ - -#if HAVE_MACH_O_DYLD_H - -void *zend_mh_bundle_load(char* bundle_path) -{ - NSObjectFileImage bundle_image; - NSModule bundle_handle; - NSSymbol bundle_init_nssymbol; - void (*bundle_init)(void); - - if (NSCreateObjectFileImageFromFile(bundle_path, &bundle_image) != NSObjectFileImageSuccess) { - return NULL; - } - - bundle_handle = NSLinkModule(bundle_image, bundle_path, NSLINKMODULE_OPTION_NONE); - NSDestroyObjectFileImage(bundle_image); - - /* call the init function of the bundle */ - bundle_init_nssymbol = NSLookupSymbolInModule(bundle_handle, "__init"); - if (bundle_init_nssymbol != NULL) { - bundle_init = NSAddressOfSymbol(bundle_init_nssymbol); - bundle_init(); - } - - return bundle_handle; -} - -int zend_mh_bundle_unload(void *bundle_handle) -{ - NSSymbol bundle_fini_nssymbol; - void (*bundle_fini)(void); - - /* call the fini function of the bundle */ - bundle_fini_nssymbol = NSLookupSymbolInModule(bundle_handle, "__fini"); - if (bundle_fini_nssymbol != NULL) { - bundle_fini = NSAddressOfSymbol(bundle_fini_nssymbol); - bundle_fini(); - } - - return (int) NSUnLinkModule(bundle_handle, NULL); -} - -void *zend_mh_bundle_symbol(void *bundle_handle, const char *symbol_name) -{ - NSSymbol symbol; - symbol = NSLookupSymbolInModule(bundle_handle, symbol_name); - return NSAddressOfSymbol(symbol); -} - -const char *zend_mh_bundle_error(void) -{ - /* Witness the state of the art error reporting */ - return NULL; -} - -#endif /* HAVE_MACH_O_DYLD_H */ - /* * Local variables: * tab-width: 4 diff --git a/Zend/zend_extensions.h b/Zend/zend_extensions.h index 1d8e3e2d3..449f37bb6 100644 --- a/Zend/zend_extensions.h +++ b/Zend/zend_extensions.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_extensions.h,v 1.67.2.3.2.3.2.9 2009/06/26 15:44:18 johannes Exp $ */ +/* $Id: zend_extensions.h 282827 2009-06-26 15:44:19Z johannes $ */ #ifndef ZEND_EXTENSIONS_H #define ZEND_EXTENSIONS_H diff --git a/Zend/zend_fast_cache.h b/Zend/zend_fast_cache.h index 66d6f59ae..e67c09b5a 100644 --- a/Zend/zend_fast_cache.h +++ b/Zend/zend_fast_cache.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_fast_cache.h,v 1.21.2.1.2.2.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_fast_cache.h 272370 2008-12-31 11:15:49Z sebastian $ */ #if 0 #ifndef ZEND_FAST_CACHE_H #define ZEND_FAST_CACHE_H diff --git a/Zend/zend_float.c b/Zend/zend_float.c index ab59c9159..263e0c7d2 100644 --- a/Zend/zend_float.c +++ b/Zend/zend_float.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_float.c,v 1.1.2.2 2009/03/18 11:53:10 dmitry Exp $ */ +/* $Id: zend_float.c 277413 2009-03-18 11:53:10Z dmitry $ */ #include "zend.h" #include "zend_compile.h" diff --git a/Zend/zend_float.h b/Zend/zend_float.h index 1c8c96ad9..45acbfd80 100644 --- a/Zend/zend_float.h +++ b/Zend/zend_float.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_float.h,v 1.2.2.5 2009/03/18 10:18:09 dmitry Exp $ */ +/* $Id: zend_float.h 277398 2009-03-18 10:18:10Z dmitry $ */ #ifndef ZEND_FLOAT_H #define ZEND_FLOAT_H diff --git a/Zend/zend_gc.c b/Zend/zend_gc.c index 52e37ddcd..0c3166815 100644 --- a/Zend/zend_gc.c +++ b/Zend/zend_gc.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_gc.c,v 1.1.2.22 2009/04/03 18:52:21 dmitry Exp $ */ +/* $Id: zend_gc.c 278220 2009-04-03 18:52:21Z dmitry $ */ #include "zend.h" #include "zend_API.h" diff --git a/Zend/zend_gc.h b/Zend/zend_gc.h index d4a9b2bc9..5b99e976f 100644 --- a/Zend/zend_gc.h +++ b/Zend/zend_gc.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_gc.h,v 1.1.2.9 2009/01/02 20:45:41 felipe Exp $ */ +/* $Id: zend_gc.h 272619 2009-01-02 20:45:43Z felipe $ */ #ifndef ZEND_GC_H #define ZEND_GC_H diff --git a/Zend/zend_globals.h b/Zend/zend_globals.h index efda0010a..d199019a0 100644 --- a/Zend/zend_globals.h +++ b/Zend/zend_globals.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_globals.h,v 1.141.2.3.2.7.2.24 2009/03/25 15:23:17 dmitry Exp $ */ +/* $Id: zend_globals.h 277761 2009-03-25 15:23:58Z dmitry $ */ #ifndef ZEND_GLOBALS_H #define ZEND_GLOBALS_H diff --git a/Zend/zend_globals_macros.h b/Zend/zend_globals_macros.h index 0a3705dc2..3175fc530 100644 --- a/Zend/zend_globals_macros.h +++ b/Zend/zend_globals_macros.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_globals_macros.h,v 1.22.2.1.2.4.2.3 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_globals_macros.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_GLOBALS_MACROS_H #define ZEND_GLOBALS_MACROS_H diff --git a/Zend/zend_hash.c b/Zend/zend_hash.c index ba2b8312f..e62ecbbf4 100644 --- a/Zend/zend_hash.c +++ b/Zend/zend_hash.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_hash.c,v 1.121.2.4.2.8.2.9 2009/06/07 19:28:15 mattwil Exp $ */ +/* $Id: zend_hash.c 281778 2009-06-07 19:28:15Z mattwil $ */ #include "zend.h" diff --git a/Zend/zend_hash.h b/Zend/zend_hash.h index 8575f6bc5..a80cd563e 100644 --- a/Zend/zend_hash.h +++ b/Zend/zend_hash.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_hash.h,v 1.78.2.2.2.2.2.13 2009/05/25 01:18:00 pollita Exp $ */ +/* $Id: zend_hash.h 281050 2009-05-25 01:18:00Z pollita $ */ #ifndef ZEND_HASH_H #define ZEND_HASH_H diff --git a/Zend/zend_highlight.c b/Zend/zend_highlight.c index b2f2c2a43..60b2bc3da 100644 --- a/Zend/zend_highlight.c +++ b/Zend/zend_highlight.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_highlight.c,v 1.49.2.3.2.2.2.7 2009/05/05 01:35:44 mattwil Exp $ */ +/* $Id: zend_highlight.c 279941 2009-05-05 01:35:44Z mattwil $ */ #include "zend.h" #include diff --git a/Zend/zend_highlight.h b/Zend/zend_highlight.h index 7b00895df..756175f39 100644 --- a/Zend/zend_highlight.h +++ b/Zend/zend_highlight.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_highlight.h,v 1.25.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_highlight.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_HIGHLIGHT_H #define ZEND_HIGHLIGHT_H diff --git a/Zend/zend_indent.c b/Zend/zend_indent.c index 9f5c33c0e..32d99cbfd 100644 --- a/Zend/zend_indent.c +++ b/Zend/zend_indent.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_indent.c,v 1.24.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_indent.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* This indenter doesn't really work, it's here for no particular reason. */ diff --git a/Zend/zend_indent.h b/Zend/zend_indent.h index 76069e4cd..cc00d11c6 100644 --- a/Zend/zend_indent.h +++ b/Zend/zend_indent.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_indent.h,v 1.17.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_indent.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_INDENT_H #define ZEND_INDENT_H diff --git a/Zend/zend_ini.c b/Zend/zend_ini.c index 6147abf8f..6914d7bf1 100644 --- a/Zend/zend_ini.c +++ b/Zend/zend_ini.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ini.c,v 1.39.2.2.2.18.2.18 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_ini.c 284254 2009-07-17 11:49:50Z jani $ */ #include "zend.h" #include "zend_qsort.h" @@ -46,15 +46,21 @@ static int zend_remove_ini_entries(zend_ini_entry *ini_entry, int *module_number static int zend_restore_ini_entry_cb(zend_ini_entry *ini_entry, int stage TSRMLS_DC) /* {{{ */ { + int result = FAILURE; + if (ini_entry->modified) { if (ini_entry->on_modify) { zend_try { /* even if on_modify bails out, we have to continue on with restoring, since there can be allocated variables that would be freed on MM shutdown and would lead to memory corruption later ini entry is modified again */ - ini_entry->on_modify(ini_entry, ini_entry->orig_value, ini_entry->orig_value_length, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage TSRMLS_CC); + result = ini_entry->on_modify(ini_entry, ini_entry->orig_value, ini_entry->orig_value_length, ini_entry->mh_arg1, ini_entry->mh_arg2, ini_entry->mh_arg3, stage TSRMLS_CC); } zend_end_try(); } + if (stage == ZEND_INI_STAGE_RUNTIME && result == FAILURE) { + /* runtime failure is OK */ + return 1; + } if (ini_entry->value != ini_entry->orig_value) { efree(ini_entry->value); } @@ -309,8 +315,11 @@ ZEND_API int zend_restore_ini_entry(char *name, uint name_length, int stage) /* } if (EG(modified_ini_directives)) { - zend_restore_ini_entry_cb(ini_entry, stage TSRMLS_CC); - zend_hash_del(EG(modified_ini_directives), name, name_length); + if (zend_restore_ini_entry_cb(ini_entry, stage TSRMLS_CC) == 0) { + zend_hash_del(EG(modified_ini_directives), name, name_length); + } else { + return FAILURE; + } } return SUCCESS; diff --git a/Zend/zend_ini.h b/Zend/zend_ini.h index 23e89da39..7f866d9ae 100644 --- a/Zend/zend_ini.h +++ b/Zend/zend_ini.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ini.h,v 1.34.2.1.2.6.2.7 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_ini.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_INI_H #define ZEND_INI_H diff --git a/Zend/zend_ini_parser.c b/Zend/zend_ini_parser.c index 75a6a86d3..cfaf58304 100644 --- a/Zend/zend_ini_parser.c +++ b/Zend/zend_ini_parser.c @@ -131,7 +131,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ini_parser.y,v 1.41.2.2.2.2.2.6 2008/12/31 11:13:47 sebastian Exp $ */ +/* $Id: zend_ini_parser.y 272368 2008-12-31 11:13:47Z sebastian $ */ #define DEBUG_CFG_PARSER 0 diff --git a/Zend/zend_ini_parser.y b/Zend/zend_ini_parser.y index 42e292ea6..121236dca 100644 --- a/Zend/zend_ini_parser.y +++ b/Zend/zend_ini_parser.y @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ini_parser.y,v 1.41.2.2.2.2.2.6 2008/12/31 11:13:47 sebastian Exp $ */ +/* $Id: zend_ini_parser.y 272368 2008-12-31 11:13:47Z sebastian $ */ #define DEBUG_CFG_PARSER 0 diff --git a/Zend/zend_ini_scanner.c b/Zend/zend_ini_scanner.c index f5cd73138..b09018e98 100644 --- a/Zend/zend_ini_scanner.c +++ b/Zend/zend_ini_scanner.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Tue May 19 08:53:54 2009 */ +/* Generated by re2c 0.13.5 on Fri Aug 7 18:29:12 2009 */ #line 1 "Zend/zend_ini_scanner.l" /* +----------------------------------------------------------------------+ @@ -22,7 +22,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ini_scanner.c,v 1.1.2.18 2009/05/19 15:59:36 shire Exp $ */ +/* $Id: zend_ini_scanner.c 286914 2009-08-07 15:45:56Z jani $ */ #include #include "zend.h" @@ -56,7 +56,9 @@ #define YYSTATE YYGETCONDITION() #define yytext ((char*)SCNG(yy_text)) #define yyleng SCNG(yy_leng) -#define yyless(x) YYCURSOR = yytext + x +#define yyless(x) do { YYCURSOR = (unsigned char*)yytext + x; \ + yyleng = (unsigned int)x; } while(0) + /* #define yymore() goto yymore_restart */ /* perform sanity check. If this message is triggered you should @@ -158,12 +160,28 @@ static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC) /* {{{ init_ini_scanner() */ -static void init_ini_scanner(TSRMLS_D) +static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC) { + /* Sanity check */ + if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW) { + zend_error(E_WARNING, "Invalid scanner mode"); + return FAILURE; + } + SCNG(lineno) = 1; - SCNG(scanner_mode) = ZEND_INI_SCANNER_NORMAL; + SCNG(scanner_mode) = scanner_mode; + SCNG(yy_in) = fh; + + if (fh != NULL) { + ini_filename = zend_strndup(fh->filename, strlen(fh->filename)); + } else { + ini_filename = NULL; + } + zend_stack_init(&SCNG(state_stack)); BEGIN(INITIAL); + + return SUCCESS; } /* }}} */ @@ -201,15 +219,14 @@ int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRML char *buf; size_t size; - if (zend_stream_fixup(fh, &buf, &size TSRMLS_CC) == FAILURE) { + if (zend_stream_fixup(fh, &buf, &size TSRMLS_CC) == FAILURE || + init_ini_scanner(scanner_mode, fh TSRMLS_CC) == FAILURE + ) { return FAILURE; } - init_ini_scanner(TSRMLS_C); - SCNG(scanner_mode) = scanner_mode; - SCNG(yy_in) = fh; yy_scan_buffer(buf, size TSRMLS_CC); - ini_filename = zend_strndup(fh->filename, strlen(fh->filename)); + return SUCCESS; } /* }}} */ @@ -220,11 +237,12 @@ int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC) { int len = strlen(str); - init_ini_scanner(TSRMLS_C); - SCNG(scanner_mode) = scanner_mode; - SCNG(yy_in) = NULL; + if (init_ini_scanner(scanner_mode, NULL TSRMLS_CC) == FAILURE) { + return FAILURE; + } + yy_scan_buffer(str, len TSRMLS_CC); - ini_filename = NULL; + return SUCCESS; } /* }}} */ @@ -301,7 +319,7 @@ restart: } } -#line 305 "Zend/zend_ini_scanner.c" +#line 323 "Zend/zend_ini_scanner.c" { YYCTYPE yych; unsigned int yyaccept = 0; @@ -338,38 +356,38 @@ restart: yyc_INITIAL: { static const unsigned char yybm[] = { - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 160, 0, 128, 128, 0, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 160, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 192, 128, 128, 192, 192, 128, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 128, 128, 128, 128, 128, 128, - 128, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 128, 128, 128, 128, 192, - 128, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 192, 192, 192, 192, 192, - 192, 192, 192, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 128, 128, 128, 128, 128, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 192, 0, 160, 160, 0, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 192, 128, 128, 160, 128, 160, 128, 160, + 128, 128, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 128, 160, 128, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 128, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 128, 128, 128, 128, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, + 160, 160, 160, 160, 160, 160, 160, 160, }; YYDEBUG(0, *YYCURSOR); @@ -378,19 +396,27 @@ yyc_INITIAL: YYDEBUG(-1, yych); switch (yych) { case '\t': - case ' ': goto yy5; - case '\n': goto yy7; - case '\r': goto yy9; + case ' ': goto yy4; + case '\n': goto yy6; + case '\r': goto yy8; case '!': case '"': case '$': - case '%': case '&': - case '\'': case '(': case ')': + case '{': + case '|': + case '}': + case '~': goto yy9; + case '#': goto yy11; + case '%': + case '\'': + case '*': case '+': case ',': + case '-': + case '.': case '/': case ':': case '<': @@ -398,169 +424,106 @@ yyc_INITIAL: case '?': case '@': case ']': - case '^': - case '{': - case '|': - case '}': - case '~': goto yy10; - case '#': goto yy12; - case '*': - case '-': - case '.': goto yy13; - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - case 'A': - case 'B': - case 'C': - case 'D': - case 'E': - case 'G': - case 'H': - case 'I': - case 'J': - case 'K': - case 'L': - case 'M': - case 'P': - case 'Q': - case 'R': - case 'S': - case 'U': - case 'V': - case 'W': - case 'X': - case 'Z': - case '_': - case 'a': - case 'b': - case 'c': - case 'd': - case 'e': - case 'g': - case 'h': - case 'i': - case 'j': - case 'k': - case 'l': - case 'm': - case 'p': - case 'q': - case 'r': - case 's': - case 'u': - case 'v': - case 'w': - case 'x': - case 'z': goto yy14; - case ';': goto yy15; - case '=': goto yy16; + case '^': goto yy12; + case ';': goto yy13; + case '=': goto yy15; case 'F': - case 'f': goto yy18; + case 'f': goto yy17; case 'N': - case 'n': goto yy19; + case 'n': goto yy18; case 'O': - case 'o': goto yy20; + case 'o': goto yy19; case 'T': - case 't': goto yy21; + case 't': goto yy20; case 'Y': - case 'y': goto yy22; - case '[': goto yy23; - default: goto yy3; + case 'y': goto yy21; + case '[': goto yy22; + default: goto yy2; } yy2: YYDEBUG(2, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy25; +yy3: + YYDEBUG(3, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 389 "Zend/zend_ini_scanner.l" +#line 406 "Zend/zend_ini_scanner.l" { /* Get option name */ RETURN_TOKEN(TC_LABEL, yytext, yyleng); } -#line 486 "Zend/zend_ini_scanner.c" -yy3: - YYDEBUG(3, *YYCURSOR); - ++YYCURSOR; +#line 456 "Zend/zend_ini_scanner.c" +yy4: YYDEBUG(4, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 502 "Zend/zend_ini_scanner.l" - { - return 0; -} -#line 496 "Zend/zend_ini_scanner.c" -yy5: - YYDEBUG(5, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - goto yy63; -yy6: - YYDEBUG(6, *YYCURSOR); + goto yy66; +yy5: + YYDEBUG(5, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 474 "Zend/zend_ini_scanner.l" +#line 518 "Zend/zend_ini_scanner.l" { /* eat whitespace */ goto restart; } -#line 510 "Zend/zend_ini_scanner.c" +#line 470 "Zend/zend_ini_scanner.c" +yy6: + YYDEBUG(6, *YYCURSOR); + ++YYCURSOR; yy7: YYDEBUG(7, *YYCURSOR); - ++YYCURSOR; -yy8: - YYDEBUG(8, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 479 "Zend/zend_ini_scanner.l" +#line 523 "Zend/zend_ini_scanner.l" { SCNG(lineno)++; return END_OF_LINE; } -#line 522 "Zend/zend_ini_scanner.c" +#line 482 "Zend/zend_ini_scanner.c" +yy8: + YYDEBUG(8, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy64; + goto yy7; yy9: YYDEBUG(9, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy61; - goto yy8; -yy10: - YYDEBUG(10, *YYCURSOR); ++YYCURSOR; - YYDEBUG(11, *YYCURSOR); + YYDEBUG(10, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 429 "Zend/zend_ini_scanner.l" +#line 446 "Zend/zend_ini_scanner.l" { /* Disallow these chars outside option values */ return yytext[0]; } -#line 537 "Zend/zend_ini_scanner.c" -yy12: - YYDEBUG(12, *YYCURSOR); +#line 497 "Zend/zend_ini_scanner.c" +yy11: + YYDEBUG(11, *YYCURSOR); yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - goto yy57; + goto yy56; +yy12: + YYDEBUG(12, *YYCURSOR); + yych = *++YYCURSOR; + goto yy25; yy13: YYDEBUG(13, *YYCURSOR); - yych = *++YYCURSOR; - goto yy29; -yy14: + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + goto yy51; YYDEBUG(14, *YYCURSOR); - yych = *++YYCURSOR; - goto yy29; + yyleng = YYCURSOR - SCNG(yy_text); +#line 546 "Zend/zend_ini_scanner.l" + { + return 0; +} +#line 518 "Zend/zend_ini_scanner.c" yy15: YYDEBUG(15, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - goto yy52; -yy16: - YYDEBUG(16, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy50; -yy17: - YYDEBUG(17, *YYCURSOR); + goto yy49; +yy16: + YYDEBUG(16, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 393 "Zend/zend_ini_scanner.l" +#line 410 "Zend/zend_ini_scanner.l" { /* Start option value */ if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) { yy_push_state(ST_RAW TSRMLS_CC); @@ -569,66 +532,63 @@ yy17: } return '='; } -#line 573 "Zend/zend_ini_scanner.c" +#line 536 "Zend/zend_ini_scanner.c" +yy17: + YYDEBUG(17, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'A') goto yy45; + if (yych == 'a') goto yy45; + goto yy25; yy18: YYDEBUG(18, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'A') goto yy46; - if (yych == 'a') goto yy46; - goto yy29; -yy19: - YYDEBUG(19, *YYCURSOR); - yych = *++YYCURSOR; if (yych <= 'U') { - if (yych == 'O') goto yy42; - if (yych <= 'T') goto yy29; - goto yy43; + if (yych == 'O') goto yy41; + if (yych <= 'T') goto yy25; + goto yy42; } else { if (yych <= 'o') { - if (yych <= 'n') goto yy29; - goto yy42; + if (yych <= 'n') goto yy25; + goto yy41; } else { - if (yych == 'u') goto yy43; - goto yy29; + if (yych == 'u') goto yy42; + goto yy25; } } -yy20: - YYDEBUG(20, *YYCURSOR); +yy19: + YYDEBUG(19, *YYCURSOR); yych = *++YYCURSOR; if (yych <= 'N') { - if (yych == 'F') goto yy37; - if (yych <= 'M') goto yy29; - goto yy31; + if (yych == 'F') goto yy36; + if (yych <= 'M') goto yy25; + goto yy30; } else { if (yych <= 'f') { - if (yych <= 'e') goto yy29; - goto yy37; + if (yych <= 'e') goto yy25; + goto yy36; } else { - if (yych == 'n') goto yy31; - goto yy29; + if (yych == 'n') goto yy30; + goto yy25; } } +yy20: + YYDEBUG(20, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'R') goto yy34; + if (yych == 'r') goto yy34; + goto yy25; yy21: YYDEBUG(21, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'R') goto yy35; - if (yych == 'r') goto yy35; - goto yy29; + if (yych == 'E') goto yy26; + if (yych == 'e') goto yy26; + goto yy25; yy22: YYDEBUG(22, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy30; - if (yych == 'e') goto yy30; - goto yy29; -yy23: - YYDEBUG(23, *YYCURSOR); ++YYCURSOR; - if (yybm[0+(yych = *YYCURSOR)] & 32) { - goto yy25; - } - YYDEBUG(24, *YYCURSOR); + YYDEBUG(23, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 327 "Zend/zend_ini_scanner.l" +#line 344 "Zend/zend_ini_scanner.l" { /* Section start */ /* Enter section data lookup state */ if (SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW) { @@ -638,19 +598,37 @@ yy23: } return TC_SECTION; } -#line 642 "Zend/zend_ini_scanner.c" -yy25: - YYDEBUG(25, *YYCURSOR); +#line 602 "Zend/zend_ini_scanner.c" +yy24: + YYDEBUG(24, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(26, *YYCURSOR); +yy25: + YYDEBUG(25, *YYCURSOR); if (yybm[0+yych] & 32) { - goto yy25; + goto yy24; } + if (yych == '[') goto yy27; + goto yy3; +yy26: + YYDEBUG(26, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'S') goto yy30; + if (yych == 's') goto yy30; + goto yy25; +yy27: YYDEBUG(27, *YYCURSOR); + ++YYCURSOR; + YYFILL(1); + yych = *YYCURSOR; + YYDEBUG(28, *YYCURSOR); + if (yybm[0+yych] & 64) { + goto yy27; + } + YYDEBUG(29, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 352 "Zend/zend_ini_scanner.l" +#line 369 "Zend/zend_ini_scanner.l" { /* Start of option with offset */ /* Eat trailing whitespace and [ */ EAT_TRAILING_WHITESPACE_EX('['); @@ -660,494 +638,496 @@ yy25: RETURN_TOKEN(TC_OFFSET, yytext, yyleng); } -#line 664 "Zend/zend_ini_scanner.c" -yy28: - YYDEBUG(28, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy29: - YYDEBUG(29, *YYCURSOR); - if (yybm[0+yych] & 64) { - goto yy28; - } - if (yych == '[') goto yy25; - goto yy2; +#line 642 "Zend/zend_ini_scanner.c" yy30: YYDEBUG(30, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'S') goto yy31; - if (yych != 's') goto yy29; -yy31: - YYDEBUG(31, *YYCURSOR); ++YYCURSOR; - if (yybm[0+(yych = *YYCURSOR)] & 64) { - goto yy28; + if ((yych = *YYCURSOR) <= '$') { + if (yych <= '\r') { + if (yych <= '\t') { + if (yych <= 0x08) goto yy25; + goto yy32; + } else { + if (yych <= '\n') goto yy31; + if (yych <= '\f') goto yy25; + } + } else { + if (yych <= ' ') { + if (yych <= 0x1F) goto yy25; + goto yy32; + } else { + if (yych == '#') goto yy25; + } + } + } else { + if (yych <= ':') { + if (yych <= '&') { + if (yych <= '%') goto yy25; + } else { + if (yych <= '\'') goto yy25; + if (yych >= '*') goto yy25; + } + } else { + if (yych <= '=') { + if (yych == '<') goto yy25; + } else { + if (yych <= 'z') goto yy25; + if (yych >= 0x7F) goto yy25; + } + } } - if (yych == '[') goto yy25; - goto yy34; -yy32: - YYDEBUG(32, *YYCURSOR); +yy31: + YYDEBUG(31, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 381 "Zend/zend_ini_scanner.l" +#line 398 "Zend/zend_ini_scanner.l" { /* TRUE value (when used outside option value/offset this causes parse error!) */ RETURN_TOKEN(BOOL_TRUE, "1", 1); } -#line 697 "Zend/zend_ini_scanner.c" -yy33: - YYDEBUG(33, *YYCURSOR); +#line 687 "Zend/zend_ini_scanner.c" +yy32: + YYDEBUG(32, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; + YYDEBUG(33, *YYCURSOR); + if (yych == '\t') goto yy32; + if (yych == ' ') goto yy32; + goto yy31; yy34: YYDEBUG(34, *YYCURSOR); - if (yych == '\t') goto yy33; - if (yych == ' ') goto yy33; - goto yy32; + yych = *++YYCURSOR; + if (yych == 'U') goto yy35; + if (yych != 'u') goto yy25; yy35: YYDEBUG(35, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'U') goto yy36; - if (yych != 'u') goto yy29; + if (yych == 'E') goto yy30; + if (yych == 'e') goto yy30; + goto yy25; yy36: YYDEBUG(36, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy31; - if (yych == 'e') goto yy31; - goto yy29; + if (yych == 'F') goto yy37; + if (yych != 'f') goto yy25; yy37: YYDEBUG(37, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'F') goto yy38; - if (yych != 'f') goto yy29; -yy38: - YYDEBUG(38, *YYCURSOR); ++YYCURSOR; - if (yybm[0+(yych = *YYCURSOR)] & 64) { - goto yy28; + if ((yych = *YYCURSOR) <= '$') { + if (yych <= '\r') { + if (yych <= '\t') { + if (yych <= 0x08) goto yy25; + goto yy39; + } else { + if (yych <= '\n') goto yy38; + if (yych <= '\f') goto yy25; + } + } else { + if (yych <= ' ') { + if (yych <= 0x1F) goto yy25; + goto yy39; + } else { + if (yych == '#') goto yy25; + } + } + } else { + if (yych <= ':') { + if (yych <= '&') { + if (yych <= '%') goto yy25; + } else { + if (yych <= '\'') goto yy25; + if (yych >= '*') goto yy25; + } + } else { + if (yych <= '=') { + if (yych == '<') goto yy25; + } else { + if (yych <= 'z') goto yy25; + if (yych >= 0x7F) goto yy25; + } + } } - if (yych == '[') goto yy25; - goto yy41; -yy39: - YYDEBUG(39, *YYCURSOR); +yy38: + YYDEBUG(38, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 385 "Zend/zend_ini_scanner.l" +#line 402 "Zend/zend_ini_scanner.l" { /* FALSE value (when used outside option value/offset this causes parse error!)*/ RETURN_TOKEN(BOOL_FALSE, "", 0); } -#line 739 "Zend/zend_ini_scanner.c" -yy40: - YYDEBUG(40, *YYCURSOR); +#line 757 "Zend/zend_ini_scanner.c" +yy39: + YYDEBUG(39, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; + YYDEBUG(40, *YYCURSOR); + if (yych == '\t') goto yy39; + if (yych == ' ') goto yy39; + goto yy38; yy41: YYDEBUG(41, *YYCURSOR); - if (yych == '\t') goto yy40; - if (yych == ' ') goto yy40; - goto yy39; -yy42: - YYDEBUG(42, *YYCURSOR); yych = *++YYCURSOR; - if (yych <= 'N') { - if (yych <= '.') { - if (yych == '*') goto yy28; - if (yych <= ',') goto yy41; - goto yy28; + if (yych <= '&') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych <= 0x08) goto yy25; + if (yych <= '\t') goto yy39; + goto yy38; + } else { + if (yych == '\r') goto yy38; + goto yy25; + } } else { - if (yych <= '9') { - if (yych <= '/') goto yy41; - goto yy28; + if (yych <= '#') { + if (yych <= ' ') goto yy39; + if (yych <= '"') goto yy38; + goto yy25; } else { - if (yych <= '@') goto yy41; - if (yych <= 'M') goto yy28; - goto yy45; + if (yych == '%') goto yy25; + goto yy38; } } } else { - if (yych <= '_') { - if (yych <= 'Z') goto yy28; - if (yych <= '[') goto yy25; - if (yych <= '^') goto yy41; - goto yy28; + if (yych <= '=') { + if (yych <= ':') { + if (yych <= '\'') goto yy25; + if (yych <= ')') goto yy38; + goto yy25; + } else { + if (yych == '<') goto yy25; + goto yy38; + } } else { if (yych <= 'm') { - if (yych <= '`') goto yy41; - goto yy28; + if (yych == 'N') goto yy44; + goto yy25; } else { - if (yych <= 'n') goto yy45; - if (yych <= 'z') goto yy28; - goto yy41; + if (yych <= 'n') goto yy44; + if (yych <= 'z') goto yy25; + if (yych <= '~') goto yy38; + goto yy25; } } } +yy42: + YYDEBUG(42, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == 'L') goto yy43; + if (yych != 'l') goto yy25; yy43: YYDEBUG(43, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy44; - if (yych != 'l') goto yy29; + if (yych == 'L') goto yy37; + if (yych == 'l') goto yy37; + goto yy25; yy44: YYDEBUG(44, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy38; - if (yych == 'l') goto yy38; - goto yy29; + if (yych == 'E') goto yy37; + if (yych == 'e') goto yy37; + goto yy25; yy45: YYDEBUG(45, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'E') goto yy38; - if (yych == 'e') goto yy38; - goto yy29; + if (yych == 'L') goto yy46; + if (yych != 'l') goto yy25; yy46: YYDEBUG(46, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'L') goto yy47; - if (yych != 'l') goto yy29; + if (yych == 'S') goto yy47; + if (yych != 's') goto yy25; yy47: YYDEBUG(47, *YYCURSOR); yych = *++YYCURSOR; - if (yych == 'S') goto yy48; - if (yych != 's') goto yy29; + if (yych == 'E') goto yy37; + if (yych == 'e') goto yy37; + goto yy25; yy48: YYDEBUG(48, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == 'E') goto yy38; - if (yych == 'e') goto yy38; - goto yy29; -yy49: - YYDEBUG(49, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; +yy49: + YYDEBUG(49, *YYCURSOR); + if (yych == '\t') goto yy48; + if (yych == ' ') goto yy48; + goto yy16; yy50: YYDEBUG(50, *YYCURSOR); - if (yych == '\t') goto yy49; - if (yych == ' ') goto yy49; - goto yy17; -yy51: - YYDEBUG(51, *YYCURSOR); ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; -yy52: - YYDEBUG(52, *YYCURSOR); +yy51: + YYDEBUG(51, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy51; + goto yy50; } - if (yych >= '\r') goto yy55; + if (yych >= '\r') goto yy54; +yy52: + YYDEBUG(52, *YYCURSOR); + ++YYCURSOR; yy53: YYDEBUG(53, *YYCURSOR); - ++YYCURSOR; -yy54: - YYDEBUG(54, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 484 "Zend/zend_ini_scanner.l" +#line 528 "Zend/zend_ini_scanner.l" { /* Comment */ BEGIN(INITIAL); SCNG(lineno)++; return END_OF_LINE; } -#line 851 "Zend/zend_ini_scanner.c" +#line 878 "Zend/zend_ini_scanner.c" +yy54: + YYDEBUG(54, *YYCURSOR); + yych = *++YYCURSOR; + if (yych == '\n') goto yy52; + goto yy53; yy55: YYDEBUG(55, *YYCURSOR); - yych = *++YYCURSOR; - if (yych == '\n') goto yy53; - goto yy54; + yyaccept = 1; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; yy56: YYDEBUG(56, *YYCURSOR); + if (yych <= '&') { + if (yych <= '\r') { + if (yych <= '\t') { + if (yych <= 0x08) goto yy55; + } else { + if (yych <= '\n') goto yy61; + if (yych <= '\f') goto yy55; + goto yy63; + } + } else { + if (yych <= '#') { + if (yych <= 0x1F) goto yy55; + if (yych >= '#') goto yy55; + } else { + if (yych == '%') goto yy55; + } + } + } else { + if (yych <= '<') { + if (yych <= ')') { + if (yych <= '\'') goto yy55; + } else { + if (yych != ';') goto yy55; + } + } else { + if (yych <= '[') { + if (yych <= '=') goto yy57; + if (yych <= 'Z') goto yy55; + goto yy59; + } else { + if (yych <= 'z') goto yy55; + if (yych >= 0x7F) goto yy55; + } + } + } +yy57: + YYDEBUG(57, *YYCURSOR); ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; -yy57: - YYDEBUG(57, *YYCURSOR); - if (yych == '\n') goto yy58; - if (yych == '\r') goto yy60; - goto yy56; -yy58: YYDEBUG(58, *YYCURSOR); - ++YYCURSOR; + if (yych == '\n') goto yy61; + if (yych == '\r') goto yy63; + goto yy57; yy59: YYDEBUG(59, *YYCURSOR); + yyaccept = 3; + YYMARKER = ++YYCURSOR; + YYFILL(2); + yych = *YYCURSOR; + YYDEBUG(60, *YYCURSOR); + if (yych <= '\f') { + if (yych <= 0x08) goto yy57; + if (yych <= '\t') goto yy59; + if (yych >= '\v') goto yy57; + } else { + if (yych <= '\r') goto yy63; + if (yych == ' ') goto yy59; + goto yy57; + } +yy61: + YYDEBUG(61, *YYCURSOR); + ++YYCURSOR; +yy62: + YYDEBUG(62, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 490 "Zend/zend_ini_scanner.l" +#line 534 "Zend/zend_ini_scanner.l" { /* #Comment */ zend_error(E_DEPRECATED, "Comments starting with '#' are deprecated in %s on line %d", zend_ini_scanner_get_filename(TSRMLS_C), SCNG(lineno)); BEGIN(INITIAL); SCNG(lineno)++; return END_OF_LINE; } -#line 880 "Zend/zend_ini_scanner.c" -yy60: - YYDEBUG(60, *YYCURSOR); +#line 965 "Zend/zend_ini_scanner.c" +yy63: + YYDEBUG(63, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy58; - goto yy59; -yy61: - YYDEBUG(61, *YYCURSOR); + if (yych == '\n') goto yy61; + goto yy62; +yy64: + YYDEBUG(64, *YYCURSOR); yych = *++YYCURSOR; - goto yy8; -yy62: - YYDEBUG(62, *YYCURSOR); + goto yy7; +yy65: + YYDEBUG(65, *YYCURSOR); yyaccept = 0; YYMARKER = ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; -yy63: - YYDEBUG(63, *YYCURSOR); +yy66: + YYDEBUG(66, *YYCURSOR); if (yych <= ' ') { if (yych <= '\n') { - if (yych <= 0x08) goto yy6; - if (yych <= '\t') goto yy62; - goto yy61; + if (yych <= 0x08) goto yy5; + if (yych <= '\t') goto yy65; + goto yy64; } else { - if (yych == '\r') goto yy64; - if (yych <= 0x1F) goto yy6; - goto yy62; + if (yych == '\r') goto yy67; + if (yych <= 0x1F) goto yy5; + goto yy65; } } else { if (yych <= ':') { - if (yych == '#') goto yy56; - goto yy6; + if (yych == '#') goto yy57; + goto yy5; } else { - if (yych <= ';') goto yy51; - if (yych == '=') goto yy49; - goto yy6; + if (yych <= ';') goto yy50; + if (yych == '=') goto yy48; + goto yy5; } } -yy64: - YYDEBUG(64, *YYCURSOR); +yy67: + YYDEBUG(67, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) == '\n') goto yy61; - goto yy8; + if ((yych = *YYCURSOR) == '\n') goto yy64; + goto yy7; } /* *********************************** */ yyc_ST_DOUBLE_QUOTES: { static const unsigned char yybm[] = { - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 144, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 144, 16, 0, 16, 32, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 64, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, - 16, 16, 16, 16, 16, 16, 16, 16, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 128, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 128, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, }; - YYDEBUG(65, *YYCURSOR); - YYFILL(3); - yych = *YYCURSOR; - if (yych <= '#') { - if (yych == '"') goto yy69; - } else { - if (yych <= '$') goto yy71; - if (yych == '\\') goto yy73; - } - YYDEBUG(67, *YYCURSOR); - yyaccept = 0; - yych = *(YYMARKER = ++YYCURSOR); - goto yy77; -yy68: YYDEBUG(68, *YYCURSOR); + YYFILL(2); + yych = *YYCURSOR; + if (yych == '"') goto yy72; + if (yych == '$') goto yy74; + YYDEBUG(70, *YYCURSOR); + ++YYCURSOR; +yy71: + YYDEBUG(71, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 456 "Zend/zend_ini_scanner.l" +#line 478 "Zend/zend_ini_scanner.l" { /* Escape double quoted string contents */ - if(yyleng > 1 && yytext[yyleng-1] == '"' && yytext[yyleng-2] == '\\') { - yyless(yyleng-1); - yyleng--; + if (YYCURSOR > YYLIMIT) { + return 0; } + + while (YYCURSOR < YYLIMIT) { + switch (*YYCURSOR++) { + case '"': + if (YYCURSOR < YYLIMIT && YYCURSOR[-2] == '\\' && *YYCURSOR != '\r' && *YYCURSOR != '\n') { + continue; + } + break; + case '$': + if (*YYCURSOR == '{') { + break; + } + continue; + case '\\': + if (YYCURSOR < YYLIMIT && *YYCURSOR != '"') { + YYCURSOR++; + } + /* fall through */ + default: + continue; + } + + YYCURSOR--; + break; + } + + yyleng = YYCURSOR - SCNG(yy_text); + zend_ini_escape_string(ini_lval, yytext, yyleng, '"' TSRMLS_CC); return TC_QUOTED_STRING; } -#line 986 "Zend/zend_ini_scanner.c" -yy69: - YYDEBUG(69, *YYCURSOR); +#line 1092 "Zend/zend_ini_scanner.c" +yy72: + YYDEBUG(72, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy91; -yy70: - YYDEBUG(70, *YYCURSOR); + goto yy78; +yy73: + YYDEBUG(73, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 465 "Zend/zend_ini_scanner.l" +#line 473 "Zend/zend_ini_scanner.l" { /* Double quoted '"' string ends */ yy_pop_state(TSRMLS_C); return '"'; } -#line 1000 "Zend/zend_ini_scanner.c" -yy71: - YYDEBUG(71, *YYCURSOR); - ++YYCURSOR; - if ((yych = *YYCURSOR) <= '\\') { - if (yych <= 0x00) goto yy72; - if (yych <= '[') goto yy76; - goto yy80; - } else { - if (yych == '{') goto yy88; - goto yy76; - } -yy72: - YYDEBUG(72, *YYCURSOR); - yyleng = YYCURSOR - SCNG(yy_text); -#line 502 "Zend/zend_ini_scanner.l" - { - return 0; -} -#line 1019 "Zend/zend_ini_scanner.c" -yy73: - YYDEBUG(73, *YYCURSOR); - yyaccept = 1; - yych = *(YYMARKER = ++YYCURSOR); - if (yych != '"') goto yy76; +#line 1106 "Zend/zend_ini_scanner.c" +yy74: YYDEBUG(74, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy75; - if (yych != '\r') goto yy76; -yy75: + if (yych != '{') goto yy71; YYDEBUG(75, *YYCURSOR); - YYCURSOR = YYMARKER; - if (yyaccept <= 0) { - goto yy68; - } else { - goto yy72; - } -yy76: - YYDEBUG(76, *YYCURSOR); - yyaccept = 0; - YYMARKER = ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; -yy77: - YYDEBUG(77, *YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy76; - } - if (yych <= '#') goto yy68; - if (yych <= '$') goto yy79; - YYDEBUG(78, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yych == '"') goto yy85; - goto yy76; -yy79: - YYDEBUG(79, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yych <= '\\') { - if (yych <= 0x00) goto yy75; - if (yych <= '[') goto yy76; - } else { - if (yych == '{') goto yy75; - goto yy76; - } -yy80: - YYDEBUG(80, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 32) { - goto yy81; - } - if (yych == '\\') goto yy83; - goto yy76; -yy81: - YYDEBUG(81, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(82, *YYCURSOR); - if (yybm[0+yych] & 32) { - goto yy81; - } - if (yych == '\\') goto yy86; - goto yy76; -yy83: - YYDEBUG(83, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - YYDEBUG(84, *YYCURSOR); - if (yybm[0+yych] & 16) { - goto yy76; - } - if (yych <= '#') goto yy85; - if (yych <= '$') goto yy81; - goto yy83; -yy85: - YYDEBUG(85, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yych == '\n') goto yy68; - if (yych == '\r') goto yy68; - goto yy76; -yy86: - YYDEBUG(86, *YYCURSOR); - ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 16) { - goto yy76; - } - if (yych <= '#') goto yy87; - if (yych <= '$') goto yy81; - goto yy83; -yy87: - YYDEBUG(87, *YYCURSOR); ++YYCURSOR; - YYFILL(1); - yych = *YYCURSOR; - if (yybm[0+yych] & 32) { - goto yy81; - } - if (yych == '\\') goto yy83; - goto yy76; -yy88: - YYDEBUG(88, *YYCURSOR); - ++YYCURSOR; - YYDEBUG(89, *YYCURSOR); + YYDEBUG(76, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 367 "Zend/zend_ini_scanner.l" +#line 384 "Zend/zend_ini_scanner.l" { /* Variable start */ yy_push_state(ST_VARNAME TSRMLS_CC); return TC_DOLLAR_CURLY; } -#line 1140 "Zend/zend_ini_scanner.c" -yy90: - YYDEBUG(90, *YYCURSOR); +#line 1120 "Zend/zend_ini_scanner.c" +yy77: + YYDEBUG(77, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy91: - YYDEBUG(91, *YYCURSOR); +yy78: + YYDEBUG(78, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy90; + goto yy77; } - goto yy70; + goto yy73; } /* *********************************** */ yyc_ST_OFFSET: @@ -1186,495 +1166,495 @@ yyc_ST_OFFSET: 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, 66, }; - YYDEBUG(92, *YYCURSOR); + YYDEBUG(79, *YYCURSOR); YYFILL(2); yych = *YYCURSOR; if (yych <= ',') { if (yych <= ' ') { if (yych <= '\n') { - if (yych <= 0x08) goto yy94; - if (yych <= '\t') goto yy96; - goto yy97; + if (yych <= 0x08) goto yy81; + if (yych <= '\t') goto yy83; + goto yy84; } else { - if (yych == '\r') goto yy97; - if (yych >= ' ') goto yy96; + if (yych == '\r') goto yy84; + if (yych >= ' ') goto yy83; } } else { if (yych <= '#') { - if (yych == '"') goto yy99; + if (yych == '"') goto yy86; } else { - if (yych <= '$') goto yy101; - if (yych == '\'') goto yy102; + if (yych <= '$') goto yy88; + if (yych == '\'') goto yy89; } } } else { if (yych <= '@') { if (yych <= '/') { - if (yych <= '-') goto yy103; - if (yych <= '.') goto yy104; + if (yych <= '-') goto yy90; + if (yych <= '.') goto yy91; } else { - if (yych <= '9') goto yy105; - if (yych == ';') goto yy97; + if (yych <= '9') goto yy92; + if (yych == ';') goto yy84; } } else { if (yych <= '\\') { - if (yych <= 'Z') goto yy107; - if (yych >= '\\') goto yy109; + if (yych <= 'Z') goto yy94; + if (yych >= '\\') goto yy96; } else { - if (yych <= ']') goto yy110; - if (yych <= '`') goto yy94; - if (yych <= 'z') goto yy107; + if (yych <= ']') goto yy97; + if (yych <= '`') goto yy81; + if (yych <= 'z') goto yy94; } } } -yy94: - YYDEBUG(94, *YYCURSOR); +yy81: + YYDEBUG(81, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - goto yy113; -yy95: - YYDEBUG(95, *YYCURSOR); + goto yy100; +yy82: + YYDEBUG(82, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 447 "Zend/zend_ini_scanner.l" +#line 464 "Zend/zend_ini_scanner.l" { /* Get rest as section/offset value */ RETURN_TOKEN(TC_STRING, yytext, yyleng); } -#line 1243 "Zend/zend_ini_scanner.c" -yy96: - YYDEBUG(96, *YYCURSOR); +#line 1223 "Zend/zend_ini_scanner.c" +yy83: + YYDEBUG(83, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yybm[0+yych] & 128) { - goto yy139; + goto yy126; } - if (yych == '"') goto yy141; - if (yych == ']') goto yy142; - goto yy113; -yy97: - YYDEBUG(97, *YYCURSOR); + if (yych == '"') goto yy128; + if (yych == ']') goto yy129; + goto yy100; +yy84: + YYDEBUG(84, *YYCURSOR); ++YYCURSOR; -yy98: - YYDEBUG(98, *YYCURSOR); +yy85: + YYDEBUG(85, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 502 "Zend/zend_ini_scanner.l" +#line 546 "Zend/zend_ini_scanner.l" { return 0; } -#line 1264 "Zend/zend_ini_scanner.c" -yy99: - YYDEBUG(99, *YYCURSOR); +#line 1244 "Zend/zend_ini_scanner.c" +yy86: + YYDEBUG(86, *YYCURSOR); ++YYCURSOR; -yy100: - YYDEBUG(100, *YYCURSOR); +yy87: + YYDEBUG(87, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 451 "Zend/zend_ini_scanner.l" +#line 468 "Zend/zend_ini_scanner.l" { /* Double quoted '"' string start */ yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); return '"'; } -#line 1276 "Zend/zend_ini_scanner.c" -yy101: - YYDEBUG(101, *YYCURSOR); +#line 1256 "Zend/zend_ini_scanner.c" +yy88: + YYDEBUG(88, *YYCURSOR); yych = *++YYCURSOR; if (yych <= '\\') { - if (yych <= 0x00) goto yy98; - if (yych <= '[') goto yy112; - goto yy117; + if (yych <= 0x00) goto yy85; + if (yych <= '[') goto yy99; + goto yy104; } else { - if (yych == '{') goto yy137; - goto yy112; + if (yych == '{') goto yy124; + goto yy99; } -yy102: - YYDEBUG(102, *YYCURSOR); +yy89: + YYDEBUG(89, *YYCURSOR); yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); if (yybm[0+yych] & 64) { - goto yy133; + goto yy120; } - goto yy98; -yy103: - YYDEBUG(103, *YYCURSOR); + goto yy85; +yy90: + YYDEBUG(90, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy113; - if (yych <= '9') goto yy131; - goto yy113; -yy104: - YYDEBUG(104, *YYCURSOR); + if (yych <= '/') goto yy100; + if (yych <= '9') goto yy118; + goto yy100; +yy91: + YYDEBUG(91, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy113; - if (yych <= '9') goto yy129; - goto yy113; -yy105: - YYDEBUG(105, *YYCURSOR); + if (yych <= '/') goto yy100; + if (yych <= '9') goto yy116; + goto yy100; +yy92: + YYDEBUG(92, *YYCURSOR); yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '\'') { if (yych <= '\r') { - if (yych == '\n') goto yy106; - if (yych <= '\f') goto yy113; + if (yych == '\n') goto yy93; + if (yych <= '\f') goto yy100; } else { - if (yych == '"') goto yy106; - if (yych <= '&') goto yy113; + if (yych == '"') goto yy93; + if (yych <= '&') goto yy100; } } else { if (yych <= '9') { - if (yych == '.') goto yy125; - if (yych <= '/') goto yy113; - goto yy127; + if (yych == '.') goto yy112; + if (yych <= '/') goto yy100; + goto yy114; } else { if (yych <= ';') { - if (yych <= ':') goto yy113; + if (yych <= ':') goto yy100; } else { - if (yych != ']') goto yy113; + if (yych != ']') goto yy100; } } } -yy106: - YYDEBUG(106, *YYCURSOR); +yy93: + YYDEBUG(93, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 425 "Zend/zend_ini_scanner.l" +#line 442 "Zend/zend_ini_scanner.l" { /* Get number option value as string */ RETURN_TOKEN(TC_NUMBER, yytext, yyleng); } -#line 1342 "Zend/zend_ini_scanner.c" -yy107: - YYDEBUG(107, *YYCURSOR); +#line 1322 "Zend/zend_ini_scanner.c" +yy94: + YYDEBUG(94, *YYCURSOR); yyaccept = 3; yych = *(YYMARKER = ++YYCURSOR); if (yybm[0+yych] & 16) { - goto yy123; + goto yy110; } if (yych <= '"') { if (yych <= '\f') { - if (yych != '\n') goto yy113; + if (yych != '\n') goto yy100; } else { - if (yych <= '\r') goto yy108; - if (yych <= '!') goto yy113; + if (yych <= '\r') goto yy95; + if (yych <= '!') goto yy100; } } else { if (yych <= ':') { - if (yych != '\'') goto yy113; + if (yych != '\'') goto yy100; } else { - if (yych <= ';') goto yy108; - if (yych != ']') goto yy113; + if (yych <= ';') goto yy95; + if (yych != ']') goto yy100; } } -yy108: - YYDEBUG(108, *YYCURSOR); +yy95: + YYDEBUG(95, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 421 "Zend/zend_ini_scanner.l" +#line 438 "Zend/zend_ini_scanner.l" { /* Get constant option value */ RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); } -#line 1372 "Zend/zend_ini_scanner.c" -yy109: - YYDEBUG(109, *YYCURSOR); +#line 1352 "Zend/zend_ini_scanner.c" +yy96: + YYDEBUG(96, *YYCURSOR); yych = *++YYCURSOR; - goto yy112; -yy110: - YYDEBUG(110, *YYCURSOR); + goto yy99; +yy97: + YYDEBUG(97, *YYCURSOR); ++YYCURSOR; -yy111: - YYDEBUG(111, *YYCURSOR); +yy98: + YYDEBUG(98, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 362 "Zend/zend_ini_scanner.l" +#line 379 "Zend/zend_ini_scanner.l" { /* End of section or an option offset */ BEGIN(INITIAL); return ']'; } -#line 1388 "Zend/zend_ini_scanner.c" -yy112: - YYDEBUG(112, *YYCURSOR); +#line 1368 "Zend/zend_ini_scanner.c" +yy99: + YYDEBUG(99, *YYCURSOR); yyaccept = 0; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy113: - YYDEBUG(113, *YYCURSOR); +yy100: + YYDEBUG(100, *YYCURSOR); if (yybm[0+yych] & 2) { - goto yy112; + goto yy99; } - if (yych == '$') goto yy115; - if (yych != '\\') goto yy95; -yy114: - YYDEBUG(114, *YYCURSOR); + if (yych == '$') goto yy102; + if (yych != '\\') goto yy82; +yy101: + YYDEBUG(101, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - goto yy112; -yy115: - YYDEBUG(115, *YYCURSOR); + goto yy99; +yy102: + YYDEBUG(102, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; if (yych <= '\\') { - if (yych <= 0x00) goto yy116; - if (yych <= '[') goto yy112; - goto yy117; + if (yych <= 0x00) goto yy103; + if (yych <= '[') goto yy99; + goto yy104; } else { - if (yych != '{') goto yy112; - } -yy116: - YYDEBUG(116, *YYCURSOR); + if (yych != '{') goto yy99; + } +yy103: + YYDEBUG(103, *YYCURSOR); YYCURSOR = YYMARKER; if (yyaccept <= 1) { if (yyaccept <= 0) { - goto yy95; + goto yy82; } else { - goto yy98; + goto yy85; } } else { if (yyaccept <= 2) { - goto yy106; + goto yy93; } else { - goto yy108; + goto yy95; } } -yy117: - YYDEBUG(117, *YYCURSOR); +yy104: + YYDEBUG(104, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; if (yybm[0+yych] & 4) { - goto yy118; + goto yy105; } - if (yych == '\\') goto yy120; - goto yy112; -yy118: - YYDEBUG(118, *YYCURSOR); + if (yych == '\\') goto yy107; + goto yy99; +yy105: + YYDEBUG(105, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(119, *YYCURSOR); + YYDEBUG(106, *YYCURSOR); if (yybm[0+yych] & 4) { - goto yy118; + goto yy105; } - if (yych == '\\') goto yy122; - goto yy112; -yy120: - YYDEBUG(120, *YYCURSOR); + if (yych == '\\') goto yy109; + goto yy99; +yy107: + YYDEBUG(107, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(121, *YYCURSOR); + YYDEBUG(108, *YYCURSOR); if (yybm[0+yych] & 4) { - goto yy118; + goto yy105; } - if (yych == '\\') goto yy120; - goto yy112; -yy122: - YYDEBUG(122, *YYCURSOR); + if (yych == '\\') goto yy107; + goto yy99; +yy109: + YYDEBUG(109, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; if (yybm[0+yych] & 4) { - goto yy118; + goto yy105; } - if (yych == '\\') goto yy120; - goto yy112; -yy123: - YYDEBUG(123, *YYCURSOR); + if (yych == '\\') goto yy107; + goto yy99; +yy110: + YYDEBUG(110, *YYCURSOR); yyaccept = 3; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(124, *YYCURSOR); + YYDEBUG(111, *YYCURSOR); if (yybm[0+yych] & 16) { - goto yy123; + goto yy110; } if (yych <= '$') { if (yych <= '\r') { - if (yych == '\n') goto yy108; - if (yych <= '\f') goto yy112; - goto yy108; + if (yych == '\n') goto yy95; + if (yych <= '\f') goto yy99; + goto yy95; } else { - if (yych == '"') goto yy108; - if (yych <= '#') goto yy112; - goto yy115; + if (yych == '"') goto yy95; + if (yych <= '#') goto yy99; + goto yy102; } } else { if (yych <= ';') { - if (yych == '\'') goto yy108; - if (yych <= ':') goto yy112; - goto yy108; + if (yych == '\'') goto yy95; + if (yych <= ':') goto yy99; + goto yy95; } else { - if (yych <= '[') goto yy112; - if (yych <= '\\') goto yy114; - if (yych <= ']') goto yy108; - goto yy112; + if (yych <= '[') goto yy99; + if (yych <= '\\') goto yy101; + if (yych <= ']') goto yy95; + goto yy99; } } -yy125: - YYDEBUG(125, *YYCURSOR); +yy112: + YYDEBUG(112, *YYCURSOR); yyaccept = 2; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(126, *YYCURSOR); + YYDEBUG(113, *YYCURSOR); if (yybm[0+yych] & 32) { - goto yy125; + goto yy112; } if (yych <= '$') { if (yych <= '\r') { - if (yych == '\n') goto yy106; - if (yych <= '\f') goto yy112; - goto yy106; + if (yych == '\n') goto yy93; + if (yych <= '\f') goto yy99; + goto yy93; } else { - if (yych == '"') goto yy106; - if (yych <= '#') goto yy112; - goto yy115; + if (yych == '"') goto yy93; + if (yych <= '#') goto yy99; + goto yy102; } } else { if (yych <= ';') { - if (yych == '\'') goto yy106; - if (yych <= ':') goto yy112; - goto yy106; + if (yych == '\'') goto yy93; + if (yych <= ':') goto yy99; + goto yy93; } else { - if (yych <= '[') goto yy112; - if (yych <= '\\') goto yy114; - if (yych <= ']') goto yy106; - goto yy112; + if (yych <= '[') goto yy99; + if (yych <= '\\') goto yy101; + if (yych <= ']') goto yy93; + goto yy99; } } -yy127: - YYDEBUG(127, *YYCURSOR); +yy114: + YYDEBUG(114, *YYCURSOR); yyaccept = 2; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(128, *YYCURSOR); + YYDEBUG(115, *YYCURSOR); if (yych <= '\'') { if (yych <= '!') { if (yych <= '\n') { - if (yych <= '\t') goto yy112; - goto yy106; + if (yych <= '\t') goto yy99; + goto yy93; } else { - if (yych == '\r') goto yy106; - goto yy112; + if (yych == '\r') goto yy93; + goto yy99; } } else { if (yych <= '#') { - if (yych <= '"') goto yy106; - goto yy112; + if (yych <= '"') goto yy93; + goto yy99; } else { - if (yych <= '$') goto yy115; - if (yych <= '&') goto yy112; - goto yy106; + if (yych <= '$') goto yy102; + if (yych <= '&') goto yy99; + goto yy93; } } } else { if (yych <= ':') { if (yych <= '.') { - if (yych <= '-') goto yy112; - goto yy125; - } else { - if (yych <= '/') goto yy112; - if (yych <= '9') goto yy127; + if (yych <= '-') goto yy99; goto yy112; + } else { + if (yych <= '/') goto yy99; + if (yych <= '9') goto yy114; + goto yy99; } } else { if (yych <= '[') { - if (yych <= ';') goto yy106; - goto yy112; + if (yych <= ';') goto yy93; + goto yy99; } else { - if (yych <= '\\') goto yy114; - if (yych <= ']') goto yy106; - goto yy112; + if (yych <= '\\') goto yy101; + if (yych <= ']') goto yy93; + goto yy99; } } } -yy129: - YYDEBUG(129, *YYCURSOR); +yy116: + YYDEBUG(116, *YYCURSOR); yyaccept = 2; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(130, *YYCURSOR); + YYDEBUG(117, *YYCURSOR); if (yych <= '&') { if (yych <= '\r') { - if (yych == '\n') goto yy106; - if (yych <= '\f') goto yy112; - goto yy106; + if (yych == '\n') goto yy93; + if (yych <= '\f') goto yy99; + goto yy93; } else { if (yych <= '"') { - if (yych <= '!') goto yy112; - goto yy106; + if (yych <= '!') goto yy99; + goto yy93; } else { - if (yych == '$') goto yy115; - goto yy112; + if (yych == '$') goto yy102; + goto yy99; } } } else { if (yych <= ':') { - if (yych <= '\'') goto yy106; - if (yych <= '/') goto yy112; - if (yych <= '9') goto yy129; - goto yy112; + if (yych <= '\'') goto yy93; + if (yych <= '/') goto yy99; + if (yych <= '9') goto yy116; + goto yy99; } else { if (yych <= '[') { - if (yych <= ';') goto yy106; - goto yy112; + if (yych <= ';') goto yy93; + goto yy99; } else { - if (yych <= '\\') goto yy114; - if (yych <= ']') goto yy106; - goto yy112; + if (yych <= '\\') goto yy101; + if (yych <= ']') goto yy93; + goto yy99; } } } -yy131: - YYDEBUG(131, *YYCURSOR); +yy118: + YYDEBUG(118, *YYCURSOR); yyaccept = 2; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(132, *YYCURSOR); + YYDEBUG(119, *YYCURSOR); if (yych <= '&') { if (yych <= '\r') { - if (yych == '\n') goto yy106; - if (yych <= '\f') goto yy112; - goto yy106; + if (yych == '\n') goto yy93; + if (yych <= '\f') goto yy99; + goto yy93; } else { if (yych <= '"') { - if (yych <= '!') goto yy112; - goto yy106; + if (yych <= '!') goto yy99; + goto yy93; } else { - if (yych == '$') goto yy115; - goto yy112; + if (yych == '$') goto yy102; + goto yy99; } } } else { if (yych <= ':') { - if (yych <= '\'') goto yy106; - if (yych <= '/') goto yy112; - if (yych <= '9') goto yy131; - goto yy112; + if (yych <= '\'') goto yy93; + if (yych <= '/') goto yy99; + if (yych <= '9') goto yy118; + goto yy99; } else { if (yych <= '[') { - if (yych <= ';') goto yy106; - goto yy112; + if (yych <= ';') goto yy93; + goto yy99; } else { - if (yych <= '\\') goto yy114; - if (yych <= ']') goto yy106; - goto yy112; + if (yych <= '\\') goto yy101; + if (yych <= ']') goto yy93; + goto yy99; } } } -yy133: - YYDEBUG(133, *YYCURSOR); +yy120: + YYDEBUG(120, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(134, *YYCURSOR); + YYDEBUG(121, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy133; + goto yy120; } - YYDEBUG(135, *YYCURSOR); + YYDEBUG(122, *YYCURSOR); ++YYCURSOR; - YYDEBUG(136, *YYCURSOR); + YYDEBUG(123, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 337 "Zend/zend_ini_scanner.l" +#line 354 "Zend/zend_ini_scanner.l" { /* Raw string */ /* Eat leading and trailing single quotes */ if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { @@ -1683,59 +1663,59 @@ yy133: } RETURN_TOKEN(TC_RAW, yytext, yyleng); } -#line 1687 "Zend/zend_ini_scanner.c" -yy137: - YYDEBUG(137, *YYCURSOR); +#line 1667 "Zend/zend_ini_scanner.c" +yy124: + YYDEBUG(124, *YYCURSOR); ++YYCURSOR; - YYDEBUG(138, *YYCURSOR); + YYDEBUG(125, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 367 "Zend/zend_ini_scanner.l" +#line 384 "Zend/zend_ini_scanner.l" { /* Variable start */ yy_push_state(ST_VARNAME TSRMLS_CC); return TC_DOLLAR_CURLY; } -#line 1698 "Zend/zend_ini_scanner.c" -yy139: - YYDEBUG(139, *YYCURSOR); +#line 1678 "Zend/zend_ini_scanner.c" +yy126: + YYDEBUG(126, *YYCURSOR); yyaccept = 0; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(140, *YYCURSOR); + YYDEBUG(127, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy139; + goto yy126; } if (yych <= '$') { if (yych <= '\r') { - if (yych == '\n') goto yy95; - if (yych <= '\f') goto yy112; - goto yy95; + if (yych == '\n') goto yy82; + if (yych <= '\f') goto yy99; + goto yy82; } else { - if (yych == '"') goto yy141; - if (yych <= '#') goto yy112; - goto yy115; + if (yych == '"') goto yy128; + if (yych <= '#') goto yy99; + goto yy102; } } else { if (yych <= ';') { - if (yych == '\'') goto yy95; - if (yych <= ':') goto yy112; - goto yy95; + if (yych == '\'') goto yy82; + if (yych <= ':') goto yy99; + goto yy82; } else { - if (yych <= '[') goto yy112; - if (yych <= '\\') goto yy114; - if (yych <= ']') goto yy142; - goto yy112; + if (yych <= '[') goto yy99; + if (yych <= '\\') goto yy101; + if (yych <= ']') goto yy129; + goto yy99; } } -yy141: - YYDEBUG(141, *YYCURSOR); +yy128: + YYDEBUG(128, *YYCURSOR); yych = *++YYCURSOR; - goto yy100; -yy142: - YYDEBUG(142, *YYCURSOR); + goto yy87; +yy129: + YYDEBUG(129, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy111; + goto yy98; } /* *********************************** */ yyc_ST_RAW: @@ -1748,7 +1728,7 @@ yyc_ST_RAW: 224, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, - 160, 160, 160, 32, 160, 32, 160, 160, + 160, 160, 160, 32, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, @@ -1774,34 +1754,31 @@ yyc_ST_RAW: 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, 160, }; - YYDEBUG(143, *YYCURSOR); + YYDEBUG(130, *YYCURSOR); YYFILL(3); yych = *YYCURSOR; - if (yych <= 0x1F) { - if (yych <= '\n') { - if (yych <= 0x08) goto yy145; - if (yych <= '\t') goto yy147; - goto yy148; + if (yych <= '\r') { + if (yych <= '\t') { + if (yych >= '\t') goto yy134; } else { - if (yych == '\r') goto yy150; + if (yych <= '\n') goto yy135; + if (yych >= '\r') goto yy137; } } else { - if (yych <= ';') { - if (yych <= ' ') goto yy147; - if (yych >= ';') goto yy151; + if (yych <= ' ') { + if (yych >= ' ') goto yy134; } else { - if (yych == '=') goto yy153; + if (yych == ';') goto yy138; } } -yy145: - YYDEBUG(145, *YYCURSOR); + YYDEBUG(132, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy164; -yy146: - YYDEBUG(146, *YYCURSOR); + goto yy150; +yy133: + YYDEBUG(133, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 402 "Zend/zend_ini_scanner.l" +#line 419 "Zend/zend_ini_scanner.l" { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */ /* Eat leading and trailing double quotes */ if (yytext[0] == '"' && yytext[yyleng - 1] == '"') { @@ -1810,129 +1787,120 @@ yy146: } RETURN_TOKEN(TC_RAW, yytext, yyleng); } -#line 1814 "Zend/zend_ini_scanner.c" -yy147: - YYDEBUG(147, *YYCURSOR); +#line 1791 "Zend/zend_ini_scanner.c" +yy134: + YYDEBUG(134, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yybm[0+yych] & 64) { - goto yy160; + goto yy146; } if (yych <= '\f') { - if (yych == '\n') goto yy159; - goto yy164; + if (yych == '\n') goto yy145; + goto yy149; } else { - if (yych <= '\r') goto yy162; - if (yych == ';') goto yy154; - goto yy164; + if (yych <= '\r') goto yy148; + if (yych == ';') goto yy140; + goto yy149; } -yy148: - YYDEBUG(148, *YYCURSOR); +yy135: + YYDEBUG(135, *YYCURSOR); ++YYCURSOR; -yy149: - YYDEBUG(149, *YYCURSOR); +yy136: + YYDEBUG(136, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 415 "Zend/zend_ini_scanner.l" +#line 432 "Zend/zend_ini_scanner.l" { /* End of option value */ BEGIN(INITIAL); SCNG(lineno)++; return END_OF_LINE; } -#line 1842 "Zend/zend_ini_scanner.c" -yy150: - YYDEBUG(150, *YYCURSOR); +#line 1819 "Zend/zend_ini_scanner.c" +yy137: + YYDEBUG(137, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy159; - goto yy149; -yy151: - YYDEBUG(151, *YYCURSOR); + if (yych == '\n') goto yy145; + goto yy136; +yy138: + YYDEBUG(138, *YYCURSOR); yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - goto yy155; -yy152: - YYDEBUG(152, *YYCURSOR); + goto yy141; + YYDEBUG(139, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 497 "Zend/zend_ini_scanner.l" +#line 541 "Zend/zend_ini_scanner.l" { /* End of option value (if EOF is reached before EOL */ BEGIN(INITIAL); return END_OF_LINE; } -#line 1861 "Zend/zend_ini_scanner.c" -yy153: - YYDEBUG(153, *YYCURSOR); - yych = *++YYCURSOR; - goto yy152; -yy154: - YYDEBUG(154, *YYCURSOR); +#line 1837 "Zend/zend_ini_scanner.c" +yy140: + YYDEBUG(140, *YYCURSOR); ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; -yy155: - YYDEBUG(155, *YYCURSOR); +yy141: + YYDEBUG(141, *YYCURSOR); if (yybm[0+yych] & 32) { - goto yy154; + goto yy140; } - if (yych >= '\r') goto yy158; -yy156: - YYDEBUG(156, *YYCURSOR); + if (yych >= '\r') goto yy144; +yy142: + YYDEBUG(142, *YYCURSOR); ++YYCURSOR; -yy157: - YYDEBUG(157, *YYCURSOR); +yy143: + YYDEBUG(143, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 484 "Zend/zend_ini_scanner.l" +#line 528 "Zend/zend_ini_scanner.l" { /* Comment */ BEGIN(INITIAL); SCNG(lineno)++; return END_OF_LINE; } -#line 1889 "Zend/zend_ini_scanner.c" -yy158: - YYDEBUG(158, *YYCURSOR); +#line 1861 "Zend/zend_ini_scanner.c" +yy144: + YYDEBUG(144, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy156; - goto yy157; -yy159: - YYDEBUG(159, *YYCURSOR); + if (yych == '\n') goto yy142; + goto yy143; +yy145: + YYDEBUG(145, *YYCURSOR); yych = *++YYCURSOR; - goto yy149; -yy160: - YYDEBUG(160, *YYCURSOR); + goto yy136; +yy146: + YYDEBUG(146, *YYCURSOR); yyaccept = 0; YYMARKER = ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; - YYDEBUG(161, *YYCURSOR); + YYDEBUG(147, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy160; + goto yy146; } - if (yych <= '\r') { - if (yych == '\n') goto yy159; - if (yych <= '\f') goto yy163; + if (yych <= '\f') { + if (yych == '\n') goto yy145; + goto yy149; } else { - if (yych <= ';') { - if (yych <= ':') goto yy163; - goto yy154; - } else { - if (yych == '=') goto yy146; - goto yy163; - } + if (yych <= '\r') goto yy148; + if (yych == ';') goto yy140; + goto yy149; } -yy162: - YYDEBUG(162, *YYCURSOR); +yy148: + YYDEBUG(148, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy159; - goto yy149; -yy163: - YYDEBUG(163, *YYCURSOR); + if (yych == '\n') goto yy145; + goto yy136; +yy149: + YYDEBUG(149, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy164: - YYDEBUG(164, *YYCURSOR); +yy150: + YYDEBUG(150, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy163; + goto yy149; } - goto yy146; + goto yy133; } /* *********************************** */ yyc_ST_SECTION_RAW: @@ -1971,85 +1939,85 @@ yyc_ST_SECTION_RAW: 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, }; - YYDEBUG(165, *YYCURSOR); + YYDEBUG(151, *YYCURSOR); YYFILL(3); yych = *YYCURSOR; if (yych <= '\f') { - if (yych == '\n') goto yy169; + if (yych == '\n') goto yy155; } else { - if (yych <= '\r') goto yy169; - if (yych == ']') goto yy171; + if (yych <= '\r') goto yy155; + if (yych == ']') goto yy157; } - YYDEBUG(167, *YYCURSOR); + YYDEBUG(153, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy178; -yy168: - YYDEBUG(168, *YYCURSOR); + goto yy164; +yy154: + YYDEBUG(154, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 411 "Zend/zend_ini_scanner.l" +#line 428 "Zend/zend_ini_scanner.l" { /* Raw value, only used when SCNG(scanner_mode) == ZEND_INI_SCANNER_RAW. */ RETURN_TOKEN(TC_RAW, yytext, yyleng); } -#line 1995 "Zend/zend_ini_scanner.c" -yy169: - YYDEBUG(169, *YYCURSOR); +#line 1963 "Zend/zend_ini_scanner.c" +yy155: + YYDEBUG(155, *YYCURSOR); ++YYCURSOR; - YYDEBUG(170, *YYCURSOR); + YYDEBUG(156, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 502 "Zend/zend_ini_scanner.l" +#line 546 "Zend/zend_ini_scanner.l" { return 0; } -#line 2005 "Zend/zend_ini_scanner.c" -yy171: - YYDEBUG(171, *YYCURSOR); +#line 1973 "Zend/zend_ini_scanner.c" +yy157: + YYDEBUG(157, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy174; -yy172: - YYDEBUG(172, *YYCURSOR); + goto yy160; +yy158: + YYDEBUG(158, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 346 "Zend/zend_ini_scanner.l" +#line 363 "Zend/zend_ini_scanner.l" { /* End of section */ BEGIN(INITIAL); SCNG(lineno)++; return ']'; } -#line 2020 "Zend/zend_ini_scanner.c" -yy173: - YYDEBUG(173, *YYCURSOR); +#line 1988 "Zend/zend_ini_scanner.c" +yy159: + YYDEBUG(159, *YYCURSOR); ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; -yy174: - YYDEBUG(174, *YYCURSOR); +yy160: + YYDEBUG(160, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy173; + goto yy159; } - if (yych == '\n') goto yy175; - if (yych == '\r') goto yy176; - goto yy172; -yy175: - YYDEBUG(175, *YYCURSOR); + if (yych == '\n') goto yy161; + if (yych == '\r') goto yy162; + goto yy158; +yy161: + YYDEBUG(161, *YYCURSOR); yych = *++YYCURSOR; - goto yy172; -yy176: - YYDEBUG(176, *YYCURSOR); + goto yy158; +yy162: + YYDEBUG(162, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy175; - goto yy172; -yy177: - YYDEBUG(177, *YYCURSOR); + if (yych == '\n') goto yy161; + goto yy158; +yy163: + YYDEBUG(163, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy178: - YYDEBUG(178, *YYCURSOR); +yy164: + YYDEBUG(164, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy177; + goto yy163; } - goto yy168; + goto yy154; } /* *********************************** */ yyc_ST_SECTION_VALUE: @@ -2088,522 +2056,522 @@ yyc_ST_SECTION_VALUE: 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, 132, }; - YYDEBUG(179, *YYCURSOR); + YYDEBUG(165, *YYCURSOR); YYFILL(3); yych = *YYCURSOR; if (yych <= ',') { if (yych <= ' ') { if (yych <= '\n') { - if (yych <= 0x08) goto yy181; - if (yych <= '\t') goto yy183; - goto yy184; + if (yych <= 0x08) goto yy167; + if (yych <= '\t') goto yy169; + goto yy170; } else { - if (yych == '\r') goto yy184; - if (yych >= ' ') goto yy183; + if (yych == '\r') goto yy170; + if (yych >= ' ') goto yy169; } } else { if (yych <= '#') { - if (yych == '"') goto yy186; + if (yych == '"') goto yy172; } else { - if (yych <= '$') goto yy188; - if (yych == '\'') goto yy189; + if (yych <= '$') goto yy174; + if (yych == '\'') goto yy175; } } } else { if (yych <= '@') { if (yych <= '/') { - if (yych <= '-') goto yy190; - if (yych <= '.') goto yy191; + if (yych <= '-') goto yy176; + if (yych <= '.') goto yy177; } else { - if (yych <= '9') goto yy192; - if (yych == ';') goto yy184; + if (yych <= '9') goto yy178; + if (yych == ';') goto yy170; } } else { if (yych <= '\\') { - if (yych <= 'Z') goto yy194; - if (yych >= '\\') goto yy196; + if (yych <= 'Z') goto yy180; + if (yych >= '\\') goto yy182; } else { - if (yych <= ']') goto yy197; - if (yych <= '`') goto yy181; - if (yych <= 'z') goto yy194; + if (yych <= ']') goto yy183; + if (yych <= '`') goto yy167; + if (yych <= 'z') goto yy180; } } } -yy181: - YYDEBUG(181, *YYCURSOR); +yy167: + YYDEBUG(167, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - goto yy204; -yy182: - YYDEBUG(182, *YYCURSOR); + goto yy190; +yy168: + YYDEBUG(168, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 447 "Zend/zend_ini_scanner.l" +#line 464 "Zend/zend_ini_scanner.l" { /* Get rest as section/offset value */ RETURN_TOKEN(TC_STRING, yytext, yyleng); } -#line 2145 "Zend/zend_ini_scanner.c" -yy183: - YYDEBUG(183, *YYCURSOR); +#line 2113 "Zend/zend_ini_scanner.c" +yy169: + YYDEBUG(169, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 0x1F) { - if (yych == '\t') goto yy230; - goto yy204; + if (yych == '\t') goto yy216; + goto yy190; } else { - if (yych <= ' ') goto yy230; - if (yych == '"') goto yy232; - goto yy204; + if (yych <= ' ') goto yy216; + if (yych == '"') goto yy218; + goto yy190; } -yy184: - YYDEBUG(184, *YYCURSOR); +yy170: + YYDEBUG(170, *YYCURSOR); ++YYCURSOR; -yy185: - YYDEBUG(185, *YYCURSOR); +yy171: + YYDEBUG(171, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 502 "Zend/zend_ini_scanner.l" +#line 546 "Zend/zend_ini_scanner.l" { return 0; } -#line 2168 "Zend/zend_ini_scanner.c" -yy186: - YYDEBUG(186, *YYCURSOR); +#line 2136 "Zend/zend_ini_scanner.c" +yy172: + YYDEBUG(172, *YYCURSOR); ++YYCURSOR; -yy187: - YYDEBUG(187, *YYCURSOR); +yy173: + YYDEBUG(173, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 451 "Zend/zend_ini_scanner.l" +#line 468 "Zend/zend_ini_scanner.l" { /* Double quoted '"' string start */ yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); return '"'; } -#line 2180 "Zend/zend_ini_scanner.c" -yy188: - YYDEBUG(188, *YYCURSOR); +#line 2148 "Zend/zend_ini_scanner.c" +yy174: + YYDEBUG(174, *YYCURSOR); yych = *++YYCURSOR; if (yych <= '\\') { - if (yych <= 0x00) goto yy185; - if (yych <= '[') goto yy203; - goto yy208; + if (yych <= 0x00) goto yy171; + if (yych <= '[') goto yy189; + goto yy194; } else { - if (yych == '{') goto yy228; - goto yy203; + if (yych == '{') goto yy214; + goto yy189; } -yy189: - YYDEBUG(189, *YYCURSOR); +yy175: + YYDEBUG(175, *YYCURSOR); yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); if (yybm[0+yych] & 128) { - goto yy224; + goto yy210; } - goto yy185; -yy190: - YYDEBUG(190, *YYCURSOR); + goto yy171; +yy176: + YYDEBUG(176, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy204; - if (yych <= '9') goto yy222; - goto yy204; -yy191: - YYDEBUG(191, *YYCURSOR); + if (yych <= '/') goto yy190; + if (yych <= '9') goto yy208; + goto yy190; +yy177: + YYDEBUG(177, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy204; - if (yych <= '9') goto yy220; - goto yy204; -yy192: - YYDEBUG(192, *YYCURSOR); + if (yych <= '/') goto yy190; + if (yych <= '9') goto yy206; + goto yy190; +yy178: + YYDEBUG(178, *YYCURSOR); yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '\'') { if (yych <= '\r') { - if (yych == '\n') goto yy193; - if (yych <= '\f') goto yy204; + if (yych == '\n') goto yy179; + if (yych <= '\f') goto yy190; } else { - if (yych == '"') goto yy193; - if (yych <= '&') goto yy204; + if (yych == '"') goto yy179; + if (yych <= '&') goto yy190; } } else { if (yych <= '9') { - if (yych == '.') goto yy216; - if (yych <= '/') goto yy204; - goto yy218; + if (yych == '.') goto yy202; + if (yych <= '/') goto yy190; + goto yy204; } else { if (yych <= ';') { - if (yych <= ':') goto yy204; + if (yych <= ':') goto yy190; } else { - if (yych != ']') goto yy204; + if (yych != ']') goto yy190; } } } -yy193: - YYDEBUG(193, *YYCURSOR); +yy179: + YYDEBUG(179, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 425 "Zend/zend_ini_scanner.l" +#line 442 "Zend/zend_ini_scanner.l" { /* Get number option value as string */ RETURN_TOKEN(TC_NUMBER, yytext, yyleng); } -#line 2246 "Zend/zend_ini_scanner.c" -yy194: - YYDEBUG(194, *YYCURSOR); +#line 2214 "Zend/zend_ini_scanner.c" +yy180: + YYDEBUG(180, *YYCURSOR); yyaccept = 3; yych = *(YYMARKER = ++YYCURSOR); if (yybm[0+yych] & 32) { - goto yy214; + goto yy200; } if (yych <= '"') { if (yych <= '\f') { - if (yych != '\n') goto yy204; + if (yych != '\n') goto yy190; } else { - if (yych <= '\r') goto yy195; - if (yych <= '!') goto yy204; + if (yych <= '\r') goto yy181; + if (yych <= '!') goto yy190; } } else { if (yych <= ':') { - if (yych != '\'') goto yy204; + if (yych != '\'') goto yy190; } else { - if (yych <= ';') goto yy195; - if (yych != ']') goto yy204; + if (yych <= ';') goto yy181; + if (yych != ']') goto yy190; } } -yy195: - YYDEBUG(195, *YYCURSOR); +yy181: + YYDEBUG(181, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 421 "Zend/zend_ini_scanner.l" +#line 438 "Zend/zend_ini_scanner.l" { /* Get constant option value */ RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); } -#line 2276 "Zend/zend_ini_scanner.c" -yy196: - YYDEBUG(196, *YYCURSOR); +#line 2244 "Zend/zend_ini_scanner.c" +yy182: + YYDEBUG(182, *YYCURSOR); yych = *++YYCURSOR; - goto yy203; -yy197: - YYDEBUG(197, *YYCURSOR); + goto yy189; +yy183: + YYDEBUG(183, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy200; -yy198: - YYDEBUG(198, *YYCURSOR); + goto yy186; +yy184: + YYDEBUG(184, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 346 "Zend/zend_ini_scanner.l" +#line 363 "Zend/zend_ini_scanner.l" { /* End of section */ BEGIN(INITIAL); SCNG(lineno)++; return ']'; } -#line 2295 "Zend/zend_ini_scanner.c" -yy199: - YYDEBUG(199, *YYCURSOR); +#line 2263 "Zend/zend_ini_scanner.c" +yy185: + YYDEBUG(185, *YYCURSOR); ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; -yy200: - YYDEBUG(200, *YYCURSOR); +yy186: + YYDEBUG(186, *YYCURSOR); if (yybm[0+yych] & 2) { - goto yy199; + goto yy185; } - if (yych == '\n') goto yy201; - if (yych == '\r') goto yy202; - goto yy198; -yy201: - YYDEBUG(201, *YYCURSOR); + if (yych == '\n') goto yy187; + if (yych == '\r') goto yy188; + goto yy184; +yy187: + YYDEBUG(187, *YYCURSOR); yych = *++YYCURSOR; - goto yy198; -yy202: - YYDEBUG(202, *YYCURSOR); + goto yy184; +yy188: + YYDEBUG(188, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy201; - goto yy198; -yy203: - YYDEBUG(203, *YYCURSOR); + if (yych == '\n') goto yy187; + goto yy184; +yy189: + YYDEBUG(189, *YYCURSOR); yyaccept = 0; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy204: - YYDEBUG(204, *YYCURSOR); +yy190: + YYDEBUG(190, *YYCURSOR); if (yybm[0+yych] & 4) { - goto yy203; + goto yy189; } - if (yych == '$') goto yy206; - if (yych != '\\') goto yy182; -yy205: - YYDEBUG(205, *YYCURSOR); + if (yych == '$') goto yy192; + if (yych != '\\') goto yy168; +yy191: + YYDEBUG(191, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - goto yy203; -yy206: - YYDEBUG(206, *YYCURSOR); + goto yy189; +yy192: + YYDEBUG(192, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; if (yych <= '\\') { - if (yych <= 0x00) goto yy207; - if (yych <= '[') goto yy203; - goto yy208; + if (yych <= 0x00) goto yy193; + if (yych <= '[') goto yy189; + goto yy194; } else { - if (yych != '{') goto yy203; + if (yych != '{') goto yy189; } -yy207: - YYDEBUG(207, *YYCURSOR); +yy193: + YYDEBUG(193, *YYCURSOR); YYCURSOR = YYMARKER; if (yyaccept <= 1) { if (yyaccept <= 0) { - goto yy182; + goto yy168; } else { - goto yy185; + goto yy171; } } else { if (yyaccept <= 2) { - goto yy193; + goto yy179; } else { - goto yy195; + goto yy181; } } -yy208: - YYDEBUG(208, *YYCURSOR); +yy194: + YYDEBUG(194, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; if (yybm[0+yych] & 8) { - goto yy209; + goto yy195; } - if (yych == '\\') goto yy211; - goto yy203; -yy209: - YYDEBUG(209, *YYCURSOR); + if (yych == '\\') goto yy197; + goto yy189; +yy195: + YYDEBUG(195, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(210, *YYCURSOR); + YYDEBUG(196, *YYCURSOR); if (yybm[0+yych] & 8) { - goto yy209; + goto yy195; } - if (yych == '\\') goto yy213; - goto yy203; -yy211: - YYDEBUG(211, *YYCURSOR); + if (yych == '\\') goto yy199; + goto yy189; +yy197: + YYDEBUG(197, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(212, *YYCURSOR); + YYDEBUG(198, *YYCURSOR); if (yybm[0+yych] & 8) { - goto yy209; + goto yy195; } - if (yych == '\\') goto yy211; - goto yy203; -yy213: - YYDEBUG(213, *YYCURSOR); + if (yych == '\\') goto yy197; + goto yy189; +yy199: + YYDEBUG(199, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; if (yybm[0+yych] & 8) { - goto yy209; + goto yy195; } - if (yych == '\\') goto yy211; - goto yy203; -yy214: - YYDEBUG(214, *YYCURSOR); + if (yych == '\\') goto yy197; + goto yy189; +yy200: + YYDEBUG(200, *YYCURSOR); yyaccept = 3; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(215, *YYCURSOR); + YYDEBUG(201, *YYCURSOR); if (yybm[0+yych] & 32) { - goto yy214; + goto yy200; } if (yych <= '$') { if (yych <= '\r') { - if (yych == '\n') goto yy195; - if (yych <= '\f') goto yy203; - goto yy195; + if (yych == '\n') goto yy181; + if (yych <= '\f') goto yy189; + goto yy181; } else { - if (yych == '"') goto yy195; - if (yych <= '#') goto yy203; - goto yy206; + if (yych == '"') goto yy181; + if (yych <= '#') goto yy189; + goto yy192; } } else { if (yych <= ';') { - if (yych == '\'') goto yy195; - if (yych <= ':') goto yy203; - goto yy195; + if (yych == '\'') goto yy181; + if (yych <= ':') goto yy189; + goto yy181; } else { - if (yych <= '[') goto yy203; - if (yych <= '\\') goto yy205; - if (yych <= ']') goto yy195; - goto yy203; + if (yych <= '[') goto yy189; + if (yych <= '\\') goto yy191; + if (yych <= ']') goto yy181; + goto yy189; } } -yy216: - YYDEBUG(216, *YYCURSOR); +yy202: + YYDEBUG(202, *YYCURSOR); yyaccept = 2; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(217, *YYCURSOR); + YYDEBUG(203, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy216; + goto yy202; } if (yych <= '$') { if (yych <= '\r') { - if (yych == '\n') goto yy193; - if (yych <= '\f') goto yy203; - goto yy193; + if (yych == '\n') goto yy179; + if (yych <= '\f') goto yy189; + goto yy179; } else { - if (yych == '"') goto yy193; - if (yych <= '#') goto yy203; - goto yy206; + if (yych == '"') goto yy179; + if (yych <= '#') goto yy189; + goto yy192; } } else { if (yych <= ';') { - if (yych == '\'') goto yy193; - if (yych <= ':') goto yy203; - goto yy193; + if (yych == '\'') goto yy179; + if (yych <= ':') goto yy189; + goto yy179; } else { - if (yych <= '[') goto yy203; - if (yych <= '\\') goto yy205; - if (yych <= ']') goto yy193; - goto yy203; + if (yych <= '[') goto yy189; + if (yych <= '\\') goto yy191; + if (yych <= ']') goto yy179; + goto yy189; } } -yy218: - YYDEBUG(218, *YYCURSOR); +yy204: + YYDEBUG(204, *YYCURSOR); yyaccept = 2; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(219, *YYCURSOR); + YYDEBUG(205, *YYCURSOR); if (yych <= '\'') { if (yych <= '!') { if (yych <= '\n') { - if (yych <= '\t') goto yy203; - goto yy193; + if (yych <= '\t') goto yy189; + goto yy179; } else { - if (yych == '\r') goto yy193; - goto yy203; + if (yych == '\r') goto yy179; + goto yy189; } } else { if (yych <= '#') { - if (yych <= '"') goto yy193; - goto yy203; + if (yych <= '"') goto yy179; + goto yy189; } else { - if (yych <= '$') goto yy206; - if (yych <= '&') goto yy203; - goto yy193; + if (yych <= '$') goto yy192; + if (yych <= '&') goto yy189; + goto yy179; } } } else { if (yych <= ':') { if (yych <= '.') { - if (yych <= '-') goto yy203; - goto yy216; + if (yych <= '-') goto yy189; + goto yy202; } else { - if (yych <= '/') goto yy203; - if (yych <= '9') goto yy218; - goto yy203; + if (yych <= '/') goto yy189; + if (yych <= '9') goto yy204; + goto yy189; } } else { if (yych <= '[') { - if (yych <= ';') goto yy193; - goto yy203; + if (yych <= ';') goto yy179; + goto yy189; } else { - if (yych <= '\\') goto yy205; - if (yych <= ']') goto yy193; - goto yy203; + if (yych <= '\\') goto yy191; + if (yych <= ']') goto yy179; + goto yy189; } } } -yy220: - YYDEBUG(220, *YYCURSOR); +yy206: + YYDEBUG(206, *YYCURSOR); yyaccept = 2; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(221, *YYCURSOR); + YYDEBUG(207, *YYCURSOR); if (yych <= '&') { if (yych <= '\r') { - if (yych == '\n') goto yy193; - if (yych <= '\f') goto yy203; - goto yy193; + if (yych == '\n') goto yy179; + if (yych <= '\f') goto yy189; + goto yy179; } else { if (yych <= '"') { - if (yych <= '!') goto yy203; - goto yy193; + if (yych <= '!') goto yy189; + goto yy179; } else { - if (yych == '$') goto yy206; - goto yy203; + if (yych == '$') goto yy192; + goto yy189; } } } else { if (yych <= ':') { - if (yych <= '\'') goto yy193; - if (yych <= '/') goto yy203; - if (yych <= '9') goto yy220; - goto yy203; + if (yych <= '\'') goto yy179; + if (yych <= '/') goto yy189; + if (yych <= '9') goto yy206; + goto yy189; } else { if (yych <= '[') { - if (yych <= ';') goto yy193; - goto yy203; + if (yych <= ';') goto yy179; + goto yy189; } else { - if (yych <= '\\') goto yy205; - if (yych <= ']') goto yy193; - goto yy203; + if (yych <= '\\') goto yy191; + if (yych <= ']') goto yy179; + goto yy189; } } } -yy222: - YYDEBUG(222, *YYCURSOR); +yy208: + YYDEBUG(208, *YYCURSOR); yyaccept = 2; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(223, *YYCURSOR); + YYDEBUG(209, *YYCURSOR); if (yych <= '&') { if (yych <= '\r') { - if (yych == '\n') goto yy193; - if (yych <= '\f') goto yy203; - goto yy193; + if (yych == '\n') goto yy179; + if (yych <= '\f') goto yy189; + goto yy179; } else { if (yych <= '"') { - if (yych <= '!') goto yy203; - goto yy193; + if (yych <= '!') goto yy189; + goto yy179; } else { - if (yych == '$') goto yy206; - goto yy203; + if (yych == '$') goto yy192; + goto yy189; } } } else { if (yych <= ':') { - if (yych <= '\'') goto yy193; - if (yych <= '/') goto yy203; - if (yych <= '9') goto yy222; - goto yy203; + if (yych <= '\'') goto yy179; + if (yych <= '/') goto yy189; + if (yych <= '9') goto yy208; + goto yy189; } else { if (yych <= '[') { - if (yych <= ';') goto yy193; - goto yy203; + if (yych <= ';') goto yy179; + goto yy189; } else { - if (yych <= '\\') goto yy205; - if (yych <= ']') goto yy193; - goto yy203; + if (yych <= '\\') goto yy191; + if (yych <= ']') goto yy179; + goto yy189; } } } -yy224: - YYDEBUG(224, *YYCURSOR); +yy210: + YYDEBUG(210, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(225, *YYCURSOR); + YYDEBUG(211, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy224; + goto yy210; } - YYDEBUG(226, *YYCURSOR); + YYDEBUG(212, *YYCURSOR); ++YYCURSOR; - YYDEBUG(227, *YYCURSOR); + YYDEBUG(213, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 337 "Zend/zend_ini_scanner.l" +#line 354 "Zend/zend_ini_scanner.l" { /* Raw string */ /* Eat leading and trailing single quotes */ if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { @@ -2612,65 +2580,65 @@ yy224: } RETURN_TOKEN(TC_RAW, yytext, yyleng); } -#line 2616 "Zend/zend_ini_scanner.c" -yy228: - YYDEBUG(228, *YYCURSOR); +#line 2584 "Zend/zend_ini_scanner.c" +yy214: + YYDEBUG(214, *YYCURSOR); ++YYCURSOR; - YYDEBUG(229, *YYCURSOR); + YYDEBUG(215, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 367 "Zend/zend_ini_scanner.l" +#line 384 "Zend/zend_ini_scanner.l" { /* Variable start */ yy_push_state(ST_VARNAME TSRMLS_CC); return TC_DOLLAR_CURLY; } -#line 2627 "Zend/zend_ini_scanner.c" -yy230: - YYDEBUG(230, *YYCURSOR); +#line 2595 "Zend/zend_ini_scanner.c" +yy216: + YYDEBUG(216, *YYCURSOR); yyaccept = 0; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(231, *YYCURSOR); + YYDEBUG(217, *YYCURSOR); if (yych <= '"') { if (yych <= '\f') { - if (yych <= 0x08) goto yy203; - if (yych <= '\t') goto yy230; - if (yych <= '\n') goto yy182; - goto yy203; + if (yych <= 0x08) goto yy189; + if (yych <= '\t') goto yy216; + if (yych <= '\n') goto yy168; + goto yy189; } else { if (yych <= 0x1F) { - if (yych <= '\r') goto yy182; - goto yy203; + if (yych <= '\r') goto yy168; + goto yy189; } else { - if (yych <= ' ') goto yy230; - if (yych <= '!') goto yy203; + if (yych <= ' ') goto yy216; + if (yych <= '!') goto yy189; } } } else { if (yych <= ':') { if (yych <= '$') { - if (yych <= '#') goto yy203; - goto yy206; + if (yych <= '#') goto yy189; + goto yy192; } else { - if (yych == '\'') goto yy182; - goto yy203; + if (yych == '\'') goto yy168; + goto yy189; } } else { if (yych <= '[') { - if (yych <= ';') goto yy182; - goto yy203; + if (yych <= ';') goto yy168; + goto yy189; } else { - if (yych <= '\\') goto yy205; - if (yych <= ']') goto yy182; - goto yy203; + if (yych <= '\\') goto yy191; + if (yych <= ']') goto yy168; + goto yy189; } } } -yy232: - YYDEBUG(232, *YYCURSOR); +yy218: + YYDEBUG(218, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy187; + goto yy173; } /* *********************************** */ yyc_ST_VALUE: @@ -2709,27 +2677,27 @@ yyc_ST_VALUE: 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, 162, }; - YYDEBUG(233, *YYCURSOR); + YYDEBUG(219, *YYCURSOR); YYFILL(6); yych = *YYCURSOR; YYDEBUG(-1, yych); switch (yych) { - case 0x00: goto yy235; + case 0x00: goto yy221; case '\t': - case ' ': goto yy239; - case '\n': goto yy241; - case '\r': goto yy243; + case ' ': goto yy225; + case '\n': goto yy227; + case '\r': goto yy229; case '!': case '&': case '(': case ')': case '|': - case '~': goto yy244; - case '"': goto yy246; - case '$': goto yy248; - case '\'': goto yy249; - case '-': goto yy250; - case '.': goto yy251; + case '~': goto yy230; + case '"': goto yy232; + case '$': goto yy234; + case '\'': goto yy235; + case '-': goto yy236; + case '.': goto yy237; case '0': case '1': case '2': @@ -2739,9 +2707,9 @@ yyc_ST_VALUE: case '6': case '7': case '8': - case '9': goto yy252; - case ';': goto yy254; - case '=': goto yy255; + case '9': goto yy238; + case ';': goto yy240; + case '=': goto yy241; case 'A': case 'B': case 'C': @@ -2783,1531 +2751,1531 @@ yyc_ST_VALUE: case 'v': case 'w': case 'x': - case 'z': goto yy257; + case 'z': goto yy243; case 'F': - case 'f': goto yy259; + case 'f': goto yy245; case 'N': - case 'n': goto yy260; + case 'n': goto yy246; case 'O': - case 'o': goto yy261; + case 'o': goto yy247; case 'T': - case 't': goto yy262; + case 't': goto yy248; case 'Y': - case 'y': goto yy263; - default: goto yy237; + case 'y': goto yy249; + default: goto yy223; } -yy235: - YYDEBUG(235, *YYCURSOR); +yy221: + YYDEBUG(221, *YYCURSOR); ++YYCURSOR; -yy236: - YYDEBUG(236, *YYCURSOR); +yy222: + YYDEBUG(222, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 497 "Zend/zend_ini_scanner.l" +#line 541 "Zend/zend_ini_scanner.l" { /* End of option value (if EOF is reached before EOL */ BEGIN(INITIAL); return END_OF_LINE; } -#line 2811 "Zend/zend_ini_scanner.c" -yy237: - YYDEBUG(237, *YYCURSOR); +#line 2779 "Zend/zend_ini_scanner.c" +yy223: + YYDEBUG(223, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - goto yy265; -yy238: - YYDEBUG(238, *YYCURSOR); + goto yy251; +yy224: + YYDEBUG(224, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 443 "Zend/zend_ini_scanner.l" +#line 460 "Zend/zend_ini_scanner.l" { /* Get everything else as option/offset value */ RETURN_TOKEN(TC_STRING, yytext, yyleng); } -#line 2824 "Zend/zend_ini_scanner.c" -yy239: - YYDEBUG(239, *YYCURSOR); +#line 2792 "Zend/zend_ini_scanner.c" +yy225: + YYDEBUG(225, *YYCURSOR); yyaccept = 1; yych = *(YYMARKER = ++YYCURSOR); - goto yy315; -yy240: - YYDEBUG(240, *YYCURSOR); + goto yy301; +yy226: + YYDEBUG(226, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 470 "Zend/zend_ini_scanner.l" +#line 514 "Zend/zend_ini_scanner.l" { RETURN_TOKEN(TC_WHITESPACE, yytext, yyleng); } -#line 2837 "Zend/zend_ini_scanner.c" -yy241: - YYDEBUG(241, *YYCURSOR); +#line 2805 "Zend/zend_ini_scanner.c" +yy227: + YYDEBUG(227, *YYCURSOR); ++YYCURSOR; -yy242: - YYDEBUG(242, *YYCURSOR); +yy228: + YYDEBUG(228, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 415 "Zend/zend_ini_scanner.l" +#line 432 "Zend/zend_ini_scanner.l" { /* End of option value */ BEGIN(INITIAL); SCNG(lineno)++; return END_OF_LINE; } -#line 2850 "Zend/zend_ini_scanner.c" -yy243: - YYDEBUG(243, *YYCURSOR); +#line 2818 "Zend/zend_ini_scanner.c" +yy229: + YYDEBUG(229, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy313; - goto yy242; -yy244: - YYDEBUG(244, *YYCURSOR); + if (yych == '\n') goto yy299; + goto yy228; +yy230: + YYDEBUG(230, *YYCURSOR); ++YYCURSOR; yych = *YYCURSOR; - goto yy312; -yy245: - YYDEBUG(245, *YYCURSOR); + goto yy298; +yy231: + YYDEBUG(231, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 433 "Zend/zend_ini_scanner.l" +#line 450 "Zend/zend_ini_scanner.l" { /* Boolean operators */ return yytext[0]; } -#line 2868 "Zend/zend_ini_scanner.c" -yy246: - YYDEBUG(246, *YYCURSOR); +#line 2836 "Zend/zend_ini_scanner.c" +yy232: + YYDEBUG(232, *YYCURSOR); ++YYCURSOR; -yy247: - YYDEBUG(247, *YYCURSOR); +yy233: + YYDEBUG(233, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 451 "Zend/zend_ini_scanner.l" +#line 468 "Zend/zend_ini_scanner.l" { /* Double quoted '"' string start */ yy_push_state(ST_DOUBLE_QUOTES TSRMLS_CC); return '"'; } -#line 2880 "Zend/zend_ini_scanner.c" -yy248: - YYDEBUG(248, *YYCURSOR); +#line 2848 "Zend/zend_ini_scanner.c" +yy234: + YYDEBUG(234, *YYCURSOR); yych = *++YYCURSOR; if (yych <= '\\') { - if (yych <= 0x00) goto yy236; - if (yych <= '[') goto yy264; - goto yy271; + if (yych <= 0x00) goto yy222; + if (yych <= '[') goto yy250; + goto yy257; } else { - if (yych == '{') goto yy309; - goto yy264; + if (yych == '{') goto yy295; + goto yy250; } -yy249: - YYDEBUG(249, *YYCURSOR); +yy235: + YYDEBUG(235, *YYCURSOR); yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); if (yybm[0+yych] & 128) { - goto yy305; + goto yy291; } - goto yy236; -yy250: - YYDEBUG(250, *YYCURSOR); + goto yy222; +yy236: + YYDEBUG(236, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy265; - if (yych <= '9') goto yy303; - goto yy265; -yy251: - YYDEBUG(251, *YYCURSOR); + if (yych <= '/') goto yy251; + if (yych <= '9') goto yy289; + goto yy251; +yy237: + YYDEBUG(237, *YYCURSOR); yyaccept = 0; yych = *(YYMARKER = ++YYCURSOR); - if (yych <= '/') goto yy265; - if (yych <= '9') goto yy301; - goto yy265; -yy252: - YYDEBUG(252, *YYCURSOR); + if (yych <= '/') goto yy251; + if (yych <= '9') goto yy287; + goto yy251; +yy238: + YYDEBUG(238, *YYCURSOR); yyaccept = 3; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '.') { if (yych <= '\r') { if (yych <= 0x08) { - if (yych >= 0x01) goto yy265; + if (yych >= 0x01) goto yy251; } else { - if (yych <= '\n') goto yy253; - if (yych <= '\f') goto yy265; + if (yych <= '\n') goto yy239; + if (yych <= '\f') goto yy251; } } else { if (yych <= '%') { - if (yych <= 0x1F) goto yy265; - if (yych >= '#') goto yy265; + if (yych <= 0x1F) goto yy251; + if (yych >= '#') goto yy251; } else { - if (yych <= ')') goto yy253; - if (yych <= '-') goto yy265; - goto yy297; + if (yych <= ')') goto yy239; + if (yych <= '-') goto yy251; + goto yy283; } } } else { if (yych <= '<') { if (yych <= '9') { - if (yych <= '/') goto yy265; - goto yy299; + if (yych <= '/') goto yy251; + goto yy285; } else { - if (yych != ';') goto yy265; + if (yych != ';') goto yy251; } } else { if (yych <= '|') { - if (yych <= '=') goto yy253; - if (yych <= '{') goto yy265; + if (yych <= '=') goto yy239; + if (yych <= '{') goto yy251; } else { - if (yych != '~') goto yy265; + if (yych != '~') goto yy251; } } } -yy253: - YYDEBUG(253, *YYCURSOR); +yy239: + YYDEBUG(239, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 425 "Zend/zend_ini_scanner.l" +#line 442 "Zend/zend_ini_scanner.l" { /* Get number option value as string */ RETURN_TOKEN(TC_NUMBER, yytext, yyleng); } -#line 2960 "Zend/zend_ini_scanner.c" -yy254: - YYDEBUG(254, *YYCURSOR); +#line 2928 "Zend/zend_ini_scanner.c" +yy240: + YYDEBUG(240, *YYCURSOR); yyaccept = 2; yych = *(YYMARKER = ++YYCURSOR); - goto yy293; -yy255: - YYDEBUG(255, *YYCURSOR); + goto yy279; +yy241: + YYDEBUG(241, *YYCURSOR); ++YYCURSOR; - YYDEBUG(256, *YYCURSOR); + YYDEBUG(242, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 437 "Zend/zend_ini_scanner.l" +#line 454 "Zend/zend_ini_scanner.l" { /* Make = used in option value to trigger error */ yyless(0); BEGIN(INITIAL); return END_OF_LINE; } -#line 2977 "Zend/zend_ini_scanner.c" -yy257: - YYDEBUG(257, *YYCURSOR); +#line 2945 "Zend/zend_ini_scanner.c" +yy243: + YYDEBUG(243, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yybm[0+yych] & 4) { - goto yy266; + goto yy252; } if (yych <= ')') { if (yych <= '\f') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - if (yych >= '\v') goto yy265; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + if (yych >= '\v') goto yy251; } else { if (yych <= 0x1F) { - if (yych >= 0x0E) goto yy265; + if (yych >= 0x0E) goto yy251; } else { - if (yych <= '"') goto yy258; - if (yych <= '%') goto yy265; + if (yych <= '"') goto yy244; + if (yych <= '%') goto yy251; } } } else { if (yych <= '=') { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; } else { if (yych <= '|') { - if (yych <= '{') goto yy265; + if (yych <= '{') goto yy251; } else { - if (yych != '~') goto yy265; + if (yych != '~') goto yy251; } } } -yy258: - YYDEBUG(258, *YYCURSOR); +yy244: + YYDEBUG(244, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 421 "Zend/zend_ini_scanner.l" +#line 438 "Zend/zend_ini_scanner.l" { /* Get constant option value */ RETURN_TOKEN(TC_CONSTANT, yytext, yyleng); } -#line 3017 "Zend/zend_ini_scanner.c" -yy259: - YYDEBUG(259, *YYCURSOR); +#line 2985 "Zend/zend_ini_scanner.c" +yy245: + YYDEBUG(245, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '<') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '/') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - goto yy265; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + goto yy251; } else { - if (yych <= '9') goto yy266; - if (yych == ';') goto yy258; - goto yy265; + if (yych <= '9') goto yy252; + if (yych == ';') goto yy244; + goto yy251; } } } else { if (yych <= '`') { if (yych <= 'A') { - if (yych <= '=') goto yy258; - if (yych <= '@') goto yy265; - goto yy289; + if (yych <= '=') goto yy244; + if (yych <= '@') goto yy251; + goto yy275; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych <= 'a') goto yy289; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych <= 'a') goto yy275; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy260: - YYDEBUG(260, *YYCURSOR); +yy246: + YYDEBUG(246, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'N') { if (yych <= '%') { if (yych <= '\f') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - if (yych <= '\n') goto yy258; - goto yy265; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + if (yych <= '\n') goto yy244; + goto yy251; } else { - if (yych <= '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - if (yych <= '"') goto yy258; - goto yy265; + if (yych <= '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + if (yych <= '"') goto yy244; + goto yy251; } } else { if (yych <= ':') { - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - if (yych <= '9') goto yy266; - goto yy265; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + if (yych <= '9') goto yy252; + goto yy251; } else { if (yych <= '<') { - if (yych <= ';') goto yy258; - goto yy265; + if (yych <= ';') goto yy244; + goto yy251; } else { - if (yych <= '=') goto yy258; - if (yych <= '@') goto yy265; - goto yy266; + if (yych <= '=') goto yy244; + if (yych <= '@') goto yy251; + goto yy252; } } } } else { if (yych <= 'n') { if (yych <= 'Z') { - if (yych <= 'O') goto yy285; - if (yych == 'U') goto yy286; - goto yy266; + if (yych <= 'O') goto yy271; + if (yych == 'U') goto yy272; + goto yy252; } else { - if (yych == '_') goto yy266; - if (yych <= '`') goto yy265; - goto yy266; + if (yych == '_') goto yy252; + if (yych <= '`') goto yy251; + goto yy252; } } else { if (yych <= 'z') { - if (yych <= 'o') goto yy285; - if (yych == 'u') goto yy286; - goto yy266; + if (yych <= 'o') goto yy271; + if (yych == 'u') goto yy272; + goto yy252; } else { if (yych <= '|') { - if (yych <= '{') goto yy265; - goto yy258; + if (yych <= '{') goto yy251; + goto yy244; } else { - if (yych == '~') goto yy258; - goto yy265; + if (yych == '~') goto yy244; + goto yy251; } } } } -yy261: - YYDEBUG(261, *YYCURSOR); +yy247: + YYDEBUG(247, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= 'E') { if (yych <= '%') { if (yych <= '\f') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - if (yych <= '\n') goto yy258; - goto yy265; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + if (yych <= '\n') goto yy244; + goto yy251; } else { - if (yych <= '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - if (yych <= '"') goto yy258; - goto yy265; + if (yych <= '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + if (yych <= '"') goto yy244; + goto yy251; } } else { if (yych <= ':') { - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - if (yych <= '9') goto yy266; - goto yy265; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + if (yych <= '9') goto yy252; + goto yy251; } else { if (yych <= '<') { - if (yych <= ';') goto yy258; - goto yy265; + if (yych <= ';') goto yy244; + goto yy251; } else { - if (yych <= '=') goto yy258; - if (yych <= '@') goto yy265; - goto yy266; + if (yych <= '=') goto yy244; + if (yych <= '@') goto yy251; + goto yy252; } } } } else { if (yych <= 'e') { if (yych <= 'Z') { - if (yych <= 'F') goto yy280; - if (yych == 'N') goto yy274; - goto yy266; + if (yych <= 'F') goto yy266; + if (yych == 'N') goto yy260; + goto yy252; } else { - if (yych == '_') goto yy266; - if (yych <= '`') goto yy265; - goto yy266; + if (yych == '_') goto yy252; + if (yych <= '`') goto yy251; + goto yy252; } } else { if (yych <= 'z') { - if (yych <= 'f') goto yy280; - if (yych == 'n') goto yy274; - goto yy266; + if (yych <= 'f') goto yy266; + if (yych == 'n') goto yy260; + goto yy252; } else { if (yych <= '|') { - if (yych <= '{') goto yy265; - goto yy258; + if (yych <= '{') goto yy251; + goto yy244; } else { - if (yych == '~') goto yy258; - goto yy265; + if (yych == '~') goto yy244; + goto yy251; } } } } -yy262: - YYDEBUG(262, *YYCURSOR); +yy248: + YYDEBUG(248, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '=') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '9') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - goto yy266; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + goto yy252; } else { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; - goto yy258; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; + goto yy244; } } } else { if (yych <= '`') { if (yych <= 'R') { - if (yych <= '@') goto yy265; - if (yych <= 'Q') goto yy266; - goto yy278; + if (yych <= '@') goto yy251; + if (yych <= 'Q') goto yy252; + goto yy264; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 'r') goto yy278; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 'r') goto yy264; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy263: - YYDEBUG(263, *YYCURSOR); +yy249: + YYDEBUG(249, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '=') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '9') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - goto yy266; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + goto yy252; } else { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; - goto yy258; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; + goto yy244; } } } else { if (yych <= '`') { if (yych <= 'E') { - if (yych <= '@') goto yy265; - if (yych <= 'D') goto yy266; - goto yy268; + if (yych <= '@') goto yy251; + if (yych <= 'D') goto yy252; + goto yy254; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 'e') goto yy268; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 'e') goto yy254; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy264: - YYDEBUG(264, *YYCURSOR); +yy250: + YYDEBUG(250, *YYCURSOR); yyaccept = 0; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy265: - YYDEBUG(265, *YYCURSOR); +yy251: + YYDEBUG(251, *YYCURSOR); if (yybm[0+yych] & 2) { - goto yy264; + goto yy250; } - if (yych == '$') goto yy269; - goto yy238; -yy266: - YYDEBUG(266, *YYCURSOR); + if (yych == '$') goto yy255; + goto yy224; +yy252: + YYDEBUG(252, *YYCURSOR); yyaccept = 4; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(267, *YYCURSOR); + YYDEBUG(253, *YYCURSOR); if (yybm[0+yych] & 4) { - goto yy266; + goto yy252; } if (yych <= '%') { if (yych <= '\r') { if (yych <= 0x08) { - if (yych <= 0x00) goto yy258; - goto yy264; + if (yych <= 0x00) goto yy244; + goto yy250; } else { - if (yych <= '\n') goto yy258; - if (yych <= '\f') goto yy264; - goto yy258; + if (yych <= '\n') goto yy244; + if (yych <= '\f') goto yy250; + goto yy244; } } else { if (yych <= '"') { - if (yych <= 0x1F) goto yy264; - goto yy258; + if (yych <= 0x1F) goto yy250; + goto yy244; } else { - if (yych == '$') goto yy269; - goto yy264; + if (yych == '$') goto yy255; + goto yy250; } } } else { if (yych <= '=') { if (yych <= ':') { - if (yych <= ')') goto yy258; - goto yy264; + if (yych <= ')') goto yy244; + goto yy250; } else { - if (yych == '<') goto yy264; - goto yy258; + if (yych == '<') goto yy250; + goto yy244; } } else { if (yych <= '|') { - if (yych <= '{') goto yy264; - goto yy258; + if (yych <= '{') goto yy250; + goto yy244; } else { - if (yych == '~') goto yy258; - goto yy264; + if (yych == '~') goto yy244; + goto yy250; } } } -yy268: - YYDEBUG(268, *YYCURSOR); +yy254: + YYDEBUG(254, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '=') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '9') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - goto yy266; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + goto yy252; } else { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; - goto yy258; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; + goto yy244; } } } else { if (yych <= '`') { if (yych <= 'S') { - if (yych <= '@') goto yy265; - if (yych <= 'R') goto yy266; - goto yy274; + if (yych <= '@') goto yy251; + if (yych <= 'R') goto yy252; + goto yy260; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 's') goto yy274; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 's') goto yy260; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy269: - YYDEBUG(269, *YYCURSOR); +yy255: + YYDEBUG(255, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; if (yych <= '\\') { - if (yych <= 0x00) goto yy270; - if (yych <= '[') goto yy264; - goto yy271; + if (yych <= 0x00) goto yy256; + if (yych <= '[') goto yy250; + goto yy257; } else { - if (yych != '{') goto yy264; + if (yych != '{') goto yy250; } -yy270: - YYDEBUG(270, *YYCURSOR); +yy256: + YYDEBUG(256, *YYCURSOR); YYCURSOR = YYMARKER; if (yyaccept <= 3) { if (yyaccept <= 1) { if (yyaccept <= 0) { - goto yy238; + goto yy224; } else { - goto yy240; + goto yy226; } } else { if (yyaccept <= 2) { - goto yy236; + goto yy222; } else { - goto yy253; + goto yy239; } } } else { if (yyaccept <= 5) { if (yyaccept <= 4) { - goto yy258; + goto yy244; } else { - goto yy275; + goto yy261; } } else { - goto yy282; + goto yy268; } } -yy271: - YYDEBUG(271, *YYCURSOR); +yy257: + YYDEBUG(257, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; if (yybm[0+yych] & 8) { - goto yy272; + goto yy258; } - goto yy264; -yy272: - YYDEBUG(272, *YYCURSOR); + goto yy250; +yy258: + YYDEBUG(258, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(273, *YYCURSOR); + YYDEBUG(259, *YYCURSOR); if (yybm[0+yych] & 8) { - goto yy272; + goto yy258; } - if (yych <= 0x00) goto yy238; - if (yych == '\\') goto yy271; - goto yy264; -yy274: - YYDEBUG(274, *YYCURSOR); + if (yych <= 0x00) goto yy224; + if (yych == '\\') goto yy257; + goto yy250; +yy260: + YYDEBUG(260, *YYCURSOR); yyaccept = 5; yych = *(YYMARKER = ++YYCURSOR); if (yybm[0+yych] & 16) { - goto yy276; + goto yy262; } if (yych <= ';') { if (yych <= ' ') { if (yych <= '\n') { - if (yych <= 0x00) goto yy275; - if (yych <= '\t') goto yy265; + if (yych <= 0x00) goto yy261; + if (yych <= '\t') goto yy251; } else { - if (yych != '\r') goto yy265; + if (yych != '\r') goto yy251; } } else { if (yych <= ')') { - if (yych <= '"') goto yy275; - if (yych <= '%') goto yy265; + if (yych <= '"') goto yy261; + if (yych <= '%') goto yy251; } else { - if (yych <= '/') goto yy265; - if (yych <= '9') goto yy266; - if (yych <= ':') goto yy265; + if (yych <= '/') goto yy251; + if (yych <= '9') goto yy252; + if (yych <= ':') goto yy251; } } } else { if (yych <= '_') { if (yych <= '@') { - if (yych != '=') goto yy265; + if (yych != '=') goto yy251; } else { - if (yych <= 'Z') goto yy266; - if (yych <= '^') goto yy265; - goto yy266; + if (yych <= 'Z') goto yy252; + if (yych <= '^') goto yy251; + goto yy252; } } else { if (yych <= '{') { - if (yych <= '`') goto yy265; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych <= '`') goto yy251; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych >= 0x7F) goto yy265; + if (yych == '}') goto yy251; + if (yych >= 0x7F) goto yy251; } } } -yy275: - YYDEBUG(275, *YYCURSOR); +yy261: + YYDEBUG(261, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 381 "Zend/zend_ini_scanner.l" +#line 398 "Zend/zend_ini_scanner.l" { /* TRUE value (when used outside option value/offset this causes parse error!) */ RETURN_TOKEN(BOOL_TRUE, "1", 1); } -#line 3513 "Zend/zend_ini_scanner.c" -yy276: - YYDEBUG(276, *YYCURSOR); +#line 3481 "Zend/zend_ini_scanner.c" +yy262: + YYDEBUG(262, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(277, *YYCURSOR); + YYDEBUG(263, *YYCURSOR); if (yybm[0+yych] & 16) { - goto yy276; + goto yy262; } - goto yy275; -yy278: - YYDEBUG(278, *YYCURSOR); + goto yy261; +yy264: + YYDEBUG(264, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '=') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '9') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - goto yy266; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + goto yy252; } else { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; - goto yy258; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; + goto yy244; } } } else { if (yych <= '`') { if (yych <= 'U') { - if (yych <= '@') goto yy265; - if (yych <= 'T') goto yy266; + if (yych <= '@') goto yy251; + if (yych <= 'T') goto yy252; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 'u') goto yy279; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 'u') goto yy265; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy279: - YYDEBUG(279, *YYCURSOR); +yy265: + YYDEBUG(265, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '=') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '9') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - goto yy266; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + goto yy252; } else { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; - goto yy258; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; + goto yy244; } } } else { if (yych <= '`') { if (yych <= 'E') { - if (yych <= '@') goto yy265; - if (yych <= 'D') goto yy266; - goto yy274; + if (yych <= '@') goto yy251; + if (yych <= 'D') goto yy252; + goto yy260; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 'e') goto yy274; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 'e') goto yy260; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy280: - YYDEBUG(280, *YYCURSOR); +yy266: + YYDEBUG(266, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '=') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '9') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - goto yy266; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + goto yy252; } else { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; - goto yy258; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; + goto yy244; } } } else { if (yych <= '`') { if (yych <= 'F') { - if (yych <= '@') goto yy265; - if (yych <= 'E') goto yy266; + if (yych <= '@') goto yy251; + if (yych <= 'E') goto yy252; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 'f') goto yy281; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 'f') goto yy267; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy281: - YYDEBUG(281, *YYCURSOR); +yy267: + YYDEBUG(267, *YYCURSOR); yyaccept = 6; yych = *(YYMARKER = ++YYCURSOR); if (yybm[0+yych] & 4) { - goto yy266; + goto yy252; } if (yych <= '%') { if (yych <= '\f') { if (yych <= 0x08) { - if (yych >= 0x01) goto yy265; + if (yych >= 0x01) goto yy251; } else { - if (yych <= '\t') goto yy283; - if (yych >= '\v') goto yy265; + if (yych <= '\t') goto yy269; + if (yych >= '\v') goto yy251; } } else { if (yych <= 0x1F) { - if (yych >= 0x0E) goto yy265; + if (yych >= 0x0E) goto yy251; } else { - if (yych <= ' ') goto yy283; - if (yych >= '#') goto yy265; + if (yych <= ' ') goto yy269; + if (yych >= '#') goto yy251; } } } else { if (yych <= '=') { if (yych <= ':') { - if (yych >= '*') goto yy265; + if (yych >= '*') goto yy251; } else { - if (yych == '<') goto yy265; + if (yych == '<') goto yy251; } } else { if (yych <= '|') { - if (yych <= '{') goto yy265; + if (yych <= '{') goto yy251; } else { - if (yych != '~') goto yy265; + if (yych != '~') goto yy251; } } } -yy282: - YYDEBUG(282, *YYCURSOR); +yy268: + YYDEBUG(268, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 385 "Zend/zend_ini_scanner.l" +#line 402 "Zend/zend_ini_scanner.l" { /* FALSE value (when used outside option value/offset this causes parse error!)*/ RETURN_TOKEN(BOOL_FALSE, "", 0); } -#line 3717 "Zend/zend_ini_scanner.c" -yy283: - YYDEBUG(283, *YYCURSOR); +#line 3685 "Zend/zend_ini_scanner.c" +yy269: + YYDEBUG(269, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(284, *YYCURSOR); - if (yych == '\t') goto yy283; - if (yych == ' ') goto yy283; - goto yy282; -yy285: - YYDEBUG(285, *YYCURSOR); + YYDEBUG(270, *YYCURSOR); + if (yych == '\t') goto yy269; + if (yych == ' ') goto yy269; + goto yy268; +yy271: + YYDEBUG(271, *YYCURSOR); yyaccept = 6; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '<') { if (yych <= ' ') { if (yych <= '\n') { - if (yych <= 0x00) goto yy282; - if (yych <= 0x08) goto yy265; - if (yych <= '\t') goto yy283; - goto yy282; + if (yych <= 0x00) goto yy268; + if (yych <= 0x08) goto yy251; + if (yych <= '\t') goto yy269; + goto yy268; } else { - if (yych == '\r') goto yy282; - if (yych <= 0x1F) goto yy265; - goto yy283; + if (yych == '\r') goto yy268; + if (yych <= 0x1F) goto yy251; + goto yy269; } } else { if (yych <= '/') { - if (yych <= '"') goto yy282; - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy282; - goto yy265; + if (yych <= '"') goto yy268; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy268; + goto yy251; } else { - if (yych <= '9') goto yy266; - if (yych == ';') goto yy282; - goto yy265; + if (yych <= '9') goto yy252; + if (yych == ';') goto yy268; + goto yy251; } } } else { if (yych <= '`') { if (yych <= 'N') { - if (yych <= '=') goto yy282; - if (yych <= '@') goto yy265; - if (yych <= 'M') goto yy266; - goto yy288; + if (yych <= '=') goto yy268; + if (yych <= '@') goto yy251; + if (yych <= 'M') goto yy252; + goto yy274; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 'n') goto yy288; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 'n') goto yy274; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy282; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy268; + goto yy251; } } } -yy286: - YYDEBUG(286, *YYCURSOR); +yy272: + YYDEBUG(272, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '=') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '9') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - goto yy266; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + goto yy252; } else { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; - goto yy258; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; + goto yy244; } } } else { if (yych <= '`') { if (yych <= 'L') { - if (yych <= '@') goto yy265; - if (yych <= 'K') goto yy266; + if (yych <= '@') goto yy251; + if (yych <= 'K') goto yy252; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 'l') goto yy287; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 'l') goto yy273; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy287: - YYDEBUG(287, *YYCURSOR); +yy273: + YYDEBUG(273, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '=') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '9') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - goto yy266; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + goto yy252; } else { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; - goto yy258; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; + goto yy244; } } } else { if (yych <= '`') { if (yych <= 'L') { - if (yych <= '@') goto yy265; - if (yych <= 'K') goto yy266; - goto yy281; + if (yych <= '@') goto yy251; + if (yych <= 'K') goto yy252; + goto yy267; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 'l') goto yy281; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 'l') goto yy267; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy288: - YYDEBUG(288, *YYCURSOR); +yy274: + YYDEBUG(274, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '=') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '9') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - goto yy266; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + goto yy252; } else { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; - goto yy258; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; + goto yy244; } } } else { if (yych <= '`') { if (yych <= 'E') { - if (yych <= '@') goto yy265; - if (yych <= 'D') goto yy266; - goto yy281; + if (yych <= '@') goto yy251; + if (yych <= 'D') goto yy252; + goto yy267; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 'e') goto yy281; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 'e') goto yy267; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy289: - YYDEBUG(289, *YYCURSOR); +yy275: + YYDEBUG(275, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '=') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '9') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - goto yy266; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + goto yy252; } else { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; - goto yy258; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; + goto yy244; } } } else { if (yych <= '`') { if (yych <= 'L') { - if (yych <= '@') goto yy265; - if (yych <= 'K') goto yy266; + if (yych <= '@') goto yy251; + if (yych <= 'K') goto yy252; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 'l') goto yy290; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 'l') goto yy276; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy290: - YYDEBUG(290, *YYCURSOR); +yy276: + YYDEBUG(276, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '=') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '9') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - goto yy266; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + goto yy252; } else { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; - goto yy258; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; + goto yy244; } } } else { if (yych <= '`') { if (yych <= 'S') { - if (yych <= '@') goto yy265; - if (yych <= 'R') goto yy266; + if (yych <= '@') goto yy251; + if (yych <= 'R') goto yy252; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 's') goto yy291; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 's') goto yy277; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy291: - YYDEBUG(291, *YYCURSOR); +yy277: + YYDEBUG(277, *YYCURSOR); yyaccept = 4; yych = *(YYMARKER = ++YYCURSOR); if (yych <= '=') { if (yych <= '"') { if (yych <= '\n') { - if (yych <= 0x00) goto yy258; - if (yych <= 0x08) goto yy265; - goto yy258; + if (yych <= 0x00) goto yy244; + if (yych <= 0x08) goto yy251; + goto yy244; } else { - if (yych == '\r') goto yy258; - if (yych <= 0x1F) goto yy265; - goto yy258; + if (yych == '\r') goto yy244; + if (yych <= 0x1F) goto yy251; + goto yy244; } } else { if (yych <= '9') { - if (yych <= '%') goto yy265; - if (yych <= ')') goto yy258; - if (yych <= '/') goto yy265; - goto yy266; + if (yych <= '%') goto yy251; + if (yych <= ')') goto yy244; + if (yych <= '/') goto yy251; + goto yy252; } else { - if (yych == ';') goto yy258; - if (yych <= '<') goto yy265; - goto yy258; + if (yych == ';') goto yy244; + if (yych <= '<') goto yy251; + goto yy244; } } } else { if (yych <= '`') { if (yych <= 'E') { - if (yych <= '@') goto yy265; - if (yych <= 'D') goto yy266; - goto yy281; + if (yych <= '@') goto yy251; + if (yych <= 'D') goto yy252; + goto yy267; } else { - if (yych <= 'Z') goto yy266; - if (yych == '_') goto yy266; - goto yy265; + if (yych <= 'Z') goto yy252; + if (yych == '_') goto yy252; + goto yy251; } } else { if (yych <= '{') { - if (yych == 'e') goto yy281; - if (yych <= 'z') goto yy266; - goto yy265; + if (yych == 'e') goto yy267; + if (yych <= 'z') goto yy252; + goto yy251; } else { - if (yych == '}') goto yy265; - if (yych <= '~') goto yy258; - goto yy265; + if (yych == '}') goto yy251; + if (yych <= '~') goto yy244; + goto yy251; } } } -yy292: - YYDEBUG(292, *YYCURSOR); +yy278: + YYDEBUG(278, *YYCURSOR); ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; -yy293: - YYDEBUG(293, *YYCURSOR); +yy279: + YYDEBUG(279, *YYCURSOR); if (yybm[0+yych] & 32) { - goto yy292; + goto yy278; } - if (yych >= '\r') goto yy296; -yy294: - YYDEBUG(294, *YYCURSOR); + if (yych >= '\r') goto yy282; +yy280: + YYDEBUG(280, *YYCURSOR); ++YYCURSOR; -yy295: - YYDEBUG(295, *YYCURSOR); +yy281: + YYDEBUG(281, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 484 "Zend/zend_ini_scanner.l" +#line 528 "Zend/zend_ini_scanner.l" { /* Comment */ BEGIN(INITIAL); SCNG(lineno)++; return END_OF_LINE; } -#line 4099 "Zend/zend_ini_scanner.c" -yy296: - YYDEBUG(296, *YYCURSOR); +#line 4067 "Zend/zend_ini_scanner.c" +yy282: + YYDEBUG(282, *YYCURSOR); yych = *++YYCURSOR; - if (yych == '\n') goto yy294; - goto yy295; -yy297: - YYDEBUG(297, *YYCURSOR); + if (yych == '\n') goto yy280; + goto yy281; +yy283: + YYDEBUG(283, *YYCURSOR); yyaccept = 3; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(298, *YYCURSOR); + YYDEBUG(284, *YYCURSOR); if (yybm[0+yych] & 64) { - goto yy297; + goto yy283; } if (yych <= '%') { if (yych <= '\r') { if (yych <= 0x08) { - if (yych <= 0x00) goto yy253; - goto yy264; + if (yych <= 0x00) goto yy239; + goto yy250; } else { - if (yych <= '\n') goto yy253; - if (yych <= '\f') goto yy264; - goto yy253; + if (yych <= '\n') goto yy239; + if (yych <= '\f') goto yy250; + goto yy239; } } else { if (yych <= '"') { - if (yych <= 0x1F) goto yy264; - goto yy253; + if (yych <= 0x1F) goto yy250; + goto yy239; } else { - if (yych == '$') goto yy269; - goto yy264; + if (yych == '$') goto yy255; + goto yy250; } } } else { if (yych <= '=') { if (yych <= ':') { - if (yych <= ')') goto yy253; - goto yy264; + if (yych <= ')') goto yy239; + goto yy250; } else { - if (yych == '<') goto yy264; - goto yy253; + if (yych == '<') goto yy250; + goto yy239; } } else { if (yych <= '|') { - if (yych <= '{') goto yy264; - goto yy253; + if (yych <= '{') goto yy250; + goto yy239; } else { - if (yych == '~') goto yy253; - goto yy264; + if (yych == '~') goto yy239; + goto yy250; } } } -yy299: - YYDEBUG(299, *YYCURSOR); +yy285: + YYDEBUG(285, *YYCURSOR); yyaccept = 3; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(300, *YYCURSOR); + YYDEBUG(286, *YYCURSOR); if (yych <= '-') { if (yych <= 0x1F) { if (yych <= '\n') { - if (yych <= 0x00) goto yy253; - if (yych <= 0x08) goto yy264; - goto yy253; + if (yych <= 0x00) goto yy239; + if (yych <= 0x08) goto yy250; + goto yy239; } else { - if (yych == '\r') goto yy253; - goto yy264; + if (yych == '\r') goto yy239; + goto yy250; } } else { if (yych <= '$') { - if (yych <= '"') goto yy253; - if (yych <= '#') goto yy264; - goto yy269; + if (yych <= '"') goto yy239; + if (yych <= '#') goto yy250; + goto yy255; } else { - if (yych <= '%') goto yy264; - if (yych <= ')') goto yy253; - goto yy264; + if (yych <= '%') goto yy250; + if (yych <= ')') goto yy239; + goto yy250; } } } else { if (yych <= '<') { if (yych <= '9') { - if (yych <= '.') goto yy297; - if (yych <= '/') goto yy264; - goto yy299; + if (yych <= '.') goto yy283; + if (yych <= '/') goto yy250; + goto yy285; } else { - if (yych == ';') goto yy253; - goto yy264; + if (yych == ';') goto yy239; + goto yy250; } } else { if (yych <= '|') { - if (yych <= '=') goto yy253; - if (yych <= '{') goto yy264; - goto yy253; + if (yych <= '=') goto yy239; + if (yych <= '{') goto yy250; + goto yy239; } else { - if (yych == '~') goto yy253; - goto yy264; + if (yych == '~') goto yy239; + goto yy250; } } } -yy301: - YYDEBUG(301, *YYCURSOR); +yy287: + YYDEBUG(287, *YYCURSOR); yyaccept = 3; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(302, *YYCURSOR); + YYDEBUG(288, *YYCURSOR); if (yych <= ')') { if (yych <= '\r') { if (yych <= 0x08) { - if (yych <= 0x00) goto yy253; - goto yy264; + if (yych <= 0x00) goto yy239; + goto yy250; } else { - if (yych <= '\n') goto yy253; - if (yych <= '\f') goto yy264; - goto yy253; + if (yych <= '\n') goto yy239; + if (yych <= '\f') goto yy250; + goto yy239; } } else { if (yych <= '#') { - if (yych <= 0x1F) goto yy264; - if (yych <= '"') goto yy253; - goto yy264; + if (yych <= 0x1F) goto yy250; + if (yych <= '"') goto yy239; + goto yy250; } else { - if (yych <= '$') goto yy269; - if (yych <= '%') goto yy264; - goto yy253; + if (yych <= '$') goto yy255; + if (yych <= '%') goto yy250; + goto yy239; } } } else { if (yych <= '<') { if (yych <= '9') { - if (yych <= '/') goto yy264; - goto yy301; + if (yych <= '/') goto yy250; + goto yy287; } else { - if (yych == ';') goto yy253; - goto yy264; + if (yych == ';') goto yy239; + goto yy250; } } else { if (yych <= '|') { - if (yych <= '=') goto yy253; - if (yych <= '{') goto yy264; - goto yy253; + if (yych <= '=') goto yy239; + if (yych <= '{') goto yy250; + goto yy239; } else { - if (yych == '~') goto yy253; - goto yy264; + if (yych == '~') goto yy239; + goto yy250; } } } -yy303: - YYDEBUG(303, *YYCURSOR); +yy289: + YYDEBUG(289, *YYCURSOR); yyaccept = 3; YYMARKER = ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(304, *YYCURSOR); + YYDEBUG(290, *YYCURSOR); if (yych <= ')') { if (yych <= '\r') { if (yych <= 0x08) { - if (yych <= 0x00) goto yy253; - goto yy264; + if (yych <= 0x00) goto yy239; + goto yy250; } else { - if (yych <= '\n') goto yy253; - if (yych <= '\f') goto yy264; - goto yy253; + if (yych <= '\n') goto yy239; + if (yych <= '\f') goto yy250; + goto yy239; } } else { if (yych <= '#') { - if (yych <= 0x1F) goto yy264; - if (yych <= '"') goto yy253; - goto yy264; + if (yych <= 0x1F) goto yy250; + if (yych <= '"') goto yy239; + goto yy250; } else { - if (yych <= '$') goto yy269; - if (yych <= '%') goto yy264; - goto yy253; + if (yych <= '$') goto yy255; + if (yych <= '%') goto yy250; + goto yy239; } } } else { if (yych <= '<') { if (yych <= '9') { - if (yych <= '/') goto yy264; - goto yy303; + if (yych <= '/') goto yy250; + goto yy289; } else { - if (yych == ';') goto yy253; - goto yy264; + if (yych == ';') goto yy239; + goto yy250; } } else { if (yych <= '|') { - if (yych <= '=') goto yy253; - if (yych <= '{') goto yy264; - goto yy253; + if (yych <= '=') goto yy239; + if (yych <= '{') goto yy250; + goto yy239; } else { - if (yych == '~') goto yy253; - goto yy264; + if (yych == '~') goto yy239; + goto yy250; } } } -yy305: - YYDEBUG(305, *YYCURSOR); +yy291: + YYDEBUG(291, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; - YYDEBUG(306, *YYCURSOR); + YYDEBUG(292, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy305; + goto yy291; } - YYDEBUG(307, *YYCURSOR); + YYDEBUG(293, *YYCURSOR); ++YYCURSOR; - YYDEBUG(308, *YYCURSOR); + YYDEBUG(294, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 337 "Zend/zend_ini_scanner.l" +#line 354 "Zend/zend_ini_scanner.l" { /* Raw string */ /* Eat leading and trailing single quotes */ if (yytext[0] == '\'' && yytext[yyleng - 1] == '\'') { @@ -4316,173 +4284,185 @@ yy305: } RETURN_TOKEN(TC_RAW, yytext, yyleng); } -#line 4320 "Zend/zend_ini_scanner.c" -yy309: - YYDEBUG(309, *YYCURSOR); +#line 4288 "Zend/zend_ini_scanner.c" +yy295: + YYDEBUG(295, *YYCURSOR); ++YYCURSOR; - YYDEBUG(310, *YYCURSOR); + YYDEBUG(296, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 367 "Zend/zend_ini_scanner.l" +#line 384 "Zend/zend_ini_scanner.l" { /* Variable start */ yy_push_state(ST_VARNAME TSRMLS_CC); return TC_DOLLAR_CURLY; } -#line 4331 "Zend/zend_ini_scanner.c" -yy311: - YYDEBUG(311, *YYCURSOR); +#line 4299 "Zend/zend_ini_scanner.c" +yy297: + YYDEBUG(297, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy312: - YYDEBUG(312, *YYCURSOR); - if (yych == '\t') goto yy311; - if (yych == ' ') goto yy311; - goto yy245; -yy313: - YYDEBUG(313, *YYCURSOR); +yy298: + YYDEBUG(298, *YYCURSOR); + if (yych == '\t') goto yy297; + if (yych == ' ') goto yy297; + goto yy231; +yy299: + YYDEBUG(299, *YYCURSOR); yych = *++YYCURSOR; - goto yy242; -yy314: - YYDEBUG(314, *YYCURSOR); + goto yy228; +yy300: + YYDEBUG(300, *YYCURSOR); yyaccept = 1; YYMARKER = ++YYCURSOR; YYFILL(2); yych = *YYCURSOR; -yy315: - YYDEBUG(315, *YYCURSOR); +yy301: + YYDEBUG(301, *YYCURSOR); if (yych <= 0x1F) { if (yych <= '\n') { - if (yych <= 0x08) goto yy240; - if (yych <= '\t') goto yy314; - goto yy313; + if (yych <= 0x08) goto yy226; + if (yych <= '\t') goto yy300; + goto yy299; } else { - if (yych == '\r') goto yy317; - goto yy240; + if (yych == '\r') goto yy303; + goto yy226; } } else { if (yych <= '"') { - if (yych <= ' ') goto yy314; - if (yych <= '!') goto yy240; + if (yych <= ' ') goto yy300; + if (yych <= '!') goto yy226; } else { - if (yych == ';') goto yy292; - goto yy240; + if (yych == ';') goto yy278; + goto yy226; } } - YYDEBUG(316, *YYCURSOR); + YYDEBUG(302, *YYCURSOR); yych = *++YYCURSOR; - goto yy247; -yy317: - YYDEBUG(317, *YYCURSOR); + goto yy233; +yy303: + YYDEBUG(303, *YYCURSOR); ++YYCURSOR; - if ((yych = *YYCURSOR) == '\n') goto yy313; - goto yy242; + if ((yych = *YYCURSOR) == '\n') goto yy299; + goto yy228; } /* *********************************** */ yyc_ST_VARNAME: { static const unsigned char yybm[] = { - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 128, 0, 0, 128, 128, 0, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 0, 0, 0, 0, 0, 0, - 0, 128, 128, 128, 128, 128, 128, 128, + 128, 0, 0, 128, 128, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 0, 0, 0, 128, 0, 128, 0, 128, + 0, 0, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 128, 0, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 0, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 0, 0, 0, 0, 128, - 0, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, - 128, 128, 128, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, + 128, 128, 128, 128, 128, 128, 128, 128, }; - YYDEBUG(318, *YYCURSOR); + YYDEBUG(304, *YYCURSOR); YYFILL(2); yych = *YYCURSOR; - if (yych <= '@') { - if (yych <= ',') { - if (yych == '*') goto yy323; - goto yy321; + if (yych <= '\'') { + if (yych <= 0x1F) { + if (yych <= '\n') { + if (yych >= '\t') goto yy308; + } else { + if (yych == '\r') goto yy308; + } } else { - if (yych == '/') goto yy321; - if (yych <= '9') goto yy323; - goto yy321; + if (yych <= '$') { + if (yych != '#') goto yy308; + } else { + if (yych == '&') goto yy308; + } } } else { - if (yych <= '`') { - if (yych <= 'Z') goto yy323; - if (yych == '_') goto yy323; - goto yy321; + if (yych <= 'Z') { + if (yych <= ';') { + if (yych <= ')') goto yy308; + if (yych >= ';') goto yy308; + } else { + if (yych == '=') goto yy308; + } } else { - if (yych <= 'z') goto yy323; - if (yych == '}') goto yy324; - goto yy321; + if (yych <= '|') { + if (yych <= '[') goto yy308; + if (yych >= '{') goto yy308; + } else { + if (yych <= '}') goto yy310; + if (yych <= '~') goto yy308; + } } } -yy320: - YYDEBUG(320, *YYCURSOR); + YYDEBUG(306, *YYCURSOR); + ++YYCURSOR; + yych = *YYCURSOR; + goto yy313; +yy307: + YYDEBUG(307, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 372 "Zend/zend_ini_scanner.l" +#line 389 "Zend/zend_ini_scanner.l" { /* Variable name */ RETURN_TOKEN(TC_VARNAME, yytext, yyleng); } -#line 4448 "Zend/zend_ini_scanner.c" -yy321: - YYDEBUG(321, *YYCURSOR); +#line 4432 "Zend/zend_ini_scanner.c" +yy308: + YYDEBUG(308, *YYCURSOR); ++YYCURSOR; - YYDEBUG(322, *YYCURSOR); + YYDEBUG(309, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 502 "Zend/zend_ini_scanner.l" +#line 546 "Zend/zend_ini_scanner.l" { return 0; } -#line 4458 "Zend/zend_ini_scanner.c" -yy323: - YYDEBUG(323, *YYCURSOR); - yych = *++YYCURSOR; - goto yy327; -yy324: - YYDEBUG(324, *YYCURSOR); +#line 4442 "Zend/zend_ini_scanner.c" +yy310: + YYDEBUG(310, *YYCURSOR); ++YYCURSOR; - YYDEBUG(325, *YYCURSOR); + YYDEBUG(311, *YYCURSOR); yyleng = YYCURSOR - SCNG(yy_text); -#line 376 "Zend/zend_ini_scanner.l" +#line 393 "Zend/zend_ini_scanner.l" { /* Variable end */ yy_pop_state(TSRMLS_C); return '}'; } -#line 4473 "Zend/zend_ini_scanner.c" -yy326: - YYDEBUG(326, *YYCURSOR); +#line 4453 "Zend/zend_ini_scanner.c" +yy312: + YYDEBUG(312, *YYCURSOR); ++YYCURSOR; YYFILL(1); yych = *YYCURSOR; -yy327: - YYDEBUG(327, *YYCURSOR); +yy313: + YYDEBUG(313, *YYCURSOR); if (yybm[0+yych] & 128) { - goto yy326; + goto yy312; } - goto yy320; + goto yy307; } } -#line 506 "Zend/zend_ini_scanner.l" +#line 550 "Zend/zend_ini_scanner.l" } diff --git a/Zend/zend_ini_scanner.h b/Zend/zend_ini_scanner.h index cef499fa5..f3109b1c3 100644 --- a/Zend/zend_ini_scanner.h +++ b/Zend/zend_ini_scanner.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ini_scanner.h,v 1.14.2.1.2.2.2.4 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_ini_scanner.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef _ZEND_INI_SCANNER_H #define _ZEND_INI_SCANNER_H diff --git a/Zend/zend_ini_scanner.l b/Zend/zend_ini_scanner.l index f283acddb..e87c6d74e 100644 --- a/Zend/zend_ini_scanner.l +++ b/Zend/zend_ini_scanner.l @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ini_scanner.l,v 1.41.2.2.2.2.2.17 2009/05/19 15:59:36 shire Exp $ */ +/* $Id: zend_ini_scanner.l 286913 2009-08-07 15:44:37Z jani $ */ #include #include "zend.h" @@ -54,7 +54,9 @@ #define YYSTATE YYGETCONDITION() #define yytext ((char*)SCNG(yy_text)) #define yyleng SCNG(yy_leng) -#define yyless(x) YYCURSOR = yytext + x +#define yyless(x) do { YYCURSOR = (unsigned char*)yytext + x; \ + yyleng = (unsigned int)x; } while(0) + /* #define yymore() goto yymore_restart */ /* perform sanity check. If this message is triggered you should @@ -156,12 +158,28 @@ static void yy_scan_buffer(char *str, unsigned int len TSRMLS_DC) /* {{{ init_ini_scanner() */ -static void init_ini_scanner(TSRMLS_D) +static int init_ini_scanner(int scanner_mode, zend_file_handle *fh TSRMLS_DC) { + /* Sanity check */ + if (scanner_mode != ZEND_INI_SCANNER_NORMAL && scanner_mode != ZEND_INI_SCANNER_RAW) { + zend_error(E_WARNING, "Invalid scanner mode"); + return FAILURE; + } + SCNG(lineno) = 1; - SCNG(scanner_mode) = ZEND_INI_SCANNER_NORMAL; + SCNG(scanner_mode) = scanner_mode; + SCNG(yy_in) = fh; + + if (fh != NULL) { + ini_filename = zend_strndup(fh->filename, strlen(fh->filename)); + } else { + ini_filename = NULL; + } + zend_stack_init(&SCNG(state_stack)); BEGIN(INITIAL); + + return SUCCESS; } /* }}} */ @@ -199,15 +217,14 @@ int zend_ini_open_file_for_scanning(zend_file_handle *fh, int scanner_mode TSRML char *buf; size_t size; - if (zend_stream_fixup(fh, &buf, &size TSRMLS_CC) == FAILURE) { + if (zend_stream_fixup(fh, &buf, &size TSRMLS_CC) == FAILURE || + init_ini_scanner(scanner_mode, fh TSRMLS_CC) == FAILURE + ) { return FAILURE; } - init_ini_scanner(TSRMLS_C); - SCNG(scanner_mode) = scanner_mode; - SCNG(yy_in) = fh; yy_scan_buffer(buf, size TSRMLS_CC); - ini_filename = zend_strndup(fh->filename, strlen(fh->filename)); + return SUCCESS; } /* }}} */ @@ -218,11 +235,12 @@ int zend_ini_prepare_string_for_scanning(char *str, int scanner_mode TSRMLS_DC) { int len = strlen(str); - init_ini_scanner(TSRMLS_C); - SCNG(scanner_mode) = scanner_mode; - SCNG(yy_in) = NULL; + if (init_ini_scanner(scanner_mode, NULL TSRMLS_CC) == FAILURE) { + return FAILURE; + } + yy_scan_buffer(str, len TSRMLS_CC); - ini_filename = NULL; + return SUCCESS; } /* }}} */ @@ -308,19 +326,18 @@ NEWLINE ("\r"|"\n"|"\r\n") TABS_AND_SPACES [ \t] WHITESPACE [ \t]+ CONSTANT [a-zA-Z][a-zA-Z0-9_]* -LABEL [a-zA-Z0-9*._-]* +LABEL [^=\n\r\t ;|&$~(){}!"\[]+ TOKENS [:,.\[\]"'()|^&+-/*=%$!~<>?@{}] OPERATORS [&|~()!] DOLLAR_CURLY "${" SECTION_RAW_CHARS [^\]\n\r] SINGLE_QUOTED_CHARS [^'] -RAW_VALUE_CHARS [^=\n\r;] +RAW_VALUE_CHARS [^\n\r;] LITERAL_DOLLAR ("$"([^{\000]|("\\"{ANY_CHAR}))) VALUE_CHARS ([^$= \t\n\r;&|~()!"'\000]|{LITERAL_DOLLAR}) SECTION_VALUE_CHARS ([^$\n\r;"'\]\\]|("\\"{ANY_CHAR})|{LITERAL_DOLLAR}) -DOUBLE_QUOTES_CHARS ([^$"\\]|("\\"[^"])|{LITERAL_DOLLAR}|"\\"["][^\r\n]) := yyleng = YYCURSOR - SCNG(yy_text); @@ -453,20 +470,47 @@ DOUBLE_QUOTES_CHARS ([^$"\\]|("\\"[^"])|{LITERAL_DOLLAR}|"\\"["][^\r\n]) return '"'; } -{DOUBLE_QUOTES_CHARS}+("\\"["])? { /* Escape double quoted string contents */ - if(yyleng > 1 && yytext[yyleng-1] == '"' && yytext[yyleng-2] == '\\') { - yyless(yyleng-1); - yyleng--; - } - zend_ini_escape_string(ini_lval, yytext, yyleng, '"' TSRMLS_CC); - return TC_QUOTED_STRING; -} - ["]{TABS_AND_SPACES}* { /* Double quoted '"' string ends */ yy_pop_state(TSRMLS_C); return '"'; } +[^] { /* Escape double quoted string contents */ + if (YYCURSOR > YYLIMIT) { + return 0; + } + + while (YYCURSOR < YYLIMIT) { + switch (*YYCURSOR++) { + case '"': + if (YYCURSOR < YYLIMIT && YYCURSOR[-2] == '\\' && *YYCURSOR != '\r' && *YYCURSOR != '\n') { + continue; + } + break; + case '$': + if (*YYCURSOR == '{') { + break; + } + continue; + case '\\': + if (YYCURSOR < YYLIMIT && *YYCURSOR != '"') { + YYCURSOR++; + } + /* fall through */ + default: + continue; + } + + YYCURSOR--; + break; + } + + yyleng = YYCURSOR - SCNG(yy_text); + + zend_ini_escape_string(ini_lval, yytext, yyleng, '"' TSRMLS_CC); + return TC_QUOTED_STRING; +} + {WHITESPACE} { RETURN_TOKEN(TC_WHITESPACE, yytext, yyleng); } diff --git a/Zend/zend_ini_scanner_defs.h b/Zend/zend_ini_scanner_defs.h index 7c5dc4a4c..280132abd 100644 --- a/Zend/zend_ini_scanner_defs.h +++ b/Zend/zend_ini_scanner_defs.h @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Tue May 19 08:53:54 2009 */ +/* Generated by re2c 0.13.5 on Fri Aug 7 18:29:12 2009 */ #line 3 "Zend/zend_ini_scanner_defs.h" enum YYCONDTYPE { diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index d14ac528c..c14c52437 100755 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_interfaces.c,v 1.33.2.4.2.6.2.13 2009/03/25 10:39:26 dmitry Exp $ */ +/* $Id: zend_interfaces.c 277750 2009-03-25 10:39:26Z dmitry $ */ #include "zend.h" #include "zend_API.h" diff --git a/Zend/zend_interfaces.h b/Zend/zend_interfaces.h index 774d16742..7ff906537 100755 --- a/Zend/zend_interfaces.h +++ b/Zend/zend_interfaces.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_interfaces.h,v 1.11.2.1.2.2.2.4 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_interfaces.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_INTERFACES_H #define ZEND_INTERFACES_H diff --git a/Zend/zend_istdiostream.h b/Zend/zend_istdiostream.h index 6cdc4c8e4..da1cfed87 100644 --- a/Zend/zend_istdiostream.h +++ b/Zend/zend_istdiostream.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_istdiostream.h,v 1.6.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_istdiostream.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef _ZEND_STDIOSTREAM #define _ZEND_STDIOSTREAM diff --git a/Zend/zend_iterators.c b/Zend/zend_iterators.c index 9d3d8009e..9d9f04595 100755 --- a/Zend/zend_iterators.c +++ b/Zend/zend_iterators.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_iterators.c,v 1.12.2.1.2.2.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_iterators.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "zend.h" #include "zend_API.h" diff --git a/Zend/zend_iterators.h b/Zend/zend_iterators.h index becc47e74..6c90d817b 100755 --- a/Zend/zend_iterators.h +++ b/Zend/zend_iterators.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_iterators.h,v 1.10.2.1.2.2.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_iterators.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* These iterators were designed to operate within the foreach() * structures provided by the engine, but could be extended for use diff --git a/Zend/zend_language_parser.c b/Zend/zend_language_parser.c index e875a5e46..faf71f822 100644 --- a/Zend/zend_language_parser.c +++ b/Zend/zend_language_parser.c @@ -349,7 +349,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_language_parser.y,v 1.160.2.4.2.8.2.35 2009/03/26 12:37:17 dmitry Exp $ */ +/* $Id: zend_language_parser.y 277815 2009-03-26 12:37:54Z dmitry $ */ /* * LALR shift/reduce conflicts and how they are resolved: diff --git a/Zend/zend_language_parser.y b/Zend/zend_language_parser.y index ab3c29ad0..5923ff550 100644 --- a/Zend/zend_language_parser.y +++ b/Zend/zend_language_parser.y @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_language_parser.y,v 1.160.2.4.2.8.2.35 2009/03/26 12:37:17 dmitry Exp $ */ +/* $Id: zend_language_parser.y 277815 2009-03-26 12:37:54Z dmitry $ */ /* * LALR shift/reduce conflicts and how they are resolved: diff --git a/Zend/zend_language_scanner.c b/Zend/zend_language_scanner.c index 607a9df66..1cb027f11 100644 --- a/Zend/zend_language_scanner.c +++ b/Zend/zend_language_scanner.c @@ -23,7 +23,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_language_scanner.c,v 1.1.2.38 2009/05/05 01:44:50 mattwil Exp $ */ +/* $Id: zend_language_scanner.c 279948 2009-05-05 01:44:52Z mattwil $ */ #if 0 # define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c) diff --git a/Zend/zend_language_scanner.h b/Zend/zend_language_scanner.h index e75f54b39..5add51c97 100644 --- a/Zend/zend_language_scanner.h +++ b/Zend/zend_language_scanner.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_language_scanner.h,v 1.19.2.1.2.1.2.5 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_language_scanner.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_SCANNER_H #define ZEND_SCANNER_H diff --git a/Zend/zend_language_scanner.l b/Zend/zend_language_scanner.l index 23c06a016..9d42299dc 100644 --- a/Zend/zend_language_scanner.l +++ b/Zend/zend_language_scanner.l @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_language_scanner.l,v 1.131.2.11.2.13.2.40 2009/05/05 01:35:44 mattwil Exp $ */ +/* $Id: zend_language_scanner.l 279941 2009-05-05 01:35:44Z mattwil $ */ #if 0 # define YYDEBUG(s, c) printf("state: %d char: %c\n", s, c) diff --git a/Zend/zend_list.c b/Zend/zend_list.c index ae3bbc97b..2f71ea718 100644 --- a/Zend/zend_list.c +++ b/Zend/zend_list.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_list.c,v 1.66.2.1.2.1.2.4 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_list.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* resource lists */ diff --git a/Zend/zend_list.h b/Zend/zend_list.h index 1bdcfed86..a38e057dc 100644 --- a/Zend/zend_list.h +++ b/Zend/zend_list.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_list.h,v 1.48.2.1.2.1.2.4 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_list.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_LIST_H #define ZEND_LIST_H diff --git a/Zend/zend_llist.c b/Zend/zend_llist.c index 80dbc0a0b..b48b15072 100644 --- a/Zend/zend_llist.c +++ b/Zend/zend_llist.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_llist.c,v 1.35.2.1.2.2.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_llist.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "zend.h" #include "zend_llist.h" diff --git a/Zend/zend_llist.h b/Zend/zend_llist.h index 6b9cdd0ab..47ec5a0d0 100644 --- a/Zend/zend_llist.h +++ b/Zend/zend_llist.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_llist.h,v 1.33.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_llist.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_LLIST_H #define ZEND_LLIST_H diff --git a/Zend/zend_modules.h b/Zend/zend_modules.h index d3d4b9716..67736704f 100644 --- a/Zend/zend_modules.h +++ b/Zend/zend_modules.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_modules.h,v 1.67.2.3.2.4.2.9 2009/06/26 15:44:19 johannes Exp $ */ +/* $Id: zend_modules.h 282827 2009-06-26 15:44:19Z johannes $ */ #ifndef MODULES_H #define MODULES_H diff --git a/Zend/zend_multibyte.c b/Zend/zend_multibyte.c index 5159afa43..7d270ade9 100644 --- a/Zend/zend_multibyte.c +++ b/Zend/zend_multibyte.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_multibyte.c,v 1.4.2.4.2.1.2.7 2009/03/18 17:44:25 moriyoshi Exp $ */ +/* $Id: zend_multibyte.c 277438 2009-03-18 17:44:25Z moriyoshi $ */ #include "zend.h" #include "zend_compile.h" diff --git a/Zend/zend_multibyte.h b/Zend/zend_multibyte.h index 454e35d2e..ee3e2743f 100644 --- a/Zend/zend_multibyte.h +++ b/Zend/zend_multibyte.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_multibyte.h,v 1.3.2.3.2.1.2.4 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_multibyte.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_MULTIBYTE_H #define ZEND_MULTIBYTE_H diff --git a/Zend/zend_multiply.h b/Zend/zend_multiply.h index ad4adc88d..afac089f9 100644 --- a/Zend/zend_multiply.h +++ b/Zend/zend_multiply.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_multiply.h,v 1.10.2.1.2.2.2.3 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_multiply.h 272370 2008-12-31 11:15:49Z sebastian $ */ #if defined(__i386__) && defined(__GNUC__) diff --git a/Zend/zend_object_handlers.c b/Zend/zend_object_handlers.c index 73edc0f71..7c081caab 100644 --- a/Zend/zend_object_handlers.c +++ b/Zend/zend_object_handlers.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_object_handlers.c,v 1.135.2.6.2.22.2.31 2009/06/19 03:29:47 scottmac Exp $ */ +/* $Id: zend_object_handlers.c 282413 2009-06-19 03:29:47Z scottmac $ */ #include "zend.h" #include "zend_globals.h" diff --git a/Zend/zend_object_handlers.h b/Zend/zend_object_handlers.h index 463852341..88871ef29 100644 --- a/Zend/zend_object_handlers.h +++ b/Zend/zend_object_handlers.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_object_handlers.h,v 1.47.2.2.2.5.2.7 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_object_handlers.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_OBJECT_HANDLERS_H #define ZEND_OBJECT_HANDLERS_H diff --git a/Zend/zend_objects.c b/Zend/zend_objects.c index 3b41926e1..f69b82d9d 100644 --- a/Zend/zend_objects.c +++ b/Zend/zend_objects.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_objects.c,v 1.56.2.3.2.6.2.8 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_objects.c 289775 2009-10-19 21:43:34Z johannes $ */ #include "zend.h" #include "zend_globals.h" @@ -49,7 +49,7 @@ ZEND_API void zend_object_std_dtor(zend_object *object TSRMLS_DC) ZEND_API void zend_objects_destroy_object(zend_object *object, zend_object_handle handle TSRMLS_DC) { - zend_function *destructor = object->ce->destructor; + zend_function *destructor = object ? object->ce->destructor : NULL; if (destructor) { zval *obj; diff --git a/Zend/zend_objects.h b/Zend/zend_objects.h index 1b60e9953..1a87ca3a2 100644 --- a/Zend/zend_objects.h +++ b/Zend/zend_objects.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_objects.h,v 1.25.2.2.2.1.2.3 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_objects.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_OBJECTS_H #define ZEND_OBJECTS_H diff --git a/Zend/zend_objects_API.c b/Zend/zend_objects_API.c index 1cce7ca62..020796e95 100644 --- a/Zend/zend_objects_API.c +++ b/Zend/zend_objects_API.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_objects_API.c,v 1.47.2.6.2.6.2.9 2009/02/11 09:58:23 tony2001 Exp $ */ +/* $Id: zend_objects_API.c 275561 2009-02-11 09:58:23Z tony2001 $ */ #include "zend.h" #include "zend_globals.h" diff --git a/Zend/zend_objects_API.h b/Zend/zend_objects_API.h index de9bf114f..643eaffba 100644 --- a/Zend/zend_objects_API.h +++ b/Zend/zend_objects_API.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_objects_API.h,v 1.20.2.1.2.4.2.5 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_objects_API.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_OBJECTS_API_H #define ZEND_OBJECTS_API_H diff --git a/Zend/zend_opcode.c b/Zend/zend_opcode.c index fd3cb84df..a721b0d7b 100644 --- a/Zend/zend_opcode.c +++ b/Zend/zend_opcode.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_opcode.c,v 1.110.2.6.2.3.2.11 2009/06/05 23:20:59 shire Exp $ */ +/* $Id: zend_opcode.c 281737 2009-06-05 23:20:59Z shire $ */ #include diff --git a/Zend/zend_operators.c b/Zend/zend_operators.c index 3b3fef10e..6ee0d8e59 100644 --- a/Zend/zend_operators.c +++ b/Zend/zend_operators.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_operators.c,v 1.208.2.4.2.23.2.27 2009/06/04 18:20:42 mattwil Exp $ */ +/* $Id: zend_operators.c 281670 2009-06-04 18:20:45Z mattwil $ */ #include diff --git a/Zend/zend_operators.h b/Zend/zend_operators.h index 8896d0f9d..03cd707d4 100644 --- a/Zend/zend_operators.h +++ b/Zend/zend_operators.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_operators.h,v 1.94.2.4.2.10.2.16 2009/06/04 18:20:42 mattwil Exp $ */ +/* $Id: zend_operators.h 281670 2009-06-04 18:20:45Z mattwil $ */ #ifndef ZEND_OPERATORS_H #define ZEND_OPERATORS_H diff --git a/Zend/zend_ptr_stack.c b/Zend/zend_ptr_stack.c index 54296c740..5625a349d 100644 --- a/Zend/zend_ptr_stack.c +++ b/Zend/zend_ptr_stack.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ptr_stack.c,v 1.23.2.1.2.1.2.3 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_ptr_stack.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "zend.h" #include "zend_ptr_stack.h" diff --git a/Zend/zend_ptr_stack.h b/Zend/zend_ptr_stack.h index f4536ce93..bd2f8b2d3 100644 --- a/Zend/zend_ptr_stack.h +++ b/Zend/zend_ptr_stack.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ptr_stack.h,v 1.22.2.2.2.1.2.5 2009/06/05 11:21:31 lbarnaud Exp $ */ +/* $Id: zend_ptr_stack.h 281712 2009-06-05 11:21:31Z lbarnaud $ */ #ifndef ZEND_PTR_STACK_H #define ZEND_PTR_STACK_H diff --git a/Zend/zend_qsort.c b/Zend/zend_qsort.c index 33c2d12cc..8b65f964d 100644 --- a/Zend/zend_qsort.c +++ b/Zend/zend_qsort.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_qsort.c,v 1.8.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_qsort.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "zend.h" diff --git a/Zend/zend_qsort.h b/Zend/zend_qsort.h index b2981d828..1044320d9 100644 --- a/Zend/zend_qsort.h +++ b/Zend/zend_qsort.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_qsort.h,v 1.8.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_qsort.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_QSORT_H #define ZEND_QSORT_H diff --git a/Zend/zend_sprintf.c b/Zend/zend_sprintf.c index e6a871833..de1dd208f 100644 --- a/Zend/zend_sprintf.c +++ b/Zend/zend_sprintf.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_sprintf.c,v 1.16.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_sprintf.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include diff --git a/Zend/zend_stack.c b/Zend/zend_stack.c index 688aced3c..a8da8244c 100644 --- a/Zend/zend_stack.c +++ b/Zend/zend_stack.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_stack.c,v 1.16.2.1.2.1.2.4 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_stack.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "zend.h" #include "zend_stack.h" diff --git a/Zend/zend_stack.h b/Zend/zend_stack.h index 8c8adf279..5aed0321b 100644 --- a/Zend/zend_stack.h +++ b/Zend/zend_stack.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_stack.h,v 1.19.2.1.2.1.2.3 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_stack.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_STACK_H #define ZEND_STACK_H diff --git a/Zend/zend_static_allocator.c b/Zend/zend_static_allocator.c index a0c0ddf2c..efa299e94 100644 --- a/Zend/zend_static_allocator.c +++ b/Zend/zend_static_allocator.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_static_allocator.c,v 1.13.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_static_allocator.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "zend_static_allocator.h" diff --git a/Zend/zend_static_allocator.h b/Zend/zend_static_allocator.h index e037a4399..70cfab744 100644 --- a/Zend/zend_static_allocator.h +++ b/Zend/zend_static_allocator.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_static_allocator.h,v 1.13.2.1.2.1.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_static_allocator.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_STATIC_ALLOCATOR_H #define ZEND_STATIC_ALLOCATOR_H diff --git a/Zend/zend_stream.c b/Zend/zend_stream.c index 7befee849..2b99358f0 100644 --- a/Zend/zend_stream.c +++ b/Zend/zend_stream.c @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_stream.c,v 1.13.2.1.2.1.2.11 2009/03/26 17:28:49 dmitry Exp $ */ +/* $Id: zend_stream.c 277834 2009-03-26 17:28:49Z dmitry $ */ #include "zend.h" diff --git a/Zend/zend_stream.h b/Zend/zend_stream.h index ced3cffe4..f9c08eaf8 100644 --- a/Zend/zend_stream.h +++ b/Zend/zend_stream.h @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_stream.h,v 1.8.2.1.2.1.2.6 2009/06/16 14:33:33 felipe Exp $ */ +/* $Id: zend_stream.h 282248 2009-06-16 14:33:33Z felipe $ */ #ifndef ZEND_STREAM_H #define ZEND_STREAM_H diff --git a/Zend/zend_strtod.c b/Zend/zend_strtod.c index 85c59a3d5..c3a86c676 100644 --- a/Zend/zend_strtod.c +++ b/Zend/zend_strtod.c @@ -89,7 +89,7 @@ * directly -- and assumed always to succeed. */ -/* $Id: zend_strtod.c,v 1.17.2.2.2.13.2.5 2009/03/18 10:18:10 dmitry Exp $ */ +/* $Id: zend_strtod.c 277398 2009-03-18 10:18:10Z dmitry $ */ #include #include diff --git a/Zend/zend_strtod.h b/Zend/zend_strtod.h index 8c7aaa276..01eb99375 100644 --- a/Zend/zend_strtod.h +++ b/Zend/zend_strtod.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_strtod.h,v 1.3.2.1.2.4.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_strtod.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* This is a header file for the strtod implementation by David M. Gay which * can be found in zend_strtod.c */ diff --git a/Zend/zend_ts_hash.c b/Zend/zend_ts_hash.c index 01b2a8d05..cc27dc9c5 100644 --- a/Zend/zend_ts_hash.c +++ b/Zend/zend_ts_hash.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ts_hash.c,v 1.14.2.1.2.2.2.4 2009/01/09 19:16:55 tony2001 Exp $ */ +/* $Id: zend_ts_hash.c 273192 2009-01-09 19:16:55Z tony2001 $ */ #include "zend.h" #include "zend_ts_hash.h" diff --git a/Zend/zend_ts_hash.h b/Zend/zend_ts_hash.h index c01c23236..d6ffb7726 100644 --- a/Zend/zend_ts_hash.h +++ b/Zend/zend_ts_hash.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_ts_hash.h,v 1.13.2.1.2.1.2.4 2009/01/09 19:16:55 tony2001 Exp $ */ +/* $Id: zend_ts_hash.h 273192 2009-01-09 19:16:55Z tony2001 $ */ #ifndef ZEND_TS_HASH_H #define ZEND_TS_HASH_H diff --git a/Zend/zend_types.h b/Zend/zend_types.h index cce63c6a9..100b27927 100644 --- a/Zend/zend_types.h +++ b/Zend/zend_types.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_types.h,v 1.6.2.2.2.3.2.5 2009/06/05 11:21:31 lbarnaud Exp $ */ +/* $Id: zend_types.h 281712 2009-06-05 11:21:31Z lbarnaud $ */ #ifndef ZEND_TYPES_H #define ZEND_TYPES_H diff --git a/Zend/zend_variables.c b/Zend/zend_variables.c index 743207cac..5aad679b0 100644 --- a/Zend/zend_variables.c +++ b/Zend/zend_variables.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_variables.c,v 1.62.2.1.2.2.2.4 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_variables.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include #include "zend.h" diff --git a/Zend/zend_variables.h b/Zend/zend_variables.h index 32fe34c11..fbc989353 100644 --- a/Zend/zend_variables.h +++ b/Zend/zend_variables.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_variables.h,v 1.34.2.1.2.1.2.5 2009/05/01 21:46:53 jani Exp $ */ +/* $Id: zend_variables.h 279681 2009-05-01 21:46:53Z jani $ */ #ifndef ZEND_VARIABLES_H #define ZEND_VARIABLES_H diff --git a/Zend/zend_vm.h b/Zend/zend_vm.h index 5974b317c..a80a4b89b 100644 --- a/Zend/zend_vm.h +++ b/Zend/zend_vm.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_vm.h,v 1.7.2.1.2.2.2.2 2008/12/31 11:15:32 sebastian Exp $ */ +/* $Id: zend_vm.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef ZEND_VM_H #define ZEND_VM_H diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 7946feae7..485f2cc17 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zend_vm_def.h,v 1.59.2.29.2.48.2.95 2009/06/07 15:46:51 mattwil Exp $ */ +/* $Id: zend_vm_def.h 290152 2009-11-02 18:11:33Z pajoye $ */ /* If you change this file, please regenerate the zend_vm_execute.h and * zend_vm_opcodes.h files by running: @@ -940,6 +940,7 @@ ZEND_VM_HELPER_EX(zend_fetch_var_address_helper, CONST|TMP|VAR|CV, ANY, int type if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) { retval = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0 TSRMLS_CC); + FREE_OP1(); } else { target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), type, varname TSRMLS_CC); /* @@ -2328,16 +2329,12 @@ ZEND_VM_HELPER(zend_do_fcall_common_helper, ANY, ANY) EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference; } -#ifndef ZEND_VM_EXPORT if (zend_execute == execute && !EG(exception)) { EX(call_opline) = opline; ZEND_VM_ENTER(); } else { zend_execute(EG(active_op_array) TSRMLS_CC); } -#else - zend_execute(EG(active_op_array) TSRMLS_CC); -#endif EG(opline_ptr) = &EX(opline); EG(active_op_array) = EX(op_array); @@ -2662,7 +2659,9 @@ ZEND_VM_HANDLER(106, ZEND_SEND_VAR_NO_REF, VAR|CV, ANY) } else { zval *valptr; - if (!(opline->extended_value & ZEND_ARG_SEND_SILENT)) { + if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? + !(opline->extended_value & ZEND_ARG_SEND_SILENT) : + !ARG_MAY_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { zend_error(E_STRICT, "Only variables should be passed by reference"); } ALLOC_ZVAL(valptr); @@ -2688,6 +2687,10 @@ ZEND_VM_HANDLER(67, ZEND_SEND_REF, VAR|CV, ANY) zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); } + if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { + ZEND_VM_DISPATCH_TO_HELPER(zend_send_by_var_helper); + } + SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); varptr = *varptr_ptr; Z_ADDREF_P(varptr); @@ -3571,28 +3574,33 @@ ZEND_VM_HANDLER(77, ZEND_FE_RESET, CONST|TMP|VAR|CV, ANY) ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); array_ptr = tmp; + if (Z_TYPE_P(array_ptr) == IS_OBJECT) { + ce = Z_OBJCE_P(array_ptr); + if (ce && ce->get_iterator) { + Z_DELREF_P(array_ptr); + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { Z_ADDREF_P(array_ptr); } + } else if (OP1_TYPE == IS_CONST || + ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 1)) { + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; } else { - if ((OP1_TYPE == IS_CV || OP1_TYPE == IS_VAR) && - !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1) { - zval *tmp; - - ALLOC_ZVAL(tmp); - INIT_PZVAL_COPY(tmp, array_ptr); - zval_copy_ctor(tmp); - array_ptr = tmp; - } else { - Z_ADDREF_P(array_ptr); - } + Z_ADDREF_P(array_ptr); } } - if (OP1_TYPE != IS_TMP_VAR && ce && ce->get_iterator) { + if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); if (iter && !EG(exception)) { @@ -4237,12 +4245,13 @@ ZEND_VM_HANDLER(144, ZEND_ADD_INTERFACE, ANY, CONST) zend_class_entry *ce = EX_T(opline->op1.u.var).class_entry; zend_class_entry *iface = zend_fetch_class(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant), opline->extended_value TSRMLS_CC); - if (!(iface->ce_flags & ZEND_ACC_INTERFACE)) { - zend_error_noreturn(E_ERROR, "%s cannot implement %s - it is not an interface", ce->name, iface->name); + if (iface) { + if (!(iface->ce_flags & ZEND_ACC_INTERFACE)) { + zend_error_noreturn(E_ERROR, "%s cannot implement %s - it is not an interface", ce->name, iface->name); + } + zend_do_implement_interface(ce, iface TSRMLS_CC); } - zend_do_implement_interface(ce, iface TSRMLS_CC); - ZEND_VM_NEXT_OPCODE(); } @@ -4254,8 +4263,8 @@ ZEND_VM_HANDLER(149, ZEND_HANDLE_EXCEPTION, ANY, ANY) int catched = 0; zval restored_error_reporting; - void **stack_frame = (void**)EX(Ts) + - (sizeof(temp_variable) * EX(op_array)->T) / sizeof(void*); + void **stack_frame = (void**)(((char*)EX(Ts)) + + (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T)); while (zend_vm_stack_top(TSRMLS_C) != stack_frame) { zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C); @@ -4351,6 +4360,10 @@ ZEND_VM_HANDLER(150, ZEND_USER_OPCODE, ANY, ANY) ZEND_VM_CONTINUE(); case ZEND_USER_OPCODE_RETURN: ZEND_VM_DISPATCH_TO_HELPER(zend_leave_helper); + case ZEND_USER_OPCODE_ENTER: + ZEND_VM_ENTER(); + case ZEND_USER_OPCODE_LEAVE: + ZEND_VM_LEAVE(); case ZEND_USER_OPCODE_DISPATCH: ZEND_VM_DISPATCH(EX(opline)->opcode, EX(opline)); default: diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index 2c3e7875a..9d931107d 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -52,13 +52,13 @@ ZEND_API void execute(zend_op_array *op_array TSRMLS_DC) zend_vm_enter: /* Initialize execute_data */ execute_data = (zend_execute_data *)zend_vm_stack_alloc( - sizeof(zend_execute_data) + - sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2) + - sizeof(temp_variable) * op_array->T TSRMLS_CC); + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) + + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) + + ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T TSRMLS_CC); - EX(CVs) = (zval***)((char*)execute_data + sizeof(zend_execute_data)); + EX(CVs) = (zval***)((char*)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data))); memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var); - EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var * (EG(active_symbol_table) ? 1 : 2)); + EX(Ts) = (temp_variable *)(((char*)EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2))); EX(fbc) = NULL; EX(called_scope) = NULL; EX(object) = NULL; @@ -330,16 +330,12 @@ static int ZEND_FASTCALL zend_do_fcall_common_helper_SPEC(ZEND_OPCODE_HANDLER_AR EX_T(opline->result.u.var).var.fcall_returned_reference = EX(function_state).function->common.return_reference; } -#if 1 if (zend_execute == execute && !EG(exception)) { EX(call_opline) = opline; ZEND_VM_ENTER(); } else { zend_execute(EG(active_op_array) TSRMLS_CC); } -#else - zend_execute(EG(active_op_array) TSRMLS_CC); -#endif EG(opline_ptr) = &EX(opline); EG(active_op_array) = EX(op_array); @@ -602,8 +598,8 @@ static int ZEND_FASTCALL ZEND_HANDLE_EXCEPTION_SPEC_HANDLER(ZEND_OPCODE_HANDLER int catched = 0; zval restored_error_reporting; - void **stack_frame = (void**)EX(Ts) + - (sizeof(temp_variable) * EX(op_array)->T) / sizeof(void*); + void **stack_frame = (void**)(((char*)EX(Ts)) + + (ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * EX(op_array)->T)); while (zend_vm_stack_top(TSRMLS_C) != stack_frame) { zval *stack_zval_p = zend_vm_stack_pop(TSRMLS_C); @@ -699,6 +695,10 @@ static int ZEND_FASTCALL ZEND_USER_OPCODE_SPEC_HANDLER(ZEND_OPCODE_HANDLER_ARGS ZEND_VM_CONTINUE(); case ZEND_USER_OPCODE_RETURN: return zend_leave_helper_SPEC(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + case ZEND_USER_OPCODE_ENTER: + ZEND_VM_ENTER(); + case ZEND_USER_OPCODE_LEAVE: + ZEND_VM_LEAVE(); case ZEND_USER_OPCODE_DISPATCH: ZEND_VM_DISPATCH(EX(opline)->opcode, EX(opline)); default: @@ -889,12 +889,13 @@ static int ZEND_FASTCALL ZEND_ADD_INTERFACE_SPEC_CONST_HANDLER(ZEND_OPCODE_HAND zend_class_entry *ce = EX_T(opline->op1.u.var).class_entry; zend_class_entry *iface = zend_fetch_class(Z_STRVAL(opline->op2.u.constant), Z_STRLEN(opline->op2.u.constant), opline->extended_value TSRMLS_CC); - if (!(iface->ce_flags & ZEND_ACC_INTERFACE)) { - zend_error_noreturn(E_ERROR, "%s cannot implement %s - it is not an interface", ce->name, iface->name); + if (iface) { + if (!(iface->ce_flags & ZEND_ACC_INTERFACE)) { + zend_error_noreturn(E_ERROR, "%s cannot implement %s - it is not an interface", ce->name, iface->name); + } + zend_do_implement_interface(ce, iface TSRMLS_CC); } - zend_do_implement_interface(ce, iface TSRMLS_CC); - ZEND_VM_NEXT_OPCODE(); } @@ -2108,28 +2109,33 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CONST_HANDLER(ZEND_OPCODE_HANDLER_A ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); array_ptr = tmp; + if (Z_TYPE_P(array_ptr) == IS_OBJECT) { + ce = Z_OBJCE_P(array_ptr); + if (ce && ce->get_iterator) { + Z_DELREF_P(array_ptr); + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { Z_ADDREF_P(array_ptr); } + } else if (IS_CONST == IS_CONST || + ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 1)) { + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; } else { - if ((IS_CONST == IS_CV || IS_CONST == IS_VAR) && - !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1) { - zval *tmp; - - ALLOC_ZVAL(tmp); - INIT_PZVAL_COPY(tmp, array_ptr); - zval_copy_ctor(tmp); - array_ptr = tmp; - } else { - Z_ADDREF_P(array_ptr); - } + Z_ADDREF_P(array_ptr); } } - if (IS_CONST != IS_TMP_VAR && ce && ce->get_iterator) { + if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); if (iter && !EG(exception)) { @@ -4602,6 +4608,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_TMP(int type, ZEND_O if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) { retval = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0 TSRMLS_CC); + zval_dtor(free_op1.var); } else { target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), type, varname TSRMLS_CC); /* @@ -5370,28 +5377,33 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_TMP_HANDLER(ZEND_OPCODE_HANDLER_ARG ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); array_ptr = tmp; + if (Z_TYPE_P(array_ptr) == IS_OBJECT) { + ce = Z_OBJCE_P(array_ptr); + if (ce && ce->get_iterator) { + Z_DELREF_P(array_ptr); + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { Z_ADDREF_P(array_ptr); } + } else if (IS_TMP_VAR == IS_CONST || + ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 1)) { + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; } else { - if ((IS_TMP_VAR == IS_CV || IS_TMP_VAR == IS_VAR) && - !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1) { - zval *tmp; - - ALLOC_ZVAL(tmp); - INIT_PZVAL_COPY(tmp, array_ptr); - zval_copy_ctor(tmp); - array_ptr = tmp; - } else { - Z_ADDREF_P(array_ptr); - } + Z_ADDREF_P(array_ptr); } } - if (IS_TMP_VAR != IS_TMP_VAR && ce && ce->get_iterator) { + if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); if (iter && !EG(exception)) { @@ -7838,6 +7850,7 @@ static int ZEND_FASTCALL zend_fetch_var_address_helper_SPEC_VAR(int type, ZEND_O if (opline->op2.u.EA.type == ZEND_FETCH_STATIC_MEMBER) { retval = zend_std_get_static_property(EX_T(opline->op2.u.var).class_entry, Z_STRVAL_P(varname), Z_STRLEN_P(varname), 0 TSRMLS_CC); + if (free_op1.var) {zval_ptr_dtor(&free_op1.var);}; } else { target_symbol_table = zend_get_target_symbol_table(opline, EX(Ts), type, varname TSRMLS_CC); /* @@ -8278,7 +8291,9 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HAND } else { zval *valptr; - if (!(opline->extended_value & ZEND_ARG_SEND_SILENT)) { + if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? + !(opline->extended_value & ZEND_ARG_SEND_SILENT) : + !ARG_MAY_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { zend_error(E_STRICT, "Only variables should be passed by reference"); } ALLOC_ZVAL(valptr); @@ -8304,6 +8319,10 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); } + if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { + return zend_send_by_var_helper_SPEC_VAR(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); varptr = *varptr_ptr; Z_ADDREF_P(varptr); @@ -8715,28 +8734,33 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_VAR_HANDLER(ZEND_OPCODE_HANDLER_ARG ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); array_ptr = tmp; + if (Z_TYPE_P(array_ptr) == IS_OBJECT) { + ce = Z_OBJCE_P(array_ptr); + if (ce && ce->get_iterator) { + Z_DELREF_P(array_ptr); + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { Z_ADDREF_P(array_ptr); } + } else if (IS_VAR == IS_CONST || + ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 1)) { + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; } else { - if ((IS_VAR == IS_CV || IS_VAR == IS_VAR) && - !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1) { - zval *tmp; - - ALLOC_ZVAL(tmp); - INIT_PZVAL_COPY(tmp, array_ptr); - zval_copy_ctor(tmp); - array_ptr = tmp; - } else { - Z_ADDREF_P(array_ptr); - } + Z_ADDREF_P(array_ptr); } } - if (IS_VAR != IS_TMP_VAR && ce && ce->get_iterator) { + if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); if (iter && !EG(exception)) { @@ -22128,7 +22152,9 @@ static int ZEND_FASTCALL ZEND_SEND_VAR_NO_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDL } else { zval *valptr; - if (!(opline->extended_value & ZEND_ARG_SEND_SILENT)) { + if ((opline->extended_value & ZEND_ARG_COMPILE_TIME_BOUND) ? + !(opline->extended_value & ZEND_ARG_SEND_SILENT) : + !ARG_MAY_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { zend_error(E_STRICT, "Only variables should be passed by reference"); } ALLOC_ZVAL(valptr); @@ -22154,6 +22180,10 @@ static int ZEND_FASTCALL ZEND_SEND_REF_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS zend_error_noreturn(E_ERROR, "Only variables can be passed by reference"); } + if (EX(function_state).function->type == ZEND_INTERNAL_FUNCTION && !ARG_SHOULD_BE_SENT_BY_REF(EX(fbc), opline->op2.u.opline_num)) { + return zend_send_by_var_helper_SPEC_CV(ZEND_OPCODE_HANDLER_ARGS_PASSTHRU); + } + SEPARATE_ZVAL_TO_MAKE_IS_REF(varptr_ptr); varptr = *varptr_ptr; Z_ADDREF_P(varptr); @@ -22555,28 +22585,33 @@ static int ZEND_FASTCALL ZEND_FE_RESET_SPEC_CV_HANDLER(ZEND_OPCODE_HANDLER_ARGS ALLOC_ZVAL(tmp); INIT_PZVAL_COPY(tmp, array_ptr); array_ptr = tmp; + if (Z_TYPE_P(array_ptr) == IS_OBJECT) { + ce = Z_OBJCE_P(array_ptr); + if (ce && ce->get_iterator) { + Z_DELREF_P(array_ptr); + } + } } else if (Z_TYPE_P(array_ptr) == IS_OBJECT) { ce = Z_OBJCE_P(array_ptr); if (!ce || !ce->get_iterator) { Z_ADDREF_P(array_ptr); } + } else if (IS_CV == IS_CONST || + ((IS_CV == IS_CV || IS_CV == IS_VAR) && + !Z_ISREF_P(array_ptr) && + Z_REFCOUNT_P(array_ptr) > 1)) { + zval *tmp; + + ALLOC_ZVAL(tmp); + INIT_PZVAL_COPY(tmp, array_ptr); + zval_copy_ctor(tmp); + array_ptr = tmp; } else { - if ((IS_CV == IS_CV || IS_CV == IS_VAR) && - !Z_ISREF_P(array_ptr) && - Z_REFCOUNT_P(array_ptr) > 1) { - zval *tmp; - - ALLOC_ZVAL(tmp); - INIT_PZVAL_COPY(tmp, array_ptr); - zval_copy_ctor(tmp); - array_ptr = tmp; - } else { - Z_ADDREF_P(array_ptr); - } + Z_ADDREF_P(array_ptr); } } - if (IS_CV != IS_TMP_VAR && ce && ce->get_iterator) { + if (ce && ce->get_iterator) { iter = ce->get_iterator(ce, array_ptr, opline->extended_value & ZEND_FE_RESET_REFERENCE TSRMLS_CC); if (iter && !EG(exception)) { diff --git a/Zend/zend_vm_execute.skl b/Zend/zend_vm_execute.skl index 52592dac2..18d0e2935 100644 --- a/Zend/zend_vm_execute.skl +++ b/Zend/zend_vm_execute.skl @@ -18,13 +18,13 @@ ZEND_API void {%EXECUTOR_NAME%}(zend_op_array *op_array TSRMLS_DC) zend_vm_enter: /* Initialize execute_data */ execute_data = (zend_execute_data *)zend_vm_stack_alloc( - sizeof(zend_execute_data) + - sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2) + - sizeof(temp_variable) * op_array->T TSRMLS_CC); + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data)) + + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2)) + + ZEND_MM_ALIGNED_SIZE(sizeof(temp_variable)) * op_array->T TSRMLS_CC); - EX(CVs) = (zval***)((char*)execute_data + sizeof(zend_execute_data)); + EX(CVs) = (zval***)((char*)execute_data + ZEND_MM_ALIGNED_SIZE(sizeof(zend_execute_data))); memset(EX(CVs), 0, sizeof(zval**) * op_array->last_var); - EX(Ts) = (temp_variable *)(EX(CVs) + op_array->last_var * (EG(active_symbol_table) ? 1 : 2)); + EX(Ts) = (temp_variable *)(((char*)EX(CVs)) + ZEND_MM_ALIGNED_SIZE(sizeof(zval**) * op_array->last_var * (EG(active_symbol_table) ? 1 : 2))); EX(fbc) = NULL; EX(called_scope) = NULL; EX(object) = NULL; diff --git a/Zend/zend_vm_gen.php b/Zend/zend_vm_gen.php index e99d0407a..f67296bf0 100644 --- a/Zend/zend_vm_gen.php +++ b/Zend/zend_vm_gen.php @@ -16,7 +16,7 @@ | Authors: Dmitry Stogov | +----------------------------------------------------------------------+ - $Id: zend_vm_gen.php,v 1.12.2.5.2.4.2.5 2008/12/31 11:15:35 sebastian Exp $ + $Id: zend_vm_gen.php 272370 2008-12-31 11:15:49Z sebastian $ */ $header_text = <<< DATA diff --git a/acconfig.h b/acconfig.h index a89f91581..4c5d4a181 100644 --- a/acconfig.h +++ b/acconfig.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: acconfig.h,v 1.40.2.1.2.1.2.3 2008/12/31 11:15:31 sebastian Exp $ */ +/* $Id: acconfig.h 272370 2008-12-31 11:15:49Z sebastian $ */ #if defined(__GNUC__) && __GNUC__ >= 4 # define ZEND_API __attribute__ ((visibility("default"))) diff --git a/acinclude.m4 b/acinclude.m4 index 82c1f8e25..46e6eb75c 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: acinclude.m4,v 1.332.2.14.2.26.2.13 2009/05/09 20:26:51 jani Exp $ +dnl $Id: acinclude.m4 287126 2009-08-11 23:45:35Z srinatar $ dnl dnl This file contains local autoconf functions. dnl @@ -2780,7 +2780,7 @@ AC_DEFUN([PHP_DETECT_SUNCC],[ AC_MSG_RESULT([no]), SUNCC="yes" GCC="no" - test -n "$auto_cflags" && CFLAGS="-fsimple=2 -xnorunpath -xO4 -xalias_level=basic -xipo=1 -xlibmopt -xprefetch_level=1 -xprefetch=auto -xstrconst -xtarget=native -zlazyload" + test -n "$auto_cflags" && CFLAGS="-O -xs -xstrconst -zlazyload" GCC="" AC_MSG_RESULT([yes]) ) diff --git a/aclocal.m4 b/aclocal.m4 index 67570c55a..68a847c40 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: acinclude.m4,v 1.332.2.14.2.26.2.13 2009/05/09 20:26:51 jani Exp $ +dnl $Id: acinclude.m4 287126 2009-08-11 23:45:35Z srinatar $ dnl dnl This file contains local autoconf functions. dnl @@ -2780,7 +2780,7 @@ AC_DEFUN([PHP_DETECT_SUNCC],[ AC_MSG_RESULT([no]), SUNCC="yes" GCC="no" - test -n "$auto_cflags" && CFLAGS="-fsimple=2 -xnorunpath -xO4 -xalias_level=basic -xipo=1 -xlibmopt -xprefetch_level=1 -xprefetch=auto -xstrconst -xtarget=native -zlazyload" + test -n "$auto_cflags" && CFLAGS="-O -xs -xstrconst -zlazyload" GCC="" AC_MSG_RESULT([yes]) ) diff --git a/build/build.mk b/build/build.mk index c6f68028f..51961f66b 100644 --- a/build/build.mk +++ b/build/build.mk @@ -1,7 +1,7 @@ # +----------------------------------------------------------------------+ # | PHP Version 5 | # +----------------------------------------------------------------------+ -# | Copyright (c) 1997-2007 The PHP Group | +# | Copyright (c) 1997-2006 The PHP Group | # +----------------------------------------------------------------------+ # | This source file is subject to version 3.01 of the PHP license, | # | that is bundled with this package in the file LICENSE, and is | @@ -14,15 +14,13 @@ # | Author: Sascha Schumann | # +----------------------------------------------------------------------+ # -# $Id: build.mk,v 1.26.2.2.2.2.2.1 2008/03/17 15:22:22 gwynne Exp $ +# $Id: build.mk 287074 2009-08-11 02:21:09Z dsp $ # # # Makefile to generate build tools # -ZENDDIR = Zend - -SUBDIRS = $(ZENDDIR) TSRM +SUBDIRS = Zend TSRM STAMP = buildmk.stamp @@ -33,11 +31,10 @@ all: $(STAMP) $(ALWAYS) @$(MAKE) -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 >> $@ + @echo makefile_am_files = Zend/Makefile.am TSRM/Makefile.am > $@ + @echo config_h_files = Zend/acconfig.h TSRM/acconfig.h >> $@ + @echo config_m4_files = Zend/Zend.m4 TSRM/tsrm.m4 TSRM/threads.m4 \ + Zend/acinclude.m4 ext/*/config*.m4 sapi/*/config.m4 >> $@ $(STAMP): build/buildcheck.sh @build/buildcheck.sh $(STAMP) @@ -67,7 +64,18 @@ snapshot: cvsclean-work: @for i in `find . -name .cvsignore`; do \ - (cd `dirname $$i` 2>/dev/null && rm -rf `cat .cvsignore | grep -v config.nice | sed 's/[[:space:]]/ /g'` *.o *.a .libs || true); \ + (cd `dirname $$i` 2>/dev/null && rm -rf `cat .cvsignore | grep -v config.nice | sed 's/[[:space:]]/ /g'` *.o *.a *.lo *.la *.gcno *.gcda .libs || true); \ + done + +svnclean-work: + @for i in `find . -type d -not -path '*/.svn/*' | grep -v '.svn'`; do \ + (cd $$i 2>/dev/null && rm -rf `svn propget svn:ignore . | grep -v config.nice` *.o *.a *.lo *.la *.gcno *.gcda .libs || true); \ done +gitclean-work: + @if (test ! -f '.git/info/exclude' || grep -s "git-ls-files" .git/info/exclude); then \ + (echo "Rebuild .git/info/exclude" && echo '*.o' > .git/info/exclude && git svn propget svn:ignore | grep -v config.nice >> .git/info/exclude); \ + fi; \ + git clean -X -f -d; + .PHONY: $(ALWAYS) snapshot diff --git a/build/build2.mk b/build/build2.mk index 19eed1b40..050f3763f 100644 --- a/build/build2.mk +++ b/build/build2.mk @@ -14,7 +14,7 @@ # | Author: Sascha Schumann | # +----------------------------------------------------------------------+ # -# $Id: build2.mk,v 1.37.2.2.2.1 2007/01/01 19:32:10 iliaa Exp $ +# $Id: build2.mk 226204 2007-01-01 19:32:10Z iliaa $ # include generated_lists diff --git a/build/buildcheck.sh b/build/buildcheck.sh index 388130760..4d76bf24d 100755 --- a/build/buildcheck.sh +++ b/build/buildcheck.sh @@ -16,7 +16,7 @@ # | Sascha Schumann | # +----------------------------------------------------------------------+ # -# $Id: buildcheck.sh,v 1.37.2.2.2.1 2007/01/01 19:32:10 iliaa Exp $ +# $Id: buildcheck.sh,v 1.37.2.2.2.1 2007-01-01 19:32:10 iliaa Exp $ # echo "buildconf: checking installation..." @@ -33,14 +33,14 @@ ac_version=`$PHP_AUTOCONF --version 2>/dev/null|head -n 1|sed -e 's/^[^0-9]*//' 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." +echo " to build PHP from SVN." 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." +echo " to build PHP from SVN." exit 1 else echo "buildconf: autoconf version $ac_version (ok)" @@ -48,9 +48,9 @@ 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 " Running vcsclean for you." echo " To avoid this, install autoconf-2.13." - ./cvsclean + ./vcsclean stamp= fi diff --git a/build/config-stubs b/build/config-stubs index 341ac8e3d..04f4eaa19 100755 --- a/build/config-stubs +++ b/build/config-stubs @@ -1,6 +1,6 @@ #!/bin/sh # -# $Id: config-stubs,v 1.1 2003/01/28 10:59:10 sniper Exp $ +# $Id: config-stubs 242949 2007-09-26 15:44:16Z cvs2svn $ dir=$1; shift for stubfile in $dir/*/config0.m4 $dir/*/config.m4 $dir/*/config9.m4; do diff --git a/build/genif.sh b/build/genif.sh index 28d18ebb4..61d1f0045 100644 --- a/build/genif.sh +++ b/build/genif.sh @@ -1,6 +1,6 @@ #! /bin/sh -# $Id: genif.sh,v 1.6 2005/06/21 13:47:38 sniper Exp $ +# $Id: genif.sh,v 1.6 2005-06-21 13:47:38 sniper Exp $ # replacement for genif.pl infile=$1 diff --git a/build/mkdep.awk b/build/mkdep.awk index e77056c23..36238c6ca 100644 --- a/build/mkdep.awk +++ b/build/mkdep.awk @@ -14,7 +14,7 @@ # | Author: Sascha Schumann | # +----------------------------------------------------------------------+ # -# $Id: mkdep.awk,v 1.8.2.1 2006/01/01 12:50:00 sniper Exp $ +# $Id: mkdep.awk 204189 2006-01-01 12:51:34Z sniper $ # # Usage: # diff --git a/buildconf b/buildconf index 3c5d4fbcb..2d639e986 100755 --- a/buildconf +++ b/buildconf @@ -1,5 +1,5 @@ #!/bin/sh -# $Id: buildconf,v 1.64.2.1.2.1 2007/07/26 22:45:59 jani Exp $ +# $Id: buildconf 284427 2009-07-20 10:51:40Z jani $ eval `grep '^PHP_EXTRA_VERSION=' configure.in` case "$PHP_EXTRA_VERSION" in @@ -32,38 +32,11 @@ if test "$dev" = "0" -a "$devok" = "0"; then 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 if test "$debug" = "yes"; then - ${MAKE:-make} -s -f build/build.mk ZENDDIR="$ZENDDIR" SUPPRESS_WARNINGS="" + ${MAKE:-make} -s -f build/build.mk SUPPRESS_WARNINGS="" else - ${MAKE:-make} -s -f build/build.mk ZENDDIR="$ZENDDIR" + ${MAKE:-make} -s -f build/build.mk fi diff --git a/configure b/configure index 365e20ed4..2200efdfe 100755 --- a/configure +++ b/configure @@ -1117,7 +1117,7 @@ ac_help="$ac_help ac_help="$ac_help --with-curl[=DIR] Include cURL support" ac_help="$ac_help - --with-curlwrappers Use cURL for url streams" + --with-curlwrappers EXPERIMENTAL: Use cURL for url streams" ac_help="$ac_help --enable-dba Build DBA with bundled modules. To build shared DBA extension use --enable-dba=shared" @@ -2073,7 +2073,7 @@ echo > confdefs.h # A filename unique to this package, relative to the directory that # configure is in, which we can look for to find out if srcdir is correct. -ac_unique_file=README.CVS-RULES +ac_unique_file=README.SVN-RULES # Find the source files, if location was not specified. if test -z "$srcdir"; then @@ -2427,7 +2427,7 @@ echo "$ac_t""$target" 1>&6 PHP_MAJOR_VERSION=5 PHP_MINOR_VERSION=3 -PHP_RELEASE_VERSION=0 +PHP_RELEASE_VERSION=1 PHP_EXTRA_VERSION="" PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION" PHP_VERSION_ID=`expr $PHP_MAJOR_VERSION \* 10000 + $PHP_MINOR_VERSION \* 100 + $PHP_RELEASE_VERSION` @@ -2861,7 +2861,7 @@ else rm -rf conftest* SUNCC="yes" GCC="no" - test -n "$auto_cflags" && CFLAGS="-fsimple=2 -xnorunpath -xO4 -xalias_level=basic -xipo=1 -xlibmopt -xprefetch_level=1 -xprefetch=auto -xstrconst -xtarget=native -zlazyload" + test -n "$auto_cflags" && CFLAGS="-O -xs -xstrconst -zlazyload" GCC="" echo "$ac_t""yes" 1>&6 @@ -3376,7 +3376,7 @@ echo "$ac_t""$php_cv_re2c_version" 1>&6 case $php_cv_bison_version in ""|invalid) if ! test -f "$abs_srcdir/Zend/zend_language_parser.h" || ! test -f "$abs_srcdir/Zend/zend_language_parser.c" ; then - { echo "configure: error: bison is required to build PHP/Zend when building a CVS checkout!" 1>&2; exit 1; } + { echo "configure: error: bison is required to build PHP/Zend when building a SVN checkout!" 1>&2; exit 1; } fi ;; esac @@ -3463,9 +3463,7 @@ case $host_cpu in ;; sparc*) if test "$SUNCC" = "yes"; then - CFLAGS="$CFLAGS -xmemalign=8i" - else - CFLAGS="" + CFLAGS="$CFLAGS -xmemalign=8s" fi ;; esac @@ -3499,7 +3497,7 @@ case $host_alias in gcc_arg_name=ac_cv_gcc_arg_no_cpp_precomp echo $ac_n "checking whether $CC supports -no-cpp-precomp""... $ac_c" 1>&6 -echo "configure:3503: checking whether $CC supports -no-cpp-precomp" >&5 +echo "configure:3501: checking whether $CC supports -no-cpp-precomp" >&5 if eval "test \"`echo '$''{'ac_cv_gcc_arg_no_cpp_precomp'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3528,10 +3526,6 @@ echo "$ac_t""$ac_cv_gcc_arg_no_cpp_precomp" 1>&6 CPPFLAGS="$CPPFLAGS -no-cpp-precomp" fi fi - cat >> confdefs.h <<\EOF -#define BIND_8_COMPAT 1 -EOF - php_multiple_shlib_versions_ok=yes ;; *beos*) @@ -3704,7 +3698,7 @@ esac # Disable PIC mode by default where it is known to be safe to do so, # to avoid the performance hit from the lost register echo $ac_n "checking whether to force non-PIC code in shared modules""... $ac_c" 1>&6 -echo "configure:3708: checking whether to force non-PIC code in shared modules" >&5 +echo "configure:3702: checking whether to force non-PIC code in shared modules" >&5 case $host_alias in i?86-*-linux*|i?86-*-freebsd*) if test "${with_pic+set}" != "set" || test "$with_pic" = "no"; then @@ -3734,7 +3728,7 @@ esac echo $ac_n "checking whether /dev/urandom exists""... $ac_c" 1>&6 -echo "configure:3738: checking whether /dev/urandom exists" >&5 +echo "configure:3732: checking whether /dev/urandom exists" >&5 if test -r "/dev/urandom" && test -c "/dev/urandom"; then cat >> confdefs.h <<\EOF #define HAVE_DEV_URANDOM 1 @@ -3795,7 +3789,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -3813,7 +3807,7 @@ int main() { return pthread_create(&thd, NULL, thread_routine, &data); } EOF -if { (eval echo configure:3817: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3811: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then pthreads_working=yes @@ -3833,7 +3827,7 @@ fi CFLAGS=$save_CFLAGS echo $ac_n "checking for pthreads_cflags""... $ac_c" 1>&6 -echo "configure:3837: checking for pthreads_cflags" >&5 +echo "configure:3831: checking for pthreads_cflags" >&5 if eval "test \"`echo '$''{'ac_cv_pthreads_cflags'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3855,7 +3849,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -3873,7 +3867,7 @@ int main() { return pthread_create(&thd, NULL, thread_routine, &data); } EOF -if { (eval echo configure:3877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3871: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then pthreads_working=yes @@ -3903,7 +3897,7 @@ fi echo "$ac_t""$ac_cv_pthreads_cflags" 1>&6 echo $ac_n "checking for pthreads_lib""... $ac_c" 1>&6 -echo "configure:3907: checking for pthreads_lib" >&5 +echo "configure:3901: checking for pthreads_lib" >&5 if eval "test \"`echo '$''{'ac_cv_pthreads_lib'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -3925,7 +3919,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -3943,7 +3937,7 @@ int main() { return pthread_create(&thd, NULL, thread_routine, &data); } EOF -if { (eval echo configure:3947: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:3941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then pthreads_working=yes @@ -4077,7 +4071,7 @@ ext_output=$PHP_AOLSERVER echo $ac_n "checking for AOLserver support""... $ac_c" 1>&6 -echo "configure:4081: checking for AOLserver support" >&5 +echo "configure:4075: checking for AOLserver support" >&5 if test "$PHP_AOLSERVER" != "no"; then if test -d "$PHP_AOLSERVER/include"; then @@ -4334,7 +4328,7 @@ ext_output=$PHP_APXS echo $ac_n "checking for Apache 1.x module support via DSO through APXS""... $ac_c" 1>&6 -echo "configure:4338: checking for Apache 1.x module support via DSO through APXS" >&5 +echo "configure:4332: checking for Apache 1.x module support via DSO through APXS" >&5 if test "$PHP_APXS" != "no"; then if test "$PHP_APXS" = "yes"; then @@ -4657,7 +4651,7 @@ ext_output=$PHP_APACHE echo $ac_n "checking for Apache 1.x module support""... $ac_c" 1>&6 -echo "configure:4661: checking for Apache 1.x module support" >&5 +echo "configure:4655: checking for Apache 1.x module support" >&5 if test "$PHP_SAPI" != "apache" && test "$PHP_APACHE" != "no"; then @@ -5490,7 +5484,7 @@ fi php_enable_mod_charset=no echo $ac_n "checking whether to enable Apache charset compatibility option""... $ac_c" 1>&6 -echo "configure:5494: checking whether to enable Apache charset compatibility option" >&5 +echo "configure:5488: checking whether to enable Apache charset compatibility option" >&5 # Check whether --enable-mod-charset or --disable-mod-charset was given. if test "${enable_mod_charset+set}" = set; then enableval="$enable_mod_charset" @@ -5525,7 +5519,7 @@ if test "$APACHE_MODULE" = "yes"; then gcc_arg_name=ac_cv_gcc_arg_rdynamic echo $ac_n "checking whether $CC supports -rdynamic""... $ac_c" 1>&6 -echo "configure:5529: checking whether $CC supports -rdynamic" >&5 +echo "configure:5523: checking whether $CC supports -rdynamic" >&5 if eval "test \"`echo '$''{'ac_cv_gcc_arg_rdynamic'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5568,7 +5562,7 @@ if test -n "$APACHE_INSTALL"; then echo $ac_n "checking for member fd in BUFF *""... $ac_c" 1>&6 -echo "configure:5572: checking for member fd in BUFF *" >&5 +echo "configure:5566: checking for member fd in BUFF *" >&5 if eval "test \"`echo '$''{'ac_cv_php_fd_in_buff'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -5580,14 +5574,14 @@ else CPPFLAGS="$CPPFLAGS $APACHE_INCLUDE" fi cat > conftest.$ac_ext < int main() { conn_rec *c; int fd = c->client->fd; ; return 0; } EOF -if { (eval echo configure:5591: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:5585: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_php_fd_in_buff=yes @@ -5663,7 +5657,7 @@ ext_output=$PHP_APXS2FILTER echo $ac_n "checking for Apache 2.0 filter-module support via DSO through APXS""... $ac_c" 1>&6 -echo "configure:5667: checking for Apache 2.0 filter-module support via DSO through APXS" >&5 +echo "configure:5661: checking for Apache 2.0 filter-module support via DSO through APXS" >&5 if test "$PHP_APXS2FILTER" != "no"; then if test "$PHP_APXS2FILTER" = "yes"; then @@ -6511,7 +6505,7 @@ ext_output=$PHP_APXS2 echo $ac_n "checking for Apache 2.0 handler-module support via DSO through APXS""... $ac_c" 1>&6 -echo "configure:6515: checking for Apache 2.0 handler-module support via DSO through APXS" >&5 +echo "configure:6509: checking for Apache 2.0 handler-module support via DSO through APXS" >&5 if test "$PHP_APXS2" != "no"; then if test "$PHP_APXS2" = "yes"; then @@ -7360,7 +7354,7 @@ ext_output=$PHP_APACHE_HOOKS echo $ac_n "checking for Apache 1.x (hooks) module support via DSO through APXS""... $ac_c" 1>&6 -echo "configure:7364: checking for Apache 1.x (hooks) module support via DSO through APXS" >&5 +echo "configure:7358: checking for Apache 1.x (hooks) module support via DSO through APXS" >&5 if test "$PHP_APACHE_HOOKS" != "no"; then if test "$PHP_APACHE_HOOKS" = "yes"; then @@ -7683,7 +7677,7 @@ ext_output=$PHP_APACHE_HOOKS_STATIC echo $ac_n "checking for Apache 1.x (hooks) module support""... $ac_c" 1>&6 -echo "configure:7687: checking for Apache 1.x (hooks) module support" >&5 +echo "configure:7681: checking for Apache 1.x (hooks) module support" >&5 if test "$PHP_SAPI" != "apache" && test "$PHP_SAPI" != "apache_hooks" && test "$PHP_APACHE_HOOKS_STATIC" != "no"; then @@ -8516,7 +8510,7 @@ fi php_enable_mod_charset=no echo $ac_n "checking whether to enable Apache charset compatibility option""... $ac_c" 1>&6 -echo "configure:8520: checking whether to enable Apache charset compatibility option" >&5 +echo "configure:8514: checking whether to enable Apache charset compatibility option" >&5 # Check whether --enable-mod-charset or --disable-mod-charset was given. if test "${enable_mod_charset+set}" = set; then enableval="$enable_mod_charset" @@ -8551,7 +8545,7 @@ if test "$APACHE_HOOKS_MODULE" = "yes"; then gcc_arg_name=ac_cv_gcc_arg_rdynamic echo $ac_n "checking whether $CC supports -rdynamic""... $ac_c" 1>&6 -echo "configure:8555: checking whether $CC supports -rdynamic" >&5 +echo "configure:8549: checking whether $CC supports -rdynamic" >&5 if eval "test \"`echo '$''{'ac_cv_gcc_arg_rdynamic'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8594,7 +8588,7 @@ if test -n "$APACHE_HOOKS_INSTALL"; then echo $ac_n "checking for member fd in BUFF *""... $ac_c" 1>&6 -echo "configure:8598: checking for member fd in BUFF *" >&5 +echo "configure:8592: checking for member fd in BUFF *" >&5 if eval "test \"`echo '$''{'ac_cv_php_fd_in_buff'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -8606,14 +8600,14 @@ else CPPFLAGS="$CPPFLAGS $APACHE_INCLUDE" fi cat > conftest.$ac_ext < int main() { conn_rec *c; int fd = c->client->fd; ; return 0; } EOF -if { (eval echo configure:8617: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:8611: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_php_fd_in_buff=yes @@ -8690,7 +8684,7 @@ ext_output=$PHP_CAUDIUM echo $ac_n "checking for Caudium support""... $ac_c" 1>&6 -echo "configure:8694: checking for Caudium support" >&5 +echo "configure:8688: checking for Caudium support" >&5 if test "$PHP_CAUDIUM" != "no"; then if test "$prefix" = "NONE"; then CPREF=/usr/local/; fi @@ -8760,7 +8754,7 @@ if test "$PHP_CAUDIUM" != "no"; then PIKE_C_INCLUDE=/usr/local/include/`basename $PIKE` fi echo $ac_n "checking for C includes in $PIKE_C_INCLUDE""... $ac_c" 1>&6 -echo "configure:8764: checking for C includes in $PIKE_C_INCLUDE" >&5 +echo "configure:8758: checking for C includes in $PIKE_C_INCLUDE" >&5 if test -f $PIKE_C_INCLUDE/version.h; then PIKE_TEST_VER=`$PIKE -e 'string v; int rel;sscanf(version(), "Pike v%s release %d", v, rel); write(v+"."+rel);'` ###### VERSION MATCH CHECK ####### @@ -9041,7 +9035,7 @@ ext_output=$PHP_CLI echo $ac_n "checking for CLI build""... $ac_c" 1>&6 -echo "configure:9045: checking for CLI build" >&5 +echo "configure:9039: checking for CLI build" >&5 if test "$PHP_CLI" != "no"; then src=$abs_srcdir/sapi/cli/Makefile.frag @@ -9091,7 +9085,7 @@ echo "$ac_t""$PHP_CLI" 1>&6 php_with_continuity=no echo $ac_n "checking for Continuity support""... $ac_c" 1>&6 -echo "configure:9095: checking for Continuity support" >&5 +echo "configure:9089: checking for Continuity support" >&5 # Check whether --with-continuity or --without-continuity was given. if test "${with_continuity+set}" = set; then withval="$with_continuity" @@ -9118,7 +9112,7 @@ if test "$PHP_CONTINUITY" != "no"; then { echo "configure: error: Please specify the path to the root of your Continuity server using --with-continuity=DIR" 1>&2; exit 1; } fi echo $ac_n "checking for Continuity include files""... $ac_c" 1>&6 -echo "configure:9122: checking for Continuity include files" >&5 +echo "configure:9116: checking for Continuity include files" >&5 if test -d $PHP_CONTINUITY/include ; then CAPI_INCLUDE=$PHP_CONTINUITY/include echo "$ac_t""Continuity Binary Distribution" 1>&6 @@ -9368,7 +9362,7 @@ ext_output=$PHP_EMBED echo $ac_n "checking for embedded SAPI library support""... $ac_c" 1>&6 -echo "configure:9372: checking for embedded SAPI library support" >&5 +echo "configure:9366: checking for embedded SAPI library support" >&5 if test "$PHP_EMBED" != "no"; then case "$PHP_EMBED" in @@ -9585,7 +9579,7 @@ fi php_with_isapi=no echo $ac_n "checking for Zeus ISAPI support""... $ac_c" 1>&6 -echo "configure:9589: checking for Zeus ISAPI support" >&5 +echo "configure:9583: checking for Zeus ISAPI support" >&5 # Check whether --with-isapi or --without-isapi was given. if test "${with_isapi+set}" = set; then withval="$with_isapi" @@ -9831,7 +9825,7 @@ fi echo $ac_n "checking for LiteSpeed support""... $ac_c" 1>&6 -echo "configure:9835: checking for LiteSpeed support" >&5 +echo "configure:9829: checking for LiteSpeed support" >&5 php_with_litespeed=no @@ -10085,7 +10079,7 @@ echo "$ac_t""$PHP_LITESPEED" 1>&6 php_with_milter=no echo $ac_n "checking for Milter support""... $ac_c" 1>&6 -echo "configure:10089: checking for Milter support" >&5 +echo "configure:10083: checking for Milter support" >&5 # Check whether --with-milter or --without-milter was given. if test "${with_milter+set}" = set; then withval="$with_milter" @@ -10369,7 +10363,7 @@ fi php_with_nsapi=no echo $ac_n "checking for NSAPI support""... $ac_c" 1>&6 -echo "configure:10373: checking for NSAPI support" >&5 +echo "configure:10367: checking for NSAPI support" >&5 # Check whether --with-nsapi or --without-nsapi was given. if test "${with_nsapi+set}" = set; then withval="$with_nsapi" @@ -10396,7 +10390,7 @@ if test "$PHP_NSAPI" != "no"; then { echo "configure: error: Please specify the path to the root of your Netscape/iPlanet/Sun Webserver using --with-nsapi=DIR" 1>&2; exit 1; } fi echo $ac_n "checking for NSAPI include files""... $ac_c" 1>&6 -echo "configure:10400: checking for NSAPI include files" >&5 +echo "configure:10394: checking for NSAPI include files" >&5 if test -d $PHP_NSAPI/include ; then NSAPI_INC_DIR="$PHP_NSAPI/include" echo "$ac_t""Netscape 3.x / Sun 7.x style" 1>&6 @@ -10404,17 +10398,17 @@ echo "configure:10400: checking for NSAPI include files" >&5 do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:10408: checking for $ac_hdr" >&5 +echo "configure:10402: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:10418: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:10412: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -10449,17 +10443,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:10453: checking for $ac_hdr" >&5 +echo "configure:10447: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:10463: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:10457: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -10721,7 +10715,7 @@ fi php_with_phttpd=no echo $ac_n "checking for PHTTPD support""... $ac_c" 1>&6 -echo "configure:10725: checking for PHTTPD support" >&5 +echo "configure:10719: checking for PHTTPD support" >&5 # Check whether --with-phttpd or --without-phttpd was given. if test "${with_phttpd+set}" = set; then withval="$with_phttpd" @@ -10967,7 +10961,7 @@ fi php_with_pi3web=no echo $ac_n "checking for Pi3Web support""... $ac_c" 1>&6 -echo "configure:10971: checking for Pi3Web support" >&5 +echo "configure:10965: checking for Pi3Web support" >&5 # Check whether --with-pi3web or --without-pi3web was given. if test "${with_pi3web+set}" = set; then withval="$with_pi3web" @@ -11334,7 +11328,7 @@ ext_output=$PHP_ROXEN php_enable_roxen_zts=no echo $ac_n "checking whether Roxen module is build using ZTS""... $ac_c" 1>&6 -echo "configure:11338: checking whether Roxen module is build using ZTS" >&5 +echo "configure:11332: checking whether Roxen module is build using ZTS" >&5 # Check whether --enable-roxen-zts or --disable-roxen-zts was given. if test "${enable_roxen_zts+set}" = set; then enableval="$enable_roxen_zts" @@ -11358,7 +11352,7 @@ echo "$ac_t""$ext_output" 1>&6 RESULT= echo $ac_n "checking for Roxen/Pike support""... $ac_c" 1>&6 -echo "configure:11362: checking for Roxen/Pike support" >&5 +echo "configure:11356: checking for Roxen/Pike support" >&5 if test "$PHP_ROXEN" != "no"; then if test ! -d $PHP_ROXEN ; then { echo "configure: error: You did not specify a directory" 1>&2; exit 1; } @@ -11636,7 +11630,7 @@ ext_output=$PHP_THTTPD echo $ac_n "checking for thttpd""... $ac_c" 1>&6 -echo "configure:11640: checking for thttpd" >&5 +echo "configure:11634: checking for thttpd" >&5 if test "$PHP_THTTPD" != "no"; then if test ! -d $PHP_THTTPD; then @@ -11669,7 +11663,7 @@ if test "$PHP_THTTPD" != "no"; then gcc_arg_name=ac_cv_gcc_arg_rdynamic echo $ac_n "checking whether $CC supports -rdynamic""... $ac_c" 1>&6 -echo "configure:11673: checking whether $CC supports -rdynamic" >&5 +echo "configure:11667: checking whether $CC supports -rdynamic" >&5 if eval "test \"`echo '$''{'ac_cv_gcc_arg_rdynamic'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -11897,24 +11891,24 @@ ext_output=$PHP_TUX echo $ac_n "checking for TUX""... $ac_c" 1>&6 -echo "configure:11901: checking for TUX" >&5 +echo "configure:11895: checking for TUX" >&5 if test "$PHP_TUX" != "no"; then INSTALL_IT="\$(INSTALL) -m 0755 $SAPI_SHARED $PHP_TUX/php5.tux.so" for ac_hdr in tuxmodule.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:11908: checking for $ac_hdr" >&5 +echo "configure:11902: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:11918: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:11912: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -12143,7 +12137,7 @@ ext_output=$PHP_WEBJAMES echo $ac_n "checking for webjames""... $ac_c" 1>&6 -echo "configure:12147: checking for webjames" >&5 +echo "configure:12141: checking for webjames" >&5 if test "$PHP_WEBJAMES" != "no"; then @@ -12395,14 +12389,14 @@ ext_output=$PHP_CGI if test "$PHP_SAPI" = "default"; then echo $ac_n "checking whether to build CGI binary""... $ac_c" 1>&6 -echo "configure:12399: checking whether to build CGI binary" >&5 +echo "configure:12393: checking whether to build CGI binary" >&5 if test "$PHP_CGI" != "no"; then echo "$ac_t""yes" 1>&6 echo $ac_n "checking for socklen_t in sys/socket.h""... $ac_c" 1>&6 -echo "configure:12404: checking for socklen_t in sys/socket.h" >&5 +echo "configure:12398: checking for socklen_t in sys/socket.h" >&5 cat > conftest.$ac_ext < EOF @@ -12422,9 +12416,9 @@ rm -f conftest* echo $ac_n "checking for sun_len in sys/un.h""... $ac_c" 1>&6 -echo "configure:12426: checking for sun_len in sys/un.h" >&5 +echo "configure:12420: checking for sun_len in sys/un.h" >&5 cat > conftest.$ac_ext < EOF @@ -12444,7 +12438,7 @@ rm -f conftest* echo $ac_n "checking whether cross-process locking is required by accept()""... $ac_c" 1>&6 -echo "configure:12448: checking whether cross-process locking is required by accept()" >&5 +echo "configure:12442: checking whether cross-process locking is required by accept()" >&5 case "`uname -sr`" in IRIX\ 5.* | SunOS\ 5.* | UNIX_System_V\ 4.0) echo "$ac_t""yes" 1>&6 @@ -12677,7 +12671,7 @@ fi echo $ac_n "checking for chosen SAPI module""... $ac_c" 1>&6 -echo "configure:12681: checking for chosen SAPI module" >&5 +echo "configure:12675: checking for chosen SAPI module" >&5 echo "$ac_t""$PHP_SAPI" 1>&6 if test "$enable_maintainer_zts" = "yes"; then @@ -12734,7 +12728,7 @@ fi # Extract the first word of "sendmail", so it can be a program name with args. set dummy sendmail; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:12738: checking for $ac_word" >&5 +echo "configure:12732: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_PROG_SENDMAIL'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -12773,7 +12767,7 @@ fi echo $ac_n "checking whether system uses EBCDIC""... $ac_c" 1>&6 -echo "configure:12777: checking whether system uses EBCDIC" >&5 +echo "configure:12771: checking whether system uses EBCDIC" >&5 if eval "test \"`echo '$''{'ac_cv_ebcdic'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -12784,7 +12778,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:12790: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_ebcdic=yes @@ -12820,7 +12814,7 @@ EOF echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 -echo "configure:12824: checking whether byte ordering is bigendian" >&5 +echo "configure:12818: checking whether byte ordering is bigendian" >&5 if eval "test \"`echo '$''{'ac_cv_c_bigendian_php'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -12830,7 +12824,7 @@ else ac_cv_c_bigendian_php=unknown else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:12844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_bigendian_php=yes else @@ -12872,7 +12866,7 @@ EOF echo $ac_n "checking whether writing to stdout works""... $ac_c" 1>&6 -echo "configure:12876: checking whether writing to stdout works" >&5 +echo "configure:12870: checking whether writing to stdout works" >&5 if eval "test \"`echo '$''{'ac_cv_write_stdout'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -12883,7 +12877,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:12899: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_write_stdout=yes @@ -12976,12 +12970,12 @@ test -d /usr/ucblib && unset found echo $ac_n "checking for socket""... $ac_c" 1>&6 -echo "configure:12980: checking for socket" >&5 +echo "configure:12974: checking for socket" >&5 if eval "test \"`echo '$''{'ac_cv_func_socket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13002: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_socket=yes" else @@ -13022,12 +13016,12 @@ if eval "test \"`echo '$ac_cv_func_'socket`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __socket""... $ac_c" 1>&6 -echo "configure:13026: checking for __socket" >&5 +echo "configure:13020: checking for __socket" >&5 if eval "test \"`echo '$''{'ac_cv_func___socket'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13048: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func___socket=yes" else @@ -13088,7 +13082,7 @@ EOF unset ac_cv_lib_socket___socket unset found echo $ac_n "checking for socket in -lsocket""... $ac_c" 1>&6 -echo "configure:13092: checking for socket in -lsocket" >&5 +echo "configure:13086: checking for socket in -lsocket" >&5 ac_lib_var=`echo socket'_'socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13096,7 +13090,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13105: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13127,7 +13121,7 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __socket in -lsocket""... $ac_c" 1>&6 -echo "configure:13131: checking for __socket in -lsocket" >&5 +echo "configure:13125: checking for __socket in -lsocket" >&5 ac_lib_var=`echo socket'_'__socket | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13135,7 +13129,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13178,11 +13172,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:13180: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -13233,12 +13227,12 @@ EOF unset found echo $ac_n "checking for socketpair""... $ac_c" 1>&6 -echo "configure:13237: checking for socketpair" >&5 +echo "configure:13231: checking for socketpair" >&5 if eval "test \"`echo '$''{'ac_cv_func_socketpair'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13259: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_socketpair=yes" else @@ -13279,12 +13273,12 @@ if eval "test \"`echo '$ac_cv_func_'socketpair`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __socketpair""... $ac_c" 1>&6 -echo "configure:13283: checking for __socketpair" >&5 +echo "configure:13277: checking for __socketpair" >&5 if eval "test \"`echo '$''{'ac_cv_func___socketpair'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13305: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func___socketpair=yes" else @@ -13345,7 +13339,7 @@ EOF unset ac_cv_lib_socket___socketpair unset found echo $ac_n "checking for socketpair in -lsocket""... $ac_c" 1>&6 -echo "configure:13349: checking for socketpair in -lsocket" >&5 +echo "configure:13343: checking for socketpair in -lsocket" >&5 ac_lib_var=`echo socket'_'socketpair | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13353,7 +13347,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13362: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13384,7 +13378,7 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __socketpair in -lsocket""... $ac_c" 1>&6 -echo "configure:13388: checking for __socketpair in -lsocket" >&5 +echo "configure:13382: checking for __socketpair in -lsocket" >&5 ac_lib_var=`echo socket'_'__socketpair | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13392,7 +13386,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13401: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13435,11 +13429,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:13437: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -13490,12 +13484,12 @@ EOF unset found echo $ac_n "checking for htonl""... $ac_c" 1>&6 -echo "configure:13494: checking for htonl" >&5 +echo "configure:13488: checking for htonl" >&5 if eval "test \"`echo '$''{'ac_cv_func_htonl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13516: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_htonl=yes" else @@ -13536,12 +13530,12 @@ if eval "test \"`echo '$ac_cv_func_'htonl`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __htonl""... $ac_c" 1>&6 -echo "configure:13540: checking for __htonl" >&5 +echo "configure:13534: checking for __htonl" >&5 if eval "test \"`echo '$''{'ac_cv_func___htonl'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13562: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func___htonl=yes" else @@ -13602,7 +13596,7 @@ EOF unset ac_cv_lib_socket___htonl unset found echo $ac_n "checking for htonl in -lsocket""... $ac_c" 1>&6 -echo "configure:13606: checking for htonl in -lsocket" >&5 +echo "configure:13600: checking for htonl in -lsocket" >&5 ac_lib_var=`echo socket'_'htonl | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13610,7 +13604,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13619: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13641,7 +13635,7 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __htonl in -lsocket""... $ac_c" 1>&6 -echo "configure:13645: checking for __htonl in -lsocket" >&5 +echo "configure:13639: checking for __htonl in -lsocket" >&5 ac_lib_var=`echo socket'_'__htonl | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13649,7 +13643,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13658: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13692,11 +13686,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:13694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -13747,12 +13741,12 @@ EOF unset found echo $ac_n "checking for gethostname""... $ac_c" 1>&6 -echo "configure:13751: checking for gethostname" >&5 +echo "configure:13745: checking for gethostname" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostname=yes" else @@ -13793,12 +13787,12 @@ if eval "test \"`echo '$ac_cv_func_'gethostname`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __gethostname""... $ac_c" 1>&6 -echo "configure:13797: checking for __gethostname" >&5 +echo "configure:13791: checking for __gethostname" >&5 if eval "test \"`echo '$''{'ac_cv_func___gethostname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13819: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func___gethostname=yes" else @@ -13859,7 +13853,7 @@ EOF unset ac_cv_lib_nsl___gethostname unset found echo $ac_n "checking for gethostname in -lnsl""... $ac_c" 1>&6 -echo "configure:13863: checking for gethostname in -lnsl" >&5 +echo "configure:13857: checking for gethostname in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13867,7 +13861,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13876: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13898,7 +13892,7 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __gethostname in -lnsl""... $ac_c" 1>&6 -echo "configure:13902: checking for __gethostname in -lnsl" >&5 +echo "configure:13896: checking for __gethostname in -lnsl" >&5 ac_lib_var=`echo nsl'_'__gethostname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -13906,7 +13900,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:13915: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -13949,11 +13943,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:13951: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -14004,12 +13998,12 @@ EOF unset found echo $ac_n "checking for gethostbyaddr""... $ac_c" 1>&6 -echo "configure:14008: checking for gethostbyaddr" >&5 +echo "configure:14002: checking for gethostbyaddr" >&5 if eval "test \"`echo '$''{'ac_cv_func_gethostbyaddr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14030: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_gethostbyaddr=yes" else @@ -14050,12 +14044,12 @@ if eval "test \"`echo '$ac_cv_func_'gethostbyaddr`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __gethostbyaddr""... $ac_c" 1>&6 -echo "configure:14054: checking for __gethostbyaddr" >&5 +echo "configure:14048: checking for __gethostbyaddr" >&5 if eval "test \"`echo '$''{'ac_cv_func___gethostbyaddr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14076: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func___gethostbyaddr=yes" else @@ -14116,7 +14110,7 @@ EOF unset ac_cv_lib_nsl___gethostbyaddr unset found echo $ac_n "checking for gethostbyaddr in -lnsl""... $ac_c" 1>&6 -echo "configure:14120: checking for gethostbyaddr in -lnsl" >&5 +echo "configure:14114: checking for gethostbyaddr in -lnsl" >&5 ac_lib_var=`echo nsl'_'gethostbyaddr | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -14124,7 +14118,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14133: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14155,7 +14149,7 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __gethostbyaddr in -lnsl""... $ac_c" 1>&6 -echo "configure:14159: checking for __gethostbyaddr in -lnsl" >&5 +echo "configure:14153: checking for __gethostbyaddr in -lnsl" >&5 ac_lib_var=`echo nsl'_'__gethostbyaddr | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -14163,7 +14157,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14172: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14206,11 +14200,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:14208: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -14261,12 +14255,12 @@ EOF unset found echo $ac_n "checking for yp_get_default_domain""... $ac_c" 1>&6 -echo "configure:14265: checking for yp_get_default_domain" >&5 +echo "configure:14259: checking for yp_get_default_domain" >&5 if eval "test \"`echo '$''{'ac_cv_func_yp_get_default_domain'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14287: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_yp_get_default_domain=yes" else @@ -14307,12 +14301,12 @@ if eval "test \"`echo '$ac_cv_func_'yp_get_default_domain`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __yp_get_default_domain""... $ac_c" 1>&6 -echo "configure:14311: checking for __yp_get_default_domain" >&5 +echo "configure:14305: checking for __yp_get_default_domain" >&5 if eval "test \"`echo '$''{'ac_cv_func___yp_get_default_domain'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14333: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func___yp_get_default_domain=yes" else @@ -14373,7 +14367,7 @@ EOF unset ac_cv_lib_nsl___yp_get_default_domain unset found echo $ac_n "checking for yp_get_default_domain in -lnsl""... $ac_c" 1>&6 -echo "configure:14377: checking for yp_get_default_domain in -lnsl" >&5 +echo "configure:14371: checking for yp_get_default_domain in -lnsl" >&5 ac_lib_var=`echo nsl'_'yp_get_default_domain | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -14381,7 +14375,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14390: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14412,7 +14406,7 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __yp_get_default_domain in -lnsl""... $ac_c" 1>&6 -echo "configure:14416: checking for __yp_get_default_domain in -lnsl" >&5 +echo "configure:14410: checking for __yp_get_default_domain in -lnsl" >&5 ac_lib_var=`echo nsl'_'__yp_get_default_domain | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -14420,7 +14414,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lnsl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14429: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14463,11 +14457,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:14465: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -14519,12 +14513,12 @@ EOF unset found echo $ac_n "checking for dlopen""... $ac_c" 1>&6 -echo "configure:14523: checking for dlopen" >&5 +echo "configure:14517: checking for dlopen" >&5 if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14545: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_dlopen=yes" else @@ -14565,12 +14559,12 @@ if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __dlopen""... $ac_c" 1>&6 -echo "configure:14569: checking for __dlopen" >&5 +echo "configure:14563: checking for __dlopen" >&5 if eval "test \"`echo '$''{'ac_cv_func___dlopen'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14591: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func___dlopen=yes" else @@ -14631,7 +14625,7 @@ EOF unset ac_cv_lib_dl___dlopen unset found echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:14635: checking for dlopen in -ldl" >&5 +echo "configure:14629: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -14639,7 +14633,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14670,7 +14664,7 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:14674: checking for __dlopen in -ldl" >&5 +echo "configure:14668: checking for __dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'__dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -14678,7 +14672,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14687: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14721,11 +14715,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:14723: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -14777,7 +14771,7 @@ EOF fi echo $ac_n "checking for sin in -lm""... $ac_c" 1>&6 -echo "configure:14781: checking for sin in -lm" >&5 +echo "configure:14775: checking for sin in -lm" >&5 ac_lib_var=`echo m'_'sin | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -14785,7 +14779,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14794: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14830,12 +14824,12 @@ fi unset found echo $ac_n "checking for inet_aton""... $ac_c" 1>&6 -echo "configure:14834: checking for inet_aton" >&5 +echo "configure:14828: checking for inet_aton" >&5 if eval "test \"`echo '$''{'ac_cv_func_inet_aton'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14856: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_inet_aton=yes" else @@ -14876,12 +14870,12 @@ if eval "test \"`echo '$ac_cv_func_'inet_aton`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __inet_aton""... $ac_c" 1>&6 -echo "configure:14880: checking for __inet_aton" >&5 +echo "configure:14874: checking for __inet_aton" >&5 if eval "test \"`echo '$''{'ac_cv_func___inet_aton'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14902: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func___inet_aton=yes" else @@ -14942,7 +14936,7 @@ EOF unset ac_cv_lib_resolv___inet_aton unset found echo $ac_n "checking for inet_aton in -lresolv""... $ac_c" 1>&6 -echo "configure:14946: checking for inet_aton in -lresolv" >&5 +echo "configure:14940: checking for inet_aton in -lresolv" >&5 ac_lib_var=`echo resolv'_'inet_aton | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -14950,7 +14944,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -14981,7 +14975,7 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __inet_aton in -lresolv""... $ac_c" 1>&6 -echo "configure:14985: checking for __inet_aton in -lresolv" >&5 +echo "configure:14979: checking for __inet_aton in -lresolv" >&5 ac_lib_var=`echo resolv'_'__inet_aton | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -14989,7 +14983,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:14998: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -15032,11 +15026,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:15034: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -15078,7 +15072,7 @@ EOF unset ac_cv_lib_bind___inet_aton unset found echo $ac_n "checking for inet_aton in -lbind""... $ac_c" 1>&6 -echo "configure:15082: checking for inet_aton in -lbind" >&5 +echo "configure:15076: checking for inet_aton in -lbind" >&5 ac_lib_var=`echo bind'_'inet_aton | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -15086,7 +15080,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15095: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -15117,7 +15111,7 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for __inet_aton in -lbind""... $ac_c" 1>&6 -echo "configure:15121: checking for __inet_aton in -lbind" >&5 +echo "configure:15115: checking for __inet_aton in -lbind" >&5 ac_lib_var=`echo bind'_'__inet_aton | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -15125,7 +15119,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15134: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -15168,11 +15162,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:15170: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -15222,14 +15216,271 @@ EOF + unset ac_cv_func_nanosleep + unset ac_cv_func___nanosleep + unset found + + echo $ac_n "checking for nanosleep""... $ac_c" 1>&6 +echo "configure:15225: checking for nanosleep" >&5 +if eval "test \"`echo '$''{'ac_cv_func_nanosleep'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char nanosleep(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub_nanosleep) || defined (__stub___nanosleep) +choke me +#else +nanosleep(); +#endif + +; return 0; } +EOF +if { (eval echo configure:15253: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func_nanosleep=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func_nanosleep=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'nanosleep`\" = yes"; then + echo "$ac_t""yes" 1>&6 + found=yes +else + echo "$ac_t""no" 1>&6 + echo $ac_n "checking for __nanosleep""... $ac_c" 1>&6 +echo "configure:15271: checking for __nanosleep" >&5 +if eval "test \"`echo '$''{'ac_cv_func___nanosleep'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext < +/* Override any gcc2 internal prototype to avoid an error. */ +/* We use char because int might match the return type of a gcc2 + builtin and then its argument prototype would still apply. */ +char __nanosleep(); + +int main() { + +/* The GNU C library defines this for functions which it implements + to always fail with ENOSYS. Some functions are actually named + something starting with __ and the normal name is an alias. */ +#if defined (__stub___nanosleep) || defined (__stub_____nanosleep) +choke me +#else +__nanosleep(); +#endif + +; return 0; } +EOF +if { (eval echo configure:15299: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_func___nanosleep=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_func___nanosleep=no" +fi +rm -f conftest* +fi + +if eval "test \"`echo '$ac_cv_func_'__nanosleep`\" = yes"; then + echo "$ac_t""yes" 1>&6 + found=yes +else + echo "$ac_t""no" 1>&6 +found=no +fi + +fi + + + case $found in + yes) + cat >> confdefs.h <<\EOF +#define HAVE_NANOSLEEP 1 +EOF + + ac_cv_func_nanosleep=yes + ;; + + *) + + unset ac_cv_lib_rt_nanosleep + unset ac_cv_lib_rt___nanosleep + unset found + echo $ac_n "checking for nanosleep in -lrt""... $ac_c" 1>&6 +echo "configure:15337: checking for nanosleep in -lrt" >&5 +ac_lib_var=`echo rt'_'nanosleep | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lrt $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + found=yes +else + echo "$ac_t""no" 1>&6 + + echo $ac_n "checking for __nanosleep in -lrt""... $ac_c" 1>&6 +echo "configure:15376: checking for __nanosleep in -lrt" >&5 +ac_lib_var=`echo rt'_'__nanosleep | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lrt $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + found=yes +else + echo "$ac_t""no" 1>&6 +found=no +fi + + +fi + + + if test "$found" = "yes"; then + ac_libs=$LIBS + LIBS="$LIBS -lrt" + if test "$cross_compiling" = yes; then + found=no +else + cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + found=yes +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + found=no +fi +rm -fr conftest* +fi + + LIBS=$ac_libs + fi + + if test "$found" = "yes"; then + + + case rt in + c|c_r|pthread*) ;; + *) + LIBS="-lrt $LIBS" + ;; + esac + + + cat >> confdefs.h <<\EOF +#define HAVE_NANOSLEEP 1 +EOF + + cat >> confdefs.h <<\EOF +#define HAVE_LIBRT 1 +EOF + + ac_cv_func_nanosleep=yes + else + + : + + fi + + ;; + + esac + + echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:15228: checking for ANSI C header files" >&5 +echo "configure:15479: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -15237,7 +15488,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:15241: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:15492: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -15254,7 +15505,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -15272,7 +15523,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -15293,7 +15544,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -15304,7 +15555,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:15308: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:15559: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -15332,12 +15583,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 -echo "configure:15336: checking for $ac_hdr that defines DIR" >&5 +echo "configure:15587: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> @@ -15345,7 +15596,7 @@ int main() { DIR *dirp = 0; ; return 0; } EOF -if { (eval echo configure:15349: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:15600: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else @@ -15370,7 +15621,7 @@ done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 -echo "configure:15374: checking for opendir in -ldir" >&5 +echo "configure:15625: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -15378,7 +15629,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15644: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -15411,7 +15662,7 @@ fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 -echo "configure:15415: checking for opendir in -lx" >&5 +echo "configure:15666: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -15419,7 +15670,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15685: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -15464,9 +15715,11 @@ sys/time.h \ netinet/in.h \ alloca.h \ arpa/inet.h \ +arpa/nameser_compat.h \ arpa/nameser.h \ assert.h \ crypt.h \ +dns.h \ fcntl.h \ grp.h \ ieeefp.h \ @@ -15511,62 +15764,17 @@ assert.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:15515: checking for $ac_hdr" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:15525: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - cat >> confdefs.h <&6 -fi -done - - -case $host_alias in - *darwin[89]*) - ;; - *) - for ac_hdr in mach-o/dyld.h -do -ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:15560: checking for $ac_hdr" >&5 +echo "configure:15768: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:15570: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:15778: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -15592,17 +15800,15 @@ else fi done - ;; -esac echo $ac_n "checking for fopencookie""... $ac_c" 1>&6 -echo "configure:15601: checking for fopencookie" >&5 +echo "configure:15807: checking for fopencookie" >&5 if eval "test \"`echo '$''{'ac_cv_func_fopencookie'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:15835: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_fopencookie=yes" else @@ -15647,7 +15853,7 @@ fi if test "$have_glibc_fopencookie" = "yes"; then cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:15867: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* have_cookie_io_functions_t=yes else @@ -15676,7 +15882,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:15918: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then cookie_io_functions_use_off64_t=yes @@ -15728,7 +15934,7 @@ fi else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:15948: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* have_IO_cookie_io_functions_t=yes else @@ -15772,7 +15978,7 @@ EOF echo $ac_n "checking for broken getcwd""... $ac_c" 1>&6 -echo "configure:15776: checking for broken getcwd" >&5 +echo "configure:15982: checking for broken getcwd" >&5 os=`uname -sr 2>/dev/null` case $os in SunOS*) @@ -15787,14 +15993,14 @@ EOF echo $ac_n "checking for broken libc stdio""... $ac_c" 1>&6 -echo "configure:15791: checking for broken libc stdio" >&5 +echo "configure:15997: checking for broken libc stdio" >&5 if eval "test \"`echo '$''{'have_broken_glibc_fopen_append'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then cat > conftest.$ac_ext < @@ -15807,7 +16013,7 @@ choke me ; return 0; } EOF -if { (eval echo configure:15811: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16017: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* have_broken_glibc_fopen_append=yes else @@ -15820,7 +16026,7 @@ rm -f conftest* else cat > conftest.$ac_ext < @@ -15848,7 +16054,7 @@ int main(int argc, char *argv[]) } EOF -if { (eval echo configure:15852: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:16058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then have_broken_glibc_fopen_append=no else @@ -15876,12 +16082,12 @@ EOF echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6 -echo "configure:15880: checking whether struct tm is in sys/time.h or time.h" >&5 +echo "configure:16086: checking whether struct tm is in sys/time.h or time.h" >&5 if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -15889,7 +16095,7 @@ int main() { struct tm *tp; tp->tm_sec; ; return 0; } EOF -if { (eval echo configure:15893: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16099: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_tm=time.h else @@ -15910,12 +16116,12 @@ EOF fi echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6 -echo "configure:15914: checking for tm_zone in struct tm" >&5 +echo "configure:16120: checking for tm_zone in struct tm" >&5 if eval "test \"`echo '$''{'ac_cv_struct_tm_zone'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_cv_struct_tm> @@ -15923,7 +16129,7 @@ int main() { struct tm tm; tm.tm_zone; ; return 0; } EOF -if { (eval echo configure:15927: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16133: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_tm_zone=yes else @@ -15943,12 +16149,12 @@ EOF else echo $ac_n "checking for tzname""... $ac_c" 1>&6 -echo "configure:15947: checking for tzname" >&5 +echo "configure:16153: checking for tzname" >&5 if eval "test \"`echo '$''{'ac_cv_var_tzname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #ifndef tzname /* For SGI. */ @@ -15958,7 +16164,7 @@ int main() { atoi(*tzname); ; return 0; } EOF -if { (eval echo configure:15962: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:16168: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_var_tzname=yes else @@ -15982,16 +16188,16 @@ fi echo $ac_n "checking for missing declarations of reentrant functions""... $ac_c" 1>&6 -echo "configure:15986: checking for missing declarations of reentrant functions" >&5 +echo "configure:16192: checking for missing declarations of reentrant functions" >&5 cat > conftest.$ac_ext < int main() { struct tm *(*func)() = localtime_r ; return 0; } EOF -if { (eval echo configure:15995: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16201: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* : @@ -16009,14 +16215,14 @@ EOF fi rm -f conftest* cat > conftest.$ac_ext < int main() { struct tm *(*func)() = gmtime_r ; return 0; } EOF -if { (eval echo configure:16020: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16226: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* : @@ -16034,14 +16240,14 @@ EOF fi rm -f conftest* cat > conftest.$ac_ext < int main() { char *(*func)() = asctime_r ; return 0; } EOF -if { (eval echo configure:16045: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16251: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* : @@ -16059,14 +16265,14 @@ EOF fi rm -f conftest* cat > conftest.$ac_ext < int main() { char *(*func)() = ctime_r ; return 0; } EOF -if { (eval echo configure:16070: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16276: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* : @@ -16084,14 +16290,14 @@ EOF fi rm -f conftest* cat > conftest.$ac_ext < int main() { char *(*func)() = strtok_r ; return 0; } EOF -if { (eval echo configure:16095: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16301: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* : @@ -16112,16 +16318,16 @@ rm -f conftest* echo $ac_n "checking for fclose declaration""... $ac_c" 1>&6 -echo "configure:16116: checking for fclose declaration" >&5 +echo "configure:16322: checking for fclose declaration" >&5 cat > conftest.$ac_ext < int main() { int (*func)() = fclose ; return 0; } EOF -if { (eval echo configure:16125: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16331: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF @@ -16147,12 +16353,12 @@ rm -f conftest* echo $ac_n "checking for tm_gmtoff in struct tm""... $ac_c" 1>&6 -echo "configure:16151: checking for tm_gmtoff in struct tm" >&5 +echo "configure:16357: checking for tm_gmtoff in struct tm" >&5 if eval "test \"`echo '$''{'ac_cv_struct_tm_gmtoff'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_cv_struct_tm> @@ -16160,7 +16366,7 @@ int main() { struct tm tm; tm.tm_gmtoff; ; return 0; } EOF -if { (eval echo configure:16164: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16370: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_tm_gmtoff=yes else @@ -16183,12 +16389,12 @@ fi echo $ac_n "checking for struct flock""... $ac_c" 1>&6 -echo "configure:16187: checking for struct flock" >&5 +echo "configure:16393: checking for struct flock" >&5 if eval "test \"`echo '$''{'ac_cv_struct_flock'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -16198,7 +16404,7 @@ int main() { struct flock x; ; return 0; } EOF -if { (eval echo configure:16202: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16408: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_flock=yes @@ -16225,12 +16431,12 @@ fi echo $ac_n "checking for socklen_t""... $ac_c" 1>&6 -echo "configure:16229: checking for socklen_t" >&5 +echo "configure:16435: checking for socklen_t" >&5 if eval "test \"`echo '$''{'ac_cv_socklen_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -16242,7 +16448,7 @@ socklen_t x; ; return 0; } EOF -if { (eval echo configure:16246: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16452: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_socklen_t=yes @@ -16268,7 +16474,7 @@ fi echo $ac_n "checking size of size_t""... $ac_c" 1>&6 -echo "configure:16272: checking size of size_t" >&5 +echo "configure:16478: checking size of size_t" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -16276,7 +16482,7 @@ else ac_cv_sizeof_size_t=8 else cat > conftest.$ac_ext < int main() @@ -16287,7 +16493,7 @@ int main() return(0); } EOF -if { (eval echo configure:16291: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:16497: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_size_t=`cat conftestval` else @@ -16307,7 +16513,7 @@ EOF echo $ac_n "checking size of long long""... $ac_c" 1>&6 -echo "configure:16311: checking size of long long" >&5 +echo "configure:16517: checking size of long long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -16315,7 +16521,7 @@ else ac_cv_sizeof_long_long=8 else cat > conftest.$ac_ext < int main() @@ -16326,7 +16532,7 @@ int main() return(0); } EOF -if { (eval echo configure:16330: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:16536: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long_long=`cat conftestval` else @@ -16346,7 +16552,7 @@ EOF echo $ac_n "checking size of long long int""... $ac_c" 1>&6 -echo "configure:16350: checking size of long long int" >&5 +echo "configure:16556: checking size of long long int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -16354,7 +16560,7 @@ else ac_cv_sizeof_long_long_int=8 else cat > conftest.$ac_ext < int main() @@ -16365,7 +16571,7 @@ int main() return(0); } EOF -if { (eval echo configure:16369: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:16575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long_long_int=`cat conftestval` else @@ -16385,7 +16591,7 @@ EOF echo $ac_n "checking size of long""... $ac_c" 1>&6 -echo "configure:16389: checking size of long" >&5 +echo "configure:16595: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -16393,7 +16599,7 @@ else ac_cv_sizeof_long=8 else cat > conftest.$ac_ext < int main() @@ -16404,7 +16610,7 @@ int main() return(0); } EOF -if { (eval echo configure:16408: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:16614: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -16424,7 +16630,7 @@ EOF echo $ac_n "checking size of int""... $ac_c" 1>&6 -echo "configure:16428: checking size of int" >&5 +echo "configure:16634: checking size of int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -16432,7 +16638,7 @@ else ac_cv_sizeof_int=4 else cat > conftest.$ac_ext < int main() @@ -16443,7 +16649,7 @@ int main() return(0); } EOF -if { (eval echo configure:16447: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:16653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_int=`cat conftestval` else @@ -16465,7 +16671,7 @@ EOF echo $ac_n "checking size of intmax_t""... $ac_c" 1>&6 -echo "configure:16469: checking size of intmax_t" >&5 +echo "configure:16675: checking size of intmax_t" >&5 php_cache_value=php_cv_sizeof_intmax_t if eval "test \"`echo '$''{'php_cv_sizeof_intmax_t'+set}'`\" = set"; then @@ -16482,7 +16688,7 @@ else else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -16506,7 +16712,7 @@ int main() } EOF -if { (eval echo configure:16510: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:16716: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then eval $php_cache_value=`cat conftestval` @@ -16545,7 +16751,7 @@ EOF echo $ac_n "checking size of ssize_t""... $ac_c" 1>&6 -echo "configure:16549: checking size of ssize_t" >&5 +echo "configure:16755: checking size of ssize_t" >&5 php_cache_value=php_cv_sizeof_ssize_t if eval "test \"`echo '$''{'php_cv_sizeof_ssize_t'+set}'`\" = set"; then @@ -16562,7 +16768,7 @@ else else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -16586,7 +16792,7 @@ int main() } EOF -if { (eval echo configure:16590: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:16796: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then eval $php_cache_value=`cat conftestval` @@ -16625,7 +16831,7 @@ EOF echo $ac_n "checking size of ptrdiff_t""... $ac_c" 1>&6 -echo "configure:16629: checking size of ptrdiff_t" >&5 +echo "configure:16835: checking size of ptrdiff_t" >&5 php_cache_value=php_cv_sizeof_ptrdiff_t if eval "test \"`echo '$''{'php_cv_sizeof_ptrdiff_t'+set}'`\" = set"; then @@ -16642,7 +16848,7 @@ else else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -16666,7 +16872,7 @@ int main() } EOF -if { (eval echo configure:16670: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:16876: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then eval $php_cache_value=`cat conftestval` @@ -16705,12 +16911,12 @@ EOF echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6 -echo "configure:16709: checking for st_blksize in struct stat" >&5 +echo "configure:16915: checking for st_blksize in struct stat" >&5 if eval "test \"`echo '$''{'ac_cv_struct_st_blksize'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -16718,7 +16924,7 @@ int main() { struct stat s; s.st_blksize; ; return 0; } EOF -if { (eval echo configure:16722: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16928: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_st_blksize=yes else @@ -16740,12 +16946,12 @@ fi if test "`uname -s 2>/dev/null`" != "QNX"; then echo $ac_n "checking for st_blocks in struct stat""... $ac_c" 1>&6 -echo "configure:16744: checking for st_blocks in struct stat" >&5 +echo "configure:16950: checking for st_blocks in struct stat" >&5 if eval "test \"`echo '$''{'ac_cv_struct_st_blocks'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -16753,7 +16959,7 @@ int main() { struct stat s; s.st_blocks; ; return 0; } EOF -if { (eval echo configure:16757: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:16963: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_st_blocks=yes else @@ -16780,12 +16986,12 @@ else WARNING_LEVEL=0 fi echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6 -echo "configure:16784: checking for st_rdev in struct stat" >&5 +echo "configure:16990: checking for st_rdev in struct stat" >&5 if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -16793,7 +16999,7 @@ int main() { struct stat s; s.st_rdev; ; return 0; } EOF -if { (eval echo configure:16797: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:17003: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_st_rdev=yes else @@ -16815,12 +17021,12 @@ fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:16819: checking for size_t" >&5 +echo "configure:17025: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -16848,12 +17054,12 @@ EOF fi echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 -echo "configure:16852: checking for uid_t in sys/types.h" >&5 +echo "configure:17058: checking for uid_t in sys/types.h" >&5 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF @@ -16884,12 +17090,12 @@ fi echo $ac_n "checking for struct sockaddr_storage""... $ac_c" 1>&6 -echo "configure:16888: checking for struct sockaddr_storage" >&5 +echo "configure:17094: checking for struct sockaddr_storage" >&5 if eval "test \"`echo '$''{'ac_cv_sockaddr_storage'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -16897,7 +17103,7 @@ int main() { struct sockaddr_storage s; s ; return 0; } EOF -if { (eval echo configure:16901: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:17107: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_sockaddr_storage=yes else @@ -16918,13 +17124,13 @@ EOF fi echo $ac_n "checking for field sa_len in struct sockaddr""... $ac_c" 1>&6 -echo "configure:16922: checking for field sa_len in struct sockaddr" >&5 +echo "configure:17128: checking for field sa_len in struct sockaddr" >&5 if eval "test \"`echo '$''{'ac_cv_sockaddr_sa_len'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -16932,7 +17138,7 @@ int main() { static struct sockaddr sa; int n = (int) sa.sa_len; return n; ; return 0; } EOF -if { (eval echo configure:16936: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:17142: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_sockaddr_sa_len=yes else @@ -16955,12 +17161,12 @@ EOF echo $ac_n "checking for IPv6 support""... $ac_c" 1>&6 -echo "configure:16959: checking for IPv6 support" >&5 +echo "configure:17165: checking for IPv6 support" >&5 if eval "test \"`echo '$''{'ac_cv_ipv6_support'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -16969,7 +17175,7 @@ int main() { struct sockaddr_in6 s; struct in6_addr t=in6addr_any; int i=AF_INET6; s; t.s6_addr[0] = 0; ; return 0; } EOF -if { (eval echo configure:16973: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:17179: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_ipv6_support=yes else @@ -16985,12 +17191,12 @@ echo "$ac_t""$ac_cv_ipv6_support" 1>&6 echo $ac_n "checking for vprintf""... $ac_c" 1>&6 -echo "configure:16989: checking for vprintf" >&5 +echo "configure:17195: checking for vprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:17223: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vprintf=yes" else @@ -17037,12 +17243,12 @@ fi if test "$ac_cv_func_vprintf" != yes; then echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 -echo "configure:17041: checking for _doprnt" >&5 +echo "configure:17247: checking for _doprnt" >&5 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:17275: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func__doprnt=yes" else @@ -17135,7 +17341,6 @@ putenv \ realpath \ random \ rand_r \ -res_search \ scandir \ setitimer \ setlocale \ @@ -17167,7 +17372,6 @@ tzset \ unlockpt \ unsetenv \ usleep \ -nanosleep \ utime \ vsnprintf \ vasprintf \ @@ -17175,12 +17379,12 @@ asprintf \ do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:17179: checking for $ac_func" >&5 +echo "configure:17383: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:17411: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -17229,25 +17433,25 @@ done echo $ac_n "checking for getaddrinfo""... $ac_c" 1>&6 -echo "configure:17233: checking for getaddrinfo" >&5 +echo "configure:17437: checking for getaddrinfo" >&5 if eval "test \"`echo '$''{'ac_cv_func_getaddrinfo'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { struct addrinfo *g,h;g=&h;getaddrinfo("","",g,&g); ; return 0; } EOF -if { (eval echo configure:17245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:17449: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* if test "$cross_compiling" = yes; then ac_cv_func_getaddrinfo=no else cat > conftest.$ac_ext < @@ -17287,7 +17491,7 @@ int main(void) { } EOF -if { (eval echo configure:17291: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:17495: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_getaddrinfo=yes else @@ -17319,12 +17523,12 @@ fi for ac_func in strlcat strlcpy getopt do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:17323: checking for $ac_func" >&5 +echo "configure:17527: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:17555: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -17374,7 +17578,7 @@ done echo $ac_n "checking whether utime accepts a null argument""... $ac_c" 1>&6 -echo "configure:17378: checking whether utime accepts a null argument" >&5 +echo "configure:17582: checking whether utime accepts a null argument" >&5 if eval "test \"`echo '$''{'ac_cv_func_utime_null'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -17384,7 +17588,7 @@ if test "$cross_compiling" = yes; then ac_cv_func_utime_null=no else cat > conftest.$ac_ext < #include @@ -17395,7 +17599,7 @@ exit(!(stat ("conftestdata", &s) == 0 && utime("conftestdata", (long *)0) == 0 && t.st_mtime - s.st_mtime < 120)); } EOF -if { (eval echo configure:17399: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:17603: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_utime_null=yes else @@ -17421,19 +17625,19 @@ fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:17425: checking for working alloca.h" >&5 +echo "configure:17629: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:17437: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:17641: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -17454,12 +17658,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:17458: checking for alloca" >&5 +echo "configure:17662: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:17695: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -17519,12 +17723,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:17523: checking whether alloca needs Cray hooks" >&5 +echo "configure:17727: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:17553: checking for $ac_func" >&5 +echo "configure:17757: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:17785: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -17604,7 +17808,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:17608: checking stack direction for C alloca" >&5 +echo "configure:17812: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -17612,7 +17816,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:17839: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -17654,13 +17858,13 @@ fi echo $ac_n "checking for declared timezone""... $ac_c" 1>&6 -echo "configure:17658: checking for declared timezone" >&5 +echo "configure:17862: checking for declared timezone" >&5 if eval "test \"`echo '$''{'ac_cv_declared_timezone'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -17675,7 +17879,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:17679: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:17883: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_declared_timezone=yes @@ -17701,7 +17905,7 @@ EOF echo $ac_n "checking for type of reentrant time-related functions""... $ac_c" 1>&6 -echo "configure:17705: checking for type of reentrant time-related functions" >&5 +echo "configure:17909: checking for type of reentrant time-related functions" >&5 if eval "test \"`echo '$''{'ac_cv_time_r_type'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -17712,7 +17916,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -17730,7 +17934,7 @@ return (1); } EOF -if { (eval echo configure:17734: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:17938: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_time_r_type=hpux @@ -17746,7 +17950,7 @@ else else cat > conftest.$ac_ext < @@ -17762,7 +17966,7 @@ main() { } EOF -if { (eval echo configure:17766: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:17970: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_time_r_type=irix @@ -17800,12 +18004,12 @@ EOF echo $ac_n "checking for readdir_r""... $ac_c" 1>&6 -echo "configure:17804: checking for readdir_r" >&5 +echo "configure:18008: checking for readdir_r" >&5 if eval "test \"`echo '$''{'ac_cv_func_readdir_r'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:18036: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_readdir_r=yes" else @@ -17850,7 +18054,7 @@ fi if test "$ac_cv_func_readdir_r" = "yes"; then echo $ac_n "checking for type of readdir_r""... $ac_c" 1>&6 -echo "configure:17854: checking for type of readdir_r" >&5 +echo "configure:18058: checking for type of readdir_r" >&5 if eval "test \"`echo '$''{'ac_cv_what_readdir_r'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -17861,7 +18065,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:18094: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_what_readdir_r=POSIX @@ -17897,7 +18101,7 @@ else rm -fr conftest* cat > conftest.$ac_ext <&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:18115: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -17949,12 +18153,12 @@ EOF echo $ac_n "checking for in_addr_t""... $ac_c" 1>&6 -echo "configure:17953: checking for in_addr_t" >&5 +echo "configure:18157: checking for in_addr_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_in_addr_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -17988,12 +18192,12 @@ fi for ac_func in crypt_r do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:17992: checking for $ac_func" >&5 +echo "configure:18196: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:18224: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -18044,14 +18248,14 @@ done if test "x$php_crypt_r" = "x1"; then echo $ac_n "checking which data struct is used by crypt_r""... $ac_c" 1>&6 -echo "configure:18048: checking which data struct is used by crypt_r" >&5 +echo "configure:18252: checking which data struct is used by crypt_r" >&5 if eval "test \"`echo '$''{'php_cv_crypt_r_style'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else php_cv_crypt_r_style=none cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:18272: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* php_cv_crypt_r_style=cryptd else @@ -18075,7 +18279,7 @@ rm -f conftest* if test "$php_cv_crypt_r_style" = "none"; then cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:18296: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* php_cv_crypt_r_style=struct_crypt_data else @@ -18100,7 +18304,7 @@ rm -f conftest* if test "$php_cv_crypt_r_style" = "none"; then cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:18322: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* php_cv_crypt_r_style=struct_crypt_data_gnu_source else @@ -18173,7 +18377,7 @@ fi php_enable_gcov=no echo $ac_n "checking whether to include gcov symbols""... $ac_c" 1>&6 -echo "configure:18177: checking whether to include gcov symbols" >&5 +echo "configure:18381: checking whether to include gcov symbols" >&5 # Check whether --enable-gcov or --disable-gcov was given. if test "${enable_gcov+set}" = set; then enableval="$enable_gcov" @@ -18215,7 +18419,7 @@ if test "$PHP_GCOV" = "yes"; then # Extract the first word of "lcov", so it can be a program name with args. set dummy lcov; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:18219: checking for $ac_word" >&5 +echo "configure:18423: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LTP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -18244,7 +18448,7 @@ fi # Extract the first word of "genhtml", so it can be a program name with args. set dummy genhtml; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:18248: checking for $ac_word" >&5 +echo "configure:18452: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LTP_GENHTML'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -18279,7 +18483,7 @@ fi if test "$LTP"; then echo $ac_n "checking for ltp version""... $ac_c" 1>&6 -echo "configure:18283: checking for ltp version" >&5 +echo "configure:18487: checking for ltp version" >&5 if eval "test \"`echo '$''{'php_cv_ltp_version'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -18336,7 +18540,7 @@ fi php_enable_debug=no echo $ac_n "checking whether to include debugging symbols""... $ac_c" 1>&6 -echo "configure:18340: checking whether to include debugging symbols" >&5 +echo "configure:18544: checking whether to include debugging symbols" >&5 # Check whether --enable-debug or --disable-debug was given. if test "${enable_debug+set}" = set; then enableval="$enable_debug" @@ -18366,8 +18570,8 @@ if test "$PHP_DEBUG" = "yes"; then CXXFLAGS=`echo "$CXXFLAGS" | $SED -e 's/-O[0-9s]*//g'` if test "$GCC" = "yes" || test "$ICC" = "yes"; then - CFLAGS="$CFLAGS -O0" - CXXFLAGS="$CXXFLAGS -O0" + CFLAGS="$CFLAGS -g -O0" + CXXFLAGS="$CXXFLAGS -g -O0" fi if test "$SUNCC" = "yes"; then if test -n "$auto_cflags"; then @@ -18387,7 +18591,7 @@ fi php_with_layout=PHP echo $ac_n "checking layout of installed files""... $ac_c" 1>&6 -echo "configure:18391: checking layout of installed files" >&5 +echo "configure:18595: checking layout of installed files" >&5 # Check whether --with-layout or --without-layout was given. if test "${with_layout+set}" = set; then withval="$with_layout" @@ -18422,7 +18626,7 @@ esac php_with_config_file_path=DEFAULT echo $ac_n "checking path to configuration file""... $ac_c" 1>&6 -echo "configure:18426: checking path to configuration file" >&5 +echo "configure:18630: checking path to configuration file" >&5 # Check whether --with-config-file-path or --without-config-file-path was given. if test "${with_config_file_path+set}" = set; then withval="$with_config_file_path" @@ -18456,7 +18660,7 @@ if test "$PHP_CONFIG_FILE_PATH" = "DEFAULT"; then fi echo $ac_n "checking where to scan for configuration files""... $ac_c" 1>&6 -echo "configure:18460: checking where to scan for configuration files" >&5 +echo "configure:18664: checking where to scan for configuration files" >&5 php_with_config_file_scan_dir=DEFAULT @@ -18492,7 +18696,7 @@ test -n "$DEBUG_CFLAGS" && CFLAGS="$CFLAGS $DEBUG_CFLAGS" php_enable_safe_mode=no echo $ac_n "checking whether to enable safe mode by default""... $ac_c" 1>&6 -echo "configure:18496: checking whether to enable safe mode by default" >&5 +echo "configure:18700: checking whether to enable safe mode by default" >&5 # Check whether --enable-safe-mode or --disable-safe-mode was given. if test "${enable_safe_mode+set}" = set; then enableval="$enable_safe_mode" @@ -18527,7 +18731,7 @@ EOF fi echo $ac_n "checking for safe mode exec dir""... $ac_c" 1>&6 -echo "configure:18531: checking for safe mode exec dir" >&5 +echo "configure:18735: checking for safe mode exec dir" >&5 php_with_exec_dir=no @@ -18571,7 +18775,7 @@ fi php_enable_sigchild=no echo $ac_n "checking whether to enable PHP's own SIGCHLD handler""... $ac_c" 1>&6 -echo "configure:18575: checking whether to enable PHP's own SIGCHLD handler" >&5 +echo "configure:18779: checking whether to enable PHP's own SIGCHLD handler" >&5 # Check whether --enable-sigchild or --disable-sigchild was given. if test "${enable_sigchild+set}" = set; then enableval="$enable_sigchild" @@ -18609,7 +18813,7 @@ fi php_enable_magic_quotes=no echo $ac_n "checking whether to enable magic quotes by default""... $ac_c" 1>&6 -echo "configure:18613: checking whether to enable magic quotes by default" >&5 +echo "configure:18817: checking whether to enable magic quotes by default" >&5 # Check whether --enable-magic-quotes or --disable-magic-quotes was given. if test "${enable_magic_quotes+set}" = set; then enableval="$enable_magic_quotes" @@ -18647,7 +18851,7 @@ fi php_enable_libgcc=no echo $ac_n "checking whether to explicitly link against libgcc""... $ac_c" 1>&6 -echo "configure:18651: checking whether to explicitly link against libgcc" >&5 +echo "configure:18855: checking whether to explicitly link against libgcc" >&5 # Check whether --enable-libgcc or --disable-libgcc was given. if test "${enable_libgcc+set}" = set; then enableval="$enable_libgcc" @@ -18727,7 +18931,7 @@ fi php_enable_short_tags=yes echo $ac_n "checking whether to enable short tags by default""... $ac_c" 1>&6 -echo "configure:18731: checking whether to enable short tags by default" >&5 +echo "configure:18935: checking whether to enable short tags by default" >&5 # Check whether --enable-short-tags or --disable-short-tags was given. if test "${enable_short_tags+set}" = set; then enableval="$enable_short_tags" @@ -18765,7 +18969,7 @@ fi php_enable_dmalloc=no echo $ac_n "checking whether to enable dmalloc""... $ac_c" 1>&6 -echo "configure:18769: checking whether to enable dmalloc" >&5 +echo "configure:18973: checking whether to enable dmalloc" >&5 # Check whether --enable-dmalloc or --disable-dmalloc was given. if test "${enable_dmalloc+set}" = set; then enableval="$enable_dmalloc" @@ -18789,7 +18993,7 @@ echo "$ac_t""$ext_output" 1>&6 if test "$PHP_DMALLOC" = "yes"; then echo $ac_n "checking for dmalloc_error in -ldmalloc""... $ac_c" 1>&6 -echo "configure:18793: checking for dmalloc_error in -ldmalloc" >&5 +echo "configure:18997: checking for dmalloc_error in -ldmalloc" >&5 ac_lib_var=`echo dmalloc'_'dmalloc_error | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -18797,7 +19001,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldmalloc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:19016: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -18853,7 +19057,7 @@ fi php_enable_ipv6=yes echo $ac_n "checking whether to enable IPv6 support""... $ac_c" 1>&6 -echo "configure:18857: checking whether to enable IPv6 support" >&5 +echo "configure:19061: checking whether to enable IPv6 support" >&5 # Check whether --enable-ipv6 or --disable-ipv6 was given. if test "${enable_ipv6+set}" = set; then enableval="$enable_ipv6" @@ -18883,7 +19087,7 @@ EOF fi echo $ac_n "checking how big to make fd sets""... $ac_c" 1>&6 -echo "configure:18887: checking how big to make fd sets" >&5 +echo "configure:19091: checking how big to make fd sets" >&5 php_enable_fd_setsize=no @@ -18954,7 +19158,7 @@ fi echo $ac_n "checking size of long""... $ac_c" 1>&6 -echo "configure:18958: checking size of long" >&5 +echo "configure:19162: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -18962,7 +19166,7 @@ else ac_cv_sizeof_long=8 else cat > conftest.$ac_ext < int main() @@ -18973,7 +19177,7 @@ int main() return(0); } EOF -if { (eval echo configure:18977: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:19181: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -18993,7 +19197,7 @@ EOF echo $ac_n "checking size of int""... $ac_c" 1>&6 -echo "configure:18997: checking size of int" >&5 +echo "configure:19201: checking size of int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -19001,7 +19205,7 @@ else ac_cv_sizeof_int=4 else cat > conftest.$ac_ext < int main() @@ -19012,7 +19216,7 @@ int main() return(0); } EOF -if { (eval echo configure:19016: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:19220: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_int=`cat conftestval` else @@ -19033,13 +19237,13 @@ EOF echo $ac_n "checking for int32_t""... $ac_c" 1>&6 -echo "configure:19037: checking for int32_t" >&5 +echo "configure:19241: checking for int32_t" >&5 if eval "test \"`echo '$''{'ac_cv_int_type_int32_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:19266: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_int_type_int32_t=yes else @@ -19081,13 +19285,13 @@ fi echo $ac_n "checking for uint32_t""... $ac_c" 1>&6 -echo "configure:19085: checking for uint32_t" >&5 +echo "configure:19289: checking for uint32_t" >&5 if eval "test \"`echo '$''{'ac_cv_int_type_uint32_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:19314: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_int_type_uint32_t=yes else @@ -19138,17 +19342,17 @@ stdlib.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:19142: checking for $ac_hdr" >&5 +echo "configure:19346: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:19152: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:19356: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -19178,12 +19382,12 @@ done for ac_func in strtoll atoll strftime do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:19182: checking for $ac_func" >&5 +echo "configure:19386: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:19414: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -19671,7 +19875,7 @@ case $PHP_REGEX in esac echo $ac_n "checking which regex library to use""... $ac_c" 1>&6 -echo "configure:19675: checking which regex library to use" >&5 +echo "configure:19879: checking which regex library to use" >&5 echo "$ac_t""$REGEX_TYPE" 1>&6 if test "$REGEX_TYPE" = "php"; then @@ -20048,13 +20252,13 @@ elif test "$REGEX_TYPE" = "system"; then EOF echo $ac_n "checking whether field re_magic exists in struct regex_t""... $ac_c" 1>&6 -echo "configure:20052: checking whether field re_magic exists in struct regex_t" >&5 +echo "configure:20256: checking whether field re_magic exists in struct regex_t" >&5 if eval "test \"`echo '$''{'ac_cv_regex_t_re_magic'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -20062,7 +20266,7 @@ int main() { regex_t rt; rt.re_magic; ; return 0; } EOF -if { (eval echo configure:20066: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:20270: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_regex_t_re_magic=yes else @@ -20088,7 +20292,7 @@ fi php_enable_libxml=yes echo $ac_n "checking whether to enable LIBXML support""... $ac_c" 1>&6 -echo "configure:20092: checking whether to enable LIBXML support" >&5 +echo "configure:20296: checking whether to enable LIBXML support" >&5 # Check whether --enable-libxml or --disable-libxml was given. if test "${enable_libxml+set}" = set; then enableval="$enable_libxml" @@ -20136,7 +20340,7 @@ if test -z "$PHP_LIBXML_DIR"; then php_with_libxml_dir=no echo $ac_n "checking libxml2 install dir""... $ac_c" 1>&6 -echo "configure:20140: checking libxml2 install dir" >&5 +echo "configure:20344: checking libxml2 install dir" >&5 # Check whether --with-libxml-dir or --without-libxml-dir was given. if test "${with_libxml_dir+set}" = set; then withval="$with_libxml_dir" @@ -20165,7 +20369,7 @@ if test "$PHP_LIBXML" != "no"; then echo $ac_n "checking for xml2-config path""... $ac_c" 1>&6 -echo "configure:20169: checking for xml2-config path" >&5 +echo "configure:20373: checking for xml2-config path" >&5 if eval "test \"`echo '$''{'ac_cv_php_xml2_config_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -20323,7 +20527,7 @@ echo "$ac_t""$ac_cv_php_xml2_config_path" 1>&6 echo $ac_n "checking whether libxml build works""... $ac_c" 1>&6 -echo "configure:20327: checking whether libxml build works" >&5 +echo "configure:20531: checking whether libxml build works" >&5 if eval "test \"`echo '$''{'php_cv_libxml_build_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -20339,7 +20543,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:20558: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -20715,7 +20919,7 @@ fi php_with_openssl=no echo $ac_n "checking for OpenSSL support""... $ac_c" 1>&6 -echo "configure:20719: checking for OpenSSL support" >&5 +echo "configure:20923: checking for OpenSSL support" >&5 # Check whether --with-openssl or --without-openssl was given. if test "${with_openssl+set}" = set; then withval="$with_openssl" @@ -20762,7 +20966,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_kerberos=no echo $ac_n "checking for Kerberos support""... $ac_c" 1>&6 -echo "configure:20766: checking for Kerberos support" >&5 +echo "configure:20970: checking for Kerberos support" >&5 # Check whether --with-kerberos or --without-kerberos was given. if test "${with_kerberos+set}" = set; then withval="$with_kerberos" @@ -21091,7 +21295,7 @@ EOF # Extract the first word of "krb5-config", so it can be a program name with args. set dummy krb5-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:21095: checking for $ac_word" >&5 +echo "configure:21299: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_KRB5_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -21451,7 +21655,7 @@ fi fi echo $ac_n "checking for DSA_get_default_method in -lssl""... $ac_c" 1>&6 -echo "configure:21455: checking for DSA_get_default_method in -lssl" >&5 +echo "configure:21659: checking for DSA_get_default_method in -lssl" >&5 ac_lib_var=`echo ssl'_'DSA_get_default_method | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -21459,7 +21663,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lssl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:21678: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -21512,7 +21716,7 @@ fi # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:21516: checking for $ac_word" >&5 +echo "configure:21720: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_PKG_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -21717,9 +21921,9 @@ fi old_CPPFLAGS=$CPPFLAGS CPPFLAGS=-I$OPENSSL_INCDIR echo $ac_n "checking for OpenSSL version""... $ac_c" 1>&6 -echo "configure:21721: checking for OpenSSL version" >&5 +echo "configure:21925: checking for OpenSSL version" >&5 cat > conftest.$ac_ext < @@ -21874,7 +22078,7 @@ rm -f conftest* done echo $ac_n "checking for CRYPTO_free in -lcrypto""... $ac_c" 1>&6 -echo "configure:21878: checking for CRYPTO_free in -lcrypto" >&5 +echo "configure:22082: checking for CRYPTO_free in -lcrypto" >&5 ac_lib_var=`echo crypto'_'CRYPTO_free | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -21882,7 +22086,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypto $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:22101: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -22050,7 +22254,7 @@ fi done echo $ac_n "checking for SSL_CTX_set_ssl_version in -lssl""... $ac_c" 1>&6 -echo "configure:22054: checking for SSL_CTX_set_ssl_version in -lssl" >&5 +echo "configure:22258: checking for SSL_CTX_set_ssl_version in -lssl" >&5 ac_lib_var=`echo ssl'_'SSL_CTX_set_ssl_version | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -22058,7 +22262,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lssl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:22277: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -22214,8 +22418,8 @@ ext_output=$PHP_PCRE_REGEX if test "$PHP_PCRE_REGEX" != "yes" && test "$PHP_PCRE_REGEX" != "no"; then echo $ac_n "checking for PCRE headers location""... $ac_c" 1>&6 -echo "configure:22218: checking for PCRE headers location" >&5 - for i in $PHP_PCRE_REGEX $PHP_PCRE_REGEX/include $PHP_PCRE_REGEX/include/pcre; do +echo "configure:22422: checking for PCRE headers location" >&5 + for i in $PHP_PCRE_REGEX $PHP_PCRE_REGEX/include $PHP_PCRE_REGEX/include/pcre $PHP_PCRE_REGEX/local/include; do test -f $i/pcre.h && PCRE_INCDIR=$i done @@ -22225,7 +22429,7 @@ echo "configure:22218: checking for PCRE headers location" >&5 echo "$ac_t""$PCRE_INCDIR" 1>&6 echo $ac_n "checking for PCRE library location""... $ac_c" 1>&6 -echo "configure:22229: checking for PCRE library location" >&5 +echo "configure:22433: checking for PCRE library location" >&5 for j in $PHP_PCRE_REGEX $PHP_PCRE_REGEX/$PHP_LIBDIR; do test -f $j/libpcre.a || test -f $j/libpcre.$SHLIB_SUFFIX_NAME && PCRE_LIBDIR=$j done @@ -22647,7 +22851,7 @@ EOF else echo $ac_n "checking for PCRE library to use""... $ac_c" 1>&6 -echo "configure:22651: checking for PCRE library to use" >&5 +echo "configure:22855: checking for PCRE library to use" >&5 echo "$ac_t""bundled" 1>&6 pcrelib_sources="pcrelib/pcre_chartables.c pcrelib/pcre_ucd.c \ pcrelib/pcre_compile.c pcrelib/pcre_config.c pcrelib/pcre_exec.c \ @@ -22984,7 +23188,7 @@ EOF php_with_sqlite3=yes echo $ac_n "checking whether to enable the SQLite3 extension""... $ac_c" 1>&6 -echo "configure:22988: checking whether to enable the SQLite3 extension" >&5 +echo "configure:23192: checking whether to enable the SQLite3 extension" >&5 # Check whether --with-sqlite3 or --without-sqlite3 was given. if test "${with_sqlite3+set}" = set; then withval="$with_sqlite3" @@ -23042,7 +23246,7 @@ if test $PHP_SQLITE3 != "no"; then if test $PHP_SQLITE3 != "yes"; then echo $ac_n "checking for sqlite3 files in default path""... $ac_c" 1>&6 -echo "configure:23046: checking for sqlite3 files in default path" >&5 +echo "configure:23250: checking for sqlite3 files in default path" >&5 for i in $PHP_SQLITE3 /usr/local /usr; do if test -r $i/include/sqlite3.h; then SQLITE3_DIR=$i @@ -23057,7 +23261,7 @@ echo "configure:23046: checking for sqlite3 files in default path" >&5 fi echo $ac_n "checking for SQLite 3.3.9+""... $ac_c" 1>&6 -echo "configure:23061: checking for SQLite 3.3.9+" >&5 +echo "configure:23265: checking for SQLite 3.3.9+" >&5 save_old_LDFLAGS=$LDFLAGS ac_stuff=" @@ -23156,7 +23360,7 @@ echo "configure:23061: checking for SQLite 3.3.9+" >&5 done echo $ac_n "checking for sqlite3_prepare_v2 in -lsqlite3""... $ac_c" 1>&6 -echo "configure:23160: checking for sqlite3_prepare_v2 in -lsqlite3" >&5 +echo "configure:23364: checking for sqlite3_prepare_v2 in -lsqlite3" >&5 ac_lib_var=`echo sqlite3'_'sqlite3_prepare_v2 | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -23164,7 +23368,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsqlite3 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:23383: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -23435,7 +23639,7 @@ fi done echo $ac_n "checking for sqlite3_key in -lsqlite3""... $ac_c" 1>&6 -echo "configure:23439: checking for sqlite3_key in -lsqlite3" >&5 +echo "configure:23643: checking for sqlite3_key in -lsqlite3" >&5 ac_lib_var=`echo sqlite3'_'sqlite3_key | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -23443,7 +23647,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsqlite3 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:23662: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -23586,7 +23790,7 @@ fi done echo $ac_n "checking for sqlite3_load_extension in -lsqlite3""... $ac_c" 1>&6 -echo "configure:23590: checking for sqlite3_load_extension in -lsqlite3" >&5 +echo "configure:23794: checking for sqlite3_load_extension in -lsqlite3" >&5 ac_lib_var=`echo sqlite3'_'sqlite3_load_extension | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -23594,7 +23798,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsqlite3 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:23813: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -23642,7 +23846,7 @@ fi else echo $ac_n "checking bundled sqlite3 library""... $ac_c" 1>&6 -echo "configure:23646: checking bundled sqlite3 library" >&5 +echo "configure:23850: checking bundled sqlite3 library" >&5 echo "$ac_t""yes" 1>&6 sqlite3_extra_sources="libsqlite/sqlite3.c" @@ -23980,7 +24184,7 @@ fi php_with_zlib=no echo $ac_n "checking for ZLIB support""... $ac_c" 1>&6 -echo "configure:23984: checking for ZLIB support" >&5 +echo "configure:24188: checking for ZLIB support" >&5 # Check whether --with-zlib or --without-zlib was given. if test "${with_zlib+set}" = set; then withval="$with_zlib" @@ -24027,7 +24231,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_zlib_dir=no echo $ac_n "checking if the location of ZLIB install directory is defined""... $ac_c" 1>&6 -echo "configure:24031: checking if the location of ZLIB install directory is defined" >&5 +echo "configure:24235: checking if the location of ZLIB install directory is defined" >&5 # Check whether --with-zlib-dir or --without-zlib-dir was given. if test "${with_zlib_dir+set}" = set; then withval="$with_zlib_dir" @@ -24473,7 +24677,7 @@ EOF done echo $ac_n "checking for gzgets in -lz""... $ac_c" 1>&6 -echo "configure:24477: checking for gzgets in -lz" >&5 +echo "configure:24681: checking for gzgets in -lz" >&5 ac_lib_var=`echo z'_'gzgets | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -24481,7 +24685,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lz $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:24700: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -24632,7 +24836,7 @@ fi php_enable_bcmath=no echo $ac_n "checking whether to enable bc style precision math functions""... $ac_c" 1>&6 -echo "configure:24636: checking whether to enable bc style precision math functions" >&5 +echo "configure:24840: checking whether to enable bc style precision math functions" >&5 # Check whether --enable-bcmath or --disable-bcmath was given. if test "${enable_bcmath+set}" = set; then enableval="$enable_bcmath" @@ -25000,7 +25204,7 @@ fi php_with_bz2=no echo $ac_n "checking for BZip2 support""... $ac_c" 1>&6 -echo "configure:25004: checking for BZip2 support" >&5 +echo "configure:25208: checking for BZip2 support" >&5 # Check whether --with-bz2 or --without-bz2 was given. if test "${with_bz2+set}" = set; then withval="$with_bz2" @@ -25048,7 +25252,7 @@ if test "$PHP_BZ2" != "no"; then BZIP_DIR=$PHP_BZ2 else echo $ac_n "checking for BZip2 in default path""... $ac_c" 1>&6 -echo "configure:25052: checking for BZip2 in default path" >&5 +echo "configure:25256: checking for BZip2 in default path" >&5 for i in /usr/local /usr; do if test -r $i/include/bzlib.h; then BZIP_DIR=$i @@ -25161,7 +25365,7 @@ echo "configure:25052: checking for BZip2 in default path" >&5 done echo $ac_n "checking for BZ2_bzerror in -lbz2""... $ac_c" 1>&6 -echo "configure:25165: checking for BZ2_bzerror in -lbz2" >&5 +echo "configure:25369: checking for BZ2_bzerror in -lbz2" >&5 ac_lib_var=`echo bz2'_'BZ2_bzerror | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -25169,7 +25373,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lbz2 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:25388: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -25648,7 +25852,7 @@ fi php_enable_calendar=no echo $ac_n "checking whether to enable calendar conversion support""... $ac_c" 1>&6 -echo "configure:25652: checking whether to enable calendar conversion support" >&5 +echo "configure:25856: checking whether to enable calendar conversion support" >&5 # Check whether --enable-calendar or --disable-calendar was given. if test "${enable_calendar+set}" = set; then enableval="$enable_calendar" @@ -25995,7 +26199,7 @@ fi php_enable_ctype=yes echo $ac_n "checking whether to enable ctype functions""... $ac_c" 1>&6 -echo "configure:25999: checking whether to enable ctype functions" >&5 +echo "configure:26203: checking whether to enable ctype functions" >&5 # Check whether --enable-ctype or --disable-ctype was given. if test "${enable_ctype+set}" = set; then enableval="$enable_ctype" @@ -26342,7 +26546,7 @@ fi php_with_curl=no echo $ac_n "checking for cURL support""... $ac_c" 1>&6 -echo "configure:26346: checking for cURL support" >&5 +echo "configure:26550: checking for cURL support" >&5 # Check whether --with-curl or --without-curl was given. if test "${with_curl+set}" = set; then withval="$with_curl" @@ -26389,7 +26593,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_curlwrappers=no echo $ac_n "checking if we should use cURL for url streams""... $ac_c" 1>&6 -echo "configure:26393: checking if we should use cURL for url streams" >&5 +echo "configure:26597: checking if we should use cURL for url streams" >&5 # Check whether --with-curlwrappers or --without-curlwrappers was given. if test "${with_curlwrappers+set}" = set; then withval="$with_curlwrappers" @@ -26416,7 +26620,7 @@ if test "$PHP_CURL" != "no"; then CURL_DIR=$PHP_CURL else echo $ac_n "checking for cURL in default path""... $ac_c" 1>&6 -echo "configure:26420: checking for cURL in default path" >&5 +echo "configure:26624: checking for cURL in default path" >&5 for i in /usr/local /usr; do if test -r $i/include/curl/easy.h; then CURL_DIR=$i @@ -26434,7 +26638,7 @@ echo "configure:26420: checking for cURL in default path" >&5 CURL_CONFIG="curl-config" echo $ac_n "checking for cURL 7.10.5 or greater""... $ac_c" 1>&6 -echo "configure:26438: checking for cURL 7.10.5 or greater" >&5 +echo "configure:26642: checking for cURL 7.10.5 or greater" >&5 if ${CURL_DIR}/bin/curl-config --libs > /dev/null 2>&1; then CURL_CONFIG=${CURL_DIR}/bin/curl-config @@ -26672,7 +26876,7 @@ echo "configure:26438: checking for cURL 7.10.5 or greater" >&5 echo $ac_n "checking for SSL support in libcurl""... $ac_c" 1>&6 -echo "configure:26676: checking for SSL support in libcurl" >&5 +echo "configure:26880: checking for SSL support in libcurl" >&5 CURL_SSL=`$CURL_CONFIG --feature | $EGREP SSL` if test "$CURL_SSL" = "SSL"; then echo "$ac_t""yes" 1>&6 @@ -26685,7 +26889,7 @@ EOF CFLAGS="`$CURL_CONFIG --cflags`" echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:26689: checking how to run the C preprocessor" >&5 +echo "configure:26893: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -26700,13 +26904,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:26710: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:26914: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -26717,13 +26921,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:26727: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:26931: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -26734,13 +26938,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:26744: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:26948: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -26765,14 +26969,14 @@ fi echo "$ac_t""$CPP" 1>&6 echo $ac_n "checking for openssl support in libcurl""... $ac_c" 1>&6 -echo "configure:26769: checking for openssl support in libcurl" >&5 +echo "configure:26973: checking for openssl support in libcurl" >&5 if test "$cross_compiling" = yes; then echo "$ac_t""no" 1>&6 else cat > conftest.$ac_ext < @@ -26791,7 +26995,7 @@ int main(int argc, char *argv[]) } EOF -if { (eval echo configure:26795: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:26999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 @@ -26799,17 +27003,17 @@ then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:26803: checking for $ac_hdr" >&5 +echo "configure:27007: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:26813: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:27017: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -26854,14 +27058,14 @@ fi echo $ac_n "checking for gnutls support in libcurl""... $ac_c" 1>&6 -echo "configure:26858: checking for gnutls support in libcurl" >&5 +echo "configure:27062: checking for gnutls support in libcurl" >&5 if test "$cross_compiling" = yes; then echo "$ac_t""no" 1>&6 else cat > conftest.$ac_ext < @@ -26880,23 +27084,23 @@ int main(int argc, char *argv[]) } EOF -if { (eval echo configure:26884: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:27088: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 ac_safe=`echo "gcrypt.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for gcrypt.h""... $ac_c" 1>&6 -echo "configure:26890: checking for gcrypt.h" >&5 +echo "configure:27094: checking for gcrypt.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:26900: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:27104: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -27038,7 +27242,7 @@ fi done echo $ac_n "checking for curl_easy_perform in -lcurl""... $ac_c" 1>&6 -echo "configure:27042: checking for curl_easy_perform in -lcurl" >&5 +echo "configure:27246: checking for curl_easy_perform in -lcurl" >&5 ac_lib_var=`echo curl'_'curl_easy_perform | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -27046,7 +27250,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcurl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:27265: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -27193,7 +27397,7 @@ fi done echo $ac_n "checking for curl_version_info in -lcurl""... $ac_c" 1>&6 -echo "configure:27197: checking for curl_version_info in -lcurl" >&5 +echo "configure:27401: checking for curl_version_info in -lcurl" >&5 ac_lib_var=`echo curl'_'curl_version_info | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -27201,7 +27405,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcurl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:27420: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -27346,7 +27550,7 @@ fi done echo $ac_n "checking for curl_easy_strerror in -lcurl""... $ac_c" 1>&6 -echo "configure:27350: checking for curl_easy_strerror in -lcurl" >&5 +echo "configure:27554: checking for curl_easy_strerror in -lcurl" >&5 ac_lib_var=`echo curl'_'curl_easy_strerror | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -27354,7 +27558,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcurl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:27573: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -27499,7 +27703,7 @@ fi done echo $ac_n "checking for curl_multi_strerror in -lcurl""... $ac_c" 1>&6 -echo "configure:27503: checking for curl_multi_strerror in -lcurl" >&5 +echo "configure:27707: checking for curl_multi_strerror in -lcurl" >&5 ac_lib_var=`echo curl'_'curl_multi_strerror | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -27507,7 +27711,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcurl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:27726: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -28231,7 +28435,7 @@ if test "$PHP_QDBM" != "no"; then done echo $ac_n "checking for dpopen in -l$LIB""... $ac_c" 1>&6 -echo "configure:28235: checking for dpopen in -l$LIB" >&5 +echo "configure:28439: checking for dpopen in -l$LIB" >&5 ac_lib_var=`echo $LIB'_'dpopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -28239,7 +28443,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$LIB $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:28458: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -28419,7 +28623,7 @@ fi THIS_FULL_NAME="$THIS_NAME" fi echo $ac_n "checking for $THIS_FULL_NAME support""... $ac_c" 1>&6 -echo "configure:28423: checking for $THIS_FULL_NAME support" >&5 +echo "configure:28627: checking for $THIS_FULL_NAME support" >&5 if test -n ""; then { echo "configure: error: " 1>&2; exit 1; } fi @@ -28447,7 +28651,7 @@ if test "$PHP_GDBM" != "no"; then THIS_FULL_NAME="$THIS_NAME" fi echo $ac_n "checking for $THIS_FULL_NAME support""... $ac_c" 1>&6 -echo "configure:28451: checking for $THIS_FULL_NAME support" >&5 +echo "configure:28655: checking for $THIS_FULL_NAME support" >&5 if test -n "You cannot combine --with-gdbm with --with-qdbm"; then { echo "configure: error: You cannot combine --with-gdbm with --with-qdbm" 1>&2; exit 1; } fi @@ -28566,7 +28770,7 @@ echo "configure:28451: checking for $THIS_FULL_NAME support" >&5 done echo $ac_n "checking for gdbm_open in -lgdbm""... $ac_c" 1>&6 -echo "configure:28570: checking for gdbm_open in -lgdbm" >&5 +echo "configure:28774: checking for gdbm_open in -lgdbm" >&5 ac_lib_var=`echo gdbm'_'gdbm_open | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -28574,7 +28778,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgdbm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:28793: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -28750,7 +28954,7 @@ fi THIS_FULL_NAME="$THIS_NAME" fi echo $ac_n "checking for $THIS_FULL_NAME support""... $ac_c" 1>&6 -echo "configure:28754: checking for $THIS_FULL_NAME support" >&5 +echo "configure:28958: checking for $THIS_FULL_NAME support" >&5 if test -n ""; then { echo "configure: error: " 1>&2; exit 1; } fi @@ -28879,7 +29083,7 @@ if test "$PHP_NDBM" != "no"; then done echo $ac_n "checking for dbm_open in -l$LIB""... $ac_c" 1>&6 -echo "configure:28883: checking for dbm_open in -l$LIB" >&5 +echo "configure:29087: checking for dbm_open in -l$LIB" >&5 ac_lib_var=`echo $LIB'_'dbm_open | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -28887,7 +29091,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$LIB $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:29106: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -29067,7 +29271,7 @@ fi THIS_FULL_NAME="$THIS_NAME" fi echo $ac_n "checking for $THIS_FULL_NAME support""... $ac_c" 1>&6 -echo "configure:29071: checking for $THIS_FULL_NAME support" >&5 +echo "configure:29275: checking for $THIS_FULL_NAME support" >&5 if test -n ""; then { echo "configure: error: " 1>&2; exit 1; } fi @@ -29134,7 +29338,7 @@ if test "$PHP_DB4" != "no"; then LIBS="-l$LIB $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:29353: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* cat > conftest.$ac_ext <&6 -echo "configure:29190: checking for db4 major version" >&5 +echo "configure:29394: checking for db4 major version" >&5 { echo "configure: error: Header contains different version" 1>&2; exit 1; } fi if test "4" = "4"; then echo $ac_n "checking for db4 minor version and patch level""... $ac_c" 1>&6 -echo "configure:29195: checking for db4 minor version and patch level" >&5 +echo "configure:29399: checking for db4 minor version and patch level" >&5 cat > conftest.$ac_ext <&6 -echo "configure:29223: checking if dba can be used as shared extension" >&5 +echo "configure:29427: checking if dba can be used as shared extension" >&5 cat > conftest.$ac_ext <&6 -echo "configure:29382: checking for $THIS_FULL_NAME support" >&5 +echo "configure:29586: checking for $THIS_FULL_NAME support" >&5 if test -n ""; then { echo "configure: error: " 1>&2; exit 1; } fi @@ -29406,7 +29610,7 @@ if test "$PHP_DB3" != "no"; then THIS_FULL_NAME="$THIS_NAME" fi echo $ac_n "checking for $THIS_FULL_NAME support""... $ac_c" 1>&6 -echo "configure:29410: checking for $THIS_FULL_NAME support" >&5 +echo "configure:29614: checking for $THIS_FULL_NAME support" >&5 if test -n "You cannot combine --with-db3 with --with-db4"; then { echo "configure: error: You cannot combine --with-db3 with --with-db4" 1>&2; exit 1; } fi @@ -29457,7 +29661,7 @@ echo "configure:29410: checking for $THIS_FULL_NAME support" >&5 LIBS="-l$LIB $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:29676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* cat > conftest.$ac_ext <&6 -echo "configure:29513: checking for db3 major version" >&5 +echo "configure:29717: checking for db3 major version" >&5 { echo "configure: error: Header contains different version" 1>&2; exit 1; } fi if test "3" = "4"; then echo $ac_n "checking for db4 minor version and patch level""... $ac_c" 1>&6 -echo "configure:29518: checking for db4 minor version and patch level" >&5 +echo "configure:29722: checking for db4 minor version and patch level" >&5 cat > conftest.$ac_ext <&6 -echo "configure:29546: checking if dba can be used as shared extension" >&5 +echo "configure:29750: checking if dba can be used as shared extension" >&5 cat > conftest.$ac_ext <&6 -echo "configure:29705: checking for $THIS_FULL_NAME support" >&5 +echo "configure:29909: checking for $THIS_FULL_NAME support" >&5 if test -n ""; then { echo "configure: error: " 1>&2; exit 1; } fi @@ -29729,7 +29933,7 @@ if test "$PHP_DB2" != "no"; then THIS_FULL_NAME="$THIS_NAME" fi echo $ac_n "checking for $THIS_FULL_NAME support""... $ac_c" 1>&6 -echo "configure:29733: checking for $THIS_FULL_NAME support" >&5 +echo "configure:29937: checking for $THIS_FULL_NAME support" >&5 if test -n "You cannot combine --with-db2 with --with-db3 or --with-db4"; then { echo "configure: error: You cannot combine --with-db2 with --with-db3 or --with-db4" 1>&2; exit 1; } fi @@ -29780,7 +29984,7 @@ echo "configure:29733: checking for $THIS_FULL_NAME support" >&5 LIBS="-l$LIB $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:29999: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* cat > conftest.$ac_ext <&6 -echo "configure:29836: checking for db2 major version" >&5 +echo "configure:30040: checking for db2 major version" >&5 { echo "configure: error: Header contains different version" 1>&2; exit 1; } fi if test "2" = "4"; then echo $ac_n "checking for db4 minor version and patch level""... $ac_c" 1>&6 -echo "configure:29841: checking for db4 minor version and patch level" >&5 +echo "configure:30045: checking for db4 minor version and patch level" >&5 cat > conftest.$ac_ext <&6 -echo "configure:29869: checking if dba can be used as shared extension" >&5 +echo "configure:30073: checking if dba can be used as shared extension" >&5 cat > conftest.$ac_ext <&6 -echo "configure:30028: checking for $THIS_FULL_NAME support" >&5 +echo "configure:30232: checking for $THIS_FULL_NAME support" >&5 if test -n ""; then { echo "configure: error: " 1>&2; exit 1; } fi @@ -30044,7 +30248,7 @@ if test "$PHP_DB1" != "no"; then unset THIS_INCLUDE THIS_LIBS THIS_LFLAGS THIS_PREFIX THIS_RESULT echo $ac_n "checking for DB1 in library""... $ac_c" 1>&6 -echo "configure:30048: checking for DB1 in library" >&5 +echo "configure:30252: checking for DB1 in library" >&5 if test "$HAVE_DB4" = "1"; then THIS_VERSION=4 THIS_LIBS=$DB4_LIBS @@ -30092,7 +30296,7 @@ EOF fi echo "$ac_t""$THIS_LIBS" 1>&6 echo $ac_n "checking for DB1 in header""... $ac_c" 1>&6 -echo "configure:30096: checking for DB1 in header" >&5 +echo "configure:30300: checking for DB1 in header" >&5 echo "$ac_t""$THIS_INCLUDE" 1>&6 if test -n "$THIS_INCLUDE"; then @@ -30102,7 +30306,7 @@ echo "configure:30096: checking for DB1 in header" >&5 LIBS="-l$THIS_LIBS $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:30321: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* cat >> confdefs.h <&6 -echo "configure:30267: checking for $THIS_FULL_NAME support" >&5 +echo "configure:30471: checking for $THIS_FULL_NAME support" >&5 if test -n ""; then { echo "configure: error: " 1>&2; exit 1; } fi @@ -30291,7 +30495,7 @@ if test "$PHP_DBM" != "no"; then THIS_FULL_NAME="$THIS_NAME" fi echo $ac_n "checking for $THIS_FULL_NAME support""... $ac_c" 1>&6 -echo "configure:30295: checking for $THIS_FULL_NAME support" >&5 +echo "configure:30499: checking for $THIS_FULL_NAME support" >&5 if test -n "You cannot combine --with-dbm with --with-qdbm"; then { echo "configure: error: You cannot combine --with-dbm with --with-qdbm" 1>&2; exit 1; } fi @@ -30415,7 +30619,7 @@ echo "configure:30295: checking for $THIS_FULL_NAME support" >&5 done echo $ac_n "checking for dbminit in -l$LIB""... $ac_c" 1>&6 -echo "configure:30419: checking for dbminit in -l$LIB" >&5 +echo "configure:30623: checking for dbminit in -l$LIB" >&5 ac_lib_var=`echo $LIB'_'dbminit | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -30423,7 +30627,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$LIB $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:30642: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -30454,7 +30658,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then ext_shared=$save_ext_shared echo $ac_n "checking for DBM using GDBM""... $ac_c" 1>&6 -echo "configure:30458: checking for DBM using GDBM" >&5 +echo "configure:30662: checking for DBM using GDBM" >&5 cat >> confdefs.h <&6 -echo "configure:30622: checking for $THIS_FULL_NAME support" >&5 +echo "configure:30826: checking for $THIS_FULL_NAME support" >&5 if test -n ""; then { echo "configure: error: " 1>&2; exit 1; } fi @@ -30839,7 +31043,7 @@ elif test "$PHP_CDB" != "no"; then done echo $ac_n "checking for cdb_read in -l$LIB""... $ac_c" 1>&6 -echo "configure:30843: checking for cdb_read in -l$LIB" >&5 +echo "configure:31047: checking for cdb_read in -l$LIB" >&5 ac_lib_var=`echo $LIB'_'cdb_read | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -30847,7 +31051,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$LIB $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:31066: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -31027,7 +31231,7 @@ fi THIS_FULL_NAME="$THIS_NAME" fi echo $ac_n "checking for $THIS_FULL_NAME support""... $ac_c" 1>&6 -echo "configure:31031: checking for $THIS_FULL_NAME support" >&5 +echo "configure:31235: checking for $THIS_FULL_NAME support" >&5 if test -n ""; then { echo "configure: error: " 1>&2; exit 1; } fi @@ -31058,7 +31262,7 @@ fi THIS_FULL_NAME="$THIS_NAME" fi echo $ac_n "checking for $THIS_FULL_NAME support""... $ac_c" 1>&6 -echo "configure:31062: checking for $THIS_FULL_NAME support" >&5 +echo "configure:31266: checking for $THIS_FULL_NAME support" >&5 if test -n ""; then { echo "configure: error: " 1>&2; exit 1; } fi @@ -31089,7 +31293,7 @@ fi THIS_FULL_NAME="$THIS_NAME" fi echo $ac_n "checking for $THIS_FULL_NAME support""... $ac_c" 1>&6 -echo "configure:31093: checking for $THIS_FULL_NAME support" >&5 +echo "configure:31297: checking for $THIS_FULL_NAME support" >&5 if test -n ""; then { echo "configure: error: " 1>&2; exit 1; } fi @@ -31104,7 +31308,7 @@ echo "configure:31093: checking for $THIS_FULL_NAME support" >&5 echo $ac_n "checking whether to enable DBA interface""... $ac_c" 1>&6 -echo "configure:31108: checking whether to enable DBA interface" >&5 +echo "configure:31312: checking whether to enable DBA interface" >&5 if test "$HAVE_DBA" = "1"; then if test "$ext_shared" = "yes"; then echo "$ac_t""yes, shared" 1>&6 @@ -31434,7 +31638,7 @@ fi php_enable_dom=yes echo $ac_n "checking whether to enable DOM support""... $ac_c" 1>&6 -echo "configure:31438: checking whether to enable DOM support" >&5 +echo "configure:31642: checking whether to enable DOM support" >&5 # Check whether --enable-dom or --disable-dom was given. if test "${enable_dom+set}" = set; then enableval="$enable_dom" @@ -31482,7 +31686,7 @@ if test -z "$PHP_LIBXML_DIR"; then php_with_libxml_dir=no echo $ac_n "checking libxml2 install dir""... $ac_c" 1>&6 -echo "configure:31486: checking libxml2 install dir" >&5 +echo "configure:31690: checking libxml2 install dir" >&5 # Check whether --with-libxml-dir or --without-libxml-dir was given. if test "${with_libxml_dir+set}" = set; then withval="$with_libxml_dir" @@ -31513,7 +31717,7 @@ if test "$PHP_DOM" != "no"; then echo $ac_n "checking for xml2-config path""... $ac_c" 1>&6 -echo "configure:31517: checking for xml2-config path" >&5 +echo "configure:31721: checking for xml2-config path" >&5 if eval "test \"`echo '$''{'ac_cv_php_xml2_config_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -31671,7 +31875,7 @@ echo "$ac_t""$ac_cv_php_xml2_config_path" 1>&6 echo $ac_n "checking whether libxml build works""... $ac_c" 1>&6 -echo "configure:31675: checking whether libxml build works" >&5 +echo "configure:31879: checking whether libxml build works" >&5 if eval "test \"`echo '$''{'php_cv_libxml_build_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -31687,7 +31891,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:31906: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -32121,7 +32325,7 @@ fi php_with_enchant=no echo $ac_n "checking for ENCHANT support""... $ac_c" 1>&6 -echo "configure:32125: checking for ENCHANT support" >&5 +echo "configure:32329: checking for ENCHANT support" >&5 # Check whether --with-enchant or --without-enchant was given. if test "${with_enchant+set}" = set; then withval="$with_enchant" @@ -32613,6 +32817,161 @@ EOF fi + + save_old_LDFLAGS=$LDFLAGS + ac_stuff=" -L$ENCHANT_LIB $ENCHANT_SHARED_LIBADD" + + save_ext_shared=$ext_shared + ext_shared=yes + + for ac_i in $ac_stuff; do + case $ac_i in + -pthread) + if test "$ext_shared" = "yes"; then + LDFLAGS="$LDFLAGS -pthread" + else + + + unique=`echo $ac_i|$SED 's/[^a-zA-Z0-9]/_/g'` + + cmd="echo $ac_n \"\$EXTRA_LDFLAGS$unique$ac_c\"" + if test -n "$unique" && test "`eval $cmd`" = "" ; then + eval "EXTRA_LDFLAGS$unique=set" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS $ac_i" + fi + + fi + ;; + -l*) + ac_ii=`echo $ac_i|cut -c 3-` + + + case $ac_ii in + c|c_r|pthread*) ;; + *) + if test "$ext_shared" = "yes"; then + LDFLAGS="$LDFLAGS -l$ac_ii" + else + + + case $ac_ii in + c|c_r|pthread*) ;; + *) + LIBS="$LIBS -l$ac_ii" + ;; + esac + + + fi + ;; + esac + + + ;; + -L*) + ac_ii=`echo $ac_i|cut -c 3-` + + if test "$ac_ii" != "/usr/$PHP_LIBDIR" && test "$ac_ii" != "/usr/lib"; then + + if test -z "$ac_ii" || echo "$ac_ii" | grep '^/' >/dev/null ; then + ai_p=$ac_ii + else + + ep_dir="`echo $ac_ii|$SED 's%/*[^/][^/]*/*$%%'`" + + ep_realdir="`(cd \"$ep_dir\" && pwd)`" + ai_p="$ep_realdir/`basename \"$ac_ii\"`" + fi + + + if test "$ext_shared" = "yes"; then + LDFLAGS="-L$ai_p $LDFLAGS" + test -n "$ld_runpath_switch" && LDFLAGS="$ld_runpath_switch$ai_p $LDFLAGS" + else + + + + unique=`echo $ai_p|$SED 's/[^a-zA-Z0-9]/_/g'` + + cmd="echo $ac_n \"\$LIBPATH$unique$ac_c\"" + if test -n "$unique" && test "`eval $cmd`" = "" ; then + eval "LIBPATH$unique=set" + + test -n "$ld_runpath_switch" && LDFLAGS="$LDFLAGS $ld_runpath_switch$ai_p" + LDFLAGS="$LDFLAGS -L$ai_p" + PHP_RPATHS="$PHP_RPATHS $ai_p" + + fi + + + fi + + fi + + ;; + esac + done + + echo $ac_n "checking for enchant_broker_set_param in -lenchant""... $ac_c" 1>&6 +echo "configure:32917: checking for enchant_broker_set_param in -lenchant" >&5 +ac_lib_var=`echo enchant'_'enchant_broker_set_param | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lenchant $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + LDFLAGS=$save_old_LDFLAGS + ext_shared=$save_ext_shared + + cat >> confdefs.h <<\EOF +#define HAVE_ENCHANT_BROKER_SET_PARAM 1 +EOF + + cat >> confdefs.h <<\EOF +#define ENCHANT_VERSION_STRING "1.5.x" +EOF + + + +else + echo "$ac_t""no" 1>&6 + + LDFLAGS=$save_old_LDFLAGS + ext_shared=$save_ext_shared + unset ac_cv_lib_enchant_enchant_broker_set_param + + +fi + + fi @@ -32620,7 +32979,7 @@ fi php_enable_exif=no echo $ac_n "checking whether to enable EXIF (metadata from images) support""... $ac_c" 1>&6 -echo "configure:32624: checking whether to enable EXIF (metadata from images) support" >&5 +echo "configure:32983: checking whether to enable EXIF (metadata from images) support" >&5 # Check whether --enable-exif or --disable-exif was given. if test "${enable_exif+set}" = set; then enableval="$enable_exif" @@ -32967,7 +33326,7 @@ fi php_enable_fileinfo=yes echo $ac_n "checking for fileinfo support""... $ac_c" 1>&6 -echo "configure:32971: checking for fileinfo support" >&5 +echo "configure:33330: checking for fileinfo support" >&5 # Check whether --enable-fileinfo or --disable-fileinfo was given. if test "${enable_fileinfo+set}" = set; then enableval="$enable_fileinfo" @@ -33320,12 +33679,12 @@ EOF for ac_func in utimes strndup do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:33324: checking for $ac_func" >&5 +echo "configure:33683: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:33711: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -33386,7 +33745,7 @@ fi php_enable_filter=yes echo $ac_n "checking whether to enable input filter support""... $ac_c" 1>&6 -echo "configure:33390: checking whether to enable input filter support" >&5 +echo "configure:33749: checking whether to enable input filter support" >&5 # Check whether --enable-filter or --disable-filter was given. if test "${enable_filter+set}" = set; then enableval="$enable_filter" @@ -33433,7 +33792,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_pcre_dir=no echo $ac_n "checking pcre install prefix""... $ac_c" 1>&6 -echo "configure:33437: checking pcre install prefix" >&5 +echo "configure:33796: checking pcre install prefix" >&5 # Check whether --with-pcre-dir or --without-pcre-dir was given. if test "${with_pcre_dir+set}" = set; then withval="$with_pcre_dir" @@ -33463,7 +33822,7 @@ if test "$PHP_FILTER" != "no"; then old_CPPFLAGS=$CPPFLAGS CPPFLAGS=$INCLUDES cat > conftest.$ac_ext < @@ -33482,7 +33841,7 @@ else rm -rf conftest* cat > conftest.$ac_ext < @@ -33852,7 +34211,7 @@ fi php_enable_ftp=no echo $ac_n "checking whether to enable FTP support""... $ac_c" 1>&6 -echo "configure:33856: checking whether to enable FTP support" >&5 +echo "configure:34215: checking whether to enable FTP support" >&5 # Check whether --enable-ftp or --disable-ftp was given. if test "${enable_ftp+set}" = set; then enableval="$enable_ftp" @@ -33899,7 +34258,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_openssl_dir=no echo $ac_n "checking OpenSSL dir for FTP""... $ac_c" 1>&6 -echo "configure:33903: checking OpenSSL dir for FTP" >&5 +echo "configure:34262: checking OpenSSL dir for FTP" >&5 # Check whether --with-openssl-dir or --without-openssl-dir was given. if test "${with_openssl_dir+set}" = set; then withval="$with_openssl_dir" @@ -34240,7 +34599,7 @@ EOF # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:34244: checking for $ac_word" >&5 +echo "configure:34603: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_PKG_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -34445,9 +34804,9 @@ fi old_CPPFLAGS=$CPPFLAGS CPPFLAGS=-I$OPENSSL_INCDIR echo $ac_n "checking for OpenSSL version""... $ac_c" 1>&6 -echo "configure:34449: checking for OpenSSL version" >&5 +echo "configure:34808: checking for OpenSSL version" >&5 cat > conftest.$ac_ext < @@ -34602,7 +34961,7 @@ rm -f conftest* done echo $ac_n "checking for CRYPTO_free in -lcrypto""... $ac_c" 1>&6 -echo "configure:34606: checking for CRYPTO_free in -lcrypto" >&5 +echo "configure:34965: checking for CRYPTO_free in -lcrypto" >&5 ac_lib_var=`echo crypto'_'CRYPTO_free | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -34610,7 +34969,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypto $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:34984: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -34778,7 +35137,7 @@ fi done echo $ac_n "checking for SSL_CTX_set_ssl_version in -lssl""... $ac_c" 1>&6 -echo "configure:34782: checking for SSL_CTX_set_ssl_version in -lssl" >&5 +echo "configure:35141: checking for SSL_CTX_set_ssl_version in -lssl" >&5 ac_lib_var=`echo ssl'_'SSL_CTX_set_ssl_version | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -34786,7 +35145,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lssl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:35160: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -34916,7 +35275,7 @@ fi php_with_gd=no echo $ac_n "checking for GD support""... $ac_c" 1>&6 -echo "configure:34920: checking for GD support" >&5 +echo "configure:35279: checking for GD support" >&5 # Check whether --with-gd or --without-gd was given. if test "${with_gd+set}" = set; then withval="$with_gd" @@ -34964,7 +35323,7 @@ if test -z "$PHP_JPEG_DIR"; then php_with_jpeg_dir=no echo $ac_n "checking for the location of libjpeg""... $ac_c" 1>&6 -echo "configure:34968: checking for the location of libjpeg" >&5 +echo "configure:35327: checking for the location of libjpeg" >&5 # Check whether --with-jpeg-dir or --without-jpeg-dir was given. if test "${with_jpeg_dir+set}" = set; then withval="$with_jpeg_dir" @@ -34992,7 +35351,7 @@ if test -z "$PHP_PNG_DIR"; then php_with_png_dir=no echo $ac_n "checking for the location of libpng""... $ac_c" 1>&6 -echo "configure:34996: checking for the location of libpng" >&5 +echo "configure:35355: checking for the location of libpng" >&5 # Check whether --with-png-dir or --without-png-dir was given. if test "${with_png_dir+set}" = set; then withval="$with_png_dir" @@ -35020,7 +35379,7 @@ if test -z "$PHP_ZLIB_DIR"; then php_with_zlib_dir=no echo $ac_n "checking for the location of libz""... $ac_c" 1>&6 -echo "configure:35024: checking for the location of libz" >&5 +echo "configure:35383: checking for the location of libz" >&5 # Check whether --with-zlib-dir or --without-zlib-dir was given. if test "${with_zlib_dir+set}" = set; then withval="$with_zlib_dir" @@ -35047,7 +35406,7 @@ fi php_with_xpm_dir=no echo $ac_n "checking for the location of libXpm""... $ac_c" 1>&6 -echo "configure:35051: checking for the location of libXpm" >&5 +echo "configure:35410: checking for the location of libXpm" >&5 # Check whether --with-xpm-dir or --without-xpm-dir was given. if test "${with_xpm_dir+set}" = set; then withval="$with_xpm_dir" @@ -35073,7 +35432,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_freetype_dir=no echo $ac_n "checking for FreeType 2""... $ac_c" 1>&6 -echo "configure:35077: checking for FreeType 2" >&5 +echo "configure:35436: checking for FreeType 2" >&5 # Check whether --with-freetype-dir or --without-freetype-dir was given. if test "${with_freetype_dir+set}" = set; then withval="$with_freetype_dir" @@ -35099,7 +35458,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_t1lib=no echo $ac_n "checking for T1lib support""... $ac_c" 1>&6 -echo "configure:35103: checking for T1lib support" >&5 +echo "configure:35462: checking for T1lib support" >&5 # Check whether --with-t1lib or --without-t1lib was given. if test "${with_t1lib+set}" = set; then withval="$with_t1lib" @@ -35125,7 +35484,7 @@ echo "$ac_t""$ext_output" 1>&6 php_enable_gd_native_ttf=no echo $ac_n "checking whether to enable truetype string function in GD""... $ac_c" 1>&6 -echo "configure:35129: checking whether to enable truetype string function in GD" >&5 +echo "configure:35488: checking whether to enable truetype string function in GD" >&5 # Check whether --enable-gd-native-ttf or --disable-gd-native-ttf was given. if test "${enable_gd_native_ttf+set}" = set; then enableval="$enable_gd_native_ttf" @@ -35151,7 +35510,7 @@ echo "$ac_t""$ext_output" 1>&6 php_enable_gd_jis_conv=no echo $ac_n "checking whether to enable JIS-mapped Japanese font support in GD""... $ac_c" 1>&6 -echo "configure:35155: checking whether to enable JIS-mapped Japanese font support in GD" >&5 +echo "configure:35514: checking whether to enable JIS-mapped Japanese font support in GD" >&5 # Check whether --enable-gd-jis-conv or --disable-gd-jis-conv was given. if test "${enable_gd_jis_conv+set}" = set; then enableval="$enable_gd_jis_conv" @@ -35206,12 +35565,12 @@ if test "$PHP_GD" = "yes"; then for ac_func in fabsf floorf do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:35210: checking for $ac_func" >&5 +echo "configure:35569: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:35597: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -35406,7 +35765,7 @@ EOF done echo $ac_n "checking for jpeg_read_header in -ljpeg""... $ac_c" 1>&6 -echo "configure:35410: checking for jpeg_read_header in -ljpeg" >&5 +echo "configure:35769: checking for jpeg_read_header in -ljpeg" >&5 ac_lib_var=`echo jpeg'_'jpeg_read_header | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -35414,7 +35773,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ljpeg $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:35788: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -35707,7 +36066,7 @@ fi done echo $ac_n "checking for png_write_image in -lpng""... $ac_c" 1>&6 -echo "configure:35711: checking for png_write_image in -lpng" >&5 +echo "configure:36070: checking for png_write_image in -lpng" >&5 ac_lib_var=`echo png'_'png_write_image | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -35715,7 +36074,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpng $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:36089: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -36106,7 +36465,7 @@ fi done echo $ac_n "checking for XpmFreeXpmImage in -lXpm""... $ac_c" 1>&6 -echo "configure:36110: checking for XpmFreeXpmImage in -lXpm" >&5 +echo "configure:36469: checking for XpmFreeXpmImage in -lXpm" >&5 ac_lib_var=`echo Xpm'_'XpmFreeXpmImage | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -36114,7 +36473,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXpm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:36488: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -36500,7 +36859,7 @@ fi done echo $ac_n "checking for FT_New_Face in -lfreetype""... $ac_c" 1>&6 -echo "configure:36504: checking for FT_New_Face in -lfreetype" >&5 +echo "configure:36863: checking for FT_New_Face in -lfreetype" >&5 ac_lib_var=`echo freetype'_'FT_New_Face | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -36508,7 +36867,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lfreetype $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:36882: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -36836,7 +37195,7 @@ fi done echo $ac_n "checking for T1_StrError in -lt1""... $ac_c" 1>&6 -echo "configure:36840: checking for T1_StrError in -lt1" >&5 +echo "configure:37199: checking for T1_StrError in -lt1" >&5 ac_lib_var=`echo t1'_'T1_StrError | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -36844,7 +37203,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lt1 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:37218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -37298,7 +37657,7 @@ EOF done echo $ac_n "checking for jpeg_read_header in -ljpeg""... $ac_c" 1>&6 -echo "configure:37302: checking for jpeg_read_header in -ljpeg" >&5 +echo "configure:37661: checking for jpeg_read_header in -ljpeg" >&5 ac_lib_var=`echo jpeg'_'jpeg_read_header | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -37306,7 +37665,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ljpeg $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:37680: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -37599,7 +37958,7 @@ fi done echo $ac_n "checking for png_write_image in -lpng""... $ac_c" 1>&6 -echo "configure:37603: checking for png_write_image in -lpng" >&5 +echo "configure:37962: checking for png_write_image in -lpng" >&5 ac_lib_var=`echo png'_'png_write_image | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -37607,7 +37966,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpng $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:37981: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -37998,7 +38357,7 @@ fi done echo $ac_n "checking for XpmFreeXpmImage in -lXpm""... $ac_c" 1>&6 -echo "configure:38002: checking for XpmFreeXpmImage in -lXpm" >&5 +echo "configure:38361: checking for XpmFreeXpmImage in -lXpm" >&5 ac_lib_var=`echo Xpm'_'XpmFreeXpmImage | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -38006,7 +38365,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lXpm $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:38380: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -38392,7 +38751,7 @@ fi done echo $ac_n "checking for FT_New_Face in -lfreetype""... $ac_c" 1>&6 -echo "configure:38396: checking for FT_New_Face in -lfreetype" >&5 +echo "configure:38755: checking for FT_New_Face in -lfreetype" >&5 ac_lib_var=`echo freetype'_'FT_New_Face | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -38400,7 +38759,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lfreetype $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:38774: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -38728,7 +39087,7 @@ fi done echo $ac_n "checking for T1_StrError in -lt1""... $ac_c" 1>&6 -echo "configure:38732: checking for T1_StrError in -lt1" >&5 +echo "configure:39091: checking for T1_StrError in -lt1" >&5 ac_lib_var=`echo t1'_'T1_StrError | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -38736,7 +39095,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lt1 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:39110: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -39122,7 +39481,7 @@ EOF done echo $ac_n "checking for gdImageString16 in -lgd""... $ac_c" 1>&6 -echo "configure:39126: checking for gdImageString16 in -lgd" >&5 +echo "configure:39485: checking for gdImageString16 in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageString16 | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -39130,7 +39489,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:39504: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -39270,7 +39629,7 @@ fi done echo $ac_n "checking for gdImagePaletteCopy in -lgd""... $ac_c" 1>&6 -echo "configure:39274: checking for gdImagePaletteCopy in -lgd" >&5 +echo "configure:39633: checking for gdImagePaletteCopy in -lgd" >&5 ac_lib_var=`echo gd'_'gdImagePaletteCopy | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -39278,7 +39637,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:39652: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -39418,7 +39777,7 @@ fi done echo $ac_n "checking for gdImageCreateFromPng in -lgd""... $ac_c" 1>&6 -echo "configure:39422: checking for gdImageCreateFromPng in -lgd" >&5 +echo "configure:39781: checking for gdImageCreateFromPng in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageCreateFromPng | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -39426,7 +39785,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:39800: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -39566,7 +39925,7 @@ fi done echo $ac_n "checking for gdImageCreateFromGif in -lgd""... $ac_c" 1>&6 -echo "configure:39570: checking for gdImageCreateFromGif in -lgd" >&5 +echo "configure:39929: checking for gdImageCreateFromGif in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageCreateFromGif | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -39574,7 +39933,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:39948: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -39714,7 +40073,7 @@ fi done echo $ac_n "checking for gdImageGif in -lgd""... $ac_c" 1>&6 -echo "configure:39718: checking for gdImageGif in -lgd" >&5 +echo "configure:40077: checking for gdImageGif in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageGif | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -39722,7 +40081,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:40096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -39862,7 +40221,7 @@ fi done echo $ac_n "checking for gdImageWBMP in -lgd""... $ac_c" 1>&6 -echo "configure:39866: checking for gdImageWBMP in -lgd" >&5 +echo "configure:40225: checking for gdImageWBMP in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageWBMP | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -39870,7 +40229,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:40244: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -40010,7 +40369,7 @@ fi done echo $ac_n "checking for gdImageCreateFromJpeg in -lgd""... $ac_c" 1>&6 -echo "configure:40014: checking for gdImageCreateFromJpeg in -lgd" >&5 +echo "configure:40373: checking for gdImageCreateFromJpeg in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageCreateFromJpeg | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -40018,7 +40377,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:40392: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -40158,7 +40517,7 @@ fi done echo $ac_n "checking for gdImageCreateFromXpm in -lgd""... $ac_c" 1>&6 -echo "configure:40162: checking for gdImageCreateFromXpm in -lgd" >&5 +echo "configure:40521: checking for gdImageCreateFromXpm in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageCreateFromXpm | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -40166,7 +40525,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:40540: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -40306,7 +40665,7 @@ fi done echo $ac_n "checking for gdImageCreateFromGd2 in -lgd""... $ac_c" 1>&6 -echo "configure:40310: checking for gdImageCreateFromGd2 in -lgd" >&5 +echo "configure:40669: checking for gdImageCreateFromGd2 in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageCreateFromGd2 | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -40314,7 +40673,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:40688: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -40454,7 +40813,7 @@ fi done echo $ac_n "checking for gdImageCreateTrueColor in -lgd""... $ac_c" 1>&6 -echo "configure:40458: checking for gdImageCreateTrueColor in -lgd" >&5 +echo "configure:40817: checking for gdImageCreateTrueColor in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageCreateTrueColor | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -40462,7 +40821,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:40836: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -40602,7 +40961,7 @@ fi done echo $ac_n "checking for gdImageSetTile in -lgd""... $ac_c" 1>&6 -echo "configure:40606: checking for gdImageSetTile in -lgd" >&5 +echo "configure:40965: checking for gdImageSetTile in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageSetTile | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -40610,7 +40969,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:40984: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -40750,7 +41109,7 @@ fi done echo $ac_n "checking for gdImageEllipse in -lgd""... $ac_c" 1>&6 -echo "configure:40754: checking for gdImageEllipse in -lgd" >&5 +echo "configure:41113: checking for gdImageEllipse in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageEllipse | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -40758,7 +41117,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:41132: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -40898,7 +41257,7 @@ fi done echo $ac_n "checking for gdImageSetBrush in -lgd""... $ac_c" 1>&6 -echo "configure:40902: checking for gdImageSetBrush in -lgd" >&5 +echo "configure:41261: checking for gdImageSetBrush in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageSetBrush | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -40906,7 +41265,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:41280: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -41046,7 +41405,7 @@ fi done echo $ac_n "checking for gdImageStringTTF in -lgd""... $ac_c" 1>&6 -echo "configure:41050: checking for gdImageStringTTF in -lgd" >&5 +echo "configure:41409: checking for gdImageStringTTF in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageStringTTF | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -41054,7 +41413,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:41428: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -41194,7 +41553,7 @@ fi done echo $ac_n "checking for gdImageStringFT in -lgd""... $ac_c" 1>&6 -echo "configure:41198: checking for gdImageStringFT in -lgd" >&5 +echo "configure:41557: checking for gdImageStringFT in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageStringFT | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -41202,7 +41561,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:41576: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -41342,7 +41701,7 @@ fi done echo $ac_n "checking for gdImageStringFTEx in -lgd""... $ac_c" 1>&6 -echo "configure:41346: checking for gdImageStringFTEx in -lgd" >&5 +echo "configure:41705: checking for gdImageStringFTEx in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageStringFTEx | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -41350,7 +41709,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:41724: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -41490,7 +41849,7 @@ fi done echo $ac_n "checking for gdImageColorClosestHWB in -lgd""... $ac_c" 1>&6 -echo "configure:41494: checking for gdImageColorClosestHWB in -lgd" >&5 +echo "configure:41853: checking for gdImageColorClosestHWB in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageColorClosestHWB | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -41498,7 +41857,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:41872: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -41638,7 +41997,7 @@ fi done echo $ac_n "checking for gdImageColorResolve in -lgd""... $ac_c" 1>&6 -echo "configure:41642: checking for gdImageColorResolve in -lgd" >&5 +echo "configure:42001: checking for gdImageColorResolve in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageColorResolve | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -41646,7 +42005,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:42020: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -41786,7 +42145,7 @@ fi done echo $ac_n "checking for gdImageGifCtx in -lgd""... $ac_c" 1>&6 -echo "configure:41790: checking for gdImageGifCtx in -lgd" >&5 +echo "configure:42149: checking for gdImageGifCtx in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageGifCtx | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -41794,7 +42153,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:42168: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -41934,7 +42293,7 @@ fi done echo $ac_n "checking for gdCacheCreate in -lgd""... $ac_c" 1>&6 -echo "configure:41938: checking for gdCacheCreate in -lgd" >&5 +echo "configure:42297: checking for gdCacheCreate in -lgd" >&5 ac_lib_var=`echo gd'_'gdCacheCreate | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -41942,7 +42301,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:42316: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -42082,7 +42441,7 @@ fi done echo $ac_n "checking for gdFontCacheShutdown in -lgd""... $ac_c" 1>&6 -echo "configure:42086: checking for gdFontCacheShutdown in -lgd" >&5 +echo "configure:42445: checking for gdFontCacheShutdown in -lgd" >&5 ac_lib_var=`echo gd'_'gdFontCacheShutdown | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -42090,7 +42449,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:42464: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -42230,7 +42589,7 @@ fi done echo $ac_n "checking for gdFreeFontCache in -lgd""... $ac_c" 1>&6 -echo "configure:42234: checking for gdFreeFontCache in -lgd" >&5 +echo "configure:42593: checking for gdFreeFontCache in -lgd" >&5 ac_lib_var=`echo gd'_'gdFreeFontCache | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -42238,7 +42597,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:42612: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -42378,7 +42737,7 @@ fi done echo $ac_n "checking for gdFontCacheMutexSetup in -lgd""... $ac_c" 1>&6 -echo "configure:42382: checking for gdFontCacheMutexSetup in -lgd" >&5 +echo "configure:42741: checking for gdFontCacheMutexSetup in -lgd" >&5 ac_lib_var=`echo gd'_'gdFontCacheMutexSetup | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -42386,7 +42745,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:42760: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -42526,7 +42885,7 @@ fi done echo $ac_n "checking for gdNewDynamicCtxEx in -lgd""... $ac_c" 1>&6 -echo "configure:42530: checking for gdNewDynamicCtxEx in -lgd" >&5 +echo "configure:42889: checking for gdNewDynamicCtxEx in -lgd" >&5 ac_lib_var=`echo gd'_'gdNewDynamicCtxEx | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -42534,7 +42893,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:42908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -42600,7 +42959,7 @@ fi old_CPPFLAGS=$CPPFLAGS CPPFLAGS=-I$GD_INCLUDE cat > conftest.$ac_ext < @@ -42614,7 +42973,7 @@ ctx->gd_free = 1; ; return 0; } EOF -if { (eval echo configure:42618: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:42977: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <<\EOF @@ -42945,7 +43304,7 @@ EOF else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:43319: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -43107,7 +43466,7 @@ fi done echo $ac_n "checking for gdImageCreate in -lgd""... $ac_c" 1>&6 -echo "configure:43111: checking for gdImageCreate in -lgd" >&5 +echo "configure:43470: checking for gdImageCreate in -lgd" >&5 ac_lib_var=`echo gd'_'gdImageCreate | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -43115,7 +43474,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgd $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:43489: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -43191,7 +43550,7 @@ fi php_with_gettext=no echo $ac_n "checking for GNU gettext support""... $ac_c" 1>&6 -echo "configure:43195: checking for GNU gettext support" >&5 +echo "configure:43554: checking for GNU gettext support" >&5 # Check whether --with-gettext or --without-gettext was given. if test "${with_gettext+set}" = set; then withval="$with_gettext" @@ -43249,7 +43608,7 @@ if test "$PHP_GETTEXT" != "no"; then O_LDFLAGS=$LDFLAGS LDFLAGS="$LDFLAGS -L$GETTEXT_LIBDIR" echo $ac_n "checking for bindtextdomain in -lintl""... $ac_c" 1>&6 -echo "configure:43253: checking for bindtextdomain in -lintl" >&5 +echo "configure:43612: checking for bindtextdomain in -lintl" >&5 ac_lib_var=`echo intl'_'bindtextdomain | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -43257,7 +43616,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lintl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:43631: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -43290,7 +43649,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for bindtextdomain in -lc""... $ac_c" 1>&6 -echo "configure:43294: checking for bindtextdomain in -lc" >&5 +echo "configure:43653: checking for bindtextdomain in -lc" >&5 ac_lib_var=`echo c'_'bindtextdomain | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -43298,7 +43657,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lc $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:43672: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -43773,7 +44132,7 @@ EOF echo $ac_n "checking for ngettext in -l$GETTEXT_CHECK_IN_LIB""... $ac_c" 1>&6 -echo "configure:43777: checking for ngettext in -l$GETTEXT_CHECK_IN_LIB" >&5 +echo "configure:44136: checking for ngettext in -l$GETTEXT_CHECK_IN_LIB" >&5 ac_lib_var=`echo $GETTEXT_CHECK_IN_LIB'_'ngettext | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -43781,7 +44140,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$GETTEXT_CHECK_IN_LIB $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:44155: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -43816,7 +44175,7 @@ else fi echo $ac_n "checking for dngettext in -l$GETTEXT_CHECK_IN_LIB""... $ac_c" 1>&6 -echo "configure:43820: checking for dngettext in -l$GETTEXT_CHECK_IN_LIB" >&5 +echo "configure:44179: checking for dngettext in -l$GETTEXT_CHECK_IN_LIB" >&5 ac_lib_var=`echo $GETTEXT_CHECK_IN_LIB'_'dngettext | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -43824,7 +44183,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$GETTEXT_CHECK_IN_LIB $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:44198: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -43859,7 +44218,7 @@ else fi echo $ac_n "checking for dcngettext in -l$GETTEXT_CHECK_IN_LIB""... $ac_c" 1>&6 -echo "configure:43863: checking for dcngettext in -l$GETTEXT_CHECK_IN_LIB" >&5 +echo "configure:44222: checking for dcngettext in -l$GETTEXT_CHECK_IN_LIB" >&5 ac_lib_var=`echo $GETTEXT_CHECK_IN_LIB'_'dcngettext | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -43867,7 +44226,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$GETTEXT_CHECK_IN_LIB $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:44241: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -43902,7 +44261,7 @@ else fi echo $ac_n "checking for bind_textdomain_codeset in -l$GETTEXT_CHECK_IN_LIB""... $ac_c" 1>&6 -echo "configure:43906: checking for bind_textdomain_codeset in -l$GETTEXT_CHECK_IN_LIB" >&5 +echo "configure:44265: checking for bind_textdomain_codeset in -l$GETTEXT_CHECK_IN_LIB" >&5 ac_lib_var=`echo $GETTEXT_CHECK_IN_LIB'_'bind_textdomain_codeset | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -43910,7 +44269,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$GETTEXT_CHECK_IN_LIB $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:44284: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -43952,7 +44311,7 @@ fi php_with_gmp=no echo $ac_n "checking for GNU MP support""... $ac_c" 1>&6 -echo "configure:43956: checking for GNU MP support" >&5 +echo "configure:44315: checking for GNU MP support" >&5 # Check whether --with-gmp or --without-gmp was given. if test "${with_gmp+set}" = set; then withval="$with_gmp" @@ -44103,7 +44462,7 @@ if test "$PHP_GMP" != "no"; then done echo $ac_n "checking for __gmp_randinit_lc_2exp_size in -lgmp""... $ac_c" 1>&6 -echo "configure:44107: checking for __gmp_randinit_lc_2exp_size in -lgmp" >&5 +echo "configure:44466: checking for __gmp_randinit_lc_2exp_size in -lgmp" >&5 ac_lib_var=`echo gmp'_'__gmp_randinit_lc_2exp_size | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -44111,7 +44470,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgmp $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:44485: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -44247,7 +44606,7 @@ else done echo $ac_n "checking for gmp_randinit_lc_2exp_size in -lgmp""... $ac_c" 1>&6 -echo "configure:44251: checking for gmp_randinit_lc_2exp_size in -lgmp" >&5 +echo "configure:44610: checking for gmp_randinit_lc_2exp_size in -lgmp" >&5 ac_lib_var=`echo gmp'_'gmp_randinit_lc_2exp_size | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -44255,7 +44614,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgmp $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:44629: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -44738,7 +45097,7 @@ fi php_with_mhash=no echo $ac_n "checking for mhash support""... $ac_c" 1>&6 -echo "configure:44742: checking for mhash support" >&5 +echo "configure:45101: checking for mhash support" >&5 # Check whether --with-mhash or --without-mhash was given. if test "${with_mhash+set}" = set; then withval="$with_mhash" @@ -44785,7 +45144,7 @@ echo "$ac_t""$ext_output" 1>&6 php_enable_hash=yes echo $ac_n "checking whether to enable hash support""... $ac_c" 1>&6 -echo "configure:44789: checking whether to enable hash support" >&5 +echo "configure:45148: checking whether to enable hash support" >&5 # Check whether --enable-hash or --disable-hash was given. if test "${enable_hash+set}" = set; then enableval="$enable_hash" @@ -44846,7 +45205,7 @@ EOF echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6 -echo "configure:44850: checking whether byte ordering is bigendian" >&5 +echo "configure:45209: checking whether byte ordering is bigendian" >&5 if eval "test \"`echo '$''{'ac_cv_c_bigendian_php'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -44856,7 +45215,7 @@ else ac_cv_c_bigendian_php=unknown else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:45235: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_bigendian_php=yes else @@ -44897,7 +45256,7 @@ EOF echo $ac_n "checking size of short""... $ac_c" 1>&6 -echo "configure:44901: checking size of short" >&5 +echo "configure:45260: checking size of short" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -44905,7 +45264,7 @@ else ac_cv_sizeof_short=2 else cat > conftest.$ac_ext < int main() @@ -44916,7 +45275,7 @@ int main() return(0); } EOF -if { (eval echo configure:44920: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:45279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_short=`cat conftestval` else @@ -44936,7 +45295,7 @@ EOF echo $ac_n "checking size of int""... $ac_c" 1>&6 -echo "configure:44940: checking size of int" >&5 +echo "configure:45299: checking size of int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -44944,7 +45303,7 @@ else ac_cv_sizeof_int=4 else cat > conftest.$ac_ext < int main() @@ -44955,7 +45314,7 @@ int main() return(0); } EOF -if { (eval echo configure:44959: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:45318: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_int=`cat conftestval` else @@ -44975,7 +45334,7 @@ EOF echo $ac_n "checking size of long""... $ac_c" 1>&6 -echo "configure:44979: checking size of long" >&5 +echo "configure:45338: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -44983,7 +45342,7 @@ else ac_cv_sizeof_long=4 else cat > conftest.$ac_ext < int main() @@ -44994,7 +45353,7 @@ int main() return(0); } EOF -if { (eval echo configure:44998: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:45357: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -45014,7 +45373,7 @@ EOF echo $ac_n "checking size of long long""... $ac_c" 1>&6 -echo "configure:45018: checking size of long long" >&5 +echo "configure:45377: checking size of long long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -45022,7 +45381,7 @@ else ac_cv_sizeof_long_long=8 else cat > conftest.$ac_ext < int main() @@ -45033,7 +45392,7 @@ int main() return(0); } EOF -if { (eval echo configure:45037: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:45396: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long_long=`cat conftestval` else @@ -45382,7 +45741,7 @@ fi php_with_iconv=yes echo $ac_n "checking for iconv support""... $ac_c" 1>&6 -echo "configure:45386: checking for iconv support" >&5 +echo "configure:45745: checking for iconv support" >&5 # Check whether --with-iconv or --without-iconv was given. if test "${with_iconv+set}" = set; then withval="$with_iconv" @@ -45445,12 +45804,12 @@ if test "$PHP_ICONV" != "no"; then if test "$PHP_ICONV" = "yes"; then echo $ac_n "checking for iconv""... $ac_c" 1>&6 -echo "configure:45449: checking for iconv" >&5 +echo "configure:45808: checking for iconv" >&5 if eval "test \"`echo '$''{'ac_cv_func_iconv'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:45836: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_iconv=yes" else @@ -45494,12 +45853,12 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for libiconv""... $ac_c" 1>&6 -echo "configure:45498: checking for libiconv" >&5 +echo "configure:45857: checking for libiconv" >&5 if eval "test \"`echo '$''{'ac_cv_func_libiconv'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:45885: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_libiconv=yes" else @@ -45678,7 +46037,7 @@ EOF done echo $ac_n "checking for libiconv in -l$iconv_lib_name""... $ac_c" 1>&6 -echo "configure:45682: checking for libiconv in -l$iconv_lib_name" >&5 +echo "configure:46041: checking for libiconv in -l$iconv_lib_name" >&5 ac_lib_var=`echo $iconv_lib_name'_'libiconv | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -45686,7 +46045,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$iconv_lib_name $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:46060: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -45831,7 +46190,7 @@ else done echo $ac_n "checking for iconv in -l$iconv_lib_name""... $ac_c" 1>&6 -echo "configure:45835: checking for iconv in -l$iconv_lib_name" >&5 +echo "configure:46194: checking for iconv in -l$iconv_lib_name" >&5 ac_lib_var=`echo $iconv_lib_name'_'iconv | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -45839,7 +46198,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$iconv_lib_name $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:46213: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -46061,16 +46420,16 @@ else fi echo $ac_n "checking if iconv is glibc's""... $ac_c" 1>&6 -echo "configure:46065: checking if iconv is glibc's" >&5 +echo "configure:46424: checking if iconv is glibc's" >&5 cat > conftest.$ac_ext < int main() { gnu_get_libc_version(); ; return 0; } EOF -if { (eval echo configure:46074: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:46433: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""yes" 1>&6 @@ -46088,7 +46447,7 @@ rm -f conftest* if test -z "$iconv_impl_name"; then echo $ac_n "checking if using GNU libiconv""... $ac_c" 1>&6 -echo "configure:46092: checking if using GNU libiconv" >&5 +echo "configure:46451: checking if using GNU libiconv" >&5 php_iconv_old_ld="$LDFLAGS" LDFLAGS="-liconv $LDFLAGS" if test "$cross_compiling" = yes; then @@ -46098,7 +46457,7 @@ echo "configure:46092: checking if using GNU libiconv" >&5 else cat > conftest.$ac_ext < @@ -46108,7 +46467,7 @@ int main() { } EOF -if { (eval echo configure:46112: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:46471: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 @@ -46130,16 +46489,16 @@ fi if test -z "$iconv_impl_name"; then echo $ac_n "checking if iconv is Konstantin Chuguev's""... $ac_c" 1>&6 -echo "configure:46134: checking if iconv is Konstantin Chuguev's" >&5 +echo "configure:46493: checking if iconv is Konstantin Chuguev's" >&5 cat > conftest.$ac_ext < int main() { iconv_ccs_init(NULL, NULL); ; return 0; } EOF -if { (eval echo configure:46143: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:46502: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""yes" 1>&6 @@ -46158,18 +46517,18 @@ rm -f conftest* if test -z "$iconv_impl_name"; then echo $ac_n "checking if using IBM iconv""... $ac_c" 1>&6 -echo "configure:46162: checking if using IBM iconv" >&5 +echo "configure:46521: checking if using IBM iconv" >&5 php_iconv_old_ld="$LDFLAGS" LDFLAGS="-liconv $LDFLAGS" cat > conftest.$ac_ext < int main() { cstoccsid(""); ; return 0; } EOF -if { (eval echo configure:46173: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:46532: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""yes" 1>&6 @@ -46355,7 +46714,7 @@ EOF esac echo $ac_n "checking if iconv supports errno""... $ac_c" 1>&6 -echo "configure:46359: checking if iconv supports errno" >&5 +echo "configure:46718: checking if iconv supports errno" >&5 if test "$cross_compiling" = yes; then echo "$ac_t""no" 1>&6 @@ -46369,7 +46728,7 @@ EOF else cat > conftest.$ac_ext < @@ -46390,7 +46749,7 @@ int main() { } EOF -if { (eval echo configure:46394: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:46753: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 @@ -46422,9 +46781,9 @@ fi echo $ac_n "checking if your cpp allows macro usage in include lines""... $ac_c" 1>&6 -echo "configure:46426: checking if your cpp allows macro usage in include lines" >&5 +echo "configure:46785: checking if your cpp allows macro usage in include lines" >&5 cat > conftest.$ac_ext < @@ -46434,7 +46793,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:46438: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:46797: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* echo "$ac_t""yes" 1>&6 @@ -46790,7 +47149,7 @@ fi php_with_imap=no echo $ac_n "checking for IMAP support""... $ac_c" 1>&6 -echo "configure:46794: checking for IMAP support" >&5 +echo "configure:47153: checking for IMAP support" >&5 # Check whether --with-imap or --without-imap was given. if test "${with_imap+set}" = set; then withval="$with_imap" @@ -46837,7 +47196,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_kerberos=no echo $ac_n "checking for IMAP Kerberos support""... $ac_c" 1>&6 -echo "configure:46841: checking for IMAP Kerberos support" >&5 +echo "configure:47200: checking for IMAP Kerberos support" >&5 # Check whether --with-kerberos or --without-kerberos was given. if test "${with_kerberos+set}" = set; then withval="$with_kerberos" @@ -46863,7 +47222,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_imap_ssl=no echo $ac_n "checking for IMAP SSL support""... $ac_c" 1>&6 -echo "configure:46867: checking for IMAP SSL support" >&5 +echo "configure:47226: checking for IMAP SSL support" >&5 # Check whether --with-imap-ssl or --without-imap-ssl was given. if test "${with_imap_ssl+set}" = set; then withval="$with_imap_ssl" @@ -47270,7 +47629,7 @@ EOF done cat > conftest.$ac_ext < EOF @@ -47290,12 +47649,12 @@ rm -f conftest* old_CFLAGS=$CFLAGS CFLAGS="-I$IMAP_INC_DIR" echo $ac_n "checking for utf8_mime2text signature""... $ac_c" 1>&6 -echo "configure:47294: checking for utf8_mime2text signature" >&5 +echo "configure:47653: checking for utf8_mime2text signature" >&5 if eval "test \"`echo '$''{'ac_cv_utf8_mime2text'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -47308,7 +47667,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:47312: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:47671: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_utf8_mime2text=old @@ -47337,12 +47696,12 @@ EOF old_CFLAGS=$CFLAGS CFLAGS="-I$IMAP_INC_DIR" echo $ac_n "checking for U8T_CANONICAL""... $ac_c" 1>&6 -echo "configure:47341: checking for U8T_CANONICAL" >&5 +echo "configure:47700: checking for U8T_CANONICAL" >&5 if eval "test \"`echo '$''{'ac_cv_u8t_canonical'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -47353,7 +47712,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:47357: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:47716: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_u8t_canonical=yes @@ -47383,7 +47742,7 @@ echo "$ac_t""$ac_cv_u8t_canonical" 1>&6 old_CPPFLAGS=$CPPFLAGS CPPFLAGS=-I$IMAP_INC_DIR cat > conftest.$ac_ext <&6 -echo "configure:47506: checking for pam_start in -lpam" >&5 +echo "configure:47865: checking for pam_start in -lpam" >&5 ac_lib_var=`echo pam'_'pam_start | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -47510,7 +47869,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpam $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:47884: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -47676,7 +48035,7 @@ fi done echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 -echo "configure:47680: checking for crypt in -lcrypt" >&5 +echo "configure:48039: checking for crypt in -lcrypt" >&5 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -47684,7 +48043,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:48058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -47899,7 +48258,7 @@ fi # Extract the first word of "krb5-config", so it can be a program name with args. set dummy krb5-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:47903: checking for $ac_word" >&5 +echo "configure:48262: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_KRB5_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -48268,7 +48627,7 @@ else else cat > conftest.$ac_ext < EOF @@ -48309,7 +48668,7 @@ rm -f conftest* # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:48313: checking for $ac_word" >&5 +echo "configure:48672: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_PKG_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -48514,9 +48873,9 @@ fi old_CPPFLAGS=$CPPFLAGS CPPFLAGS=-I$OPENSSL_INCDIR echo $ac_n "checking for OpenSSL version""... $ac_c" 1>&6 -echo "configure:48518: checking for OpenSSL version" >&5 +echo "configure:48877: checking for OpenSSL version" >&5 cat > conftest.$ac_ext < @@ -48671,7 +49030,7 @@ rm -f conftest* done echo $ac_n "checking for CRYPTO_free in -lcrypto""... $ac_c" 1>&6 -echo "configure:48675: checking for CRYPTO_free in -lcrypto" >&5 +echo "configure:49034: checking for CRYPTO_free in -lcrypto" >&5 ac_lib_var=`echo crypto'_'CRYPTO_free | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -48679,7 +49038,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypto $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:49053: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -48847,7 +49206,7 @@ fi done echo $ac_n "checking for SSL_CTX_set_ssl_version in -lssl""... $ac_c" 1>&6 -echo "configure:48851: checking for SSL_CTX_set_ssl_version in -lssl" >&5 +echo "configure:49210: checking for SSL_CTX_set_ssl_version in -lssl" >&5 ac_lib_var=`echo ssl'_'SSL_CTX_set_ssl_version | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -48855,7 +49214,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lssl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:49229: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -48985,7 +49344,7 @@ else elif test -f "$IMAP_INC_DIR/linkage.c"; then cat > conftest.$ac_ext < EOF @@ -49016,7 +49375,7 @@ rm -f conftest* else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:49412: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -49085,7 +49444,7 @@ fi else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:49481: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -49145,7 +49504,7 @@ fi echo $ac_n "checking whether rfc822_output_address_list function present""... $ac_c" 1>&6 -echo "configure:49149: checking whether rfc822_output_address_list function present" >&5 +echo "configure:49508: checking whether rfc822_output_address_list function present" >&5 old_LIBS=$LIBS LIBS=" @@ -49157,7 +49516,7 @@ echo "configure:49149: checking whether rfc822_output_address_list function pres else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:49556: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -49222,7 +49581,7 @@ fi echo $ac_n "checking whether build with IMAP works""... $ac_c" 1>&6 -echo "configure:49226: checking whether build with IMAP works" >&5 +echo "configure:49585: checking whether build with IMAP works" >&5 old_LIBS=$LIBS @@ -49233,7 +49592,7 @@ echo "configure:49226: checking whether build with IMAP works" >&5 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:49629: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -49298,7 +49657,7 @@ fi php_with_interbase=no echo $ac_n "checking for InterBase support""... $ac_c" 1>&6 -echo "configure:49302: checking for InterBase support" >&5 +echo "configure:49661: checking for InterBase support" >&5 # Check whether --with-interbase or --without-interbase was given. if test "${with_interbase+set}" = set; then withval="$with_interbase" @@ -49448,7 +49807,7 @@ if test "$PHP_INTERBASE" != "no"; then done echo $ac_n "checking for isc_detach_database in -lfbclient""... $ac_c" 1>&6 -echo "configure:49452: checking for isc_detach_database in -lfbclient" >&5 +echo "configure:49811: checking for isc_detach_database in -lfbclient" >&5 ac_lib_var=`echo fbclient'_'isc_detach_database | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -49456,7 +49815,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lfbclient $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:49830: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -49594,7 +49953,7 @@ else done echo $ac_n "checking for isc_detach_database in -lgds""... $ac_c" 1>&6 -echo "configure:49598: checking for isc_detach_database in -lgds" >&5 +echo "configure:49957: checking for isc_detach_database in -lgds" >&5 ac_lib_var=`echo gds'_'isc_detach_database | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -49602,7 +49961,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgds $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:49976: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -49740,7 +50099,7 @@ else done echo $ac_n "checking for isc_detach_database in -lib_util""... $ac_c" 1>&6 -echo "configure:49744: checking for isc_detach_database in -lib_util" >&5 +echo "configure:50103: checking for isc_detach_database in -lib_util" >&5 ac_lib_var=`echo ib_util'_'isc_detach_database | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -49748,7 +50107,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lib_util $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:50122: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -50236,7 +50595,7 @@ fi php_enable_intl=no echo $ac_n "checking whether to enable internationalization support""... $ac_c" 1>&6 -echo "configure:50240: checking whether to enable internationalization support" >&5 +echo "configure:50599: checking whether to enable internationalization support" >&5 # Check whether --enable-intl or --disable-intl was given. if test "${enable_intl+set}" = set; then enableval="$enable_intl" @@ -50314,7 +50673,7 @@ ext_output=$PHP_ICU_DIR # Extract the first word of "icu-config", so it can be a program name with args. set dummy icu-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:50318: checking for $ac_word" >&5 +echo "configure:50677: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_ICU_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -50352,7 +50711,7 @@ fi fi echo $ac_n "checking for location of ICU headers and libraries""... $ac_c" 1>&6 -echo "configure:50356: checking for location of ICU headers and libraries" >&5 +echo "configure:50715: checking for location of ICU headers and libraries" >&5 icu_install_prefix=`$ICU_CONFIG --prefix 2> /dev/null` if test "$?" != "0" || test -z "$icu_install_prefix"; then @@ -50362,7 +50721,7 @@ echo "configure:50356: checking for location of ICU headers and libraries" >&5 echo "$ac_t""$icu_install_prefix" 1>&6 echo $ac_n "checking for ICU 3.4 or greater""... $ac_c" 1>&6 -echo "configure:50366: checking for ICU 3.4 or greater" >&5 +echo "configure:50725: checking for ICU 3.4 or greater" >&5 icu_version_full=`$ICU_CONFIG --version` ac_IFS=$IFS IFS="." @@ -50518,7 +50877,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:50522: checking for $ac_word" >&5 +echo "configure:50881: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CXX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -50550,7 +50909,7 @@ test -n "$CXX" || CXX="gcc" echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:50554: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 +echo "configure:50913: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) works" >&5 ac_ext=C # CXXFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -50561,12 +50920,12 @@ cross_compiling=$ac_cv_prog_cxx_cross cat > conftest.$ac_ext << EOF -#line 50565 "configure" +#line 50924 "configure" #include "confdefs.h" int main(){return(0);} EOF -if { (eval echo configure:50570: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:50929: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cxx_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -50592,12 +50951,12 @@ if test $ac_cv_prog_cxx_works = no; then { echo "configure: error: installation or configuration problem: C++ compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:50596: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:50955: checking whether the C++ compiler ($CXX $CXXFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cxx_cross" 1>&6 cross_compiling=$ac_cv_prog_cxx_cross echo $ac_n "checking whether we are using GNU C++""... $ac_c" 1>&6 -echo "configure:50601: checking whether we are using GNU C++" >&5 +echo "configure:50960: checking whether we are using GNU C++" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gxx'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -50606,7 +50965,7 @@ else yes; #endif EOF -if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:50610: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CXX-g++} -E conftest.C'; { (eval echo configure:50969: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gxx=yes else ac_cv_prog_gxx=no @@ -50625,7 +50984,7 @@ ac_test_CXXFLAGS="${CXXFLAGS+set}" ac_save_CXXFLAGS="$CXXFLAGS" CXXFLAGS= echo $ac_n "checking whether ${CXX-g++} accepts -g""... $ac_c" 1>&6 -echo "configure:50629: checking whether ${CXX-g++} accepts -g" >&5 +echo "configure:50988: checking whether ${CXX-g++} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cxx_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -50666,7 +51025,7 @@ for ac_declaration in \ 'void exit (int);' do cat > conftest.$ac_ext < $ac_declaration @@ -50674,7 +51033,7 @@ int main() { exit (42); ; return 0; } EOF -if { (eval echo configure:50678: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:51037: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then : else echo "configure: failed program was:" >&5 @@ -50684,14 +51043,14 @@ else fi rm -f conftest* cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:51054: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* break else @@ -50708,7 +51067,7 @@ fi echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6 -echo "configure:50712: checking how to run the C++ preprocessor" >&5 +echo "configure:51071: checking how to run the C++ preprocessor" >&5 if test -z "$CXXCPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -50721,12 +51080,12 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross CXXCPP="${CXX-g++} -E" cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:50730: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:51089: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -51267,7 +51626,7 @@ fi php_enable_json=yes echo $ac_n "checking whether to enable JavaScript Object Serialization support""... $ac_c" 1>&6 -echo "configure:51271: checking whether to enable JavaScript Object Serialization support" >&5 +echo "configure:51630: checking whether to enable JavaScript Object Serialization support" >&5 # Check whether --enable-json or --disable-json was given. if test "${enable_json+set}" = set; then enableval="$enable_json" @@ -51316,12 +51675,12 @@ if test "$PHP_JSON" != "no"; then EOF echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:51320: checking for ANSI C header files" >&5 +echo "configure:51679: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -51329,7 +51688,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:51333: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:51692: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -51346,7 +51705,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -51364,7 +51723,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -51385,7 +51744,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -51396,7 +51755,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:51400: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:51759: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -51746,7 +52105,7 @@ fi php_with_ldap=no echo $ac_n "checking for LDAP support""... $ac_c" 1>&6 -echo "configure:51750: checking for LDAP support" >&5 +echo "configure:52109: checking for LDAP support" >&5 # Check whether --with-ldap or --without-ldap was given. if test "${with_ldap+set}" = set; then withval="$with_ldap" @@ -51793,7 +52152,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_ldap_sasl=no echo $ac_n "checking for LDAP Cyrus SASL support""... $ac_c" 1>&6 -echo "configure:51797: checking for LDAP Cyrus SASL support" >&5 +echo "configure:52156: checking for LDAP Cyrus SASL support" >&5 # Check whether --with-ldap-sasl or --without-ldap-sasl was given. if test "${with_ldap_sasl+set}" = set; then withval="$with_ldap_sasl" @@ -54138,19 +54497,19 @@ EOF LIBS="$LIBS $LDAP_SHARED_LIBADD" echo $ac_n "checking for 3 arg ldap_set_rebind_proc""... $ac_c" 1>&6 -echo "configure:54142: checking for 3 arg ldap_set_rebind_proc" >&5 +echo "configure:54501: checking for 3 arg ldap_set_rebind_proc" >&5 if eval "test \"`echo '$''{'ac_cv_3arg_setrebindproc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { ldap_set_rebind_proc(0,0,0) ; return 0; } EOF -if { (eval echo configure:54154: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:54513: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_3arg_setrebindproc=yes else @@ -54173,12 +54532,12 @@ EOF for ac_func in ldap_parse_result ldap_parse_reference ldap_start_tls_s do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:54177: checking for $ac_func" >&5 +echo "configure:54536: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:54564: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -54363,7 +54722,7 @@ EOF done echo $ac_n "checking for sasl_version in -lldap""... $ac_c" 1>&6 -echo "configure:54367: checking for sasl_version in -lldap" >&5 +echo "configure:54726: checking for sasl_version in -lldap" >&5 ac_lib_var=`echo ldap'_'sasl_version | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -54371,7 +54730,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lldap $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:54745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -54551,12 +54910,12 @@ fi fi echo $ac_n "checking for ldap_bind_s""... $ac_c" 1>&6 -echo "configure:54555: checking for ldap_bind_s" >&5 +echo "configure:54914: checking for ldap_bind_s" >&5 if eval "test \"`echo '$''{'ac_cv_func_ldap_bind_s'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:54942: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_ldap_bind_s=yes" else @@ -54632,7 +54991,7 @@ fi php_enable_mbstring=no echo $ac_n "checking whether to enable multibyte string support""... $ac_c" 1>&6 -echo "configure:54636: checking whether to enable multibyte string support" >&5 +echo "configure:54995: checking whether to enable multibyte string support" >&5 # Check whether --enable-mbstring or --disable-mbstring was given. if test "${enable_mbstring+set}" = set; then enableval="$enable_mbstring" @@ -54679,7 +55038,7 @@ echo "$ac_t""$ext_output" 1>&6 php_enable_mbregex=yes echo $ac_n "checking whether to enable multibyte regex support""... $ac_c" 1>&6 -echo "configure:54683: checking whether to enable multibyte regex support" >&5 +echo "configure:55042: checking whether to enable multibyte regex support" >&5 # Check whether --enable-mbregex or --disable-mbregex was given. if test "${enable_mbregex+set}" = set; then enableval="$enable_mbregex" @@ -54705,7 +55064,7 @@ echo "$ac_t""$ext_output" 1>&6 php_enable_mbregex_backtrack=yes echo $ac_n "checking whether to check multibyte regex backtrack""... $ac_c" 1>&6 -echo "configure:54709: checking whether to check multibyte regex backtrack" >&5 +echo "configure:55068: checking whether to check multibyte regex backtrack" >&5 # Check whether --enable-mbregex_backtrack or --disable-mbregex_backtrack was given. if test "${enable_mbregex_backtrack+set}" = set; then enableval="$enable_mbregex_backtrack" @@ -54731,7 +55090,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_libmbfl=no echo $ac_n "checking for external libmbfl""... $ac_c" 1>&6 -echo "configure:54735: checking for external libmbfl" >&5 +echo "configure:55094: checking for external libmbfl" >&5 # Check whether --with-libmbfl or --without-libmbfl was given. if test "${with_libmbfl+set}" = set; then withval="$with_libmbfl" @@ -54757,7 +55116,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_onig=no echo $ac_n "checking for external oniguruma""... $ac_c" 1>&6 -echo "configure:54761: checking for external oniguruma" >&5 +echo "configure:55120: checking for external oniguruma" >&5 # Check whether --with-onig or --without-onig was given. if test "${with_onig+set}" = set; then withval="$with_onig" @@ -54801,7 +55160,7 @@ EOF fi echo $ac_n "checking for variable length prototypes and stdarg.h""... $ac_c" 1>&6 -echo "configure:54805: checking for variable length prototypes and stdarg.h" >&5 +echo "configure:55164: checking for variable length prototypes and stdarg.h" >&5 if eval "test \"`echo '$''{'cv_php_mbstring_stdarg'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -54819,7 +55178,7 @@ else else cat > conftest.$ac_ext < @@ -54834,7 +55193,7 @@ int foo(int x, ...) { int main() { return foo(10, "", 3.14); } EOF -if { (eval echo configure:54838: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:55197: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then cv_php_mbstring_stdarg=yes else @@ -54855,17 +55214,17 @@ echo "$ac_t""$cv_php_mbstring_stdarg" 1>&6 do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:54859: checking for $ac_hdr" >&5 +echo "configure:55218: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:54869: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:55228: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -54892,7 +55251,7 @@ fi done echo $ac_n "checking size of int""... $ac_c" 1>&6 -echo "configure:54896: checking size of int" >&5 +echo "configure:55255: checking size of int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -54900,7 +55259,7 @@ else ac_cv_sizeof_int=4 else cat > conftest.$ac_ext < int main() @@ -54911,7 +55270,7 @@ int main() return(0); } EOF -if { (eval echo configure:54915: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:55274: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_int=`cat conftestval` else @@ -54931,7 +55290,7 @@ EOF echo $ac_n "checking size of short""... $ac_c" 1>&6 -echo "configure:54935: checking size of short" >&5 +echo "configure:55294: checking size of short" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -54939,7 +55298,7 @@ else ac_cv_sizeof_short=2 else cat > conftest.$ac_ext < int main() @@ -54950,7 +55309,7 @@ int main() return(0); } EOF -if { (eval echo configure:54954: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:55313: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_short=`cat conftestval` else @@ -54970,7 +55329,7 @@ EOF echo $ac_n "checking size of long""... $ac_c" 1>&6 -echo "configure:54974: checking size of long" >&5 +echo "configure:55333: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -54978,7 +55337,7 @@ else ac_cv_sizeof_long=4 else cat > conftest.$ac_ext < int main() @@ -54989,7 +55348,7 @@ int main() return(0); } EOF -if { (eval echo configure:54993: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:55352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -55009,12 +55368,12 @@ EOF echo $ac_n "checking for working const""... $ac_c" 1>&6 -echo "configure:55013: checking for working const" >&5 +echo "configure:55372: checking for working const" >&5 if eval "test \"`echo '$''{'ac_cv_c_const'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:55426: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_const=yes else @@ -55084,12 +55443,12 @@ EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 -echo "configure:55088: checking whether time.h and sys/time.h may both be included" >&5 +echo "configure:55447: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -55098,7 +55457,7 @@ int main() { struct tm *tp; ; return 0; } EOF -if { (eval echo configure:55102: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:55461: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else @@ -55121,19 +55480,19 @@ fi # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:55125: checking for working alloca.h" >&5 +echo "configure:55484: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:55137: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:55496: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -55154,12 +55513,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:55158: checking for alloca" >&5 +echo "configure:55517: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:55550: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -55219,12 +55578,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:55223: checking whether alloca needs Cray hooks" >&5 +echo "configure:55582: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:55253: checking for $ac_func" >&5 +echo "configure:55612: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:55640: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -55304,7 +55663,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:55308: checking stack direction for C alloca" >&5 +echo "configure:55667: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -55312,7 +55671,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:55694: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -55353,7 +55712,7 @@ EOF fi echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 -echo "configure:55357: checking for 8-bit clean memcmp" >&5 +echo "configure:55716: checking for 8-bit clean memcmp" >&5 if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -55361,7 +55720,7 @@ else ac_cv_func_memcmp_clean=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:55734: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_memcmp_clean=yes else @@ -55390,17 +55749,17 @@ test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}" ac_safe=`echo "stdarg.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for stdarg.h""... $ac_c" 1>&6 -echo "configure:55394: checking for stdarg.h" >&5 +echo "configure:55753: checking for stdarg.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:55404: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:55763: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -55630,7 +55989,7 @@ EOF done echo $ac_n "checking for onig_init in -lonig""... $ac_c" 1>&6 -echo "configure:55634: checking for onig_init in -lonig" >&5 +echo "configure:55993: checking for onig_init in -lonig" >&5 ac_lib_var=`echo onig'_'onig_init | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -55638,7 +55997,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lonig $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:56012: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -55875,9 +56234,9 @@ fi done echo $ac_n "checking if oniguruma has an invalid entry for KOI8 encoding""... $ac_c" 1>&6 -echo "configure:55879: checking if oniguruma has an invalid entry for KOI8 encoding" >&5 +echo "configure:56238: checking if oniguruma has an invalid entry for KOI8 encoding" >&5 cat > conftest.$ac_ext < @@ -55888,7 +56247,7 @@ return (int)(ONIG_ENCODING_KOI8 + 1); ; return 0; } EOF -if { (eval echo configure:55892: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:56251: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* echo "$ac_t""no" 1>&6 @@ -56183,7 +56542,7 @@ EOF done echo $ac_n "checking for mbfl_buffer_converter_new in -lmbfl""... $ac_c" 1>&6 -echo "configure:56187: checking for mbfl_buffer_converter_new in -lmbfl" >&5 +echo "configure:56546: checking for mbfl_buffer_converter_new in -lmbfl" >&5 ac_lib_var=`echo mbfl'_'mbfl_buffer_converter_new | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -56191,7 +56550,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lmbfl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:56565: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -56839,7 +57198,7 @@ fi php_with_mcrypt=no echo $ac_n "checking for mcrypt support""... $ac_c" 1>&6 -echo "configure:56843: checking for mcrypt support" >&5 +echo "configure:57202: checking for mcrypt support" >&5 # Check whether --with-mcrypt or --without-mcrypt was given. if test "${with_mcrypt+set}" = set; then withval="$with_mcrypt" @@ -56895,9 +57254,9 @@ if test "$PHP_MCRYPT" != "no"; then old_CPPFLAGS=$CPPFLAGS CPPFLAGS=-I$MCRYPT_DIR/include echo $ac_n "checking for libmcrypt version""... $ac_c" 1>&6 -echo "configure:56899: checking for libmcrypt version" >&5 +echo "configure:57258: checking for libmcrypt version" >&5 cat > conftest.$ac_ext < @@ -57021,7 +57380,7 @@ rm -f conftest* done echo $ac_n "checking for mcrypt_module_open in -lmcrypt""... $ac_c" 1>&6 -echo "configure:57025: checking for mcrypt_module_open in -lmcrypt" >&5 +echo "configure:57384: checking for mcrypt_module_open in -lmcrypt" >&5 ac_lib_var=`echo mcrypt'_'mcrypt_module_open | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -57029,7 +57388,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lmcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:57403: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -57193,7 +57552,7 @@ else done echo $ac_n "checking for mcrypt_module_open in -lmcrypt""... $ac_c" 1>&6 -echo "configure:57197: checking for mcrypt_module_open in -lmcrypt" >&5 +echo "configure:57556: checking for mcrypt_module_open in -lmcrypt" >&5 ac_lib_var=`echo mcrypt'_'mcrypt_module_open | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -57201,7 +57560,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lmcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:57575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -57685,7 +58044,7 @@ fi php_with_mssql=no echo $ac_n "checking for MSSQL support via FreeTDS""... $ac_c" 1>&6 -echo "configure:57689: checking for MSSQL support via FreeTDS" >&5 +echo "configure:58048: checking for MSSQL support via FreeTDS" >&5 # Check whether --with-mssql or --without-mssql was given. if test "${with_mssql+set}" = set; then withval="$with_mssql" @@ -58186,7 +58545,7 @@ EOF fi echo $ac_n "checking for dnet_addr in -ldnet_stub""... $ac_c" 1>&6 -echo "configure:58190: checking for dnet_addr in -ldnet_stub" >&5 +echo "configure:58549: checking for dnet_addr in -ldnet_stub" >&5 ac_lib_var=`echo dnet_stub'_'dnet_addr | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -58194,7 +58553,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldnet_stub $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:58568: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -58349,7 +58708,7 @@ fi php_with_mysql=no echo $ac_n "checking for MySQL support""... $ac_c" 1>&6 -echo "configure:58353: checking for MySQL support" >&5 +echo "configure:58712: checking for MySQL support" >&5 # Check whether --with-mysql or --without-mysql was given. if test "${with_mysql+set}" = set; then withval="$with_mysql" @@ -58396,7 +58755,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_mysql_sock=no echo $ac_n "checking for specified location of the MySQL UNIX socket""... $ac_c" 1>&6 -echo "configure:58400: checking for specified location of the MySQL UNIX socket" >&5 +echo "configure:58759: checking for specified location of the MySQL UNIX socket" >&5 # Check whether --with-mysql-sock or --without-mysql-sock was given. if test "${with_mysql_sock+set}" = set; then withval="$with_mysql_sock" @@ -58423,7 +58782,7 @@ if test -z "$PHP_ZLIB_DIR"; then php_with_zlib_dir=no echo $ac_n "checking for the location of libz""... $ac_c" 1>&6 -echo "configure:58427: checking for the location of libz" >&5 +echo "configure:58786: checking for the location of libz" >&5 # Check whether --with-zlib-dir or --without-zlib-dir was given. if test "${with_zlib_dir+set}" = set; then withval="$with_zlib_dir" @@ -58452,7 +58811,7 @@ if test "$PHP_MYSQL" = "mysqlnd"; then elif test "$PHP_MYSQL" != "no"; then echo $ac_n "checking for MySQL UNIX socket location""... $ac_c" 1>&6 -echo "configure:58456: checking for MySQL UNIX socket location" >&5 +echo "configure:58815: checking for MySQL UNIX socket location" >&5 if test "$PHP_MYSQL_SOCK" != "no" && test "$PHP_MYSQL_SOCK" != "yes"; then MYSQL_SOCK=$PHP_MYSQL_SOCK cat >> confdefs.h <&2; exit 1; } done echo $ac_n "checking for mysql_close in -l$MYSQL_LIBNAME""... $ac_c" 1>&6 -echo "configure:58647: checking for mysql_close in -l$MYSQL_LIBNAME" >&5 +echo "configure:59006: checking for mysql_close in -l$MYSQL_LIBNAME" >&5 ac_lib_var=`echo $MYSQL_LIBNAME'_'mysql_close | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -58651,7 +59010,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$MYSQL_LIBNAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:59025: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -58885,7 +59244,7 @@ else done echo $ac_n "checking for mysql_error in -l$MYSQL_LIBNAME""... $ac_c" 1>&6 -echo "configure:58889: checking for mysql_error in -l$MYSQL_LIBNAME" >&5 +echo "configure:59248: checking for mysql_error in -l$MYSQL_LIBNAME" >&5 ac_lib_var=`echo $MYSQL_LIBNAME'_'mysql_error | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -58893,7 +59252,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$MYSQL_LIBNAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:59267: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -59059,7 +59418,7 @@ fi done echo $ac_n "checking for mysql_errno in -l$MYSQL_LIBNAME""... $ac_c" 1>&6 -echo "configure:59063: checking for mysql_errno in -l$MYSQL_LIBNAME" >&5 +echo "configure:59422: checking for mysql_errno in -l$MYSQL_LIBNAME" >&5 ac_lib_var=`echo $MYSQL_LIBNAME'_'mysql_errno | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -59067,7 +59426,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$MYSQL_LIBNAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:59441: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -59603,7 +59962,7 @@ fi php_with_mysqli=no echo $ac_n "checking for MySQLi support""... $ac_c" 1>&6 -echo "configure:59607: checking for MySQLi support" >&5 +echo "configure:59966: checking for MySQLi support" >&5 # Check whether --with-mysqli or --without-mysqli was given. if test "${with_mysqli+set}" = set; then withval="$with_mysqli" @@ -59650,7 +60009,7 @@ echo "$ac_t""$ext_output" 1>&6 php_enable_embedded_mysqli=no echo $ac_n "checking whether to enable embedded MySQLi support""... $ac_c" 1>&6 -echo "configure:59654: checking whether to enable embedded MySQLi support" >&5 +echo "configure:60013: checking whether to enable embedded MySQLi support" >&5 # Check whether --enable-embedded_mysqli or --disable-embedded_mysqli was given. if test "${enable_embedded_mysqli+set}" = set; then enableval="$enable_embedded_mysqli" @@ -59804,7 +60163,7 @@ EOF done echo $ac_n "checking for mysql_set_server_option in -l$MYSQL_LIB_NAME""... $ac_c" 1>&6 -echo "configure:59808: checking for mysql_set_server_option in -l$MYSQL_LIB_NAME" >&5 +echo "configure:60167: checking for mysql_set_server_option in -l$MYSQL_LIB_NAME" >&5 ac_lib_var=`echo $MYSQL_LIB_NAME'_'mysql_set_server_option | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -59812,7 +60171,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$MYSQL_LIB_NAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:60186: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -60071,7 +60430,7 @@ EOF done echo $ac_n "checking for mysql_set_character_set in -l$MYSQL_LIB_NAME""... $ac_c" 1>&6 -echo "configure:60075: checking for mysql_set_character_set in -l$MYSQL_LIB_NAME" >&5 +echo "configure:60434: checking for mysql_set_character_set in -l$MYSQL_LIB_NAME" >&5 ac_lib_var=`echo $MYSQL_LIB_NAME'_'mysql_set_character_set | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -60079,7 +60438,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$MYSQL_LIB_NAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:60453: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -60234,7 +60593,7 @@ fi done echo $ac_n "checking for mysql_stmt_next_result in -l$MYSQL_LIB_NAME""... $ac_c" 1>&6 -echo "configure:60238: checking for mysql_stmt_next_result in -l$MYSQL_LIB_NAME" >&5 +echo "configure:60597: checking for mysql_stmt_next_result in -l$MYSQL_LIB_NAME" >&5 ac_lib_var=`echo $MYSQL_LIB_NAME'_'mysql_stmt_next_result | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -60242,7 +60601,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$MYSQL_LIB_NAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:60616: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -60639,7 +60998,7 @@ fi php_with_oci8=no echo $ac_n "checking for Oracle (OCI8) support""... $ac_c" 1>&6 -echo "configure:60643: checking for Oracle (OCI8) support" >&5 +echo "configure:61002: checking for Oracle (OCI8) support" >&5 # Check whether --with-oci8 or --without-oci8 was given. if test "${with_oci8+set}" = set; then withval="$with_oci8" @@ -60690,7 +61049,7 @@ if test "$PHP_OCI8" != "no"; then echo $ac_n "checking PHP version""... $ac_c" 1>&6 -echo "configure:60694: checking PHP version" >&5 +echo "configure:61053: checking PHP version" >&5 tmp_version=$PHP_VERSION if test -z "$tmp_version"; then @@ -60722,7 +61081,7 @@ echo "configure:60694: checking PHP version" >&5 echo $ac_n "checking size of long int""... $ac_c" 1>&6 -echo "configure:60726: checking size of long int" >&5 +echo "configure:61085: checking size of long int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -60730,7 +61089,7 @@ else ac_cv_sizeof_long_int=4 else cat > conftest.$ac_ext < int main() @@ -60741,7 +61100,7 @@ int main() return(0); } EOF -if { (eval echo configure:60745: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:61104: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long_int=`cat conftestval` else @@ -60761,7 +61120,7 @@ EOF echo $ac_n "checking checking if we're on a 64-bit platform""... $ac_c" 1>&6 -echo "configure:60765: checking checking if we're on a 64-bit platform" >&5 +echo "configure:61124: checking checking if we're on a 64-bit platform" >&5 if test "$ac_cv_sizeof_long_int" = "4"; then echo "$ac_t""no" 1>&6 PHP_OCI8_OH_LIBDIR=lib32 @@ -60805,7 +61164,7 @@ echo "configure:60765: checking checking if we're on a 64-bit platform" >&5 if test "$PHP_OCI8_INSTANT_CLIENT" = "no"; then echo $ac_n "checking Oracle ORACLE_HOME install directory""... $ac_c" 1>&6 -echo "configure:60809: checking Oracle ORACLE_HOME install directory" >&5 +echo "configure:61168: checking Oracle ORACLE_HOME install directory" >&5 if test "$PHP_OCI8" = "yes"; then OCI8_DIR=$ORACLE_HOME @@ -60816,7 +61175,7 @@ echo "configure:60809: checking Oracle ORACLE_HOME install directory" >&5 echo $ac_n "checking ORACLE_HOME library validity""... $ac_c" 1>&6 -echo "configure:60820: checking ORACLE_HOME library validity" >&5 +echo "configure:61179: checking ORACLE_HOME library validity" >&5 if test ! -d "$OCI8_DIR"; then { echo "configure: error: ${OCI8_DIR} is not a directory" 1>&2; exit 1; } fi @@ -61157,7 +61516,7 @@ echo "configure:60820: checking ORACLE_HOME library validity" >&5 echo $ac_n "checking Oracle version""... $ac_c" 1>&6 -echo "configure:61161: checking Oracle version" >&5 +echo "configure:61520: checking Oracle version" >&5 if test -s "$OCI8_DIR/orainst/unix.rgs"; then OCI8_ORACLE_VERSION=`grep '"ocommon"' $OCI8_DIR/orainst/unix.rgs | $PHP_OCI8_SED 's/ */:/g' | cut -d: -f 6 | cut -c 2-4` test -z "$OCI8_ORACLE_VERSION" && OCI8_ORACLE_VERSION=7.3 @@ -61287,7 +61646,7 @@ echo "configure:61161: checking Oracle version" >&5 done echo $ac_n "checking for OCIEnvNlsCreate in -lclntsh""... $ac_c" 1>&6 -echo "configure:61291: checking for OCIEnvNlsCreate in -lclntsh" >&5 +echo "configure:61650: checking for OCIEnvNlsCreate in -lclntsh" >&5 ac_lib_var=`echo clntsh'_'OCIEnvNlsCreate | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -61295,7 +61654,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lclntsh $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:61669: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -61743,7 +62102,7 @@ EOF else echo $ac_n "checking Oracle Instant Client directory""... $ac_c" 1>&6 -echo "configure:61747: checking Oracle Instant Client directory" >&5 +echo "configure:62106: checking Oracle Instant Client directory" >&5 if test "$PHP_OCI8_INSTANT_CLIENT" = "yes"; then PHP_OCI8_INSTANT_CLIENT=`ls -d /usr/lib/oracle/*/client${PHP_OCI8_IC_LIBDIR_SUFFIX}/lib/libclntsh.* 2> /dev/null | tail -1 | $PHP_OCI8_SED -e 's#/libclntsh[^/]*##'` @@ -61756,7 +62115,7 @@ echo "configure:61747: checking Oracle Instant Client directory" >&5 OCI8_DIR=$PHP_OCI8_INSTANT_CLIENT echo $ac_n "checking Oracle Instant Client SDK header directory""... $ac_c" 1>&6 -echo "configure:61760: checking Oracle Instant Client SDK header directory" >&5 +echo "configure:62119: checking Oracle Instant Client SDK header directory" >&5 OCISDKRPMINC=`echo "$PHP_OCI8_INSTANT_CLIENT" | $PHP_OCI8_SED -e 's!^/usr/lib/oracle/\(.*\)/client\('${PHP_OCI8_IC_LIBDIR_SUFFIX}'\)*/lib/*$!/usr/include/oracle/\1/client\2!'` @@ -61965,7 +62324,7 @@ echo "configure:61760: checking Oracle Instant Client SDK header directory" >&5 echo $ac_n "checking Oracle Instant Client version""... $ac_c" 1>&6 -echo "configure:61969: checking Oracle Instant Client version" >&5 +echo "configure:62328: checking Oracle Instant Client version" >&5 if test -f $PHP_OCI8_INSTANT_CLIENT/libnnz11.$SHLIB_SUFFIX_NAME; then if test -f $PHP_OCI8_INSTANT_CLIENT/libclntsh.$SHLIB_SUFFIX_NAME.11.1; then if test ! -f $PHP_OCI8_INSTANT_CLIENT/libclntsh.$SHLIB_SUFFIX_NAME; then @@ -62447,7 +62806,7 @@ esac if test "$PHP_ADABAS" != "no"; then echo $ac_n "checking for Adabas support""... $ac_c" 1>&6 -echo "configure:62451: checking for Adabas support" >&5 +echo "configure:62810: checking for Adabas support" >&5 if test "$PHP_ADABAS" = "yes"; then PHP_ADABAS=/usr/local fi @@ -62653,7 +63012,7 @@ esac if test "$PHP_SAPDB" != "no"; then echo $ac_n "checking for SAP DB support""... $ac_c" 1>&6 -echo "configure:62657: checking for SAP DB support" >&5 +echo "configure:63016: checking for SAP DB support" >&5 if test "$PHP_SAPDB" = "yes"; then PHP_SAPDB=/usr/local fi @@ -62789,7 +63148,7 @@ esac if test "$PHP_SOLID" != "no"; then echo $ac_n "checking for Solid support""... $ac_c" 1>&6 -echo "configure:62793: checking for Solid support" >&5 +echo "configure:63152: checking for Solid support" >&5 if test "$PHP_SOLID" = "yes"; then PHP_SOLID=/usr/local/solid fi @@ -62816,7 +63175,7 @@ EOF echo "$ac_t""$ext_output" 1>&6 echo $ac_n "checking Solid library file""... $ac_c" 1>&6 -echo "configure:62820: checking Solid library file" >&5 +echo "configure:63179: checking Solid library file" >&5 ac_solid_uname_r=`uname -r 2>/dev/null` ac_solid_uname_s=`uname -s 2>/dev/null` case $ac_solid_uname_s in @@ -62940,7 +63299,7 @@ esac if test "$PHP_IBM_DB2" != "no"; then echo $ac_n "checking for IBM DB2 support""... $ac_c" 1>&6 -echo "configure:62944: checking for IBM DB2 support" >&5 +echo "configure:63303: checking for IBM DB2 support" >&5 if test "$PHP_IBM_DB2" = "yes"; then ODBC_INCDIR=/home/db2inst1/sqllib/include ODBC_LIBDIR=/home/db2inst1/sqllib/lib @@ -62971,7 +63330,7 @@ fi else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:63345: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -63066,7 +63425,7 @@ esac if test "$PHP_ODBCROUTER" != "no"; then echo $ac_n "checking for ODBCRouter.com support""... $ac_c" 1>&6 -echo "configure:63070: checking for ODBCRouter.com support" >&5 +echo "configure:63429: checking for ODBCRouter.com support" >&5 if test "$PHP_ODBCROUTER" = "yes"; then PHP_ODBCROUTER=/usr fi @@ -63133,7 +63492,7 @@ esac if test "$PHP_EMPRESS" != "no"; then echo $ac_n "checking for Empress support""... $ac_c" 1>&6 -echo "configure:63137: checking for Empress support" >&5 +echo "configure:63496: checking for Empress support" >&5 if test "$PHP_EMPRESS" = "yes"; then ODBC_INCDIR=$EMPRESSPATH/include/odbc ODBC_LIBDIR=$EMPRESSPATH/shlib @@ -63151,7 +63510,7 @@ EOF echo "$ac_t""$ext_output" 1>&6 echo $ac_n "checking Empress library file""... $ac_c" 1>&6 -echo "configure:63155: checking Empress library file" >&5 +echo "configure:63514: checking Empress library file" >&5 ODBC_LIBS=`echo $ODBC_LIBDIR/libempodbccl.so | cut -d' ' -f1` if test ! -f $ODBC_LIBS; then ODBC_LIBS=`echo $ODBC_LIBDIR/libempodbccl.so | cut -d' ' -f1` @@ -63210,7 +63569,7 @@ esac if test "$PHP_EMPRESS_BCS" != "no"; then echo $ac_n "checking for Empress local access support""... $ac_c" 1>&6 -echo "configure:63214: checking for Empress local access support" >&5 +echo "configure:63573: checking for Empress local access support" >&5 if test "$PHP_EMPRESS_BCS" = "yes"; then ODBC_INCDIR=$EMPRESSPATH/include/odbc ODBC_LIBDIR=$EMPRESSPATH/shlib @@ -63244,7 +63603,7 @@ EOF echo "$ac_t""$ext_output" 1>&6 echo $ac_n "checking Empress local access library file""... $ac_c" 1>&6 -echo "configure:63248: checking Empress local access library file" >&5 +echo "configure:63607: checking Empress local access library file" >&5 ODBCBCS_LIBS=`echo $ODBC_LIBDIR/libempodbcbcs.a | cut -d' ' -f1` if test ! -f $ODBCBCS_LIBS; then ODBCBCS_LIBS=`echo $ODBC_LIBDIR/libempodbcbcs.a | cut -d' ' -f1` @@ -63303,7 +63662,7 @@ esac if test "$PHP_BIRDSTEP" != "no"; then echo $ac_n "checking for Birdstep support""... $ac_c" 1>&6 -echo "configure:63307: checking for Birdstep support" >&5 +echo "configure:63666: checking for Birdstep support" >&5 if test "$PHP_BIRDSTEP" = "yes"; then ODBC_INCDIR=/usr/local/birdstep/include ODBC_LIBDIR=/usr/local/birdstep/lib @@ -63418,7 +63777,7 @@ esac if test "$PHP_CUSTOM_ODBC" != "no"; then echo $ac_n "checking for a custom ODBC support""... $ac_c" 1>&6 -echo "configure:63422: checking for a custom ODBC support" >&5 +echo "configure:63781: checking for a custom ODBC support" >&5 if test "$PHP_CUSTOM_ODBC" = "yes"; then PHP_CUSTOM_ODBC=/usr/local fi @@ -63485,7 +63844,7 @@ esac if test "$PHP_IODBC" != "no"; then echo $ac_n "checking for iODBC support""... $ac_c" 1>&6 -echo "configure:63489: checking for iODBC support" >&5 +echo "configure:63848: checking for iODBC support" >&5 if test "$PHP_IODBC" = "yes"; then PHP_IODBC=/usr/local fi @@ -63634,7 +63993,7 @@ esac if test "$PHP_ESOOB" != "no"; then echo $ac_n "checking for Easysoft ODBC-ODBC Bridge support""... $ac_c" 1>&6 -echo "configure:63638: checking for Easysoft ODBC-ODBC Bridge support" >&5 +echo "configure:63997: checking for Easysoft ODBC-ODBC Bridge support" >&5 if test "$PHP_ESOOB" = "yes"; then PHP_ESOOB=/usr/local/easysoft/oob/client fi @@ -63701,7 +64060,7 @@ esac if test "$PHP_UNIXODBC" != "no"; then echo $ac_n "checking for unixODBC support""... $ac_c" 1>&6 -echo "configure:63705: checking for unixODBC support" >&5 +echo "configure:64064: checking for unixODBC support" >&5 if test "$PHP_UNIXODBC" = "yes"; then PHP_UNIXODBC=/usr/local fi @@ -63773,7 +64132,7 @@ esac if test "$PHP_DBMAKER" != "no"; then echo $ac_n "checking for DBMaker support""... $ac_c" 1>&6 -echo "configure:63777: checking for DBMaker support" >&5 +echo "configure:64136: checking for DBMaker support" >&5 if test "$PHP_DBMAKER" = "yes"; then # find dbmaker's home directory DBMAKER_HOME=`grep "^dbmaker:" /etc/passwd | $AWK -F: '{print $6}'` @@ -64335,7 +64694,7 @@ fi php_enable_pcntl=no echo $ac_n "checking whether to enable pcntl support""... $ac_c" 1>&6 -echo "configure:64339: checking whether to enable pcntl support" >&5 +echo "configure:64698: checking whether to enable pcntl support" >&5 # Check whether --enable-pcntl or --disable-pcntl was given. if test "${enable_pcntl+set}" = set; then enableval="$enable_pcntl" @@ -64382,12 +64741,12 @@ if test "$PHP_PCNTL" != "no"; then for ac_func in fork do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:64386: checking for $ac_func" >&5 +echo "configure:64745: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:64773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -64441,12 +64800,12 @@ done for ac_func in waitpid do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:64445: checking for $ac_func" >&5 +echo "configure:64804: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:64832: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -64500,12 +64859,12 @@ done for ac_func in sigaction do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:64504: checking for $ac_func" >&5 +echo "configure:64863: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:64891: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -64559,12 +64918,12 @@ done for ac_func in getpriority setpriority wait3 sigprocmask sigwaitinfo sigtimedwait do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:64563: checking for $ac_func" >&5 +echo "configure:64922: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:64950: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -64912,7 +65271,7 @@ fi php_enable_pdo=yes echo $ac_n "checking whether to enable PDO support""... $ac_c" 1>&6 -echo "configure:64916: checking whether to enable PDO support" >&5 +echo "configure:65275: checking whether to enable PDO support" >&5 # Check whether --enable-pdo or --disable-pdo was given. if test "${enable_pdo+set}" = set; then enableval="$enable_pdo" @@ -65349,7 +65708,7 @@ fi php_with_pdo_dblib=no echo $ac_n "checking for PDO_DBLIB support via FreeTDS""... $ac_c" 1>&6 -echo "configure:65353: checking for PDO_DBLIB support via FreeTDS" >&5 +echo "configure:65712: checking for PDO_DBLIB support via FreeTDS" >&5 # Check whether --with-pdo-dblib or --without-pdo-dblib was given. if test "${with_pdo_dblib+set}" = set; then withval="$with_pdo_dblib" @@ -65569,13 +65928,13 @@ if test "$PHP_PDO_DBLIB" != "no"; then echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:65573: checking for PDO includes" >&5 +echo "configure:65932: checking for PDO includes" >&5 if eval "test \"`echo '$''{'pdo_inc_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:65579: checking for PDO includes" >&5 +echo "configure:65938: checking for PDO includes" >&5 if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then pdo_inc_path=$abs_srcdir/ext elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then @@ -65889,7 +66248,7 @@ EOF fi echo $ac_n "checking for dnet_addr in -ldnet_stub""... $ac_c" 1>&6 -echo "configure:65893: checking for dnet_addr in -ldnet_stub" >&5 +echo "configure:66252: checking for dnet_addr in -ldnet_stub" >&5 ac_lib_var=`echo dnet_stub'_'dnet_addr | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -65897,7 +66256,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldnet_stub $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:66271: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -66069,7 +66428,7 @@ fi php_with_pdo_firebird=no echo $ac_n "checking for Firebird support for PDO""... $ac_c" 1>&6 -echo "configure:66073: checking for Firebird support for PDO" >&5 +echo "configure:66432: checking for Firebird support for PDO" >&5 # Check whether --with-pdo-firebird or --without-pdo-firebird was given. if test "${with_pdo_firebird+set}" = set; then withval="$with_pdo_firebird" @@ -66226,7 +66585,7 @@ if test "$PHP_PDO_FIREBIRD" != "no"; then done echo $ac_n "checking for isc_detach_database in -lfbclient""... $ac_c" 1>&6 -echo "configure:66230: checking for isc_detach_database in -lfbclient" >&5 +echo "configure:66589: checking for isc_detach_database in -lfbclient" >&5 ac_lib_var=`echo fbclient'_'isc_detach_database | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -66234,7 +66593,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lfbclient $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:66608: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -66372,7 +66731,7 @@ else done echo $ac_n "checking for isc_detach_database in -lgds""... $ac_c" 1>&6 -echo "configure:66376: checking for isc_detach_database in -lgds" >&5 +echo "configure:66735: checking for isc_detach_database in -lgds" >&5 ac_lib_var=`echo gds'_'isc_detach_database | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -66380,7 +66739,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lgds $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:66754: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -66518,7 +66877,7 @@ else done echo $ac_n "checking for isc_detach_database in -lib_util""... $ac_c" 1>&6 -echo "configure:66522: checking for isc_detach_database in -lib_util" >&5 +echo "configure:66881: checking for isc_detach_database in -lib_util" >&5 ac_lib_var=`echo ib_util'_'isc_detach_database | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -66526,7 +66885,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lib_util $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:66900: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -66582,13 +66941,13 @@ fi echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:66586: checking for PDO includes" >&5 +echo "configure:66945: checking for PDO includes" >&5 if eval "test \"`echo '$''{'pdo_inc_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:66592: checking for PDO includes" >&5 +echo "configure:66951: checking for PDO includes" >&5 if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then pdo_inc_path=$abs_srcdir/ext elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then @@ -67060,7 +67419,7 @@ fi php_with_pdo_mysql=no echo $ac_n "checking for MySQL support for PDO""... $ac_c" 1>&6 -echo "configure:67064: checking for MySQL support for PDO" >&5 +echo "configure:67423: checking for MySQL support for PDO" >&5 # Check whether --with-pdo-mysql or --without-pdo-mysql was given. if test "${with_pdo_mysql+set}" = set; then withval="$with_pdo_mysql" @@ -67108,7 +67467,7 @@ if test -z "$PHP_ZLIB_DIR"; then php_with_zlib_dir=no echo $ac_n "checking for the location of libz""... $ac_c" 1>&6 -echo "configure:67112: checking for the location of libz" >&5 +echo "configure:67471: checking for the location of libz" >&5 # Check whether --with-zlib-dir or --without-zlib-dir was given. if test "${with_zlib_dir+set}" = set; then withval="$with_zlib_dir" @@ -67151,7 +67510,7 @@ EOF EOF echo $ac_n "checking for mysql_config""... $ac_c" 1>&6 -echo "configure:67155: checking for mysql_config" >&5 +echo "configure:67514: checking for mysql_config" >&5 if test -f $PHP_PDO_MYSQL && test -x $PHP_PDO_MYSQL ; then PDO_MYSQL_CONFIG=$PHP_PDO_MYSQL @@ -67185,7 +67544,7 @@ echo "configure:67155: checking for mysql_config" >&5 # Extract the first word of "sed", so it can be a program name with args. set dummy sed; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:67189: checking for $ac_word" >&5 +echo "configure:67548: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_SED'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -67234,7 +67593,7 @@ fi else echo "$ac_t""not found" 1>&6 echo $ac_n "checking for mysql install under $PDO_MYSQL_DIR""... $ac_c" 1>&6 -echo "configure:67238: checking for mysql install under $PDO_MYSQL_DIR" >&5 +echo "configure:67597: checking for mysql install under $PDO_MYSQL_DIR" >&5 if test -r $PDO_MYSQL_DIR/include/mysql; then PDO_MYSQL_INC_DIR=$PDO_MYSQL_DIR/include/mysql else @@ -67390,7 +67749,7 @@ EOF done echo $ac_n "checking for mysql_query in -l$PDO_MYSQL_LIBNAME""... $ac_c" 1>&6 -echo "configure:67394: checking for mysql_query in -l$PDO_MYSQL_LIBNAME" >&5 +echo "configure:67753: checking for mysql_query in -l$PDO_MYSQL_LIBNAME" >&5 ac_lib_var=`echo $PDO_MYSQL_LIBNAME'_'mysql_query | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -67398,7 +67757,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$PDO_MYSQL_LIBNAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:67772: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -67762,7 +68121,7 @@ else done echo $ac_n "checking for mysql_query in -l$PDO_MYSQL_LIBNAME""... $ac_c" 1>&6 -echo "configure:67766: checking for mysql_query in -l$PDO_MYSQL_LIBNAME" >&5 +echo "configure:68125: checking for mysql_query in -l$PDO_MYSQL_LIBNAME" >&5 ac_lib_var=`echo $PDO_MYSQL_LIBNAME'_'mysql_query | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -67770,7 +68129,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$PDO_MYSQL_LIBNAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:68144: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -67936,7 +68295,7 @@ fi done echo $ac_n "checking for mysql_query in -l$PDO_MYSQL_LIBNAME""... $ac_c" 1>&6 -echo "configure:67940: checking for mysql_query in -l$PDO_MYSQL_LIBNAME" >&5 +echo "configure:68299: checking for mysql_query in -l$PDO_MYSQL_LIBNAME" >&5 ac_lib_var=`echo $PDO_MYSQL_LIBNAME'_'mysql_query | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -67944,7 +68303,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$PDO_MYSQL_LIBNAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:68318: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -68129,12 +68488,12 @@ fi for ac_func in mysql_commit mysql_stmt_prepare mysql_next_result mysql_sqlstate do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:68133: checking for $ac_func" >&5 +echo "configure:68492: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:68520: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -68187,13 +68546,13 @@ done echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:68191: checking for PDO includes" >&5 +echo "configure:68550: checking for PDO includes" >&5 if eval "test \"`echo '$''{'pdo_inc_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:68197: checking for PDO includes" >&5 +echo "configure:68556: checking for PDO includes" >&5 if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then pdo_inc_path=$abs_srcdir/ext elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then @@ -68551,6 +68910,9 @@ but you've either not enabled mysqlnd, or have disabled it. PDO_MYSQL_MODULE_TYPE=external + PHP_VAR_SUBST="$PHP_VAR_SUBST PDO_MYSQL_SHARED_LIBADD" + + PHP_VAR_SUBST="$PHP_VAR_SUBST PDO_MYSQL_MODULE_TYPE" @@ -68568,7 +68930,7 @@ SUPPORTED_LIB_VERS="9.0 10.1 11.1" # This caters for all Oracle 9.x, 10.x and 1 php_with_pdo_oci=no echo $ac_n "checking Oracle OCI support for PDO""... $ac_c" 1>&6 -echo "configure:68572: checking Oracle OCI support for PDO" >&5 +echo "configure:68934: checking Oracle OCI support for PDO" >&5 # Check whether --with-pdo-oci or --without-pdo-oci was given. if test "${with_pdo_oci+set}" = set; then withval="$with_pdo_oci" @@ -68618,7 +68980,7 @@ if test "$PHP_PDO_OCI" != "no"; then fi echo $ac_n "checking Oracle Install-Dir""... $ac_c" 1>&6 -echo "configure:68622: checking Oracle Install-Dir" >&5 +echo "configure:68984: checking Oracle Install-Dir" >&5 if test "$PHP_PDO_OCI" = "yes" || test -z "$PHP_PDO_OCI"; then PDO_OCI_DIR=$ORACLE_HOME else @@ -68627,7 +68989,7 @@ echo "configure:68622: checking Oracle Install-Dir" >&5 echo "$ac_t""$PHP_PDO_OCI" 1>&6 echo $ac_n "checking if that is sane""... $ac_c" 1>&6 -echo "configure:68631: checking if that is sane" >&5 +echo "configure:68993: checking if that is sane" >&5 if test -z "$PDO_OCI_DIR"; then { echo "configure: error: You need to tell me where to find your Oracle Instant Client SDK, or set ORACLE_HOME. @@ -68640,7 +69002,7 @@ You need to tell me where to find your Oracle Instant Client SDK, or set ORACLE_ PDO_OCI_IC_PREFIX="`echo $PDO_OCI_DIR | cut -d, -f2`" PDO_OCI_IC_VERS="`echo $PDO_OCI_DIR | cut -d, -f3`" echo $ac_n "checking for oci.h""... $ac_c" 1>&6 -echo "configure:68644: checking for oci.h" >&5 +echo "configure:69006: checking for oci.h" >&5 if test -f $PDO_OCI_IC_PREFIX/include/oracle/$PDO_OCI_IC_VERS/client/oci.h ; then if test "$PDO_OCI_IC_PREFIX/include/oracle/$PDO_OCI_IC_VERS/client" != "/usr/include"; then @@ -68789,7 +69151,7 @@ echo "configure:68644: checking for oci.h" >&5 else echo $ac_n "checking size of long int""... $ac_c" 1>&6 -echo "configure:68793: checking size of long int" >&5 +echo "configure:69155: checking size of long int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -68797,7 +69159,7 @@ else ac_cv_sizeof_long_int=4 else cat > conftest.$ac_ext < int main() @@ -68808,7 +69170,7 @@ int main() return(0); } EOF -if { (eval echo configure:68812: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:69174: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long_int=`cat conftestval` else @@ -68828,7 +69190,7 @@ EOF echo $ac_n "checking if we're on a 64-bit platform""... $ac_c" 1>&6 -echo "configure:68832: checking if we're on a 64-bit platform" >&5 +echo "configure:69194: checking if we're on a 64-bit platform" >&5 if test "$ac_cv_sizeof_long_int" = "4" ; then echo "$ac_t""no" 1>&6 TMP_PDO_OCI_LIB_DIR="$PDO_OCI_DIR/lib32" @@ -68838,7 +69200,7 @@ echo "configure:68832: checking if we're on a 64-bit platform" >&5 fi echo $ac_n "checking OCI8 libraries dir""... $ac_c" 1>&6 -echo "configure:68842: checking OCI8 libraries dir" >&5 +echo "configure:69204: checking OCI8 libraries dir" >&5 if test -d "$PDO_OCI_DIR/lib" && test ! -d "$PDO_OCI_DIR/lib32"; then PDO_OCI_LIB_DIR="$PDO_OCI_DIR/lib" elif test ! -d "$PDO_OCI_DIR/lib" && test -d "$PDO_OCI_DIR/lib32"; then @@ -69205,7 +69567,7 @@ echo "configure:68842: checking OCI8 libraries dir" >&5 fi echo $ac_n "checking Oracle version""... $ac_c" 1>&6 -echo "configure:69209: checking Oracle version" >&5 +echo "configure:69571: checking Oracle version" >&5 for OCI_VER in $SUPPORTED_LIB_VERS; do if test -f $PDO_OCI_DIR/lib/libclntsh.$SHLIB_SUFFIX_NAME.$OCI_VER; then PDO_OCI_VERSION="$OCI_VER" @@ -69387,7 +69749,7 @@ echo "configure:69209: checking Oracle version" >&5 done echo $ac_n "checking for OCIEnvCreate in -lclntsh""... $ac_c" 1>&6 -echo "configure:69391: checking for OCIEnvCreate in -lclntsh" >&5 +echo "configure:69753: checking for OCIEnvCreate in -lclntsh" >&5 ac_lib_var=`echo clntsh'_'OCIEnvCreate | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -69395,7 +69757,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lclntsh $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:69772: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -69540,7 +69902,7 @@ fi done echo $ac_n "checking for OCIEnvNlsCreate in -lclntsh""... $ac_c" 1>&6 -echo "configure:69544: checking for OCIEnvNlsCreate in -lclntsh" >&5 +echo "configure:69906: checking for OCIEnvNlsCreate in -lclntsh" >&5 ac_lib_var=`echo clntsh'_'OCIEnvNlsCreate | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -69548,7 +69910,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lclntsh $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:69925: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -69693,7 +70055,7 @@ fi done echo $ac_n "checking for OCILobIsTemporary in -lclntsh""... $ac_c" 1>&6 -echo "configure:69697: checking for OCILobIsTemporary in -lclntsh" >&5 +echo "configure:70059: checking for OCILobIsTemporary in -lclntsh" >&5 ac_lib_var=`echo clntsh'_'OCILobIsTemporary | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -69701,7 +70063,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lclntsh $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:70078: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -69842,7 +70204,7 @@ else done echo $ac_n "checking for OCILobIsTemporary in -locijdbc8""... $ac_c" 1>&6 -echo "configure:69846: checking for OCILobIsTemporary in -locijdbc8" >&5 +echo "configure:70208: checking for OCILobIsTemporary in -locijdbc8" >&5 ac_lib_var=`echo ocijdbc8'_'OCILobIsTemporary | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -69850,7 +70212,7 @@ else ac_save_LIBS="$LIBS" LIBS="-locijdbc8 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:70227: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -70022,7 +70384,7 @@ fi done echo $ac_n "checking for OCICollAssign in -lclntsh""... $ac_c" 1>&6 -echo "configure:70026: checking for OCICollAssign in -lclntsh" >&5 +echo "configure:70388: checking for OCICollAssign in -lclntsh" >&5 ac_lib_var=`echo clntsh'_'OCICollAssign | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -70030,7 +70392,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lclntsh $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:70407: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -70175,7 +70537,7 @@ fi done echo $ac_n "checking for OCIStmtFetch2 in -lclntsh""... $ac_c" 1>&6 -echo "configure:70179: checking for OCIStmtFetch2 in -lclntsh" >&5 +echo "configure:70541: checking for OCIStmtFetch2 in -lclntsh" >&5 ac_lib_var=`echo clntsh'_'OCIStmtFetch2 | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -70183,7 +70545,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lclntsh $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:70560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -70233,13 +70595,13 @@ fi echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:70237: checking for PDO includes" >&5 +echo "configure:70599: checking for PDO includes" >&5 if eval "test \"`echo '$''{'pdo_inc_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:70243: checking for PDO includes" >&5 +echo "configure:70605: checking for PDO includes" >&5 if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then pdo_inc_path=$abs_srcdir/ext elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then @@ -70607,7 +70969,7 @@ fi php_with_pdo_odbc=no echo $ac_n "checking for ODBC v3 support for PDO""... $ac_c" 1>&6 -echo "configure:70611: checking for ODBC v3 support for PDO" >&5 +echo "configure:70973: checking for ODBC v3 support for PDO" >&5 # Check whether --with-pdo-odbc or --without-pdo-odbc was given. if test "${with_pdo_odbc+set}" = set; then withval="$with_pdo_odbc" @@ -70662,13 +71024,13 @@ if test "$PHP_PDO_ODBC" != "no"; then echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:70666: checking for PDO includes" >&5 +echo "configure:71028: checking for PDO includes" >&5 if eval "test \"`echo '$''{'pdo_inc_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:70672: checking for PDO includes" >&5 +echo "configure:71034: checking for PDO includes" >&5 if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then pdo_inc_path=$abs_srcdir/ext elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then @@ -70689,7 +71051,7 @@ echo "$ac_t""$pdo_inc_path" 1>&6 echo $ac_n "checking for selected PDO ODBC flavour""... $ac_c" 1>&6 -echo "configure:70693: checking for selected PDO ODBC flavour" >&5 +echo "configure:71055: checking for selected PDO ODBC flavour" >&5 pdo_odbc_flavour="`echo $PHP_PDO_ODBC | cut -d, -f1`" pdo_odbc_dir="`echo $PHP_PDO_ODBC | cut -d, -f2`" @@ -70768,7 +71130,7 @@ echo "configure:70693: checking for selected PDO ODBC flavour" >&5 echo $ac_n "checking for odbc.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70772: checking for odbc.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71134: checking for odbc.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/odbc.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70782,7 +71144,7 @@ EOF echo $ac_n "checking for odbcsdk.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70786: checking for odbcsdk.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71148: checking for odbcsdk.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/odbcsdk.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70796,7 +71158,7 @@ EOF echo $ac_n "checking for iodbc.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70800: checking for iodbc.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71162: checking for iodbc.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/iodbc.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70810,7 +71172,7 @@ EOF echo $ac_n "checking for sqlunix.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70814: checking for sqlunix.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71176: checking for sqlunix.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/sqlunix.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70824,7 +71186,7 @@ EOF echo $ac_n "checking for sqltypes.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70828: checking for sqltypes.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71190: checking for sqltypes.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/sqltypes.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70838,7 +71200,7 @@ EOF echo $ac_n "checking for sqlucode.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70842: checking for sqlucode.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71204: checking for sqlucode.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/sqlucode.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70852,7 +71214,7 @@ EOF echo $ac_n "checking for sql.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70856: checking for sql.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71218: checking for sql.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/sql.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70866,7 +71228,7 @@ EOF echo $ac_n "checking for isql.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70870: checking for isql.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71232: checking for isql.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/isql.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70880,7 +71242,7 @@ EOF echo $ac_n "checking for sqlext.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70884: checking for sqlext.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71246: checking for sqlext.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/sqlext.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70894,7 +71256,7 @@ EOF echo $ac_n "checking for isqlext.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70898: checking for isqlext.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71260: checking for isqlext.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/isqlext.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70908,7 +71270,7 @@ EOF echo $ac_n "checking for udbcext.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70912: checking for udbcext.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71274: checking for udbcext.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/udbcext.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70922,7 +71284,7 @@ EOF echo $ac_n "checking for sqlcli1.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70926: checking for sqlcli1.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71288: checking for sqlcli1.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/sqlcli1.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70936,7 +71298,7 @@ EOF echo $ac_n "checking for LibraryManager.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70940: checking for LibraryManager.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71302: checking for LibraryManager.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/LibraryManager.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70950,7 +71312,7 @@ EOF echo $ac_n "checking for cli0core.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70954: checking for cli0core.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71316: checking for cli0core.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/cli0core.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70964,7 +71326,7 @@ EOF echo $ac_n "checking for cli0ext.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70968: checking for cli0ext.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71330: checking for cli0ext.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/cli0ext.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70978,7 +71340,7 @@ EOF echo $ac_n "checking for cli0cli.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70982: checking for cli0cli.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71344: checking for cli0cli.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/cli0cli.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -70992,7 +71354,7 @@ EOF echo $ac_n "checking for cli0defs.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:70996: checking for cli0defs.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71358: checking for cli0defs.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/cli0defs.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -71006,7 +71368,7 @@ EOF echo $ac_n "checking for cli0env.h in $PDO_ODBC_INCDIR""... $ac_c" 1>&6 -echo "configure:71010: checking for cli0env.h in $PDO_ODBC_INCDIR" >&5 +echo "configure:71372: checking for cli0env.h in $PDO_ODBC_INCDIR" >&5 if test -f "$PDO_ODBC_INCDIR/cli0env.h"; then php_pdo_have_header=yes cat >> confdefs.h <<\EOF @@ -71212,7 +71574,7 @@ EOF done echo $ac_n "checking for SQLBindCol in -l$pdo_odbc_def_lib""... $ac_c" 1>&6 -echo "configure:71216: checking for SQLBindCol in -l$pdo_odbc_def_lib" >&5 +echo "configure:71578: checking for SQLBindCol in -l$pdo_odbc_def_lib" >&5 ac_lib_var=`echo $pdo_odbc_def_lib'_'SQLBindCol | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -71220,7 +71582,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$pdo_odbc_def_lib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:71597: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -71346,7 +71708,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then done echo $ac_n "checking for SQLAllocHandle in -l$pdo_odbc_def_lib""... $ac_c" 1>&6 -echo "configure:71350: checking for SQLAllocHandle in -l$pdo_odbc_def_lib" >&5 +echo "configure:71712: checking for SQLAllocHandle in -l$pdo_odbc_def_lib" >&5 ac_lib_var=`echo $pdo_odbc_def_lib'_'SQLAllocHandle | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -71354,7 +71716,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$pdo_odbc_def_lib $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:71731: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -71739,7 +72101,7 @@ fi php_with_pdo_pgsql=no echo $ac_n "checking for PostgreSQL support for PDO""... $ac_c" 1>&6 -echo "configure:71743: checking for PostgreSQL support for PDO" >&5 +echo "configure:72105: checking for PostgreSQL support for PDO" >&5 # Check whether --with-pdo-pgsql or --without-pdo-pgsql was given. if test "${with_pdo_pgsql+set}" = set; then withval="$with_pdo_pgsql" @@ -71801,7 +72163,7 @@ if test "$PHP_PDO_PGSQL" != "no"; then echo $ac_n "checking for pg_config""... $ac_c" 1>&6 -echo "configure:71805: checking for pg_config" >&5 +echo "configure:72167: checking for pg_config" >&5 for i in $PHP_PDO_PGSQL $PHP_PDO_PGSQL/bin /usr/local/pgsql/bin /usr/local/bin /usr/bin ""; do if test -x $i/pg_config; then PG_CONFIG="$i/pg_config" @@ -71865,13 +72227,13 @@ EOF echo $ac_n "checking for openssl dependencies""... $ac_c" 1>&6 -echo "configure:71869: checking for openssl dependencies" >&5 +echo "configure:72231: checking for openssl dependencies" >&5 if grep -q openssl $PGSQL_INCLUDE/libpq-fe.h ; then echo "$ac_t""yes" 1>&6 # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:71875: checking for $ac_word" >&5 +echo "configure:72237: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_PKG_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -71915,7 +72277,7 @@ fi old_LDFLAGS=$LDFLAGS LDFLAGS="-L$PGSQL_LIBDIR $LDFLAGS" echo $ac_n "checking for PQparameterStatus in -lpq""... $ac_c" 1>&6 -echo "configure:71919: checking for PQparameterStatus in -lpq" >&5 +echo "configure:72281: checking for PQparameterStatus in -lpq" >&5 ac_lib_var=`echo pq'_'PQparameterStatus | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -71923,7 +72285,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:72300: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -71963,7 +72325,7 @@ fi echo $ac_n "checking for PQprepare in -lpq""... $ac_c" 1>&6 -echo "configure:71967: checking for PQprepare in -lpq" >&5 +echo "configure:72329: checking for PQprepare in -lpq" >&5 ac_lib_var=`echo pq'_'PQprepare | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -71971,7 +72333,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:72348: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -72006,7 +72368,7 @@ else fi echo $ac_n "checking for PQescapeStringConn in -lpq""... $ac_c" 1>&6 -echo "configure:72010: checking for PQescapeStringConn in -lpq" >&5 +echo "configure:72372: checking for PQescapeStringConn in -lpq" >&5 ac_lib_var=`echo pq'_'PQescapeStringConn | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -72014,7 +72376,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:72391: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -72049,7 +72411,7 @@ else fi echo $ac_n "checking for PQescapeByteaConn in -lpq""... $ac_c" 1>&6 -echo "configure:72053: checking for PQescapeByteaConn in -lpq" >&5 +echo "configure:72415: checking for PQescapeByteaConn in -lpq" >&5 ac_lib_var=`echo pq'_'PQescapeByteaConn | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -72057,7 +72419,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:72434: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -72093,7 +72455,7 @@ fi echo $ac_n "checking for pg_encoding_to_char in -lpq""... $ac_c" 1>&6 -echo "configure:72097: checking for pg_encoding_to_char in -lpq" >&5 +echo "configure:72459: checking for pg_encoding_to_char in -lpq" >&5 ac_lib_var=`echo pq'_'pg_encoding_to_char | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -72101,7 +72463,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:72478: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -72276,13 +72638,13 @@ fi echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:72280: checking for PDO includes" >&5 +echo "configure:72642: checking for PDO includes" >&5 if eval "test \"`echo '$''{'pdo_inc_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:72286: checking for PDO includes" >&5 +echo "configure:72648: checking for PDO includes" >&5 if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then pdo_inc_path=$abs_srcdir/ext elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then @@ -72622,7 +72984,7 @@ fi php_with_pdo_sqlite=$PHP_PDO echo $ac_n "checking for sqlite 3 support for PDO""... $ac_c" 1>&6 -echo "configure:72626: checking for sqlite 3 support for PDO" >&5 +echo "configure:72988: checking for sqlite 3 support for PDO" >&5 # Check whether --with-pdo-sqlite or --without-pdo-sqlite was given. if test "${with_pdo_sqlite+set}" = set; then withval="$with_pdo_sqlite" @@ -72674,13 +73036,13 @@ if test "$PHP_PDO_SQLITE" != "no"; then echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:72678: checking for PDO includes" >&5 +echo "configure:73040: checking for PDO includes" >&5 if eval "test \"`echo '$''{'pdo_inc_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:72684: checking for PDO includes" >&5 +echo "configure:73046: checking for PDO includes" >&5 if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then pdo_inc_path=$abs_srcdir/ext elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then @@ -72709,7 +73071,7 @@ echo "$ac_t""$pdo_inc_path" 1>&6 PDO_SQLITE_DIR=$PHP_PDO_SQLITE else # search default path list echo $ac_n "checking for sqlite3 files in default path""... $ac_c" 1>&6 -echo "configure:72713: checking for sqlite3 files in default path" >&5 +echo "configure:73075: checking for sqlite3 files in default path" >&5 for i in $SEARCH_PATH ; do if test -r $i/$SEARCH_FOR; then PDO_SQLITE_DIR=$i @@ -72855,7 +73217,7 @@ echo "configure:72713: checking for sqlite3 files in default path" >&5 done echo $ac_n "checking for $LIBSYMBOL in -l$LIBNAME""... $ac_c" 1>&6 -echo "configure:72859: checking for $LIBSYMBOL in -l$LIBNAME" >&5 +echo "configure:73221: checking for $LIBSYMBOL in -l$LIBNAME" >&5 ac_lib_var=`echo $LIBNAME'_'$LIBSYMBOL | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -72863,7 +73225,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$LIBNAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:73240: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -73104,7 +73466,7 @@ fi done echo $ac_n "checking for sqlite3_key in -lsqlite3""... $ac_c" 1>&6 -echo "configure:73108: checking for sqlite3_key in -lsqlite3" >&5 +echo "configure:73470: checking for sqlite3_key in -lsqlite3" >&5 ac_lib_var=`echo sqlite3'_'sqlite3_key | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -73112,7 +73474,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsqlite3 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:73489: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -73864,12 +74226,12 @@ but you've either not enabled sqlite3, or have disabled it. for ac_func in usleep nanosleep do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:73868: checking for $ac_func" >&5 +echo "configure:74230: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:74258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -73920,17 +74282,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:73924: checking for $ac_hdr" >&5 +echo "configure:74286: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:73934: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:74296: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -74054,7 +74416,7 @@ done done echo $ac_n "checking for fdatasync in -lrt""... $ac_c" 1>&6 -echo "configure:74058: checking for fdatasync in -lrt" >&5 +echo "configure:74420: checking for fdatasync in -lrt" >&5 ac_lib_var=`echo rt'_'fdatasync | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74062,7 +74424,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lrt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:74439: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74154,7 +74516,7 @@ fi php_with_pgsql=no echo $ac_n "checking for PostgreSQL support""... $ac_c" 1>&6 -echo "configure:74158: checking for PostgreSQL support" >&5 +echo "configure:74520: checking for PostgreSQL support" >&5 # Check whether --with-pgsql or --without-pgsql was given. if test "${with_pgsql+set}" = set; then withval="$with_pgsql" @@ -74211,7 +74573,7 @@ if test "$PHP_PGSQL" != "no"; then echo $ac_n "checking for pg_config""... $ac_c" 1>&6 -echo "configure:74215: checking for pg_config" >&5 +echo "configure:74577: checking for pg_config" >&5 for i in $PHP_PGSQL $PHP_PGSQL/bin /usr/local/pgsql/bin /usr/local/bin /usr/bin ""; do if test -x $i/pg_config; then PG_CONFIG="$i/pg_config" @@ -74279,7 +74641,7 @@ EOF old_LDFLAGS=$LDFLAGS LDFLAGS="-L$PGSQL_LIBDIR $LDFLAGS" echo $ac_n "checking for PQescapeString in -lpq""... $ac_c" 1>&6 -echo "configure:74283: checking for PQescapeString in -lpq" >&5 +echo "configure:74645: checking for PQescapeString in -lpq" >&5 ac_lib_var=`echo pq'_'PQescapeString | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74287,7 +74649,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:74664: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74322,7 +74684,7 @@ else fi echo $ac_n "checking for PQunescapeBytea in -lpq""... $ac_c" 1>&6 -echo "configure:74326: checking for PQunescapeBytea in -lpq" >&5 +echo "configure:74688: checking for PQunescapeBytea in -lpq" >&5 ac_lib_var=`echo pq'_'PQunescapeBytea | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74330,7 +74692,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:74707: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74365,7 +74727,7 @@ else fi echo $ac_n "checking for PQsetnonblocking in -lpq""... $ac_c" 1>&6 -echo "configure:74369: checking for PQsetnonblocking in -lpq" >&5 +echo "configure:74731: checking for PQsetnonblocking in -lpq" >&5 ac_lib_var=`echo pq'_'PQsetnonblocking | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74373,7 +74735,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:74750: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74408,7 +74770,7 @@ else fi echo $ac_n "checking for PQcmdTuples in -lpq""... $ac_c" 1>&6 -echo "configure:74412: checking for PQcmdTuples in -lpq" >&5 +echo "configure:74774: checking for PQcmdTuples in -lpq" >&5 ac_lib_var=`echo pq'_'PQcmdTuples | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74416,7 +74778,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:74793: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74451,7 +74813,7 @@ else fi echo $ac_n "checking for PQoidValue in -lpq""... $ac_c" 1>&6 -echo "configure:74455: checking for PQoidValue in -lpq" >&5 +echo "configure:74817: checking for PQoidValue in -lpq" >&5 ac_lib_var=`echo pq'_'PQoidValue | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74459,7 +74821,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:74836: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74494,7 +74856,7 @@ else fi echo $ac_n "checking for PQclientEncoding in -lpq""... $ac_c" 1>&6 -echo "configure:74498: checking for PQclientEncoding in -lpq" >&5 +echo "configure:74860: checking for PQclientEncoding in -lpq" >&5 ac_lib_var=`echo pq'_'PQclientEncoding | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74502,7 +74864,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:74879: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74537,7 +74899,7 @@ else fi echo $ac_n "checking for PQparameterStatus in -lpq""... $ac_c" 1>&6 -echo "configure:74541: checking for PQparameterStatus in -lpq" >&5 +echo "configure:74903: checking for PQparameterStatus in -lpq" >&5 ac_lib_var=`echo pq'_'PQparameterStatus | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74545,7 +74907,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:74922: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74580,7 +74942,7 @@ else fi echo $ac_n "checking for PQprotocolVersion in -lpq""... $ac_c" 1>&6 -echo "configure:74584: checking for PQprotocolVersion in -lpq" >&5 +echo "configure:74946: checking for PQprotocolVersion in -lpq" >&5 ac_lib_var=`echo pq'_'PQprotocolVersion | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74588,7 +74950,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:74965: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74623,7 +74985,7 @@ else fi echo $ac_n "checking for PQtransactionStatus in -lpq""... $ac_c" 1>&6 -echo "configure:74627: checking for PQtransactionStatus in -lpq" >&5 +echo "configure:74989: checking for PQtransactionStatus in -lpq" >&5 ac_lib_var=`echo pq'_'PQtransactionStatus | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74631,7 +74993,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75008: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74666,7 +75028,7 @@ else fi echo $ac_n "checking for PQexecParams in -lpq""... $ac_c" 1>&6 -echo "configure:74670: checking for PQexecParams in -lpq" >&5 +echo "configure:75032: checking for PQexecParams in -lpq" >&5 ac_lib_var=`echo pq'_'PQexecParams | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74674,7 +75036,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75051: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74709,7 +75071,7 @@ else fi echo $ac_n "checking for PQprepare in -lpq""... $ac_c" 1>&6 -echo "configure:74713: checking for PQprepare in -lpq" >&5 +echo "configure:75075: checking for PQprepare in -lpq" >&5 ac_lib_var=`echo pq'_'PQprepare | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74717,7 +75079,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75094: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74752,7 +75114,7 @@ else fi echo $ac_n "checking for PQexecPrepared in -lpq""... $ac_c" 1>&6 -echo "configure:74756: checking for PQexecPrepared in -lpq" >&5 +echo "configure:75118: checking for PQexecPrepared in -lpq" >&5 ac_lib_var=`echo pq'_'PQexecPrepared | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74760,7 +75122,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75137: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74795,7 +75157,7 @@ else fi echo $ac_n "checking for PQresultErrorField in -lpq""... $ac_c" 1>&6 -echo "configure:74799: checking for PQresultErrorField in -lpq" >&5 +echo "configure:75161: checking for PQresultErrorField in -lpq" >&5 ac_lib_var=`echo pq'_'PQresultErrorField | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74803,7 +75165,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75180: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74838,7 +75200,7 @@ else fi echo $ac_n "checking for PQsendQueryParams in -lpq""... $ac_c" 1>&6 -echo "configure:74842: checking for PQsendQueryParams in -lpq" >&5 +echo "configure:75204: checking for PQsendQueryParams in -lpq" >&5 ac_lib_var=`echo pq'_'PQsendQueryParams | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74846,7 +75208,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75223: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74881,7 +75243,7 @@ else fi echo $ac_n "checking for PQsendPrepare in -lpq""... $ac_c" 1>&6 -echo "configure:74885: checking for PQsendPrepare in -lpq" >&5 +echo "configure:75247: checking for PQsendPrepare in -lpq" >&5 ac_lib_var=`echo pq'_'PQsendPrepare | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74889,7 +75251,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75266: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74924,7 +75286,7 @@ else fi echo $ac_n "checking for PQsendQueryPrepared in -lpq""... $ac_c" 1>&6 -echo "configure:74928: checking for PQsendQueryPrepared in -lpq" >&5 +echo "configure:75290: checking for PQsendQueryPrepared in -lpq" >&5 ac_lib_var=`echo pq'_'PQsendQueryPrepared | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74932,7 +75294,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75309: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -74967,7 +75329,7 @@ else fi echo $ac_n "checking for PQputCopyData in -lpq""... $ac_c" 1>&6 -echo "configure:74971: checking for PQputCopyData in -lpq" >&5 +echo "configure:75333: checking for PQputCopyData in -lpq" >&5 ac_lib_var=`echo pq'_'PQputCopyData | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -74975,7 +75337,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75352: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -75010,7 +75372,7 @@ else fi echo $ac_n "checking for PQputCopyEnd in -lpq""... $ac_c" 1>&6 -echo "configure:75014: checking for PQputCopyEnd in -lpq" >&5 +echo "configure:75376: checking for PQputCopyEnd in -lpq" >&5 ac_lib_var=`echo pq'_'PQputCopyEnd | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -75018,7 +75380,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75395: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -75053,7 +75415,7 @@ else fi echo $ac_n "checking for PQgetCopyData in -lpq""... $ac_c" 1>&6 -echo "configure:75057: checking for PQgetCopyData in -lpq" >&5 +echo "configure:75419: checking for PQgetCopyData in -lpq" >&5 ac_lib_var=`echo pq'_'PQgetCopyData | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -75061,7 +75423,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75438: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -75096,7 +75458,7 @@ else fi echo $ac_n "checking for PQfreemem in -lpq""... $ac_c" 1>&6 -echo "configure:75100: checking for PQfreemem in -lpq" >&5 +echo "configure:75462: checking for PQfreemem in -lpq" >&5 ac_lib_var=`echo pq'_'PQfreemem | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -75104,7 +75466,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75481: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -75139,7 +75501,7 @@ else fi echo $ac_n "checking for PQsetErrorVerbosity in -lpq""... $ac_c" 1>&6 -echo "configure:75143: checking for PQsetErrorVerbosity in -lpq" >&5 +echo "configure:75505: checking for PQsetErrorVerbosity in -lpq" >&5 ac_lib_var=`echo pq'_'PQsetErrorVerbosity | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -75147,7 +75509,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75524: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -75182,7 +75544,7 @@ else fi echo $ac_n "checking for PQftable in -lpq""... $ac_c" 1>&6 -echo "configure:75186: checking for PQftable in -lpq" >&5 +echo "configure:75548: checking for PQftable in -lpq" >&5 ac_lib_var=`echo pq'_'PQftable | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -75190,7 +75552,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75567: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -75225,7 +75587,7 @@ else fi echo $ac_n "checking for PQescapeStringConn in -lpq""... $ac_c" 1>&6 -echo "configure:75229: checking for PQescapeStringConn in -lpq" >&5 +echo "configure:75591: checking for PQescapeStringConn in -lpq" >&5 ac_lib_var=`echo pq'_'PQescapeStringConn | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -75233,7 +75595,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75610: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -75268,7 +75630,7 @@ else fi echo $ac_n "checking for PQescapeByteaConn in -lpq""... $ac_c" 1>&6 -echo "configure:75272: checking for PQescapeByteaConn in -lpq" >&5 +echo "configure:75634: checking for PQescapeByteaConn in -lpq" >&5 ac_lib_var=`echo pq'_'PQescapeByteaConn | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -75276,7 +75638,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75653: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -75311,7 +75673,7 @@ else fi echo $ac_n "checking for pg_encoding_to_char in -lpq""... $ac_c" 1>&6 -echo "configure:75315: checking for pg_encoding_to_char in -lpq" >&5 +echo "configure:75677: checking for pg_encoding_to_char in -lpq" >&5 ac_lib_var=`echo pq'_'pg_encoding_to_char | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -75319,7 +75681,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75696: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -75354,7 +75716,7 @@ else fi echo $ac_n "checking for lo_create in -lpq""... $ac_c" 1>&6 -echo "configure:75358: checking for lo_create in -lpq" >&5 +echo "configure:75720: checking for lo_create in -lpq" >&5 ac_lib_var=`echo pq'_'lo_create | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -75362,7 +75724,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75739: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -75397,7 +75759,7 @@ else fi echo $ac_n "checking for lo_import_with_oid in -lpq""... $ac_c" 1>&6 -echo "configure:75401: checking for lo_import_with_oid in -lpq" >&5 +echo "configure:75763: checking for lo_import_with_oid in -lpq" >&5 ac_lib_var=`echo pq'_'lo_import_with_oid | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -75405,7 +75767,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lpq $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:75782: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -75876,7 +76238,7 @@ fi php_enable_phar=yes echo $ac_n "checking for phar archive support""... $ac_c" 1>&6 -echo "configure:75880: checking for phar archive support" >&5 +echo "configure:76242: checking for phar archive support" >&5 # Check whether --enable-phar or --disable-phar was given. if test "${enable_phar+set}" = set; then enableval="$enable_phar" @@ -76213,7 +76575,7 @@ EOF fi echo $ac_n "checking for phar openssl support""... $ac_c" 1>&6 -echo "configure:76217: checking for phar openssl support" >&5 +echo "configure:76579: checking for phar openssl support" >&5 if test "$PHP_HASH_SHARED" != "yes"; then if test "$PHP_HASH" != "no"; then cat >> confdefs.h <<\EOF @@ -76288,7 +76650,7 @@ fi php_enable_posix=yes echo $ac_n "checking whether to enable POSIX-like functions""... $ac_c" 1>&6 -echo "configure:76292: checking whether to enable POSIX-like functions" >&5 +echo "configure:76654: checking whether to enable POSIX-like functions" >&5 # Check whether --enable-posix or --disable-posix was given. if test "${enable_posix+set}" = set; then enableval="$enable_posix" @@ -76633,17 +76995,17 @@ EOF do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:76637: checking for $ac_hdr" >&5 +echo "configure:76999: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:76647: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:77009: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -76673,12 +77035,12 @@ done for ac_func in seteuid setegid setsid getsid setpgid getpgid ctermid mkfifo mknod getrlimit getlogin getgroups makedev initgroups getpwuid_r getgrgid_r do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:76677: checking for $ac_func" >&5 +echo "configure:77039: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:77067: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -76727,14 +77089,14 @@ done echo $ac_n "checking for working ttyname_r() implementation""... $ac_c" 1>&6 -echo "configure:76731: checking for working ttyname_r() implementation" >&5 +echo "configure:77093: checking for working ttyname_r() implementation" >&5 if test "$cross_compiling" = yes; then echo "$ac_t""no, cannot detect working ttyname_r() when cross compiling. posix_ttyname() will be thread-unsafe" 1>&6 else cat > conftest.$ac_ext < @@ -76747,7 +77109,7 @@ int main(int argc, char *argv[]) } EOF -if { (eval echo configure:76751: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:77113: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then echo "$ac_t""yes" 1>&6 @@ -76769,13 +77131,13 @@ fi echo $ac_n "checking for utsname.domainname""... $ac_c" 1>&6 -echo "configure:76773: checking for utsname.domainname" >&5 +echo "configure:77135: checking for utsname.domainname" >&5 if eval "test \"`echo '$''{'ac_cv_have_utsname_domainname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:77153: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_have_utsname_domainname=yes @@ -76818,7 +77180,7 @@ fi php_with_pspell=no echo $ac_n "checking for PSPELL support""... $ac_c" 1>&6 -echo "configure:76822: checking for PSPELL support" >&5 +echo "configure:77184: checking for PSPELL support" >&5 # Check whether --with-pspell or --without-pspell was given. if test "${with_pspell+set}" = set; then withval="$with_pspell" @@ -77371,7 +77733,7 @@ EOF done echo $ac_n "checking for new_aspell_config in -laspell""... $ac_c" 1>&6 -echo "configure:77375: checking for new_aspell_config in -laspell" >&5 +echo "configure:77737: checking for new_aspell_config in -laspell" >&5 ac_lib_var=`echo aspell'_'new_aspell_config | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -77379,7 +77741,7 @@ else ac_save_LIBS="$LIBS" LIBS="-laspell $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:77756: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -77564,7 +77926,7 @@ fi php_with_libedit=no echo $ac_n "checking for libedit readline replacement""... $ac_c" 1>&6 -echo "configure:77568: checking for libedit readline replacement" >&5 +echo "configure:77930: checking for libedit readline replacement" >&5 # Check whether --with-libedit or --without-libedit was given. if test "${with_libedit+set}" = set; then withval="$with_libedit" @@ -77612,7 +77974,7 @@ if test "$PHP_LIBEDIT" = "no"; then php_with_readline=no echo $ac_n "checking for readline support""... $ac_c" 1>&6 -echo "configure:77616: checking for readline support" >&5 +echo "configure:77978: checking for readline support" >&5 # Check whether --with-readline or --without-readline was given. if test "${with_readline+set}" = set; then withval="$with_readline" @@ -77654,6 +78016,8 @@ echo "$ac_t""$ext_output" 1>&6 +else + php_with_readline=no fi if test "$PHP_READLINE" && test "$PHP_READLINE" != "no"; then @@ -77699,7 +78063,7 @@ if test "$PHP_READLINE" && test "$PHP_READLINE" != "no"; then PHP_READLINE_LIBS="" echo $ac_n "checking for tgetent in -lncurses""... $ac_c" 1>&6 -echo "configure:77703: checking for tgetent in -lncurses" >&5 +echo "configure:78067: checking for tgetent in -lncurses" >&5 ac_lib_var=`echo ncurses'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -77707,7 +78071,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lncurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:78086: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -77763,7 +78127,7 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6 -echo "configure:77767: checking for tgetent in -ltermcap" >&5 +echo "configure:78131: checking for tgetent in -ltermcap" >&5 ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -77771,7 +78135,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ltermcap $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:78150: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -77929,7 +78293,7 @@ fi done echo $ac_n "checking for readline in -lreadline""... $ac_c" 1>&6 -echo "configure:77933: checking for readline in -lreadline" >&5 +echo "configure:78297: checking for readline in -lreadline" >&5 ac_lib_var=`echo readline'_'readline | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -77937,7 +78301,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lreadline $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:78316: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -78080,6 +78444,156 @@ fi + save_old_LDFLAGS=$LDFLAGS + ac_stuff=" + -L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS + " + + save_ext_shared=$ext_shared + ext_shared=yes + + for ac_i in $ac_stuff; do + case $ac_i in + -pthread) + if test "$ext_shared" = "yes"; then + LDFLAGS="$LDFLAGS -pthread" + else + + + unique=`echo $ac_i|$SED 's/[^a-zA-Z0-9]/_/g'` + + cmd="echo $ac_n \"\$EXTRA_LDFLAGS$unique$ac_c\"" + if test -n "$unique" && test "`eval $cmd`" = "" ; then + eval "EXTRA_LDFLAGS$unique=set" + EXTRA_LDFLAGS="$EXTRA_LDFLAGS $ac_i" + fi + + fi + ;; + -l*) + ac_ii=`echo $ac_i|cut -c 3-` + + + case $ac_ii in + c|c_r|pthread*) ;; + *) + if test "$ext_shared" = "yes"; then + LDFLAGS="$LDFLAGS -l$ac_ii" + else + + + case $ac_ii in + c|c_r|pthread*) ;; + *) + LIBS="$LIBS -l$ac_ii" + ;; + esac + + + fi + ;; + esac + + + ;; + -L*) + ac_ii=`echo $ac_i|cut -c 3-` + + if test "$ac_ii" != "/usr/$PHP_LIBDIR" && test "$ac_ii" != "/usr/lib"; then + + if test -z "$ac_ii" || echo "$ac_ii" | grep '^/' >/dev/null ; then + ai_p=$ac_ii + else + + ep_dir="`echo $ac_ii|$SED 's%/*[^/][^/]*/*$%%'`" + + ep_realdir="`(cd \"$ep_dir\" && pwd)`" + ai_p="$ep_realdir/`basename \"$ac_ii\"`" + fi + + + if test "$ext_shared" = "yes"; then + LDFLAGS="-L$ai_p $LDFLAGS" + test -n "$ld_runpath_switch" && LDFLAGS="$ld_runpath_switch$ai_p $LDFLAGS" + else + + + + unique=`echo $ai_p|$SED 's/[^a-zA-Z0-9]/_/g'` + + cmd="echo $ac_n \"\$LIBPATH$unique$ac_c\"" + if test -n "$unique" && test "`eval $cmd`" = "" ; then + eval "LIBPATH$unique=set" + + test -n "$ld_runpath_switch" && LDFLAGS="$LDFLAGS $ld_runpath_switch$ai_p" + LDFLAGS="$LDFLAGS -L$ai_p" + PHP_RPATHS="$PHP_RPATHS $ai_p" + + fi + + + fi + + fi + + ;; + esac + done + + echo $ac_n "checking for rl_pending_input in -lreadline""... $ac_c" 1>&6 +echo "configure:78545: checking for rl_pending_input in -lreadline" >&5 +ac_lib_var=`echo readline'_'rl_pending_input | sed 'y%./+-%__p_%'` +if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + ac_save_LIBS="$LIBS" +LIBS="-lreadline $LIBS" +cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=yes" +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + eval "ac_cv_lib_$ac_lib_var=no" +fi +rm -f conftest* +LIBS="$ac_save_LIBS" + +fi +if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then + echo "$ac_t""yes" 1>&6 + + LDFLAGS=$save_old_LDFLAGS + ext_shared=$save_ext_shared + + +else + echo "$ac_t""no" 1>&6 + + LDFLAGS=$save_old_LDFLAGS + ext_shared=$save_ext_shared + unset ac_cv_lib_readline_rl_pending_input + + { echo "configure: error: invalid readline installation detected. Try --with-libedit instead." 1>&2; exit 1; } + + +fi + + + save_old_LDFLAGS=$LDFLAGS ac_stuff=" -L$READLINE_DIR/$PHP_LIBDIR $PHP_READLINE_LIBS @@ -78177,7 +78691,7 @@ fi done echo $ac_n "checking for rl_callback_read_char in -lreadline""... $ac_c" 1>&6 -echo "configure:78181: checking for rl_callback_read_char in -lreadline" >&5 +echo "configure:78695: checking for rl_callback_read_char in -lreadline" >&5 ac_lib_var=`echo readline'_'rl_callback_read_char | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -78185,7 +78699,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lreadline $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:78714: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -78280,7 +78794,7 @@ elif test "$PHP_LIBEDIT" != "no"; then echo $ac_n "checking for tgetent in -lncurses""... $ac_c" 1>&6 -echo "configure:78284: checking for tgetent in -lncurses" >&5 +echo "configure:78798: checking for tgetent in -lncurses" >&5 ac_lib_var=`echo ncurses'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -78288,7 +78802,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lncurses $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:78817: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -78343,7 +78857,7 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for tgetent in -ltermcap""... $ac_c" 1>&6 -echo "configure:78347: checking for tgetent in -ltermcap" >&5 +echo "configure:78861: checking for tgetent in -ltermcap" >&5 ac_lib_var=`echo termcap'_'tgetent | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -78351,7 +78865,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ltermcap $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:78880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -78508,7 +79022,7 @@ fi done echo $ac_n "checking for readline in -ledit""... $ac_c" 1>&6 -echo "configure:78512: checking for readline in -ledit" >&5 +echo "configure:79026: checking for readline in -ledit" >&5 ac_lib_var=`echo edit'_'readline | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -78516,7 +79030,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ledit $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:79045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -78668,12 +79182,12 @@ if test "$PHP_READLINE" != "no" || test "$PHP_LIBEDIT" != "no"; then for ac_func in rl_completion_matches do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:78672: checking for $ac_func" >&5 +echo "configure:79186: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:79214: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -79022,7 +79536,7 @@ fi php_with_recode=no echo $ac_n "checking for recode support""... $ac_c" 1>&6 -echo "configure:79026: checking for recode support" >&5 +echo "configure:79540: checking for recode support" >&5 # Check whether --with-recode or --without-recode was given. if test "${with_recode+set}" = set; then withval="$with_recode" @@ -79189,7 +79703,7 @@ if test "$PHP_RECODE" != "no"; then done echo $ac_n "checking for recode_format_table in -lrecode""... $ac_c" 1>&6 -echo "configure:79193: checking for recode_format_table in -lrecode" >&5 +echo "configure:79707: checking for recode_format_table in -lrecode" >&5 ac_lib_var=`echo recode'_'recode_format_table | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -79197,7 +79711,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lrecode $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:79726: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -79338,7 +79852,7 @@ else LDFLAGS="$LDFLAGS -L$RECODE_DIR/$RECODE_LIB" LIBS="$LIBS -lrecode" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:79867: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* @@ -79512,17 +80026,17 @@ EOF do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:79516: checking for $ac_hdr" >&5 +echo "configure:80030: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:79526: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:80040: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -80145,7 +80659,7 @@ EOF php_enable_session=yes echo $ac_n "checking whether to enable PHP sessions""... $ac_c" 1>&6 -echo "configure:80149: checking whether to enable PHP sessions" >&5 +echo "configure:80663: checking whether to enable PHP sessions" >&5 # Check whether --enable-session or --disable-session was given. if test "${enable_session+set}" = set; then enableval="$enable_session" @@ -80192,7 +80706,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_mm=no echo $ac_n "checking for mm support""... $ac_c" 1>&6 -echo "configure:80196: checking for mm support" >&5 +echo "configure:80710: checking for mm support" >&5 # Check whether --with-mm or --without-mm was given. if test "${with_mm+set}" = set; then withval="$with_mm" @@ -80217,7 +80731,7 @@ echo "$ac_t""$ext_output" 1>&6 if test "$PHP_SESSION" != "no"; then echo $ac_n "checking whether pwrite works""... $ac_c" 1>&6 -echo "configure:80221: checking whether pwrite works" >&5 +echo "configure:80735: checking whether pwrite works" >&5 if eval "test \"`echo '$''{'ac_cv_pwrite'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -80229,7 +80743,7 @@ else else cat > conftest.$ac_ext < @@ -80250,7 +80764,7 @@ else EOF -if { (eval echo configure:80254: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:80768: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_pwrite=yes @@ -80275,7 +80789,7 @@ fi else cat > conftest.$ac_ext < @@ -80296,7 +80810,7 @@ ssize_t pwrite(int, void *, size_t, off64_t); EOF -if { (eval echo configure:80300: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:80814: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_pwrite=yes @@ -80337,7 +80851,7 @@ EOF echo $ac_n "checking whether pread works""... $ac_c" 1>&6 -echo "configure:80341: checking whether pread works" >&5 +echo "configure:80855: checking whether pread works" >&5 if eval "test \"`echo '$''{'ac_cv_pread'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -80350,7 +80864,7 @@ else else cat > conftest.$ac_ext < @@ -80370,7 +80884,7 @@ else } EOF -if { (eval echo configure:80374: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:80888: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_pread=yes @@ -80397,7 +80911,7 @@ fi else cat > conftest.$ac_ext < @@ -80417,7 +80931,7 @@ ssize_t pread(int, void *, size_t, off64_t); } EOF -if { (eval echo configure:80421: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:80935: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_pread=yes @@ -80750,6 +81264,25 @@ EOF fi + am_i_shared=$PHP_SESSION_SHARED + is_it_shared=$PHP_HASH_SHARED + is_it_enabled=$PHP_HASH + if test "$am_i_shared" = "no" && test "$is_it_shared" = "yes" ; then + { echo "configure: error: +You've configured extension session to build statically, but it +depends on extension hash, which you've configured to build shared. +You either need to build session shared or build hash statically for the +build to be successful. +" 1>&2; exit 1; } + fi + if test "x$is_it_enabled" = "xno" && test "xtrue" != "xtrue"; then + { echo "configure: error: +You've configured extension session, which depends on extension hash, +but you've either not enabled hash, or have disabled it. +" 1>&2; exit 1; } + fi + + PHP_VAR_SUBST="$PHP_VAR_SUBST SESSION_SHARED_LIBADD" @@ -80943,7 +81476,7 @@ fi php_enable_shmop=no echo $ac_n "checking whether to enable shmop support""... $ac_c" 1>&6 -echo "configure:80947: checking whether to enable shmop support" >&5 +echo "configure:81480: checking whether to enable shmop support" >&5 # Check whether --enable-shmop or --disable-shmop was given. if test "${enable_shmop+set}" = set; then enableval="$enable_shmop" @@ -81290,7 +81823,7 @@ fi php_enable_simplexml=yes echo $ac_n "checking whether to enable SimpleXML support""... $ac_c" 1>&6 -echo "configure:81294: checking whether to enable SimpleXML support" >&5 +echo "configure:81827: checking whether to enable SimpleXML support" >&5 # Check whether --enable-simplexml or --disable-simplexml was given. if test "${enable_simplexml+set}" = set; then enableval="$enable_simplexml" @@ -81338,7 +81871,7 @@ if test -z "$PHP_LIBXML_DIR"; then php_with_libxml_dir=no echo $ac_n "checking libxml2 install dir""... $ac_c" 1>&6 -echo "configure:81342: checking libxml2 install dir" >&5 +echo "configure:81875: checking libxml2 install dir" >&5 # Check whether --with-libxml-dir or --without-libxml-dir was given. if test "${with_libxml_dir+set}" = set; then withval="$with_libxml_dir" @@ -81369,7 +81902,7 @@ if test "$PHP_SIMPLEXML" != "no"; then echo $ac_n "checking for xml2-config path""... $ac_c" 1>&6 -echo "configure:81373: checking for xml2-config path" >&5 +echo "configure:81906: checking for xml2-config path" >&5 if eval "test \"`echo '$''{'ac_cv_php_xml2_config_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -81527,7 +82060,7 @@ echo "$ac_t""$ac_cv_php_xml2_config_path" 1>&6 echo $ac_n "checking whether libxml build works""... $ac_c" 1>&6 -echo "configure:81531: checking whether libxml build works" >&5 +echo "configure:82064: checking whether libxml build works" >&5 if eval "test \"`echo '$''{'php_cv_libxml_build_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -81543,7 +82076,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:82091: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -81942,7 +82475,7 @@ fi php_with_snmp=no echo $ac_n "checking for SNMP support""... $ac_c" 1>&6 -echo "configure:81946: checking for SNMP support" >&5 +echo "configure:82479: checking for SNMP support" >&5 # Check whether --with-snmp or --without-snmp was given. if test "${with_snmp+set}" = set; then withval="$with_snmp" @@ -81989,7 +82522,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_openssl_dir=no echo $ac_n "checking OpenSSL dir for SNMP""... $ac_c" 1>&6 -echo "configure:81993: checking OpenSSL dir for SNMP" >&5 +echo "configure:82526: checking OpenSSL dir for SNMP" >&5 # Check whether --with-openssl-dir or --without-openssl-dir was given. if test "${with_openssl_dir+set}" = set; then withval="$with_openssl_dir" @@ -82015,7 +82548,7 @@ echo "$ac_t""$ext_output" 1>&6 php_enable_ucd_snmp_hack=no echo $ac_n "checking whether to enable UCD SNMP hack""... $ac_c" 1>&6 -echo "configure:82019: checking whether to enable UCD SNMP hack" >&5 +echo "configure:82552: checking whether to enable UCD SNMP hack" >&5 # Check whether --enable-ucd-snmp-hack or --disable-ucd-snmp-hack was given. if test "${enable_ucd_snmp_hack+set}" = set; then enableval="$enable_ucd_snmp_hack" @@ -82043,7 +82576,7 @@ if test "$PHP_SNMP" != "no"; then # Extract the first word of "net-snmp-config", so it can be a program name with args. set dummy net-snmp-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:82047: checking for $ac_word" >&5 +echo "configure:82580: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_SNMP_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -82244,17 +82777,17 @@ EOF do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:82248: checking for $ac_hdr" >&5 +echo "configure:82781: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:82258: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:82791: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -82282,9 +82815,9 @@ done if test "$ac_cv_header_default_store_h" = "yes"; then echo $ac_n "checking for OpenSSL support in SNMP libraries""... $ac_c" 1>&6 -echo "configure:82286: checking for OpenSSL support in SNMP libraries" >&5 +echo "configure:82819: checking for OpenSSL support in SNMP libraries" >&5 cat > conftest.$ac_ext < @@ -82339,7 +82872,7 @@ rm -f conftest* # Extract the first word of "pkg-config", so it can be a program name with args. set dummy pkg-config; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:82343: checking for $ac_word" >&5 +echo "configure:82876: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_path_PKG_CONFIG'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -82544,9 +83077,9 @@ fi old_CPPFLAGS=$CPPFLAGS CPPFLAGS=-I$OPENSSL_INCDIR echo $ac_n "checking for OpenSSL version""... $ac_c" 1>&6 -echo "configure:82548: checking for OpenSSL version" >&5 +echo "configure:83081: checking for OpenSSL version" >&5 cat > conftest.$ac_ext < @@ -82701,7 +83234,7 @@ rm -f conftest* done echo $ac_n "checking for CRYPTO_free in -lcrypto""... $ac_c" 1>&6 -echo "configure:82705: checking for CRYPTO_free in -lcrypto" >&5 +echo "configure:83238: checking for CRYPTO_free in -lcrypto" >&5 ac_lib_var=`echo crypto'_'CRYPTO_free | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -82709,7 +83242,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypto $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:83257: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -82877,7 +83410,7 @@ fi done echo $ac_n "checking for SSL_CTX_set_ssl_version in -lssl""... $ac_c" 1>&6 -echo "configure:82881: checking for SSL_CTX_set_ssl_version in -lssl" >&5 +echo "configure:83414: checking for SSL_CTX_set_ssl_version in -lssl" >&5 ac_lib_var=`echo ssl'_'SSL_CTX_set_ssl_version | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -82885,7 +83418,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lssl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:83433: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -83009,7 +83542,7 @@ else fi echo $ac_n "checking for kstat_read in -lkstat""... $ac_c" 1>&6 -echo "configure:83013: checking for kstat_read in -lkstat" >&5 +echo "configure:83546: checking for kstat_read in -lkstat" >&5 ac_lib_var=`echo kstat'_'kstat_read | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -83017,7 +83550,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lkstat $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:83565: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -83299,7 +83832,7 @@ fi done echo $ac_n "checking for snmp_parse_oid in -l$SNMP_LIBNAME""... $ac_c" 1>&6 -echo "configure:83303: checking for snmp_parse_oid in -l$SNMP_LIBNAME" >&5 +echo "configure:83836: checking for snmp_parse_oid in -l$SNMP_LIBNAME" >&5 ac_lib_var=`echo $SNMP_LIBNAME'_'snmp_parse_oid | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -83307,7 +83840,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$SNMP_LIBNAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:83855: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -83452,7 +83985,7 @@ fi done echo $ac_n "checking for init_snmp in -l$SNMP_LIBNAME""... $ac_c" 1>&6 -echo "configure:83456: checking for init_snmp in -l$SNMP_LIBNAME" >&5 +echo "configure:83989: checking for init_snmp in -l$SNMP_LIBNAME" >&5 ac_lib_var=`echo $SNMP_LIBNAME'_'init_snmp | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -83460,7 +83993,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$SNMP_LIBNAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:84008: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -83818,7 +84351,7 @@ fi php_enable_soap=no echo $ac_n "checking whether to enable SOAP support""... $ac_c" 1>&6 -echo "configure:83822: checking whether to enable SOAP support" >&5 +echo "configure:84355: checking whether to enable SOAP support" >&5 # Check whether --enable-soap or --disable-soap was given. if test "${enable_soap+set}" = set; then enableval="$enable_soap" @@ -83866,7 +84399,7 @@ if test -z "$PHP_LIBXML_DIR"; then php_with_libxml_dir=no echo $ac_n "checking libxml2 install dir""... $ac_c" 1>&6 -echo "configure:83870: checking libxml2 install dir" >&5 +echo "configure:84403: checking libxml2 install dir" >&5 # Check whether --with-libxml-dir or --without-libxml-dir was given. if test "${with_libxml_dir+set}" = set; then withval="$with_libxml_dir" @@ -83897,7 +84430,7 @@ if test "$PHP_SOAP" != "no"; then echo $ac_n "checking for xml2-config path""... $ac_c" 1>&6 -echo "configure:83901: checking for xml2-config path" >&5 +echo "configure:84434: checking for xml2-config path" >&5 if eval "test \"`echo '$''{'ac_cv_php_xml2_config_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -84055,7 +84588,7 @@ echo "$ac_t""$ac_cv_php_xml2_config_path" 1>&6 echo $ac_n "checking whether libxml build works""... $ac_c" 1>&6 -echo "configure:84059: checking whether libxml build works" >&5 +echo "configure:84592: checking whether libxml build works" >&5 if eval "test \"`echo '$''{'php_cv_libxml_build_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -84071,7 +84604,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:84619: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -84432,7 +84965,7 @@ fi php_enable_sockets=no echo $ac_n "checking whether to enable sockets support""... $ac_c" 1>&6 -echo "configure:84436: checking whether to enable sockets support" >&5 +echo "configure:84969: checking whether to enable sockets support" >&5 # Check whether --enable-sockets or --disable-sockets was given. if test "${enable_sockets+set}" = set; then enableval="$enable_sockets" @@ -84477,13 +85010,13 @@ echo "$ac_t""$ext_output" 1>&6 if test "$PHP_SOCKETS" != "no"; then echo $ac_n "checking for struct cmsghdr""... $ac_c" 1>&6 -echo "configure:84481: checking for struct cmsghdr" >&5 +echo "configure:85014: checking for struct cmsghdr" >&5 if eval "test \"`echo '$''{'ac_cv_cmsghdr'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -84492,7 +85025,7 @@ int main() { struct cmsghdr s; s ; return 0; } EOF -if { (eval echo configure:84496: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:85029: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_cmsghdr=yes else @@ -84517,12 +85050,12 @@ EOF for ac_func in hstrerror socketpair do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:84521: checking for $ac_func" >&5 +echo "configure:85054: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:85082: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -84573,17 +85106,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:84577: checking for $ac_hdr" >&5 +echo "configure:85110: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:84587: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:85120: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -84610,7 +85143,7 @@ fi done cat > conftest.$ac_ext < @@ -84620,7 +85153,7 @@ int main() { static struct msghdr tp; int n = (int) tp.msg_flags; return n ; return 0; } EOF -if { (eval echo configure:84624: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:85157: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then : else echo "configure: failed program was:" >&5 @@ -84934,7 +85467,7 @@ fi echo $ac_n "checking whether zend_object_value is packed""... $ac_c" 1>&6 -echo "configure:84938: checking whether zend_object_value is packed" >&5 +echo "configure:85471: checking whether zend_object_value is packed" >&5 old_CPPFLAGS=$CPPFLAGS CPPFLAGS="$INCLUDES -I$abs_srcdir $CPPFLAGS" if test "$cross_compiling" = yes; then @@ -84944,7 +85477,7 @@ echo "configure:84938: checking whether zend_object_value is packed" >&5 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:85490: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_result=1 @@ -85317,7 +85850,7 @@ but you've either not enabled pcre, or have disabled it. php_with_sqlite=yes echo $ac_n "checking for sqlite support""... $ac_c" 1>&6 -echo "configure:85321: checking for sqlite support" >&5 +echo "configure:85854: checking for sqlite support" >&5 # Check whether --with-sqlite or --without-sqlite was given. if test "${with_sqlite+set}" = set; then withval="$with_sqlite" @@ -85364,7 +85897,7 @@ echo "$ac_t""$ext_output" 1>&6 php_enable_sqlite_utf8=no echo $ac_n "checking whether to enable UTF-8 support in sqlite (default: ISO-8859-1)""... $ac_c" 1>&6 -echo "configure:85368: checking whether to enable UTF-8 support in sqlite (default: ISO-8859-1)" >&5 +echo "configure:85901: checking whether to enable UTF-8 support in sqlite (default: ISO-8859-1)" >&5 # Check whether --enable-sqlite-utf8 or --disable-sqlite-utf8 was given. if test "${enable_sqlite_utf8+set}" = set; then enableval="$enable_sqlite_utf8" @@ -85395,13 +85928,13 @@ if test "$PHP_SQLITE" != "no"; then if test "$PHP_PDO" != "no"; then echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:85399: checking for PDO includes" >&5 +echo "configure:85932: checking for PDO includes" >&5 if eval "test \"`echo '$''{'pdo_inc_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else echo $ac_n "checking for PDO includes""... $ac_c" 1>&6 -echo "configure:85405: checking for PDO includes" >&5 +echo "configure:85938: checking for PDO includes" >&5 if test -f $abs_srcdir/include/php/ext/pdo/php_pdo_driver.h; then pdo_inc_path=$abs_srcdir/ext elif test -f $abs_srcdir/ext/pdo/php_pdo_driver.h; then @@ -85435,7 +85968,7 @@ EOF SQLITE_DIR=$PHP_SQLITE else # search default path list echo $ac_n "checking for sqlite files in default path""... $ac_c" 1>&6 -echo "configure:85439: checking for sqlite files in default path" >&5 +echo "configure:85972: checking for sqlite files in default path" >&5 for i in $SEARCH_PATH ; do if test -r $i/$SEARCH_FOR; then SQLITE_DIR=$i @@ -85547,7 +86080,7 @@ echo "configure:85439: checking for sqlite files in default path" >&5 done echo $ac_n "checking for sqlite_open in -lsqlite""... $ac_c" 1>&6 -echo "configure:85551: checking for sqlite_open in -lsqlite" >&5 +echo "configure:86084: checking for sqlite_open in -lsqlite" >&5 ac_lib_var=`echo sqlite'_'sqlite_open | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -85555,7 +86088,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsqlite $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:86103: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -85739,7 +86272,7 @@ fi # Extract the first word of "lemon", so it can be a program name with args. set dummy lemon; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:85743: checking for $ac_word" >&5 +echo "configure:86276: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_LEMON'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -85767,7 +86300,7 @@ fi if test "$LEMON"; then echo $ac_n "checking for lemon version""... $ac_c" 1>&6 -echo "configure:85771: checking for lemon version" >&5 +echo "configure:86304: checking for lemon version" >&5 if eval "test \"`echo '$''{'php_cv_lemon_version'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -86180,7 +86713,7 @@ but you've either not enabled pdo, or have disabled it. echo $ac_n "checking size of char *""... $ac_c" 1>&6 -echo "configure:86184: checking size of char *" >&5 +echo "configure:86717: checking size of char *" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_char_p'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -86188,7 +86721,7 @@ else ac_cv_sizeof_char_p=4 else cat > conftest.$ac_ext < int main() @@ -86199,7 +86732,7 @@ int main() return(0); } EOF -if { (eval echo configure:86203: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:86736: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_char_p=`cat conftestval` else @@ -86261,12 +86794,12 @@ EOF for ac_func in usleep nanosleep do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:86265: checking for $ac_func" >&5 +echo "configure:86798: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:86826: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -86317,17 +86850,17 @@ done do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:86321: checking for $ac_hdr" >&5 +echo "configure:86854: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:86331: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:86864: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -86358,7 +86891,7 @@ fi echo $ac_n "checking whether flush should be called explicitly after a buffered io""... $ac_c" 1>&6 -echo "configure:86362: checking whether flush should be called explicitly after a buffered io" >&5 +echo "configure:86895: checking whether flush should be called explicitly after a buffered io" >&5 if eval "test \"`echo '$''{'ac_cv_flush_io'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -86369,7 +86902,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -86407,7 +86940,7 @@ int main(int argc, char **argv) } EOF -if { (eval echo configure:86411: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:86944: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_flush_io=no @@ -86435,7 +86968,7 @@ fi if test "$ac_cv_func_crypt" = "no"; then echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 -echo "configure:86439: checking for crypt in -lcrypt" >&5 +echo "configure:86972: checking for crypt in -lcrypt" >&5 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -86443,7 +86976,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:86991: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -86483,7 +87016,7 @@ fi fi echo $ac_n "checking for standard DES crypt""... $ac_c" 1>&6 -echo "configure:86487: checking for standard DES crypt" >&5 +echo "configure:87020: checking for standard DES crypt" >&5 if eval "test \"`echo '$''{'ac_cv_crypt_des'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -86494,7 +87027,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:87050: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_crypt_des=yes @@ -86534,7 +87067,7 @@ fi echo "$ac_t""$ac_cv_crypt_des" 1>&6 echo $ac_n "checking for extended DES crypt""... $ac_c" 1>&6 -echo "configure:86538: checking for extended DES crypt" >&5 +echo "configure:87071: checking for extended DES crypt" >&5 if eval "test \"`echo '$''{'ac_cv_crypt_ext_des'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -86545,7 +87078,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:87101: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_crypt_ext_des=yes @@ -86585,7 +87118,7 @@ fi echo "$ac_t""$ac_cv_crypt_ext_des" 1>&6 echo $ac_n "checking for MD5 crypt""... $ac_c" 1>&6 -echo "configure:86589: checking for MD5 crypt" >&5 +echo "configure:87122: checking for MD5 crypt" >&5 if eval "test \"`echo '$''{'ac_cv_crypt_md5'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -86596,7 +87129,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:87161: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_crypt_md5=yes @@ -86645,7 +87178,7 @@ fi echo "$ac_t""$ac_cv_crypt_md5" 1>&6 echo $ac_n "checking for Blowfish crypt""... $ac_c" 1>&6 -echo "configure:86649: checking for Blowfish crypt" >&5 +echo "configure:87182: checking for Blowfish crypt" >&5 if eval "test \"`echo '$''{'ac_cv_crypt_blowfish'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -86656,7 +87189,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:87218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_crypt_blowfish=yes @@ -86812,12 +87345,12 @@ fi for ac_func in getcwd getwd asinh acosh atanh log1p hypot glob strfmon nice fpclass isinf isnan do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:86816: checking for $ac_func" >&5 +echo "configure:87349: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:87377: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -86865,7 +87398,7 @@ fi done echo $ac_n "checking for working fnmatch""... $ac_c" 1>&6 -echo "configure:86869: checking for working fnmatch" >&5 +echo "configure:87402: checking for working fnmatch" >&5 if eval "test \"`echo '$''{'ac_cv_func_fnmatch_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -86876,11 +87409,11 @@ if test "$cross_compiling" = yes; then ac_cv_func_fnmatch_works=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:87417: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_fnmatch_works=yes else @@ -86911,12 +87444,12 @@ else for ac_func in fork CreateProcess do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:86915: checking for $ac_func" >&5 +echo "configure:87448: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:87476: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -86971,7 +87504,7 @@ done fi echo $ac_n "checking if your OS can spawn processes with inherited handles""... $ac_c" 1>&6 -echo "configure:86975: checking if your OS can spawn processes with inherited handles" >&5 +echo "configure:87508: checking if your OS can spawn processes with inherited handles" >&5 if test "$php_can_support_proc_open" = "yes"; then echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF @@ -86990,98 +87523,98 @@ EOF fi - unset ac_cv_func_res_nmkquery - unset ac_cv_func___res_nmkquery + unset ac_cv_func_res_nsearch + unset ac_cv_func___res_nsearch unset found - echo $ac_n "checking for res_nmkquery""... $ac_c" 1>&6 -echo "configure:86999: checking for res_nmkquery" >&5 -if eval "test \"`echo '$''{'ac_cv_func_res_nmkquery'+set}'`\" = set"; then + echo $ac_n "checking for res_nsearch""... $ac_c" 1>&6 +echo "configure:87532: checking for res_nsearch" >&5 +if eval "test \"`echo '$''{'ac_cv_func_res_nsearch'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char res_nmkquery(); +char res_nsearch(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_res_nmkquery) || defined (__stub___res_nmkquery) +#if defined (__stub_res_nsearch) || defined (__stub___res_nsearch) choke me #else -res_nmkquery(); +res_nsearch(); #endif ; return 0; } EOF -if { (eval echo configure:87027: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:87560: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_func_res_nmkquery=yes" + eval "ac_cv_func_res_nsearch=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_func_res_nmkquery=no" + eval "ac_cv_func_res_nsearch=no" fi rm -f conftest* fi -if eval "test \"`echo '$ac_cv_func_'res_nmkquery`\" = yes"; then +if eval "test \"`echo '$ac_cv_func_'res_nsearch`\" = yes"; then echo "$ac_t""yes" 1>&6 found=yes else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_nmkquery""... $ac_c" 1>&6 -echo "configure:87045: checking for __res_nmkquery" >&5 -if eval "test \"`echo '$''{'ac_cv_func___res_nmkquery'+set}'`\" = set"; then + echo $ac_n "checking for __res_nsearch""... $ac_c" 1>&6 +echo "configure:87578: checking for __res_nsearch" >&5 +if eval "test \"`echo '$''{'ac_cv_func___res_nsearch'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char __res_nmkquery(); +char __res_nsearch(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub___res_nmkquery) || defined (__stub_____res_nmkquery) +#if defined (__stub___res_nsearch) || defined (__stub_____res_nsearch) choke me #else -__res_nmkquery(); +__res_nsearch(); #endif ; return 0; } EOF -if { (eval echo configure:87073: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:87606: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_func___res_nmkquery=yes" + eval "ac_cv_func___res_nsearch=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_func___res_nmkquery=no" + eval "ac_cv_func___res_nsearch=no" fi rm -f conftest* fi -if eval "test \"`echo '$ac_cv_func_'__res_nmkquery`\" = yes"; then +if eval "test \"`echo '$ac_cv_func_'__res_nsearch`\" = yes"; then echo "$ac_t""yes" 1>&6 found=yes else @@ -87095,38 +87628,38 @@ fi case $found in yes) cat >> confdefs.h <<\EOF -#define HAVE_RES_NMKQUERY 1 +#define HAVE_RES_NSEARCH 1 EOF - ac_cv_func_res_nmkquery=yes + ac_cv_func_res_nsearch=yes ;; *) - unset ac_cv_lib_resolv_res_nmkquery - unset ac_cv_lib_resolv___res_nmkquery + unset ac_cv_lib_resolv_res_nsearch + unset ac_cv_lib_resolv___res_nsearch unset found - echo $ac_n "checking for res_nmkquery in -lresolv""... $ac_c" 1>&6 -echo "configure:87111: checking for res_nmkquery in -lresolv" >&5 -ac_lib_var=`echo resolv'_'res_nmkquery | sed 'y%./+-%__p_%'` + echo $ac_n "checking for res_nsearch in -lresolv""... $ac_c" 1>&6 +echo "configure:87644: checking for res_nsearch in -lresolv" >&5 +ac_lib_var=`echo resolv'_'res_nsearch | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:87663: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -87145,27 +87678,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_nmkquery in -lresolv""... $ac_c" 1>&6 -echo "configure:87150: checking for __res_nmkquery in -lresolv" >&5 -ac_lib_var=`echo resolv'_'__res_nmkquery | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __res_nsearch in -lresolv""... $ac_c" 1>&6 +echo "configure:87683: checking for __res_nsearch in -lresolv" >&5 +ac_lib_var=`echo resolv'_'__res_nsearch | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:87702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -87197,11 +87730,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:87738: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -87228,41 +87761,41 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_RES_NMKQUERY 1 +#define HAVE_RES_NSEARCH 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBRESOLV 1 EOF - ac_cv_func_res_nmkquery=yes + ac_cv_func_res_nsearch=yes else - unset ac_cv_lib_bind_res_nmkquery - unset ac_cv_lib_bind___res_nmkquery + unset ac_cv_lib_bind_res_nsearch + unset ac_cv_lib_bind___res_nsearch unset found - echo $ac_n "checking for res_nmkquery in -lbind""... $ac_c" 1>&6 -echo "configure:87247: checking for res_nmkquery in -lbind" >&5 -ac_lib_var=`echo bind'_'res_nmkquery | sed 'y%./+-%__p_%'` + echo $ac_n "checking for res_nsearch in -lbind""... $ac_c" 1>&6 +echo "configure:87780: checking for res_nsearch in -lbind" >&5 +ac_lib_var=`echo bind'_'res_nsearch | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:87799: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -87281,27 +87814,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_nmkquery in -lbind""... $ac_c" 1>&6 -echo "configure:87286: checking for __res_nmkquery in -lbind" >&5 -ac_lib_var=`echo bind'_'__res_nmkquery | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __res_nsearch in -lbind""... $ac_c" 1>&6 +echo "configure:87819: checking for __res_nsearch in -lbind" >&5 +ac_lib_var=`echo bind'_'__res_nsearch | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:87838: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -87333,11 +87866,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:87874: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -87364,41 +87897,41 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_RES_NMKQUERY 1 +#define HAVE_RES_NSEARCH 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBBIND 1 EOF - ac_cv_func_res_nmkquery=yes + ac_cv_func_res_nsearch=yes else - unset ac_cv_lib_socket_res_nmkquery - unset ac_cv_lib_socket___res_nmkquery + unset ac_cv_lib_socket_res_nsearch + unset ac_cv_lib_socket___res_nsearch unset found - echo $ac_n "checking for res_nmkquery in -lsocket""... $ac_c" 1>&6 -echo "configure:87383: checking for res_nmkquery in -lsocket" >&5 -ac_lib_var=`echo socket'_'res_nmkquery | sed 'y%./+-%__p_%'` + echo $ac_n "checking for res_nsearch in -lsocket""... $ac_c" 1>&6 +echo "configure:87916: checking for res_nsearch in -lsocket" >&5 +ac_lib_var=`echo socket'_'res_nsearch | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:87935: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -87417,27 +87950,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_nmkquery in -lsocket""... $ac_c" 1>&6 -echo "configure:87422: checking for __res_nmkquery in -lsocket" >&5 -ac_lib_var=`echo socket'_'__res_nmkquery | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __res_nsearch in -lsocket""... $ac_c" 1>&6 +echo "configure:87955: checking for __res_nsearch in -lsocket" >&5 +ac_lib_var=`echo socket'_'__res_nsearch | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:87974: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -87469,11 +88002,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:88010: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -87500,14 +88033,14 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_RES_NMKQUERY 1 +#define HAVE_RES_NSEARCH 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBSOCKET 1 EOF - ac_cv_func_res_nmkquery=yes + ac_cv_func_res_nsearch=yes else : @@ -87525,98 +88058,98 @@ EOF esac - unset ac_cv_func_res_nsend - unset ac_cv_func___res_nsend + unset ac_cv_func_dns_search + unset ac_cv_func___dns_search unset found - echo $ac_n "checking for res_nsend""... $ac_c" 1>&6 -echo "configure:87534: checking for res_nsend" >&5 -if eval "test \"`echo '$''{'ac_cv_func_res_nsend'+set}'`\" = set"; then + echo $ac_n "checking for dns_search""... $ac_c" 1>&6 +echo "configure:88067: checking for dns_search" >&5 +if eval "test \"`echo '$''{'ac_cv_func_dns_search'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char res_nsend(); +char dns_search(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_res_nsend) || defined (__stub___res_nsend) +#if defined (__stub_dns_search) || defined (__stub___dns_search) choke me #else -res_nsend(); +dns_search(); #endif ; return 0; } EOF -if { (eval echo configure:87562: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88095: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_func_res_nsend=yes" + eval "ac_cv_func_dns_search=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_func_res_nsend=no" + eval "ac_cv_func_dns_search=no" fi rm -f conftest* fi -if eval "test \"`echo '$ac_cv_func_'res_nsend`\" = yes"; then +if eval "test \"`echo '$ac_cv_func_'dns_search`\" = yes"; then echo "$ac_t""yes" 1>&6 found=yes else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_nsend""... $ac_c" 1>&6 -echo "configure:87580: checking for __res_nsend" >&5 -if eval "test \"`echo '$''{'ac_cv_func___res_nsend'+set}'`\" = set"; then + echo $ac_n "checking for __dns_search""... $ac_c" 1>&6 +echo "configure:88113: checking for __dns_search" >&5 +if eval "test \"`echo '$''{'ac_cv_func___dns_search'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char __res_nsend(); +char __dns_search(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub___res_nsend) || defined (__stub_____res_nsend) +#if defined (__stub___dns_search) || defined (__stub_____dns_search) choke me #else -__res_nsend(); +__dns_search(); #endif ; return 0; } EOF -if { (eval echo configure:87608: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88141: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_func___res_nsend=yes" + eval "ac_cv_func___dns_search=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_func___res_nsend=no" + eval "ac_cv_func___dns_search=no" fi rm -f conftest* fi -if eval "test \"`echo '$ac_cv_func_'__res_nsend`\" = yes"; then +if eval "test \"`echo '$ac_cv_func_'__dns_search`\" = yes"; then echo "$ac_t""yes" 1>&6 found=yes else @@ -87630,38 +88163,38 @@ fi case $found in yes) cat >> confdefs.h <<\EOF -#define HAVE_RES_NSEND 1 +#define HAVE_DNS_SEARCH 1 EOF - ac_cv_func_res_nsend=yes + ac_cv_func_dns_search=yes ;; *) - unset ac_cv_lib_resolv_res_nsend - unset ac_cv_lib_resolv___res_nsend + unset ac_cv_lib_resolv_dns_search + unset ac_cv_lib_resolv___dns_search unset found - echo $ac_n "checking for res_nsend in -lresolv""... $ac_c" 1>&6 -echo "configure:87646: checking for res_nsend in -lresolv" >&5 -ac_lib_var=`echo resolv'_'res_nsend | sed 'y%./+-%__p_%'` + echo $ac_n "checking for dns_search in -lresolv""... $ac_c" 1>&6 +echo "configure:88179: checking for dns_search in -lresolv" >&5 +ac_lib_var=`echo resolv'_'dns_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88198: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -87680,27 +88213,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_nsend in -lresolv""... $ac_c" 1>&6 -echo "configure:87685: checking for __res_nsend in -lresolv" >&5 -ac_lib_var=`echo resolv'_'__res_nsend | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __dns_search in -lresolv""... $ac_c" 1>&6 +echo "configure:88218: checking for __dns_search in -lresolv" >&5 +ac_lib_var=`echo resolv'_'__dns_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88237: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -87732,11 +88265,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:88273: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -87763,41 +88296,41 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_RES_NSEND 1 +#define HAVE_DNS_SEARCH 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBRESOLV 1 EOF - ac_cv_func_res_nsend=yes + ac_cv_func_dns_search=yes else - unset ac_cv_lib_bind_res_nsend - unset ac_cv_lib_bind___res_nsend + unset ac_cv_lib_bind_dns_search + unset ac_cv_lib_bind___dns_search unset found - echo $ac_n "checking for res_nsend in -lbind""... $ac_c" 1>&6 -echo "configure:87782: checking for res_nsend in -lbind" >&5 -ac_lib_var=`echo bind'_'res_nsend | sed 'y%./+-%__p_%'` + echo $ac_n "checking for dns_search in -lbind""... $ac_c" 1>&6 +echo "configure:88315: checking for dns_search in -lbind" >&5 +ac_lib_var=`echo bind'_'dns_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88334: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -87816,27 +88349,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_nsend in -lbind""... $ac_c" 1>&6 -echo "configure:87821: checking for __res_nsend in -lbind" >&5 -ac_lib_var=`echo bind'_'__res_nsend | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __dns_search in -lbind""... $ac_c" 1>&6 +echo "configure:88354: checking for __dns_search in -lbind" >&5 +ac_lib_var=`echo bind'_'__dns_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -87868,11 +88401,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:88409: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -87899,41 +88432,41 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_RES_NSEND 1 +#define HAVE_DNS_SEARCH 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBBIND 1 EOF - ac_cv_func_res_nsend=yes + ac_cv_func_dns_search=yes else - unset ac_cv_lib_socket_res_nsend - unset ac_cv_lib_socket___res_nsend + unset ac_cv_lib_socket_dns_search + unset ac_cv_lib_socket___dns_search unset found - echo $ac_n "checking for res_nsend in -lsocket""... $ac_c" 1>&6 -echo "configure:87918: checking for res_nsend in -lsocket" >&5 -ac_lib_var=`echo socket'_'res_nsend | sed 'y%./+-%__p_%'` + echo $ac_n "checking for dns_search in -lsocket""... $ac_c" 1>&6 +echo "configure:88451: checking for dns_search in -lsocket" >&5 +ac_lib_var=`echo socket'_'dns_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88470: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -87952,27 +88485,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_nsend in -lsocket""... $ac_c" 1>&6 -echo "configure:87957: checking for __res_nsend in -lsocket" >&5 -ac_lib_var=`echo socket'_'__res_nsend | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __dns_search in -lsocket""... $ac_c" 1>&6 +echo "configure:88490: checking for __dns_search in -lsocket" >&5 +ac_lib_var=`echo socket'_'__dns_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88509: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -88004,11 +88537,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:88545: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -88035,14 +88568,14 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_RES_NSEND 1 +#define HAVE_DNS_SEARCH 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBSOCKET 1 EOF - ac_cv_func_res_nsend=yes + ac_cv_func_dns_search=yes else : @@ -88060,98 +88593,98 @@ EOF esac - unset ac_cv_func_res_search - unset ac_cv_func___res_search + unset ac_cv_func_dn_expand + unset ac_cv_func___dn_expand unset found - echo $ac_n "checking for res_search""... $ac_c" 1>&6 -echo "configure:88069: checking for res_search" >&5 -if eval "test \"`echo '$''{'ac_cv_func_res_search'+set}'`\" = set"; then + echo $ac_n "checking for dn_expand""... $ac_c" 1>&6 +echo "configure:88602: checking for dn_expand" >&5 +if eval "test \"`echo '$''{'ac_cv_func_dn_expand'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char res_search(); +char dn_expand(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_res_search) || defined (__stub___res_search) +#if defined (__stub_dn_expand) || defined (__stub___dn_expand) choke me #else -res_search(); +dn_expand(); #endif ; return 0; } EOF -if { (eval echo configure:88097: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88630: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_func_res_search=yes" + eval "ac_cv_func_dn_expand=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_func_res_search=no" + eval "ac_cv_func_dn_expand=no" fi rm -f conftest* fi -if eval "test \"`echo '$ac_cv_func_'res_search`\" = yes"; then +if eval "test \"`echo '$ac_cv_func_'dn_expand`\" = yes"; then echo "$ac_t""yes" 1>&6 found=yes else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_search""... $ac_c" 1>&6 -echo "configure:88115: checking for __res_search" >&5 -if eval "test \"`echo '$''{'ac_cv_func___res_search'+set}'`\" = set"; then + echo $ac_n "checking for __dn_expand""... $ac_c" 1>&6 +echo "configure:88648: checking for __dn_expand" >&5 +if eval "test \"`echo '$''{'ac_cv_func___dn_expand'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char __res_search(); +char __dn_expand(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub___res_search) || defined (__stub_____res_search) +#if defined (__stub___dn_expand) || defined (__stub_____dn_expand) choke me #else -__res_search(); +__dn_expand(); #endif ; return 0; } EOF -if { (eval echo configure:88143: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88676: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_func___res_search=yes" + eval "ac_cv_func___dn_expand=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_func___res_search=no" + eval "ac_cv_func___dn_expand=no" fi rm -f conftest* fi -if eval "test \"`echo '$ac_cv_func_'__res_search`\" = yes"; then +if eval "test \"`echo '$ac_cv_func_'__dn_expand`\" = yes"; then echo "$ac_t""yes" 1>&6 found=yes else @@ -88165,38 +88698,38 @@ fi case $found in yes) cat >> confdefs.h <<\EOF -#define HAVE_RES_SEARCH 1 +#define HAVE_DN_EXPAND 1 EOF - ac_cv_func_res_search=yes + ac_cv_func_dn_expand=yes ;; *) - unset ac_cv_lib_resolv_res_search - unset ac_cv_lib_resolv___res_search + unset ac_cv_lib_resolv_dn_expand + unset ac_cv_lib_resolv___dn_expand unset found - echo $ac_n "checking for res_search in -lresolv""... $ac_c" 1>&6 -echo "configure:88181: checking for res_search in -lresolv" >&5 -ac_lib_var=`echo resolv'_'res_search | sed 'y%./+-%__p_%'` + echo $ac_n "checking for dn_expand in -lresolv""... $ac_c" 1>&6 +echo "configure:88714: checking for dn_expand in -lresolv" >&5 +ac_lib_var=`echo resolv'_'dn_expand | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88733: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -88215,551 +88748,16 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_search in -lresolv""... $ac_c" 1>&6 -echo "configure:88220: checking for __res_search in -lresolv" >&5 -ac_lib_var=`echo resolv'_'__res_search | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __dn_expand in -lresolv""... $ac_c" 1>&6 +echo "configure:88753: checking for __dn_expand in -lresolv" >&5 +ac_lib_var=`echo resolv'_'__dn_expand | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 -found=no -fi - - -fi - - - if test "$found" = "yes"; then - ac_libs=$LIBS - LIBS="$LIBS -lresolv" - if test "$cross_compiling" = yes; then - found=no -else - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -then - found=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - found=no -fi -rm -fr conftest* -fi - - LIBS=$ac_libs - fi - - if test "$found" = "yes"; then - - - case resolv in - c|c_r|pthread*) ;; - *) - LIBS="-lresolv $LIBS" - ;; - esac - - - cat >> confdefs.h <<\EOF -#define HAVE_RES_SEARCH 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_LIBRESOLV 1 -EOF - - ac_cv_func_res_search=yes - else - - - unset ac_cv_lib_bind_res_search - unset ac_cv_lib_bind___res_search - unset found - echo $ac_n "checking for res_search in -lbind""... $ac_c" 1>&6 -echo "configure:88317: checking for res_search in -lbind" >&5 -ac_lib_var=`echo bind'_'res_search | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lbind $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 - - echo $ac_n "checking for __res_search in -lbind""... $ac_c" 1>&6 -echo "configure:88356: checking for __res_search in -lbind" >&5 -ac_lib_var=`echo bind'_'__res_search | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lbind $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 -found=no -fi - - -fi - - - if test "$found" = "yes"; then - ac_libs=$LIBS - LIBS="$LIBS -lbind" - if test "$cross_compiling" = yes; then - found=no -else - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -then - found=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - found=no -fi -rm -fr conftest* -fi - - LIBS=$ac_libs - fi - - if test "$found" = "yes"; then - - - case bind in - c|c_r|pthread*) ;; - *) - LIBS="-lbind $LIBS" - ;; - esac - - - cat >> confdefs.h <<\EOF -#define HAVE_RES_SEARCH 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_LIBBIND 1 -EOF - - ac_cv_func_res_search=yes - else - - - unset ac_cv_lib_socket_res_search - unset ac_cv_lib_socket___res_search - unset found - echo $ac_n "checking for res_search in -lsocket""... $ac_c" 1>&6 -echo "configure:88453: checking for res_search in -lsocket" >&5 -ac_lib_var=`echo socket'_'res_search | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lsocket $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 - - echo $ac_n "checking for __res_search in -lsocket""... $ac_c" 1>&6 -echo "configure:88492: checking for __res_search in -lsocket" >&5 -ac_lib_var=`echo socket'_'__res_search | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lsocket $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 -found=no -fi - - -fi - - - if test "$found" = "yes"; then - ac_libs=$LIBS - LIBS="$LIBS -lsocket" - if test "$cross_compiling" = yes; then - found=no -else - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -then - found=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - found=no -fi -rm -fr conftest* -fi - - LIBS=$ac_libs - fi - - if test "$found" = "yes"; then - - - case socket in - c|c_r|pthread*) ;; - *) - LIBS="-lsocket $LIBS" - ;; - esac - - - cat >> confdefs.h <<\EOF -#define HAVE_RES_SEARCH 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_LIBSOCKET 1 -EOF - - ac_cv_func_res_search=yes - else - - : - - fi - - - fi - - - fi - - ;; - - esac - - - unset ac_cv_func_dn_expand - unset ac_cv_func___dn_expand - unset found - - echo $ac_n "checking for dn_expand""... $ac_c" 1>&6 -echo "configure:88604: checking for dn_expand" >&5 -if eval "test \"`echo '$''{'ac_cv_func_dn_expand'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dn_expand(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dn_expand) || defined (__stub___dn_expand) -choke me -#else -dn_expand(); -#endif - -; return 0; } -EOF -if { (eval echo configure:88632: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_dn_expand=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_dn_expand=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'dn_expand`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __dn_expand""... $ac_c" 1>&6 -echo "configure:88650: checking for __dn_expand" >&5 -if eval "test \"`echo '$''{'ac_cv_func___dn_expand'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char __dn_expand(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub___dn_expand) || defined (__stub_____dn_expand) -choke me -#else -__dn_expand(); -#endif - -; return 0; } -EOF -if { (eval echo configure:88678: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func___dn_expand=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func___dn_expand=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'__dn_expand`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 -found=no -fi - -fi - - - case $found in - yes) - cat >> confdefs.h <<\EOF -#define HAVE_DN_EXPAND 1 -EOF - - ac_cv_func_dn_expand=yes - ;; - - *) - - unset ac_cv_lib_resolv_dn_expand - unset ac_cv_lib_resolv___dn_expand - unset found - echo $ac_n "checking for dn_expand in -lresolv""... $ac_c" 1>&6 -echo "configure:88716: checking for dn_expand in -lresolv" >&5 -ac_lib_var=`echo resolv'_'dn_expand | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lresolv $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 - - echo $ac_n "checking for __dn_expand in -lresolv""... $ac_c" 1>&6 -echo "configure:88755: checking for __dn_expand in -lresolv" >&5 -ac_lib_var=`echo resolv'_'__dn_expand | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lresolv $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 -found=no -fi - - -fi - - - if test "$found" = "yes"; then - ac_libs=$LIBS - LIBS="$LIBS -lresolv" - if test "$cross_compiling" = yes; then - found=no -else - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -then - found=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - found=no -fi -rm -fr conftest* -fi - - LIBS=$ac_libs - fi - - if test "$found" = "yes"; then - - - case resolv in - c|c_r|pthread*) ;; - *) - LIBS="-lresolv $LIBS" - ;; - esac - - - cat >> confdefs.h <<\EOF -#define HAVE_DN_EXPAND 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_LIBRESOLV 1 -EOF - - ac_cv_func_dn_expand=yes - else - - - unset ac_cv_lib_bind_dn_expand - unset ac_cv_lib_bind___dn_expand - unset found - echo $ac_n "checking for dn_expand in -lbind""... $ac_c" 1>&6 -echo "configure:88852: checking for dn_expand in -lbind" >&5 -ac_lib_var=`echo bind'_'dn_expand | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lbind $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 - - echo $ac_n "checking for __dn_expand in -lbind""... $ac_c" 1>&6 -echo "configure:88891: checking for __dn_expand in -lbind" >&5 -ac_lib_var=`echo bind'_'__dn_expand | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lbind $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 -found=no -fi - - -fi - - - if test "$found" = "yes"; then - ac_libs=$LIBS - LIBS="$LIBS -lbind" - if test "$cross_compiling" = yes; then - found=no -else - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -then - found=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - found=no -fi -rm -fr conftest* -fi - - LIBS=$ac_libs - fi - - if test "$found" = "yes"; then - - - case bind in - c|c_r|pthread*) ;; - *) - LIBS="-lbind $LIBS" - ;; - esac - - - cat >> confdefs.h <<\EOF -#define HAVE_DN_EXPAND 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_LIBBIND 1 -EOF - - ac_cv_func_dn_expand=yes - else - - - unset ac_cv_lib_socket_dn_expand - unset ac_cv_lib_socket___dn_expand - unset found - echo $ac_n "checking for dn_expand in -lsocket""... $ac_c" 1>&6 -echo "configure:88988: checking for dn_expand in -lsocket" >&5 -ac_lib_var=`echo socket'_'dn_expand | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lsocket $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 - - echo $ac_n "checking for __dn_expand in -lsocket""... $ac_c" 1>&6 -echo "configure:89027: checking for __dn_expand in -lsocket" >&5 -ac_lib_var=`echo socket'_'__dn_expand | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lsocket $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 -found=no -fi - - -fi - - - if test "$found" = "yes"; then - ac_libs=$LIBS - LIBS="$LIBS -lsocket" - if test "$cross_compiling" = yes; then - found=no -else - cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null -then - found=yes -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -fr conftest* - found=no -fi -rm -fr conftest* -fi - - LIBS=$ac_libs - fi - - if test "$found" = "yes"; then - - - case socket in - c|c_r|pthread*) ;; - *) - LIBS="-lsocket $LIBS" - ;; - esac - - - cat >> confdefs.h <<\EOF -#define HAVE_DN_EXPAND 1 -EOF - - cat >> confdefs.h <<\EOF -#define HAVE_LIBSOCKET 1 -EOF - - ac_cv_func_dn_expand=yes - else - - : - - fi - - - fi - - - fi - - ;; - - esac - - - unset ac_cv_func_dn_skipname - unset ac_cv_func___dn_skipname - unset found - - echo $ac_n "checking for dn_skipname""... $ac_c" 1>&6 -echo "configure:89139: checking for dn_skipname" >&5 -if eval "test \"`echo '$''{'ac_cv_func_dn_skipname'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char dn_skipname(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub_dn_skipname) || defined (__stub___dn_skipname) -choke me -#else -dn_skipname(); -#endif - -; return 0; } -EOF -if { (eval echo configure:89167: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func_dn_skipname=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func_dn_skipname=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'dn_skipname`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __dn_skipname""... $ac_c" 1>&6 -echo "configure:89185: checking for __dn_skipname" >&5 -if eval "test \"`echo '$''{'ac_cv_func___dn_skipname'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -/* Override any gcc2 internal prototype to avoid an error. */ -/* We use char because int might match the return type of a gcc2 - builtin and then its argument prototype would still apply. */ -char __dn_skipname(); - -int main() { - -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined (__stub___dn_skipname) || defined (__stub_____dn_skipname) -choke me -#else -__dn_skipname(); -#endif - -; return 0; } -EOF -if { (eval echo configure:89213: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_func___dn_skipname=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_func___dn_skipname=no" -fi -rm -f conftest* -fi - -if eval "test \"`echo '$ac_cv_func_'__dn_skipname`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 -found=no -fi - -fi - - - case $found in - yes) - cat >> confdefs.h <<\EOF -#define HAVE_DN_SKIPNAME 1 -EOF - - ac_cv_func_dn_skipname=yes - ;; - - *) - - unset ac_cv_lib_resolv_dn_skipname - unset ac_cv_lib_resolv___dn_skipname - unset found - echo $ac_n "checking for dn_skipname in -lresolv""... $ac_c" 1>&6 -echo "configure:89251: checking for dn_skipname in -lresolv" >&5 -ac_lib_var=`echo resolv'_'dn_skipname | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lresolv $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=yes" -else - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_lib_$ac_lib_var=no" -fi -rm -f conftest* -LIBS="$ac_save_LIBS" - -fi -if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then - echo "$ac_t""yes" 1>&6 - found=yes -else - echo "$ac_t""no" 1>&6 - - echo $ac_n "checking for __dn_skipname in -lresolv""... $ac_c" 1>&6 -echo "configure:89290: checking for __dn_skipname in -lresolv" >&5 -ac_lib_var=`echo resolv'_'__dn_skipname | sed 'y%./+-%__p_%'` -if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - ac_save_LIBS="$LIBS" -LIBS="-lresolv $LIBS" -cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88772: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -89337,11 +88800,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:88808: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -89368,41 +88831,41 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_DN_SKIPNAME 1 +#define HAVE_DN_EXPAND 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBRESOLV 1 EOF - ac_cv_func_dn_skipname=yes + ac_cv_func_dn_expand=yes else - unset ac_cv_lib_bind_dn_skipname - unset ac_cv_lib_bind___dn_skipname + unset ac_cv_lib_bind_dn_expand + unset ac_cv_lib_bind___dn_expand unset found - echo $ac_n "checking for dn_skipname in -lbind""... $ac_c" 1>&6 -echo "configure:89387: checking for dn_skipname in -lbind" >&5 -ac_lib_var=`echo bind'_'dn_skipname | sed 'y%./+-%__p_%'` + echo $ac_n "checking for dn_expand in -lbind""... $ac_c" 1>&6 +echo "configure:88850: checking for dn_expand in -lbind" >&5 +ac_lib_var=`echo bind'_'dn_expand | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88869: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -89421,27 +88884,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __dn_skipname in -lbind""... $ac_c" 1>&6 -echo "configure:89426: checking for __dn_skipname in -lbind" >&5 -ac_lib_var=`echo bind'_'__dn_skipname | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __dn_expand in -lbind""... $ac_c" 1>&6 +echo "configure:88889: checking for __dn_expand in -lbind" >&5 +ac_lib_var=`echo bind'_'__dn_expand | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:88908: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -89473,11 +88936,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:88944: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -89504,41 +88967,41 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_DN_SKIPNAME 1 +#define HAVE_DN_EXPAND 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBBIND 1 EOF - ac_cv_func_dn_skipname=yes + ac_cv_func_dn_expand=yes else - unset ac_cv_lib_socket_dn_skipname - unset ac_cv_lib_socket___dn_skipname + unset ac_cv_lib_socket_dn_expand + unset ac_cv_lib_socket___dn_expand unset found - echo $ac_n "checking for dn_skipname in -lsocket""... $ac_c" 1>&6 -echo "configure:89523: checking for dn_skipname in -lsocket" >&5 -ac_lib_var=`echo socket'_'dn_skipname | sed 'y%./+-%__p_%'` + echo $ac_n "checking for dn_expand in -lsocket""... $ac_c" 1>&6 +echo "configure:88986: checking for dn_expand in -lsocket" >&5 +ac_lib_var=`echo socket'_'dn_expand | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89005: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -89557,27 +89020,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __dn_skipname in -lsocket""... $ac_c" 1>&6 -echo "configure:89562: checking for __dn_skipname in -lsocket" >&5 -ac_lib_var=`echo socket'_'__dn_skipname | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __dn_expand in -lsocket""... $ac_c" 1>&6 +echo "configure:89025: checking for __dn_expand in -lsocket" >&5 +ac_lib_var=`echo socket'_'__dn_expand | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89044: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -89609,11 +89072,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:89080: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -89640,14 +89103,14 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_DN_SKIPNAME 1 +#define HAVE_DN_EXPAND 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBSOCKET 1 EOF - ac_cv_func_dn_skipname=yes + ac_cv_func_dn_expand=yes else : @@ -89665,100 +89128,98 @@ EOF esac - - - unset ac_cv_func_res_mkquery - unset ac_cv_func___res_mkquery + unset ac_cv_func_dn_skipname + unset ac_cv_func___dn_skipname unset found - echo $ac_n "checking for res_mkquery""... $ac_c" 1>&6 -echo "configure:89676: checking for res_mkquery" >&5 -if eval "test \"`echo '$''{'ac_cv_func_res_mkquery'+set}'`\" = set"; then + echo $ac_n "checking for dn_skipname""... $ac_c" 1>&6 +echo "configure:89137: checking for dn_skipname" >&5 +if eval "test \"`echo '$''{'ac_cv_func_dn_skipname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char res_mkquery(); +char dn_skipname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_res_mkquery) || defined (__stub___res_mkquery) +#if defined (__stub_dn_skipname) || defined (__stub___dn_skipname) choke me #else -res_mkquery(); +dn_skipname(); #endif ; return 0; } EOF -if { (eval echo configure:89704: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_func_res_mkquery=yes" + eval "ac_cv_func_dn_skipname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_func_res_mkquery=no" + eval "ac_cv_func_dn_skipname=no" fi rm -f conftest* fi -if eval "test \"`echo '$ac_cv_func_'res_mkquery`\" = yes"; then +if eval "test \"`echo '$ac_cv_func_'dn_skipname`\" = yes"; then echo "$ac_t""yes" 1>&6 found=yes else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_mkquery""... $ac_c" 1>&6 -echo "configure:89722: checking for __res_mkquery" >&5 -if eval "test \"`echo '$''{'ac_cv_func___res_mkquery'+set}'`\" = set"; then + echo $ac_n "checking for __dn_skipname""... $ac_c" 1>&6 +echo "configure:89183: checking for __dn_skipname" >&5 +if eval "test \"`echo '$''{'ac_cv_func___dn_skipname'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char __res_mkquery(); +char __dn_skipname(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub___res_mkquery) || defined (__stub_____res_mkquery) +#if defined (__stub___dn_skipname) || defined (__stub_____dn_skipname) choke me #else -__res_mkquery(); +__dn_skipname(); #endif ; return 0; } EOF -if { (eval echo configure:89750: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89211: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_func___res_mkquery=yes" + eval "ac_cv_func___dn_skipname=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_func___res_mkquery=no" + eval "ac_cv_func___dn_skipname=no" fi rm -f conftest* fi -if eval "test \"`echo '$ac_cv_func_'__res_mkquery`\" = yes"; then +if eval "test \"`echo '$ac_cv_func_'__dn_skipname`\" = yes"; then echo "$ac_t""yes" 1>&6 found=yes else @@ -89772,38 +89233,38 @@ fi case $found in yes) cat >> confdefs.h <<\EOF -#define HAVE_RES_MKQUERY 1 +#define HAVE_DN_SKIPNAME 1 EOF - ac_cv_func_res_mkquery=yes + ac_cv_func_dn_skipname=yes ;; *) - unset ac_cv_lib_resolv_res_mkquery - unset ac_cv_lib_resolv___res_mkquery + unset ac_cv_lib_resolv_dn_skipname + unset ac_cv_lib_resolv___dn_skipname unset found - echo $ac_n "checking for res_mkquery in -lresolv""... $ac_c" 1>&6 -echo "configure:89788: checking for res_mkquery in -lresolv" >&5 -ac_lib_var=`echo resolv'_'res_mkquery | sed 'y%./+-%__p_%'` + echo $ac_n "checking for dn_skipname in -lresolv""... $ac_c" 1>&6 +echo "configure:89249: checking for dn_skipname in -lresolv" >&5 +ac_lib_var=`echo resolv'_'dn_skipname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89268: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -89822,27 +89283,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_mkquery in -lresolv""... $ac_c" 1>&6 -echo "configure:89827: checking for __res_mkquery in -lresolv" >&5 -ac_lib_var=`echo resolv'_'__res_mkquery | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __dn_skipname in -lresolv""... $ac_c" 1>&6 +echo "configure:89288: checking for __dn_skipname in -lresolv" >&5 +ac_lib_var=`echo resolv'_'__dn_skipname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89307: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -89874,11 +89335,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:89343: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -89905,41 +89366,41 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_RES_MKQUERY 1 +#define HAVE_DN_SKIPNAME 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBRESOLV 1 EOF - ac_cv_func_res_mkquery=yes + ac_cv_func_dn_skipname=yes else - unset ac_cv_lib_bind_res_mkquery - unset ac_cv_lib_bind___res_mkquery + unset ac_cv_lib_bind_dn_skipname + unset ac_cv_lib_bind___dn_skipname unset found - echo $ac_n "checking for res_mkquery in -lbind""... $ac_c" 1>&6 -echo "configure:89924: checking for res_mkquery in -lbind" >&5 -ac_lib_var=`echo bind'_'res_mkquery | sed 'y%./+-%__p_%'` + echo $ac_n "checking for dn_skipname in -lbind""... $ac_c" 1>&6 +echo "configure:89385: checking for dn_skipname in -lbind" >&5 +ac_lib_var=`echo bind'_'dn_skipname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89404: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -89958,27 +89419,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_mkquery in -lbind""... $ac_c" 1>&6 -echo "configure:89963: checking for __res_mkquery in -lbind" >&5 -ac_lib_var=`echo bind'_'__res_mkquery | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __dn_skipname in -lbind""... $ac_c" 1>&6 +echo "configure:89424: checking for __dn_skipname in -lbind" >&5 +ac_lib_var=`echo bind'_'__dn_skipname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89443: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -90010,11 +89471,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:89479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -90041,41 +89502,41 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_RES_MKQUERY 1 +#define HAVE_DN_SKIPNAME 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBBIND 1 EOF - ac_cv_func_res_mkquery=yes + ac_cv_func_dn_skipname=yes else - unset ac_cv_lib_socket_res_mkquery - unset ac_cv_lib_socket___res_mkquery + unset ac_cv_lib_socket_dn_skipname + unset ac_cv_lib_socket___dn_skipname unset found - echo $ac_n "checking for res_mkquery in -lsocket""... $ac_c" 1>&6 -echo "configure:90060: checking for res_mkquery in -lsocket" >&5 -ac_lib_var=`echo socket'_'res_mkquery | sed 'y%./+-%__p_%'` + echo $ac_n "checking for dn_skipname in -lsocket""... $ac_c" 1>&6 +echo "configure:89521: checking for dn_skipname in -lsocket" >&5 +ac_lib_var=`echo socket'_'dn_skipname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89540: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -90094,27 +89555,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_mkquery in -lsocket""... $ac_c" 1>&6 -echo "configure:90099: checking for __res_mkquery in -lsocket" >&5 -ac_lib_var=`echo socket'_'__res_mkquery | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __dn_skipname in -lsocket""... $ac_c" 1>&6 +echo "configure:89560: checking for __dn_skipname in -lsocket" >&5 +ac_lib_var=`echo socket'_'__dn_skipname | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89579: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -90146,11 +89607,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:89615: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -90177,14 +89638,14 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_RES_MKQUERY 1 +#define HAVE_DN_SKIPNAME 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBSOCKET 1 EOF - ac_cv_func_res_mkquery=yes + ac_cv_func_dn_skipname=yes else : @@ -90202,98 +89663,100 @@ EOF esac - unset ac_cv_func_res_send - unset ac_cv_func___res_send + + + unset ac_cv_func_res_search + unset ac_cv_func___res_search unset found - echo $ac_n "checking for res_send""... $ac_c" 1>&6 -echo "configure:90211: checking for res_send" >&5 -if eval "test \"`echo '$''{'ac_cv_func_res_send'+set}'`\" = set"; then + echo $ac_n "checking for res_search""... $ac_c" 1>&6 +echo "configure:89674: checking for res_search" >&5 +if eval "test \"`echo '$''{'ac_cv_func_res_search'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char res_send(); +char res_search(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub_res_send) || defined (__stub___res_send) +#if defined (__stub_res_search) || defined (__stub___res_search) choke me #else -res_send(); +res_search(); #endif ; return 0; } EOF -if { (eval echo configure:90239: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89702: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_func_res_send=yes" + eval "ac_cv_func_res_search=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_func_res_send=no" + eval "ac_cv_func_res_search=no" fi rm -f conftest* fi -if eval "test \"`echo '$ac_cv_func_'res_send`\" = yes"; then +if eval "test \"`echo '$ac_cv_func_'res_search`\" = yes"; then echo "$ac_t""yes" 1>&6 found=yes else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_send""... $ac_c" 1>&6 -echo "configure:90257: checking for __res_send" >&5 -if eval "test \"`echo '$''{'ac_cv_func___res_send'+set}'`\" = set"; then + echo $ac_n "checking for __res_search""... $ac_c" 1>&6 +echo "configure:89720: checking for __res_search" >&5 +if eval "test \"`echo '$''{'ac_cv_func___res_search'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < /* Override any gcc2 internal prototype to avoid an error. */ /* We use char because int might match the return type of a gcc2 builtin and then its argument prototype would still apply. */ -char __res_send(); +char __res_search(); int main() { /* The GNU C library defines this for functions which it implements to always fail with ENOSYS. Some functions are actually named something starting with __ and the normal name is an alias. */ -#if defined (__stub___res_send) || defined (__stub_____res_send) +#if defined (__stub___res_search) || defined (__stub_____res_search) choke me #else -__res_send(); +__res_search(); #endif ; return 0; } EOF -if { (eval echo configure:90285: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89748: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* - eval "ac_cv_func___res_send=yes" + eval "ac_cv_func___res_search=yes" else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -rf conftest* - eval "ac_cv_func___res_send=no" + eval "ac_cv_func___res_search=no" fi rm -f conftest* fi -if eval "test \"`echo '$ac_cv_func_'__res_send`\" = yes"; then +if eval "test \"`echo '$ac_cv_func_'__res_search`\" = yes"; then echo "$ac_t""yes" 1>&6 found=yes else @@ -90307,38 +89770,38 @@ fi case $found in yes) cat >> confdefs.h <<\EOF -#define HAVE_RES_SEND 1 +#define HAVE_RES_SEARCH 1 EOF - ac_cv_func_res_send=yes + ac_cv_func_res_search=yes ;; *) - unset ac_cv_lib_resolv_res_send - unset ac_cv_lib_resolv___res_send + unset ac_cv_lib_resolv_res_search + unset ac_cv_lib_resolv___res_search unset found - echo $ac_n "checking for res_send in -lresolv""... $ac_c" 1>&6 -echo "configure:90323: checking for res_send in -lresolv" >&5 -ac_lib_var=`echo resolv'_'res_send | sed 'y%./+-%__p_%'` + echo $ac_n "checking for res_search in -lresolv""... $ac_c" 1>&6 +echo "configure:89786: checking for res_search in -lresolv" >&5 +ac_lib_var=`echo resolv'_'res_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89805: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -90357,27 +89820,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_send in -lresolv""... $ac_c" 1>&6 -echo "configure:90362: checking for __res_send in -lresolv" >&5 -ac_lib_var=`echo resolv'_'__res_send | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __res_search in -lresolv""... $ac_c" 1>&6 +echo "configure:89825: checking for __res_search in -lresolv" >&5 +ac_lib_var=`echo resolv'_'__res_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lresolv $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89844: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -90409,11 +89872,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:89880: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -90440,41 +89903,41 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_RES_SEND 1 +#define HAVE_RES_SEARCH 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBRESOLV 1 EOF - ac_cv_func_res_send=yes + ac_cv_func_res_search=yes else - unset ac_cv_lib_bind_res_send - unset ac_cv_lib_bind___res_send + unset ac_cv_lib_bind_res_search + unset ac_cv_lib_bind___res_search unset found - echo $ac_n "checking for res_send in -lbind""... $ac_c" 1>&6 -echo "configure:90459: checking for res_send in -lbind" >&5 -ac_lib_var=`echo bind'_'res_send | sed 'y%./+-%__p_%'` + echo $ac_n "checking for res_search in -lbind""... $ac_c" 1>&6 +echo "configure:89922: checking for res_search in -lbind" >&5 +ac_lib_var=`echo bind'_'res_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89941: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -90493,27 +89956,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_send in -lbind""... $ac_c" 1>&6 -echo "configure:90498: checking for __res_send in -lbind" >&5 -ac_lib_var=`echo bind'_'__res_send | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __res_search in -lbind""... $ac_c" 1>&6 +echo "configure:89961: checking for __res_search in -lbind" >&5 +ac_lib_var=`echo bind'_'__res_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lbind $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:89980: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -90545,11 +90008,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:90016: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -90576,41 +90039,41 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_RES_SEND 1 +#define HAVE_RES_SEARCH 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBBIND 1 EOF - ac_cv_func_res_send=yes + ac_cv_func_res_search=yes else - unset ac_cv_lib_socket_res_send - unset ac_cv_lib_socket___res_send + unset ac_cv_lib_socket_res_search + unset ac_cv_lib_socket___res_search unset found - echo $ac_n "checking for res_send in -lsocket""... $ac_c" 1>&6 -echo "configure:90595: checking for res_send in -lsocket" >&5 -ac_lib_var=`echo socket'_'res_send | sed 'y%./+-%__p_%'` + echo $ac_n "checking for res_search in -lsocket""... $ac_c" 1>&6 +echo "configure:90058: checking for res_search in -lsocket" >&5 +ac_lib_var=`echo socket'_'res_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:90077: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -90629,27 +90092,27 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 - echo $ac_n "checking for __res_send in -lsocket""... $ac_c" 1>&6 -echo "configure:90634: checking for __res_send in -lsocket" >&5 -ac_lib_var=`echo socket'_'__res_send | sed 'y%./+-%__p_%'` + echo $ac_n "checking for __res_search in -lsocket""... $ac_c" 1>&6 +echo "configure:90097: checking for __res_search in -lsocket" >&5 +ac_lib_var=`echo socket'_'__res_search | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_save_LIBS="$LIBS" LIBS="-lsocket $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:90116: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -90681,11 +90144,11 @@ fi found=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:90152: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then found=yes else @@ -90712,14 +90175,14 @@ fi cat >> confdefs.h <<\EOF -#define HAVE_RES_SEND 1 +#define HAVE_RES_SEARCH 1 EOF cat >> confdefs.h <<\EOF #define HAVE_LIBSOCKET 1 EOF - ac_cv_func_res_send=yes + ac_cv_func_res_search=yes else : @@ -90738,7 +90201,7 @@ EOF echo $ac_n "checking whether atof() accepts NAN""... $ac_c" 1>&6 -echo "configure:90742: checking whether atof() accepts NAN" >&5 +echo "configure:90205: checking whether atof() accepts NAN" >&5 if eval "test \"`echo '$''{'ac_cv_atof_accept_nan'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -90749,7 +90212,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -90769,7 +90232,7 @@ int main(int argc, char** argv) } EOF -if { (eval echo configure:90773: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:90236: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_atof_accept_nan=yes @@ -90796,7 +90259,7 @@ EOF fi echo $ac_n "checking whether atof() accepts INF""... $ac_c" 1>&6 -echo "configure:90800: checking whether atof() accepts INF" >&5 +echo "configure:90263: checking whether atof() accepts INF" >&5 if eval "test \"`echo '$''{'ac_cv_atof_accept_inf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -90807,7 +90270,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -90830,7 +90293,7 @@ int main(int argc, char** argv) } EOF -if { (eval echo configure:90834: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:90297: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_atof_accept_inf=yes @@ -90857,7 +90320,7 @@ EOF fi echo $ac_n "checking whether HUGE_VAL == INF""... $ac_c" 1>&6 -echo "configure:90861: checking whether HUGE_VAL == INF" >&5 +echo "configure:90324: checking whether HUGE_VAL == INF" >&5 if eval "test \"`echo '$''{'ac_cv_huge_val_inf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -90868,7 +90331,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -90891,7 +90354,7 @@ int main(int argc, char** argv) } EOF -if { (eval echo configure:90895: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:90358: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_huge_val_inf=yes @@ -90918,7 +90381,7 @@ EOF fi echo $ac_n "checking whether HUGE_VAL + -HUGEVAL == NAN""... $ac_c" 1>&6 -echo "configure:90922: checking whether HUGE_VAL + -HUGEVAL == NAN" >&5 +echo "configure:90385: checking whether HUGE_VAL + -HUGEVAL == NAN" >&5 if eval "test \"`echo '$''{'ac_cv_huge_val_nan'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -90929,7 +90392,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -90954,7 +90417,7 @@ int main(int argc, char** argv) } EOF -if { (eval echo configure:90958: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:90421: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_huge_val_nan=yes @@ -90981,13 +90444,13 @@ EOF fi echo $ac_n "checking whether strptime() declaration fails""... $ac_c" 1>&6 -echo "configure:90985: checking whether strptime() declaration fails" >&5 +echo "configure:90448: checking whether strptime() declaration fails" >&5 if eval "test \"`echo '$''{'ac_cv_strptime_decl_fails'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -91003,7 +90466,7 @@ int strptime(const char *s, const char *format, struct tm *tm); ; return 0; } EOF -if { (eval echo configure:91007: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:90470: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_strptime_decl_fails=no @@ -91031,17 +90494,17 @@ for ac_hdr in wchar.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:91035: checking for $ac_hdr" >&5 +echo "configure:90498: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:91045: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:90508: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -91070,12 +90533,12 @@ done for ac_func in mblen do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:91074: checking for $ac_func" >&5 +echo "configure:90537: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:90565: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -91125,12 +90588,12 @@ done for ac_func in mbrlen mbsinit do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:91129: checking for $ac_func" >&5 +echo "configure:90592: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:90620: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -91178,13 +90641,13 @@ fi done echo $ac_n "checking for mbstate_t""... $ac_c" 1>&6 -echo "configure:91182: checking for mbstate_t" >&5 +echo "configure:90645: checking for mbstate_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_mbstate_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:90664: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_mbstate_t=yes @@ -91255,7 +90718,7 @@ fi info.c iptc.c lcg.c link.c mail.c math.c md5.c metaphone.c \ microtime.c pack.c pageinfo.c quot_print.c rand.c \ soundex.c string.c scanf.c syslog.c type.c uniqid.c url.c \ - url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \ + var.c versioning.c assert.c strnatcmp.c levenshtein.c \ incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ @@ -91314,7 +90777,7 @@ EOF info.c iptc.c lcg.c link.c mail.c math.c md5.c metaphone.c \ microtime.c pack.c pageinfo.c quot_print.c rand.c \ soundex.c string.c scanf.c syslog.c type.c uniqid.c url.c \ - url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \ + var.c versioning.c assert.c strnatcmp.c levenshtein.c \ incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ @@ -91453,7 +90916,7 @@ EOF info.c iptc.c lcg.c link.c mail.c math.c md5.c metaphone.c \ microtime.c pack.c pageinfo.c quot_print.c rand.c \ soundex.c string.c scanf.c syslog.c type.c uniqid.c url.c \ - url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \ + var.c versioning.c assert.c strnatcmp.c levenshtein.c \ incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ @@ -91509,7 +90972,7 @@ EOF info.c iptc.c lcg.c link.c mail.c math.c md5.c metaphone.c \ microtime.c pack.c pageinfo.c quot_print.c rand.c \ soundex.c string.c scanf.c syslog.c type.c uniqid.c url.c \ - url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \ + var.c versioning.c assert.c strnatcmp.c levenshtein.c \ incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ @@ -91584,7 +91047,7 @@ EOF php_with_sybase_ct=no echo $ac_n "checking for Sybase-CT support""... $ac_c" 1>&6 -echo "configure:91588: checking for Sybase-CT support" >&5 +echo "configure:91051: checking for Sybase-CT support" >&5 # Check whether --with-sybase-ct or --without-sybase-ct was given. if test "${with_sybase_ct+set}" = set; then withval="$with_sybase_ct" @@ -92234,7 +91697,7 @@ EOF done echo $ac_n "checking for netg_errstr in -ltcl""... $ac_c" 1>&6 -echo "configure:92238: checking for netg_errstr in -ltcl" >&5 +echo "configure:91701: checking for netg_errstr in -ltcl" >&5 ac_lib_var=`echo tcl'_'netg_errstr | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -92242,7 +91705,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ltcl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:91720: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -92428,7 +91891,7 @@ fi done echo $ac_n "checking for insck__getVdate in -linsck""... $ac_c" 1>&6 -echo "configure:92432: checking for insck__getVdate in -linsck" >&5 +echo "configure:91895: checking for insck__getVdate in -linsck" >&5 ac_lib_var=`echo insck'_'insck__getVdate | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -92436,7 +91899,7 @@ else ac_save_LIBS="$LIBS" LIBS="-linsck $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:91914: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -92595,7 +92058,7 @@ fi done echo $ac_n "checking for bsd_tcp in -linsck""... $ac_c" 1>&6 -echo "configure:92599: checking for bsd_tcp in -linsck" >&5 +echo "configure:92062: checking for bsd_tcp in -linsck" >&5 ac_lib_var=`echo insck'_'bsd_tcp | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -92603,7 +92066,7 @@ else ac_save_LIBS="$LIBS" LIBS="-linsck $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:92081: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -92674,7 +92137,7 @@ fi php_enable_sysvmsg=no echo $ac_n "checking whether to enable System V IPC support""... $ac_c" 1>&6 -echo "configure:92678: checking whether to enable System V IPC support" >&5 +echo "configure:92141: checking whether to enable System V IPC support" >&5 # Check whether --enable-sysvmsg or --disable-sysvmsg was given. if test "${enable_sysvmsg+set}" = set; then enableval="$enable_sysvmsg" @@ -92720,17 +92183,17 @@ echo "$ac_t""$ext_output" 1>&6 if test "$PHP_SYSVMSG" != "no"; then ac_safe=`echo "sys/msg.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for sys/msg.h""... $ac_c" 1>&6 -echo "configure:92724: checking for sys/msg.h" >&5 +echo "configure:92187: checking for sys/msg.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:92734: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:92197: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -93057,7 +92520,7 @@ fi php_enable_sysvsem=no echo $ac_n "checking whether to enable System V semaphore support""... $ac_c" 1>&6 -echo "configure:93061: checking whether to enable System V semaphore support" >&5 +echo "configure:92524: checking whether to enable System V semaphore support" >&5 # Check whether --enable-sysvsem or --disable-sysvsem was given. if test "${enable_sysvsem+set}" = set; then enableval="$enable_sysvsem" @@ -93398,12 +92861,12 @@ EOF EOF echo $ac_n "checking for union semun""... $ac_c" 1>&6 -echo "configure:93402: checking for union semun" >&5 +echo "configure:92865: checking for union semun" >&5 if eval "test \"`echo '$''{'php_cv_semun'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -93414,7 +92877,7 @@ int main() { union semun x; ; return 0; } EOF -if { (eval echo configure:93418: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:92881: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* php_cv_semun=yes @@ -93450,7 +92913,7 @@ fi php_enable_sysvshm=no echo $ac_n "checking whether to enable System V shared memory support""... $ac_c" 1>&6 -echo "configure:93454: checking whether to enable System V shared memory support" >&5 +echo "configure:92917: checking whether to enable System V shared memory support" >&5 # Check whether --enable-sysvshm or --disable-sysvshm was given. if test "${enable_sysvshm+set}" = set; then enableval="$enable_sysvshm" @@ -93797,7 +93260,7 @@ fi php_with_tidy=no echo $ac_n "checking for TIDY support""... $ac_c" 1>&6 -echo "configure:93801: checking for TIDY support" >&5 +echo "configure:93264: checking for TIDY support" >&5 # Check whether --with-tidy or --without-tidy was given. if test "${with_tidy+set}" = set; then withval="$with_tidy" @@ -94089,7 +93552,7 @@ if test "$PHP_TIDY" != "no"; then done echo $ac_n "checking for tidyOptGetDoc in -ltidy""... $ac_c" 1>&6 -echo "configure:94093: checking for tidyOptGetDoc in -ltidy" >&5 +echo "configure:93556: checking for tidyOptGetDoc in -ltidy" >&5 ac_lib_var=`echo tidy'_'tidyOptGetDoc | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -94097,7 +93560,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ltidy $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:93575: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -94452,7 +93915,7 @@ fi php_enable_tokenizer=yes echo $ac_n "checking whether to enable tokenizer support""... $ac_c" 1>&6 -echo "configure:94456: checking whether to enable tokenizer support" >&5 +echo "configure:93919: checking whether to enable tokenizer support" >&5 # Check whether --enable-tokenizer or --disable-tokenizer was given. if test "${enable_tokenizer+set}" = set; then enableval="$enable_tokenizer" @@ -94801,7 +94264,7 @@ fi php_enable_wddx=no echo $ac_n "checking whether to enable WDDX support""... $ac_c" 1>&6 -echo "configure:94805: checking whether to enable WDDX support" >&5 +echo "configure:94268: checking whether to enable WDDX support" >&5 # Check whether --enable-wddx or --disable-wddx was given. if test "${enable_wddx+set}" = set; then enableval="$enable_wddx" @@ -94849,7 +94312,7 @@ if test -z "$PHP_LIBXML_DIR"; then php_with_libxml_dir=no echo $ac_n "checking libxml2 install dir""... $ac_c" 1>&6 -echo "configure:94853: checking libxml2 install dir" >&5 +echo "configure:94316: checking libxml2 install dir" >&5 # Check whether --with-libxml-dir or --without-libxml-dir was given. if test "${with_libxml_dir+set}" = set; then withval="$with_libxml_dir" @@ -94876,7 +94339,7 @@ fi php_with_libexpat_dir=no echo $ac_n "checking libexpat dir for WDDX""... $ac_c" 1>&6 -echo "configure:94880: checking libexpat dir for WDDX" >&5 +echo "configure:94343: checking libexpat dir for WDDX" >&5 # Check whether --with-libexpat-dir or --without-libexpat-dir was given. if test "${with_libexpat_dir+set}" = set; then withval="$with_libexpat_dir" @@ -94907,7 +94370,7 @@ if test "$PHP_WDDX" != "no"; then echo $ac_n "checking for xml2-config path""... $ac_c" 1>&6 -echo "configure:94911: checking for xml2-config path" >&5 +echo "configure:94374: checking for xml2-config path" >&5 if eval "test \"`echo '$''{'ac_cv_php_xml2_config_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -95065,7 +94528,7 @@ echo "$ac_t""$ac_cv_php_xml2_config_path" 1>&6 echo $ac_n "checking whether libxml build works""... $ac_c" 1>&6 -echo "configure:95069: checking whether libxml build works" >&5 +echo "configure:94532: checking whether libxml build works" >&5 if eval "test \"`echo '$''{'php_cv_libxml_build_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -95081,7 +94544,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:94559: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -95659,7 +95122,7 @@ fi php_enable_xml=yes echo $ac_n "checking whether to enable XML support""... $ac_c" 1>&6 -echo "configure:95663: checking whether to enable XML support" >&5 +echo "configure:95126: checking whether to enable XML support" >&5 # Check whether --enable-xml or --disable-xml was given. if test "${enable_xml+set}" = set; then enableval="$enable_xml" @@ -95707,7 +95170,7 @@ if test -z "$PHP_LIBXML_DIR"; then php_with_libxml_dir=no echo $ac_n "checking libxml2 install dir""... $ac_c" 1>&6 -echo "configure:95711: checking libxml2 install dir" >&5 +echo "configure:95174: checking libxml2 install dir" >&5 # Check whether --with-libxml-dir or --without-libxml-dir was given. if test "${with_libxml_dir+set}" = set; then withval="$with_libxml_dir" @@ -95734,7 +95197,7 @@ fi php_with_libexpat_dir=no echo $ac_n "checking libexpat install dir""... $ac_c" 1>&6 -echo "configure:95738: checking libexpat install dir" >&5 +echo "configure:95201: checking libexpat install dir" >&5 # Check whether --with-libexpat-dir or --without-libexpat-dir was given. if test "${with_libexpat_dir+set}" = set; then withval="$with_libexpat_dir" @@ -95766,7 +95229,7 @@ if test "$PHP_XML" != "no"; then echo $ac_n "checking for xml2-config path""... $ac_c" 1>&6 -echo "configure:95770: checking for xml2-config path" >&5 +echo "configure:95233: checking for xml2-config path" >&5 if eval "test \"`echo '$''{'ac_cv_php_xml2_config_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -95924,7 +95387,7 @@ echo "$ac_t""$ac_cv_php_xml2_config_path" 1>&6 echo $ac_n "checking whether libxml build works""... $ac_c" 1>&6 -echo "configure:95928: checking whether libxml build works" >&5 +echo "configure:95391: checking whether libxml build works" >&5 if eval "test \"`echo '$''{'php_cv_libxml_build_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -95940,7 +95403,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:95418: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -96487,7 +95950,7 @@ fi php_enable_xmlreader=yes echo $ac_n "checking whether to enable XMLReader support""... $ac_c" 1>&6 -echo "configure:96491: checking whether to enable XMLReader support" >&5 +echo "configure:95954: checking whether to enable XMLReader support" >&5 # Check whether --enable-xmlreader or --disable-xmlreader was given. if test "${enable_xmlreader+set}" = set; then enableval="$enable_xmlreader" @@ -96535,7 +95998,7 @@ if test -z "$PHP_LIBXML_DIR"; then php_with_libxml_dir=no echo $ac_n "checking libxml2 install dir""... $ac_c" 1>&6 -echo "configure:96539: checking libxml2 install dir" >&5 +echo "configure:96002: checking libxml2 install dir" >&5 # Check whether --with-libxml-dir or --without-libxml-dir was given. if test "${with_libxml_dir+set}" = set; then withval="$with_libxml_dir" @@ -96566,7 +96029,7 @@ if test "$PHP_XMLREADER" != "no"; then echo $ac_n "checking for xml2-config path""... $ac_c" 1>&6 -echo "configure:96570: checking for xml2-config path" >&5 +echo "configure:96033: checking for xml2-config path" >&5 if eval "test \"`echo '$''{'ac_cv_php_xml2_config_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -96724,7 +96187,7 @@ echo "$ac_t""$ac_cv_php_xml2_config_path" 1>&6 echo $ac_n "checking whether libxml build works""... $ac_c" 1>&6 -echo "configure:96728: checking whether libxml build works" >&5 +echo "configure:96191: checking whether libxml build works" >&5 if eval "test \"`echo '$''{'php_cv_libxml_build_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -96740,7 +96203,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:96218: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -97133,7 +96596,7 @@ fi php_with_xmlrpc=no echo $ac_n "checking for XMLRPC-EPI support""... $ac_c" 1>&6 -echo "configure:97137: checking for XMLRPC-EPI support" >&5 +echo "configure:96600: checking for XMLRPC-EPI support" >&5 # Check whether --with-xmlrpc or --without-xmlrpc was given. if test "${with_xmlrpc+set}" = set; then withval="$with_xmlrpc" @@ -97181,7 +96644,7 @@ if test -z "$PHP_LIBXML_DIR"; then php_with_libxml_dir=no echo $ac_n "checking libxml2 install dir""... $ac_c" 1>&6 -echo "configure:97185: checking libxml2 install dir" >&5 +echo "configure:96648: checking libxml2 install dir" >&5 # Check whether --with-libxml-dir or --without-libxml-dir was given. if test "${with_libxml_dir+set}" = set; then withval="$with_libxml_dir" @@ -97208,7 +96671,7 @@ fi php_with_libexpat_dir=no echo $ac_n "checking libexpat dir for XMLRPC-EPI""... $ac_c" 1>&6 -echo "configure:97212: checking libexpat dir for XMLRPC-EPI" >&5 +echo "configure:96675: checking libexpat dir for XMLRPC-EPI" >&5 # Check whether --with-libexpat-dir or --without-libexpat-dir was given. if test "${with_libexpat_dir+set}" = set; then withval="$with_libexpat_dir" @@ -97234,7 +96697,7 @@ echo "$ac_t""$ext_output" 1>&6 php_with_iconv_dir=no echo $ac_n "checking iconv dir for XMLRPC-EPI""... $ac_c" 1>&6 -echo "configure:97238: checking iconv dir for XMLRPC-EPI" >&5 +echo "configure:96701: checking iconv dir for XMLRPC-EPI" >&5 # Check whether --with-iconv-dir or --without-iconv-dir was given. if test "${with_iconv_dir+set}" = set; then withval="$with_iconv_dir" @@ -97293,7 +96756,7 @@ EOF echo $ac_n "checking for xml2-config path""... $ac_c" 1>&6 -echo "configure:97297: checking for xml2-config path" >&5 +echo "configure:96760: checking for xml2-config path" >&5 if eval "test \"`echo '$''{'ac_cv_php_xml2_config_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -97451,7 +96914,7 @@ echo "$ac_t""$ac_cv_php_xml2_config_path" 1>&6 echo $ac_n "checking whether libxml build works""... $ac_c" 1>&6 -echo "configure:97455: checking whether libxml build works" >&5 +echo "configure:96918: checking whether libxml build works" >&5 if eval "test \"`echo '$''{'php_cv_libxml_build_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -97467,7 +96930,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:96945: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -97746,12 +97209,12 @@ EOF if test "$PHP_ICONV" = "yes"; then echo $ac_n "checking for iconv""... $ac_c" 1>&6 -echo "configure:97750: checking for iconv" >&5 +echo "configure:97213: checking for iconv" >&5 if eval "test \"`echo '$''{'ac_cv_func_iconv'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:97241: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_iconv=yes" else @@ -97795,12 +97258,12 @@ else echo "$ac_t""no" 1>&6 echo $ac_n "checking for libiconv""... $ac_c" 1>&6 -echo "configure:97799: checking for libiconv" >&5 +echo "configure:97262: checking for libiconv" >&5 if eval "test \"`echo '$''{'ac_cv_func_libiconv'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:97290: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_libiconv=yes" else @@ -97979,7 +97442,7 @@ EOF done echo $ac_n "checking for libiconv in -l$iconv_lib_name""... $ac_c" 1>&6 -echo "configure:97983: checking for libiconv in -l$iconv_lib_name" >&5 +echo "configure:97446: checking for libiconv in -l$iconv_lib_name" >&5 ac_lib_var=`echo $iconv_lib_name'_'libiconv | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -97987,7 +97450,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$iconv_lib_name $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:97465: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -98132,7 +97595,7 @@ else done echo $ac_n "checking for iconv in -l$iconv_lib_name""... $ac_c" 1>&6 -echo "configure:98136: checking for iconv in -l$iconv_lib_name" >&5 +echo "configure:97599: checking for iconv in -l$iconv_lib_name" >&5 ac_lib_var=`echo $iconv_lib_name'_'iconv | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -98140,7 +97603,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$iconv_lib_name $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:97618: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -98341,7 +97804,7 @@ if test "$PHP_XMLRPC" = "yes"; then # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:98345: checking for $ac_word" >&5 +echo "configure:97808: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -98369,21 +97832,21 @@ else fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:98373: checking for inline" >&5 +echo "configure:97836: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:97850: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -98421,12 +97884,12 @@ EOF echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:98425: checking for ANSI C header files" >&5 +echo "configure:97888: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -98434,7 +97897,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:98438: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:97901: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -98451,7 +97914,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -98469,7 +97932,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -98490,7 +97953,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -98501,7 +97964,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:98505: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:97968: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -98528,17 +97991,17 @@ for ac_hdr in xmlparse.h xmltok.h stdlib.h strings.h string.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:98532: checking for $ac_hdr" >&5 +echo "configure:97995: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:98542: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:98005: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -98570,7 +98033,7 @@ done echo $ac_n "checking size of char""... $ac_c" 1>&6 -echo "configure:98574: checking size of char" >&5 +echo "configure:98037: checking size of char" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_char'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -98578,7 +98041,7 @@ else ac_cv_sizeof_char=1 else cat > conftest.$ac_ext < int main() @@ -98589,7 +98052,7 @@ int main() return(0); } EOF -if { (eval echo configure:98593: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:98056: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_char=`cat conftestval` else @@ -98610,7 +98073,7 @@ EOF echo $ac_n "checking size of int""... $ac_c" 1>&6 -echo "configure:98614: checking size of int" >&5 +echo "configure:98077: checking size of int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -98618,7 +98081,7 @@ else ac_cv_sizeof_int=4 else cat > conftest.$ac_ext < int main() @@ -98629,7 +98092,7 @@ int main() return(0); } EOF -if { (eval echo configure:98633: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:98096: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_int=`cat conftestval` else @@ -98649,7 +98112,7 @@ EOF echo $ac_n "checking size of long""... $ac_c" 1>&6 -echo "configure:98653: checking size of long" >&5 +echo "configure:98116: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -98657,7 +98120,7 @@ else ac_cv_sizeof_long=4 else cat > conftest.$ac_ext < int main() @@ -98668,7 +98131,7 @@ int main() return(0); } EOF -if { (eval echo configure:98672: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:98135: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -98688,7 +98151,7 @@ EOF echo $ac_n "checking size of long long""... $ac_c" 1>&6 -echo "configure:98692: checking size of long long" >&5 +echo "configure:98155: checking size of long long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -98696,7 +98159,7 @@ else ac_cv_sizeof_long_long=8 else cat > conftest.$ac_ext < int main() @@ -98707,7 +98170,7 @@ int main() return(0); } EOF -if { (eval echo configure:98711: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:98174: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long_long=`cat conftestval` else @@ -98727,12 +98190,12 @@ EOF echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:98731: checking for size_t" >&5 +echo "configure:98194: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -98760,12 +98223,12 @@ EOF fi echo $ac_n "checking whether time.h and sys/time.h may both be included""... $ac_c" 1>&6 -echo "configure:98764: checking whether time.h and sys/time.h may both be included" >&5 +echo "configure:98227: checking whether time.h and sys/time.h may both be included" >&5 if eval "test \"`echo '$''{'ac_cv_header_time'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -98774,7 +98237,7 @@ int main() { struct tm *tp; ; return 0; } EOF -if { (eval echo configure:98778: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:98241: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_header_time=yes else @@ -98795,12 +98258,12 @@ EOF fi echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 -echo "configure:98799: checking for uid_t in sys/types.h" >&5 +echo "configure:98262: checking for uid_t in sys/types.h" >&5 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF @@ -98840,12 +98303,12 @@ for ac_func in \ memcpy memmove do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:98844: checking for $ac_func" >&5 +echo "configure:98307: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:98335: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -99222,7 +98685,7 @@ elif test "$PHP_XMLRPC" != "no"; then XMLRPC_DIR=$PHP_XMLRPC/include/xmlrpc-epi else echo $ac_n "checking for XMLRPC-EPI in default path""... $ac_c" 1>&6 -echo "configure:99226: checking for XMLRPC-EPI in default path" >&5 +echo "configure:98689: checking for XMLRPC-EPI in default path" >&5 for i in /usr/local /usr; do if test -r $i/include/xmlrpc.h; then XMLRPC_DIR=$i/include @@ -99665,7 +99128,7 @@ fi php_enable_xmlwriter=yes echo $ac_n "checking whether to enable XMLWriter support""... $ac_c" 1>&6 -echo "configure:99669: checking whether to enable XMLWriter support" >&5 +echo "configure:99132: checking whether to enable XMLWriter support" >&5 # Check whether --enable-xmlwriter or --disable-xmlwriter was given. if test "${enable_xmlwriter+set}" = set; then enableval="$enable_xmlwriter" @@ -99713,7 +99176,7 @@ if test -z "$PHP_LIBXML_DIR"; then php_with_libxml_dir=no echo $ac_n "checking libxml2 install dir""... $ac_c" 1>&6 -echo "configure:99717: checking libxml2 install dir" >&5 +echo "configure:99180: checking libxml2 install dir" >&5 # Check whether --with-libxml-dir or --without-libxml-dir was given. if test "${with_libxml_dir+set}" = set; then withval="$with_libxml_dir" @@ -99744,7 +99207,7 @@ if test "$PHP_XMLWRITER" != "no"; then echo $ac_n "checking for xml2-config path""... $ac_c" 1>&6 -echo "configure:99748: checking for xml2-config path" >&5 +echo "configure:99211: checking for xml2-config path" >&5 if eval "test \"`echo '$''{'ac_cv_php_xml2_config_path'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -99902,7 +99365,7 @@ echo "$ac_t""$ac_cv_php_xml2_config_path" 1>&6 echo $ac_n "checking whether libxml build works""... $ac_c" 1>&6 -echo "configure:99906: checking whether libxml build works" >&5 +echo "configure:99369: checking whether libxml build works" >&5 if eval "test \"`echo '$''{'php_cv_libxml_build_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -99918,7 +99381,7 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:99396: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBS=$old_LIBS @@ -100279,7 +99742,7 @@ fi php_with_xsl=no echo $ac_n "checking for XSL support""... $ac_c" 1>&6 -echo "configure:100283: checking for XSL support" >&5 +echo "configure:99746: checking for XSL support" >&5 # Check whether --with-xsl or --without-xsl was given. if test "${with_xsl+set}" = set; then withval="$with_xsl" @@ -100482,7 +99945,7 @@ if test "$PHP_XSL" != "no"; then echo $ac_n "checking for EXSLT support""... $ac_c" 1>&6 -echo "configure:100486: checking for EXSLT support" >&5 +echo "configure:99949: checking for EXSLT support" >&5 for i in $PHP_XSL /usr/local /usr; do if test -r "$i/include/libexslt/exslt.h"; then PHP_XSL_EXSL_DIR=$i @@ -100958,7 +100421,7 @@ fi php_enable_zip=no echo $ac_n "checking for zip archive read/writesupport""... $ac_c" 1>&6 -echo "configure:100962: checking for zip archive read/writesupport" >&5 +echo "configure:100425: checking for zip archive read/writesupport" >&5 # Check whether --enable-zip or --disable-zip was given. if test "${enable_zip+set}" = set; then enableval="$enable_zip" @@ -101006,7 +100469,7 @@ if test -z "$PHP_ZLIB_DIR"; then php_with_zlib_dir=no echo $ac_n "checking for the location of libz""... $ac_c" 1>&6 -echo "configure:101010: checking for the location of libz" >&5 +echo "configure:100473: checking for the location of libz" >&5 # Check whether --with-zlib-dir or --without-zlib-dir was given. if test "${with_zlib_dir+set}" = set; then withval="$with_zlib_dir" @@ -101033,7 +100496,7 @@ fi php_with_pcre_dir=no echo $ac_n "checking pcre install prefix""... $ac_c" 1>&6 -echo "configure:101037: checking pcre install prefix" >&5 +echo "configure:100500: checking pcre install prefix" >&5 # Check whether --with-pcre-dir or --without-pcre-dir was given. if test "${with_pcre_dir+set}" = set; then withval="$with_pcre_dir" @@ -101080,7 +100543,7 @@ if test "$PHP_ZIP" != "no"; then fi echo $ac_n "checking for the location of zlib""... $ac_c" 1>&6 -echo "configure:101084: checking for the location of zlib" >&5 +echo "configure:100547: checking for the location of zlib" >&5 if test "$PHP_ZLIB_DIR" = "no"; then { echo "configure: error: zip support requires ZLIB. Use --with-zlib-dir= to specify prefix where ZLIB include and library are located" 1>&2; exit 1; } else @@ -101218,7 +100681,7 @@ echo "configure:101084: checking for the location of zlib" >&5 old_CPPFLAGS=$CPPFLAGS CPPFLAGS=$INCLUDES cat > conftest.$ac_ext < @@ -101237,7 +100700,7 @@ else rm -rf conftest* cat > conftest.$ac_ext < @@ -101601,11 +101064,10 @@ fi - php_enable_mysqlnd_threading=no echo $ac_n "checking whether to enable threaded fetch in mysqlnd""... $ac_c" 1>&6 -echo "configure:101609: checking whether to enable threaded fetch in mysqlnd" >&5 +echo "configure:101071: checking whether to enable threaded fetch in mysqlnd" >&5 # Check whether --enable-mysqlnd_threading or --disable-mysqlnd_threading was given. if test "${enable_mysqlnd_threading+set}" = set; then enableval="$enable_mysqlnd_threading" @@ -101931,42 +101393,6 @@ EOF $php_shtool mkdir -p ext/mysqlnd - - - for header_file in ext/mysqlnd; do - - - unique=`echo $header_file|$SED 's/[^a-zA-Z0-9]/_/g'` - - cmd="echo $ac_n \"\$INSTALLHEADERS$unique$ac_c\"" - if test -n "$unique" && test "`eval $cmd`" = "" ; then - eval "INSTALLHEADERS$unique=set" - - INSTALL_HEADERS="$INSTALL_HEADERS $header_file" - - fi - - done - - - - - for header_file in $ext_builddir/php_mysqlnd_config.h; do - - - unique=`echo $header_file|$SED 's/[^a-zA-Z0-9]/_/g'` - - cmd="echo $ac_n \"\$INSTALLHEADERS$unique$ac_c\"" - if test -n "$unique" && test "`eval $cmd`" = "" ; then - eval "INSTALLHEADERS$unique=set" - - INSTALL_HEADERS="$INSTALL_HEADERS $header_file" - - fi - - done - - if test "$PHP_MYSQLND_THREADING" = "yes"; then @@ -101980,11 +101406,19 @@ EOF EOF fi +fi + +if test "$PHP_MYSQLND_ENABLED" = "yes" || test "$PHP_MYSQLI" != "no"; then + + + $php_shtool mkdir -p ext/mysqlnd + + for php_typename in int8 uint8 int16 uint16 int32 uint32 uchar ulong int8_t uint8_t int16_t uint16_t int32_t uint32_t int64_t uint64_t; do echo $ac_n "checking whether $php_typename exists""... $ac_c" 1>&6 -echo "configure:101988: checking whether $php_typename exists" >&5 +echo "configure:101422: checking whether $php_typename exists" >&5 php_cache_value=php_cv_sizeof_$php_typename if eval "test \"`echo '$''{'php_cv_sizeof_$php_typename'+set}'`\" = set"; then @@ -102001,7 +101435,7 @@ else else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -102031,7 +101465,7 @@ int main() } EOF -if { (eval echo configure:102035: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:101469: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then eval $php_cache_value=`cat conftestval` @@ -102056,7 +101490,7 @@ fi php_def_have_what=HAVE_`echo $php_typename | tr 'abcdefghijklmnopqrstuvwxyz-' 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_' ` - echo "#define $php_def_have_what 1" >> $ext_builddir/php_mysqlnd_config.h + echo "#define $php_def_have_what 1" >> ext/mysqlnd/php_mysqlnd_config.h echo "$ac_t""yes" 1>&6 @@ -102171,7 +101605,7 @@ if test "$PHP_RECODE" != "no"; then done echo $ac_n "checking for hash_insert in -l$MYSQL_LIBNAME""... $ac_c" 1>&6 -echo "configure:102175: checking for hash_insert in -l$MYSQL_LIBNAME" >&5 +echo "configure:101609: checking for hash_insert in -l$MYSQL_LIBNAME" >&5 ac_lib_var=`echo $MYSQL_LIBNAME'_'hash_insert | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -102179,7 +101613,7 @@ else ac_save_LIBS="$LIBS" LIBS="-l$MYSQL_LIBNAME $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:101628: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -102292,7 +101726,7 @@ fi php_with_pear=DEFAULT echo $ac_n "checking whether to install PEAR""... $ac_c" 1>&6 -echo "configure:102296: checking whether to install PEAR" >&5 +echo "configure:101730: checking whether to install PEAR" >&5 # Check whether --with-pear or --without-pear was given. if test "${with_pear+set}" = set; then withval="$with_pear" @@ -102397,7 +101831,7 @@ fi bison_version=none if test "$YACC"; then echo $ac_n "checking for bison version""... $ac_c" 1>&6 -echo "configure:102401: checking for bison version" >&5 +echo "configure:101835: checking for bison version" >&5 if eval "test \"`echo '$''{'php_cv_bison_version'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -102453,17 +101887,17 @@ dlfcn.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:102457: checking for $ac_hdr" >&5 +echo "configure:101891: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:102467: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:101901: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -102490,62 +101924,13 @@ fi done -case $host_alias in -*darwin[89]*) - ;; -*) - for ac_hdr in \ -mach-o/dyld.h - -do -ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` -echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:102504: checking for $ac_hdr" >&5 -if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then - echo $ac_n "(cached) $ac_c" 1>&6 -else - cat > conftest.$ac_ext < -EOF -ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:102514: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } -ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` -if test -z "$ac_err"; then - rm -rf conftest* - eval "ac_cv_header_$ac_safe=yes" -else - echo "$ac_err" >&5 - echo "configure: failed program was:" >&5 - cat conftest.$ac_ext >&5 - rm -rf conftest* - eval "ac_cv_header_$ac_safe=no" -fi -rm -f conftest* -fi -if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then - echo "$ac_t""yes" 1>&6 - ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'` - cat >> confdefs.h <&6 -fi -done - - ;; -esac - echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:102544: checking for size_t" >&5 +echo "configure:101929: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -102573,12 +101958,12 @@ EOF fi echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 -echo "configure:102577: checking return type of signal handlers" >&5 +echo "configure:101962: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -102595,7 +101980,7 @@ int main() { int i; ; return 0; } EOF -if { (eval echo configure:102599: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:101984: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else @@ -102619,12 +102004,12 @@ EOF echo $ac_n "checking for uint""... $ac_c" 1>&6 -echo "configure:102623: checking for uint" >&5 +echo "configure:102008: checking for uint" >&5 if eval "test \"`echo '$''{'ac_cv_type_uint'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -102652,12 +102037,12 @@ EOF fi echo $ac_n "checking for ulong""... $ac_c" 1>&6 -echo "configure:102656: checking for ulong" >&5 +echo "configure:102041: checking for ulong" >&5 if eval "test \"`echo '$''{'ac_cv_type_ulong'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -102687,9 +102072,9 @@ fi echo $ac_n "checking for int32_t""... $ac_c" 1>&6 -echo "configure:102691: checking for int32_t" >&5 +echo "configure:102076: checking for int32_t" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:102097: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <&6 -echo "configure:102731: checking for uint32_t" >&5 +echo "configure:102116: checking for uint32_t" >&5 cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:102137: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* cat >> confdefs.h <&6 -echo "configure:102771: checking for vprintf" >&5 +echo "configure:102156: checking for vprintf" >&5 if eval "test \"`echo '$''{'ac_cv_func_vprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:102184: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vprintf=yes" else @@ -102819,12 +102204,12 @@ fi if test "$ac_cv_func_vprintf" != yes; then echo $ac_n "checking for _doprnt""... $ac_c" 1>&6 -echo "configure:102823: checking for _doprnt" >&5 +echo "configure:102208: checking for _doprnt" >&5 if eval "test \"`echo '$''{'ac_cv_func__doprnt'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:102236: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func__doprnt=yes" else @@ -102872,7 +102257,7 @@ fi fi echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 -echo "configure:102876: checking for 8-bit clean memcmp" >&5 +echo "configure:102261: checking for 8-bit clean memcmp" >&5 if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -102880,7 +102265,7 @@ else ac_cv_func_memcmp_clean=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:102279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_memcmp_clean=yes else @@ -102910,19 +102295,19 @@ test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}" # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:102914: checking for working alloca.h" >&5 +echo "configure:102299: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:102926: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:102311: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -102943,12 +102328,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:102947: checking for alloca" >&5 +echo "configure:102332: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:102365: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -103008,12 +102393,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:103012: checking whether alloca needs Cray hooks" >&5 +echo "configure:102397: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:103042: checking for $ac_func" >&5 +echo "configure:102427: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:102455: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -103093,7 +102478,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:103097: checking stack direction for C alloca" >&5 +echo "configure:102482: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -103101,7 +102486,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:102509: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -103144,12 +102529,12 @@ fi for ac_func in memcpy strdup getpid kill strtod strtol finite fpclass sigsetjmp do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:103148: checking for $ac_func" >&5 +echo "configure:102533: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:102561: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -103198,7 +102583,7 @@ done echo $ac_n "checking whether sprintf is broken""... $ac_c" 1>&6 -echo "configure:103202: checking whether sprintf is broken" >&5 +echo "configure:102587: checking whether sprintf is broken" >&5 if eval "test \"`echo '$''{'ac_cv_broken_sprintf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -103209,11 +102594,11 @@ else else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:102602: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_broken_sprintf=no @@ -103247,12 +102632,12 @@ EOF for ac_func in finite isfinite isinf isnan do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:103251: checking for $ac_func" >&5 +echo "configure:102636: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:102664: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -103302,13 +102687,13 @@ done echo $ac_n "checking whether fp_except is defined""... $ac_c" 1>&6 -echo "configure:103306: checking whether fp_except is defined" >&5 +echo "configure:102691: checking whether fp_except is defined" >&5 if eval "test \"`echo '$''{'ac_cv_type_fp_except'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -103319,7 +102704,7 @@ fp_except x = (fp_except) 0; ; return 0; } EOF -if { (eval echo configure:103323: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:102708: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_fp_except=yes @@ -103346,9 +102731,9 @@ EOF echo $ac_n "checking for usable _FPU_SETCW""... $ac_c" 1>&6 -echo "configure:103350: checking for usable _FPU_SETCW" >&5 +echo "configure:102735: checking for usable _FPU_SETCW" >&5 cat > conftest.$ac_ext < @@ -103368,7 +102753,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:103372: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:102757: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cfp_have__fpu_setcw=yes else @@ -103389,9 +102774,9 @@ EOF fi echo $ac_n "checking for usable fpsetprec""... $ac_c" 1>&6 -echo "configure:103393: checking for usable fpsetprec" >&5 +echo "configure:102778: checking for usable fpsetprec" >&5 cat > conftest.$ac_ext < @@ -103410,7 +102795,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:103414: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:102799: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cfp_have_fpsetprec=yes else @@ -103431,9 +102816,9 @@ EOF fi echo $ac_n "checking for usable _controlfp""... $ac_c" 1>&6 -echo "configure:103435: checking for usable _controlfp" >&5 +echo "configure:102820: checking for usable _controlfp" >&5 cat > conftest.$ac_ext < @@ -103452,7 +102837,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:103456: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:102841: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cfp_have__controlfp=yes else @@ -103473,9 +102858,9 @@ EOF fi echo $ac_n "checking for usable _controlfp_s""... $ac_c" 1>&6 -echo "configure:103477: checking for usable _controlfp_s" >&5 +echo "configure:102862: checking for usable _controlfp_s" >&5 cat > conftest.$ac_ext < @@ -103495,7 +102880,7 @@ int main() { ; return 0; } EOF -if { (eval echo configure:103499: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:102884: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cfp_have__controlfp_s=yes else @@ -103516,9 +102901,9 @@ EOF fi echo $ac_n "checking whether FPU control word can be manipulated by inline assembler""... $ac_c" 1>&6 -echo "configure:103520: checking whether FPU control word can be manipulated by inline assembler" >&5 +echo "configure:102905: checking whether FPU control word can be manipulated by inline assembler" >&5 cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:102929: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cfp_have_fpu_inline_asm_x86=yes else @@ -103562,7 +102947,7 @@ EOF echo $ac_n "checking whether double cast to long preserves least significant bits""... $ac_c" 1>&6 -echo "configure:103566: checking whether double cast to long preserves least significant bits" >&5 +echo "configure:102951: checking whether double cast to long preserves least significant bits" >&5 if test "$cross_compiling" = yes; then @@ -103570,7 +102955,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -103594,7 +102979,7 @@ int main() } EOF -if { (eval echo configure:103598: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:102983: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then cat >> confdefs.h <<\EOF @@ -103620,17 +103005,17 @@ for ac_hdr in dlfcn.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:103624: checking for $ac_hdr" >&5 +echo "configure:103009: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:103634: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:103019: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -103658,14 +103043,14 @@ done echo $ac_n "checking whether dlsym() requires a leading underscore in symbol names""... $ac_c" 1>&6 -echo "configure:103662: checking whether dlsym() requires a leading underscore in symbol names" >&5 +echo "configure:103047: checking whether dlsym() requires a leading underscore in symbol names" >&5 if test "$cross_compiling" = yes; then : else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then + if { (eval echo configure:103115: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -103809,23 +103194,23 @@ fi echo $ac_n "checking virtual machine dispatch method""... $ac_c" 1>&6 -echo "configure:103813: checking virtual machine dispatch method" >&5 +echo "configure:103198: checking virtual machine dispatch method" >&5 echo "$ac_t""$PHP_ZEND_VM" 1>&6 echo $ac_n "checking whether to enable thread-safety""... $ac_c" 1>&6 -echo "configure:103817: checking whether to enable thread-safety" >&5 +echo "configure:103202: checking whether to enable thread-safety" >&5 echo "$ac_t""$ZEND_MAINTAINER_ZTS" 1>&6 echo $ac_n "checking whether to enable inline optimization for GCC""... $ac_c" 1>&6 -echo "configure:103821: checking whether to enable inline optimization for GCC" >&5 +echo "configure:103206: checking whether to enable inline optimization for GCC" >&5 echo "$ac_t""$ZEND_INLINE_OPTIMIZATION" 1>&6 echo $ac_n "checking whether to enable Zend debugging""... $ac_c" 1>&6 -echo "configure:103825: checking whether to enable Zend debugging" >&5 +echo "configure:103210: checking whether to enable Zend debugging" >&5 echo "$ac_t""$ZEND_DEBUG" 1>&6 echo $ac_n "checking whether to enable Zend multibyte""... $ac_c" 1>&6 -echo "configure:103829: checking whether to enable Zend multibyte" >&5 +echo "configure:103214: checking whether to enable Zend multibyte" >&5 echo "$ac_t""$ZEND_MULTIBYTE" 1>&6 case $PHP_ZEND_VM in @@ -103898,21 +103283,21 @@ fi echo $ac_n "checking for inline""... $ac_c" 1>&6 -echo "configure:103902: checking for inline" >&5 +echo "configure:103287: checking for inline" >&5 if eval "test \"`echo '$''{'ac_cv_c_inline'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_cv_c_inline=no for ac_kw in inline __inline__ __inline; do cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:103301: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_c_inline=$ac_kw; break else @@ -103941,7 +103326,7 @@ esac echo $ac_n "checking target system is Darwin""... $ac_c" 1>&6 -echo "configure:103945: checking target system is Darwin" >&5 +echo "configure:103330: checking target system is Darwin" >&5 if echo "$target" | grep "darwin" > /dev/null; then cat >> confdefs.h <<\EOF #define DARWIN 1 @@ -103953,7 +103338,7 @@ else fi echo $ac_n "checking for MM alignment and log values""... $ac_c" 1>&6 -echo "configure:103957: checking for MM alignment and log values" >&5 +echo "configure:103342: checking for MM alignment and log values" >&5 if test "$cross_compiling" = yes; then @@ -103961,7 +103346,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -103997,7 +103382,7 @@ int main() } EOF -if { (eval echo configure:104001: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:103386: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then LIBZEND_MM_ALIGN=`cat conftest.zend | cut -d ' ' -f 1` @@ -104022,7 +103407,7 @@ fi echo "$ac_t""done" 1>&6 echo $ac_n "checking for memory allocation using mmap(MAP_ANON)""... $ac_c" 1>&6 -echo "configure:104026: checking for memory allocation using mmap(MAP_ANON)" >&5 +echo "configure:103411: checking for memory allocation using mmap(MAP_ANON)" >&5 if test "$cross_compiling" = yes; then @@ -104030,7 +103415,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -104066,7 +103451,7 @@ int main() } EOF -if { (eval echo configure:104070: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:103455: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then cat >> confdefs.h <<\EOF @@ -104088,7 +103473,7 @@ fi echo $ac_n "checking for memory allocation using mmap("/dev/zero")""... $ac_c" 1>&6 -echo "configure:104092: checking for memory allocation using mmap("/dev/zero")" >&5 +echo "configure:103477: checking for memory allocation using mmap("/dev/zero")" >&5 if test "$cross_compiling" = yes; then @@ -104096,7 +103481,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -104142,7 +103527,7 @@ int main() } EOF -if { (eval echo configure:104146: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:103531: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then cat >> confdefs.h <<\EOF @@ -104166,12 +103551,12 @@ fi for ac_func in mremap do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:104170: checking for $ac_func" >&5 +echo "configure:103555: checking for $ac_func" >&5 if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:103583: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_$ac_func=yes" else @@ -104261,17 +103646,17 @@ for ac_hdr in stdarg.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:104265: checking for $ac_hdr" >&5 +echo "configure:103650: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:104275: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:103660: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -104348,7 +103733,7 @@ if test "$TSRM_PTH" != "no"; then echo $ac_n "checking for GNU Pth""... $ac_c" 1>&6 -echo "configure:104352: checking for GNU Pth" >&5 +echo "configure:103737: checking for GNU Pth" >&5 PTH_PREFIX="`$TSRM_PTH --prefix`" if test -z "$PTH_PREFIX"; then echo "$ac_t""Please check your Pth installation" 1>&6 @@ -104378,17 +103763,17 @@ elif test "$TSRM_ST" != "no"; then do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:104382: checking for $ac_hdr" >&5 +echo "configure:103767: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:104392: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:103777: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -104418,7 +103803,7 @@ done LIBS="$LIBS -lst" echo $ac_n "checking for SGI's State Threads""... $ac_c" 1>&6 -echo "configure:104422: checking for SGI's State Threads" >&5 +echo "configure:103807: checking for SGI's State Threads" >&5 echo "$ac_t""yes" 1>&6 cat >> confdefs.h <<\EOF #define TSRM_ST 1 @@ -104457,7 +103842,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -104475,7 +103860,7 @@ int main() { return pthread_create(&thd, NULL, thread_routine, &data); } EOF -if { (eval echo configure:104479: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:103864: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then pthreads_working=yes @@ -104495,7 +103880,7 @@ fi CFLAGS=$save_CFLAGS echo $ac_n "checking for pthreads_cflags""... $ac_c" 1>&6 -echo "configure:104499: checking for pthreads_cflags" >&5 +echo "configure:103884: checking for pthreads_cflags" >&5 if eval "test \"`echo '$''{'ac_cv_pthreads_cflags'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -104517,7 +103902,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -104535,7 +103920,7 @@ int main() { return pthread_create(&thd, NULL, thread_routine, &data); } EOF -if { (eval echo configure:104539: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:103924: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then pthreads_working=yes @@ -104565,7 +103950,7 @@ fi echo "$ac_t""$ac_cv_pthreads_cflags" 1>&6 echo $ac_n "checking for pthreads_lib""... $ac_c" 1>&6 -echo "configure:104569: checking for pthreads_lib" >&5 +echo "configure:103954: checking for pthreads_lib" >&5 if eval "test \"`echo '$''{'ac_cv_pthreads_lib'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -104587,7 +103972,7 @@ if test "$cross_compiling" = yes; then else cat > conftest.$ac_ext < @@ -104605,7 +103990,7 @@ int main() { return pthread_create(&thd, NULL, thread_routine, &data); } EOF -if { (eval echo configure:104609: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:103994: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then pthreads_working=yes @@ -104656,7 +104041,7 @@ EOF echo $ac_n "checking for POSIX threads""... $ac_c" 1>&6 -echo "configure:104660: checking for POSIX threads" >&5 +echo "configure:104045: checking for POSIX threads" >&5 echo "$ac_t""yes" 1>&6 fi @@ -105275,7 +104660,7 @@ fi echo $ac_n "checking build system type""... $ac_c" 1>&6 -echo "configure:105279: checking build system type" >&5 +echo "configure:104664: checking build system type" >&5 build_alias=$build case "$build_alias" in @@ -105304,7 +104689,7 @@ ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. echo $ac_n "checking for ld used by $CC""... $ac_c" 1>&6 -echo "configure:105308: checking for ld used by $CC" >&5 +echo "configure:104693: checking for ld used by $CC" >&5 case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw @@ -105334,10 +104719,10 @@ echo "configure:105308: checking for ld used by $CC" >&5 esac elif test "$with_gnu_ld" = yes; then echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 -echo "configure:105338: checking for GNU ld" >&5 +echo "configure:104723: checking for GNU ld" >&5 else echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 -echo "configure:105341: checking for non-GNU ld" >&5 +echo "configure:104726: checking for non-GNU ld" >&5 fi if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -105376,7 +104761,7 @@ else fi test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 -echo "configure:105380: checking if the linker ($LD) is GNU ld" >&5 +echo "configure:104765: checking if the linker ($LD) is GNU ld" >&5 if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -105396,7 +104781,7 @@ with_gnu_ld=$lt_cv_prog_gnu_ld echo $ac_n "checking for $LD option to reload object files""... $ac_c" 1>&6 -echo "configure:105400: checking for $LD option to reload object files" >&5 +echo "configure:104785: checking for $LD option to reload object files" >&5 if eval "test \"`echo '$''{'lt_cv_ld_reload_flag'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -105421,7 +104806,7 @@ case $host_os in esac echo $ac_n "checking for BSD-compatible nm""... $ac_c" 1>&6 -echo "configure:105425: checking for BSD-compatible nm" >&5 +echo "configure:104810: checking for BSD-compatible nm" >&5 if eval "test \"`echo '$''{'lt_cv_path_NM'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -105467,7 +104852,7 @@ echo "$ac_t""$lt_cv_path_NM" 1>&6 NM="$lt_cv_path_NM" echo $ac_n "checking how to recognise dependent libraries""... $ac_c" 1>&6 -echo "configure:105471: checking how to recognise dependent libraries" >&5 +echo "configure:104856: checking how to recognise dependent libraries" >&5 if eval "test \"`echo '$''{'lt_cv_deplibs_check_method'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -105645,13 +105030,13 @@ deplibs_check_method=$lt_cv_deplibs_check_method test -z "$deplibs_check_method" && deplibs_check_method=unknown echo $ac_n "checking for object suffix""... $ac_c" 1>&6 -echo "configure:105649: checking for object suffix" >&5 +echo "configure:105034: checking for object suffix" >&5 if eval "test \"`echo '$''{'ac_cv_objext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else rm -f conftest* echo 'int i = 1;' > conftest.$ac_ext -if { (eval echo configure:105655: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:105040: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then for ac_file in conftest.*; do case $ac_file in *.c) ;; @@ -105671,7 +105056,7 @@ ac_objext=$ac_cv_objext echo $ac_n "checking for executable suffix""... $ac_c" 1>&6 -echo "configure:105675: checking for executable suffix" >&5 +echo "configure:105060: checking for executable suffix" >&5 if eval "test \"`echo '$''{'ac_cv_exeext'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -105681,7 +105066,7 @@ else rm -f conftest* echo 'int main () { return 0; }' > conftest.$ac_ext ac_cv_exeext= - if { (eval echo configure:105685: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then + if { (eval echo configure:105070: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; }; then for file in conftest.*; do case $file in *.c | *.o | *.obj) ;; @@ -105724,7 +105109,7 @@ case $host in ia64-*-hpux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext - if { (eval echo configure:105728: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + if { (eval echo configure:105113: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then case `/usr/bin/file conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE="32" @@ -105738,8 +105123,8 @@ ia64-*-hpux*) ;; *-*-irix6*) # Find out which ABI we are using. - echo '#line 105742 "configure"' > conftest.$ac_ext - if { (eval echo configure:105743: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + echo '#line 105127 "configure"' > conftest.$ac_ext + if { (eval echo configure:105128: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then if test "$lt_cv_prog_gnu_ld" = yes; then case `/usr/bin/file conftest.$ac_objext` in *32-bit*) @@ -105772,7 +105157,7 @@ ia64-*-hpux*) x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) # Find out which ABI we are using. echo 'int i;' > conftest.$ac_ext - if { (eval echo configure:105776: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + if { (eval echo configure:105161: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then case `/usr/bin/file conftest.o` in *32-bit*) case $host in @@ -105816,7 +105201,7 @@ x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*|s390*-*linux*|sparc*-*linux*) SAVE_CFLAGS="$CFLAGS" CFLAGS="$CFLAGS -belf" echo $ac_n "checking whether the C compiler needs -belf""... $ac_c" 1>&6 -echo "configure:105820: checking whether the C compiler needs -belf" >&5 +echo "configure:105205: checking whether the C compiler needs -belf" >&5 if eval "test \"`echo '$''{'lt_cv_cc_needs_belf'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -105829,14 +105214,14 @@ ac_link='${CC-cc} -o conftest${ac_exeext} $CFLAGS $CPPFLAGS $LDFLAGS conftest.$a cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:105225: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* lt_cv_cc_needs_belf=yes else @@ -105873,7 +105258,7 @@ if test -n "$CXX" && ( test "X$CXX" != "Xno" && ( (test "X$CXX" = "Xg++" && `g++ -v >/dev/null 2>&1` ) || (test "X$CXX" != "Xg++"))) ; then echo $ac_n "checking how to run the C++ preprocessor""... $ac_c" 1>&6 -echo "configure:105877: checking how to run the C++ preprocessor" >&5 +echo "configure:105262: checking how to run the C++ preprocessor" >&5 if test -z "$CXXCPP"; then if eval "test \"`echo '$''{'ac_cv_prog_CXXCPP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -105886,12 +105271,12 @@ ac_link='${CXX-g++} -o conftest${ac_exeext} $CXXFLAGS $CPPFLAGS $LDFLAGS conftes cross_compiling=$ac_cv_prog_cxx_cross CXXCPP="${CXX-g++} -E" cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:105895: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:105280: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -105922,7 +105307,7 @@ fi # find the maximum length of command line arguments echo $ac_n "checking the maximum length of command line arguments""... $ac_c" 1>&6 -echo "configure:105926: checking the maximum length of command line arguments" >&5 +echo "configure:105311: checking the maximum length of command line arguments" >&5 if eval "test \"`echo '$''{'lt_cv_sys_max_cmd_len'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106023,7 +105408,7 @@ fi # Check for command to grab the raw symbol name followed by C symbol from nm. echo $ac_n "checking command to parse $NM output from $compiler object""... $ac_c" 1>&6 -echo "configure:106027: checking command to parse $NM output from $compiler object" >&5 +echo "configure:105412: checking command to parse $NM output from $compiler object" >&5 if eval "test \"`echo '$''{'lt_cv_sys_global_symbol_pipe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106118,10 +105503,10 @@ void nm_test_func(){} int main(){nm_test_var='a';nm_test_func();return(0);} EOF - if { (eval echo configure:106122: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + if { (eval echo configure:105507: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then # Now try to grab the symbols. nlist=conftest.nm - if { (eval echo configure:106125: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5; } && test -s "$nlist"; then + if { (eval echo configure:105510: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\") 1>&5; (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5; } && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -106172,7 +105557,7 @@ EOF lt_save_CFLAGS="$CFLAGS" LIBS="conftstm.$ac_objext" CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" - if { (eval echo configure:106176: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then + if { (eval echo configure:105561: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then pipe_works=yes fi LIBS="$lt_save_LIBS" @@ -106212,7 +105597,7 @@ else fi echo $ac_n "checking for objdir""... $ac_c" 1>&6 -echo "configure:106216: checking for objdir" >&5 +echo "configure:105601: checking for objdir" >&5 if eval "test \"`echo '$''{'lt_cv_objdir'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106278,7 +105663,7 @@ with_gnu_ld="$lt_cv_prog_gnu_ld" # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. set dummy ${ac_tool_prefix}ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:106282: checking for $ac_word" >&5 +echo "configure:105667: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106310,7 +105695,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ar", so it can be a program name with args. set dummy ar; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:106314: checking for $ac_word" >&5 +echo "configure:105699: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106345,7 +105730,7 @@ fi # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. set dummy ${ac_tool_prefix}ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:106349: checking for $ac_word" >&5 +echo "configure:105734: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106377,7 +105762,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:106381: checking for $ac_word" >&5 +echo "configure:105766: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106412,7 +105797,7 @@ fi # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. set dummy ${ac_tool_prefix}strip; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:106416: checking for $ac_word" >&5 +echo "configure:105801: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106444,7 +105829,7 @@ if test -n "$ac_tool_prefix"; then # Extract the first word of "strip", so it can be a program name with args. set dummy strip; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:106448: checking for $ac_word" >&5 +echo "configure:105833: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_STRIP'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106530,7 +105915,7 @@ case $deplibs_check_method in file_magic*) if test "$file_magic_cmd" = '$MAGIC_CMD'; then echo $ac_n "checking for ${ac_tool_prefix}file""... $ac_c" 1>&6 -echo "configure:106534: checking for ${ac_tool_prefix}file" >&5 +echo "configure:105919: checking for ${ac_tool_prefix}file" >&5 if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106590,7 +105975,7 @@ fi if test -z "$lt_cv_path_MAGIC_CMD"; then if test -n "$ac_tool_prefix"; then echo $ac_n "checking for file""... $ac_c" 1>&6 -echo "configure:106594: checking for file" >&5 +echo "configure:105979: checking for file" >&5 if eval "test \"`echo '$''{'lt_cv_path_MAGIC_CMD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106749,7 +106134,7 @@ fi # Check to make sure the static flag actually works. # echo $ac_n "checking if $compiler static flag $lt_prog_compiler_static works""... $ac_c" 1>&6 -echo "configure:106753: checking if $compiler static flag $lt_prog_compiler_static works" >&5 +echo "configure:106138: checking if $compiler static flag $lt_prog_compiler_static works" >&5 if eval "test \"`echo '$''{'lt_prog_compiler_static_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106799,7 +106184,7 @@ if test "$GCC" = yes; then echo $ac_n "checking if $compiler supports -fno-rtti -fno-exceptions""... $ac_c" 1>&6 -echo "configure:106803: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 +echo "configure:106188: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 if eval "test \"`echo '$''{'lt_cv_prog_compiler_rtti_exceptions'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -106816,11 +106201,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"configure:106820: $lt_compile\"" >&5) + (eval echo "\"configure:106205: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "configure:106824: \$? = $ac_status" >&5 + echo "configure:106209: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -106849,7 +106234,7 @@ lt_prog_compiler_pic= lt_prog_compiler_static= echo $ac_n "checking for $compiler option to produce PIC""... $ac_c" 1>&6 -echo "configure:106853: checking for $compiler option to produce PIC" >&5 +echo "configure:106238: checking for $compiler option to produce PIC" >&5 if test "$GCC" = yes; then lt_prog_compiler_wl='-Wl,' @@ -107068,7 +106453,7 @@ echo "$ac_t""$lt_prog_compiler_pic" 1>&6 if test -n "$lt_prog_compiler_pic"; then echo $ac_n "checking if $compiler PIC flag $lt_prog_compiler_pic works""... $ac_c" 1>&6 -echo "configure:107072: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +echo "configure:106457: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 if eval "test \"`echo '$''{'lt_prog_compiler_pic_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -107085,11 +106470,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"configure:107089: $lt_compile\"" >&5) + (eval echo "\"configure:106474: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "configure:107093: \$? = $ac_status" >&5 + echo "configure:106478: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -107127,7 +106512,7 @@ case $host_os in esac echo $ac_n "checking if $compiler supports -c -o file.$ac_objext""... $ac_c" 1>&6 -echo "configure:107131: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo "configure:106516: checking if $compiler supports -c -o file.$ac_objext" >&5 if eval "test \"`echo '$''{'lt_cv_prog_compiler_c_o'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -107147,11 +106532,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"configure:107151: $lt_compile\"" >&5) + (eval echo "\"configure:106536: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "configure:107155: \$? = $ac_status" >&5 + echo "configure:106540: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -107181,7 +106566,7 @@ hard_links="nottested" if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user echo $ac_n "checking if we can lock with hard links""... $ac_c" 1>&6 -echo "configure:107185: checking if we can lock with hard links" >&5 +echo "configure:106570: checking if we can lock with hard links" >&5 hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no @@ -107198,7 +106583,7 @@ else fi echo $ac_n "checking whether the $compiler linker ($LD) supports shared libraries""... $ac_c" 1>&6 -echo "configure:107202: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo "configure:106587: checking whether the $compiler linker ($LD) supports shared libraries" >&5 runpath_var= allow_undefined_flag= @@ -107551,12 +106936,12 @@ EOF # Determine the default libpath from the value encoded in an empty executable. cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:106945: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -107582,12 +106967,12 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # Determine the default libpath from the value encoded in an empty executable. cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:106976: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -108059,11 +107444,11 @@ x|xyes) # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. echo $ac_n "checking whether -lc should be explicitly linked in""... $ac_c" 1>&6 -echo "configure:108063: checking whether -lc should be explicitly linked in" >&5 +echo "configure:107448: checking whether -lc should be explicitly linked in" >&5 $rm conftest* printf "$lt_simple_compile_test_code" > conftest.$ac_ext - if { (eval echo configure:108067: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } 2>conftest.err; then + if { (eval echo configure:107452: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext @@ -108076,7 +107461,7 @@ echo "configure:108063: checking whether -lc should be explicitly linked in" >&5 libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag allow_undefined_flag= - if { (eval echo configure:108080: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\") 1>&5; (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5; } + if { (eval echo configure:107465: \"$archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\") 1>&5; (eval $archive_cmds 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5; } then archive_cmds_need_lc=no else @@ -108095,7 +107480,7 @@ echo "configure:108063: checking whether -lc should be explicitly linked in" >&5 esac echo $ac_n "checking dynamic linker characteristics""... $ac_c" 1>&6 -echo "configure:108099: checking dynamic linker characteristics" >&5 +echo "configure:107484: checking dynamic linker characteristics" >&5 library_names_spec= libname_spec='lib$name' soname_spec= @@ -108469,8 +107854,8 @@ linux*) libsuff= case $host_cpu in x86_64*|s390x*|powerpc64*) - echo '#line 108473 "configure"' > conftest.$ac_ext - if { (eval echo configure:108474: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + echo '#line 107858 "configure"' > conftest.$ac_ext + if { (eval echo configure:107859: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then case `/usr/bin/file conftest.$ac_objext` in *64-bit*) libsuff=64 @@ -108669,7 +108054,7 @@ echo "$ac_t""$dynamic_linker" 1>&6 test "$dynamic_linker" = no && can_build_shared=no echo $ac_n "checking how to hardcode library paths into programs""... $ac_c" 1>&6 -echo "configure:108673: checking how to hardcode library paths into programs" >&5 +echo "configure:108058: checking how to hardcode library paths into programs" >&5 hardcode_action= if test -n "$hardcode_libdir_flag_spec" || \ test -n "$runpath_var" || \ @@ -108707,7 +108092,7 @@ fi striplib= old_striplib= echo $ac_n "checking whether stripping libraries is possible""... $ac_c" 1>&6 -echo "configure:108711: checking whether stripping libraries is possible" >&5 +echo "configure:108096: checking whether stripping libraries is possible" >&5 if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" @@ -108757,7 +108142,7 @@ else darwin*) # if libdl is installed we need to link against it echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:108761: checking for dlopen in -ldl" >&5 +echo "configure:108146: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -108765,7 +108150,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:108165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -108805,12 +108190,12 @@ fi *) echo $ac_n "checking for shl_load""... $ac_c" 1>&6 -echo "configure:108809: checking for shl_load" >&5 +echo "configure:108194: checking for shl_load" >&5 if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:108222: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_shl_load=yes" else @@ -108851,7 +108236,7 @@ if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 -echo "configure:108855: checking for shl_load in -ldld" >&5 +echo "configure:108240: checking for shl_load in -ldld" >&5 ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -108859,7 +108244,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldld $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:108259: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -108889,12 +108274,12 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dlopen""... $ac_c" 1>&6 -echo "configure:108893: checking for dlopen" >&5 +echo "configure:108278: checking for dlopen" >&5 if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:108306: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_dlopen=yes" else @@ -108935,7 +108320,7 @@ if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:108939: checking for dlopen in -ldl" >&5 +echo "configure:108324: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -108943,7 +108328,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:108343: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -108973,7 +108358,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dlopen in -lsvld""... $ac_c" 1>&6 -echo "configure:108977: checking for dlopen in -lsvld" >&5 +echo "configure:108362: checking for dlopen in -lsvld" >&5 ac_lib_var=`echo svld'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -108981,7 +108366,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsvld $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:108381: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -109011,7 +108396,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6 -echo "configure:109015: checking for dld_link in -ldld" >&5 +echo "configure:108400: checking for dld_link in -ldld" >&5 ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -109019,7 +108404,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldld $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:108419: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -109086,7 +108471,7 @@ fi LIBS="$lt_cv_dlopen_libs $LIBS" echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6 -echo "configure:109090: checking whether a program can dlopen itself" >&5 +echo "configure:108475: checking whether a program can dlopen itself" >&5 if eval "test \"`echo '$''{'lt_cv_dlopen_self'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -109096,7 +108481,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then + if { (eval echo configure:108546: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -109180,7 +108565,7 @@ echo "$ac_t""$lt_cv_dlopen_self" 1>&6 if test "x$lt_cv_dlopen_self" = xyes; then LDFLAGS="$LDFLAGS $link_static_flag" echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6 -echo "configure:109184: checking whether a statically linked program can dlopen itself" >&5 +echo "configure:108569: checking whether a statically linked program can dlopen itself" >&5 if eval "test \"`echo '$''{'lt_cv_dlopen_self_static'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -109190,7 +108575,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then + if { (eval echo configure:108640: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -109292,11 +108677,11 @@ fi # Report which librarie types wil actually be built echo $ac_n "checking if libtool supports shared libraries""... $ac_c" 1>&6 -echo "configure:109296: checking if libtool supports shared libraries" >&5 +echo "configure:108681: checking if libtool supports shared libraries" >&5 echo "$ac_t""$can_build_shared" 1>&6 echo $ac_n "checking whether to build shared libraries""... $ac_c" 1>&6 -echo "configure:109300: checking whether to build shared libraries" >&5 +echo "configure:108685: checking whether to build shared libraries" >&5 test "$can_build_shared" = "no" && enable_shared=no # On AIX, shared libraries and static libraries use the same namespace, and @@ -109319,7 +108704,7 @@ esac echo "$ac_t""$enable_shared" 1>&6 echo $ac_n "checking whether to build static libraries""... $ac_c" 1>&6 -echo "configure:109323: checking whether to build static libraries" >&5 +echo "configure:108708: checking whether to build static libraries" >&5 # Make sure either enable_shared or enable_static is yes. test "$enable_shared" = yes || enable_static=yes echo "$ac_t""$enable_static" 1>&6 @@ -109988,7 +109373,7 @@ ac_prog=ld if test "$GCC" = yes; then # Check if gcc -print-prog-name=ld gives a path. echo $ac_n "checking for ld used by $CC""... $ac_c" 1>&6 -echo "configure:109992: checking for ld used by $CC" >&5 +echo "configure:109377: checking for ld used by $CC" >&5 case $host in *-*-mingw*) # gcc leaves a trailing carriage return which upsets mingw @@ -110018,10 +109403,10 @@ echo "configure:109992: checking for ld used by $CC" >&5 esac elif test "$with_gnu_ld" = yes; then echo $ac_n "checking for GNU ld""... $ac_c" 1>&6 -echo "configure:110022: checking for GNU ld" >&5 +echo "configure:109407: checking for GNU ld" >&5 else echo $ac_n "checking for non-GNU ld""... $ac_c" 1>&6 -echo "configure:110025: checking for non-GNU ld" >&5 +echo "configure:109410: checking for non-GNU ld" >&5 fi if eval "test \"`echo '$''{'lt_cv_path_LD'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -110060,7 +109445,7 @@ else fi test -z "$LD" && { echo "configure: error: no acceptable ld found in \$PATH" 1>&2; exit 1; } echo $ac_n "checking if the linker ($LD) is GNU ld""... $ac_c" 1>&6 -echo "configure:110064: checking if the linker ($LD) is GNU ld" >&5 +echo "configure:109449: checking if the linker ($LD) is GNU ld" >&5 if eval "test \"`echo '$''{'lt_cv_prog_gnu_ld'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -110126,7 +109511,7 @@ fi # PORTME: fill in a description of your system's C++ link characteristics echo $ac_n "checking whether the $compiler linker ($LD) supports shared libraries""... $ac_c" 1>&6 -echo "configure:110130: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo "configure:109515: checking whether the $compiler linker ($LD) supports shared libraries" >&5 ld_shlibs_CXX=yes case $host_os in aix3*) @@ -110222,12 +109607,12 @@ case $host_os in # Determine the default libpath from the value encoded in an empty executable. cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:109616: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -110254,12 +109639,12 @@ if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi # Determine the default libpath from the value encoded in an empty executable. cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:109648: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0 *\(.*\)$/\1/; p; } }'` @@ -110966,7 +110351,7 @@ private: }; EOF -if { (eval echo configure:110970: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:110355: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then # Parse the compiler output and extract the necessary # objects, libraries and library flags. @@ -111076,7 +110461,7 @@ lt_prog_compiler_pic_CXX= lt_prog_compiler_static_CXX= echo $ac_n "checking for $compiler option to produce PIC""... $ac_c" 1>&6 -echo "configure:111080: checking for $compiler option to produce PIC" >&5 +echo "configure:110465: checking for $compiler option to produce PIC" >&5 # C++ specific cases for pic, static, wl, etc. if test "$GXX" = yes; then @@ -111357,7 +110742,7 @@ echo "$ac_t""$lt_prog_compiler_pic_CXX" 1>&6 if test -n "$lt_prog_compiler_pic_CXX"; then echo $ac_n "checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works""... $ac_c" 1>&6 -echo "configure:111361: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 +echo "configure:110746: checking if $compiler PIC flag $lt_prog_compiler_pic_CXX works" >&5 if eval "test \"`echo '$''{'lt_prog_compiler_pic_works_CXX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -111374,11 +110759,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"configure:111378: $lt_compile\"" >&5) + (eval echo "\"configure:110763: $lt_compile\"" >&5) (eval "$lt_compile" 2>conftest.err) ac_status=$? cat conftest.err >&5 - echo "configure:111382: \$? = $ac_status" >&5 + echo "configure:110767: \$? = $ac_status" >&5 if (exit $ac_status) && test -s "$ac_outfile"; then # The compiler can only warn and ignore the option if not recognized # So say no if there are warnings other than the usual output. @@ -111416,7 +110801,7 @@ case $host_os in esac echo $ac_n "checking if $compiler supports -c -o file.$ac_objext""... $ac_c" 1>&6 -echo "configure:111420: checking if $compiler supports -c -o file.$ac_objext" >&5 +echo "configure:110805: checking if $compiler supports -c -o file.$ac_objext" >&5 if eval "test \"`echo '$''{'lt_cv_prog_compiler_c_o_CXX'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -111436,11 +110821,11 @@ else -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ -e 's:$: $lt_compiler_flag:'` - (eval echo "\"configure:111440: $lt_compile\"" >&5) + (eval echo "\"configure:110825: $lt_compile\"" >&5) (eval "$lt_compile" 2>out/conftest.err) ac_status=$? cat out/conftest.err >&5 - echo "configure:111444: \$? = $ac_status" >&5 + echo "configure:110829: \$? = $ac_status" >&5 if (exit $ac_status) && test -s out/conftest2.$ac_objext then # The compiler can only warn and ignore the option if not recognized @@ -111470,7 +110855,7 @@ hard_links="nottested" if test "$lt_cv_prog_compiler_c_o_CXX" = no && test "$need_locks" != no; then # do not overwrite the value of need_locks provided by the user echo $ac_n "checking if we can lock with hard links""... $ac_c" 1>&6 -echo "configure:111474: checking if we can lock with hard links" >&5 +echo "configure:110859: checking if we can lock with hard links" >&5 hard_links=yes $rm conftest* ln conftest.a conftest.b 2>/dev/null && hard_links=no @@ -111487,7 +110872,7 @@ else fi echo $ac_n "checking whether the $compiler linker ($LD) supports shared libraries""... $ac_c" 1>&6 -echo "configure:111491: checking whether the $compiler linker ($LD) supports shared libraries" >&5 +echo "configure:110876: checking whether the $compiler linker ($LD) supports shared libraries" >&5 export_symbols_cmds_CXX='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' case $host_os in @@ -111537,11 +110922,11 @@ x|xyes) # systems, -lgcc has to come before -lc. If gcc already passes -lc # to ld, don't add -lc before -lgcc. echo $ac_n "checking whether -lc should be explicitly linked in""... $ac_c" 1>&6 -echo "configure:111541: checking whether -lc should be explicitly linked in" >&5 +echo "configure:110926: checking whether -lc should be explicitly linked in" >&5 $rm conftest* printf "$lt_simple_compile_test_code" > conftest.$ac_ext - if { (eval echo configure:111545: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } 2>conftest.err; then + if { (eval echo configure:110930: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; } 2>conftest.err; then soname=conftest lib=conftest libobjs=conftest.$ac_objext @@ -111554,7 +110939,7 @@ echo "configure:111541: checking whether -lc should be explicitly linked in" >&5 libname=conftest lt_save_allow_undefined_flag=$allow_undefined_flag_CXX allow_undefined_flag_CXX= - if { (eval echo configure:111558: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\") 1>&5; (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5; } + if { (eval echo configure:110943: \"$archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1\") 1>&5; (eval $archive_cmds_CXX 2\>\&1 \| grep \" -lc \" \>/dev/null 2\>\&1) 2>&5; } then archive_cmds_need_lc_CXX=no else @@ -111573,7 +110958,7 @@ echo "configure:111541: checking whether -lc should be explicitly linked in" >&5 esac echo $ac_n "checking dynamic linker characteristics""... $ac_c" 1>&6 -echo "configure:111577: checking dynamic linker characteristics" >&5 +echo "configure:110962: checking dynamic linker characteristics" >&5 library_names_spec= libname_spec='lib$name' soname_spec= @@ -111947,8 +111332,8 @@ linux*) libsuff= case $host_cpu in x86_64*|s390x*|powerpc64*) - echo '#line 111951 "configure"' > conftest.$ac_ext - if { (eval echo configure:111952: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then + echo '#line 111336 "configure"' > conftest.$ac_ext + if { (eval echo configure:111337: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then case `/usr/bin/file conftest.$ac_objext` in *64-bit*) libsuff=64 @@ -112147,7 +111532,7 @@ echo "$ac_t""$dynamic_linker" 1>&6 test "$dynamic_linker" = no && can_build_shared=no echo $ac_n "checking how to hardcode library paths into programs""... $ac_c" 1>&6 -echo "configure:112151: checking how to hardcode library paths into programs" >&5 +echo "configure:111536: checking how to hardcode library paths into programs" >&5 hardcode_action_CXX= if test -n "$hardcode_libdir_flag_spec_CXX" || \ test -n "$runpath_var_CXX" || \ @@ -112185,7 +111570,7 @@ fi striplib= old_striplib= echo $ac_n "checking whether stripping libraries is possible""... $ac_c" 1>&6 -echo "configure:112189: checking whether stripping libraries is possible" >&5 +echo "configure:111574: checking whether stripping libraries is possible" >&5 if test -n "$STRIP" && $STRIP -V 2>&1 | grep "GNU strip" >/dev/null; then test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" test -z "$striplib" && striplib="$STRIP --strip-unneeded" @@ -112235,7 +111620,7 @@ else darwin*) # if libdl is installed we need to link against it echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:112239: checking for dlopen in -ldl" >&5 +echo "configure:111624: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -112243,7 +111628,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:111646: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -112286,12 +111671,12 @@ fi *) echo $ac_n "checking for shl_load""... $ac_c" 1>&6 -echo "configure:112290: checking for shl_load" >&5 +echo "configure:111675: checking for shl_load" >&5 if eval "test \"`echo '$''{'ac_cv_func_shl_load'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:111706: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_shl_load=yes" else @@ -112335,7 +111720,7 @@ if eval "test \"`echo '$ac_cv_func_'shl_load`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 -echo "configure:112339: checking for shl_load in -ldld" >&5 +echo "configure:111724: checking for shl_load in -ldld" >&5 ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -112343,7 +111728,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldld $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:111746: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -112376,12 +111761,12 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dlopen""... $ac_c" 1>&6 -echo "configure:112380: checking for dlopen" >&5 +echo "configure:111765: checking for dlopen" >&5 if eval "test \"`echo '$''{'ac_cv_func_dlopen'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:111796: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_dlopen=yes" else @@ -112425,7 +111810,7 @@ if eval "test \"`echo '$ac_cv_func_'dlopen`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:112429: checking for dlopen in -ldl" >&5 +echo "configure:111814: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -112433,7 +111818,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:111836: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -112466,7 +111851,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dlopen in -lsvld""... $ac_c" 1>&6 -echo "configure:112470: checking for dlopen in -lsvld" >&5 +echo "configure:111855: checking for dlopen in -lsvld" >&5 ac_lib_var=`echo svld'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -112474,7 +111859,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsvld $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:111877: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -112507,7 +111892,7 @@ if eval "test \"`echo '$ac_cv_lib_'$ac_lib_var`\" = yes"; then else echo "$ac_t""no" 1>&6 echo $ac_n "checking for dld_link in -ldld""... $ac_c" 1>&6 -echo "configure:112511: checking for dld_link in -ldld" >&5 +echo "configure:111896: checking for dld_link in -ldld" >&5 ac_lib_var=`echo dld'_'dld_link | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -112515,7 +111900,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldld $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:111918: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_lib_$ac_lib_var=yes" else @@ -112585,7 +111970,7 @@ fi LIBS="$lt_cv_dlopen_libs $LIBS" echo $ac_n "checking whether a program can dlopen itself""... $ac_c" 1>&6 -echo "configure:112589: checking whether a program can dlopen itself" >&5 +echo "configure:111974: checking whether a program can dlopen itself" >&5 if eval "test \"`echo '$''{'lt_cv_dlopen_self'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -112595,7 +111980,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then + if { (eval echo configure:112045: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -112679,7 +112064,7 @@ echo "$ac_t""$lt_cv_dlopen_self" 1>&6 if test "x$lt_cv_dlopen_self" = xyes; then LDFLAGS="$LDFLAGS $link_static_flag" echo $ac_n "checking whether a statically linked program can dlopen itself""... $ac_c" 1>&6 -echo "configure:112683: checking whether a statically linked program can dlopen itself" >&5 +echo "configure:112068: checking whether a statically linked program can dlopen itself" >&5 if eval "test \"`echo '$''{'lt_cv_dlopen_self_static'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -112689,7 +112074,7 @@ else lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 lt_status=$lt_dlunknown cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then + if { (eval echo configure:112139: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} 2>/dev/null; then (./conftest; exit; ) >&5 2>/dev/null lt_status=$? case x$lt_status in @@ -114399,13 +113784,18 @@ X fi if test "$PHP_SIGCHILD" != "yes"; then + if test "$PHP_OCI8_INSTANT_CLIENT" = "no"; then cat < processes when using a local Oracle-DB | -| please recompile PHP and specify --enable-sigchild when configuring| -| (This problem has been reported under Linux using Oracle >= 8.1.5) | +| If you encounter processes when using a local Oracle | +| database, set the value BEQUEATH_DETACH=YES in Oracle Net's | +| sqlnet.ora file on the PHP host, or set the environment variable | +| BEQUEATH_DETACH to YES before starting Apache. If the problem | +| still occurs, then recompile PHP and specify --enable-sigchild | +| when configuring. | X + fi fi fi diff --git a/configure.in b/configure.in index dff131d0f..388d3af22 100644 --- a/configure.in +++ b/configure.in @@ -1,4 +1,4 @@ -## $Id: configure.in,v 1.579.2.52.2.77.2.58 2009/06/26 15:44:18 johannes Exp $ -*- autoconf -*- +## $Id: configure.in 290928 2009-11-18 19:43:33Z johannes $ -*- autoconf -*- dnl ## Process this file with autoconf to produce a configure script. divert(1) @@ -31,7 +31,7 @@ dnl Basic autoconf + automake initialization, generation of config.nice. dnl ------------------------------------------------------------------------- AC_PREREQ(2.13) -AC_INIT(README.CVS-RULES) +AC_INIT(README.SVN-RULES) PHP_CONFIG_NICE(config.nice) @@ -41,7 +41,7 @@ AC_CONFIG_HEADER(main/php_config.h) PHP_MAJOR_VERSION=5 PHP_MINOR_VERSION=3 -PHP_RELEASE_VERSION=0 +PHP_RELEASE_VERSION=1 PHP_EXTRA_VERSION="" PHP_VERSION="$PHP_MAJOR_VERSION.$PHP_MINOR_VERSION.$PHP_RELEASE_VERSION$PHP_EXTRA_VERSION" PHP_VERSION_ID=`expr [$]PHP_MAJOR_VERSION \* 10000 + [$]PHP_MINOR_VERSION \* 100 + [$]PHP_RELEASE_VERSION` @@ -170,7 +170,7 @@ dnl Check if bison generated files exist when bison does not.. case $php_cv_bison_version in ""|invalid[)] if ! test -f "$abs_srcdir/Zend/zend_language_parser.h" || ! test -f "$abs_srcdir/Zend/zend_language_parser.c" ; then - AC_MSG_ERROR([bison is required to build PHP/Zend when building a CVS checkout!]) + AC_MSG_ERROR([bison is required to build PHP/Zend when building a SVN checkout!]) fi ;; esac @@ -217,9 +217,7 @@ case $host_cpu in ;; sparc*) if test "$SUNCC" = "yes"; then - CFLAGS="$CFLAGS -xmemalign=8i" - else - CFLAGS="" + CFLAGS="$CFLAGS -xmemalign=8s" fi ;; esac @@ -256,7 +254,6 @@ case $host_alias in CPPFLAGS="$CPPFLAGS -no-cpp-precomp" fi fi - AC_DEFINE(BIND_8_COMPAT, 1, [Enabling BIND8 compatibility for Panther]) php_multiple_shlib_versions_ok=yes ;; *beos*) @@ -405,6 +402,8 @@ dnl Check for inet_aton dnl in -lc, -lbind and -lresolv PHP_CHECK_FUNC(inet_aton, resolv, bind) +dnl Some systems (like OpenSolaris) do not have nanosleep in libc +PHP_CHECK_FUNC(nanosleep, rt) dnl Then headers. dnl ------------------------------------------------------------------------- @@ -425,9 +424,11 @@ sys/time.h \ netinet/in.h \ alloca.h \ arpa/inet.h \ +arpa/nameser_compat.h \ arpa/nameser.h \ assert.h \ crypt.h \ +dns.h \ fcntl.h \ grp.h \ ieeefp.h \ @@ -486,16 +487,6 @@ assert.h #endif ]) -dnl Don't use mach-o/dyld.h on Darwin 8+, dl* is recommended by Apple from there on -dnl See http://developer.apple.com/documentation/DeveloperTools/Conceptual/MachOTopics/Articles/loading_code.html -case $host_alias in - *darwin[[89]]*) - ;; - *) - AC_CHECK_HEADERS([mach-o/dyld.h],[],[],[]) - ;; -esac - PHP_FOPENCOOKIE PHP_BROKEN_GETCWD PHP_BROKEN_GLIBC_FOPEN_APPEND @@ -601,7 +592,6 @@ putenv \ realpath \ random \ rand_r \ -res_search \ scandir \ setitimer \ setlocale \ @@ -633,7 +623,6 @@ tzset \ unlockpt \ unsetenv \ usleep \ -nanosleep \ utime \ vsnprintf \ vasprintf \ @@ -791,8 +780,8 @@ if test "$PHP_DEBUG" = "yes"; then changequote([,]) dnl add -O0 only if GCC or ICC is used if test "$GCC" = "yes" || test "$ICC" = "yes"; then - CFLAGS="$CFLAGS -O0" - CXXFLAGS="$CXXFLAGS -O0" + CFLAGS="$CFLAGS -g -O0" + CXXFLAGS="$CXXFLAGS -g -O0" fi if test "$SUNCC" = "yes"; then if test -n "$auto_cflags"; then @@ -1579,13 +1568,18 @@ X fi if test "$PHP_SIGCHILD" != "yes"; then + if test "$PHP_OCI8_INSTANT_CLIENT" = "no"; then cat < processes when using a local Oracle-DB | -| please recompile PHP and specify --enable-sigchild when configuring| -| (This problem has been reported under Linux using Oracle >= 8.1.5) | +| If you encounter processes when using a local Oracle | +| database, set the value BEQUEATH_DETACH=YES in Oracle Net's | +| sqlnet.ora file on the PHP host, or set the environment variable | +| BEQUEATH_DETACH to YES before starting Apache. If the problem | +| still occurs, then recompile PHP and specify --enable-sigchild | +| when configuring. | X + fi fi fi diff --git a/cvsclean b/cvsclean deleted file mode 100755 index 3d084df86..000000000 --- a/cvsclean +++ /dev/null @@ -1,3 +0,0 @@ -#! /bin/sh - -${MAKE:-make} -f build/build.mk cvsclean-work diff --git a/cvsclean.bat b/cvsclean.bat deleted file mode 100755 index 4c0118d67..000000000 --- a/cvsclean.bat +++ /dev/null @@ -1,2 +0,0 @@ -@echo off -cscript /nologo win32\build\cvsclean.js diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index 8572bcf85..66485ce3f 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: bcmath.c,v 1.62.2.2.2.8.2.9 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: bcmath.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/bcmath/config.m4 b/ext/bcmath/config.m4 index ea794dffd..06aaf5cad 100644 --- a/ext/bcmath/config.m4 +++ b/ext/bcmath/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.17 2005/05/29 23:16:40 sniper Exp $ +dnl $Id: config.m4 187290 2005-05-29 23:17:16Z sniper $ dnl PHP_ARG_ENABLE(bcmath, whether to enable bc style precision math functions, diff --git a/ext/bcmath/config.w32 b/ext/bcmath/config.w32 index 7496c676a..e091aa9bd 100644 --- a/ext/bcmath/config.w32 +++ b/ext/bcmath/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.2 2003/12/10 00:47:02 wez Exp $ +// $Id: config.w32 146077 2003-12-10 00:47:02Z wez $ // vim:ft=javascript ARG_ENABLE("bcmath", "bc style precision math functions", "yes"); diff --git a/ext/bcmath/php_bcmath.h b/ext/bcmath/php_bcmath.h index 1e8b03d66..49cdc1af0 100644 --- a/ext/bcmath/php_bcmath.h +++ b/ext/bcmath/php_bcmath.h @@ -16,13 +16,11 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_bcmath.h,v 1.20.2.1.2.2.2.2 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: php_bcmath.h 287499 2009-08-20 11:19:20Z jani $ */ #ifndef PHP_BCMATH_H #define PHP_BCMATH_H -#if HAVE_BCMATH - #include "libbcmath/src/bcmath.h" extern zend_module_entry bcmath_module_entry; @@ -50,18 +48,12 @@ ZEND_BEGIN_MODULE_GLOBALS(bcmath) long bc_precision; ZEND_END_MODULE_GLOBALS(bcmath) -#if ZTS -#define BCG(v) TSRMG(bcmath_globals_id, zend_bcmath_globals *, v) +#ifdef ZTS +# define BCG(v) TSRMG(bcmath_globals_id, zend_bcmath_globals *, v) #else -#define BCG(v) (bcmath_globals.v) +# define BCG(v) (bcmath_globals.v) #endif ZEND_EXTERN_MODULE_GLOBALS(bcmath) -#else - -#define phpext_bcmath_ptr NULL - -#endif - #endif /* PHP_BCMATH_H */ diff --git a/ext/bcmath/tests/bcdiv_error1.phpt b/ext/bcmath/tests/bcdiv_error1.phpt new file mode 100755 index 000000000..c69d36bb9 --- /dev/null +++ b/ext/bcmath/tests/bcdiv_error1.phpt @@ -0,0 +1,14 @@ +--TEST-- +bcdiv — Divide two arbitrary precision numbers +--CREDITS-- +TestFest2009 +Antoni Torrents +antoni@solucionsinternet.com +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: bcdiv(): Division by zero in %s.php on line %d diff --git a/ext/bcmath/tests/bcdiv_error2.phpt b/ext/bcmath/tests/bcdiv_error2.phpt new file mode 100644 index 000000000..a90c79e45 --- /dev/null +++ b/ext/bcmath/tests/bcdiv_error2.phpt @@ -0,0 +1,13 @@ +--TEST-- +bcdiv — Divide two arbitrary precision numbers +--CREDITS-- +Antoni Torrents +antoni@solucionsinternet.com +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: bcdiv() expects at most 3 parameters, 4 given in %s.php on line %d diff --git a/ext/bcmath/tests/bcmod_error1.phpt b/ext/bcmath/tests/bcmod_error1.phpt new file mode 100644 index 000000000..e36dce285 --- /dev/null +++ b/ext/bcmath/tests/bcmod_error1.phpt @@ -0,0 +1,13 @@ +--TEST-- +bcmod — Get modulus of an arbitrary precision number +--CREDITS-- +Antoni Torrents +antoni@solucionsinternet.com +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: bcmod() expects exactly 2 parameters, 3 given in %s.php on line %d diff --git a/ext/bcmath/tests/bcpowmod_error1.phpt b/ext/bcmath/tests/bcpowmod_error1.phpt new file mode 100755 index 000000000..2dc292eb5 --- /dev/null +++ b/ext/bcmath/tests/bcpowmod_error1.phpt @@ -0,0 +1,13 @@ +--TEST-- +bcpowmod — Raise an arbitrary precision number to another, reduced by a specified modulus +--CREDITS-- +Antoni Torrents +antoni@solucionsinternet.com +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: bcpowmod() expects at least 3 parameters, 1 given in %s.php on line %d diff --git a/ext/bcmath/tests/bcpowmod_error2.phpt b/ext/bcmath/tests/bcpowmod_error2.phpt new file mode 100755 index 000000000..e0a99637c --- /dev/null +++ b/ext/bcmath/tests/bcpowmod_error2.phpt @@ -0,0 +1,13 @@ +--TEST-- +bcpowmod — Raise an arbitrary precision number to another, reduced by a specified modulus +--CREDITS-- +Antoni Torrents +antoni@solucionsinternet.com +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: bcpowmod() expects at least 3 parameters, 2 given in %s.php on line %d diff --git a/ext/bcmath/tests/bcpowmod_error3.phpt b/ext/bcmath/tests/bcpowmod_error3.phpt new file mode 100644 index 000000000..c3f8df826 --- /dev/null +++ b/ext/bcmath/tests/bcpowmod_error3.phpt @@ -0,0 +1,13 @@ +--TEST-- +bcpowmod — Raise an arbitrary precision number to another, reduced by a specified modulus +--CREDITS-- +Antoni Torrents +antoni@solucionsinternet.com +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: bcpowmod() expects at most 4 parameters, 5 given in %s.php on line %d diff --git a/ext/bcmath/tests/bcsqrt_error1.phpt b/ext/bcmath/tests/bcsqrt_error1.phpt new file mode 100755 index 000000000..1f213dbc8 --- /dev/null +++ b/ext/bcmath/tests/bcsqrt_error1.phpt @@ -0,0 +1,13 @@ +--TEST-- +bcsqrt — Get the square root of an arbitrary precision number +--CREDITS-- +Antoni Torrents +antoni@solucionsinternet.com +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: bcsqrt(): Square root of negative number in %s.php on line %d diff --git a/ext/bz2/bz2.c b/ext/bz2/bz2.c index e7832a889..70eefc827 100644 --- a/ext/bz2/bz2.c +++ b/ext/bz2/bz2.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: bz2.c,v 1.14.2.3.2.12.2.12 2009/05/15 17:28:08 kalle Exp $ */ +/* $Id: bz2.c 280600 2009-05-15 17:28:08Z kalle $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/bz2/bz2_filter.c b/ext/bz2/bz2_filter.c index 3b5e7c220..1522895bf 100644 --- a/ext/bz2/bz2_filter.c +++ b/ext/bz2/bz2_filter.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: bz2_filter.c,v 1.3.2.2.2.5.2.8 2009/02/05 21:45:43 sixd Exp $ */ +/* $Id: bz2_filter.c 275246 2009-02-05 21:45:43Z sixd $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/bz2/config.m4 b/ext/bz2/config.m4 index 4c574e81d..859047183 100644 --- a/ext/bz2/config.m4 +++ b/ext/bz2/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.5 2004/11/03 14:32:48 jorton Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(bz2, for BZip2 support, diff --git a/ext/bz2/config.w32 b/ext/bz2/config.w32 index 598ae18d5..9976203b2 100644 --- a/ext/bz2/config.w32 +++ b/ext/bz2/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.4.6.1 2009/06/10 15:44:51 pajoye Exp $ +// $Id: config.w32 281934 2009-06-10 15:44:51Z pajoye $ // vim:ft=javascript ARG_WITH("bz2", "BZip2", "no"); diff --git a/ext/bz2/php_bz2.h b/ext/bz2/php_bz2.h index 707226f72..4c9085610 100644 --- a/ext/bz2/php_bz2.h +++ b/ext/bz2/php_bz2.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_bz2.h,v 1.7.2.1.2.4.2.3 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: php_bz2.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_BZ2_H #define PHP_BZ2_H diff --git a/ext/bz2/tests/bz2_filter_compress.phpt b/ext/bz2/tests/bz2_filter_compress.phpt index b3d7b0acf..fa0ecb210 100644 --- a/ext/bz2/tests/bz2_filter_compress.phpt +++ b/ext/bz2/tests/bz2_filter_compress.phpt @@ -3,7 +3,7 @@ bzip2.compress (with convert.base64-encode) --SKIPIF-- --FILE-- - --FILE-- - --FILE-- - --FILE-- - | +----------------------------------------------------------------------+ */ -/* $Id: calendar.c,v 1.46.2.2.2.4.2.6 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: calendar.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/calendar/config.m4 b/ext/calendar/config.m4 index 69831e6e0..12cb4c3cc 100644 --- a/ext/calendar/config.m4 +++ b/ext/calendar/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.6 2002/03/12 16:10:56 sas Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_ENABLE(calendar,whether to enable calendar conversion support, diff --git a/ext/calendar/config.w32 b/ext/calendar/config.w32 index a0e2d2fb7..c5e1b6290 100644 --- a/ext/calendar/config.w32 +++ b/ext/calendar/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.1 2003/12/02 23:16:49 wez Exp $ +// $Id: config.w32 242949 2007-09-26 15:44:16Z cvs2svn $ // vim:ft=javascript ARG_ENABLE("calendar", "calendar conversion support", "yes"); diff --git a/ext/com_dotnet/com_com.c b/ext/com_dotnet/com_com.c index abbabe161..7395ed2a6 100644 --- a/ext/com_dotnet/com_com.c +++ b/ext/com_dotnet/com_com.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: com_com.c,v 1.16.2.2.2.5.2.4 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: com_com.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/com_dotnet/com_dotnet.c b/ext/com_dotnet/com_dotnet.c index fa6f09468..5d77d9e1f 100644 --- a/ext/com_dotnet/com_dotnet.c +++ b/ext/com_dotnet/com_dotnet.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: com_dotnet.c,v 1.14.2.1.2.4.2.2 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: com_dotnet.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/com_dotnet/com_extension.c b/ext/com_dotnet/com_extension.c index 983a8541e..1b64d41d2 100644 --- a/ext/com_dotnet/com_extension.c +++ b/ext/com_dotnet/com_extension.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: com_extension.c,v 1.17.2.2.2.6.2.7 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: com_extension.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/com_dotnet/com_handlers.c b/ext/com_dotnet/com_handlers.c index 464b42227..5256b8576 100644 --- a/ext/com_dotnet/com_handlers.c +++ b/ext/com_dotnet/com_handlers.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: com_handlers.c,v 1.30.2.5.2.6.2.6 2009/05/19 17:38:29 kalle Exp $ */ +/* $Id: com_handlers.c 280806 2009-05-19 17:38:29Z kalle $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/com_dotnet/com_iterator.c b/ext/com_dotnet/com_iterator.c index 155eeb69c..835320339 100644 --- a/ext/com_dotnet/com_iterator.c +++ b/ext/com_dotnet/com_iterator.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: com_iterator.c,v 1.9.2.2.2.2.2.3 2009/05/19 17:38:29 kalle Exp $ */ +/* $Id: com_iterator.c 280806 2009-05-19 17:38:29Z kalle $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/com_dotnet/com_misc.c b/ext/com_dotnet/com_misc.c index c5d2f6279..525dfa487 100644 --- a/ext/com_dotnet/com_misc.c +++ b/ext/com_dotnet/com_misc.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: com_misc.c,v 1.8.2.2.2.3.2.2 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: com_misc.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/com_dotnet/com_olechar.c b/ext/com_dotnet/com_olechar.c index e4e954aef..209446c33 100644 --- a/ext/com_dotnet/com_olechar.c +++ b/ext/com_dotnet/com_olechar.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: com_olechar.c,v 1.5.2.1.2.3.2.2 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: com_olechar.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/com_dotnet/com_persist.c b/ext/com_dotnet/com_persist.c index 728de4bad..c19b5a4ff 100755 --- a/ext/com_dotnet/com_persist.c +++ b/ext/com_dotnet/com_persist.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: com_persist.c,v 1.5.2.3.2.2.2.4 2009/05/19 17:38:29 kalle Exp $ */ +/* $Id: com_persist.c 280806 2009-05-19 17:38:29Z kalle $ */ /* Infrastructure for working with persistent COM objects. * Implements: IStream* wrapper for PHP streams. diff --git a/ext/com_dotnet/com_saproxy.c b/ext/com_dotnet/com_saproxy.c index d51e067dd..4c9e61f0b 100644 --- a/ext/com_dotnet/com_saproxy.c +++ b/ext/com_dotnet/com_saproxy.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: com_saproxy.c,v 1.15.2.2.2.3.2.5 2009/05/19 17:38:29 kalle Exp $ */ +/* $Id: com_saproxy.c 280806 2009-05-19 17:38:29Z kalle $ */ /* This module implements a SafeArray proxy which is used internally * by the engine when resolving multi-dimensional array accesses on diff --git a/ext/com_dotnet/com_typeinfo.c b/ext/com_dotnet/com_typeinfo.c index 8475cbae2..a26175d6f 100644 --- a/ext/com_dotnet/com_typeinfo.c +++ b/ext/com_dotnet/com_typeinfo.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: com_typeinfo.c,v 1.7.2.1.2.3.2.2 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: com_typeinfo.c 289996 2009-10-27 19:16:55Z pajoye $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -309,7 +309,7 @@ ITypeInfo *php_com_locate_typeinfo(char *typelibname, php_com_dotnet_object *obj } } else if (typelibname) { /* Fetch the typelibrary and use that to look things up */ - typelib = php_com_load_typelib(typelibname, obj->code_page TSRMLS_CC); + typelib = php_com_load_typelib(typelibname, CP_THREAD_ACP TSRMLS_CC); } if (!gotguid && dispname && typelib) { diff --git a/ext/com_dotnet/com_variant.c b/ext/com_dotnet/com_variant.c index 0b2461d8b..44e5daa81 100644 --- a/ext/com_dotnet/com_variant.c +++ b/ext/com_dotnet/com_variant.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: com_variant.c,v 1.11.2.2.2.6.2.2 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: com_variant.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/com_dotnet/com_wrapper.c b/ext/com_dotnet/com_wrapper.c index bb9df3555..0b2cd1419 100644 --- a/ext/com_dotnet/com_wrapper.c +++ b/ext/com_dotnet/com_wrapper.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: com_wrapper.c,v 1.9.2.1.2.5.2.3 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: com_wrapper.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* This module exports a PHP object as a COM object by wrapping it * using IDispatchEx */ diff --git a/ext/com_dotnet/config.w32 b/ext/com_dotnet/config.w32 index 587d0a0f1..408ecd9a3 100644 --- a/ext/com_dotnet/config.w32 +++ b/ext/com_dotnet/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.6 2004/05/09 15:21:29 wez Exp $ +// $Id: config.w32 242949 2007-09-26 15:44:16Z cvs2svn $ // vim:ft=javascript ARG_ENABLE("com-dotnet", "COM and .Net support", "yes"); diff --git a/ext/com_dotnet/php_com_dotnet.h b/ext/com_dotnet/php_com_dotnet.h index fc112d0c8..092a82638 100644 --- a/ext/com_dotnet/php_com_dotnet.h +++ b/ext/com_dotnet/php_com_dotnet.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_com_dotnet.h,v 1.5.2.1.2.2.2.3 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: php_com_dotnet.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_COM_DOTNET_H #define PHP_COM_DOTNET_H diff --git a/ext/com_dotnet/php_com_dotnet_internal.h b/ext/com_dotnet/php_com_dotnet_internal.h index 525520d58..54963b939 100644 --- a/ext/com_dotnet/php_com_dotnet_internal.h +++ b/ext/com_dotnet/php_com_dotnet_internal.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_com_dotnet_internal.h,v 1.14.2.3.2.4.2.2 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: php_com_dotnet_internal.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_COM_DOTNET_INTERNAL_H #define PHP_COM_DOTNET_INTERNAL_H diff --git a/ext/com_dotnet/tests/27974.phpt b/ext/com_dotnet/tests/27974.phpt index b764e8dd2..8eb14471e 100755 --- a/ext/com_dotnet/tests/27974.phpt +++ b/ext/com_dotnet/tests/27974.phpt @@ -4,7 +4,7 @@ COM: mapping a safearray --FILE-- - --FILE-- - +--FILE-- + +--EXPECT-- +done diff --git a/ext/com_dotnet/tests/variants.phpt b/ext/com_dotnet/tests/variants.phpt index a7fce6b80..7702b8b94 100644 --- a/ext/com_dotnet/tests/variants.phpt +++ b/ext/com_dotnet/tests/variants.phpt @@ -4,7 +4,7 @@ COM: General variant tests --FILE-- -scheme, sizeof("file"))) { + if (uri->scheme && !strncasecmp("file", uri->scheme, sizeof("file"))) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Protocol 'file' disabled in cURL"); php_url_free(uri); return 0; @@ -781,6 +781,9 @@ PHP_MINIT_FUNCTION(curl) #if LIBCURL_VERSION_NUM >= 0x070f01 REGISTER_CURL_CONSTANT(CURLOPT_FTP_FILEMETHOD); +#endif + +#if LIBCURL_VERSION_NUM >= 0x071001 REGISTER_CURL_CONSTANT(CURLFTPMETHOD_MULTICWD); REGISTER_CURL_CONSTANT(CURLFTPMETHOD_NOCWD); REGISTER_CURL_CONSTANT(CURLFTPMETHOD_SINGLECWD); @@ -815,13 +818,24 @@ PHP_MINIT_FUNCTION(curl) char **p = (char **)info->protocols; while (*p != NULL) { - php_register_url_stream_wrapper(*p++, &php_curl_wrapper TSRMLS_CC); + /* Do not enable cURL "file" protocol and make sure cURL is always used when --with-curlwrappers is enabled */ + if (strncasecmp(*p, "file", sizeof("file")-1) != 0) { + php_unregister_url_stream_wrapper(*p TSRMLS_CC); + php_register_url_stream_wrapper(*p, &php_curl_wrapper TSRMLS_CC); + } + (void) *p++; } } # else + php_unregister_url_stream_wrapper("http"); php_register_url_stream_wrapper("http", &php_curl_wrapper TSRMLS_CC); + php_unregister_url_stream_wrapper("https"); php_register_url_stream_wrapper("https", &php_curl_wrapper TSRMLS_CC); + php_unregister_url_stream_wrapper("ftp"); php_register_url_stream_wrapper("ftp", &php_curl_wrapper TSRMLS_CC); + php_unregister_url_stream_wrapper("ftps"); + php_register_url_stream_wrapper("ftps", &php_curl_wrapper TSRMLS_CC); + php_unregister_url_stream_wrapper("ldap"); php_register_url_stream_wrapper("ldap", &php_curl_wrapper TSRMLS_CC); # endif #endif @@ -1328,6 +1342,7 @@ PHP_FUNCTION(curl_init) { php_curl *ch; CURL *cp; + zval *clone; char *url = NULL; int url_len = 0; @@ -1353,6 +1368,9 @@ PHP_FUNCTION(curl_init) ch->uses = 0; + MAKE_STD_ZVAL(clone); + ch->clone = clone; + curl_easy_setopt(ch->cp, CURLOPT_NOPROGRESS, 1); curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0); curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER, ch->err.str); @@ -1406,10 +1424,22 @@ PHP_FUNCTION(curl_copy_handle) dupch->cp = cp; dupch->uses = 0; + if (ch->handlers->write->stream) { + Z_ADDREF_P(dupch->handlers->write->stream); + dupch->handlers->write->stream = ch->handlers->write->stream; + } dupch->handlers->write->method = ch->handlers->write->method; dupch->handlers->write->type = ch->handlers->write->type; + if (ch->handlers->read->stream) { + Z_ADDREF_P(ch->handlers->read->stream); + } + dupch->handlers->read->stream = ch->handlers->read->stream; dupch->handlers->read->method = ch->handlers->read->method; dupch->handlers->write_header->method = ch->handlers->write_header->method; + if (ch->handlers->write_header->stream) { + Z_ADDREF_P(ch->handlers->write_header->stream); + } + dupch->handlers->write_header->stream = ch->handlers->write_header->stream; dupch->handlers->write->fp = ch->handlers->write->fp; dupch->handlers->write_header->fp = ch->handlers->write_header->fp; @@ -1448,6 +1478,10 @@ PHP_FUNCTION(curl_copy_handle) zend_llist_copy(&dupch->to_free.slist, &ch->to_free.slist); zend_llist_copy(&dupch->to_free.post, &ch->to_free.post); + /* Keep track of cloned copies to avoid invoking curl destructors for every clone */ + Z_ADDREF_P(ch->clone); + dupch->clone = ch->clone; + ZEND_REGISTER_RESOURCE(return_value, dupch, le_curl); dupch->id = Z_LVAL_P(return_value); } @@ -1541,7 +1575,8 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu #endif convert_to_long_ex(zvalue); #if LIBCURL_VERSION_NUM >= 0x71304 - if (((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && (Z_LVAL_PP(zvalue) & CURLPROTO_FILE)) { + if ((option == CURLOPT_PROTOCOLS || option == CURLOPT_REDIR_PROTOCOLS) && + ((PG(open_basedir) && *PG(open_basedir)) || PG(safe_mode)) && (Z_LVAL_PP(zvalue) & CURLPROTO_FILE)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "CURLPROTO_FILE cannot be activated when in safe_mode or an open_basedir is set"); RETVAL_FALSE; return 1; @@ -1649,10 +1684,11 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu error = CURLE_OK; switch (option) { case CURLOPT_FILE: - if (((php_stream *) what)->mode[0] != 'r') { - zend_list_addref(Z_LVAL_PP(zvalue)); + if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { + Z_ADDREF_PP(zvalue); ch->handlers->write->fp = fp; ch->handlers->write->method = PHP_CURL_FILE; + ch->handlers->write->stream = *zvalue; } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "the provided file handle is not writable"); RETVAL_FALSE; @@ -1660,10 +1696,11 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu } break; case CURLOPT_WRITEHEADER: - if (((php_stream *) what)->mode[0] != 'r') { - zend_list_addref(Z_LVAL_PP(zvalue)); + if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { + Z_ADDREF_PP(zvalue); ch->handlers->write_header->fp = fp; ch->handlers->write_header->method = PHP_CURL_FILE; + ch->handlers->write_header->stream = *zvalue; } else { php_error_docref(NULL TSRMLS_CC, E_WARNING, "the provided file handle is not writable"); RETVAL_FALSE; @@ -1671,12 +1708,13 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu } break; case CURLOPT_INFILE: - zend_list_addref(Z_LVAL_PP(zvalue)); + Z_ADDREF_PP(zvalue); ch->handlers->read->fp = fp; ch->handlers->read->fd = Z_LVAL_PP(zvalue); + ch->handlers->read->stream = *zvalue; break; case CURLOPT_STDERR: - if (((php_stream *) what)->mode[0] != 'r') { + if (((php_stream *) what)->mode[0] != 'r' || ((php_stream *) what)->mode[1] == '+') { if (ch->handlers->std_err) { zval_ptr_dtor(&ch->handlers->std_err); } @@ -1797,35 +1835,32 @@ static int _php_curl_setopt(php_curl *ch, long option, zval **zvalue, zval *retu * must be explicitly cast to long in curl_formadd * use since curl needs a long not an int. */ if (*postval == '@') { - char *type; + char *type, *filename; ++postval; - if ((type = php_memnstr(postval, ";type=", sizeof(";type=") - 1, postval + strlen(postval)))) { + if ((type = php_memnstr(postval, ";type=", sizeof(";type=") - 1, postval + Z_STRLEN_PP(current)))) { *type = '\0'; } + if ((filename = php_memnstr(postval, ";filename=", sizeof(";filename=") - 1, postval + Z_STRLEN_PP(current)))) { + *filename = '\0'; + } /* safe_mode / open_basedir check */ if (php_check_open_basedir(postval TSRMLS_CC) || (PG(safe_mode) && !php_checkuid(postval, "rb+", CHECKUID_CHECK_MODE_PARAM))) { - if (type) { - *type = ';'; - } RETVAL_FALSE; return 1; } + error = curl_formadd(&first, &last, + CURLFORM_COPYNAME, string_key, + CURLFORM_NAMELENGTH, (long)string_key_len - 1, + CURLFORM_FILENAME, filename ? filename : postval, + CURLFORM_CONTENTTYPE, type ? type + sizeof(";type=") - 1 : "application/octet-stream", + CURLFORM_FILE, postval, + CURLFORM_END); if (type) { - error = curl_formadd(&first, &last, - CURLFORM_COPYNAME, string_key, - CURLFORM_NAMELENGTH, (long)string_key_len - 1, - CURLFORM_FILE, postval, - CURLFORM_CONTENTTYPE, type + sizeof(";type=") - 1, - CURLFORM_END); *type = ';'; - } else { - error = curl_formadd(&first, &last, - CURLFORM_COPYNAME, string_key, - CURLFORM_NAMELENGTH, (long)string_key_len - 1, - CURLFORM_FILE, postval, - CURLFORM_END); - + } + if (filename) { + *filename = ';'; } } else { error = curl_formadd(&first, &last, @@ -2298,8 +2333,19 @@ static void _php_curl_close_ex(php_curl *ch TSRMLS_DC) #if LIBCURL_VERSION_NUM < 0x071101 zend_llist_clean(&ch->to_free.str); #endif - zend_llist_clean(&ch->to_free.slist); - zend_llist_clean(&ch->to_free.post); + + /* cURL destructors should be invoked only by last curl handle */ + if (Z_REFCOUNT_P(ch->clone) <= 1) { + zend_llist_clean(&ch->to_free.slist); + zend_llist_clean(&ch->to_free.post); + FREE_ZVAL(ch->clone); + } else { + Z_DELREF_P(ch->clone); + ch->to_free.slist.dtor = NULL; + ch->to_free.post.dtor = NULL; + zend_llist_clean(&ch->to_free.slist); + zend_llist_clean(&ch->to_free.post); + } if (ch->handlers->write->buf.len > 0) { smart_str_free(&ch->handlers->write->buf); @@ -2326,6 +2372,16 @@ static void _php_curl_close_ex(php_curl *ch TSRMLS_DC) efree(ch->header.str); } + if (ch->handlers->write_header->stream) { + zval_ptr_dtor(&ch->handlers->write_header->stream); + } + if (ch->handlers->write->stream) { + zval_ptr_dtor(&ch->handlers->write->stream); + } + if (ch->handlers->read->stream) { + zval_ptr_dtor(&ch->handlers->read->stream); + } + efree(ch->handlers->write); efree(ch->handlers->write_header); efree(ch->handlers->read); diff --git a/ext/curl/multi.c b/ext/curl/multi.c index f31f1c769..91312e4ce 100644 --- a/ext/curl/multi.c +++ b/ext/curl/multi.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: multi.c,v 1.19.2.3.2.7.2.4 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: multi.c 272370 2008-12-31 11:15:49Z sebastian $ */ #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h index 7e6283c3e..657a0cd9b 100644 --- a/ext/curl/php_curl.h +++ b/ext/curl/php_curl.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_curl.h,v 1.44.2.2.2.2.2.6 2009/05/27 22:35:26 pajoye Exp $ */ +/* $Id: php_curl.h 289496 2009-10-10 09:29:34Z pajoye $ */ #ifndef _PHP_CURL_H #define _PHP_CURL_H @@ -86,6 +86,7 @@ typedef struct { smart_str buf; int method; int type; + zval *stream; } php_curl_write; typedef struct { @@ -94,6 +95,7 @@ typedef struct { FILE *fp; long fd; int method; + zval *stream; } php_curl_read; typedef struct { @@ -139,6 +141,7 @@ typedef struct { long id; unsigned int uses; zend_bool in_callback; + zval *clone; } php_curl; typedef struct { diff --git a/ext/curl/streams.c b/ext/curl/streams.c index 14d183d6d..26786ad18 100644 --- a/ext/curl/streams.c +++ b/ext/curl/streams.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streams.c,v 1.14.2.2.2.11.2.6 2009/05/19 18:08:57 kalle Exp $ */ +/* $Id: streams.c 284747 2009-07-25 13:00:25Z jani $ */ /* This file implements cURL based wrappers. * NOTE: If you are implementing your own streams that are intended to @@ -474,8 +474,7 @@ php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename, #else php_error_docref(NULL TSRMLS_CC, E_WARNING, "There was an error mcode=%d", m); #endif - php_stream_close(stream); - return NULL; + goto exit_fail; } /* we have only one curl handle here, even though we use multi syntax, @@ -493,14 +492,23 @@ php_stream *php_curl_stream_opener(php_stream_wrapper *wrapper, char *filename, } } if (msg_found) { - php_stream_close(stream); - return NULL; + goto exit_fail; } } + + /* context headers are not needed anymore */ if (slist) { + curl_easy_setopt(curlstream->curl, CURLOPT_HTTPHEADER, NULL); curl_slist_free_all(slist); } return stream; + +exit_fail: + php_stream_close(stream); + if (slist) { + curl_slist_free_all(slist); + } + return NULL; } static php_stream_wrapper_ops php_curl_wrapper_ops = { diff --git a/ext/curl/tests/bug46739.phpt b/ext/curl/tests/bug46739.phpt index 52bfbc8ff..895bba755 100644 --- a/ext/curl/tests/bug46739.phpt +++ b/ext/curl/tests/bug46739.phpt @@ -5,9 +5,6 @@ Bug #46739 (array returned by curl_getinfo should contain content_type key) if (!extension_loaded("curl")) { exit("skip curl extension not loaded"); } -if (false === getenv('PHP_CURL_HTTP_REMOTE_SERVER')) { - exit("skip PHP_CURL_HTTP_REMOTE_SERVER env variable is not defined"); -} ?> --FILE-- +--FILE-- + +--EXPECTF-- +Warning: curl_setopt(): the provided file handle is not writable in %s on line %d +Hello World! +Hello World! diff --git a/ext/curl/tests/curl_CURLOPT_READDATA.phpt b/ext/curl/tests/curl_CURLOPT_READDATA.phpt new file mode 100644 index 000000000..00f3ea95a --- /dev/null +++ b/ext/curl/tests/curl_CURLOPT_READDATA.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test CURLOPT_READDATA without a callback function +--CREDITS-- +Mattijs Hoitink mattijshoitink@gmail.com +#Testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + + string(5) "world" + ["smurf"]=> + string(4) "blue" +} diff --git a/ext/curl/tests/curl_close_basic.phpt b/ext/curl/tests/curl_close_basic.phpt new file mode 100644 index 000000000..9c01b02f7 --- /dev/null +++ b/ext/curl/tests/curl_close_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +curl_close +--CREDITS-- +Stefan Koopmanschap +#testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +resource(%d) of type (Unknown) +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic.phpt b/ext/curl/tests/curl_copy_handle_basic.phpt new file mode 100644 index 000000000..1a6ff4169 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test curl_copy_handle() function with basic functionality +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing curl_copy_handle(): basic *** +bool(true) +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic_001.phpt b/ext/curl/tests/curl_copy_handle_basic_001.phpt new file mode 100644 index 000000000..db4bf0233 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_001.phpt @@ -0,0 +1,42 @@ +--TEST-- +Test curl_copy_handle() with simple get +--CREDITS-- +Rick Buitenman +#testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing curl copy handle with simple GET *** +string(106) "array(2) { + ["test"]=> + string(7) "getpost" + ["get_param"]=> + string(11) "Hello World" +} +array(0) { +} +" +===DONE=== \ No newline at end of file diff --git a/ext/curl/tests/curl_copy_handle_basic_002.phpt b/ext/curl/tests/curl_copy_handle_basic_002.phpt new file mode 100644 index 000000000..8a3582384 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_002.phpt @@ -0,0 +1,49 @@ +--TEST-- +Test curl_copy_handle() with simple POST +--CREDITS-- +Rick Buitenman +#testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--XFAIL-- +This test fails, the copy seems to be missing the CURLOPT_POSTFIELDS after the original is closed +--EXPECTF-- +*** Testing curl copy handle with simple POST *** +string(163) "array(1) { + ["test"]=> + string(7) "getpost" +} +array(3) { + ["Hello"]=> + string(5) "World" + ["Foo"]=> + string(3) "Bar" + ["Person"]=> + string(8) "John Doe" +} +" +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic_004.phpt b/ext/curl/tests/curl_copy_handle_basic_004.phpt new file mode 100644 index 000000000..2b75eb6a4 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_004.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test curl_copy_handle() after exec() +--CREDITS-- +Rick Buitenman +#testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +*** Test curl_copy_handle() after exec() *** +string(106) "array(2) { + ["test"]=> + string(7) "getpost" + ["get_param"]=> + string(11) "Hello World" +} +array(0) { +} +" +===DONE=== \ No newline at end of file diff --git a/ext/curl/tests/curl_copy_handle_basic_005.phpt b/ext/curl/tests/curl_copy_handle_basic_005.phpt new file mode 100644 index 000000000..dcc7e47af --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_005.phpt @@ -0,0 +1,52 @@ +--TEST-- +Test curl_copy_handle() after exec() with POST +--CREDITS-- +Rick Buitenman +#testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--XFAIL-- +This test fails, the output of the copy seems to be corrupted if the original is closed after exec() +--EXPECTF-- +*** Test curl_copy_handle() after exec() with POST *** +string(163) "array(1) { + ["test"]=> + string(7) "getpost" +} +array(3) { + ["Hello"]=> + string(5) "World" + ["Foo"]=> + string(3) "Bar" + ["Person"]=> + string(8) "John Doe" +} +" +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic_006.phpt b/ext/curl/tests/curl_copy_handle_basic_006.phpt new file mode 100644 index 000000000..d2374c721 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_006.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test curl_copy_handle() with User Agent +--CREDITS-- +Rick Buitenman +#testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing curl copy handle with User Agent *** +string(9) "cURL phpt" +string(9) "cURL phpt" +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_basic_007.phpt b/ext/curl/tests/curl_copy_handle_basic_007.phpt new file mode 100644 index 000000000..a51d9f6df --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_basic_007.phpt @@ -0,0 +1,45 @@ +--TEST-- +Test curl_copy_handle() with simple POST +--SKIPIF-- + +--FILE-- + "World", "Foo" => "Bar", "Person" => "John Doe")); + curl_setopt($ch, CURLOPT_HTTPHEADER, array('Expect:')); // Disable Expect: header (lighttpd does not support it :) + curl_setopt($ch, CURLOPT_URL, $url); //set the url we want to use + + $copy = curl_copy_handle($ch); + curl_close($ch); + + $curl_content = curl_exec($copy); + curl_close($copy); + + var_dump( $curl_content ); +?> +===DONE=== +--EXPECTF-- +*** Testing curl copy handle with simple POST using array as arguments *** +string(163) "array(1) { + ["test"]=> + string(7) "getpost" +} +array(3) { + ["Hello"]=> + string(5) "World" + ["Foo"]=> + string(3) "Bar" + ["Person"]=> + string(8) "John Doe" +} +" +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_variation1.phpt b/ext/curl/tests/curl_copy_handle_variation1.phpt new file mode 100644 index 000000000..da4522192 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_variation1.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test curl_copy_handle() change options in one handle +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing curl_copy_handle(): basic *** +bool(false) +===DONE=== diff --git a/ext/curl/tests/curl_copy_handle_variation2.phpt b/ext/curl/tests/curl_copy_handle_variation2.phpt new file mode 100644 index 000000000..924bf6a47 --- /dev/null +++ b/ext/curl/tests/curl_copy_handle_variation2.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test curl_copy_handle() add options to the handles +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- + +--COMMENT-- +the only way to test if a option is setten on a curl handle is using the curl_getinfo() function. +but this can only check on a limited amount of options... +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing curl_copy_handle(): add options after copy *** +bool(true) +bool(false) +bool(true) +bool(false) +===DONE=== diff --git a/ext/curl/tests/curl_error_basic.phpt b/ext/curl/tests/curl_error_basic.phpt new file mode 100644 index 000000000..c9aa9ef8a --- /dev/null +++ b/ext/curl/tests/curl_error_basic.phpt @@ -0,0 +1,33 @@ +--TEST-- +curl_error() function - basic test for curl_error using a fake url +--CREDITS-- +Mattijs Hoitink mattijshoitink@gmail.com +#Testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +== Testing curl_error with a fake URL == +Error: Couldn't resolve host 'fakeURL' diff --git a/ext/curl/tests/curl_multi_close_basic.phpt b/ext/curl/tests/curl_multi_close_basic.phpt new file mode 100644 index 000000000..28865bc86 --- /dev/null +++ b/ext/curl/tests/curl_multi_close_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +curl_multi_close +--CREDITS-- +Stefan Koopmanschap +#testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +resource(%d) of type (Unknown) +===DONE=== diff --git a/ext/curl/tests/curl_multi_getcontent_basic3.phpt b/ext/curl/tests/curl_multi_getcontent_basic3.phpt new file mode 100644 index 000000000..1434c58d0 --- /dev/null +++ b/ext/curl/tests/curl_multi_getcontent_basic3.phpt @@ -0,0 +1,59 @@ +--TEST-- +Curl_multi_getcontent() basic test with different sources (local file/http) +--CREDITS-- +Rein Velt (rein@velt.org) +#TestFest Utrecht 20090509 +--SKIPIF-- + +--FILE-- +0); + + $results1=curl_multi_getcontent($ch1); + $results2=curl_multi_getcontent($ch2); + + //CLOSE + curl_multi_remove_handle($mh,$ch1); + curl_multi_remove_handle($mh,$ch2); + curl_multi_close($mh); + + echo $results1; + echo $results2; + +?> +--EXPECT-- +User-agent: * +Disallow: /backend/ +Disallow: /distributions/ +Disallow: /stats/ +Disallow: /source.php +Disallow: /search.php +Disallow: /mod.php +Disallow: /manual/add-note.php +CURL2 + diff --git a/ext/curl/tests/curl_multi_getcontent_error1.phpt b/ext/curl/tests/curl_multi_getcontent_error1.phpt new file mode 100644 index 000000000..88de0d7d3 --- /dev/null +++ b/ext/curl/tests/curl_multi_getcontent_error1.phpt @@ -0,0 +1,51 @@ +--TEST-- +Curl_multi_getcontent() error test +--CREDITS-- +Rein Velt (rein@velt.org) +#TestFest Utrecht 20090509 +--SKIPIF-- + +--FILE-- +0); + + $results1=curl_multi_getcontent(); //no parameter + $results2=curl_multi_getcontent($ch2); + + //CLOSE + curl_multi_remove_handle($mh,$ch1); + curl_multi_remove_handle($mh,$ch2); + curl_multi_close($mh); + + echo $results1; + echo $results2; + +?> +--EXPECTF-- +Warning: curl_multi_getcontent() expects exactly 1 parameter, 0 given in %s on line %d +CURL2 diff --git a/ext/curl/tests/curl_multi_getcontent_error2.phpt b/ext/curl/tests/curl_multi_getcontent_error2.phpt new file mode 100644 index 000000000..ad837d828 --- /dev/null +++ b/ext/curl/tests/curl_multi_getcontent_error2.phpt @@ -0,0 +1,51 @@ +--TEST-- +Curl_multi_getcontent() error test +--CREDITS-- +Rein Velt (rein@velt.org) +#TestFest Utrecht 20090509 +--SKIPIF-- + +--FILE-- +0); + + $results1=curl_multi_getcontent($ch1,$ch2); //no parameter + $results2=curl_multi_getcontent($ch2); + + //CLOSE + curl_multi_remove_handle($mh,$ch1); + curl_multi_remove_handle($mh,$ch2); + curl_multi_close($mh); + + echo $results1; + echo $results2; + +?> +--EXPECTF-- +Warning: curl_multi_getcontent() expects exactly 1 parameter, 2 given in %s on line %d +CURL2 diff --git a/ext/curl/tests/curl_multi_getcontent_error3.phpt b/ext/curl/tests/curl_multi_getcontent_error3.phpt new file mode 100644 index 000000000..6ffc6b736 --- /dev/null +++ b/ext/curl/tests/curl_multi_getcontent_error3.phpt @@ -0,0 +1,53 @@ +--TEST-- +Curl_multi_getcontent() error test +--CREDITS-- +Rein Velt (rein@velt.org) +#TestFest Utrecht 20090509 +--SKIPIF-- + +--FILE-- +0); + + $ch1="string"; + + $results1=curl_multi_getcontent($ch1); //incorrect parameter type + $results2=curl_multi_getcontent($ch2); + + //CLOSE + //curl_multi_remove_handle($mh,$ch1); + curl_multi_remove_handle($mh,$ch2); + curl_multi_close($mh); + + echo $results1; + echo $results2; + +?> +--EXPECTF-- +Warning: curl_multi_getcontent() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d +CURL2 diff --git a/ext/curl/tests/curl_multi_getcontent_error4.phpt b/ext/curl/tests/curl_multi_getcontent_error4.phpt new file mode 100644 index 000000000..68928647a --- /dev/null +++ b/ext/curl/tests/curl_multi_getcontent_error4.phpt @@ -0,0 +1,66 @@ +--TEST-- +Curl_multi_getcontent() error test with undefined handle +--CREDITS-- +Rein Velt (rein@velt.org) +#TestFest Utrecht 20090509 +--SKIPIF-- + +--FILE-- +0); + + + $results1=curl_multi_getcontent($ch1); //incorrect parameter type + $results2=curl_multi_getcontent($ch2); + + //CLOSE + //curl_multi_remove_handle($mh,$ch1); + curl_multi_remove_handle($mh,$ch2); + curl_multi_close($mh); + + echo $results1; + echo $results2; + +?> +--EXPECTF-- +Notice: Undefined variable: ch1 in %s on line %d + +Warning: curl_setopt() expects parameter 1 to be resource, null given in %s on line %d + +Notice: Undefined variable: ch1 in %s on line %d + +Warning: curl_setopt() expects parameter 1 to be resource, null given in %s on line %d + +Notice: Undefined variable: ch1 in %s on line %d + +Warning: curl_multi_add_handle() expects parameter 2 to be resource, null given in %s on line %d + +Notice: Undefined variable: ch1 in %s on line %d + +Warning: curl_multi_getcontent() expects parameter 1 to be resource, null given in %s on line %d +CURL2 diff --git a/ext/curl/tests/curl_multi_init_basic.phpt b/ext/curl/tests/curl_multi_init_basic.phpt new file mode 100644 index 000000000..0fd865df7 --- /dev/null +++ b/ext/curl/tests/curl_multi_init_basic.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test curl_multi_init() +--CREDITS-- +Mark van der Velden +#testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing curl_multi_init(void); *** +resource(%d) of type (curl_multi) +resource(%d) of type (Unknown) +===DONE=== diff --git a/ext/curl/tests/curl_multi_select_basic1.phpt b/ext/curl/tests/curl_multi_select_basic1.phpt new file mode 100644 index 000000000..7ae812412 --- /dev/null +++ b/ext/curl/tests/curl_multi_select_basic1.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test curl_multi_select() +--CREDITS-- +Ivo Jansch +#testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +%r(0|-1)%r +===DONE=== diff --git a/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION_open_basedir.phpt b/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION_open_basedir.phpt new file mode 100644 index 000000000..68465e6da --- /dev/null +++ b/ext/curl/tests/curl_setopt_CURLOPT_FOLLOWLOCATION_open_basedir.phpt @@ -0,0 +1,22 @@ +--TEST-- +CURLOPT_FOLLOWLOCATION case check safe_mode and open_basedir +--CREDITS-- +WHITE new media architects - Dennis +--INI-- +open_basedir = DIRECTORY_SEPARATOR."tmp"; +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when %r(in safe_mode or an )?%ropen_basedir is set in %s.php on line %d +bool(false) + diff --git a/ext/curl/tests/curl_setopt_CURLOPT_READFUNCTION.phpt b/ext/curl/tests/curl_setopt_CURLOPT_READFUNCTION.phpt new file mode 100644 index 000000000..9de2c0fab --- /dev/null +++ b/ext/curl/tests/curl_setopt_CURLOPT_READFUNCTION.phpt @@ -0,0 +1,54 @@ +--TEST-- +cURL option CURLOPT_READFUNCTION +--CREDITS-- +WHITE new media architects - Jeroen Vermeulen +#testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +string(27) "custom:contents of tempfile" +===DONE=== diff --git a/ext/curl/tests/curl_setopt_array_basic.phpt b/ext/curl/tests/curl_setopt_array_basic.phpt new file mode 100644 index 000000000..877079bca --- /dev/null +++ b/ext/curl/tests/curl_setopt_array_basic.phpt @@ -0,0 +1,55 @@ +--TEST-- +curl_setopt_array() function - tests setting multiple cURL options with curl_setopt_array() +--CREDITS-- +Mattijs Hoitink mattijshoitink@gmail.com +#Testfest Utrecht 2009 +--SKIPIF-- + +--FILE-- + $url, + CURLOPT_RETURNTRANSFER => 1 +); + +ob_start(); // start output buffering + +curl_setopt_array($ch, $options); +$returnContent = curl_exec($ch); +curl_close($ch); + +var_dump($returnContent); + +?> +--EXPECT-- +== Starting test curl_setopt_array($ch, $options); == +string(25) "Hello World! +Hello World!" + diff --git a/ext/curl/tests/curl_setopt_basic001.phpt b/ext/curl/tests/curl_setopt_basic001.phpt new file mode 100644 index 000000000..4167c0532 --- /dev/null +++ b/ext/curl/tests/curl_setopt_basic001.phpt @@ -0,0 +1,35 @@ +--TEST-- +curl_setopt basic tests. +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--INI-- +safe_mode=On +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +PHP Warning: Directive 'safe_mode' is deprecated in PHP 5.3 and greater in Unknown on line 0 +*** Testing curl_setopt with CURLOPT_FOLLOWLOCATION in safemode + +Warning: curl_setopt(): CURLOPT_FOLLOWLOCATION cannot be activated when in safe_mode or an open_basedir is set in %s on line %d +bool(false) + diff --git a/ext/curl/tests/curl_setopt_basic002.phpt b/ext/curl/tests/curl_setopt_basic002.phpt new file mode 100644 index 000000000..051703fb0 --- /dev/null +++ b/ext/curl/tests/curl_setopt_basic002.phpt @@ -0,0 +1,50 @@ +--TEST-- +curl_setopt basic tests with CURLOPT_STDERR. +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Testing curl_setopt with CURLOPT_STDERR +string(%d) "%S" +string(%d) "%S" diff --git a/ext/curl/tests/curl_setopt_basic003.phpt b/ext/curl/tests/curl_setopt_basic003.phpt new file mode 100644 index 000000000..47ae0f773 --- /dev/null +++ b/ext/curl/tests/curl_setopt_basic003.phpt @@ -0,0 +1,43 @@ +--TEST-- +curl_setopt() call with CURLOPT_HTTPHEADER +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** curl_setopt() call with CURLOPT_HTTPHEADER + +Warning: curl_setopt(): You must pass either an object or an array with the CURLOPT_HTTPHEADER, CURLOPT_QUOTE, CURLOPT_HTTP200ALIASES and CURLOPT_POSTQUOTE arguments in %s on line %d +bool(false) +bool(true) diff --git a/ext/curl/tests/curl_setopt_basic004.phpt b/ext/curl/tests/curl_setopt_basic004.phpt new file mode 100644 index 000000000..63f956162 --- /dev/null +++ b/ext/curl/tests/curl_setopt_basic004.phpt @@ -0,0 +1,44 @@ +--TEST-- +curl_setopt() call with CURLOPT_RETURNTRANSFER +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** curl_setopt() call with CURLOPT_RETURNTRANSFER set to 1 +string(%d) "%a" +*** curl_setopt() call with CURLOPT_RETURNTRANSFER set to 0 +bool(true) diff --git a/ext/curl/tests/curl_setopt_error.phpt b/ext/curl/tests/curl_setopt_error.phpt new file mode 100644 index 000000000..5489b34e2 --- /dev/null +++ b/ext/curl/tests/curl_setopt_error.phpt @@ -0,0 +1,44 @@ +--TEST-- +curl_setopt() basic parameter test +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** curl_setopt() call with incorrect parameters + +Warning: curl_setopt() expects exactly 3 parameters, 0 given in %s on line %d + +Warning: curl_setopt() expects exactly 3 parameters, 1 given in %s on line %d + +Warning: curl_setopt() expects exactly 3 parameters, 1 given in %s on line %d + +Warning: curl_setopt() expects exactly 3 parameters, 2 given in %s on line %d + +Warning: curl_setopt() expects exactly 3 parameters, 2 given in %s on line %d + +Warning: curl_setopt() expects exactly 3 parameters, 2 given in %s on line %d + +Warning: curl_setopt() expects parameter 1 to be resource, boolean given in %s on line %d + +Warning: curl_setopt() expects parameter 2 to be long, %unicode_string_optional% given in %s on line %d + diff --git a/ext/curl/tests/curl_testdata1.txt b/ext/curl/tests/curl_testdata1.txt new file mode 100644 index 000000000..dc1e44627 --- /dev/null +++ b/ext/curl/tests/curl_testdata1.txt @@ -0,0 +1 @@ +CURL1 diff --git a/ext/curl/tests/curl_testdata2.txt b/ext/curl/tests/curl_testdata2.txt new file mode 100644 index 000000000..3b9f76f77 --- /dev/null +++ b/ext/curl/tests/curl_testdata2.txt @@ -0,0 +1 @@ +CURL2 diff --git a/ext/curl/tests/curl_version_error.phpt b/ext/curl/tests/curl_version_error.phpt new file mode 100644 index 000000000..f9de8dd32 --- /dev/null +++ b/ext/curl/tests/curl_version_error.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test curl_version() function : error conditions +--SKIPIF-- + +--FILE-- + +===Done=== +--EXPECTF-- +*** Testing curl_version() : error conditions *** + +-- Testing curl_version() function with more than expected no. of arguments -- + +Warning: curl_version() expects at most 1 parameter, 2 given in %s on line %d +NULL +===Done=== diff --git a/ext/curl/tests/curl_version_variation1.phpt b/ext/curl/tests/curl_version_variation1.phpt new file mode 100644 index 000000000..4b8676099 --- /dev/null +++ b/ext/curl/tests/curl_version_variation1.phpt @@ -0,0 +1,162 @@ +--TEST-- +Test curl_version() function : usage variations - test values for $ascii argument +--SKIPIF-- + +--FILE-- + +===Done=== +--EXPECTF-- +*** Testing curl_version() function: with unexpected inputs for 'age' argument *** +-- Iteration 1 -- +bool(true) +-- Iteration 2 -- +bool(true) +-- Iteration 3 -- +bool(true) +-- Iteration 4 -- +bool(true) +-- Iteration 5 -- +bool(true) +-- Iteration 6 -- +bool(true) +-- Iteration 7 -- +bool(true) +-- Iteration 8 -- +bool(true) +-- Iteration 9 -- +bool(true) +-- Iteration 10 -- + +Warning: curl_version() expects parameter 1 to be long, array given in %s on line %d +bool(false) +-- Iteration 11 -- + +Warning: curl_version() expects parameter 1 to be long, array given in %s on line %d +bool(false) +-- Iteration 12 -- + +Warning: curl_version() expects parameter 1 to be long, array given in %s on line %d +bool(false) +-- Iteration 13 -- + +Warning: curl_version() expects parameter 1 to be long, string given in %s on line %d +bool(false) +-- Iteration 14 -- + +Warning: curl_version() expects parameter 1 to be long, string given in %s on line %d +bool(false) +-- Iteration 15 -- + +Notice: A non well formed numeric value encountered in %s on line %d +bool(true) +-- Iteration 16 -- +bool(true) +-- Iteration 17 -- +bool(true) +-- Iteration 18 -- +bool(true) +-- Iteration 19 -- +bool(true) +-- Iteration 20 -- +bool(true) +-- Iteration 21 -- +bool(true) +-- Iteration 22 -- + +Warning: curl_version() expects parameter 1 to be long, object given in %s on line %d +bool(false) +-- Iteration 23 -- + +Warning: curl_version() expects parameter 1 to be long, resource given in %s on line %d +bool(false) +-- Iteration 24 -- +bool(true) +-- Iteration 25 -- +bool(true) +===Done=== diff --git a/ext/curl/tests/curl_write_callback.phpt b/ext/curl/tests/curl_write_callback.phpt new file mode 100644 index 000000000..c0b733ee4 --- /dev/null +++ b/ext/curl/tests/curl_write_callback.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test curl option CURLOPT_WRITEFUNCTION +--CREDITS-- +Mathieu Kooiman +Dutch UG, TestFest 2009, Utrecht +--DESCRIPTION-- +Writes the value 'test' to a temporary file. Use curl to access this file, passing the output into a callback. Tests the PHP_CURL_USER case in curl_write. +--SKIPIF-- + +--FILE-- + +--EXPECT-- +test diff --git a/ext/curl/tests/curl_write_file.phpt b/ext/curl/tests/curl_write_file.phpt new file mode 100644 index 000000000..95d2b0ea4 --- /dev/null +++ b/ext/curl/tests/curl_write_file.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test curl option CURLOPT_FILE +--CREDITS-- +Mathieu Kooiman +Dutch UG, TestFest 2009, Utrecht +--DESCRIPTION-- +Writes the value 'test' to a temporary file. Use curl to access this file and store the output in another temporary file. Tests the PHP_CURL_FILE case in curl_write(). +--SKIPIF-- + +--FILE-- + +--EXPECT-- +test diff --git a/ext/curl/tests/curl_write_return.phpt b/ext/curl/tests/curl_write_return.phpt new file mode 100644 index 000000000..1ddc55157 --- /dev/null +++ b/ext/curl/tests/curl_write_return.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test curl option CURLOPT_RETURNTRANSFER +--CREDITS-- +Mathieu Kooiman +Dutch UG, TestFest 2009, Utrecht +--DESCRIPTION-- +Writes the value 'test' to a temporary file. Use curl to access this file and have it return the content from curl_exec(). Tests the PHP_CURL_RETURN case +of curl_write(). +--SKIPIF-- + +--FILE-- + +--EXPECT-- +test diff --git a/ext/curl/tests/curl_write_stdout.phpt b/ext/curl/tests/curl_write_stdout.phpt new file mode 100644 index 000000000..893b27e7d --- /dev/null +++ b/ext/curl/tests/curl_write_stdout.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test curl option CURLOPT_FILE with STDOUT handle +--CREDITS-- +Mathieu Kooiman +Dutch UG, TestFest 2009, Utrecht +--DESCRIPTION-- +Writes the value 'test' to a temporary file. Use curl to access this file and store the output in another temporary file. Tests the PHP_CURL_FILE case in curl_write(). +--SKIPIF-- + +--FILE-- + +--EXPECT-- +test diff --git a/ext/curl/tests/curl_writeheader_callback.phpt b/ext/curl/tests/curl_writeheader_callback.phpt new file mode 100644 index 000000000..ae0075c84 --- /dev/null +++ b/ext/curl/tests/curl_writeheader_callback.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test curl option CURLOPT_HEADERFUNCTION +--CREDITS-- +Mathieu Kooiman +Dutch UG, TestFest 2009, Utrecht +--DESCRIPTION-- +Hit the host identified by PHP_CURL_HTTP_REMOTE_SERVER and determine that the headers are sent to the callback specified for CURLOPT_HEADERFUNCTION. Different test servers specified for PHP_CURL_HTTP_REMOTE_SERVER might return different sets of headers. Just test for HTTP/1.1 200 OK. +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +HTTP/1.1 %d %s diff --git a/ext/curl/tests/responder/get.php b/ext/curl/tests/responder/get.php index 26dd5198a..e77faa57d 100644 --- a/ext/curl/tests/responder/get.php +++ b/ext/curl/tests/responder/get.php @@ -1,5 +1,8 @@ #include diff --git a/ext/date/lib/dow.c b/ext/date/lib/dow.c index 705132285..eb4b329ad 100644 --- a/ext/date/lib/dow.c +++ b/ext/date/lib/dow.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dow.c,v 1.8.2.3.2.3.2.5 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: dow.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "timelib.h" diff --git a/ext/date/lib/interval.c b/ext/date/lib/interval.c index e9493f833..07be0264b 100644 --- a/ext/date/lib/interval.c +++ b/ext/date/lib/interval.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: interval.c,v 1.1.2.2 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: interval.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "timelib.h" diff --git a/ext/date/lib/parse_date.c b/ext/date/lib/parse_date.c index d0caeca51..493812750 100644 --- a/ext/date/lib/parse_date.c +++ b/ext/date/lib/parse_date.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Thu Dec 18 14:58:43 2008 */ +/* Generated by re2c 0.13.5 on Wed Jul 29 16:20:12 2009 */ /* +----------------------------------------------------------------------+ | PHP Version 5 | @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: parse_date.c,v 1.29.2.30.2.14.2.29 2008/12/18 14:55:14 derick Exp $ */ +/* $Id: parse_date.c 286515 2009-07-29 15:34:59Z derick $ */ #include "timelib.h" @@ -23988,10 +23988,18 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim add_pbf_error(s, "A two digit second could not be found", string, begin); } break; - case 'u': /* five digit millisecond, with leading zero */ - TIMELIB_CHECK_NUMBER; - if ((s->time->f = timelib_get_nr((char **) &ptr, 5)) == TIMELIB_UNSET) { - add_pbf_error(s, "A five digit millisecond could not be found", string, begin); + case 'u': /* six digit millisecond */ + { + double f; + char *tptr; + + TIMELIB_CHECK_NUMBER; + tptr = ptr; + if ((f = timelib_get_nr((char **) &ptr, 6)) == TIMELIB_UNSET || ptr - tptr != 6) { + add_pbf_error(s, "A six digit millisecond could not be found", string, begin); + } else { + s->time->f = (f / 1000000); + } } break; case ' ': /* any sort of whitespace (' ' and \t) */ diff --git a/ext/date/lib/parse_date.c.orig b/ext/date/lib/parse_date.c.orig index bb101300d..f1aa4702c 100644 --- a/ext/date/lib/parse_date.c.orig +++ b/ext/date/lib/parse_date.c.orig @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.5 on Thu Dec 18 14:58:43 2008 */ +/* Generated by re2c 0.13.5 on Wed Jul 29 16:20:12 2009 */ #line 1 "ext/date/lib/parse_date.re" /* +----------------------------------------------------------------------+ @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: parse_date.c,v 1.29.2.30.2.14.2.29 2008/12/18 14:55:14 derick Exp $ */ +/* $Id: parse_date.c 286515 2009-07-29 15:34:59Z derick $ */ #include "timelib.h" @@ -24086,10 +24086,18 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim add_pbf_error(s, "A two digit second could not be found", string, begin); } break; - case 'u': /* five digit millisecond, with leading zero */ - TIMELIB_CHECK_NUMBER; - if ((s->time->f = timelib_get_nr((char **) &ptr, 5)) == TIMELIB_UNSET) { - add_pbf_error(s, "A five digit millisecond could not be found", string, begin); + case 'u': /* six digit millisecond */ + { + double f; + char *tptr; + + TIMELIB_CHECK_NUMBER; + tptr = ptr; + if ((f = timelib_get_nr((char **) &ptr, 6)) == TIMELIB_UNSET || ptr - tptr != 6) { + add_pbf_error(s, "A six digit millisecond could not be found", string, begin); + } else { + s->time->f = (f / 1000000); + } } break; case ' ': /* any sort of whitespace (' ' and \t) */ diff --git a/ext/date/lib/parse_date.re b/ext/date/lib/parse_date.re index e56dc6e4b..53966d898 100644 --- a/ext/date/lib/parse_date.re +++ b/ext/date/lib/parse_date.re @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: parse_date.re,v 1.26.2.27.2.12.2.26 2008/12/18 14:55:36 derick Exp $ */ +/* $Id: parse_date.re 286515 2009-07-29 15:34:59Z derick $ */ #include "timelib.h" @@ -1943,10 +1943,18 @@ timelib_time *timelib_parse_from_format(char *format, char *string, int len, tim add_pbf_error(s, "A two digit second could not be found", string, begin); } break; - case 'u': /* five digit millisecond, with leading zero */ - TIMELIB_CHECK_NUMBER; - if ((s->time->f = timelib_get_nr((char **) &ptr, 5)) == TIMELIB_UNSET) { - add_pbf_error(s, "A five digit millisecond could not be found", string, begin); + case 'u': /* six digit millisecond */ + { + double f; + char *tptr; + + TIMELIB_CHECK_NUMBER; + tptr = ptr; + if ((f = timelib_get_nr((char **) &ptr, 6)) == TIMELIB_UNSET || ptr - tptr != 6) { + add_pbf_error(s, "A six digit millisecond could not be found", string, begin); + } else { + s->time->f = (f / 1000000); + } } break; case ' ': /* any sort of whitespace (' ' and \t) */ diff --git a/ext/date/lib/parse_iso_intervals.c b/ext/date/lib/parse_iso_intervals.c index b2d536dc2..9a9483e11 100644 --- a/ext/date/lib/parse_iso_intervals.c +++ b/ext/date/lib/parse_iso_intervals.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: parse_iso_intervals.c,v 1.1.2.7 2009/05/05 07:45:18 derick Exp $ */ +/* $Id: parse_iso_intervals.c 279957 2009-05-05 07:45:18Z derick $ */ #include "timelib.h" diff --git a/ext/date/lib/parse_iso_intervals.re b/ext/date/lib/parse_iso_intervals.re index 0aa635cd6..78053a294 100644 --- a/ext/date/lib/parse_iso_intervals.re +++ b/ext/date/lib/parse_iso_intervals.re @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: parse_iso_intervals.re,v 1.1.2.4 2008/08/02 16:50:35 pajoye Exp $ */ +/* $Id: parse_iso_intervals.re 264095 2008-08-02 16:50:35Z pajoye $ */ #include "timelib.h" diff --git a/ext/date/lib/parse_tz.c b/ext/date/lib/parse_tz.c index daad423c3..ca7acea9f 100644 --- a/ext/date/lib/parse_tz.c +++ b/ext/date/lib/parse_tz.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: parse_tz.c,v 1.20.2.6.2.13.2.6 2009/04/25 16:33:41 nlopess Exp $ */ +/* $Id: parse_tz.c 279320 2009-04-25 16:33:41Z nlopess $ */ #include "timelib.h" diff --git a/ext/date/lib/timelib.c b/ext/date/lib/timelib.c index 620db2612..3b233dda9 100644 --- a/ext/date/lib/timelib.c +++ b/ext/date/lib/timelib.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: timelib.c,v 1.7.2.4.2.6.2.8 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: timelib.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "timelib.h" #include diff --git a/ext/date/lib/timelib.h b/ext/date/lib/timelib.h index 94cd767d5..acf7f70b3 100644 --- a/ext/date/lib/timelib.h +++ b/ext/date/lib/timelib.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: timelib.h,v 1.10.2.11.2.3.2.10 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: timelib.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef __TIMELIB_H__ #define __TIMELIB_H__ diff --git a/ext/date/lib/timelib.m4 b/ext/date/lib/timelib.m4 index c3b3a06d9..f1ec76071 100644 --- a/ext/date/lib/timelib.m4 +++ b/ext/date/lib/timelib.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: timelib.m4,v 1.4 2005/07/03 23:30:52 sniper Exp $ +dnl $Id: timelib.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl dnl dnl TL_DEF_HAVE(what [, why]) diff --git a/ext/date/lib/timelib_config.h.win32 b/ext/date/lib/timelib_config.h.win32 index 4f88201a6..379b3902f 100755 --- a/ext/date/lib/timelib_config.h.win32 +++ b/ext/date/lib/timelib_config.h.win32 @@ -1 +1 @@ -# include "config.w32.h" +# include "config.w32.h" diff --git a/ext/date/lib/timelib_structs.h b/ext/date/lib/timelib_structs.h index 4d356e0aa..733b8150c 100644 --- a/ext/date/lib/timelib_structs.h +++ b/ext/date/lib/timelib_structs.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: timelib_structs.h,v 1.13.2.6.2.3.2.11 2009/06/15 15:08:12 pajoye Exp $ */ +/* $Id: timelib_structs.h 282169 2009-06-15 15:08:12Z pajoye $ */ #ifndef __TIMELIB_STRUCTS_H__ #define __TIMELIB_STRUCTS_H__ diff --git a/ext/date/lib/timezonedb.h b/ext/date/lib/timezonedb.h index 5ba53c18b..c6c8abf53 100644 --- a/ext/date/lib/timezonedb.h +++ b/ext/date/lib/timezonedb.h @@ -1,4 +1,4 @@ -const timelib_tzdb_index_entry timezonedb_idx_builtin[560] = { +const timelib_tzdb_index_entry timezonedb_idx_builtin[561] = { { "Africa/Abidjan" , 0x000000 }, { "Africa/Accra" , 0x000055 }, { "Africa/Addis_Ababa" , 0x0000FD }, @@ -58,510 +58,511 @@ const timelib_tzdb_index_entry timezonedb_idx_builtin[560] = { { "America/Antigua" , 0x002837 }, { "America/Araguaina" , 0x00289D }, { "America/Argentina/Buenos_Aires" , 0x0029F8 }, - { "America/Argentina/Catamarca" , 0x002CC3 }, - { "America/Argentina/ComodRivadavia" , 0x002E84 }, - { "America/Argentina/Cordoba" , 0x00302A }, - { "America/Argentina/Jujuy" , 0x00331C }, - { "America/Argentina/La_Rioja" , 0x0034D0 }, - { "America/Argentina/Mendoza" , 0x003688 }, - { "America/Argentina/Rio_Gallegos" , 0x003848 }, - { "America/Argentina/Salta" , 0x0039FD }, - { "America/Argentina/San_Juan" , 0x003BA9 }, - { "America/Argentina/San_Luis" , 0x003D61 }, - { "America/Argentina/Tucuman" , 0x004035 }, - { "America/Argentina/Ushuaia" , 0x00430E }, - { "America/Aruba" , 0x0044C9 }, - { "America/Asuncion" , 0x00452F }, - { "America/Atikokan" , 0x004814 }, - { "America/Atka" , 0x0048EA }, - { "America/Bahia" , 0x004C50 }, - { "America/Barbados" , 0x004DD9 }, - { "America/Belem" , 0x004E73 }, - { "America/Belize" , 0x004F6E }, - { "America/Blanc-Sablon" , 0x0050EA }, - { "America/Boa_Vista" , 0x00519E }, - { "America/Bogota" , 0x0052A7 }, - { "America/Boise" , 0x005313 }, - { "America/Buenos_Aires" , 0x0056AA }, - { "America/Cambridge_Bay" , 0x005960 }, - { "America/Campo_Grande" , 0x005C88 }, - { "America/Cancun" , 0x005F77 }, - { "America/Caracas" , 0x0061B9 }, - { "America/Catamarca" , 0x006220 }, - { "America/Cayenne" , 0x0063C6 }, - { "America/Cayman" , 0x006428 }, - { "America/Chicago" , 0x00647D }, - { "America/Chihuahua" , 0x006994 }, - { "America/Coral_Harbour" , 0x006BE3 }, - { "America/Cordoba" , 0x006C75 }, - { "America/Costa_Rica" , 0x006F38 }, - { "America/Cuiaba" , 0x006FC2 }, - { "America/Curacao" , 0x0072A0 }, - { "America/Danmarkshavn" , 0x007306 }, - { "America/Dawson" , 0x00744A }, - { "America/Dawson_Creek" , 0x007767 }, - { "America/Denver" , 0x007941 }, - { "America/Detroit" , 0x007CC7 }, - { "America/Dominica" , 0x008026 }, - { "America/Edmonton" , 0x00807B }, - { "America/Eirunepe" , 0x008433 }, - { "America/El_Salvador" , 0x008546 }, - { "America/Ensenada" , 0x0085BB }, - { "America/Fort_Wayne" , 0x008A62 }, - { "America/Fortaleza" , 0x008924 }, - { "America/Glace_Bay" , 0x008CCC }, - { "America/Godthab" , 0x009043 }, - { "America/Goose_Bay" , 0x009307 }, - { "America/Grand_Turk" , 0x0097C4 }, - { "America/Grenada" , 0x009A73 }, - { "America/Guadeloupe" , 0x009AC8 }, - { "America/Guatemala" , 0x009B1D }, - { "America/Guayaquil" , 0x009BA6 }, - { "America/Guyana" , 0x009C03 }, - { "America/Halifax" , 0x009C84 }, - { "America/Havana" , 0x00A19A }, - { "America/Hermosillo" , 0x00A50D }, - { "America/Indiana/Indianapolis" , 0x00A5EB }, - { "America/Indiana/Knox" , 0x00A87C }, - { "America/Indiana/Marengo" , 0x00AC13 }, - { "America/Indiana/Petersburg" , 0x00AEB9 }, - { "America/Indiana/Tell_City" , 0x00B406 }, - { "America/Indiana/Vevay" , 0x00B69F }, - { "America/Indiana/Vincennes" , 0x00B8DA }, - { "America/Indiana/Winamac" , 0x00BB8E }, - { "America/Indianapolis" , 0x00B19C }, - { "America/Inuvik" , 0x00BE47 }, - { "America/Iqaluit" , 0x00C13E }, - { "America/Jamaica" , 0x00C460 }, - { "America/Jujuy" , 0x00C525 }, - { "America/Juneau" , 0x00C6CF }, - { "America/Kentucky/Louisville" , 0x00CA4D }, - { "America/Kentucky/Monticello" , 0x00CE6B }, - { "America/Knox_IN" , 0x00D1F0 }, - { "America/La_Paz" , 0x00D561 }, - { "America/Lima" , 0x00D5C8 }, - { "America/Los_Angeles" , 0x00D670 }, - { "America/Louisville" , 0x00DA81 }, - { "America/Maceio" , 0x00DE76 }, - { "America/Managua" , 0x00DFB0 }, - { "America/Manaus" , 0x00E063 }, - { "America/Marigot" , 0x00E165 }, - { "America/Martinique" , 0x00E1BA }, - { "America/Mazatlan" , 0x00E226 }, - { "America/Mendoza" , 0x00E493 }, - { "America/Menominee" , 0x00E647 }, - { "America/Merida" , 0x00E9C8 }, - { "America/Mexico_City" , 0x00EC03 }, - { "America/Miquelon" , 0x00EE7E }, - { "America/Moncton" , 0x00F0F0 }, - { "America/Monterrey" , 0x00F587 }, - { "America/Montevideo" , 0x00F7CE }, - { "America/Montreal" , 0x00FAE0 }, - { "America/Montserrat" , 0x00FFF6 }, - { "America/Nassau" , 0x01004B }, - { "America/New_York" , 0x010390 }, - { "America/Nipigon" , 0x01089B }, - { "America/Nome" , 0x010BEC }, - { "America/Noronha" , 0x010F6A }, - { "America/North_Dakota/Center" , 0x01109A }, - { "America/North_Dakota/New_Salem" , 0x01142E }, - { "America/Panama" , 0x0117D7 }, - { "America/Pangnirtung" , 0x01182C }, - { "America/Paramaribo" , 0x011B62 }, - { "America/Phoenix" , 0x011BF4 }, - { "America/Port-au-Prince" , 0x011CA2 }, - { "America/Port_of_Spain" , 0x011EBD }, - { "America/Porto_Acre" , 0x011DBE }, - { "America/Porto_Velho" , 0x011F12 }, - { "America/Puerto_Rico" , 0x012008 }, - { "America/Rainy_River" , 0x012073 }, - { "America/Rankin_Inlet" , 0x0123AB }, - { "America/Recife" , 0x012691 }, - { "America/Regina" , 0x0127BB }, - { "America/Resolute" , 0x012979 }, - { "America/Rio_Branco" , 0x012C72 }, - { "America/Rosario" , 0x012D75 }, - { "America/Santarem" , 0x013038 }, - { "America/Santiago" , 0x01313D }, - { "America/Santo_Domingo" , 0x0134E6 }, - { "America/Sao_Paulo" , 0x0135AC }, - { "America/Scoresbysund" , 0x0138BB }, - { "America/Shiprock" , 0x013BA9 }, - { "America/St_Barthelemy" , 0x013F38 }, - { "America/St_Johns" , 0x013F8D }, - { "America/St_Kitts" , 0x0144E0 }, - { "America/St_Lucia" , 0x014535 }, - { "America/St_Thomas" , 0x01458A }, - { "America/St_Vincent" , 0x0145DF }, - { "America/Swift_Current" , 0x014634 }, - { "America/Tegucigalpa" , 0x014755 }, - { "America/Thule" , 0x0147D4 }, - { "America/Thunder_Bay" , 0x014A1B }, - { "America/Tijuana" , 0x014D64 }, - { "America/Toronto" , 0x0150D9 }, - { "America/Tortola" , 0x0155F0 }, - { "America/Vancouver" , 0x015645 }, - { "America/Virgin" , 0x015A82 }, - { "America/Whitehorse" , 0x015AD7 }, - { "America/Winnipeg" , 0x015DF4 }, - { "America/Yakutat" , 0x016234 }, - { "America/Yellowknife" , 0x01659F }, - { "Antarctica/Casey" , 0x0168AF }, - { "Antarctica/Davis" , 0x016923 }, - { "Antarctica/DumontDUrville" , 0x0169A0 }, - { "Antarctica/Mawson" , 0x016A32 }, - { "Antarctica/McMurdo" , 0x016AA1 }, - { "Antarctica/Palmer" , 0x016DA3 }, - { "Antarctica/Rothera" , 0x0170BF }, - { "Antarctica/South_Pole" , 0x017135 }, - { "Antarctica/Syowa" , 0x01743D }, - { "Antarctica/Vostok" , 0x0174AB }, - { "Arctic/Longyearbyen" , 0x017520 }, - { "Asia/Aden" , 0x017852 }, - { "Asia/Almaty" , 0x0178A7 }, - { "Asia/Amman" , 0x017A26 }, - { "Asia/Anadyr" , 0x017CE6 }, - { "Asia/Aqtau" , 0x017FD4 }, - { "Asia/Aqtobe" , 0x0181D3 }, - { "Asia/Ashgabat" , 0x01838B }, - { "Asia/Ashkhabad" , 0x0184A8 }, - { "Asia/Baghdad" , 0x0185C5 }, - { "Asia/Bahrain" , 0x01873A }, - { "Asia/Baku" , 0x0187A0 }, - { "Asia/Bangkok" , 0x018A88 }, - { "Asia/Beirut" , 0x018ADD }, - { "Asia/Bishkek" , 0x018DEA }, - { "Asia/Brunei" , 0x018F96 }, - { "Asia/Calcutta" , 0x018FF8 }, - { "Asia/Choibalsan" , 0x019071 }, - { "Asia/Chongqing" , 0x0191EA }, - { "Asia/Chungking" , 0x0192D9 }, - { "Asia/Colombo" , 0x019388 }, - { "Asia/Dacca" , 0x019424 }, - { "Asia/Damascus" , 0x0194C5 }, - { "Asia/Dhaka" , 0x019815 }, - { "Asia/Dili" , 0x0198B6 }, - { "Asia/Dubai" , 0x01993F }, - { "Asia/Dushanbe" , 0x019994 }, - { "Asia/Gaza" , 0x019A97 }, - { "Asia/Harbin" , 0x019DE0 }, - { "Asia/Ho_Chi_Minh" , 0x019EC7 }, - { "Asia/Hong_Kong" , 0x019F3F }, - { "Asia/Hovd" , 0x01A0F5 }, - { "Asia/Irkutsk" , 0x01A26D }, - { "Asia/Istanbul" , 0x01A554 }, - { "Asia/Jakarta" , 0x01A941 }, - { "Asia/Jayapura" , 0x01A9EB }, - { "Asia/Jerusalem" , 0x01AA6F }, - { "Asia/Kabul" , 0x01AD9E }, - { "Asia/Kamchatka" , 0x01ADEF }, - { "Asia/Karachi" , 0x01B0D4 }, - { "Asia/Kashgar" , 0x01B189 }, - { "Asia/Kathmandu" , 0x01B25A }, - { "Asia/Katmandu" , 0x01B2C0 }, - { "Asia/Kolkata" , 0x01B326 }, - { "Asia/Krasnoyarsk" , 0x01B39F }, - { "Asia/Kuala_Lumpur" , 0x01B688 }, - { "Asia/Kuching" , 0x01B745 }, - { "Asia/Kuwait" , 0x01B833 }, - { "Asia/Macao" , 0x01B888 }, - { "Asia/Macau" , 0x01B9C3 }, - { "Asia/Magadan" , 0x01BAFE }, - { "Asia/Makassar" , 0x01BDE1 }, - { "Asia/Manila" , 0x01BE9A }, - { "Asia/Muscat" , 0x01BF1F }, - { "Asia/Nicosia" , 0x01BF74 }, - { "Asia/Novosibirsk" , 0x01C25C }, - { "Asia/Omsk" , 0x01C550 }, - { "Asia/Oral" , 0x01C838 }, - { "Asia/Phnom_Penh" , 0x01CA08 }, - { "Asia/Pontianak" , 0x01CA80 }, - { "Asia/Pyongyang" , 0x01CB41 }, - { "Asia/Qatar" , 0x01CBAE }, - { "Asia/Qyzylorda" , 0x01CC14 }, - { "Asia/Rangoon" , 0x01CDEA }, - { "Asia/Riyadh" , 0x01CE62 }, - { "Asia/Saigon" , 0x01CEB7 }, - { "Asia/Sakhalin" , 0x01CF2F }, - { "Asia/Samarkand" , 0x01D22F }, - { "Asia/Seoul" , 0x01D365 }, - { "Asia/Shanghai" , 0x01D409 }, - { "Asia/Singapore" , 0x01D4E9 }, - { "Asia/Taipei" , 0x01D5A0 }, - { "Asia/Tashkent" , 0x01D6B8 }, - { "Asia/Tbilisi" , 0x01D7E9 }, - { "Asia/Tehran" , 0x01D9A3 }, - { "Asia/Tel_Aviv" , 0x01DC11 }, - { "Asia/Thimbu" , 0x01DF40 }, - { "Asia/Thimphu" , 0x01DFA6 }, - { "Asia/Tokyo" , 0x01E00C }, - { "Asia/Ujung_Pandang" , 0x01E095 }, - { "Asia/Ulaanbaatar" , 0x01E111 }, - { "Asia/Ulan_Bator" , 0x01E26C }, - { "Asia/Urumqi" , 0x01E3B9 }, - { "Asia/Vientiane" , 0x01E480 }, - { "Asia/Vladivostok" , 0x01E4F8 }, - { "Asia/Yakutsk" , 0x01E7E5 }, - { "Asia/Yekaterinburg" , 0x01EACB }, - { "Asia/Yerevan" , 0x01EDD7 }, - { "Atlantic/Azores" , 0x01F0DB }, - { "Atlantic/Bermuda" , 0x01F5DE }, - { "Atlantic/Canary" , 0x01F8BF }, - { "Atlantic/Cape_Verde" , 0x01FB95 }, - { "Atlantic/Faeroe" , 0x01FC0E }, - { "Atlantic/Faroe" , 0x01FEB2 }, - { "Atlantic/Jan_Mayen" , 0x020156 }, - { "Atlantic/Madeira" , 0x020488 }, - { "Atlantic/Reykjavik" , 0x020991 }, - { "Atlantic/South_Georgia" , 0x020B4A }, - { "Atlantic/St_Helena" , 0x020E62 }, - { "Atlantic/Stanley" , 0x020B8E }, - { "Australia/ACT" , 0x020EB7 }, - { "Australia/Adelaide" , 0x0211D4 }, - { "Australia/Brisbane" , 0x021500 }, - { "Australia/Broken_Hill" , 0x0215C7 }, - { "Australia/Canberra" , 0x021905 }, - { "Australia/Currie" , 0x021C22 }, - { "Australia/Darwin" , 0x021F55 }, - { "Australia/Eucla" , 0x021FDB }, - { "Australia/Hobart" , 0x0220B0 }, - { "Australia/LHI" , 0x02240E }, - { "Australia/Lindeman" , 0x0226A9 }, - { "Australia/Lord_Howe" , 0x02278A }, - { "Australia/Melbourne" , 0x022A35 }, - { "Australia/North" , 0x022D5A }, - { "Australia/NSW" , 0x022DCE }, - { "Australia/Perth" , 0x0230EB }, - { "Australia/Queensland" , 0x0231C3 }, - { "Australia/South" , 0x02326F }, - { "Australia/Sydney" , 0x02358C }, - { "Australia/Tasmania" , 0x0238C9 }, - { "Australia/Victoria" , 0x023C0E }, - { "Australia/West" , 0x023F2B }, - { "Australia/Yancowinna" , 0x023FE1 }, - { "Brazil/Acre" , 0x024303 }, - { "Brazil/DeNoronha" , 0x024402 }, - { "Brazil/East" , 0x024522 }, - { "Brazil/West" , 0x0247FF }, - { "Canada/Atlantic" , 0x0248F7 }, - { "Canada/Central" , 0x024DDF }, - { "Canada/East-Saskatchewan" , 0x0256E9 }, - { "Canada/Eastern" , 0x0251F9 }, - { "Canada/Mountain" , 0x025872 }, - { "Canada/Newfoundland" , 0x025BE8 }, - { "Canada/Pacific" , 0x026113 }, - { "Canada/Saskatchewan" , 0x02652C }, - { "Canada/Yukon" , 0x0266B5 }, - { "CET" , 0x0269B8 }, - { "Chile/Continental" , 0x026CC1 }, - { "Chile/EasterIsland" , 0x02705C }, - { "CST6CDT" , 0x02739E }, - { "Cuba" , 0x0276EF }, - { "EET" , 0x027A62 }, - { "Egypt" , 0x027D15 }, - { "Eire" , 0x0280DC }, - { "EST" , 0x0285ED }, - { "EST5EDT" , 0x028631 }, - { "Etc/GMT" , 0x028982 }, - { "Etc/GMT+0" , 0x028A4E }, - { "Etc/GMT+1" , 0x028AD8 }, - { "Etc/GMT+10" , 0x028B65 }, - { "Etc/GMT+11" , 0x028BF3 }, - { "Etc/GMT+12" , 0x028C81 }, - { "Etc/GMT+2" , 0x028D9C }, - { "Etc/GMT+3" , 0x028E28 }, - { "Etc/GMT+4" , 0x028EB4 }, - { "Etc/GMT+5" , 0x028F40 }, - { "Etc/GMT+6" , 0x028FCC }, - { "Etc/GMT+7" , 0x029058 }, - { "Etc/GMT+8" , 0x0290E4 }, - { "Etc/GMT+9" , 0x029170 }, - { "Etc/GMT-0" , 0x028A0A }, - { "Etc/GMT-1" , 0x028A92 }, - { "Etc/GMT-10" , 0x028B1E }, - { "Etc/GMT-11" , 0x028BAC }, - { "Etc/GMT-12" , 0x028C3A }, - { "Etc/GMT-13" , 0x028CC8 }, - { "Etc/GMT-14" , 0x028D0F }, - { "Etc/GMT-2" , 0x028D56 }, - { "Etc/GMT-3" , 0x028DE2 }, - { "Etc/GMT-4" , 0x028E6E }, - { "Etc/GMT-5" , 0x028EFA }, - { "Etc/GMT-6" , 0x028F86 }, - { "Etc/GMT-7" , 0x029012 }, - { "Etc/GMT-8" , 0x02909E }, - { "Etc/GMT-9" , 0x02912A }, - { "Etc/GMT0" , 0x0289C6 }, - { "Etc/Greenwich" , 0x0291B6 }, - { "Etc/UCT" , 0x0291FA }, - { "Etc/Universal" , 0x02923E }, - { "Etc/UTC" , 0x029282 }, - { "Etc/Zulu" , 0x0292C6 }, - { "Europe/Amsterdam" , 0x02930A }, - { "Europe/Andorra" , 0x029748 }, - { "Europe/Athens" , 0x0299C4 }, - { "Europe/Belfast" , 0x029D07 }, - { "Europe/Belgrade" , 0x02A23E }, - { "Europe/Berlin" , 0x02A507 }, - { "Europe/Bratislava" , 0x02A85D }, - { "Europe/Brussels" , 0x02AB8F }, - { "Europe/Bucharest" , 0x02AFC6 }, - { "Europe/Budapest" , 0x02B2F0 }, - { "Europe/Chisinau" , 0x02B663 }, - { "Europe/Copenhagen" , 0x02B9F1 }, - { "Europe/Dublin" , 0x02BCFB }, - { "Europe/Gibraltar" , 0x02C20C }, - { "Europe/Guernsey" , 0x02C663 }, - { "Europe/Helsinki" , 0x02CB9A }, - { "Europe/Isle_of_Man" , 0x02CE50 }, - { "Europe/Istanbul" , 0x02D387 }, - { "Europe/Jersey" , 0x02D774 }, - { "Europe/Kaliningrad" , 0x02DCAB }, - { "Europe/Kiev" , 0x02E00E }, - { "Europe/Lisbon" , 0x02E325 }, - { "Europe/Ljubljana" , 0x02E829 }, - { "Europe/London" , 0x02EAF2 }, - { "Europe/Luxembourg" , 0x02F029 }, - { "Europe/Madrid" , 0x02F47F }, - { "Europe/Malta" , 0x02F845 }, - { "Europe/Mariehamn" , 0x02FBFE }, - { "Europe/Minsk" , 0x02FEB4 }, - { "Europe/Monaco" , 0x0301BF }, - { "Europe/Moscow" , 0x0305FA }, - { "Europe/Nicosia" , 0x03094C }, - { "Europe/Oslo" , 0x030C34 }, - { "Europe/Paris" , 0x030F66 }, - { "Europe/Podgorica" , 0x0313AC }, - { "Europe/Prague" , 0x031675 }, - { "Europe/Riga" , 0x0319A7 }, - { "Europe/Rome" , 0x031CEC }, - { "Europe/Samara" , 0x0320AF }, - { "Europe/San_Marino" , 0x0323DB }, - { "Europe/Sarajevo" , 0x03279E }, - { "Europe/Simferopol" , 0x032A67 }, - { "Europe/Skopje" , 0x032D92 }, - { "Europe/Sofia" , 0x03305B }, - { "Europe/Stockholm" , 0x033363 }, - { "Europe/Tallinn" , 0x033612 }, - { "Europe/Tirane" , 0x03394C }, - { "Europe/Tiraspol" , 0x033C52 }, - { "Europe/Uzhgorod" , 0x033FE0 }, - { "Europe/Vaduz" , 0x0342F7 }, - { "Europe/Vatican" , 0x03458A }, - { "Europe/Vienna" , 0x03494D }, - { "Europe/Vilnius" , 0x034C7A }, - { "Europe/Volgograd" , 0x034FB9 }, - { "Europe/Warsaw" , 0x0352C2 }, - { "Europe/Zagreb" , 0x0356A3 }, - { "Europe/Zaporozhye" , 0x03596C }, - { "Europe/Zurich" , 0x035CAD }, - { "Factory" , 0x035F5C }, - { "GB" , 0x035FCD }, - { "GB-Eire" , 0x036504 }, - { "GMT" , 0x036A3B }, - { "GMT+0" , 0x036B07 }, - { "GMT-0" , 0x036AC3 }, - { "GMT0" , 0x036A7F }, - { "Greenwich" , 0x036B4B }, - { "Hongkong" , 0x036B8F }, - { "HST" , 0x036D45 }, - { "Iceland" , 0x036D89 }, - { "Indian/Antananarivo" , 0x036F42 }, - { "Indian/Chagos" , 0x036FB6 }, - { "Indian/Christmas" , 0x037018 }, - { "Indian/Cocos" , 0x03705C }, - { "Indian/Comoro" , 0x0370A0 }, - { "Indian/Kerguelen" , 0x0370F5 }, - { "Indian/Mahe" , 0x03714A }, - { "Indian/Maldives" , 0x03719F }, - { "Indian/Mauritius" , 0x0371F4 }, - { "Indian/Mayotte" , 0x037397 }, - { "Indian/Reunion" , 0x0373EC }, - { "Iran" , 0x037441 }, - { "Israel" , 0x0376AF }, - { "Jamaica" , 0x0379DE }, - { "Japan" , 0x037AA3 }, - { "Kwajalein" , 0x037B2C }, - { "Libya" , 0x037B8F }, - { "MET" , 0x037C89 }, - { "Mexico/BajaNorte" , 0x037F92 }, - { "Mexico/BajaSur" , 0x0382FB }, - { "Mexico/General" , 0x038540 }, - { "MST" , 0x03879E }, - { "MST7MDT" , 0x0387E2 }, - { "Navajo" , 0x038B33 }, - { "NZ" , 0x038EAC }, - { "NZ-CHAT" , 0x03922A }, - { "Pacific/Apia" , 0x039512 }, - { "Pacific/Auckland" , 0x039579 }, - { "Pacific/Chatham" , 0x039905 }, - { "Pacific/Easter" , 0x039BFC }, - { "Pacific/Efate" , 0x039F5A }, - { "Pacific/Enderbury" , 0x03A020 }, - { "Pacific/Fakaofo" , 0x03A08E }, - { "Pacific/Fiji" , 0x03A0D2 }, - { "Pacific/Funafuti" , 0x03A148 }, - { "Pacific/Galapagos" , 0x03A18C }, - { "Pacific/Gambier" , 0x03A204 }, - { "Pacific/Guadalcanal" , 0x03A269 }, - { "Pacific/Guam" , 0x03A2BE }, - { "Pacific/Honolulu" , 0x03A314 }, - { "Pacific/Johnston" , 0x03A3A8 }, - { "Pacific/Kiritimati" , 0x03A3FA }, - { "Pacific/Kosrae" , 0x03A465 }, - { "Pacific/Kwajalein" , 0x03A4C2 }, - { "Pacific/Majuro" , 0x03A52E }, - { "Pacific/Marquesas" , 0x03A58D }, - { "Pacific/Midway" , 0x03A5F4 }, - { "Pacific/Nauru" , 0x03A67E }, - { "Pacific/Niue" , 0x03A6F6 }, - { "Pacific/Norfolk" , 0x03A754 }, - { "Pacific/Noumea" , 0x03A7A9 }, - { "Pacific/Pago_Pago" , 0x03A839 }, - { "Pacific/Palau" , 0x03A8C2 }, - { "Pacific/Pitcairn" , 0x03A906 }, - { "Pacific/Ponape" , 0x03A95B }, - { "Pacific/Port_Moresby" , 0x03A9B0 }, - { "Pacific/Rarotonga" , 0x03A9F4 }, - { "Pacific/Saipan" , 0x03AAD0 }, - { "Pacific/Samoa" , 0x03AB33 }, - { "Pacific/Tahiti" , 0x03ABBC }, - { "Pacific/Tarawa" , 0x03AC21 }, - { "Pacific/Tongatapu" , 0x03AC75 }, - { "Pacific/Truk" , 0x03AD01 }, - { "Pacific/Wake" , 0x03AD5A }, - { "Pacific/Wallis" , 0x03ADAA }, - { "Pacific/Yap" , 0x03ADEE }, - { "Poland" , 0x03AE33 }, - { "Portugal" , 0x03B214 }, - { "PRC" , 0x03B710 }, - { "PST8PDT" , 0x03B7C1 }, - { "ROC" , 0x03BB12 }, - { "ROK" , 0x03BC2A }, - { "Singapore" , 0x03BCCE }, - { "Turkey" , 0x03BD85 }, - { "UCT" , 0x03C172 }, - { "Universal" , 0x03C1B6 }, - { "US/Alaska" , 0x03C1FA }, - { "US/Aleutian" , 0x03C563 }, - { "US/Arizona" , 0x03C8C9 }, - { "US/Central" , 0x03C957 }, - { "US/East-Indiana" , 0x03D361 }, - { "US/Eastern" , 0x03CE62 }, - { "US/Hawaii" , 0x03D5CB }, - { "US/Indiana-Starke" , 0x03D659 }, - { "US/Michigan" , 0x03D9CA }, - { "US/Mountain" , 0x03DD01 }, - { "US/Pacific" , 0x03E07A }, - { "US/Pacific-New" , 0x03E47F }, - { "US/Samoa" , 0x03E884 }, - { "UTC" , 0x03E90D }, - { "W-SU" , 0x03EC04 }, - { "WET" , 0x03E951 }, - { "Zulu" , 0x03EF3F }, + { "America/Argentina/Catamarca" , 0x002BA6 }, + { "America/Argentina/ComodRivadavia" , 0x002D67 }, + { "America/Argentina/Cordoba" , 0x002F0D }, + { "America/Argentina/Jujuy" , 0x0030E2 }, + { "America/Argentina/La_Rioja" , 0x003296 }, + { "America/Argentina/Mendoza" , 0x00344E }, + { "America/Argentina/Rio_Gallegos" , 0x00360E }, + { "America/Argentina/Salta" , 0x0037C3 }, + { "America/Argentina/San_Juan" , 0x00396F }, + { "America/Argentina/San_Luis" , 0x003B27 }, + { "America/Argentina/Tucuman" , 0x003E05 }, + { "America/Argentina/Ushuaia" , 0x003FC1 }, + { "America/Aruba" , 0x00417C }, + { "America/Asuncion" , 0x0041E2 }, + { "America/Atikokan" , 0x0044C7 }, + { "America/Atka" , 0x00459D }, + { "America/Bahia" , 0x004903 }, + { "America/Barbados" , 0x004A8C }, + { "America/Belem" , 0x004B26 }, + { "America/Belize" , 0x004C21 }, + { "America/Blanc-Sablon" , 0x004D9D }, + { "America/Boa_Vista" , 0x004E51 }, + { "America/Bogota" , 0x004F5A }, + { "America/Boise" , 0x004FC6 }, + { "America/Buenos_Aires" , 0x00535D }, + { "America/Cambridge_Bay" , 0x0054F6 }, + { "America/Campo_Grande" , 0x00581E }, + { "America/Cancun" , 0x005B0D }, + { "America/Caracas" , 0x005D4F }, + { "America/Catamarca" , 0x005DB6 }, + { "America/Cayenne" , 0x005F5C }, + { "America/Cayman" , 0x005FBE }, + { "America/Chicago" , 0x006013 }, + { "America/Chihuahua" , 0x00652A }, + { "America/Coral_Harbour" , 0x006779 }, + { "America/Cordoba" , 0x00680B }, + { "America/Costa_Rica" , 0x0069B1 }, + { "America/Cuiaba" , 0x006A3B }, + { "America/Curacao" , 0x006D19 }, + { "America/Danmarkshavn" , 0x006D7F }, + { "America/Dawson" , 0x006EC3 }, + { "America/Dawson_Creek" , 0x0071E0 }, + { "America/Denver" , 0x0073BA }, + { "America/Detroit" , 0x007740 }, + { "America/Dominica" , 0x007A9F }, + { "America/Edmonton" , 0x007AF4 }, + { "America/Eirunepe" , 0x007EAC }, + { "America/El_Salvador" , 0x007FBF }, + { "America/Ensenada" , 0x008034 }, + { "America/Fort_Wayne" , 0x0084DB }, + { "America/Fortaleza" , 0x00839D }, + { "America/Glace_Bay" , 0x008745 }, + { "America/Godthab" , 0x008ABC }, + { "America/Goose_Bay" , 0x008D80 }, + { "America/Grand_Turk" , 0x00923D }, + { "America/Grenada" , 0x0094EC }, + { "America/Guadeloupe" , 0x009541 }, + { "America/Guatemala" , 0x009596 }, + { "America/Guayaquil" , 0x00961F }, + { "America/Guyana" , 0x00967C }, + { "America/Halifax" , 0x0096FD }, + { "America/Havana" , 0x009C13 }, + { "America/Hermosillo" , 0x009F86 }, + { "America/Indiana/Indianapolis" , 0x00A064 }, + { "America/Indiana/Knox" , 0x00A2F5 }, + { "America/Indiana/Marengo" , 0x00A68C }, + { "America/Indiana/Petersburg" , 0x00A932 }, + { "America/Indiana/Tell_City" , 0x00AE7F }, + { "America/Indiana/Vevay" , 0x00B118 }, + { "America/Indiana/Vincennes" , 0x00B353 }, + { "America/Indiana/Winamac" , 0x00B607 }, + { "America/Indianapolis" , 0x00AC15 }, + { "America/Inuvik" , 0x00B8C0 }, + { "America/Iqaluit" , 0x00BBB7 }, + { "America/Jamaica" , 0x00BED9 }, + { "America/Jujuy" , 0x00BF9E }, + { "America/Juneau" , 0x00C148 }, + { "America/Kentucky/Louisville" , 0x00C4C6 }, + { "America/Kentucky/Monticello" , 0x00C8E4 }, + { "America/Knox_IN" , 0x00CC69 }, + { "America/La_Paz" , 0x00CFDA }, + { "America/Lima" , 0x00D041 }, + { "America/Los_Angeles" , 0x00D0E9 }, + { "America/Louisville" , 0x00D4FA }, + { "America/Maceio" , 0x00D8EF }, + { "America/Managua" , 0x00DA29 }, + { "America/Manaus" , 0x00DADC }, + { "America/Marigot" , 0x00DBDE }, + { "America/Martinique" , 0x00DC33 }, + { "America/Mazatlan" , 0x00DC9F }, + { "America/Mendoza" , 0x00DF0C }, + { "America/Menominee" , 0x00E0C0 }, + { "America/Merida" , 0x00E441 }, + { "America/Mexico_City" , 0x00E67C }, + { "America/Miquelon" , 0x00E8F7 }, + { "America/Moncton" , 0x00EB69 }, + { "America/Monterrey" , 0x00F000 }, + { "America/Montevideo" , 0x00F247 }, + { "America/Montreal" , 0x00F559 }, + { "America/Montserrat" , 0x00FA6F }, + { "America/Nassau" , 0x00FAC4 }, + { "America/New_York" , 0x00FE09 }, + { "America/Nipigon" , 0x010314 }, + { "America/Nome" , 0x010665 }, + { "America/Noronha" , 0x0109E3 }, + { "America/North_Dakota/Center" , 0x010B13 }, + { "America/North_Dakota/New_Salem" , 0x010EA7 }, + { "America/Panama" , 0x011250 }, + { "America/Pangnirtung" , 0x0112A5 }, + { "America/Paramaribo" , 0x0115DB }, + { "America/Phoenix" , 0x01166D }, + { "America/Port-au-Prince" , 0x01171B }, + { "America/Port_of_Spain" , 0x011936 }, + { "America/Porto_Acre" , 0x011837 }, + { "America/Porto_Velho" , 0x01198B }, + { "America/Puerto_Rico" , 0x011A81 }, + { "America/Rainy_River" , 0x011AEC }, + { "America/Rankin_Inlet" , 0x011E24 }, + { "America/Recife" , 0x01210A }, + { "America/Regina" , 0x012234 }, + { "America/Resolute" , 0x0123F2 }, + { "America/Rio_Branco" , 0x0126EB }, + { "America/Rosario" , 0x0127EE }, + { "America/Santarem" , 0x012994 }, + { "America/Santiago" , 0x012A99 }, + { "America/Santo_Domingo" , 0x012E42 }, + { "America/Sao_Paulo" , 0x012F08 }, + { "America/Scoresbysund" , 0x013217 }, + { "America/Shiprock" , 0x013505 }, + { "America/St_Barthelemy" , 0x013894 }, + { "America/St_Johns" , 0x0138E9 }, + { "America/St_Kitts" , 0x013E3C }, + { "America/St_Lucia" , 0x013E91 }, + { "America/St_Thomas" , 0x013EE6 }, + { "America/St_Vincent" , 0x013F3B }, + { "America/Swift_Current" , 0x013F90 }, + { "America/Tegucigalpa" , 0x0140B1 }, + { "America/Thule" , 0x014130 }, + { "America/Thunder_Bay" , 0x014377 }, + { "America/Tijuana" , 0x0146C0 }, + { "America/Toronto" , 0x014A35 }, + { "America/Tortola" , 0x014F4C }, + { "America/Vancouver" , 0x014FA1 }, + { "America/Virgin" , 0x0153DE }, + { "America/Whitehorse" , 0x015433 }, + { "America/Winnipeg" , 0x015750 }, + { "America/Yakutat" , 0x015B90 }, + { "America/Yellowknife" , 0x015EFB }, + { "Antarctica/Casey" , 0x01620B }, + { "Antarctica/Davis" , 0x016291 }, + { "Antarctica/DumontDUrville" , 0x01631B }, + { "Antarctica/Mawson" , 0x0163AD }, + { "Antarctica/McMurdo" , 0x016429 }, + { "Antarctica/Palmer" , 0x01672B }, + { "Antarctica/Rothera" , 0x016A47 }, + { "Antarctica/South_Pole" , 0x016ABD }, + { "Antarctica/Syowa" , 0x016DC5 }, + { "Antarctica/Vostok" , 0x016E33 }, + { "Arctic/Longyearbyen" , 0x016EA8 }, + { "Asia/Aden" , 0x0171DA }, + { "Asia/Almaty" , 0x01722F }, + { "Asia/Amman" , 0x0173AE }, + { "Asia/Anadyr" , 0x01766E }, + { "Asia/Aqtau" , 0x01795C }, + { "Asia/Aqtobe" , 0x017B5B }, + { "Asia/Ashgabat" , 0x017D13 }, + { "Asia/Ashkhabad" , 0x017E30 }, + { "Asia/Baghdad" , 0x017F4D }, + { "Asia/Bahrain" , 0x0180C2 }, + { "Asia/Baku" , 0x018128 }, + { "Asia/Bangkok" , 0x018410 }, + { "Asia/Beirut" , 0x018465 }, + { "Asia/Bishkek" , 0x018772 }, + { "Asia/Brunei" , 0x01891E }, + { "Asia/Calcutta" , 0x018980 }, + { "Asia/Choibalsan" , 0x0189F9 }, + { "Asia/Chongqing" , 0x018B72 }, + { "Asia/Chungking" , 0x018C61 }, + { "Asia/Colombo" , 0x018D10 }, + { "Asia/Dacca" , 0x018DAC }, + { "Asia/Damascus" , 0x018E4D }, + { "Asia/Dhaka" , 0x01919D }, + { "Asia/Dili" , 0x01923E }, + { "Asia/Dubai" , 0x0192C7 }, + { "Asia/Dushanbe" , 0x01931C }, + { "Asia/Gaza" , 0x01941F }, + { "Asia/Harbin" , 0x019768 }, + { "Asia/Ho_Chi_Minh" , 0x01984F }, + { "Asia/Hong_Kong" , 0x0198C7 }, + { "Asia/Hovd" , 0x019A93 }, + { "Asia/Irkutsk" , 0x019C0B }, + { "Asia/Istanbul" , 0x019EF2 }, + { "Asia/Jakarta" , 0x01A2DF }, + { "Asia/Jayapura" , 0x01A389 }, + { "Asia/Jerusalem" , 0x01A40D }, + { "Asia/Kabul" , 0x01A73C }, + { "Asia/Kamchatka" , 0x01A78D }, + { "Asia/Karachi" , 0x01AA72 }, + { "Asia/Kashgar" , 0x01AC3F }, + { "Asia/Kathmandu" , 0x01AD10 }, + { "Asia/Katmandu" , 0x01AD76 }, + { "Asia/Kolkata" , 0x01ADDC }, + { "Asia/Krasnoyarsk" , 0x01AE55 }, + { "Asia/Kuala_Lumpur" , 0x01B13E }, + { "Asia/Kuching" , 0x01B1FB }, + { "Asia/Kuwait" , 0x01B2E9 }, + { "Asia/Macao" , 0x01B33E }, + { "Asia/Macau" , 0x01B479 }, + { "Asia/Magadan" , 0x01B5B4 }, + { "Asia/Makassar" , 0x01B897 }, + { "Asia/Manila" , 0x01B950 }, + { "Asia/Muscat" , 0x01B9D5 }, + { "Asia/Nicosia" , 0x01BA2A }, + { "Asia/Novokuznetsk" , 0x01BD12 }, + { "Asia/Novosibirsk" , 0x01C015 }, + { "Asia/Omsk" , 0x01C309 }, + { "Asia/Oral" , 0x01C5F1 }, + { "Asia/Phnom_Penh" , 0x01C7C1 }, + { "Asia/Pontianak" , 0x01C839 }, + { "Asia/Pyongyang" , 0x01C8FA }, + { "Asia/Qatar" , 0x01C967 }, + { "Asia/Qyzylorda" , 0x01C9CD }, + { "Asia/Rangoon" , 0x01CBA3 }, + { "Asia/Riyadh" , 0x01CC1B }, + { "Asia/Saigon" , 0x01CC70 }, + { "Asia/Sakhalin" , 0x01CCE8 }, + { "Asia/Samarkand" , 0x01CFE8 }, + { "Asia/Seoul" , 0x01D11E }, + { "Asia/Shanghai" , 0x01D1C2 }, + { "Asia/Singapore" , 0x01D2A2 }, + { "Asia/Taipei" , 0x01D359 }, + { "Asia/Tashkent" , 0x01D471 }, + { "Asia/Tbilisi" , 0x01D5A2 }, + { "Asia/Tehran" , 0x01D75C }, + { "Asia/Tel_Aviv" , 0x01D9CA }, + { "Asia/Thimbu" , 0x01DCF9 }, + { "Asia/Thimphu" , 0x01DD5F }, + { "Asia/Tokyo" , 0x01DDC5 }, + { "Asia/Ujung_Pandang" , 0x01DE4E }, + { "Asia/Ulaanbaatar" , 0x01DECA }, + { "Asia/Ulan_Bator" , 0x01E025 }, + { "Asia/Urumqi" , 0x01E172 }, + { "Asia/Vientiane" , 0x01E239 }, + { "Asia/Vladivostok" , 0x01E2B1 }, + { "Asia/Yakutsk" , 0x01E59E }, + { "Asia/Yekaterinburg" , 0x01E884 }, + { "Asia/Yerevan" , 0x01EB90 }, + { "Atlantic/Azores" , 0x01EE94 }, + { "Atlantic/Bermuda" , 0x01F397 }, + { "Atlantic/Canary" , 0x01F678 }, + { "Atlantic/Cape_Verde" , 0x01F94E }, + { "Atlantic/Faeroe" , 0x01F9C7 }, + { "Atlantic/Faroe" , 0x01FC6B }, + { "Atlantic/Jan_Mayen" , 0x01FF0F }, + { "Atlantic/Madeira" , 0x020241 }, + { "Atlantic/Reykjavik" , 0x02074A }, + { "Atlantic/South_Georgia" , 0x020903 }, + { "Atlantic/St_Helena" , 0x020C1B }, + { "Atlantic/Stanley" , 0x020947 }, + { "Australia/ACT" , 0x020C70 }, + { "Australia/Adelaide" , 0x020F8D }, + { "Australia/Brisbane" , 0x0212B9 }, + { "Australia/Broken_Hill" , 0x021380 }, + { "Australia/Canberra" , 0x0216BE }, + { "Australia/Currie" , 0x0219DB }, + { "Australia/Darwin" , 0x021D0E }, + { "Australia/Eucla" , 0x021D94 }, + { "Australia/Hobart" , 0x021E69 }, + { "Australia/LHI" , 0x0221C7 }, + { "Australia/Lindeman" , 0x022462 }, + { "Australia/Lord_Howe" , 0x022543 }, + { "Australia/Melbourne" , 0x0227EE }, + { "Australia/North" , 0x022B13 }, + { "Australia/NSW" , 0x022B87 }, + { "Australia/Perth" , 0x022EA4 }, + { "Australia/Queensland" , 0x022F7C }, + { "Australia/South" , 0x023028 }, + { "Australia/Sydney" , 0x023345 }, + { "Australia/Tasmania" , 0x023682 }, + { "Australia/Victoria" , 0x0239C7 }, + { "Australia/West" , 0x023CE4 }, + { "Australia/Yancowinna" , 0x023D9A }, + { "Brazil/Acre" , 0x0240BC }, + { "Brazil/DeNoronha" , 0x0241BB }, + { "Brazil/East" , 0x0242DB }, + { "Brazil/West" , 0x0245B8 }, + { "Canada/Atlantic" , 0x0246B0 }, + { "Canada/Central" , 0x024B98 }, + { "Canada/East-Saskatchewan" , 0x0254A2 }, + { "Canada/Eastern" , 0x024FB2 }, + { "Canada/Mountain" , 0x02562B }, + { "Canada/Newfoundland" , 0x0259A1 }, + { "Canada/Pacific" , 0x025ECC }, + { "Canada/Saskatchewan" , 0x0262E5 }, + { "Canada/Yukon" , 0x02646E }, + { "CET" , 0x026771 }, + { "Chile/Continental" , 0x026A7A }, + { "Chile/EasterIsland" , 0x026E15 }, + { "CST6CDT" , 0x027157 }, + { "Cuba" , 0x0274A8 }, + { "EET" , 0x02781B }, + { "Egypt" , 0x027ACE }, + { "Eire" , 0x027E95 }, + { "EST" , 0x0283A6 }, + { "EST5EDT" , 0x0283EA }, + { "Etc/GMT" , 0x02873B }, + { "Etc/GMT+0" , 0x028807 }, + { "Etc/GMT+1" , 0x028891 }, + { "Etc/GMT+10" , 0x02891E }, + { "Etc/GMT+11" , 0x0289AC }, + { "Etc/GMT+12" , 0x028A3A }, + { "Etc/GMT+2" , 0x028B55 }, + { "Etc/GMT+3" , 0x028BE1 }, + { "Etc/GMT+4" , 0x028C6D }, + { "Etc/GMT+5" , 0x028CF9 }, + { "Etc/GMT+6" , 0x028D85 }, + { "Etc/GMT+7" , 0x028E11 }, + { "Etc/GMT+8" , 0x028E9D }, + { "Etc/GMT+9" , 0x028F29 }, + { "Etc/GMT-0" , 0x0287C3 }, + { "Etc/GMT-1" , 0x02884B }, + { "Etc/GMT-10" , 0x0288D7 }, + { "Etc/GMT-11" , 0x028965 }, + { "Etc/GMT-12" , 0x0289F3 }, + { "Etc/GMT-13" , 0x028A81 }, + { "Etc/GMT-14" , 0x028AC8 }, + { "Etc/GMT-2" , 0x028B0F }, + { "Etc/GMT-3" , 0x028B9B }, + { "Etc/GMT-4" , 0x028C27 }, + { "Etc/GMT-5" , 0x028CB3 }, + { "Etc/GMT-6" , 0x028D3F }, + { "Etc/GMT-7" , 0x028DCB }, + { "Etc/GMT-8" , 0x028E57 }, + { "Etc/GMT-9" , 0x028EE3 }, + { "Etc/GMT0" , 0x02877F }, + { "Etc/Greenwich" , 0x028F6F }, + { "Etc/UCT" , 0x028FB3 }, + { "Etc/Universal" , 0x028FF7 }, + { "Etc/UTC" , 0x02903B }, + { "Etc/Zulu" , 0x02907F }, + { "Europe/Amsterdam" , 0x0290C3 }, + { "Europe/Andorra" , 0x029501 }, + { "Europe/Athens" , 0x02977D }, + { "Europe/Belfast" , 0x029AC0 }, + { "Europe/Belgrade" , 0x029FF7 }, + { "Europe/Berlin" , 0x02A2C0 }, + { "Europe/Bratislava" , 0x02A616 }, + { "Europe/Brussels" , 0x02A948 }, + { "Europe/Bucharest" , 0x02AD7F }, + { "Europe/Budapest" , 0x02B0A9 }, + { "Europe/Chisinau" , 0x02B41C }, + { "Europe/Copenhagen" , 0x02B7AA }, + { "Europe/Dublin" , 0x02BAB4 }, + { "Europe/Gibraltar" , 0x02BFC5 }, + { "Europe/Guernsey" , 0x02C41C }, + { "Europe/Helsinki" , 0x02C953 }, + { "Europe/Isle_of_Man" , 0x02CC09 }, + { "Europe/Istanbul" , 0x02D140 }, + { "Europe/Jersey" , 0x02D52D }, + { "Europe/Kaliningrad" , 0x02DA64 }, + { "Europe/Kiev" , 0x02DDC7 }, + { "Europe/Lisbon" , 0x02E0DE }, + { "Europe/Ljubljana" , 0x02E5E2 }, + { "Europe/London" , 0x02E8AB }, + { "Europe/Luxembourg" , 0x02EDE2 }, + { "Europe/Madrid" , 0x02F238 }, + { "Europe/Malta" , 0x02F5FE }, + { "Europe/Mariehamn" , 0x02F9B7 }, + { "Europe/Minsk" , 0x02FC6D }, + { "Europe/Monaco" , 0x02FF78 }, + { "Europe/Moscow" , 0x0303B3 }, + { "Europe/Nicosia" , 0x030705 }, + { "Europe/Oslo" , 0x0309ED }, + { "Europe/Paris" , 0x030D1F }, + { "Europe/Podgorica" , 0x031165 }, + { "Europe/Prague" , 0x03142E }, + { "Europe/Riga" , 0x031760 }, + { "Europe/Rome" , 0x031AA5 }, + { "Europe/Samara" , 0x031E68 }, + { "Europe/San_Marino" , 0x032194 }, + { "Europe/Sarajevo" , 0x032557 }, + { "Europe/Simferopol" , 0x032820 }, + { "Europe/Skopje" , 0x032B4B }, + { "Europe/Sofia" , 0x032E14 }, + { "Europe/Stockholm" , 0x03311C }, + { "Europe/Tallinn" , 0x0333CB }, + { "Europe/Tirane" , 0x033705 }, + { "Europe/Tiraspol" , 0x033A0B }, + { "Europe/Uzhgorod" , 0x033D99 }, + { "Europe/Vaduz" , 0x0340B0 }, + { "Europe/Vatican" , 0x034343 }, + { "Europe/Vienna" , 0x034706 }, + { "Europe/Vilnius" , 0x034A33 }, + { "Europe/Volgograd" , 0x034D72 }, + { "Europe/Warsaw" , 0x03507B }, + { "Europe/Zagreb" , 0x03545C }, + { "Europe/Zaporozhye" , 0x035725 }, + { "Europe/Zurich" , 0x035A66 }, + { "Factory" , 0x035D15 }, + { "GB" , 0x035D86 }, + { "GB-Eire" , 0x0362BD }, + { "GMT" , 0x0367F4 }, + { "GMT+0" , 0x0368C0 }, + { "GMT-0" , 0x03687C }, + { "GMT0" , 0x036838 }, + { "Greenwich" , 0x036904 }, + { "Hongkong" , 0x036948 }, + { "HST" , 0x036B14 }, + { "Iceland" , 0x036B58 }, + { "Indian/Antananarivo" , 0x036D11 }, + { "Indian/Chagos" , 0x036D85 }, + { "Indian/Christmas" , 0x036DE7 }, + { "Indian/Cocos" , 0x036E2B }, + { "Indian/Comoro" , 0x036E6F }, + { "Indian/Kerguelen" , 0x036EC4 }, + { "Indian/Mahe" , 0x036F19 }, + { "Indian/Maldives" , 0x036F6E }, + { "Indian/Mauritius" , 0x036FC3 }, + { "Indian/Mayotte" , 0x037039 }, + { "Indian/Reunion" , 0x03708E }, + { "Iran" , 0x0370E3 }, + { "Israel" , 0x037351 }, + { "Jamaica" , 0x037680 }, + { "Japan" , 0x037745 }, + { "Kwajalein" , 0x0377CE }, + { "Libya" , 0x037831 }, + { "MET" , 0x03792B }, + { "Mexico/BajaNorte" , 0x037C34 }, + { "Mexico/BajaSur" , 0x037F9D }, + { "Mexico/General" , 0x0381E2 }, + { "MST" , 0x038440 }, + { "MST7MDT" , 0x038484 }, + { "Navajo" , 0x0387D5 }, + { "NZ" , 0x038B4E }, + { "NZ-CHAT" , 0x038ECC }, + { "Pacific/Apia" , 0x0391B4 }, + { "Pacific/Auckland" , 0x039232 }, + { "Pacific/Chatham" , 0x0395BE }, + { "Pacific/Easter" , 0x0398B5 }, + { "Pacific/Efate" , 0x039C13 }, + { "Pacific/Enderbury" , 0x039CD9 }, + { "Pacific/Fakaofo" , 0x039D47 }, + { "Pacific/Fiji" , 0x039D8B }, + { "Pacific/Funafuti" , 0x039E01 }, + { "Pacific/Galapagos" , 0x039E45 }, + { "Pacific/Gambier" , 0x039EBD }, + { "Pacific/Guadalcanal" , 0x039F22 }, + { "Pacific/Guam" , 0x039F77 }, + { "Pacific/Honolulu" , 0x039FCD }, + { "Pacific/Johnston" , 0x03A061 }, + { "Pacific/Kiritimati" , 0x03A0B3 }, + { "Pacific/Kosrae" , 0x03A11E }, + { "Pacific/Kwajalein" , 0x03A17B }, + { "Pacific/Majuro" , 0x03A1E7 }, + { "Pacific/Marquesas" , 0x03A246 }, + { "Pacific/Midway" , 0x03A2AD }, + { "Pacific/Nauru" , 0x03A337 }, + { "Pacific/Niue" , 0x03A3AF }, + { "Pacific/Norfolk" , 0x03A40D }, + { "Pacific/Noumea" , 0x03A462 }, + { "Pacific/Pago_Pago" , 0x03A4F2 }, + { "Pacific/Palau" , 0x03A57B }, + { "Pacific/Pitcairn" , 0x03A5BF }, + { "Pacific/Ponape" , 0x03A614 }, + { "Pacific/Port_Moresby" , 0x03A669 }, + { "Pacific/Rarotonga" , 0x03A6AD }, + { "Pacific/Saipan" , 0x03A789 }, + { "Pacific/Samoa" , 0x03A7EC }, + { "Pacific/Tahiti" , 0x03A875 }, + { "Pacific/Tarawa" , 0x03A8DA }, + { "Pacific/Tongatapu" , 0x03A92E }, + { "Pacific/Truk" , 0x03A9BA }, + { "Pacific/Wake" , 0x03AA13 }, + { "Pacific/Wallis" , 0x03AA63 }, + { "Pacific/Yap" , 0x03AAA7 }, + { "Poland" , 0x03AAEC }, + { "Portugal" , 0x03AECD }, + { "PRC" , 0x03B3C9 }, + { "PST8PDT" , 0x03B47A }, + { "ROC" , 0x03B7CB }, + { "ROK" , 0x03B8E3 }, + { "Singapore" , 0x03B987 }, + { "Turkey" , 0x03BA3E }, + { "UCT" , 0x03BE2B }, + { "Universal" , 0x03BE6F }, + { "US/Alaska" , 0x03BEB3 }, + { "US/Aleutian" , 0x03C21C }, + { "US/Arizona" , 0x03C582 }, + { "US/Central" , 0x03C610 }, + { "US/East-Indiana" , 0x03D01A }, + { "US/Eastern" , 0x03CB1B }, + { "US/Hawaii" , 0x03D284 }, + { "US/Indiana-Starke" , 0x03D312 }, + { "US/Michigan" , 0x03D683 }, + { "US/Mountain" , 0x03D9BA }, + { "US/Pacific" , 0x03DD33 }, + { "US/Pacific-New" , 0x03E138 }, + { "US/Samoa" , 0x03E53D }, + { "UTC" , 0x03E5C6 }, + { "W-SU" , 0x03E8BD }, + { "WET" , 0x03E60A }, + { "Zulu" , 0x03EBF8 }, }; /* This is a generated file, do not modify */ -const unsigned char timelib_timezone_db_data_builtin[257923] = { +const unsigned char timelib_timezone_db_data_builtin[257084] = { /* Africa/Abidjan */ @@ -569,8 +570,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x92, 0xE6, 0x92, 0x48, 0x01, 0xFF, 0xFF, 0xFC, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x71, 0x12, 0x01, 0x0C, 0x9B, -0x05, 0x00, 0x00, 0x00, 0x00, +0x00, 0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0x71, 0x12, 0x01, 0x0C, 0x80, +0xFA, 0x00, 0x00, 0x00, 0x00, /* Africa/Accra */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x47, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -583,7 +584,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xFF, 0xCC, 0x00, 0x00, 0x00, 0x00, 0x04, 0xB0, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x47, 0x48, 0x53, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x91, 0xCC, 0x38, -0x01, 0x12, 0xFD, 0x22, 0x00, 0x00, 0x00, 0x00, +0x01, 0x12, 0x53, 0xDD, 0x00, 0x00, 0x00, 0x00, /* Africa/Addis_Ababa */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -655,7 +656,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0xFF, 0xFF, 0xF0, 0x64, 0x00, 0x04, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x42, 0x4D, 0x54, 0x00, 0x57, 0x41, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0xE0, 0xAA, 0x00, -0xFB, 0x3C, 0x68, 0x00, 0x00, 0x00, 0x00, +0xF9, 0x40, 0x98, 0x00, 0x00, 0x00, 0x00, /* Africa/Bissau */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x47, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -663,15 +664,15 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x91, 0xC4, 0x93, 0x1C, 0x09, 0x67, 0x61, 0x10, 0x01, 0x02, 0xFF, 0xFF, 0xF1, 0x64, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x57, 0x41, 0x54, 0x00, -0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x69, 0x28, 0x00, 0xFC, -0xA8, 0xFD, 0x00, 0x00, 0x00, 0x00, +0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0x69, 0x28, 0x00, 0xFA, +0xE1, 0x42, 0x00, 0x00, 0x00, 0x00, /* Africa/Blantyre */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4D, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x82, 0x46, 0xC3, 0xB0, 0x01, 0x00, 0x00, 0x20, 0xD0, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xA2, 0xDD, 0x01, 0x48, 0x10, +0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x3E, 0xE2, 0x01, 0x48, 0x10, 0x60, 0x00, 0x00, 0x00, 0x00, /* Africa/Brazzaville */ @@ -679,14 +680,14 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x92, 0xE6, 0x80, 0x2C, 0x01, 0x00, 0x00, 0x0E, 0x54, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x57, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xA1, 0xEA, 0x01, 0x29, 0xFA, +0x00, 0x57, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0xD1, 0x95, 0x01, 0x29, 0xFA, 0x8D, 0x00, 0x00, 0x00, 0x00, /* Africa/Bujumbura */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x20, -0x00, 0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x85, 0x56, 0x1D, 0x01, 0x3F, 0x77, 0xDA, +0x00, 0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x84, 0x2A, 0xA2, 0x01, 0x3F, 0x77, 0xDA, 0x00, 0x00, 0x00, 0x00, /* Africa/Cairo */ @@ -722,7 +723,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x3F, 0x73, 0x57, 0x50, 0x40, 0x91, 0x7A, 0xE0, 0x41, 0x5C, 0x73, 0xD0, 0x42, 0x71, 0x5C, 0xE0, 0x43, 0x3C, 0x55, 0xD0, 0x44, 0x51, 0x3E, 0xE0, 0x45, 0x12, 0xFD, 0x50, 0x46, 0x31, 0x20, 0xE0, 0x46, 0xE0, 0x6A, 0x50, 0x48, 0x11, 0x02, 0xE0, 0x48, 0xB7, 0x11, 0xD0, 0x49, 0xF0, 0xE4, 0xE0, -0x4A, 0xBB, 0xDD, 0xD0, 0x4B, 0xDA, 0x01, 0x60, 0x4C, 0xA4, 0xFA, 0x50, 0x4D, 0xB9, 0xE3, 0x60, +0x4A, 0x8D, 0xB9, 0x50, 0x4B, 0xDA, 0x01, 0x60, 0x4C, 0xA4, 0xFA, 0x50, 0x4D, 0xB9, 0xE3, 0x60, 0x4E, 0x84, 0xDC, 0x50, 0x4F, 0x99, 0xC5, 0x60, 0x50, 0x64, 0xBE, 0x50, 0x51, 0x79, 0xA7, 0x60, 0x52, 0x44, 0xA0, 0x50, 0x53, 0x59, 0x89, 0x60, 0x54, 0x24, 0x82, 0x50, 0x55, 0x39, 0x6B, 0x60, 0x56, 0x04, 0x64, 0x50, 0x57, 0x22, 0x87, 0xE0, 0x57, 0xED, 0x80, 0xD0, 0x59, 0x02, 0x69, 0xE0, @@ -766,7 +767,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xF8, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x10, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x57, 0x45, 0x53, 0x54, 0x00, 0x57, 0x45, 0x54, 0x00, 0x43, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xBC, 0xAC, 0xC8, 0x01, 0x08, 0xDD, 0xFD, 0x00, 0x00, 0x00, 0x00, +0x00, 0xBC, 0xAC, 0xC8, 0x01, 0x07, 0x16, 0x42, 0x00, 0x00, 0x00, 0x00, /* Africa/Ceuta */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x45, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -816,7 +817,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x1C, 0x20, 0x01, 0x0D, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x09, 0x57, 0x45, 0x54, 0x00, 0x57, 0x45, 0x53, 0x54, 0x00, 0x43, 0x45, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xC0, 0x15, 0x2D, -0x01, 0x0B, 0x83, 0x12, 0x00, 0x00, 0x00, 0x0F, 0x43, 0x65, 0x75, 0x74, 0x61, 0x20, 0x26, 0x20, +0x01, 0x0A, 0x8B, 0xAD, 0x00, 0x00, 0x00, 0x0F, 0x43, 0x65, 0x75, 0x74, 0x61, 0x20, 0x26, 0x20, 0x4D, 0x65, 0x6C, 0x69, 0x6C, 0x6C, 0x61, /* Africa/Conakry */ @@ -826,7 +827,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xBC, 0x92, 0xB8, 0x80, 0xED, 0x30, 0x16, 0x90, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xF3, 0x24, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x57, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x97, 0xD9, 0xB2, 0x00, 0xFF, 0xEA, 0x52, 0x00, 0x00, 0x00, 0x00, +0x97, 0xD9, 0xB2, 0x00, 0xFD, 0xBA, 0x6D, 0x00, 0x00, 0x00, 0x00, /* Africa/Dakar */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x53, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -834,8 +835,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x92, 0xE6, 0x9E, 0xD8, 0xCA, 0x3B, 0x10, 0x90, 0x01, 0x02, 0xFF, 0xFF, 0xEF, 0xA8, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x57, 0x41, 0x54, 0x00, -0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xB5, 0x6A, 0x00, 0xF9, -0x61, 0x25, 0x00, 0x00, 0x00, 0x00, +0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xB5, 0x6A, 0x00, 0xF8, +0x0E, 0x9A, 0x00, 0x00, 0x00, 0x00, /* Africa/Dar_es_Salaam */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x54, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -844,7 +845,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xD6, 0x9D, 0x7F, 0xD0, 0xEF, 0x12, 0x66, 0xE3, 0x01, 0x02, 0x01, 0x00, 0x00, 0x24, 0xD4, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x04, 0x00, 0x00, 0x26, 0x9D, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x45, 0x41, 0x54, 0x00, 0x42, 0x45, 0x41, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x81, 0x65, 0x00, 0x01, 0x4E, 0x99, 0x8D, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x7E, 0xF4, 0x00, 0x01, 0x4E, 0x99, 0x8D, 0x00, 0x00, 0x00, 0x00, /* Africa/Djibouti */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x44, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -868,8 +869,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0xBC, 0x48, 0xF0, 0xE0, 0x0B, 0xD1, 0xB0, 0x90, 0x01, 0x02, 0xFF, 0xFF, 0xF3, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x57, 0x41, 0x54, 0x00, -0x57, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xC1, 0xB8, 0x00, 0xFF, -0x20, 0x7F, 0x00, 0x00, 0x00, 0x00, +0x57, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB2, 0xC1, 0xB8, 0x00, 0xFE, +0x84, 0x40, 0x00, 0x00, 0x00, 0x00, /* Africa/Freetown */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x53, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -888,7 +889,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xF1, 0xF0, 0x00, 0x09, 0x00, 0x00, 0x0E, 0x10, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x46, 0x4D, 0x54, 0x00, 0x53, 0x4C, 0x53, 0x54, 0x00, 0x57, 0x41, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x96, 0x4C, 0x90, 0x00, 0xFF, 0x34, 0x08, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x96, 0x4C, 0x90, 0x00, 0xFE, 0x70, 0xB8, 0x00, 0x00, 0x00, 0x00, /* Africa/Gaborone */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -896,14 +897,14 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0xCE, 0x8E, 0x6E, 0x80, 0xCF, 0x7E, 0x51, 0x70, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x04, 0x43, 0x41, 0x54, 0x00, 0x43, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x65, 0xB3, 0x28, 0x01, 0x3A, 0x34, 0x32, 0x00, 0x00, 0x00, 0x00, +0x63, 0xB7, 0x57, 0x01, 0x3A, 0x34, 0x32, 0x00, 0x00, 0x00, 0x00, /* Africa/Harare */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x5A, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x82, 0x46, 0xC7, 0x64, 0x01, 0x00, 0x00, 0x1D, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0xA9, 0x25, 0x01, 0x42, 0x09, +0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x1E, 0x1A, 0x01, 0x42, 0x09, 0x68, 0x00, 0x00, 0x00, 0x00, /* Africa/Johannesburg */ @@ -913,7 +914,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xCC, 0xAE, 0x8C, 0x80, 0xCD, 0x9E, 0x6F, 0x70, 0xCE, 0x8E, 0x6E, 0x80, 0xCF, 0x7E, 0x51, 0x70, 0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x15, 0x18, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x00, 0x53, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x62, 0x09, 0xA8, 0x01, 0x3D, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x61, 0x46, 0x58, 0x01, 0x3D, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00, /* Africa/Kampala */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x55, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -950,14 +951,14 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0xBE, 0xF1, 0x0E, 0x50, 0x01, 0x00, 0x00, 0x1C, 0x30, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x40, 0xB8, 0x01, 0x40, 0x89, +0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x5A, 0x88, 0x01, 0x40, 0x89, 0x4A, 0x00, 0x00, 0x00, 0x00, /* Africa/Kinshasa */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0E, 0x10, -0x00, 0x00, 0x57, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x83, 0xAE, 0xF0, 0x01, 0x2A, 0x01, 0x10, +0x00, 0x00, 0x57, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x82, 0xC4, 0x90, 0x01, 0x2A, 0x01, 0x10, 0x00, 0x00, 0x00, 0x17, 0x77, 0x65, 0x73, 0x74, 0x20, 0x44, 0x65, 0x6D, 0x2E, 0x20, 0x52, 0x65, 0x70, 0x2E, 0x20, 0x6F, 0x66, 0x20, 0x43, 0x6F, 0x6E, 0x67, 0x6F, @@ -989,14 +990,14 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xC4, 0x78, 0x4C, 0x01, 0x00, 0x00, 0x0C, 0x34, 0x00, 0x00, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x04, 0x41, 0x4F, 0x54, -0x00, 0x57, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x57, 0xC0, 0x01, 0x26, 0xD9, +0x00, 0x57, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7B, 0xE6, 0xC0, 0x01, 0x26, 0xD9, 0xC5, 0x00, 0x00, 0x00, 0x00, /* Africa/Lubumbashi */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x1C, 0x20, -0x00, 0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x79, 0x8F, 0xCA, 0x01, 0x3C, 0x91, 0xAA, +0x00, 0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x77, 0x86, 0xF5, 0x01, 0x3C, 0x91, 0xAA, 0x00, 0x00, 0x00, 0x17, 0x65, 0x61, 0x73, 0x74, 0x20, 0x44, 0x65, 0x6D, 0x2E, 0x20, 0x52, 0x65, 0x70, 0x2E, 0x20, 0x6F, 0x66, 0x20, 0x43, 0x6F, 0x6E, 0x67, 0x6F, @@ -1005,7 +1006,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x82, 0x46, 0xC9, 0xFC, 0x01, 0x00, 0x00, 0x1A, 0x84, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x13, 0xA2, 0x01, 0x3D, 0xD0, +0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xCE, 0x1D, 0x01, 0x3D, 0xD0, 0xAD, 0x00, 0x00, 0x00, 0x00, /* Africa/Malabo */ @@ -1022,7 +1023,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x82, 0x46, 0xC5, 0xF4, 0x01, 0x00, 0x00, 0x1E, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, 0xA8, 0x3A, 0x01, 0x44, 0x60, +0x00, 0x43, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0xB5, 0x05, 0x01, 0x44, 0x60, 0x5D, 0x00, 0x00, 0x00, 0x00, /* Africa/Maseru */ @@ -1031,7 +1032,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0x82, 0x46, 0xCA, 0xB8, 0xCE, 0x8E, 0x6E, 0x80, 0xCF, 0x7E, 0x51, 0x70, 0x01, 0x02, 0x01, 0x00, 0x00, 0x19, 0xC8, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x04, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x53, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xCA, 0x6A, +0x00, 0x53, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5C, 0x5D, 0xD5, 0x01, 0x3C, 0x9E, 0xB0, 0x00, 0x00, 0x00, 0x00, /* Africa/Mbabane */ @@ -1039,7 +1040,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x82, 0x46, 0xC7, 0x58, 0x01, 0x00, 0x00, 0x1D, 0x28, 0x00, 0x00, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x53, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x1D, 0x30, 0x01, 0x42, +0x00, 0x53, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x61, 0x32, 0xD0, 0x01, 0x42, 0x1C, 0xF0, 0x00, 0x00, 0x00, 0x00, /* Africa/Mogadishu */ @@ -1056,8 +1057,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0xA0, 0x5F, 0x6C, 0x9C, 0x04, 0x61, 0xF6, 0xEE, 0x01, 0x02, 0xFF, 0xFF, 0xF5, 0xE4, 0x00, 0x00, 0xFF, 0xFF, 0xF5, 0x92, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x4D, 0x4D, 0x54, 0x00, 0x4C, 0x52, 0x54, 0x00, -0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0xF1, 0x30, 0x01, 0x04, -0x98, 0x3D, 0x00, 0x00, 0x00, 0x00, +0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0xF1, 0x30, 0x01, 0x02, +0x34, 0x42, 0x00, 0x00, 0x00, 0x00, /* Africa/Nairobi */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4B, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1067,7 +1068,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x22, 0x84, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x04, 0x00, 0x00, 0x23, 0x28, 0x00, 0x08, 0x00, 0x00, 0x26, 0x9D, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x45, 0x41, 0x54, 0x00, 0x42, 0x45, 0x41, 0x54, 0x00, 0x42, 0x45, 0x41, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x88, 0x3C, 0x4D, 0x01, 0x4A, 0xD6, 0x02, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x87, 0x5E, 0xF2, 0x01, 0x4A, 0xD6, 0x02, 0x00, 0x00, 0x00, 0x00, /* Africa/Ndjamena */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x54, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1095,15 +1096,15 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xBC, 0x92, 0xB8, 0x80, 0xEE, 0xE5, 0xC8, 0x90, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xF1, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x57, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xA4, 0xF2, 0x90, 0x00, 0xFD, 0x38, 0x37, 0x00, 0x00, 0x00, 0x00, +0xA4, 0xF2, 0x90, 0x00, 0xFA, 0x52, 0x08, 0x00, 0x00, 0x00, 0x00, /* Africa/Ouagadougou */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x92, 0xE6, 0x8F, 0xEC, 0x01, 0xFF, 0xFF, 0xFE, 0x94, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x32, 0xFA, 0x01, 0x11, 0xEB, -0xB2, 0x00, 0x00, 0x00, 0x00, +0x00, 0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x32, 0xFA, 0x01, 0x10, 0x58, +0x0D, 0x00, 0x00, 0x00, 0x00, /* Africa/Porto-Novo */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x4A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1222,7 +1223,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x1C, 0x20, 0x00, 0x05, 0x00, 0x00, 0x2A, 0x30, 0x01, 0x05, 0x00, 0x00, 0x1C, 0x20, 0x00, 0x0A, 0x00, 0x00, 0x1C, 0x20, 0x01, 0x0E, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x01, 0x53, 0x57, 0x41, 0x54, 0x00, 0x53, 0x41, 0x53, 0x54, 0x00, 0x43, 0x41, 0x54, 0x00, 0x57, 0x41, 0x53, 0x54, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x9F, 0xDA, 0x01, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0xE5, 0x25, 0x01, 0x2C, 0xC0, 0x30, 0x00, 0x00, 0x00, 0x00, /* America/Adak */ @@ -1279,8 +1280,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x19, 0xFF, 0xFF, 0x73, 0x60, 0x00, 0x1E, 0x4E, 0x53, 0x54, 0x00, 0x4E, 0x57, 0x54, 0x00, 0x4E, 0x50, 0x54, 0x00, 0x42, 0x53, 0x54, 0x00, 0x42, 0x44, 0x54, 0x00, 0x41, 0x48, 0x53, 0x54, 0x00, 0x48, 0x41, 0x44, 0x54, 0x00, 0x48, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x7D, 0xE0, 0x00, 0x07, -0x1B, 0x8D, 0x00, 0x00, 0x00, 0x10, 0x41, 0x6C, 0x65, 0x75, 0x74, 0x69, 0x61, 0x6E, 0x20, 0x49, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0x7D, 0xE0, 0x00, 0x05, +0x19, 0x72, 0x00, 0x00, 0x00, 0x10, 0x41, 0x6C, 0x65, 0x75, 0x74, 0x69, 0x61, 0x6E, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, /* America/Anchorage */ @@ -1338,7 +1339,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x43, 0x41, 0x50, 0x54, 0x00, 0x41, 0x48, 0x53, 0x54, 0x00, 0x41, 0x48, 0x44, 0x54, 0x00, 0x59, 0x53, 0x54, 0x00, 0x41, 0x4B, 0x44, 0x54, 0x00, 0x41, 0x4B, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE6, 0xBD, -0x8D, 0x00, 0x30, 0xAD, 0x0B, 0x00, 0x00, 0x00, 0x0B, 0x41, 0x6C, 0x61, 0x73, 0x6B, 0x61, 0x20, +0x8D, 0x00, 0x2D, 0xED, 0xB4, 0x00, 0x00, 0x00, 0x0B, 0x41, 0x6C, 0x61, 0x73, 0x6B, 0x61, 0x20, 0x54, 0x69, 0x6D, 0x65, /* America/Anguilla */ @@ -1346,8 +1347,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x35, 0x20, 0x01, 0xFF, 0xFF, 0xC4, 0xE0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x19, 0xA0, 0x00, 0xB2, 0xA1, -0x2A, 0x00, 0x00, 0x00, 0x00, +0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x19, 0xA0, 0x00, 0xB2, 0x6D, +0x15, 0x00, 0x00, 0x00, 0x00, /* America/Antigua */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1355,8 +1356,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x93, 0x37, 0x33, 0xF0, 0xDC, 0x42, 0xDC, 0x50, 0x01, 0x02, 0xFF, 0xFF, 0xC6, 0x10, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, -0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x58, 0x68, 0x00, 0xB6, -0xCC, 0xE0, 0x00, 0x00, 0x00, 0x00, +0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0x58, 0x68, 0x00, 0xB4, +0x5B, 0xE0, 0x00, 0x00, 0x00, 0x00, /* America/Araguaina */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1379,13 +1380,13 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xD2, 0xD0, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x42, 0x52, 0x53, 0x54, 0x00, 0x42, 0x52, 0x54, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0xF4, 0x00, 0x00, 0xC9, 0xB8, 0x9F, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x57, 0xC0, 0x00, 0xC9, 0x1C, 0x60, 0x00, 0x00, 0x00, 0x09, 0x54, 0x6F, 0x63, 0x61, 0x6E, 0x74, 0x69, 0x6E, 0x73, /* America/Argentina/Buenos_Aires */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0D, 0xA2, 0x92, 0x8F, 0x30, +0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0D, 0xA2, 0x92, 0x8F, 0x30, 0xB6, 0x7B, 0x52, 0x40, 0xB7, 0x1A, 0xC9, 0xB0, 0xB8, 0x1E, 0x8F, 0x40, 0xB8, 0xD4, 0x70, 0x30, 0xBA, 0x17, 0x7D, 0xC0, 0xBA, 0xB5, 0xA3, 0xB0, 0xBB, 0xF8, 0xB1, 0x40, 0xBC, 0x96, 0xD7, 0x30, 0xBD, 0xD9, 0xE4, 0xC0, 0xBE, 0x78, 0x0A, 0xB0, 0xBF, 0xBB, 0x18, 0x40, 0xC0, 0x5A, 0x8F, 0xB0, @@ -1400,34 +1401,16 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x24, 0x10, 0x94, 0xA0, 0x25, 0x37, 0xF2, 0xB0, 0x25, 0xF0, 0x76, 0xA0, 0x27, 0x21, 0x0F, 0x30, 0x27, 0xD0, 0x58, 0xA0, 0x29, 0x00, 0xF1, 0x30, 0x29, 0xB0, 0x3A, 0xA0, 0x2A, 0xE0, 0xD3, 0x30, 0x2B, 0x99, 0x57, 0x20, 0x37, 0xF6, 0xC6, 0xB0, 0x38, 0xBF, 0x2A, 0xB0, 0x47, 0x77, 0x09, 0xB0, -0x47, 0xDC, 0x7F, 0x20, 0x48, 0xFA, 0xA2, 0xB0, 0x49, 0xBC, 0x61, 0x20, 0x4A, 0xDA, 0x84, 0xB0, -0x4B, 0xA5, 0x7D, 0xA0, 0x4C, 0xBA, 0x66, 0xB0, 0x4D, 0x85, 0x5F, 0xA0, 0x4E, 0x9A, 0x48, 0xB0, -0x4F, 0x65, 0x41, 0xA0, 0x50, 0x83, 0x65, 0x30, 0x51, 0x45, 0x23, 0xA0, 0x52, 0x63, 0x47, 0x30, -0x53, 0x25, 0x05, 0xA0, 0x54, 0x43, 0x29, 0x30, 0x55, 0x04, 0xE7, 0xA0, 0x56, 0x23, 0x0B, 0x30, -0x56, 0xEE, 0x04, 0x20, 0x58, 0x02, 0xED, 0x30, 0x58, 0xCD, 0xE6, 0x20, 0x59, 0xE2, 0xCF, 0x30, -0x5A, 0xAD, 0xC8, 0x20, 0x5B, 0xCB, 0xEB, 0xB0, 0x5C, 0x8D, 0xAA, 0x20, 0x5D, 0xAB, 0xCD, 0xB0, -0x5E, 0x6D, 0x8C, 0x20, 0x5F, 0x8B, 0xAF, 0xB0, 0x60, 0x56, 0xA8, 0xA0, 0x61, 0x6B, 0x91, 0xB0, -0x62, 0x36, 0x8A, 0xA0, 0x63, 0x4B, 0x73, 0xB0, 0x64, 0x16, 0x6C, 0xA0, 0x65, 0x2B, 0x55, 0xB0, -0x65, 0xF6, 0x4E, 0xA0, 0x67, 0x14, 0x72, 0x30, 0x67, 0xD6, 0x30, 0xA0, 0x68, 0xF4, 0x54, 0x30, -0x69, 0xB6, 0x12, 0xA0, 0x6A, 0xD4, 0x36, 0x30, 0x6B, 0x9F, 0x2F, 0x20, 0x6C, 0xB4, 0x18, 0x30, -0x6D, 0x7F, 0x11, 0x20, 0x6E, 0x93, 0xFA, 0x30, 0x6F, 0x5E, 0xF3, 0x20, 0x70, 0x7D, 0x16, 0xB0, -0x71, 0x3E, 0xD5, 0x20, 0x72, 0x5C, 0xF8, 0xB0, 0x73, 0x1E, 0xB7, 0x20, 0x74, 0x3C, 0xDA, 0xB0, -0x75, 0x07, 0xD3, 0xA0, 0x76, 0x1C, 0xBC, 0xB0, 0x76, 0xE7, 0xB5, 0xA0, 0x77, 0xFC, 0x9E, 0xB0, -0x78, 0xC7, 0x97, 0xA0, 0x79, 0xDC, 0x80, 0xB0, 0x7A, 0xA7, 0x79, 0xA0, 0x7B, 0xC5, 0x9D, 0x30, -0x7C, 0x87, 0x5B, 0xA0, 0x7D, 0xA5, 0x7F, 0x30, 0x7E, 0x67, 0x3D, 0xA0, 0x7F, 0x85, 0x61, 0x30, +0x47, 0xDC, 0x7F, 0x20, 0x48, 0xFA, 0xA2, 0xB0, 0x49, 0xBC, 0x61, 0x20, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, -0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, -0xD0, 0x00, 0x04, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x5D, 0x60, 0x00, 0xBA, -0xD8, 0x08, 0x00, 0x00, 0x00, 0x15, 0x42, 0x75, 0x65, 0x6E, 0x6F, 0x73, 0x20, 0x41, 0x69, 0x72, -0x65, 0x73, 0x20, 0x28, 0x42, 0x41, 0x2C, 0x20, 0x43, 0x46, 0x29, +0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, +0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, +0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, +0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x88, +0xA0, 0x00, 0xB9, 0x78, 0x78, 0x00, 0x00, 0x00, 0x15, 0x42, 0x75, 0x65, 0x6E, 0x6F, 0x73, 0x20, +0x41, 0x69, 0x72, 0x65, 0x73, 0x20, 0x28, 0x42, 0x41, 0x2C, 0x20, 0x43, 0x46, 0x29, /* America/Argentina/Catamarca */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1455,8 +1438,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5F, 0x51, 0x0A, 0x00, 0xB0, -0xAB, 0xDD, 0x00, 0x00, 0x00, 0x1B, 0x43, 0x61, 0x74, 0x61, 0x6D, 0x61, 0x72, 0x63, 0x61, 0x20, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0xE4, 0x75, 0x00, 0xAE, +0x47, 0xE2, 0x00, 0x00, 0x00, 0x1B, 0x43, 0x61, 0x74, 0x61, 0x6D, 0x61, 0x72, 0x63, 0x61, 0x20, 0x28, 0x43, 0x54, 0x29, 0x2C, 0x20, 0x43, 0x68, 0x75, 0x62, 0x75, 0x74, 0x20, 0x28, 0x43, 0x48, 0x29, @@ -1492,7 +1475,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { /* America/Argentina/Cordoba */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12, 0xA2, 0x92, 0x8F, 0x30, +0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12, 0xA2, 0x92, 0x8F, 0x30, 0xB6, 0x7B, 0x52, 0x40, 0xB7, 0x1A, 0xC9, 0xB0, 0xB8, 0x1E, 0x8F, 0x40, 0xB8, 0xD4, 0x70, 0x30, 0xBA, 0x17, 0x7D, 0xC0, 0xBA, 0xB5, 0xA3, 0xB0, 0xBB, 0xF8, 0xB1, 0x40, 0xBC, 0x96, 0xD7, 0x30, 0xBD, 0xD9, 0xE4, 0xC0, 0xBE, 0x78, 0x0A, 0xB0, 0xBF, 0xBB, 0x18, 0x40, 0xC0, 0x5A, 0x8F, 0xB0, @@ -1507,37 +1490,19 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x24, 0x10, 0x94, 0xA0, 0x25, 0x37, 0xF2, 0xB0, 0x25, 0xF0, 0x76, 0xA0, 0x27, 0x21, 0x0F, 0x30, 0x27, 0xD0, 0x58, 0xA0, 0x29, 0x00, 0xFF, 0x40, 0x29, 0xB0, 0x3A, 0xA0, 0x2A, 0xE0, 0xD3, 0x30, 0x2B, 0x99, 0x57, 0x20, 0x37, 0xF6, 0xC6, 0xB0, 0x38, 0xBF, 0x2A, 0xB0, 0x47, 0x77, 0x09, 0xB0, -0x47, 0xDC, 0x7F, 0x20, 0x48, 0xFA, 0xA2, 0xB0, 0x49, 0xBC, 0x61, 0x20, 0x4A, 0xDA, 0x84, 0xB0, -0x4B, 0xA5, 0x7D, 0xA0, 0x4C, 0xBA, 0x66, 0xB0, 0x4D, 0x85, 0x5F, 0xA0, 0x4E, 0x9A, 0x48, 0xB0, -0x4F, 0x65, 0x41, 0xA0, 0x50, 0x83, 0x65, 0x30, 0x51, 0x45, 0x23, 0xA0, 0x52, 0x63, 0x47, 0x30, -0x53, 0x25, 0x05, 0xA0, 0x54, 0x43, 0x29, 0x30, 0x55, 0x04, 0xE7, 0xA0, 0x56, 0x23, 0x0B, 0x30, -0x56, 0xEE, 0x04, 0x20, 0x58, 0x02, 0xED, 0x30, 0x58, 0xCD, 0xE6, 0x20, 0x59, 0xE2, 0xCF, 0x30, -0x5A, 0xAD, 0xC8, 0x20, 0x5B, 0xCB, 0xEB, 0xB0, 0x5C, 0x8D, 0xAA, 0x20, 0x5D, 0xAB, 0xCD, 0xB0, -0x5E, 0x6D, 0x8C, 0x20, 0x5F, 0x8B, 0xAF, 0xB0, 0x60, 0x56, 0xA8, 0xA0, 0x61, 0x6B, 0x91, 0xB0, -0x62, 0x36, 0x8A, 0xA0, 0x63, 0x4B, 0x73, 0xB0, 0x64, 0x16, 0x6C, 0xA0, 0x65, 0x2B, 0x55, 0xB0, -0x65, 0xF6, 0x4E, 0xA0, 0x67, 0x14, 0x72, 0x30, 0x67, 0xD6, 0x30, 0xA0, 0x68, 0xF4, 0x54, 0x30, -0x69, 0xB6, 0x12, 0xA0, 0x6A, 0xD4, 0x36, 0x30, 0x6B, 0x9F, 0x2F, 0x20, 0x6C, 0xB4, 0x18, 0x30, -0x6D, 0x7F, 0x11, 0x20, 0x6E, 0x93, 0xFA, 0x30, 0x6F, 0x5E, 0xF3, 0x20, 0x70, 0x7D, 0x16, 0xB0, -0x71, 0x3E, 0xD5, 0x20, 0x72, 0x5C, 0xF8, 0xB0, 0x73, 0x1E, 0xB7, 0x20, 0x74, 0x3C, 0xDA, 0xB0, -0x75, 0x07, 0xD3, 0xA0, 0x76, 0x1C, 0xBC, 0xB0, 0x76, 0xE7, 0xB5, 0xA0, 0x77, 0xFC, 0x9E, 0xB0, -0x78, 0xC7, 0x97, 0xA0, 0x79, 0xDC, 0x80, 0xB0, 0x7A, 0xA7, 0x79, 0xA0, 0x7B, 0xC5, 0x9D, 0x30, -0x7C, 0x87, 0x5B, 0xA0, 0x7D, 0xA5, 0x7F, 0x30, 0x7E, 0x67, 0x3D, 0xA0, 0x7F, 0x85, 0x61, 0x30, +0x47, 0xDC, 0x7F, 0x20, 0x48, 0xFA, 0xA2, 0xB0, 0x49, 0xBC, 0x61, 0x20, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x05, 0x03, 0x04, 0x03, 0x04, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, -0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, -0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, -0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5A, 0xA3, 0x20, 0x00, 0xB1, 0x48, 0x1D, 0x00, -0x00, 0x00, 0x2F, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, -0x73, 0x20, 0x28, 0x43, 0x42, 0x2C, 0x20, 0x43, 0x43, 0x2C, 0x20, 0x43, 0x4E, 0x2C, 0x20, 0x45, -0x52, 0x2C, 0x20, 0x46, 0x4D, 0x2C, 0x20, 0x4D, 0x4E, 0x2C, 0x20, 0x53, 0x45, 0x2C, 0x20, 0x53, -0x46, 0x29, +0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x05, 0x03, 0x04, +0x03, 0x04, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, +0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, +0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, +0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0x6A, 0xA0, 0x00, 0xB0, +0xB8, 0xE2, 0x00, 0x00, 0x00, 0x2F, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, +0x69, 0x6F, 0x6E, 0x73, 0x20, 0x28, 0x43, 0x42, 0x2C, 0x20, 0x43, 0x43, 0x2C, 0x20, 0x43, 0x4E, +0x2C, 0x20, 0x45, 0x52, 0x2C, 0x20, 0x46, 0x4D, 0x2C, 0x20, 0x4D, 0x4E, 0x2C, 0x20, 0x53, 0x45, +0x2C, 0x20, 0x53, 0x46, 0x29, /* America/Argentina/Jujuy */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1566,7 +1531,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x0D, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x12, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x57, 0x41, 0x52, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x64, -0xFC, 0xDD, 0x00, 0xAF, 0xEF, 0x10, 0x00, 0x00, 0x00, 0x0A, 0x4A, 0x75, 0x6A, 0x75, 0x79, 0x20, +0x6D, 0xA2, 0x00, 0xAF, 0x04, 0xB0, 0x00, 0x00, 0x00, 0x0A, 0x4A, 0x75, 0x6A, 0x75, 0x79, 0x20, 0x28, 0x4A, 0x59, 0x29, /* America/Argentina/La_Rioja */ @@ -1596,7 +1561,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x5D, 0xBD, 0x65, 0x00, 0xAF, 0x3F, 0x48, 0x00, 0x00, 0x00, 0x0D, 0x4C, 0x61, 0x20, 0x52, 0x69, +0x5C, 0x6A, 0xDA, 0x00, 0xAC, 0xA7, 0x38, 0x00, 0x00, 0x00, 0x0D, 0x4C, 0x61, 0x20, 0x52, 0x69, 0x6F, 0x6A, 0x61, 0x20, 0x28, 0x4C, 0x52, 0x29, /* America/Argentina/Mendoza */ @@ -1626,7 +1591,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x12, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x57, 0x41, 0x52, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x59, 0xD9, 0x4D, 0x00, 0xAC, 0x25, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x27, 0x32, 0x00, 0xA9, 0xA6, 0xFD, 0x00, 0x00, 0x00, 0x0C, 0x4D, 0x65, 0x6E, 0x64, 0x6F, 0x7A, 0x61, 0x20, 0x28, 0x4D, 0x5A, 0x29, @@ -1656,8 +1621,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x79, 0xC5, 0x00, 0xA9, -0xB4, 0x02, 0x00, 0x00, 0x00, 0x0F, 0x53, 0x61, 0x6E, 0x74, 0x61, 0x20, 0x43, 0x72, 0x75, 0x7A, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x8A, 0xFA, 0x00, 0xA9, +0x0A, 0xBD, 0x00, 0x00, 0x00, 0x0F, 0x53, 0x61, 0x6E, 0x74, 0x61, 0x20, 0x43, 0x72, 0x75, 0x7A, 0x20, 0x28, 0x53, 0x43, 0x29, /* America/Argentina/Salta */ @@ -1686,7 +1651,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x65, 0xE7, 0x3D, 0x00, 0xB0, 0x1C, 0xA2, 0x00, 0x00, 0x00, 0x10, 0x28, 0x53, 0x41, 0x2C, +0x00, 0x63, 0x83, 0x42, 0x00, 0xAE, 0xD7, 0x1D, 0x00, 0x00, 0x00, 0x10, 0x28, 0x53, 0x41, 0x2C, 0x20, 0x4C, 0x50, 0x2C, 0x20, 0x4E, 0x51, 0x2C, 0x20, 0x52, 0x4E, 0x29, /* America/Argentina/San_Juan */ @@ -1716,13 +1681,13 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x5A, 0xD7, 0x35, 0x00, 0xAB, 0xAF, 0xD2, 0x00, 0x00, 0x00, 0x0D, 0x53, 0x61, 0x6E, 0x20, 0x4A, +0x59, 0x36, 0x8A, 0x00, 0xAA, 0x1C, 0x2D, 0x00, 0x00, 0x00, 0x0D, 0x53, 0x61, 0x6E, 0x20, 0x4A, 0x75, 0x61, 0x6E, 0x20, 0x28, 0x53, 0x4A, 0x29, /* America/Argentina/San_Luis */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x73, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0xA2, 0x92, 0x8F, 0x30, +0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x18, 0xA2, 0x92, 0x8F, 0x30, 0xB6, 0x7B, 0x52, 0x40, 0xB7, 0x1A, 0xC9, 0xB0, 0xB8, 0x1E, 0x8F, 0x40, 0xB8, 0xD4, 0x70, 0x30, 0xBA, 0x17, 0x7D, 0xC0, 0xBA, 0xB5, 0xA3, 0xB0, 0xBB, 0xF8, 0xB1, 0x40, 0xBC, 0x96, 0xD7, 0x30, 0xBD, 0xD9, 0xE4, 0xC0, 0xBE, 0x78, 0x0A, 0xB0, 0xBF, 0xBB, 0x18, 0x40, 0xC0, 0x5A, 0x8F, 0xB0, @@ -1737,40 +1702,40 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x24, 0x10, 0x94, 0xA0, 0x25, 0x37, 0xF2, 0xB0, 0x25, 0xFD, 0xA5, 0xA0, 0x27, 0x19, 0x34, 0x40, 0x27, 0xCD, 0xC3, 0xB0, 0x28, 0x47, 0x1B, 0xC0, 0x37, 0xF6, 0xC6, 0xB0, 0x38, 0xBF, 0x2A, 0xB0, 0x40, 0xBA, 0x9F, 0xB0, 0x41, 0x03, 0x30, 0x40, 0x47, 0x77, 0x09, 0xB0, 0x47, 0x93, 0xFC, 0xA0, -0x49, 0xBC, 0x6F, 0x30, 0x4A, 0xDA, 0x92, 0xC0, 0x4B, 0xA5, 0x8B, 0xB0, 0x4C, 0xBA, 0x74, 0xC0, -0x4D, 0x85, 0x6D, 0xB0, 0x4E, 0x9A, 0x56, 0xC0, 0x4F, 0x65, 0x4F, 0xB0, 0x50, 0x83, 0x73, 0x40, -0x51, 0x45, 0x31, 0xB0, 0x52, 0x63, 0x55, 0x40, 0x53, 0x25, 0x13, 0xB0, 0x54, 0x43, 0x37, 0x40, -0x55, 0x04, 0xF5, 0xB0, 0x56, 0x23, 0x19, 0x40, 0x56, 0xEE, 0x12, 0x30, 0x58, 0x02, 0xFB, 0x40, -0x58, 0xCD, 0xF4, 0x30, 0x59, 0xE2, 0xDD, 0x40, 0x5A, 0xAD, 0xD6, 0x30, 0x5B, 0xCB, 0xF9, 0xC0, -0x5C, 0x8D, 0xB8, 0x30, 0x5D, 0xAB, 0xDB, 0xC0, 0x5E, 0x6D, 0x9A, 0x30, 0x5F, 0x8B, 0xBD, 0xC0, -0x60, 0x56, 0xB6, 0xB0, 0x61, 0x6B, 0x9F, 0xC0, 0x62, 0x36, 0x98, 0xB0, 0x63, 0x4B, 0x81, 0xC0, -0x64, 0x16, 0x7A, 0xB0, 0x65, 0x2B, 0x63, 0xC0, 0x65, 0xF6, 0x5C, 0xB0, 0x67, 0x14, 0x80, 0x40, -0x67, 0xD6, 0x3E, 0xB0, 0x68, 0xF4, 0x62, 0x40, 0x69, 0xB6, 0x20, 0xB0, 0x6A, 0xD4, 0x44, 0x40, -0x6B, 0x9F, 0x3D, 0x30, 0x6C, 0xB4, 0x26, 0x40, 0x6D, 0x7F, 0x1F, 0x30, 0x6E, 0x94, 0x08, 0x40, -0x6F, 0x5F, 0x01, 0x30, 0x70, 0x7D, 0x24, 0xC0, 0x71, 0x3E, 0xE3, 0x30, 0x72, 0x5D, 0x06, 0xC0, -0x73, 0x1E, 0xC5, 0x30, 0x74, 0x3C, 0xE8, 0xC0, 0x75, 0x07, 0xE1, 0xB0, 0x76, 0x1C, 0xCA, 0xC0, -0x76, 0xE7, 0xC3, 0xB0, 0x77, 0xFC, 0xAC, 0xC0, 0x78, 0xC7, 0xA5, 0xB0, 0x79, 0xDC, 0x8E, 0xC0, -0x7A, 0xA7, 0x87, 0xB0, 0x7B, 0xC5, 0xAB, 0x40, 0x7C, 0x87, 0x69, 0xB0, 0x7D, 0xA5, 0x8D, 0x40, -0x7E, 0x67, 0x4B, 0xB0, 0x7F, 0x85, 0x6F, 0x40, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, +0x47, 0xD3, 0x52, 0xB0, 0x48, 0xF1, 0x76, 0x40, 0x49, 0xB3, 0x34, 0xB0, 0x4A, 0xD1, 0x58, 0x40, +0x4B, 0x9C, 0x51, 0x30, 0x4C, 0xB1, 0x3A, 0x40, 0x4D, 0x7C, 0x33, 0x30, 0x4E, 0x91, 0x1C, 0x40, +0x4F, 0x5C, 0x15, 0x30, 0x50, 0x7A, 0x38, 0xC0, 0x51, 0x3B, 0xF7, 0x30, 0x52, 0x5A, 0x1A, 0xC0, +0x53, 0x1B, 0xD9, 0x30, 0x54, 0x39, 0xFC, 0xC0, 0x54, 0xFB, 0xBB, 0x30, 0x56, 0x19, 0xDE, 0xC0, +0x56, 0xE4, 0xD7, 0xB0, 0x57, 0xF9, 0xC0, 0xC0, 0x58, 0xC4, 0xB9, 0xB0, 0x59, 0xD9, 0xA2, 0xC0, +0x5A, 0xA4, 0x9B, 0xB0, 0x5B, 0xC2, 0xBF, 0x40, 0x5C, 0x84, 0x7D, 0xB0, 0x5D, 0xA2, 0xA1, 0x40, +0x5E, 0x64, 0x5F, 0xB0, 0x5F, 0x82, 0x83, 0x40, 0x60, 0x4D, 0x7C, 0x30, 0x61, 0x62, 0x65, 0x40, +0x62, 0x2D, 0x5E, 0x30, 0x63, 0x42, 0x47, 0x40, 0x64, 0x0D, 0x40, 0x30, 0x65, 0x22, 0x29, 0x40, +0x65, 0xED, 0x22, 0x30, 0x67, 0x0B, 0x45, 0xC0, 0x67, 0xCD, 0x04, 0x30, 0x68, 0xEB, 0x27, 0xC0, +0x69, 0xAC, 0xE6, 0x30, 0x6A, 0xCB, 0x09, 0xC0, 0x6B, 0x96, 0x02, 0xB0, 0x6C, 0xAA, 0xEB, 0xC0, +0x6D, 0x75, 0xE4, 0xB0, 0x6E, 0x8A, 0xCD, 0xC0, 0x6F, 0x55, 0xC6, 0xB0, 0x70, 0x73, 0xEA, 0x40, +0x71, 0x35, 0xA8, 0xB0, 0x72, 0x53, 0xCC, 0x40, 0x73, 0x15, 0x8A, 0xB0, 0x74, 0x33, 0xAE, 0x40, +0x74, 0xFE, 0xA7, 0x30, 0x76, 0x13, 0x90, 0x40, 0x76, 0xDE, 0x89, 0x30, 0x77, 0xF3, 0x72, 0x40, +0x78, 0xBE, 0x6B, 0x30, 0x79, 0xD3, 0x54, 0x40, 0x7A, 0x9E, 0x4D, 0x30, 0x7B, 0xBC, 0x70, 0xC0, +0x7C, 0x7E, 0x2F, 0x30, 0x7D, 0x9C, 0x52, 0xC0, 0x7E, 0x5E, 0x11, 0x30, 0x7F, 0x7C, 0x34, 0xC0, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x05, 0x06, 0x05, 0x04, 0x06, 0x04, 0x05, 0x04, 0x03, -0x04, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, +0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x05, +0x06, 0x05, 0x04, 0x06, 0x04, 0x05, 0x04, 0x03, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, +0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, -0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0x05, 0x06, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, -0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, -0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0xFF, -0xFF, 0xD5, 0xD0, 0x01, 0x12, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, -0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x57, 0x41, 0x52, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x57, 0x75, 0x52, 0x00, -0xAE, 0x7B, 0xF8, 0x00, 0x00, 0x00, 0x0D, 0x53, 0x61, 0x6E, 0x20, 0x4C, 0x75, 0x69, 0x73, 0x20, -0x28, 0x53, 0x4C, 0x29, +0x06, 0x05, 0x06, 0x05, 0x06, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, +0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, +0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x12, 0x43, +0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, +0x00, 0x57, 0x41, 0x52, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0x7D, 0xED, 0x00, 0xAD, 0x6A, 0x88, 0x00, 0x00, 0x00, +0x0D, 0x53, 0x61, 0x6E, 0x20, 0x4C, 0x75, 0x69, 0x73, 0x20, 0x28, 0x53, 0x4C, 0x29, /* America/Argentina/Tucuman */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12, 0xA2, 0x92, 0x8F, 0x30, +0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12, 0xA2, 0x92, 0x8F, 0x30, 0xB6, 0x7B, 0x52, 0x40, 0xB7, 0x1A, 0xC9, 0xB0, 0xB8, 0x1E, 0x8F, 0x40, 0xB8, 0xD4, 0x70, 0x30, 0xBA, 0x17, 0x7D, 0xC0, 0xBA, 0xB5, 0xA3, 0xB0, 0xBB, 0xF8, 0xB1, 0x40, 0xBC, 0x96, 0xD7, 0x30, 0xBD, 0xD9, 0xE4, 0xC0, 0xBE, 0x78, 0x0A, 0xB0, 0xBF, 0xBB, 0x18, 0x40, 0xC0, 0x5A, 0x8F, 0xB0, @@ -1786,34 +1751,16 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x27, 0xD0, 0x58, 0xA0, 0x29, 0x00, 0xFF, 0x40, 0x29, 0xB0, 0x3A, 0xA0, 0x2A, 0xE0, 0xD3, 0x30, 0x2B, 0x99, 0x57, 0x20, 0x37, 0xF6, 0xC6, 0xB0, 0x38, 0xBF, 0x2A, 0xB0, 0x40, 0xBB, 0xF1, 0x30, 0x40, 0xCB, 0xD1, 0x40, 0x47, 0x77, 0x09, 0xB0, 0x47, 0xDC, 0x7F, 0x20, 0x48, 0xFA, 0xA2, 0xB0, -0x49, 0xBC, 0x61, 0x20, 0x4A, 0xDA, 0x84, 0xB0, 0x4B, 0xA5, 0x7D, 0xA0, 0x4C, 0xBA, 0x66, 0xB0, -0x4D, 0x85, 0x5F, 0xA0, 0x4E, 0x9A, 0x48, 0xB0, 0x4F, 0x65, 0x41, 0xA0, 0x50, 0x83, 0x65, 0x30, -0x51, 0x45, 0x23, 0xA0, 0x52, 0x63, 0x47, 0x30, 0x53, 0x25, 0x05, 0xA0, 0x54, 0x43, 0x29, 0x30, -0x55, 0x04, 0xE7, 0xA0, 0x56, 0x23, 0x0B, 0x30, 0x56, 0xEE, 0x04, 0x20, 0x58, 0x02, 0xED, 0x30, -0x58, 0xCD, 0xE6, 0x20, 0x59, 0xE2, 0xCF, 0x30, 0x5A, 0xAD, 0xC8, 0x20, 0x5B, 0xCB, 0xEB, 0xB0, -0x5C, 0x8D, 0xAA, 0x20, 0x5D, 0xAB, 0xCD, 0xB0, 0x5E, 0x6D, 0x8C, 0x20, 0x5F, 0x8B, 0xAF, 0xB0, -0x60, 0x56, 0xA8, 0xA0, 0x61, 0x6B, 0x91, 0xB0, 0x62, 0x36, 0x8A, 0xA0, 0x63, 0x4B, 0x73, 0xB0, -0x64, 0x16, 0x6C, 0xA0, 0x65, 0x2B, 0x55, 0xB0, 0x65, 0xF6, 0x4E, 0xA0, 0x67, 0x14, 0x72, 0x30, -0x67, 0xD6, 0x30, 0xA0, 0x68, 0xF4, 0x54, 0x30, 0x69, 0xB6, 0x12, 0xA0, 0x6A, 0xD4, 0x36, 0x30, -0x6B, 0x9F, 0x2F, 0x20, 0x6C, 0xB4, 0x18, 0x30, 0x6D, 0x7F, 0x11, 0x20, 0x6E, 0x93, 0xFA, 0x30, -0x6F, 0x5E, 0xF3, 0x20, 0x70, 0x7D, 0x16, 0xB0, 0x71, 0x3E, 0xD5, 0x20, 0x72, 0x5C, 0xF8, 0xB0, -0x73, 0x1E, 0xB7, 0x20, 0x74, 0x3C, 0xDA, 0xB0, 0x75, 0x07, 0xD3, 0xA0, 0x76, 0x1C, 0xBC, 0xB0, -0x76, 0xE7, 0xB5, 0xA0, 0x77, 0xFC, 0x9E, 0xB0, 0x78, 0xC7, 0x97, 0xA0, 0x79, 0xDC, 0x80, 0xB0, -0x7A, 0xA7, 0x79, 0xA0, 0x7B, 0xC5, 0x9D, 0x30, 0x7C, 0x87, 0x5B, 0xA0, 0x7D, 0xA5, 0x7F, 0x30, -0x7E, 0x67, 0x3D, 0xA0, 0x7F, 0x85, 0x61, 0x30, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, +0x49, 0xBC, 0x61, 0x20, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x05, 0x03, 0x04, 0x03, 0x04, 0x02, 0x04, -0x05, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0xFF, -0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, -0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, -0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, -0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x62, 0xE7, 0x02, 0x00, 0xAF, 0xCE, 0x82, 0x00, 0x00, 0x00, 0x0C, 0x54, 0x75, 0x63, -0x75, 0x6D, 0x61, 0x6E, 0x20, 0x28, 0x54, 0x4D, 0x29, +0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, +0x03, 0x04, 0x03, 0x04, 0x03, 0x05, 0x03, 0x04, 0x03, 0x04, 0x02, 0x04, 0x05, 0x04, 0x03, 0x04, +0x03, 0x04, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, +0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, +0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, +0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x68, 0xFD, 0x00, 0xAF, 0x25, 0x3D, 0x00, 0x00, 0x00, 0x0C, +0x54, 0x75, 0x63, 0x75, 0x6D, 0x61, 0x6E, 0x20, 0x28, 0x54, 0x4D, 0x29, /* America/Argentina/Ushuaia */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1841,8 +1788,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x26, 0xFF, 0x00, 0xAB, -0x5B, 0x30, 0x00, 0x00, 0x00, 0x15, 0x54, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x64, 0x65, 0x6C, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x35, 0xB6, 0x00, 0x00, 0xAA, +0x70, 0xD0, 0x00, 0x00, 0x00, 0x15, 0x54, 0x69, 0x65, 0x72, 0x72, 0x61, 0x20, 0x64, 0x65, 0x6C, 0x20, 0x46, 0x75, 0x65, 0x67, 0x6F, 0x20, 0x28, 0x54, 0x46, 0x29, /* America/Aruba */ @@ -1851,8 +1798,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0C, 0x93, 0x1E, 0x2F, 0x38, 0xF6, 0x98, 0xEC, 0x48, 0x01, 0x02, 0xFF, 0xFF, 0xBE, 0x48, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0xB8, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x4E, 0x54, 0x00, -0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x67, 0x10, 0x00, 0xAA, -0xD8, 0xFA, 0x00, 0x00, 0x00, 0x00, +0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9C, 0x67, 0x10, 0x00, 0xA7, +0xE5, 0xC5, 0x00, 0x00, 0x00, 0x00, /* America/Asuncion */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x50, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1900,8 +1847,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0x01, 0x03, 0xFF, 0xFF, 0xC9, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0x41, 0x4D, 0x54, 0x00, 0x50, 0x59, 0x54, 0x00, 0x50, 0x59, 0x53, 0x54, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x96, 0xCA, 0x00, 0xBC, 0xB3, -0x4A, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0xC6, 0x75, 0x00, 0xBA, 0xAA, +0x75, 0x00, 0x00, 0x00, 0x00, /* America/Atikokan */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -1912,7 +1859,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x10, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xD3, 0xBA, 0x95, 0x00, 0x88, 0xC0, 0x76, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xD3, 0xBA, 0x95, 0x00, 0x86, 0xDA, 0xC9, 0x00, 0x00, 0x00, 0x44, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x41, 0x74, 0x69, 0x6B, 0x6F, 0x6B, 0x61, 0x6E, 0x2C, 0x20, 0x4F, 0x6E, 0x74, 0x61, 0x72, 0x69, 0x6F, 0x20, 0x61, 0x6E, 0x64, 0x20, @@ -2000,7 +1947,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xDB, 0xE4, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x42, 0x52, 0x53, 0x54, 0x00, 0x42, 0x52, -0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x84, 0xDD, 0x00, 0xD9, 0x76, 0x92, +0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0x84, 0xA2, 0x00, 0xD7, 0xE2, 0xED, 0x00, 0x00, 0x00, 0x05, 0x42, 0x61, 0x68, 0x69, 0x61, /* America/Barbados */ @@ -2013,7 +1960,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xC8, 0x1C, 0x00, 0x00, 0xFF, 0xFF, 0xC8, 0x1C, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x42, 0x4D, 0x54, 0x00, 0x41, 0x44, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, -0x51, 0x70, 0x00, 0xB9, 0x92, 0x82, 0x00, 0x00, 0x00, 0x00, +0x51, 0x70, 0x00, 0xB7, 0xB0, 0xBD, 0x00, 0x00, 0x00, 0x00, /* America/Belem */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2030,7 +1977,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xD2, 0x8C, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x42, 0x52, 0x53, 0x54, 0x00, 0x42, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x88, 0x7D, 0x68, 0x00, 0xCA, 0x27, 0x4D, 0x00, 0x00, 0x00, 0x0D, 0x41, 0x6D, +0x00, 0x00, 0x00, 0x87, 0x1D, 0xD8, 0x00, 0xC8, 0xAD, 0xB2, 0x00, 0x00, 0x00, 0x0D, 0x41, 0x6D, 0x61, 0x70, 0x61, 0x2C, 0x20, 0x45, 0x20, 0x50, 0x61, 0x72, 0x61, /* America/Belize */ @@ -2057,7 +2004,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xAD, 0x50, 0x00, 0x00, 0xFF, 0xFF, 0xB2, 0xA8, 0x01, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x09, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x48, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xA4, 0x08, 0x30, 0x00, 0x8C, 0xAF, 0xA0, 0x00, 0x00, 0x00, 0x00, +0x00, 0xA4, 0x08, 0x30, 0x00, 0x8C, 0x13, 0x60, 0x00, 0x00, 0x00, 0x00, /* America/Blanc-Sablon */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2067,7 +2014,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x01, 0x02, 0x03, 0x01, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x0C, 0x41, 0x44, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x41, 0x57, 0x54, 0x00, 0x41, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xD7, 0xC8, 0xE2, 0x00, 0xBB, 0xDC, 0x72, 0x00, 0x00, 0x00, +0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xD7, 0xC8, 0xE2, 0x00, 0xBB, 0x81, 0x4D, 0x00, 0x00, 0x00, 0x33, 0x41, 0x74, 0x6C, 0x61, 0x6E, 0x74, 0x69, 0x63, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x51, 0x75, 0x65, 0x62, 0x65, 0x63, 0x20, 0x2D, 0x20, 0x4C, 0x6F, 0x77, 0x65, 0x72, 0x20, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x20, 0x53, @@ -2089,7 +2036,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xC7, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x4D, 0x53, 0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8D, 0xA0, 0x82, 0x00, 0xB8, 0x1F, 0x6A, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8D, 0xA0, 0x82, 0x00, 0xB6, 0x16, 0x95, 0x00, 0x00, 0x00, 0x07, 0x52, 0x6F, 0x72, 0x61, 0x69, 0x6D, 0x61, /* America/Bogota */ @@ -2099,7 +2046,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x2A, 0x03, 0x73, 0x50, 0x2B, 0xBE, 0x5D, 0x40, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xBA, 0x8C, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x09, 0x42, 0x4D, 0x54, 0x00, 0x43, 0x4F, 0x53, 0x54, 0x00, 0x43, 0x4F, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x90, 0x59, 0x20, 0x00, 0xA1, 0xDE, 0xCD, 0x00, 0x00, 0x00, 0x00, +0x00, 0x90, 0x59, 0x20, 0x00, 0xA1, 0x9D, 0xB2, 0x00, 0x00, 0x00, 0x00, /* America/Boise */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x55, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2156,7 +2103,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x0C, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x10, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x14, 0x50, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0xCB, 0xE0, 0xD1, 0x00, 0x61, 0xF7, 0x1A, 0x00, 0x00, 0x00, 0x29, 0x4D, 0x6F, +0x00, 0x00, 0x00, 0xCB, 0xE0, 0xD1, 0x00, 0x61, 0x58, 0xE6, 0x00, 0x00, 0x00, 0x29, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x73, 0x6F, 0x75, 0x74, 0x68, 0x20, 0x49, 0x64, 0x61, 0x68, 0x6F, 0x20, 0x26, 0x20, 0x65, 0x61, 0x73, 0x74, 0x20, 0x4F, 0x72, 0x65, 0x67, 0x6F, 0x6E, @@ -2164,7 +2111,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { /* America/Buenos_Aires */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0D, 0xA2, 0x92, 0x8F, 0x30, +0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0D, 0xA2, 0x92, 0x8F, 0x30, 0xB6, 0x7B, 0x52, 0x40, 0xB7, 0x1A, 0xC9, 0xB0, 0xB8, 0x1E, 0x8F, 0x40, 0xB8, 0xD4, 0x70, 0x30, 0xBA, 0x17, 0x7D, 0xC0, 0xBA, 0xB5, 0xA3, 0xB0, 0xBB, 0xF8, 0xB1, 0x40, 0xBC, 0x96, 0xD7, 0x30, 0xBD, 0xD9, 0xE4, 0xC0, 0xBE, 0x78, 0x0A, 0xB0, 0xBF, 0xBB, 0x18, 0x40, 0xC0, 0x5A, 0x8F, 0xB0, @@ -2179,33 +2126,15 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x24, 0x10, 0x94, 0xA0, 0x25, 0x37, 0xF2, 0xB0, 0x25, 0xF0, 0x76, 0xA0, 0x27, 0x21, 0x0F, 0x30, 0x27, 0xD0, 0x58, 0xA0, 0x29, 0x00, 0xF1, 0x30, 0x29, 0xB0, 0x3A, 0xA0, 0x2A, 0xE0, 0xD3, 0x30, 0x2B, 0x99, 0x57, 0x20, 0x37, 0xF6, 0xC6, 0xB0, 0x38, 0xBF, 0x2A, 0xB0, 0x47, 0x77, 0x09, 0xB0, -0x47, 0xDC, 0x7F, 0x20, 0x48, 0xFA, 0xA2, 0xB0, 0x49, 0xBC, 0x61, 0x20, 0x4A, 0xDA, 0x84, 0xB0, -0x4B, 0xA5, 0x7D, 0xA0, 0x4C, 0xBA, 0x66, 0xB0, 0x4D, 0x85, 0x5F, 0xA0, 0x4E, 0x9A, 0x48, 0xB0, -0x4F, 0x65, 0x41, 0xA0, 0x50, 0x83, 0x65, 0x30, 0x51, 0x45, 0x23, 0xA0, 0x52, 0x63, 0x47, 0x30, -0x53, 0x25, 0x05, 0xA0, 0x54, 0x43, 0x29, 0x30, 0x55, 0x04, 0xE7, 0xA0, 0x56, 0x23, 0x0B, 0x30, -0x56, 0xEE, 0x04, 0x20, 0x58, 0x02, 0xED, 0x30, 0x58, 0xCD, 0xE6, 0x20, 0x59, 0xE2, 0xCF, 0x30, -0x5A, 0xAD, 0xC8, 0x20, 0x5B, 0xCB, 0xEB, 0xB0, 0x5C, 0x8D, 0xAA, 0x20, 0x5D, 0xAB, 0xCD, 0xB0, -0x5E, 0x6D, 0x8C, 0x20, 0x5F, 0x8B, 0xAF, 0xB0, 0x60, 0x56, 0xA8, 0xA0, 0x61, 0x6B, 0x91, 0xB0, -0x62, 0x36, 0x8A, 0xA0, 0x63, 0x4B, 0x73, 0xB0, 0x64, 0x16, 0x6C, 0xA0, 0x65, 0x2B, 0x55, 0xB0, -0x65, 0xF6, 0x4E, 0xA0, 0x67, 0x14, 0x72, 0x30, 0x67, 0xD6, 0x30, 0xA0, 0x68, 0xF4, 0x54, 0x30, -0x69, 0xB6, 0x12, 0xA0, 0x6A, 0xD4, 0x36, 0x30, 0x6B, 0x9F, 0x2F, 0x20, 0x6C, 0xB4, 0x18, 0x30, -0x6D, 0x7F, 0x11, 0x20, 0x6E, 0x93, 0xFA, 0x30, 0x6F, 0x5E, 0xF3, 0x20, 0x70, 0x7D, 0x16, 0xB0, -0x71, 0x3E, 0xD5, 0x20, 0x72, 0x5C, 0xF8, 0xB0, 0x73, 0x1E, 0xB7, 0x20, 0x74, 0x3C, 0xDA, 0xB0, -0x75, 0x07, 0xD3, 0xA0, 0x76, 0x1C, 0xBC, 0xB0, 0x76, 0xE7, 0xB5, 0xA0, 0x77, 0xFC, 0x9E, 0xB0, -0x78, 0xC7, 0x97, 0xA0, 0x79, 0xDC, 0x80, 0xB0, 0x7A, 0xA7, 0x79, 0xA0, 0x7B, 0xC5, 0x9D, 0x30, -0x7C, 0x87, 0x5B, 0xA0, 0x7D, 0xA5, 0x7F, 0x30, 0x7E, 0x67, 0x3D, 0xA0, 0x7F, 0x85, 0x61, 0x30, +0x47, 0xDC, 0x7F, 0x20, 0x48, 0xFA, 0xA2, 0xB0, 0x49, 0xBC, 0x61, 0x20, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, -0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, -0xD0, 0x00, 0x04, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, -0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, +0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, +0x03, 0x04, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, +0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, +0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, +0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, +0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, /* America/Cambridge_Bay */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2256,7 +2185,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x4D, 0x50, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x44, 0x44, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xF2, 0xC9, 0xDC, 0x00, 0x72, 0x85, 0x7D, 0x00, 0x00, 0x00, 0x1C, 0x4D, 0x6F, 0x75, 0x6E, +0x00, 0xF2, 0xC9, 0xDC, 0x00, 0x72, 0x5C, 0x42, 0x00, 0x00, 0x00, 0x1C, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x77, 0x65, 0x73, 0x74, 0x20, 0x4E, 0x75, 0x6E, 0x61, 0x76, 0x75, 0x74, @@ -2306,7 +2235,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xCC, 0xCC, 0x00, 0x00, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x4D, 0x53, 0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x6B, 0x7F, 0x88, 0x00, 0xC1, 0x33, 0xA2, 0x00, 0x00, 0x00, 0x12, 0x4D, 0x61, 0x74, +0x00, 0x00, 0x6A, 0x1F, 0xF8, 0x00, 0xBF, 0x51, 0xDD, 0x00, 0x00, 0x00, 0x12, 0x4D, 0x61, 0x74, 0x6F, 0x20, 0x47, 0x72, 0x6F, 0x73, 0x73, 0x6F, 0x20, 0x64, 0x6F, 0x20, 0x53, 0x75, 0x6C, /* America/Cancun */ @@ -2344,7 +2273,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA9, 0x7F, 0xED, 0x00, -0x90, 0x9A, 0x3A, 0x00, 0x00, 0x00, 0x1B, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, +0x8E, 0x43, 0x45, 0x00, 0x00, 0x00, 0x1B, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x51, 0x75, 0x69, 0x6E, 0x74, 0x61, 0x6E, 0x61, 0x20, 0x52, 0x6F, 0x6F, @@ -2355,7 +2284,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xF6, 0x98, 0xEC, 0x48, 0x47, 0x5B, 0x92, 0x70, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xC1, 0x44, 0x00, 0x00, 0xFF, 0xFF, 0xC0, 0xB8, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x43, 0x4D, 0x54, 0x00, 0x56, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x59, 0xD0, 0x00, -0xAF, 0x5F, 0xD5, 0x00, 0x00, 0x00, 0x00, +0xAC, 0x86, 0xAA, 0x00, 0x00, 0x00, 0x00, /* America/Catamarca */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2392,7 +2321,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF4, 0x2B, 0x90, 0xFB, 0xC3, 0x35, 0xC0, 0x01, 0x02, 0xFF, 0xFF, 0xCE, 0xF0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x47, 0x46, 0x54, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xDB, 0x55, 0x00, 0xC3, 0xD2, 0x35, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x90, 0xDB, 0x55, 0x00, 0xC2, 0xCD, 0xCA, 0x00, 0x00, 0x00, 0x00, /* America/Cayman */ @@ -2400,8 +2329,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x0F, 0xB5, 0x00, 0x01, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0x4B, 0x4D, 0x54, -0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xC7, 0x50, 0x00, 0x97, 0xA5, -0x9D, 0x00, 0x00, 0x00, 0x00, +0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA6, 0xC7, 0x50, 0x00, 0x96, 0x7A, +0x22, 0x00, 0x00, 0x00, 0x00, /* America/Chicago */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x55, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2484,7 +2413,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xB9, 0xB0, 0x00, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x10, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0xC9, 0x2F, 0xE8, 0x00, 0x8E, 0xE6, 0x08, 0x00, 0x00, 0x00, 0x0C, 0x43, 0x65, 0x6E, 0x74, 0x72, +0xC9, 0x2F, 0xE8, 0x00, 0x8C, 0xEA, 0x38, 0x00, 0x00, 0x00, 0x0C, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, /* America/Chihuahua */ @@ -2522,8 +2451,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x9C, 0x8C, 0x00, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5, 0x05, 0x25, 0x00, 0x71, -0x0A, 0xCD, 0x00, 0x00, 0x00, 0x19, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB5, 0x05, 0x25, 0x00, 0x70, +0xC9, 0xB2, 0x00, 0x00, 0x00, 0x19, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x43, 0x68, 0x69, 0x68, 0x75, 0x61, 0x68, 0x75, 0x61, /* America/Coral_Harbour */ @@ -2541,7 +2470,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { /* America/Cordoba */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12, 0xA2, 0x92, 0x8F, 0x30, +0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12, 0xA2, 0x92, 0x8F, 0x30, 0xB6, 0x7B, 0x52, 0x40, 0xB7, 0x1A, 0xC9, 0xB0, 0xB8, 0x1E, 0x8F, 0x40, 0xB8, 0xD4, 0x70, 0x30, 0xBA, 0x17, 0x7D, 0xC0, 0xBA, 0xB5, 0xA3, 0xB0, 0xBB, 0xF8, 0xB1, 0x40, 0xBC, 0x96, 0xD7, 0x30, 0xBD, 0xD9, 0xE4, 0xC0, 0xBE, 0x78, 0x0A, 0xB0, 0xBF, 0xBB, 0x18, 0x40, 0xC0, 0x5A, 0x8F, 0xB0, @@ -2556,34 +2485,16 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x24, 0x10, 0x94, 0xA0, 0x25, 0x37, 0xF2, 0xB0, 0x25, 0xF0, 0x76, 0xA0, 0x27, 0x21, 0x0F, 0x30, 0x27, 0xD0, 0x58, 0xA0, 0x29, 0x00, 0xFF, 0x40, 0x29, 0xB0, 0x3A, 0xA0, 0x2A, 0xE0, 0xD3, 0x30, 0x2B, 0x99, 0x57, 0x20, 0x37, 0xF6, 0xC6, 0xB0, 0x38, 0xBF, 0x2A, 0xB0, 0x47, 0x77, 0x09, 0xB0, -0x47, 0xDC, 0x7F, 0x20, 0x48, 0xFA, 0xA2, 0xB0, 0x49, 0xBC, 0x61, 0x20, 0x4A, 0xDA, 0x84, 0xB0, -0x4B, 0xA5, 0x7D, 0xA0, 0x4C, 0xBA, 0x66, 0xB0, 0x4D, 0x85, 0x5F, 0xA0, 0x4E, 0x9A, 0x48, 0xB0, -0x4F, 0x65, 0x41, 0xA0, 0x50, 0x83, 0x65, 0x30, 0x51, 0x45, 0x23, 0xA0, 0x52, 0x63, 0x47, 0x30, -0x53, 0x25, 0x05, 0xA0, 0x54, 0x43, 0x29, 0x30, 0x55, 0x04, 0xE7, 0xA0, 0x56, 0x23, 0x0B, 0x30, -0x56, 0xEE, 0x04, 0x20, 0x58, 0x02, 0xED, 0x30, 0x58, 0xCD, 0xE6, 0x20, 0x59, 0xE2, 0xCF, 0x30, -0x5A, 0xAD, 0xC8, 0x20, 0x5B, 0xCB, 0xEB, 0xB0, 0x5C, 0x8D, 0xAA, 0x20, 0x5D, 0xAB, 0xCD, 0xB0, -0x5E, 0x6D, 0x8C, 0x20, 0x5F, 0x8B, 0xAF, 0xB0, 0x60, 0x56, 0xA8, 0xA0, 0x61, 0x6B, 0x91, 0xB0, -0x62, 0x36, 0x8A, 0xA0, 0x63, 0x4B, 0x73, 0xB0, 0x64, 0x16, 0x6C, 0xA0, 0x65, 0x2B, 0x55, 0xB0, -0x65, 0xF6, 0x4E, 0xA0, 0x67, 0x14, 0x72, 0x30, 0x67, 0xD6, 0x30, 0xA0, 0x68, 0xF4, 0x54, 0x30, -0x69, 0xB6, 0x12, 0xA0, 0x6A, 0xD4, 0x36, 0x30, 0x6B, 0x9F, 0x2F, 0x20, 0x6C, 0xB4, 0x18, 0x30, -0x6D, 0x7F, 0x11, 0x20, 0x6E, 0x93, 0xFA, 0x30, 0x6F, 0x5E, 0xF3, 0x20, 0x70, 0x7D, 0x16, 0xB0, -0x71, 0x3E, 0xD5, 0x20, 0x72, 0x5C, 0xF8, 0xB0, 0x73, 0x1E, 0xB7, 0x20, 0x74, 0x3C, 0xDA, 0xB0, -0x75, 0x07, 0xD3, 0xA0, 0x76, 0x1C, 0xBC, 0xB0, 0x76, 0xE7, 0xB5, 0xA0, 0x77, 0xFC, 0x9E, 0xB0, -0x78, 0xC7, 0x97, 0xA0, 0x79, 0xDC, 0x80, 0xB0, 0x7A, 0xA7, 0x79, 0xA0, 0x7B, 0xC5, 0x9D, 0x30, -0x7C, 0x87, 0x5B, 0xA0, 0x7D, 0xA5, 0x7F, 0x30, 0x7E, 0x67, 0x3D, 0xA0, 0x7F, 0x85, 0x61, 0x30, +0x47, 0xDC, 0x7F, 0x20, 0x48, 0xFA, 0xA2, 0xB0, 0x49, 0xBC, 0x61, 0x20, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x05, 0x03, 0x04, 0x03, 0x04, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, -0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, -0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, -0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, -0x00, 0x00, 0x00, +0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x05, 0x03, 0x04, +0x03, 0x04, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, +0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, +0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, +0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, +0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, /* America/Costa_Rica */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2594,7 +2505,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xB1, 0x2C, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x05, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x09, 0x53, 0x4A, 0x4D, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, -0x7C, 0x75, 0x00, 0x92, 0x9C, 0x8D, 0x00, 0x00, 0x00, 0x00, +0x7C, 0x75, 0x00, 0x92, 0x5B, 0x72, 0x00, 0x00, 0x00, 0x00, /* America/Cuiaba */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2641,7 +2552,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xCB, 0x6C, 0x00, 0x00, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x4D, 0x53, 0x54, 0x00, 0x41, 0x4D, 0x54, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x54, 0xBD, 0x00, 0xBD, 0x56, 0x0D, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x8D, 0x02, 0x00, 0xBD, 0x14, 0xF2, 0x00, 0x00, 0x00, 0x0B, 0x4D, 0x61, 0x74, 0x6F, 0x20, 0x47, 0x72, 0x6F, 0x73, 0x73, 0x6F, /* America/Curacao */ @@ -2671,7 +2582,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x57, 0x47, 0x54, 0x00, 0x57, 0x47, 0x53, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, -0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xFE, 0x77, 0x3A, 0x00, 0xF8, 0x35, 0xAA, 0x00, +0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0xFE, 0x77, 0x3A, 0x00, 0xF6, 0x2C, 0xD5, 0x00, 0x00, 0x00, 0x21, 0x65, 0x61, 0x73, 0x74, 0x20, 0x63, 0x6F, 0x61, 0x73, 0x74, 0x2C, 0x20, 0x6E, 0x6F, 0x72, 0x74, 0x68, 0x20, 0x6F, 0x66, 0x20, 0x53, 0x63, 0x6F, 0x72, 0x65, 0x73, 0x62, 0x79, 0x73, 0x75, 0x6E, 0x64, @@ -2724,7 +2635,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x15, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x19, 0x59, 0x44, 0x54, 0x00, 0x59, 0x53, 0x54, 0x00, 0x59, 0x57, 0x54, 0x00, 0x59, 0x50, 0x54, 0x00, 0x59, 0x44, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x16, 0x4A, 0x00, 0x3F, 0x32, 0x62, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x16, 0x4A, 0x00, 0x3D, 0xEC, 0xDD, 0x00, 0x00, 0x00, 0x1A, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x6E, 0x6F, 0x72, 0x74, 0x68, 0x20, 0x59, 0x75, 0x6B, 0x6F, 0x6E, @@ -2753,7 +2664,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0x8F, 0x80, 0x00, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x10, 0x50, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xE4, 0x86, 0x9A, 0x00, 0x5B, 0xE8, 0xA5, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xE4, 0x86, 0x9A, 0x00, 0x5B, 0x32, 0x5A, 0x00, 0x00, 0x00, 0x49, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x44, 0x61, 0x77, 0x73, 0x6F, 0x6E, 0x20, 0x43, 0x72, 0x65, 0x65, 0x6B, 0x20, 0x26, 0x20, 0x46, 0x6F, 0x72, 0x74, 0x20, 0x53, 0x61, @@ -2816,7 +2727,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xA0, 0x01, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xC5, 0xF7, -0x5C, 0x00, 0x75, 0x77, 0xF0, 0x00, 0x00, 0x00, 0x0D, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, +0x5C, 0x00, 0x72, 0x77, 0x0F, 0x00, 0x00, 0x00, 0x0D, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, /* America/Detroit */ @@ -2871,7 +2782,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x10, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x57, 0x54, 0x00, 0x45, 0x50, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xC9, 0xEB, 0xF2, 0x00, -0x94, 0x14, 0x87, 0x00, 0x00, 0x00, 0x28, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, +0x93, 0xF0, 0xB8, 0x00, 0x00, 0x00, 0x28, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4D, 0x69, 0x63, 0x68, 0x69, 0x67, 0x61, 0x6E, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, @@ -2880,8 +2791,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF4, 0x34, 0x4C, 0x01, 0xFF, 0xFF, 0xC6, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xAC, 0xD0, 0x00, 0xB6, 0x30, -0xA0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0xAC, 0xD0, 0x00, 0xB4, 0xF8, +0x20, 0x00, 0x00, 0x00, 0x00, /* America/Edmonton */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -2938,8 +2849,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x95, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xDB, 0x0A, 0x38, 0x00, 0x66, -0xF2, 0x2A, 0x00, 0x00, 0x00, 0x42, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xDB, 0x0A, 0x38, 0x00, 0x65, +0x85, 0x95, 0x00, 0x00, 0x00, 0x42, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x41, 0x6C, 0x62, 0x65, 0x72, 0x74, 0x61, 0x2C, 0x20, 0x65, 0x61, 0x73, 0x74, 0x20, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x43, 0x6F, 0x6C, 0x75, 0x6D, 0x62, 0x69, 0x61, 0x20, 0x26, 0x20, 0x77, 0x65, 0x73, 0x74, 0x20, 0x53, 0x61, 0x73, 0x6B, @@ -2961,8 +2872,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x03, 0xFF, 0xFF, 0xBE, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x09, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x43, 0x53, 0x54, 0x00, 0x41, 0x43, 0x54, -0x00, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x81, 0x30, -0xEA, 0x00, 0xAA, 0xB1, 0xEA, 0x00, 0x00, 0x00, 0x0A, 0x57, 0x20, 0x41, 0x6D, 0x61, 0x7A, 0x6F, +0x00, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x28, +0x15, 0x00, 0xA8, 0x0C, 0xD5, 0x00, 0x00, 0x00, 0x0A, 0x57, 0x20, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x61, 0x73, /* America/El_Salvador */ @@ -2972,8 +2883,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x20, 0x9A, 0xDC, 0xE0, 0x21, 0x5C, 0x9B, 0x50, 0x22, 0x7A, 0xBE, 0xE0, 0x23, 0x3C, 0x7D, 0x50, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xAC, 0x60, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x43, -0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x3B, 0xD0, 0x00, 0x8B, 0x29, -0x00, 0x00, 0x00, 0x00, 0x00, +0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9E, 0x3B, 0xD0, 0x00, 0x8A, 0x8C, +0xC0, 0x00, 0x00, 0x00, 0x00, /* America/Ensenada */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3050,7 +2961,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xDB, 0xE8, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x42, 0x52, 0x53, 0x54, 0x00, 0x42, 0x52, 0x54, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x85, 0xD8, 0x52, 0x00, 0xD9, 0x70, 0x10, 0x00, 0x00, 0x00, 0x1E, +0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0xA8, 0x6D, 0x00, 0xD7, 0xE9, 0x70, 0x00, 0x00, 0x00, 0x1E, 0x4E, 0x45, 0x20, 0x42, 0x72, 0x61, 0x7A, 0x69, 0x6C, 0x20, 0x28, 0x4D, 0x41, 0x2C, 0x20, 0x50, 0x49, 0x2C, 0x20, 0x43, 0x45, 0x2C, 0x20, 0x52, 0x4E, 0x2C, 0x20, 0x50, 0x42, 0x29, @@ -3146,7 +3057,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xD5, 0xD0, 0x01, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x0C, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x44, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x41, 0x57, 0x54, 0x00, 0x41, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0xCF, 0xD3, 0x1F, 0x00, 0xBA, 0x14, 0xB8, 0x00, 0x00, 0x00, 0x47, +0x00, 0x00, 0x00, 0x01, 0x00, 0xCF, 0xD3, 0x1F, 0x00, 0xB7, 0x2E, 0x88, 0x00, 0x00, 0x00, 0x47, 0x41, 0x74, 0x6C, 0x61, 0x6E, 0x74, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4E, 0x6F, 0x76, 0x61, 0x20, 0x53, 0x63, 0x6F, 0x74, 0x69, 0x61, 0x20, 0x2D, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x64, 0x69, 0x64, 0x20, 0x6E, 0x6F, @@ -3196,8 +3107,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x03, 0x02, 0x03, 0x02, 0xFF, 0xFF, 0xCF, 0x80, 0x00, 0x00, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x57, 0x47, 0x54, 0x00, 0x57, 0x47, 0x53, 0x54, 0x00, -0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xEB, 0x43, 0xDD, 0x00, 0xC5, -0xF5, 0x15, 0x00, 0x00, 0x00, 0x0E, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, +0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xEB, 0x43, 0xDD, 0x00, 0xC3, +0xB8, 0x2A, 0x00, 0x00, 0x00, 0x0E, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, /* America/Goose_Bay */ @@ -3273,7 +3184,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xC0, 0x00, 0x14, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x18, 0x4E, 0x53, 0x54, 0x00, 0x4E, 0x44, 0x54, 0x00, 0x4E, 0x50, 0x54, 0x00, 0x4E, 0x57, 0x54, 0x00, 0x41, 0x44, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x41, 0x44, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDA, 0xB5, 0x95, 0x00, 0xB7, 0xBD, 0xC2, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0xDA, 0xB5, 0x95, 0x00, 0xB6, 0x78, 0x3D, 0x00, 0x00, 0x00, 0x29, 0x41, 0x74, 0x6C, 0x61, 0x6E, 0x74, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4C, 0x61, 0x62, 0x72, 0x61, 0x64, 0x6F, 0x72, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, @@ -3321,23 +3232,23 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x08, 0x4B, 0x4D, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xAA, 0x15, 0xAA, 0x00, 0xA6, 0x86, 0x35, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0xAA, 0x15, 0xAA, 0x00, 0xA6, 0x1E, 0x0A, 0x00, 0x00, 0x00, 0x00, /* America/Grenada */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x47, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF4, 0x34, 0x64, 0x01, 0xFF, 0xFF, 0xC6, 0x1C, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0xB7, 0x48, 0x00, 0xB6, 0xB9, -0x58, 0x00, 0x00, 0x00, 0x00, +0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0xB7, 0x48, 0x00, 0xB4, 0x6F, +0x68, 0x00, 0x00, 0x00, 0x00, /* America/Guadeloupe */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x47, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xD5, 0xE1, 0xB0, 0x01, 0xFF, 0xFF, 0xC6, 0x50, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x19, 0x65, 0x00, 0xB6, 0x64, -0xB5, 0x00, 0x00, 0x00, 0x00, +0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0x19, 0x65, 0x00, 0xB4, 0xC4, +0x0A, 0x00, 0x00, 0x00, 0x00, /* America/Guatemala */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x47, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3348,15 +3259,15 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xAB, 0x24, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9F, 0xA8, -0x65, 0x00, 0x8A, 0x1E, 0x12, 0x00, 0x00, 0x00, 0x00, +0x65, 0x00, 0x88, 0x8A, 0x6D, 0x00, 0x00, 0x00, 0x00, /* America/Guayaquil */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x45, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0xB6, 0xA4, 0x42, 0x18, 0x01, 0xFF, 0xFF, 0xB6, 0x68, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0x51, 0x4D, 0x54, -0x00, 0x45, 0x43, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x88, 0x1A, 0x00, 0x9B, 0x62, -0xA5, 0x00, 0x00, 0x00, 0x08, 0x6D, 0x61, 0x69, 0x6E, 0x6C, 0x61, 0x6E, 0x64, +0x00, 0x45, 0x43, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x05, 0xE5, 0x00, 0x98, 0xD7, +0x9A, 0x00, 0x00, 0x00, 0x08, 0x6D, 0x61, 0x69, 0x6E, 0x6C, 0x61, 0x6E, 0x64, /* America/Guyana */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x47, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -3366,7 +3277,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0xC9, 0x78, 0x00, 0x00, 0xFF, 0xFF, 0xCB, 0x44, 0x00, 0x04, 0xFF, 0xFF, 0xCB, 0x44, 0x00, 0x09, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x09, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x47, 0x42, 0x47, 0x54, 0x00, 0x47, 0x59, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0xB4, 0x80, 0x00, 0xBA, 0x69, 0x5A, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x93, 0xB4, 0x80, 0x00, 0xB9, 0xE7, 0x25, 0x00, 0x00, 0x00, 0x00, /* America/Halifax */ @@ -3448,7 +3359,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x0C, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x44, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x41, 0x57, 0x54, 0x00, 0x41, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xCD, 0x75, 0xA8, -0x00, 0xB3, 0x71, 0x80, 0x00, 0x00, 0x00, 0x2E, 0x41, 0x74, 0x6C, 0x61, 0x6E, 0x74, 0x69, 0x63, +0x00, 0xB1, 0x9C, 0xC0, 0x00, 0x00, 0x00, 0x2E, 0x41, 0x74, 0x6C, 0x61, 0x6E, 0x74, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4E, 0x6F, 0x76, 0x61, 0x20, 0x53, 0x63, 0x6F, 0x74, 0x69, 0x61, 0x20, 0x28, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x73, 0x29, 0x2C, 0x20, 0x50, 0x45, 0x49, @@ -3508,7 +3419,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x03, 0x04, 0x03, 0xFF, 0xFF, 0xB2, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x08, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0x48, 0x4D, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, -0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xA0, 0xB5, 0x00, 0x96, 0x18, 0x7A, 0x00, +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xA0, 0xB5, 0x00, 0x94, 0xFA, 0x05, 0x00, 0x00, 0x00, 0x00, /* America/Hermosillo */ @@ -3523,7 +3434,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x90, 0x00, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x08, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xB5, 0xAE, 0x6A, 0x00, 0x6C, 0x49, 0x5A, 0x00, 0x00, 0x00, 0x1F, 0x4D, +0x00, 0x00, 0x00, 0x00, 0xB5, 0xAE, 0x6A, 0x00, 0x69, 0x56, 0x25, 0x00, 0x00, 0x00, 0x1F, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x53, 0x6F, 0x6E, 0x6F, 0x72, 0x61, @@ -3566,7 +3477,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xB9, 0xB0, 0x00, 0x10, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x14, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC6, -0x02, 0xC1, 0x00, 0x8F, 0xAC, 0x7D, 0x00, 0x00, 0x00, 0x27, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, +0x02, 0xC1, 0x00, 0x8F, 0x31, 0x02, 0x00, 0x00, 0x00, 0x27, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x49, 0x6E, 0x64, 0x69, 0x61, 0x6E, 0x61, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, @@ -3626,7 +3537,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xAB, 0xA0, 0x00, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x10, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xC8, 0x57, 0x6F, 0x00, 0x90, 0x62, 0xE4, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xC8, 0x57, 0x6F, 0x00, 0x8E, 0x7A, 0x9C, 0x00, 0x00, 0x00, 0x26, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x49, 0x6E, 0x64, 0x69, 0x61, 0x6E, 0x61, 0x20, 0x2D, 0x20, 0x53, 0x74, 0x61, 0x72, 0x6B, 0x65, 0x20, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x79, @@ -3671,7 +3582,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x10, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x14, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0xC3, 0xE2, 0xB3, 0x00, 0x8F, 0xF5, 0x68, 0x00, 0x00, 0x00, 0x28, 0x45, 0x61, +0x00, 0x00, 0x00, 0xC3, 0xE2, 0xB3, 0x00, 0x8E, 0xE8, 0x17, 0x00, 0x00, 0x00, 0x28, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x49, 0x6E, 0x64, 0x69, 0x61, 0x6E, 0x61, 0x20, 0x2D, 0x20, 0x43, 0x72, 0x61, 0x77, 0x66, 0x6F, 0x72, 0x64, 0x20, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x79, @@ -3720,7 +3631,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x10, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x14, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0xC4, 0x10, 0x2A, 0x00, 0x8E, 0x54, 0xF5, 0x00, 0x00, 0x00, 0x24, 0x45, +0x01, 0x00, 0x00, 0x00, 0xC4, 0x10, 0x2A, 0x00, 0x8D, 0x7B, 0x4A, 0x00, 0x00, 0x00, 0x24, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x49, 0x6E, 0x64, 0x69, 0x61, 0x6E, 0x61, 0x20, 0x2D, 0x20, 0x50, 0x69, 0x6B, 0x65, 0x20, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x79, @@ -3805,7 +3716,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x10, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x14, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC3, 0x3D, 0xA9, 0x00, 0x90, 0x98, 0x2A, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC3, 0x3D, 0xA9, 0x00, 0x8E, 0x45, 0x55, 0x00, 0x00, 0x00, 0x25, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x49, 0x6E, 0x64, 0x69, 0x61, 0x6E, 0x61, 0x20, 0x2D, 0x20, 0x50, 0x65, 0x72, 0x72, 0x79, 0x20, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x79, @@ -3843,7 +3754,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xB9, 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x10, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x14, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x01, 0x00, 0x00, 0x00, 0xC4, 0x74, 0x19, 0x00, 0x91, 0x0F, 0xA2, 0x00, 0x00, 0x00, 0x2B, +0x00, 0x01, 0x00, 0x00, 0x00, 0xC4, 0x74, 0x19, 0x00, 0x90, 0xDB, 0x1D, 0x00, 0x00, 0x00, 0x2B, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x49, 0x6E, 0x64, 0x69, 0x61, 0x6E, 0x61, 0x20, 0x2D, 0x20, 0x53, 0x77, 0x69, 0x74, 0x7A, 0x65, 0x72, 0x6C, 0x61, 0x6E, 0x64, 0x20, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x79, @@ -3887,7 +3798,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x10, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x14, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC4, 0x58, 0x8A, 0x00, 0x8E, 0xB6, 0x9D, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC4, 0x58, 0x8A, 0x00, 0x8D, 0x19, 0xA2, 0x00, 0x00, 0x00, 0x40, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x49, 0x6E, 0x64, 0x69, 0x61, 0x6E, 0x61, 0x20, 0x2D, 0x20, 0x44, 0x61, 0x76, 0x69, 0x65, 0x73, 0x73, 0x2C, 0x20, 0x44, 0x75, 0x62, 0x6F, 0x69, 0x73, 0x2C, 0x20, 0x4B, 0x6E, @@ -3935,7 +3846,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x10, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x14, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC7, 0xF7, 0xF2, 0x00, 0x90, 0x5A, 0x51, 0x00, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC7, 0xF7, 0xF2, 0x00, 0x8E, 0x83, 0x2E, 0x00, 0x00, 0x00, 0x27, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x49, 0x6E, 0x64, 0x69, 0x61, 0x6E, 0x61, 0x20, 0x2D, 0x20, 0x50, 0x75, 0x6C, 0x61, 0x73, 0x6B, 0x69, 0x20, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x79, @@ -3985,7 +3896,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x09, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x0D, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x11, 0x7A, 0x7A, 0x7A, 0x00, 0x50, 0x44, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0xF1, 0x9F, 0x5C, 0x00, 0x48, 0xCF, 0x52, 0x00, 0x00, 0x00, 0x2A, 0x4D, 0x6F, 0x75, +0x00, 0x00, 0xF1, 0x9F, 0x5C, 0x00, 0x46, 0x9F, 0x6D, 0x00, 0x00, 0x00, 0x2A, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x77, 0x65, 0x73, 0x74, 0x20, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x77, 0x65, 0x73, 0x74, 0x20, 0x54, 0x65, 0x72, 0x72, 0x69, 0x74, 0x6F, 0x72, 0x69, 0x65, 0x73, @@ -4037,8 +3948,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xA0, 0x00, 0x19, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x1D, 0x7A, 0x7A, 0x7A, 0x00, 0x45, 0x50, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x44, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x45, 0x57, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0x94, 0x15, 0x00, 0xAB, -0x9C, 0x4A, 0x00, 0x00, 0x00, 0x2C, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEA, 0x94, 0x15, 0x00, 0xAA, +0x2F, 0xB5, 0x00, 0x00, 0x00, 0x2C, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x65, 0x61, 0x73, 0x74, 0x20, 0x4E, 0x75, 0x6E, 0x61, 0x76, 0x75, 0x74, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, @@ -4055,7 +3966,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xB8, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x08, 0x4B, 0x4D, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, -0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xCB, 0x80, 0x00, 0x9F, 0xE9, +0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xCB, 0x80, 0x00, 0x9D, 0x78, 0x80, 0x00, 0x00, 0x00, 0x00, /* America/Jujuy */ @@ -4141,7 +4052,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x1D, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00, 0x59, 0x53, 0x54, 0x00, 0x59, 0x44, 0x54, 0x00, 0x41, 0x4B, 0x44, 0x54, 0x00, 0x41, 0x4B, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0x4A, 0x72, 0x00, 0x46, 0xD4, 0xB4, 0x00, 0x00, 0x00, 0x1E, +0x00, 0x00, 0x00, 0x00, 0x00, 0xE2, 0x4A, 0x72, 0x00, 0x45, 0x8C, 0xCB, 0x00, 0x00, 0x00, 0x1E, 0x41, 0x6C, 0x61, 0x73, 0x6B, 0x61, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x41, 0x6C, 0x61, 0x73, 0x6B, 0x61, 0x20, 0x70, 0x61, 0x6E, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, @@ -4208,8 +4119,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xB0, 0x01, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x10, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x14, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC3, 0xB3, 0x48, 0x00, 0x92, 0x1E, -0x08, 0x00, 0x00, 0x00, 0x29, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, +0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xC3, 0xB3, 0x48, 0x00, 0x8F, 0xCC, +0xB7, 0x00, 0x00, 0x00, 0x29, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4B, 0x65, 0x6E, 0x74, 0x75, 0x63, 0x6B, 0x79, 0x20, 0x2D, 0x20, 0x4C, 0x6F, 0x75, 0x69, 0x73, 0x76, 0x69, 0x6C, 0x6C, 0x65, 0x20, 0x61, 0x72, 0x65, 0x61, @@ -4267,7 +4178,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x10, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x14, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0x00, 0xC1, 0x86, 0xDC, 0x00, 0x93, 0xC7, 0xB4, 0x00, 0x00, 0x00, 0x26, 0x45, +0x01, 0x00, 0x00, 0x00, 0xC1, 0x86, 0xDC, 0x00, 0x91, 0x30, 0x4B, 0x00, 0x00, 0x00, 0x26, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4B, 0x65, 0x6E, 0x74, 0x75, 0x63, 0x6B, 0x79, 0x20, 0x2D, 0x20, 0x57, 0x61, 0x79, 0x6E, 0x65, 0x20, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x79, @@ -4336,8 +4247,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0xB8, 0x1E, 0x96, 0xE4, 0xB8, 0xEE, 0xD5, 0xD4, 0x01, 0x02, 0xFF, 0xFF, 0xC0, 0x1C, 0x00, 0x00, 0xFF, 0xFF, 0xCE, 0x2C, 0x01, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x09, 0x43, 0x4D, 0x54, 0x00, 0x42, 0x4F, 0x53, 0x54, -0x00, 0x42, 0x4F, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0xAD, 0x90, 0x00, -0xAB, 0x20, 0x98, 0x00, 0x00, 0x00, 0x00, +0x00, 0x42, 0x4F, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x26, 0xF0, 0x00, +0xAA, 0xAB, 0x68, 0x00, 0x00, 0x00, 0x00, /* America/Lima */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x50, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -4349,8 +4260,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x2D, 0x25, 0x03, 0x50, 0x2D, 0x9B, 0x9C, 0x40, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xB7, 0xAC, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x45, 0x53, -0x54, 0x00, 0x50, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x18, 0x48, -0x00, 0x9D, 0x3D, 0xE8, 0x00, 0x00, 0x00, 0x00, +0x54, 0x00, 0x50, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xF1, 0x38, +0x00, 0x9D, 0x16, 0xD8, 0x00, 0x00, 0x00, 0x00, /* America/Los_Angeles */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x55, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -4416,8 +4327,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x00, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C, 0x50, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, -0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xBD, 0x49, 0xE6, 0x00, 0x5E, 0xF9, -0x95, 0x00, 0x00, 0x00, 0x0C, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, +0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xBD, 0x49, 0xE6, 0x00, 0x5E, 0x3B, +0xEA, 0x00, 0x00, 0x00, 0x0C, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, /* America/Louisville */ @@ -4504,8 +4415,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xDE, 0x84, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x42, -0x52, 0x53, 0x54, 0x00, 0x42, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, -0x9D, 0x0A, 0x00, 0xDE, 0x58, 0x92, 0x00, 0x00, 0x00, 0x10, 0x41, 0x6C, 0x61, 0x67, 0x6F, 0x61, +0x52, 0x53, 0x54, 0x00, 0x42, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, +0x94, 0x35, 0x00, 0xDC, 0x28, 0xAD, 0x00, 0x00, 0x00, 0x10, 0x41, 0x6C, 0x61, 0x67, 0x6F, 0x61, 0x73, 0x2C, 0x20, 0x53, 0x65, 0x72, 0x67, 0x69, 0x70, 0x65, /* America/Managua */ @@ -4519,7 +4430,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x02, 0x01, 0x03, 0x01, 0x03, 0x01, 0xFF, 0xFF, 0xAF, 0x18, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0x4D, 0x4D, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0xDE, 0x58, 0x00, 0x8F, 0xDD, 0x6D, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9B, 0xDE, 0x58, 0x00, 0x8F, 0x00, 0x12, 0x00, 0x00, 0x00, 0x00, /* America/Manaus */ @@ -4537,8 +4448,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xC7, 0xBC, 0x00, 0x00, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x4D, 0x53, -0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0xF4, 0x75, -0x00, 0xB7, 0x21, 0x82, 0x00, 0x00, 0x00, 0x0A, 0x45, 0x20, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, +0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x8C, 0x4A, +0x00, 0xB7, 0x14, 0x7D, 0x00, 0x00, 0x00, 0x0A, 0x45, 0x20, 0x41, 0x6D, 0x61, 0x7A, 0x6F, 0x6E, 0x61, 0x73, /* America/Marigot */ @@ -4546,8 +4457,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xD5, 0xE1, 0xB0, 0x01, 0xFF, 0xFF, 0xC6, 0x50, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xE5, 0x8A, 0x00, 0xB2, 0xA7, -0xAD, 0x00, 0x00, 0x00, 0x00, +0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0xE5, 0x8A, 0x00, 0xB2, 0x66, +0x92, 0x00, 0x00, 0x00, 0x00, /* America/Martinique */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4D, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -4556,7 +4467,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x13, 0x4D, 0x6E, 0x40, 0x14, 0x34, 0x16, 0xB0, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xC6, 0xBC, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x05, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x09, 0x46, 0x46, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x41, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x9F, 0x9B, 0x60, 0x00, 0xB5, 0xB4, 0xED, 0x00, 0x00, 0x00, 0x00, +0x00, 0x9F, 0x9B, 0x60, 0x00, 0xB5, 0x73, 0xD2, 0x00, 0x00, 0x00, 0x00, /* America/Mazatlan */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4D, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -4594,8 +4505,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x3C, 0x00, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x08, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xC1, 0x42, 0x00, 0x71, 0x8D, -0x02, 0x00, 0x00, 0x00, 0x28, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, 0x69, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAC, 0xC1, 0x42, 0x00, 0x70, 0x47, +0x7D, 0x00, 0x00, 0x00, 0x28, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x53, 0x20, 0x42, 0x61, 0x6A, 0x61, 0x2C, 0x20, 0x4E, 0x61, 0x79, 0x61, 0x72, 0x69, 0x74, 0x2C, 0x20, 0x53, 0x69, 0x6E, 0x61, 0x6C, 0x6F, 0x61, @@ -4681,7 +4592,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xB9, 0xB0, 0x01, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x10, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xCE, -0x28, 0x79, 0x00, 0x8E, 0xD8, 0x08, 0x00, 0x00, 0x00, 0x47, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, +0x28, 0x79, 0x00, 0x8C, 0xF8, 0x37, 0x00, 0x00, 0x00, 0x47, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4D, 0x69, 0x63, 0x68, 0x69, 0x67, 0x61, 0x6E, 0x20, 0x2D, 0x20, 0x44, 0x69, 0x63, 0x6B, 0x69, 0x6E, 0x73, 0x6F, 0x6E, 0x2C, 0x20, 0x47, 0x6F, 0x67, 0x65, 0x62, 0x69, 0x63, 0x2C, 0x20, 0x49, 0x72, 0x6F, 0x6E, 0x20, 0x26, 0x20, 0x4D, @@ -4722,7 +4633,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xAB, 0xFC, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0xA9, 0x52, 0x5A, 0x00, 0x8B, 0xCB, 0xC2, 0x00, 0x00, 0x00, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x72, +0xA9, 0x52, 0x5A, 0x00, 0x89, 0xE9, 0xFD, 0x00, 0x00, 0x00, 0x20, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x43, 0x61, 0x6D, 0x70, 0x65, 0x63, 0x68, 0x65, 0x2C, 0x20, 0x59, 0x75, 0x63, 0x61, 0x74, 0x61, 0x6E, @@ -4764,7 +4675,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x10, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xA6, 0xEE, 0x60, 0x00, 0x7B, 0xD3, 0x38, 0x00, 0x00, 0x00, 0x1D, 0x43, 0x65, +0x00, 0x00, 0x00, 0xA6, 0xEE, 0x60, 0x00, 0x7B, 0x5E, 0x07, 0x00, 0x00, 0x00, 0x1D, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, @@ -4807,7 +4718,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x03, 0x02, 0x03, 0x02, 0xFF, 0xFF, 0xCB, 0x58, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x50, 0x4D, 0x53, 0x54, 0x00, 0x50, 0x4D, 0x44, 0x54, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0x1F, 0x28, 0x00, 0xBD, 0xB7, 0xB5, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD1, 0x1F, 0x28, 0x00, 0xBC, 0xB3, 0x4A, 0x00, 0x00, 0x00, 0x00, /* America/Moncton */ @@ -4882,7 +4793,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xC7, 0xC0, 0x00, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x0C, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x10, 0x45, 0x53, 0x54, 0x00, 0x41, 0x44, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x41, 0x57, 0x54, 0x00, 0x41, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xCF, -0xAC, 0x10, 0x00, 0xB2, 0x32, 0x7D, 0x00, 0x00, 0x00, 0x1D, 0x41, 0x74, 0x6C, 0x61, 0x6E, 0x74, +0xAC, 0x10, 0x00, 0xAF, 0xCE, 0x82, 0x00, 0x00, 0x00, 0x1D, 0x41, 0x74, 0x6C, 0x61, 0x6E, 0x74, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4E, 0x65, 0x77, 0x20, 0x42, 0x72, 0x75, 0x6E, 0x73, 0x77, 0x69, 0x63, 0x6B, @@ -4919,7 +4830,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xA1, 0xF4, 0x00, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0xB0, 0x7E, 0x4A, 0x00, 0x7A, 0x8D, 0xB2, 0x00, 0x00, 0x00, 0x38, 0x43, +0x00, 0x00, 0x00, 0x00, 0xB0, 0x7E, 0x4A, 0x00, 0x79, 0x96, 0x4D, 0x00, 0x00, 0x00, 0x38, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x43, 0x6F, 0x61, 0x68, 0x75, 0x69, 0x6C, 0x61, 0x2C, 0x20, 0x44, 0x75, 0x72, 0x61, 0x6E, 0x67, 0x6F, 0x2C, 0x20, 0x4E, 0x75, 0x65, 0x76, 0x6F, 0x20, 0x4C, 0x65, 0x6F, 0x6E, 0x2C, 0x20, 0x54, 0x61, 0x6D, @@ -4974,7 +4885,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xC8, 0x00, 0x0A, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x0A, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x0E, 0xFF, 0xFF, 0xDC, 0xD8, 0x01, 0x04, 0x4D, 0x4D, 0x54, 0x00, 0x55, 0x59, 0x48, 0x53, 0x54, 0x00, 0x55, 0x59, 0x54, 0x00, 0x55, 0x59, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x56, 0xCC, 0x0D, 0x00, 0xBD, 0x7D, 0x1D, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x19, 0xF2, 0x00, 0xBC, 0xED, 0xE2, 0x00, 0x00, 0x00, 0x00, /* America/Montreal */ @@ -5056,7 +4967,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x08, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x0C, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x57, 0x54, 0x00, 0x45, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x01, 0x00, 0xCE, 0xC8, 0x32, 0x00, 0xA4, 0x22, 0x3A, 0x00, 0x00, 0x00, 0x26, +0x00, 0x00, 0x00, 0x01, 0x00, 0xCE, 0xC8, 0x32, 0x00, 0xA2, 0x67, 0x85, 0x00, 0x00, 0x00, 0x26, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x51, 0x75, 0x65, 0x62, 0x65, 0x63, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, @@ -5066,8 +4977,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF4, 0x35, 0x10, 0x01, 0xFF, 0xFF, 0xC5, 0xAC, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xD6, 0x32, 0x00, 0xB4, 0x62, -0x62, 0x00, 0x00, 0x00, 0x00, +0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xD6, 0x32, 0x00, 0xB3, 0xB9, +0x1D, 0x00, 0x00, 0x00, 0x00, /* America/Nassau */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -5121,8 +5032,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xB7, 0x7C, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x45, -0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x9A, 0x6D, 0x00, 0x9D, 0xB3, -0x18, 0x00, 0x00, 0x00, 0x00, +0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x9A, 0x6D, 0x00, 0x9C, 0xA1, +0xA8, 0x00, 0x00, 0x00, 0x00, /* America/New_York */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x55, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -5204,7 +5115,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x08, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x0C, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x57, 0x54, 0x00, 0x45, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, -0x00, 0x00, 0x01, 0x00, 0xC7, 0x74, 0x38, 0x00, 0xA1, 0xC0, 0xBE, 0x00, 0x00, 0x00, 0x0C, 0x45, +0x00, 0x00, 0x01, 0x00, 0xC7, 0x74, 0x38, 0x00, 0xA1, 0xBB, 0xC1, 0x00, 0x00, 0x00, 0x0C, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, /* America/Nipigon */ @@ -5255,8 +5166,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x08, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x0C, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x57, 0x54, 0x00, 0x45, 0x50, -0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xD4, 0x1F, 0x62, 0x00, 0x8C, -0xC9, 0xAA, 0x00, 0x00, 0x00, 0x4B, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, +0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xD4, 0x1F, 0x62, 0x00, 0x8B, +0xF9, 0x55, 0x00, 0x00, 0x00, 0x4B, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4F, 0x6E, 0x74, 0x61, 0x72, 0x69, 0x6F, 0x20, 0x26, 0x20, 0x51, 0x75, 0x65, 0x62, 0x65, 0x63, 0x20, 0x2D, 0x20, 0x70, 0x6C, 0x61, 0x63, 0x65, 0x73, 0x20, 0x74, 0x68, 0x61, 0x74, 0x20, 0x64, 0x69, 0x64, 0x20, 0x6E, 0x6F, 0x74, 0x20, 0x6F, 0x62, 0x73, 0x65, @@ -5317,8 +5228,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x18, 0xFF, 0xFF, 0x81, 0x70, 0x00, 0x1D, 0x4E, 0x53, 0x54, 0x00, 0x4E, 0x57, 0x54, 0x00, 0x4E, 0x50, 0x54, 0x00, 0x42, 0x53, 0x54, 0x00, 0x42, 0x44, 0x54, 0x00, 0x59, 0x53, 0x54, 0x00, 0x41, 0x4B, 0x44, 0x54, 0x00, 0x41, 0x4B, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEB, 0xBF, 0xFF, 0x00, 0x17, 0x82, -0x1E, 0x00, 0x00, 0x00, 0x19, 0x41, 0x6C, 0x61, 0x73, 0x6B, 0x61, 0x20, 0x54, 0x69, 0x6D, 0x65, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEB, 0xBF, 0xFF, 0x00, 0x16, 0x44, +0xA1, 0x00, 0x00, 0x00, 0x19, 0x41, 0x6C, 0x61, 0x73, 0x6B, 0x61, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x77, 0x65, 0x73, 0x74, 0x20, 0x41, 0x6C, 0x61, 0x73, 0x6B, 0x61, /* America/Noronha */ @@ -5339,7 +5250,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xE1, 0x9C, 0x00, 0x00, 0xFF, 0xFF, 0xF1, 0xF0, 0x01, 0x04, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x46, 0x4E, 0x53, 0x54, 0x00, 0x46, 0x4E, 0x54, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x86, 0x0C, 0x68, 0x00, 0xE2, 0x77, 0x42, 0x00, 0x00, 0x00, 0x10, +0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x74, 0x58, 0x00, 0xE1, 0x31, 0xBD, 0x00, 0x00, 0x00, 0x10, 0x41, 0x74, 0x6C, 0x61, 0x6E, 0x74, 0x69, 0x63, 0x20, 0x69, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, @@ -5398,7 +5309,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xB0, 0x01, 0x10, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x14, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD1, 0x39, -0x16, 0x00, 0x79, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x2B, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, +0x16, 0x00, 0x78, 0x16, 0x83, 0x00, 0x00, 0x00, 0x2B, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x20, 0x44, 0x61, 0x6B, 0x6F, 0x74, 0x61, 0x20, 0x2D, 0x20, 0x4F, 0x6C, 0x69, 0x76, 0x65, 0x72, 0x20, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x79, @@ -5458,7 +5369,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xB0, 0x01, 0x10, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x14, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD0, 0xCF, -0x14, 0x00, 0x79, 0x2B, 0xDB, 0x00, 0x00, 0x00, 0x40, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, +0x14, 0x00, 0x77, 0xEA, 0xE4, 0x00, 0x00, 0x00, 0x40, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x20, 0x44, 0x61, 0x6B, 0x6F, 0x74, 0x61, 0x20, 0x2D, 0x20, 0x4D, 0x6F, 0x72, 0x74, 0x6F, 0x6E, 0x20, 0x43, 0x6F, 0x75, 0x6E, 0x74, 0x79, 0x20, 0x28, 0x65, 0x78, 0x63, 0x65, 0x70, 0x74, 0x20, 0x4D, 0x61, 0x6E, @@ -5469,8 +5380,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x8B, 0xF4, 0x61, 0xE8, 0x01, 0xFF, 0xFF, 0xB5, 0x18, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0x43, 0x4D, 0x54, -0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x02, 0xDA, 0x00, 0x9A, 0xED, -0x75, 0x00, 0x00, 0x00, 0x00, +0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x97, 0x02, 0xDA, 0x00, 0x99, 0x4C, +0xCA, 0x00, 0x00, 0x00, 0x00, /* America/Pangnirtung */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -5521,7 +5432,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x54, 0x00, 0x41, 0x50, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x41, 0x44, 0x44, 0x54, 0x00, 0x41, 0x44, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x3D, 0x95, 0x00, 0xB0, 0x98, 0x55, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEE, 0x3D, 0x95, 0x00, 0xAE, 0x5B, 0x6A, 0x00, 0x00, 0x00, 0x23, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x50, 0x61, 0x6E, 0x67, 0x6E, 0x69, 0x72, 0x74, 0x75, 0x6E, 0x67, 0x2C, 0x20, 0x4E, 0x75, 0x6E, 0x61, 0x76, 0x75, 0x74, @@ -5535,7 +5446,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x04, 0xFF, 0xFF, 0xCC, 0x4C, 0x00, 0x04, 0xFF, 0xFF, 0xCE, 0xC8, 0x00, 0x08, 0xFF, 0xFF, 0xCE, 0xC8, 0x00, 0x0D, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x4D, 0x54, 0x00, 0x4E, 0x45, 0x47, 0x54, 0x00, 0x53, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x3A, 0xE5, 0x00, 0xBE, 0xFD, 0x3A, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x92, 0x3A, 0xE5, 0x00, 0xBE, 0x7B, 0x05, 0x00, 0x00, 0x00, 0x00, /* America/Phoenix */ @@ -5547,7 +5458,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFB, 0xE8, 0x58, 0x00, 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x08, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0xBC, 0x5E, 0x01, 0x00, 0x67, 0xDF, 0x25, 0x00, 0x00, 0x00, 0x20, 0x4D, 0x6F, +0x00, 0x00, 0x00, 0xBC, 0x5E, 0x01, 0x00, 0x67, 0xA5, 0xDA, 0x00, 0x00, 0x00, 0x20, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x41, 0x72, 0x69, 0x7A, 0x6F, 0x6E, 0x61, @@ -5569,7 +5480,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x05, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x09, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x05, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x09, 0x50, 0x50, 0x4D, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xA5, 0x9B, 0xD5, 0x00, 0xA5, 0x4D, 0xB5, 0x00, 0x00, 0x00, 0x00, +0x00, 0xA5, 0x9B, 0xD5, 0x00, 0xA4, 0x49, 0x4A, 0x00, 0x00, 0x00, 0x00, /* America/Porto_Acre */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -5594,8 +5505,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x33, 0xAC, 0x01, 0xFF, 0xFF, 0xC6, 0x54, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x94, 0x68, 0x00, 0xB6, 0x5E, -0x32, 0x00, 0x00, 0x00, 0x00, +0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x99, 0x94, 0x68, 0x00, 0xB4, 0xCA, +0x8D, 0x00, 0x00, 0x00, 0x00, /* America/Porto_Velho */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -5612,7 +5523,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xC4, 0x18, 0x00, 0x00, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x4D, 0x53, 0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x7E, 0x4A, 0xBA, 0x00, 0xB3, 0xE6, 0xB0, 0x00, 0x00, 0x00, 0x08, 0x52, 0x6F, +0x00, 0x00, 0x00, 0x7B, 0xF3, 0xC5, 0x00, 0xB1, 0x27, 0x90, 0x00, 0x00, 0x00, 0x08, 0x52, 0x6F, 0x6E, 0x64, 0x6F, 0x6E, 0x69, 0x61, /* America/Puerto_Rico */ @@ -5622,7 +5533,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xD2, 0x23, 0xF4, 0x70, 0xD2, 0x60, 0xED, 0xD0, 0x02, 0x01, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x00, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0x41, 0x53, 0x54, 0x00, 0x41, 0x50, 0x54, 0x00, 0x41, 0x57, 0x54, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01, 0x00, 0x00, -0xA5, 0x82, 0x71, 0x00, 0xAE, 0x1C, 0xB3, 0x00, 0x00, 0x00, 0x00, +0xA5, 0x82, 0x71, 0x00, 0xAD, 0xC9, 0xCC, 0x00, 0x00, 0x00, 0x00, /* America/Rainy_River */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -5672,8 +5583,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x08, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, -0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xD3, 0xAA, 0x32, 0x00, 0x84, -0x17, 0x1A, 0x00, 0x00, 0x00, 0x32, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, +0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xD3, 0xAA, 0x32, 0x00, 0x82, +0x5C, 0x65, 0x00, 0x00, 0x00, 0x32, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x52, 0x61, 0x69, 0x6E, 0x79, 0x20, 0x52, 0x69, 0x76, 0x65, 0x72, 0x20, 0x26, 0x20, 0x46, 0x6F, 0x72, 0x74, 0x20, 0x46, 0x72, 0x61, 0x6E, 0x63, 0x65, 0x73, 0x2C, 0x20, 0x4F, 0x6E, 0x74, 0x61, 0x72, 0x69, 0x6F, @@ -5723,7 +5634,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x09, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0D, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x11, 0x7A, 0x7A, 0x7A, 0x00, 0x43, 0x44, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE9, 0x2E, 0x02, -0x00, 0x86, 0x67, 0x71, 0x00, 0x00, 0x00, 0x1E, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, +0x00, 0x86, 0x26, 0x8E, 0x00, 0x00, 0x00, 0x1E, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x4E, 0x75, 0x6E, 0x61, 0x76, 0x75, 0x74, @@ -5745,7 +5656,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xDF, 0x48, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x42, 0x52, 0x53, 0x54, 0x00, 0x42, 0x52, 0x54, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0x32, 0xC8, 0x00, 0xE0, 0x26, 0xD0, 0x00, 0x00, 0x00, 0x0A, +0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0x0B, 0xB8, 0x00, 0xDD, 0x67, 0xB0, 0x00, 0x00, 0x00, 0x0A, 0x50, 0x65, 0x72, 0x6E, 0x61, 0x6D, 0x62, 0x75, 0x63, 0x6F, /* America/Regina */ @@ -5773,7 +5684,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xA0, 0x01, 0x10, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xD6, 0x3B, -0xC0, 0x00, 0x74, 0xF5, 0x68, 0x00, 0x00, 0x00, 0x35, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, +0xC0, 0x00, 0x72, 0xF9, 0x97, 0x00, 0x00, 0x00, 0x35, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x53, 0x61, 0x73, 0x6B, 0x61, 0x74, 0x63, 0x68, 0x65, 0x77, 0x61, 0x6E, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, @@ -5823,7 +5734,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x09, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0D, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x11, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x0D, 0x7A, 0x7A, 0x7A, 0x00, 0x43, 0x44, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0x4E, 0x33, 0x00, 0x84, 0x7D, 0xA4, 0x00, 0x00, 0x00, 0x29, +0x00, 0x00, 0x00, 0x00, 0x00, 0xFB, 0x4E, 0x33, 0x00, 0x81, 0xF5, 0xDB, 0x00, 0x00, 0x00, 0x29, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x52, 0x65, 0x73, 0x6F, 0x6C, 0x75, 0x74, 0x65, 0x2C, 0x20, 0x4E, 0x75, 0x6E, 0x61, 0x76, 0x75, 0x74, @@ -5844,13 +5755,13 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x03, 0xFF, 0xFF, 0xC0, 0x70, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x09, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x43, 0x53, 0x54, 0x00, 0x41, 0x43, 0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x7D, 0x12, 0x3A, 0x00, 0xAD, 0xA5, 0x20, 0x00, 0x00, 0x00, 0x04, 0x41, +0x00, 0x00, 0x00, 0x00, 0x7A, 0x1F, 0x05, 0x00, 0xAB, 0x34, 0x20, 0x00, 0x00, 0x00, 0x04, 0x41, 0x63, 0x72, 0x65, /* America/Rosario */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12, 0xA2, 0x92, 0x8F, 0x30, +0x00, 0x00, 0x00, 0x3C, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x12, 0xA2, 0x92, 0x8F, 0x30, 0xB6, 0x7B, 0x52, 0x40, 0xB7, 0x1A, 0xC9, 0xB0, 0xB8, 0x1E, 0x8F, 0x40, 0xB8, 0xD4, 0x70, 0x30, 0xBA, 0x17, 0x7D, 0xC0, 0xBA, 0xB5, 0xA3, 0xB0, 0xBB, 0xF8, 0xB1, 0x40, 0xBC, 0x96, 0xD7, 0x30, 0xBD, 0xD9, 0xE4, 0xC0, 0xBE, 0x78, 0x0A, 0xB0, 0xBF, 0xBB, 0x18, 0x40, 0xC0, 0x5A, 0x8F, 0xB0, @@ -5865,34 +5776,16 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x24, 0x10, 0x94, 0xA0, 0x25, 0x37, 0xF2, 0xB0, 0x25, 0xF0, 0x76, 0xA0, 0x27, 0x21, 0x0F, 0x30, 0x27, 0xD0, 0x58, 0xA0, 0x29, 0x00, 0xFF, 0x40, 0x29, 0xB0, 0x3A, 0xA0, 0x2A, 0xE0, 0xD3, 0x30, 0x2B, 0x99, 0x57, 0x20, 0x37, 0xF6, 0xC6, 0xB0, 0x38, 0xBF, 0x2A, 0xB0, 0x47, 0x77, 0x09, 0xB0, -0x47, 0xDC, 0x7F, 0x20, 0x48, 0xFA, 0xA2, 0xB0, 0x49, 0xBC, 0x61, 0x20, 0x4A, 0xDA, 0x84, 0xB0, -0x4B, 0xA5, 0x7D, 0xA0, 0x4C, 0xBA, 0x66, 0xB0, 0x4D, 0x85, 0x5F, 0xA0, 0x4E, 0x9A, 0x48, 0xB0, -0x4F, 0x65, 0x41, 0xA0, 0x50, 0x83, 0x65, 0x30, 0x51, 0x45, 0x23, 0xA0, 0x52, 0x63, 0x47, 0x30, -0x53, 0x25, 0x05, 0xA0, 0x54, 0x43, 0x29, 0x30, 0x55, 0x04, 0xE7, 0xA0, 0x56, 0x23, 0x0B, 0x30, -0x56, 0xEE, 0x04, 0x20, 0x58, 0x02, 0xED, 0x30, 0x58, 0xCD, 0xE6, 0x20, 0x59, 0xE2, 0xCF, 0x30, -0x5A, 0xAD, 0xC8, 0x20, 0x5B, 0xCB, 0xEB, 0xB0, 0x5C, 0x8D, 0xAA, 0x20, 0x5D, 0xAB, 0xCD, 0xB0, -0x5E, 0x6D, 0x8C, 0x20, 0x5F, 0x8B, 0xAF, 0xB0, 0x60, 0x56, 0xA8, 0xA0, 0x61, 0x6B, 0x91, 0xB0, -0x62, 0x36, 0x8A, 0xA0, 0x63, 0x4B, 0x73, 0xB0, 0x64, 0x16, 0x6C, 0xA0, 0x65, 0x2B, 0x55, 0xB0, -0x65, 0xF6, 0x4E, 0xA0, 0x67, 0x14, 0x72, 0x30, 0x67, 0xD6, 0x30, 0xA0, 0x68, 0xF4, 0x54, 0x30, -0x69, 0xB6, 0x12, 0xA0, 0x6A, 0xD4, 0x36, 0x30, 0x6B, 0x9F, 0x2F, 0x20, 0x6C, 0xB4, 0x18, 0x30, -0x6D, 0x7F, 0x11, 0x20, 0x6E, 0x93, 0xFA, 0x30, 0x6F, 0x5E, 0xF3, 0x20, 0x70, 0x7D, 0x16, 0xB0, -0x71, 0x3E, 0xD5, 0x20, 0x72, 0x5C, 0xF8, 0xB0, 0x73, 0x1E, 0xB7, 0x20, 0x74, 0x3C, 0xDA, 0xB0, -0x75, 0x07, 0xD3, 0xA0, 0x76, 0x1C, 0xBC, 0xB0, 0x76, 0xE7, 0xB5, 0xA0, 0x77, 0xFC, 0x9E, 0xB0, -0x78, 0xC7, 0x97, 0xA0, 0x79, 0xDC, 0x80, 0xB0, 0x7A, 0xA7, 0x79, 0xA0, 0x7B, 0xC5, 0x9D, 0x30, -0x7C, 0x87, 0x5B, 0xA0, 0x7D, 0xA5, 0x7F, 0x30, 0x7E, 0x67, 0x3D, 0xA0, 0x7F, 0x85, 0x61, 0x30, +0x47, 0xDC, 0x7F, 0x20, 0x48, 0xFA, 0xA2, 0xB0, 0x49, 0xBC, 0x61, 0x20, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, -0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x05, 0x03, 0x04, 0x03, 0x04, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, -0x03, 0x04, 0x03, 0x04, 0x03, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, -0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, -0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, 0x41, 0x52, 0x54, -0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, -0x00, 0x00, 0x00, +0x01, 0x02, 0x01, 0x02, 0x01, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x05, 0x03, 0x04, +0x03, 0x04, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0xFF, 0xFF, 0xC3, 0xD0, 0x00, 0x00, 0xFF, 0xFF, +0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x08, +0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x0D, 0x43, 0x4D, 0x54, 0x00, +0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x57, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, +0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, /* America/Santarem */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -5910,7 +5803,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x03, 0xFF, 0xFF, 0xCC, 0xB8, 0x00, 0x00, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x09, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x4D, 0x53, 0x54, 0x00, 0x41, 0x4D, 0x54, 0x00, 0x42, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x86, 0xF0, 0x45, 0x00, 0xC1, 0x95, 0x4A, 0x00, 0x00, 0x00, 0x06, 0x57, +0x00, 0x00, 0x00, 0x00, 0x85, 0x9D, 0xBA, 0x00, 0xBE, 0xF0, 0x35, 0x00, 0x00, 0x00, 0x06, 0x57, 0x20, 0x50, 0x61, 0x72, 0x61, /* America/Santiago */ @@ -5971,7 +5864,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x08, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x53, 0x4D, 0x54, 0x00, 0x43, 0x4C, 0x54, 0x00, 0x43, 0x4C, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, -0x57, 0xA9, 0x68, 0x00, 0xA8, 0xDD, 0x2A, 0x00, 0x00, 0x00, 0x0E, 0x6D, 0x6F, 0x73, 0x74, 0x20, +0x56, 0x49, 0xD8, 0x00, 0xA6, 0xD4, 0x55, 0x00, 0x00, 0x00, 0x0E, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, /* America/Santo_Domingo */ @@ -5986,8 +5879,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x05, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x09, 0xFF, 0xFF, 0xC0, 0xB8, 0x01, 0x0D, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x12, 0x53, 0x44, 0x4D, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x48, 0x44, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x81, 0xCA, 0x00, 0xAA, -0xBE, 0xF0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x81, 0xCA, 0x00, 0xA7, +0xFF, 0xD0, 0x00, 0x00, 0x00, 0x00, /* America/Sao_Paulo */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x42, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -6035,7 +5928,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xD4, 0x4C, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x42, 0x52, 0x53, 0x54, 0x00, 0x42, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x67, 0x0C, 0x35, 0x00, 0xCD, 0x68, 0xA2, 0x00, 0x00, 0x00, 0x32, 0x53, 0x20, 0x26, +0x00, 0x00, 0x65, 0x6B, 0x8A, 0x00, 0xCB, 0x86, 0xDD, 0x00, 0x00, 0x00, 0x32, 0x53, 0x20, 0x26, 0x20, 0x53, 0x45, 0x20, 0x42, 0x72, 0x61, 0x7A, 0x69, 0x6C, 0x20, 0x28, 0x47, 0x4F, 0x2C, 0x20, 0x44, 0x46, 0x2C, 0x20, 0x4D, 0x47, 0x2C, 0x20, 0x45, 0x53, 0x2C, 0x20, 0x52, 0x4A, 0x2C, 0x20, 0x53, 0x50, 0x2C, 0x20, 0x50, 0x52, 0x2C, 0x20, 0x53, 0x43, 0x2C, 0x20, 0x52, 0x53, 0x29, @@ -6085,7 +5978,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xF0, 0x00, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x00, 0x00, 0x00, 0x00, 0x01, 0x11, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x47, 0x54, 0x00, 0x43, 0x47, 0x53, 0x54, 0x00, 0x45, 0x47, 0x54, 0x00, 0x45, 0x47, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x01, 0x00, 0x00, 0xF4, 0xE0, 0xCD, 0x00, 0xF4, 0x16, 0xFA, 0x00, 0x00, 0x00, 0x1F, 0x53, +0x01, 0x01, 0x00, 0x00, 0xF4, 0xE0, 0xCD, 0x00, 0xF1, 0x23, 0xC5, 0x00, 0x00, 0x00, 0x1F, 0x53, 0x63, 0x6F, 0x72, 0x65, 0x73, 0x62, 0x79, 0x73, 0x75, 0x6E, 0x64, 0x20, 0x2F, 0x20, 0x49, 0x74, 0x74, 0x6F, 0x71, 0x71, 0x6F, 0x72, 0x74, 0x6F, 0x6F, 0x72, 0x6D, 0x69, 0x69, 0x74, @@ -6145,7 +6038,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xA0, 0x01, 0x00, 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xC1, 0x75, -0x9B, 0x00, 0x6E, 0xE9, 0x1E, 0x00, 0x00, 0x00, 0x16, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, +0x9B, 0x00, 0x6C, 0xD0, 0xE1, 0x00, 0x00, 0x00, 0x16, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4E, 0x61, 0x76, 0x61, 0x6A, 0x6F, /* America/St_Barthelemy */ @@ -6153,8 +6046,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xD5, 0xE1, 0xB0, 0x01, 0xFF, 0xFF, 0xC6, 0x50, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x9D, 0xED, 0x00, 0xB5, 0x59, -0xC8, 0x00, 0x00, 0x00, 0x00, +0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA4, 0x9D, 0xED, 0x00, 0xB2, 0xC1, +0xB8, 0x00, 0x00, 0x00, 0x00, /* America/St_Johns */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -6239,7 +6132,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0xDC, 0xD8, 0x01, 0x0C, 0xFF, 0xFF, 0xEA, 0xE8, 0x01, 0x10, 0x4E, 0x44, 0x54, 0x00, 0x4E, 0x53, 0x54, 0x00, 0x4E, 0x50, 0x54, 0x00, 0x4E, 0x57, 0x54, 0x00, 0x4E, 0x44, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -0xD1, 0xE8, 0xFA, 0x00, 0xC4, 0x67, 0xF2, 0x00, 0x00, 0x00, 0x28, 0x4E, 0x65, 0x77, 0x66, 0x6F, +0xD1, 0xE8, 0xFA, 0x00, 0xC2, 0x38, 0x0D, 0x00, 0x00, 0x00, 0x28, 0x4E, 0x65, 0x77, 0x66, 0x6F, 0x75, 0x6E, 0x64, 0x6C, 0x61, 0x6E, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x2C, 0x20, 0x69, 0x6E, 0x63, 0x6C, 0x75, 0x64, 0x69, 0x6E, 0x67, 0x20, 0x53, 0x45, 0x20, 0x4C, 0x61, 0x62, 0x72, 0x61, 0x64, 0x6F, 0x72, @@ -6249,8 +6142,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x93, 0x37, 0x34, 0xCC, 0x01, 0xFF, 0xFF, 0xC5, 0x34, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0xBA, 0x10, 0x00, 0xB5, 0x25, -0xB2, 0x00, 0x00, 0x00, 0x00, +0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA3, 0xBA, 0x10, 0x00, 0xB2, 0xF5, +0xCD, 0x00, 0x00, 0x00, 0x00, /* America/St_Lucia */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4C, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -6265,16 +6158,16 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF4, 0x37, 0x60, 0x01, 0xFF, 0xFF, 0xC3, 0x20, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x54, 0x38, 0x00, 0xB2, 0x6D, -0x15, 0x00, 0x00, 0x00, 0x00, +0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x54, 0x38, 0x00, 0xAF, 0x93, +0xEA, 0x00, 0x00, 0x00, 0x00, /* America/St_Vincent */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x56, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x92, 0xE6, 0xC7, 0xE8, 0x01, 0xFF, 0xFF, 0xC6, 0x98, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4B, 0x4D, 0x54, -0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x64, 0xF8, 0x00, 0xB5, 0xEF, -0x85, 0x00, 0x00, 0x00, 0x00, +0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9D, 0x64, 0xF8, 0x00, 0xB5, 0x39, +0x3A, 0x00, 0x00, 0x00, 0x00, /* America/Swift_Current */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -6291,7 +6184,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x08, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x0C, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x10, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xD6, 0x0E, 0x2D, 0x00, 0x70, 0xA9, 0x25, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xD6, 0x0E, 0x2D, 0x00, 0x6E, 0x1E, 0x1A, 0x00, 0x00, 0x00, 0x2E, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x53, 0x74, 0x61, 0x6E, 0x64, 0x61, 0x72, 0x64, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x53, 0x61, 0x73, 0x6B, 0x61, 0x74, 0x63, 0x68, 0x65, 0x77, 0x61, 0x6E, 0x20, 0x2D, 0x20, 0x6D, 0x69, 0x64, 0x77, 0x65, 0x73, @@ -6305,7 +6198,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x44, 0x5D, 0x8C, 0xE0, 0x44, 0xD6, 0xC8, 0xD0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xAE, 0x3C, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x9E, 0xD8, 0x10, 0x00, 0x8E, 0x3C, 0xC2, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x9E, 0xD8, 0x10, 0x00, 0x8D, 0x93, 0x7D, 0x00, 0x00, 0x00, 0x00, /* America/Thule */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x47, 0x4C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -6343,7 +6236,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0xFF, 0xFF, 0xBF, 0x84, 0x00, 0x00, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x44, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFE, 0x29, 0x1A, 0x00, -0xAC, 0x17, 0xFD, 0x00, 0x00, 0x00, 0x10, 0x54, 0x68, 0x75, 0x6C, 0x65, 0x20, 0x2F, 0x20, 0x50, +0xA9, 0xB4, 0x02, 0x00, 0x00, 0x00, 0x10, 0x54, 0x68, 0x75, 0x6C, 0x65, 0x20, 0x2F, 0x20, 0x50, 0x69, 0x74, 0x75, 0x66, 0x66, 0x69, 0x6B, /* America/Thunder_Bay */ @@ -6396,8 +6289,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xAB, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x08, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x0C, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x10, 0x43, 0x53, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x57, 0x54, 0x00, 0x45, 0x50, 0x54, 0x00, 0x45, 0x44, 0x54, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xD3, 0x27, 0xFD, 0x00, 0x8B, -0x3C, 0x88, 0x00, 0x00, 0x00, 0x23, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0xD3, 0x27, 0xFD, 0x00, 0x8A, +0x79, 0x38, 0x00, 0x00, 0x00, 0x23, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x54, 0x68, 0x75, 0x6E, 0x64, 0x65, 0x72, 0x20, 0x42, 0x61, 0x79, 0x2C, 0x20, 0x4F, 0x6E, 0x74, 0x61, 0x72, 0x69, 0x6F, @@ -6456,7 +6349,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x90, 0x01, 0x10, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x14, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0xBA, 0xF8, -0x95, 0x00, 0x60, 0x27, 0xE2, 0x00, 0x00, 0x00, 0x0C, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, +0x95, 0x00, 0x60, 0x1A, 0xDD, 0x00, 0x00, 0x00, 0x0C, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, /* America/Toronto */ @@ -6538,7 +6431,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x01, 0x00, 0x01, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x08, 0xFF, 0xFF, 0xC7, 0xC0, 0x01, 0x0C, 0x45, 0x44, 0x54, 0x00, 0x45, 0x53, 0x54, 0x00, 0x45, 0x57, 0x54, 0x00, 0x45, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, -0x00, 0x00, 0x00, 0x01, 0x00, 0xCB, 0xEF, 0x08, 0x00, 0x9A, 0xB2, 0xDD, 0x00, 0x00, 0x00, 0x27, +0x00, 0x00, 0x00, 0x01, 0x00, 0xCB, 0xEF, 0x08, 0x00, 0x99, 0x87, 0x62, 0x00, 0x00, 0x00, 0x27, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4F, 0x6E, 0x74, 0x61, 0x72, 0x69, 0x6F, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, @@ -6548,8 +6441,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF4, 0x37, 0x14, 0x01, 0xFF, 0xFF, 0xC3, 0x6C, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x7B, 0x48, 0x00, 0xB1, 0xF1, -0x62, 0x00, 0x00, 0x00, 0x00, +0x00, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA5, 0x7B, 0x48, 0x00, 0xB0, 0x0F, +0x9D, 0x00, 0x00, 0x00, 0x00, /* America/Vancouver */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -6617,7 +6510,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x90, 0x01, 0x00, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x04, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x08, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x0C, 0x50, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x57, 0x54, 0x00, 0x50, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0xD4, 0x81, -0x0A, 0x00, 0x57, 0x27, 0x32, 0x00, 0x00, 0x00, 0x24, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, +0x0A, 0x00, 0x56, 0xCC, 0x0D, 0x00, 0x00, 0x00, 0x24, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x77, 0x65, 0x73, 0x74, 0x20, 0x42, 0x72, 0x69, 0x74, 0x69, 0x73, 0x68, 0x20, 0x43, 0x6F, 0x6C, 0x75, 0x6D, 0x62, 0x69, 0x61, @@ -6677,7 +6570,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x15, 0xFF, 0xFF, 0x9D, 0x90, 0x01, 0x19, 0x59, 0x44, 0x54, 0x00, 0x59, 0x53, 0x54, 0x00, 0x59, 0x57, 0x54, 0x00, 0x59, 0x50, 0x54, 0x00, 0x59, 0x44, 0x44, 0x54, 0x00, 0x50, 0x53, 0x54, 0x00, 0x50, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xE5, 0xF9, 0xB2, 0x00, 0x44, 0xBD, 0xA8, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xE5, 0xF9, 0xB2, 0x00, 0x44, 0x96, 0x97, 0x00, 0x00, 0x00, 0x1A, 0x50, 0x61, 0x63, 0x69, 0x66, 0x69, 0x63, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x73, 0x6F, 0x75, 0x74, 0x68, 0x20, 0x59, 0x75, 0x6B, 0x6F, 0x6E, @@ -6747,7 +6640,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x00, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x04, 0x43, 0x44, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x43, 0x57, 0x54, 0x00, 0x43, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xD5, -0x71, 0xED, 0x00, 0x7E, 0xE0, 0x78, 0x00, 0x00, 0x00, 0x26, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, +0x71, 0xED, 0x00, 0x7E, 0x6B, 0x47, 0x00, 0x00, 0x00, 0x26, 0x43, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x4D, 0x61, 0x6E, 0x69, 0x74, 0x6F, 0x62, 0x61, 0x20, 0x26, 0x20, 0x77, 0x65, 0x73, 0x74, 0x20, 0x4F, 0x6E, 0x74, 0x61, 0x72, 0x69, 0x6F, @@ -6805,7 +6698,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0x81, 0x70, 0x00, 0x15, 0x59, 0x53, 0x54, 0x00, 0x59, 0x57, 0x54, 0x00, 0x59, 0x50, 0x54, 0x00, 0x59, 0x44, 0x54, 0x00, 0x41, 0x4B, 0x44, 0x54, 0x00, 0x41, 0x4B, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x30, 0xC6, -0x00, 0x3F, 0xAB, 0xB2, 0x00, 0x00, 0x00, 0x23, 0x41, 0x6C, 0x61, 0x73, 0x6B, 0x61, 0x20, 0x54, +0x00, 0x3D, 0x73, 0x8D, 0x00, 0x00, 0x00, 0x23, 0x41, 0x6C, 0x61, 0x73, 0x6B, 0x61, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x41, 0x6C, 0x61, 0x73, 0x6B, 0x61, 0x20, 0x70, 0x61, 0x6E, 0x68, 0x61, 0x6E, 0x64, 0x6C, 0x65, 0x20, 0x6E, 0x65, 0x63, 0x6B, @@ -6855,7 +6748,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0x9D, 0x90, 0x00, 0x0C, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x10, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x15, 0x7A, 0x7A, 0x7A, 0x00, 0x4D, 0x57, 0x54, 0x00, 0x4D, 0x50, 0x54, 0x00, 0x4D, 0x53, 0x54, 0x00, 0x4D, 0x44, 0x44, 0x54, 0x00, 0x4D, 0x44, 0x54, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x9E, 0xC7, 0x00, 0x65, 0x3D, 0xF7, 0x00, +0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0xE8, 0x9E, 0xC7, 0x00, 0x64, 0x2C, 0x88, 0x00, 0x00, 0x00, 0x2D, 0x4D, 0x6F, 0x75, 0x6E, 0x74, 0x61, 0x69, 0x6E, 0x20, 0x54, 0x69, 0x6D, 0x65, 0x20, 0x2D, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x77, 0x65, 0x73, 0x74, 0x20, 0x54, 0x65, 0x72, 0x72, 0x69, 0x74, 0x6F, 0x72, 0x69, 0x65, 0x73, @@ -6863,23 +6756,25 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { /* Antarctica/Casey */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0xFE, 0x1E, 0xCC, 0x80, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x00, 0x04, 0x7A, 0x7A, 0x7A, -0x00, 0x57, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x25, 0x0D, 0xAD, 0x01, 0xBB, 0x4B, -0x12, 0x00, 0x00, 0x00, 0x1F, 0x43, 0x61, 0x73, 0x65, 0x79, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, -0x6F, 0x6E, 0x2C, 0x20, 0x42, 0x61, 0x69, 0x6C, 0x65, 0x79, 0x20, 0x50, 0x65, 0x6E, 0x69, 0x6E, -0x73, 0x75, 0x6C, 0x61, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0xFE, 0x1E, 0xCC, 0x80, +0x4A, 0xDA, 0x06, 0x20, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x80, +0x00, 0x04, 0x00, 0x00, 0x9A, 0xB0, 0x00, 0x08, 0x7A, 0x7A, 0x7A, 0x00, 0x57, 0x53, 0x54, 0x00, +0x43, 0x41, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x30, 0x52, 0x01, +0xBB, 0x4B, 0x12, 0x00, 0x00, 0x00, 0x1F, 0x43, 0x61, 0x73, 0x65, 0x79, 0x20, 0x53, 0x74, 0x61, +0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x42, 0x61, 0x69, 0x6C, 0x65, 0x79, 0x20, 0x50, 0x65, 0x6E, +0x69, 0x6E, 0x73, 0x75, 0x6C, 0x61, /* Antarctica/Davis */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0xE7, 0x9C, 0x40, 0x00, -0xF6, 0x47, 0xDF, 0x10, 0xFE, 0x47, 0xAB, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x62, 0x70, 0x00, 0x04, 0x7A, 0x7A, 0x7A, 0x00, 0x44, 0x41, 0x56, 0x54, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x75, 0x9D, 0x01, 0x89, 0xA0, 0x3A, 0x00, 0x00, 0x00, 0x1D, -0x44, 0x61, 0x76, 0x69, 0x73, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x56, -0x65, 0x73, 0x74, 0x66, 0x6F, 0x6C, 0x64, 0x20, 0x48, 0x69, 0x6C, 0x6C, 0x73, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0xE7, 0x9C, 0x40, 0x00, +0xF6, 0x47, 0xDF, 0x10, 0xFE, 0x47, 0xAB, 0x00, 0x4A, 0xDA, 0x14, 0x30, 0x01, 0x00, 0x01, 0x02, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x62, 0x70, 0x00, 0x04, 0x00, 0x00, 0x46, 0x50, +0x00, 0x04, 0x7A, 0x7A, 0x7A, 0x00, 0x44, 0x41, 0x56, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x20, 0xAD, 0xE2, 0x01, 0x89, 0xA0, 0x3A, 0x00, 0x00, 0x00, 0x1D, 0x44, 0x61, 0x76, +0x69, 0x73, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x56, 0x65, 0x73, 0x74, +0x66, 0x6F, 0x6C, 0x64, 0x20, 0x48, 0x69, 0x6C, 0x6C, 0x73, /* Antarctica/DumontDUrville */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -6888,19 +6783,20 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xDE, 0x34, 0x60, 0x60, 0xE7, 0x3C, 0x02, 0x80, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x04, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x08, 0x7A, 0x7A, 0x7A, 0x00, 0x50, 0x4D, 0x54, 0x00, 0x44, 0x44, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x25, 0xA3, 0x6A, 0x01, 0xE8, 0x4E, 0x82, 0x00, 0x00, 0x00, 0x26, 0x44, 0x75, 0x6D, 0x6F, +0x00, 0x23, 0x9A, 0x95, 0x01, 0xE8, 0x4E, 0x82, 0x00, 0x00, 0x00, 0x26, 0x44, 0x75, 0x6D, 0x6F, 0x6E, 0x74, 0x2D, 0x64, 0x27, 0x55, 0x72, 0x76, 0x69, 0x6C, 0x6C, 0x65, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x54, 0x65, 0x72, 0x72, 0x65, 0x20, 0x41, 0x64, 0x65, 0x6C, 0x69, 0x65, /* Antarctica/Mawson */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0xE2, 0x20, 0x32, 0x80, -0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x60, 0x00, 0x04, 0x7A, 0x7A, 0x7A, -0x00, 0x4D, 0x41, 0x57, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x24, 0x02, 0xBF, 0x01, 0x72, -0x9C, 0x4D, 0x00, 0x00, 0x00, 0x19, 0x4D, 0x61, 0x77, 0x73, 0x6F, 0x6E, 0x20, 0x53, 0x74, 0x61, -0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x48, 0x6F, 0x6C, 0x6D, 0x65, 0x20, 0x42, 0x61, 0x79, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x09, 0xE2, 0x20, 0x32, 0x80, +0x4A, 0xDA, 0x22, 0x40, 0x01, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x60, +0x00, 0x04, 0x00, 0x00, 0x46, 0x50, 0x00, 0x04, 0x7A, 0x7A, 0x7A, 0x00, 0x4D, 0x41, 0x57, 0x54, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x2E, 0x00, 0x01, 0x72, 0x9C, 0x4D, 0x00, +0x00, 0x00, 0x19, 0x4D, 0x61, 0x77, 0x73, 0x6F, 0x6E, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6F, +0x6E, 0x2C, 0x20, 0x48, 0x6F, 0x6C, 0x6D, 0x65, 0x20, 0x42, 0x61, 0x79, /* Antarctica/McMurdo */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x51, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -6948,7 +6844,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xB6, 0xD0, 0x01, 0x04, 0x00, 0x00, 0xA8, 0xC0, 0x00, 0x09, 0x00, 0x00, 0xA8, 0xC0, 0x00, 0x09, 0x7A, 0x7A, 0x7A, 0x00, 0x4E, 0x5A, 0x44, 0x54, 0x00, 0x4E, 0x5A, 0x53, -0x54, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x15, 0x1B, 0xA5, 0x02, 0x10, +0x54, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x90, 0x9A, 0x02, 0x10, 0xDE, 0xA0, 0x00, 0x00, 0x00, 0x1C, 0x4D, 0x63, 0x4D, 0x75, 0x72, 0x64, 0x6F, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x52, 0x6F, 0x73, 0x73, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, @@ -7001,7 +6897,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x0D, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x12, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x12, 0x7A, 0x7A, 0x7A, 0x00, 0x41, 0x52, 0x54, 0x00, 0x41, 0x52, 0x53, 0x54, 0x00, 0x43, 0x4C, 0x53, 0x54, 0x00, 0x43, 0x4C, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x01, 0x00, 0x00, 0x28, 0xE4, 0xBF, 0x00, 0xB1, 0x27, 0x90, 0x00, 0x00, 0x00, 0x1D, 0x50, +0x01, 0x01, 0x00, 0x00, 0x26, 0x73, 0xC0, 0x00, 0xB0, 0xD9, 0x70, 0x00, 0x00, 0x00, 0x1D, 0x50, 0x61, 0x6C, 0x6D, 0x65, 0x72, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x41, 0x6E, 0x76, 0x65, 0x72, 0x73, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, @@ -7010,8 +6906,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x0D, 0x02, 0x2D, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x04, 0x7A, 0x7A, 0x7A, -0x00, 0x52, 0x4F, 0x54, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x23, 0xF5, 0xBA, 0x00, 0xAB, -0x1A, 0x15, 0x00, 0x00, 0x00, 0x20, 0x52, 0x6F, 0x74, 0x68, 0x65, 0x72, 0x61, 0x20, 0x53, 0x74, +0x00, 0x52, 0x4F, 0x54, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x22, 0x3B, 0x05, 0x00, 0xAA, +0xB1, 0xEA, 0x00, 0x00, 0x00, 0x20, 0x52, 0x6F, 0x74, 0x68, 0x65, 0x72, 0x61, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x41, 0x64, 0x65, 0x6C, 0x61, 0x69, 0x64, 0x65, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, @@ -7071,7 +6967,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0xE7, 0xB1, 0x58, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x04, 0x7A, 0x7A, 0x7A, -0x00, 0x53, 0x59, 0x4F, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x0D, 0x83, 0x01, 0x4F, +0x00, 0x53, 0x59, 0x4F, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x20, 0x08, 0xBC, 0x01, 0x4F, 0x11, 0x58, 0x00, 0x00, 0x00, 0x18, 0x53, 0x79, 0x6F, 0x77, 0x61, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x45, 0x20, 0x4F, 0x6E, 0x67, 0x75, 0x6C, 0x20, 0x49, @@ -7080,7 +6976,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0xE9, 0x58, 0x89, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x54, 0x60, 0x00, 0x04, 0x7A, 0x7A, 0x7A, -0x00, 0x56, 0x4F, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0xEB, 0xC0, 0x01, 0xB5, +0x00, 0x56, 0x4F, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x11, 0xB3, 0x3F, 0x01, 0xB5, 0xC6, 0x4F, 0x00, 0x00, 0x00, 0x1F, 0x56, 0x6F, 0x73, 0x74, 0x6F, 0x6B, 0x20, 0x53, 0x74, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x2C, 0x20, 0x53, 0x20, 0x4D, 0x61, 0x67, 0x6E, 0x65, 0x74, 0x69, 0x63, 0x20, 0x50, 0x6F, 0x6C, 0x65, @@ -7672,21 +7568,21 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x3E, 0x88, 0xBA, 0x60, 0x3F, 0x79, 0xEE, 0xD0, 0x40, 0x6B, 0x3F, 0x60, 0x41, 0x5C, 0x73, 0xD0, 0x42, 0x4C, 0x72, 0xE0, 0x43, 0x3D, 0xA7, 0x50, 0x44, 0x2D, 0xA6, 0x60, 0x45, 0x12, 0xFD, 0x50, 0x46, 0x0C, 0x36, 0xE0, 0x47, 0x2A, 0x3E, 0x50, 0x47, 0xF5, 0x53, 0x60, 0x49, 0x0B, 0x71, 0xD0, -0x49, 0xCB, 0xFA, 0xE0, 0x4A, 0xEC, 0xA5, 0x50, 0x4B, 0xAB, 0xDC, 0xE0, 0x4C, 0xCD, 0xD8, 0xD0, -0x4D, 0x8B, 0xBE, 0xE0, 0x4E, 0xAF, 0x0C, 0x50, 0x4F, 0x74, 0xDB, 0x60, 0x50, 0x91, 0x91, 0x50, -0x51, 0x54, 0xBD, 0x60, 0x52, 0x72, 0xC4, 0xD0, 0x53, 0x34, 0x9F, 0x60, 0x54, 0x53, 0xF8, 0x50, -0x55, 0x14, 0x81, 0x60, 0x56, 0x35, 0x2B, 0xD0, 0x56, 0xF4, 0x63, 0x60, 0x58, 0x17, 0xB0, 0xD0, -0x58, 0xDD, 0x7F, 0xE0, 0x59, 0xF8, 0xE4, 0x50, 0x5A, 0xBD, 0x61, 0xE0, 0x5B, 0xDA, 0x17, 0xD0, -0x5C, 0x9D, 0x43, 0xE0, 0x5D, 0xBB, 0x4B, 0x50, 0x5E, 0x7D, 0x25, 0xE0, 0x5F, 0x9D, 0xD0, 0x50, -0x60, 0x5D, 0x07, 0xE0, 0x61, 0x7F, 0x03, 0xD0, 0x62, 0x3C, 0xE9, 0xE0, 0x63, 0x60, 0x37, 0x50, -0x64, 0x26, 0x06, 0x60, 0x65, 0x41, 0x6A, 0xD0, 0x66, 0x05, 0xE8, 0x60, 0x67, 0x23, 0xEF, 0xD0, -0x67, 0xE5, 0xCA, 0x60, 0x69, 0x05, 0x23, 0x50, 0x69, 0xC5, 0xAC, 0x60, 0x6A, 0xE6, 0x56, 0xD0, -0x6B, 0xA5, 0x8E, 0x60, 0x6C, 0xC7, 0x8A, 0x50, 0x6D, 0x8E, 0xAA, 0xE0, 0x6E, 0xAA, 0x0F, 0x50, -0x6F, 0x6E, 0x8C, 0xE0, 0x70, 0x8B, 0x42, 0xD0, 0x71, 0x4E, 0x6E, 0xE0, 0x72, 0x6C, 0x76, 0x50, -0x73, 0x2E, 0x50, 0xE0, 0x74, 0x4D, 0xA9, 0xD0, 0x75, 0x0E, 0x32, 0xE0, 0x76, 0x30, 0x2E, 0xD0, -0x76, 0xEE, 0x14, 0xE0, 0x78, 0x11, 0x62, 0x50, 0x78, 0xD7, 0x31, 0x60, 0x79, 0xF2, 0x95, 0xD0, -0x7A, 0xB7, 0x13, 0x60, 0x7B, 0xD3, 0xC9, 0x50, 0x7C, 0x96, 0xF5, 0x60, 0x7D, 0xB6, 0x4E, 0x50, -0x7E, 0x76, 0xD7, 0x60, 0x7F, 0x97, 0x81, 0xD0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, +0x49, 0xCB, 0xFA, 0xE0, 0x4A, 0xEA, 0x02, 0x50, 0x4B, 0xAB, 0xDC, 0xE0, 0x4C, 0xC9, 0xE4, 0x50, +0x4D, 0x8B, 0xBE, 0xE0, 0x4E, 0xA9, 0xC6, 0x50, 0x4F, 0x74, 0xDB, 0x60, 0x50, 0x89, 0xA8, 0x50, +0x51, 0x54, 0xBD, 0x60, 0x52, 0x69, 0x8A, 0x50, 0x53, 0x34, 0x9F, 0x60, 0x54, 0x52, 0xA6, 0xD0, +0x55, 0x14, 0x81, 0x60, 0x56, 0x32, 0x88, 0xD0, 0x56, 0xF4, 0x63, 0x60, 0x58, 0x12, 0x6A, 0xD0, +0x58, 0xDD, 0x7F, 0xE0, 0x59, 0xF2, 0x4C, 0xD0, 0x5A, 0xBD, 0x61, 0xE0, 0x5B, 0xD2, 0x2E, 0xD0, +0x5C, 0x9D, 0x43, 0xE0, 0x5D, 0xB2, 0x10, 0xD0, 0x5E, 0x7D, 0x25, 0xE0, 0x5F, 0x9B, 0x2D, 0x50, +0x60, 0x5D, 0x07, 0xE0, 0x61, 0x7B, 0x0F, 0x50, 0x62, 0x3C, 0xE9, 0xE0, 0x63, 0x5A, 0xF1, 0x50, +0x64, 0x26, 0x06, 0x60, 0x65, 0x3A, 0xD3, 0x50, 0x66, 0x05, 0xE8, 0x60, 0x67, 0x1A, 0xB5, 0x50, +0x67, 0xE5, 0xCA, 0x60, 0x69, 0x03, 0xD1, 0xD0, 0x69, 0xC5, 0xAC, 0x60, 0x6A, 0xE3, 0xB3, 0xD0, +0x6B, 0xA5, 0x8E, 0x60, 0x6C, 0xC3, 0x95, 0xD0, 0x6D, 0x8E, 0xAA, 0xE0, 0x6E, 0xA3, 0x77, 0xD0, +0x6F, 0x6E, 0x8C, 0xE0, 0x70, 0x83, 0x59, 0xD0, 0x71, 0x4E, 0x6E, 0xE0, 0x72, 0x63, 0x3B, 0xD0, +0x73, 0x2E, 0x50, 0xE0, 0x74, 0x4C, 0x58, 0x50, 0x75, 0x0E, 0x32, 0xE0, 0x76, 0x2C, 0x3A, 0x50, +0x76, 0xEE, 0x14, 0xE0, 0x78, 0x0C, 0x1C, 0x50, 0x78, 0xD7, 0x31, 0x60, 0x79, 0xEB, 0xFE, 0x50, +0x7A, 0xB7, 0x13, 0x60, 0x7B, 0xCB, 0xE0, 0x50, 0x7C, 0x96, 0xF5, 0x60, 0x7D, 0xB4, 0xFC, 0xD0, +0x7E, 0x76, 0xD7, 0x60, 0x7F, 0x94, 0xDE, 0xD0, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, @@ -7722,8 +7618,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x02, 0x03, 0x04, 0x03, 0x00, 0x00, 0x75, 0xBC, 0x00, 0x00, 0x00, 0x00, 0x70, 0x80, 0x00, 0x04, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x08, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x04, 0x00, 0x00, 0x70, 0x80, 0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x54, 0x4C, 0x54, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x43, -0x49, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xF6, -0x18, 0x01, 0xD2, 0x48, 0x7D, 0x00, 0x00, 0x00, 0x00, +0x49, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x48, +0x68, 0x01, 0xD2, 0x48, 0x7D, 0x00, 0x00, 0x00, 0x00, /* Asia/Dubai */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x41, 0x45, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -7777,21 +7673,21 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x3D, 0xAF, 0x24, 0xD0, 0x3E, 0x9F, 0x23, 0xE0, 0x3F, 0x8F, 0x06, 0xD0, 0x40, 0x7F, 0x05, 0xE0, 0x41, 0x5C, 0x81, 0xE0, 0x42, 0x5E, 0xE7, 0xE0, 0x43, 0x41, 0xB7, 0xF0, 0x44, 0x2D, 0xA6, 0x60, 0x45, 0x12, 0xFD, 0x50, 0x46, 0x0E, 0xD9, 0xE0, 0x46, 0xE8, 0x6F, 0x70, 0x47, 0xF1, 0x5E, 0xE0, -0x48, 0xB7, 0x2D, 0xF0, 0x49, 0xCB, 0xFA, 0xE0, 0x4A, 0xBF, 0xEE, 0x70, 0x4B, 0xAB, 0xDC, 0xE0, -0x4C, 0x9F, 0xD0, 0x70, 0x4D, 0x8B, 0xBE, 0xE0, 0x4E, 0x7F, 0xB2, 0x70, 0x4F, 0x74, 0xDB, 0x60, -0x50, 0x5F, 0x94, 0x70, 0x51, 0x54, 0xBD, 0x60, 0x52, 0x48, 0xB0, 0xF0, 0x53, 0x34, 0x9F, 0x60, -0x54, 0x28, 0x92, 0xF0, 0x55, 0x14, 0x81, 0x60, 0x56, 0x08, 0x74, 0xF0, 0x56, 0xF4, 0x63, 0x60, -0x57, 0xE8, 0x56, 0xF0, 0x58, 0xDD, 0x7F, 0xE0, 0x59, 0xC8, 0x38, 0xF0, 0x5A, 0xBD, 0x61, 0xE0, -0x5B, 0xA8, 0x1A, 0xF0, 0x5C, 0x9D, 0x43, 0xE0, 0x5D, 0x91, 0x37, 0x70, 0x5E, 0x7D, 0x25, 0xE0, -0x5F, 0x71, 0x19, 0x70, 0x60, 0x5D, 0x07, 0xE0, 0x61, 0x50, 0xFB, 0x70, 0x62, 0x3C, 0xE9, 0xE0, -0x63, 0x30, 0xDD, 0x70, 0x64, 0x26, 0x06, 0x60, 0x65, 0x10, 0xBF, 0x70, 0x66, 0x05, 0xE8, 0x60, -0x66, 0xF9, 0xDB, 0xF0, 0x67, 0xE5, 0xCA, 0x60, 0x68, 0xD9, 0xBD, 0xF0, 0x69, 0xC5, 0xAC, 0x60, -0x6A, 0xB9, 0x9F, 0xF0, 0x6B, 0xA5, 0x8E, 0x60, 0x6C, 0x99, 0x81, 0xF0, 0x6D, 0x8E, 0xAA, 0xE0, -0x6E, 0x79, 0x63, 0xF0, 0x6F, 0x6E, 0x8C, 0xE0, 0x70, 0x59, 0x45, 0xF0, 0x71, 0x4E, 0x6E, 0xE0, -0x72, 0x42, 0x62, 0x70, 0x73, 0x2E, 0x50, 0xE0, 0x74, 0x22, 0x44, 0x70, 0x75, 0x0E, 0x32, 0xE0, -0x76, 0x02, 0x26, 0x70, 0x76, 0xEE, 0x14, 0xE0, 0x77, 0xE2, 0x08, 0x70, 0x78, 0xD7, 0x31, 0x60, -0x79, 0xC1, 0xEA, 0x70, 0x7A, 0xB7, 0x13, 0x60, 0x7B, 0xA1, 0xCC, 0x70, 0x7C, 0x96, 0xF5, 0x60, -0x7D, 0x8A, 0xE8, 0xF0, 0x7E, 0x76, 0xD7, 0x60, 0x7F, 0x6A, 0xCA, 0xF0, 0x00, 0x01, 0x00, 0x01, +0x48, 0xB7, 0x2D, 0xF0, 0x49, 0xCB, 0xFA, 0xE0, 0x4A, 0xA0, 0x4A, 0x70, 0x4B, 0xAB, 0xDC, 0xE0, +0x4C, 0x80, 0x2C, 0x70, 0x4D, 0x8B, 0xBE, 0xE0, 0x4E, 0x60, 0x0E, 0x70, 0x4F, 0x74, 0xDB, 0x60, +0x50, 0x49, 0x2A, 0xF0, 0x51, 0x54, 0xBD, 0x60, 0x52, 0x29, 0x0C, 0xF0, 0x53, 0x34, 0x9F, 0x60, +0x54, 0x08, 0xEE, 0xF0, 0x55, 0x14, 0x81, 0x60, 0x55, 0xE8, 0xD0, 0xF0, 0x56, 0xF4, 0x63, 0x60, +0x57, 0xC8, 0xB2, 0xF0, 0x58, 0xDD, 0x7F, 0xE0, 0x59, 0xA8, 0x94, 0xF0, 0x5A, 0xBD, 0x61, 0xE0, +0x5B, 0x91, 0xB1, 0x70, 0x5C, 0x9D, 0x43, 0xE0, 0x5D, 0x71, 0x93, 0x70, 0x5E, 0x7D, 0x25, 0xE0, +0x5F, 0x51, 0x75, 0x70, 0x60, 0x5D, 0x07, 0xE0, 0x61, 0x31, 0x57, 0x70, 0x62, 0x3C, 0xE9, 0xE0, +0x63, 0x11, 0x39, 0x70, 0x64, 0x26, 0x06, 0x60, 0x64, 0xF1, 0x1B, 0x70, 0x66, 0x05, 0xE8, 0x60, +0x66, 0xDA, 0x37, 0xF0, 0x67, 0xE5, 0xCA, 0x60, 0x68, 0xBA, 0x19, 0xF0, 0x69, 0xC5, 0xAC, 0x60, +0x6A, 0x99, 0xFB, 0xF0, 0x6B, 0xA5, 0x8E, 0x60, 0x6C, 0x79, 0xDD, 0xF0, 0x6D, 0x8E, 0xAA, 0xE0, +0x6E, 0x59, 0xBF, 0xF0, 0x6F, 0x6E, 0x8C, 0xE0, 0x70, 0x42, 0xDC, 0x70, 0x71, 0x4E, 0x6E, 0xE0, +0x72, 0x22, 0xBE, 0x70, 0x73, 0x2E, 0x50, 0xE0, 0x74, 0x02, 0xA0, 0x70, 0x75, 0x0E, 0x32, 0xE0, +0x75, 0xE2, 0x82, 0x70, 0x76, 0xEE, 0x14, 0xE0, 0x77, 0xC2, 0x64, 0x70, 0x78, 0xD7, 0x31, 0x60, +0x79, 0xA2, 0x46, 0x70, 0x7A, 0xB7, 0x13, 0x60, 0x7B, 0x8B, 0x62, 0xF0, 0x7C, 0x96, 0xF5, 0x60, +0x7D, 0x6B, 0x44, 0xF0, 0x7E, 0x76, 0xD7, 0x60, 0x7F, 0x4B, 0x26, 0xF0, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, @@ -7836,12 +7732,13 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { /* Asia/Hong_Kong */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x48, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x85, 0x69, 0x5A, 0xFC, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x85, 0x69, 0x5A, 0xFC, +0xC9, 0xEA, 0x57, 0xB8, 0xCA, 0xDA, 0x3A, 0xA8, 0xCB, 0x4B, 0x78, 0x80, 0xD2, 0x4C, 0x62, 0x70, 0xD3, 0x6A, 0xB7, 0x38, 0xD4, 0x93, 0x4A, 0xA8, 0xD5, 0x42, 0xB0, 0x38, 0xD6, 0x9A, 0xB9, 0xA8, 0xD7, 0x3E, 0x41, 0xB8, 0xD8, 0x2E, 0x24, 0xA8, 0xD8, 0xF9, 0x39, 0xB8, 0xDA, 0x0E, 0x06, 0xA8, 0xDA, 0xD9, 0x1B, 0xB8, 0xDB, 0xED, 0xE8, 0xA8, 0xDC, 0xB8, 0xFD, 0xB8, 0xDD, 0xCD, 0xCA, 0xA8, -0xDE, 0xA2, 0x1A, 0x38, 0xDF, 0xAD, 0xAC, 0xA8, 0xE0, 0x81, 0xFC, 0x38, 0xE1, 0x96, 0xC9, 0x28, +0xDE, 0xA2, 0x1A, 0x38, 0xDF, 0xAC, 0x5B, 0x28, 0xE0, 0x81, 0xFC, 0x38, 0xE1, 0x96, 0xC9, 0x28, 0xE2, 0x4F, 0x69, 0x38, 0xE3, 0x76, 0xAB, 0x28, 0xE4, 0x2F, 0x4B, 0x38, 0xE5, 0x5F, 0xC7, 0xA8, 0xE6, 0x0F, 0x2D, 0x38, 0xE7, 0x3F, 0xA9, 0xA8, 0xE7, 0xF8, 0x49, 0xB8, 0xE9, 0x1F, 0x8B, 0xA8, 0xE9, 0xD8, 0x2B, 0xB8, 0xEA, 0xFF, 0x6D, 0xA8, 0xEB, 0xB8, 0x0D, 0xB8, 0xEC, 0xDF, 0x4F, 0xA8, @@ -7852,17 +7749,17 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFC, 0xCE, 0x5E, 0xB8, 0xFD, 0xBE, 0x41, 0xA8, 0xFE, 0xAE, 0x40, 0xB8, 0xFF, 0x9E, 0x23, 0xA8, 0x00, 0x8E, 0x22, 0xB8, 0x01, 0x7E, 0x05, 0xA8, 0x02, 0x6E, 0x04, 0xB8, 0x03, 0x5D, 0xE7, 0xA8, 0x04, 0x4D, 0xE6, 0xB8, 0x05, 0x47, 0x04, 0x28, 0x06, 0x37, 0x03, 0x38, 0x07, 0x26, 0xE6, 0x28, -0x08, 0x16, 0xE5, 0x38, 0x09, 0x06, 0xC8, 0x28, 0x09, 0xF6, 0xC7, 0x38, 0x0A, 0xE6, 0xAA, 0x28, +0x07, 0x83, 0x3D, 0x38, 0x09, 0x06, 0xC8, 0x28, 0x09, 0xF6, 0xC7, 0x38, 0x0A, 0xE6, 0xAA, 0x28, 0x0B, 0xD6, 0xA9, 0x38, 0x0C, 0xC6, 0x8C, 0x28, 0x0D, 0xB6, 0x8B, 0x38, 0x0E, 0xA6, 0x6E, 0x28, -0x11, 0x9B, 0x39, 0x38, 0x12, 0x6F, 0x6C, 0xA8, 0x13, 0x7B, 0x1B, 0x38, 0x14, 0x4F, 0x4E, 0xA8, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, +0x11, 0x9B, 0x39, 0x38, 0x12, 0x6F, 0x6C, 0xA8, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x6B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x90, 0x01, -0x04, 0x00, 0x00, 0x70, 0x80, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x48, 0x4B, 0x53, 0x54, 0x00, -0x48, 0x4B, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAB, 0x54, 0xAD, 0x01, 0xC0, -0xD6, 0x57, 0x00, 0x00, 0x00, 0x00, +0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x00, +0x00, 0x6B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x90, 0x01, 0x04, 0x00, 0x00, 0x70, 0x80, 0x00, +0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x48, 0x4B, 0x53, 0x54, 0x00, +0x48, 0x4B, 0x54, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0xAB, 0x54, 0xAD, 0x01, 0xC0, 0xD6, 0x57, 0x00, 0x00, 0x00, 0x00, /* Asia/Hovd */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4D, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -8014,7 +7911,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x00, 0x00, 0x70, 0x80, 0x00, 0x09, 0x00, 0x00, 0x62, 0x70, 0x00, 0x09, 0x4A, 0x4D, 0x54, 0x00, 0x4A, 0x41, 0x56, 0x54, 0x00, 0x57, 0x49, 0x54, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x80, 0x6D, 0x9A, 0x01, 0xB5, 0x9F, 0x40, 0x00, 0x00, 0x00, 0x0E, 0x4A, 0x61, 0x76, 0x61, +0x00, 0x7F, 0xEB, 0x65, 0x01, 0xB5, 0x9F, 0x40, 0x00, 0x00, 0x00, 0x0E, 0x4A, 0x61, 0x76, 0x61, 0x20, 0x26, 0x20, 0x53, 0x75, 0x6D, 0x61, 0x74, 0x72, 0x61, /* Asia/Jayapura */ @@ -8024,7 +7921,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xD0, 0x58, 0xB9, 0xF0, 0xF4, 0xB5, 0xA2, 0x68, 0x01, 0x02, 0x01, 0x00, 0x00, 0x83, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x04, 0x00, 0x00, 0x85, 0x98, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x45, 0x49, 0x54, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x87, 0x17, 0x55, 0x01, 0xE9, 0x59, 0x70, 0x00, 0x00, 0x00, 0x19, 0x49, 0x72, 0x69, 0x61, 0x6E, +0x85, 0x76, 0xAA, 0x01, 0xE9, 0x59, 0x70, 0x00, 0x00, 0x00, 0x19, 0x49, 0x72, 0x69, 0x61, 0x6E, 0x20, 0x4A, 0x61, 0x79, 0x61, 0x20, 0x26, 0x20, 0x74, 0x68, 0x65, 0x20, 0x4D, 0x6F, 0x6C, 0x75, 0x63, 0x63, 0x61, 0x73, @@ -8141,16 +8038,33 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { /* Asia/Karachi */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x50, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x0B, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x89, 0x7E, 0xFC, 0xA4, +0x00, 0x00, 0x00, 0x43, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, 0x16, 0x89, 0x7E, 0xFC, 0xA4, 0xCC, 0x95, 0x32, 0xA8, 0xD2, 0x74, 0x12, 0x98, 0xDD, 0xA8, 0xE0, 0xA8, 0x02, 0x4F, 0xAB, 0x30, 0x3C, 0xAF, 0x45, 0xEC, 0x3D, 0x9F, 0x28, 0xDC, 0x48, 0x41, 0xA0, 0x30, 0x49, 0x0B, 0x47, 0xA0, -0x49, 0xE4, 0xDD, 0x30, 0x4A, 0xEC, 0x7B, 0x20, 0x01, 0x02, 0x01, 0x03, 0x05, 0x04, 0x05, 0x04, -0x05, 0x04, 0x05, 0x00, 0x00, 0x3E, 0xDC, 0x00, 0x00, 0x00, 0x00, 0x4D, 0x58, 0x00, 0x04, 0x00, -0x00, 0x5B, 0x68, 0x01, 0x04, 0x00, 0x00, 0x46, 0x50, 0x00, 0x08, 0x00, 0x00, 0x54, 0x60, 0x01, -0x0D, 0x00, 0x00, 0x46, 0x50, 0x00, 0x12, 0x4C, 0x4D, 0x54, 0x00, 0x49, 0x53, 0x54, 0x00, 0x4B, -0x41, 0x52, 0x54, 0x00, 0x50, 0x4B, 0x53, 0x54, 0x00, 0x50, 0x4B, 0x54, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xAF, 0x45, 0xCA, 0x01, 0x78, 0xF7, -0xE8, 0x00, 0x00, 0x00, 0x00, +0x49, 0xE4, 0xDD, 0x30, 0x4A, 0xEC, 0x7B, 0x20, 0x4B, 0xC6, 0x10, 0xB0, 0x4C, 0xCD, 0xAE, 0xA0, +0x4D, 0xA7, 0x44, 0x30, 0x4E, 0xAE, 0xE2, 0x20, 0x4F, 0x89, 0xC9, 0x30, 0x50, 0x91, 0x67, 0x20, +0x51, 0x6A, 0xFC, 0xB0, 0x52, 0x72, 0x9A, 0xA0, 0x53, 0x4C, 0x30, 0x30, 0x54, 0x53, 0xCE, 0x20, +0x55, 0x2D, 0x63, 0xB0, 0x56, 0x35, 0x01, 0xA0, 0x57, 0x0F, 0xE8, 0xB0, 0x58, 0x17, 0x86, 0xA0, +0x58, 0xF1, 0x1C, 0x30, 0x59, 0xF8, 0xBA, 0x20, 0x5A, 0xD2, 0x4F, 0xB0, 0x5B, 0xD9, 0xED, 0xA0, +0x5C, 0xB3, 0x83, 0x30, 0x5D, 0xBB, 0x21, 0x20, 0x5E, 0x96, 0x08, 0x30, 0x5F, 0x9D, 0xA6, 0x20, +0x60, 0x77, 0x3B, 0xB0, 0x61, 0x7E, 0xD9, 0xA0, 0x62, 0x58, 0x6F, 0x30, 0x63, 0x60, 0x0D, 0x20, +0x64, 0x39, 0xA2, 0xB0, 0x65, 0x41, 0x40, 0xA0, 0x66, 0x1C, 0x27, 0xB0, 0x67, 0x23, 0xC5, 0xA0, +0x67, 0xFD, 0x5B, 0x30, 0x69, 0x04, 0xF9, 0x20, 0x69, 0xDE, 0x8E, 0xB0, 0x6A, 0xE6, 0x2C, 0xA0, +0x6B, 0xBF, 0xC2, 0x30, 0x6C, 0xC7, 0x60, 0x20, 0x6D, 0xA2, 0x47, 0x30, 0x6E, 0xA9, 0xE5, 0x20, +0x6F, 0x83, 0x7A, 0xB0, 0x70, 0x8B, 0x18, 0xA0, 0x71, 0x64, 0xAE, 0x30, 0x72, 0x6C, 0x4C, 0x20, +0x73, 0x45, 0xE1, 0xB0, 0x74, 0x4D, 0x7F, 0xA0, 0x75, 0x28, 0x66, 0xB0, 0x76, 0x30, 0x04, 0xA0, +0x77, 0x09, 0x9A, 0x30, 0x78, 0x11, 0x38, 0x20, 0x78, 0xEA, 0xCD, 0xB0, 0x79, 0xF2, 0x6B, 0xA0, +0x7A, 0xCC, 0x01, 0x30, 0x7B, 0xD3, 0x9F, 0x20, 0x7C, 0xAE, 0x86, 0x30, 0x7D, 0xB6, 0x24, 0x20, +0x7E, 0x8F, 0xB9, 0xB0, 0x7F, 0x97, 0x57, 0xA0, 0x01, 0x02, 0x01, 0x03, 0x05, 0x04, 0x05, 0x04, +0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, +0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, +0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, +0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x00, 0x00, 0x3E, 0xDC, 0x00, +0x00, 0x00, 0x00, 0x4D, 0x58, 0x00, 0x04, 0x00, 0x00, 0x5B, 0x68, 0x01, 0x04, 0x00, 0x00, 0x46, +0x50, 0x00, 0x08, 0x00, 0x00, 0x54, 0x60, 0x01, 0x0D, 0x00, 0x00, 0x46, 0x50, 0x00, 0x12, 0x4C, +0x4D, 0x54, 0x00, 0x49, 0x53, 0x54, 0x00, 0x4B, 0x41, 0x52, 0x54, 0x00, 0x50, 0x4B, 0x53, 0x54, +0x00, 0x50, 0x4B, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0xAF, 0x45, 0xCA, 0x01, 0x78, 0xF7, 0xE8, 0x00, 0x00, 0x00, 0x00, /* Asia/Kashgar */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x4E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -8385,7 +8299,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x6F, 0xF0, 0x00, 0x00, 0x00, 0x00, 0x6F, 0xF0, 0x00, 0x04, 0x00, 0x00, 0x70, 0x80, 0x00, 0x08, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0C, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x4D, 0x54, 0x00, 0x43, 0x49, 0x54, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x81, 0xE0, 0xB2, 0x01, 0xC8, 0xD9, 0x1F, 0x00, 0x00, 0x00, 0x3D, 0x65, 0x61, 0x73, 0x74, +0x00, 0x81, 0x85, 0x8D, 0x01, 0xC8, 0xD9, 0x1F, 0x00, 0x00, 0x00, 0x3D, 0x65, 0x61, 0x73, 0x74, 0x20, 0x26, 0x20, 0x73, 0x6F, 0x75, 0x74, 0x68, 0x20, 0x42, 0x6F, 0x72, 0x6E, 0x65, 0x6F, 0x2C, 0x20, 0x43, 0x65, 0x6C, 0x65, 0x62, 0x65, 0x73, 0x2C, 0x20, 0x42, 0x61, 0x6C, 0x69, 0x2C, 0x20, 0x4E, 0x75, 0x73, 0x61, 0x20, 0x54, 0x65, 0x6E, 0x67, 0x61, 0x72, 0x72, 0x61, 0x2C, 0x20, 0x77, @@ -8459,6 +8373,57 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xBE, 0xFD, 0x3A, 0x01, 0x45, 0x92, 0x5A, 0x00, 0x00, 0x00, 0x00, +/* Asia/Novokuznetsk */ +0x50, 0x48, 0x50, 0x31, 0x01, 0x52, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x75, 0x00, 0x00, 0x00, 0x0A, 0x00, 0x00, 0x00, 0x1A, 0xA1, 0xF9, 0x13, 0x40, +0xB5, 0xA3, 0xE1, 0x20, 0x15, 0x27, 0x6F, 0x90, 0x16, 0x18, 0xA4, 0x00, 0x17, 0x08, 0xA3, 0x10, +0x17, 0xF9, 0xD7, 0x80, 0x18, 0xE9, 0xD6, 0x90, 0x19, 0xDB, 0x0B, 0x00, 0x1A, 0xCC, 0x5B, 0x90, +0x1B, 0xBC, 0x68, 0xB0, 0x1C, 0xAC, 0x59, 0xB0, 0x1D, 0x9C, 0x4A, 0xB0, 0x1E, 0x8C, 0x3B, 0xB0, +0x1F, 0x7C, 0x2C, 0xB0, 0x20, 0x6C, 0x1D, 0xB0, 0x21, 0x5C, 0x0E, 0xB0, 0x22, 0x4B, 0xFF, 0xB0, +0x23, 0x3B, 0xF0, 0xB0, 0x24, 0x2B, 0xE1, 0xB0, 0x25, 0x1B, 0xD2, 0xB0, 0x26, 0x0B, 0xC3, 0xB0, +0x27, 0x04, 0xEF, 0x30, 0x27, 0xF4, 0xE0, 0x30, 0x28, 0xE4, 0xDF, 0x40, 0x29, 0x78, 0x87, 0x40, +0x29, 0xD4, 0x98, 0x00, 0x2A, 0xC4, 0x7A, 0xF0, 0x2B, 0xB4, 0xA4, 0x30, 0x2C, 0xA4, 0x95, 0x30, +0x2D, 0x94, 0x86, 0x30, 0x2E, 0x84, 0x77, 0x30, 0x2F, 0x74, 0x68, 0x30, 0x30, 0x64, 0x59, 0x30, +0x31, 0x5D, 0x84, 0xB0, 0x32, 0x72, 0x5F, 0xB0, 0x33, 0x3D, 0x66, 0xB0, 0x34, 0x52, 0x41, 0xB0, +0x35, 0x1D, 0x48, 0xB0, 0x36, 0x32, 0x23, 0xB0, 0x36, 0xFD, 0x2A, 0xB0, 0x38, 0x1B, 0x40, 0x30, +0x38, 0xDD, 0x0C, 0xB0, 0x39, 0xFB, 0x22, 0x30, 0x3A, 0xBC, 0xEE, 0xB0, 0x3B, 0xDB, 0x04, 0x30, +0x3C, 0xA6, 0x0B, 0x30, 0x3D, 0xBA, 0xE6, 0x30, 0x3E, 0x85, 0xED, 0x30, 0x3F, 0x9A, 0xC8, 0x30, +0x40, 0x65, 0xCF, 0x30, 0x41, 0x83, 0xE4, 0xB0, 0x42, 0x45, 0xB1, 0x30, 0x43, 0x63, 0xC6, 0xB0, +0x44, 0x25, 0x93, 0x30, 0x45, 0x43, 0xA8, 0xB0, 0x46, 0x05, 0x75, 0x30, 0x47, 0x23, 0x8A, 0xB0, +0x47, 0xEE, 0x91, 0xB0, 0x49, 0x03, 0x6C, 0xB0, 0x49, 0xCE, 0x73, 0xB0, 0x4A, 0xE3, 0x4E, 0xB0, +0x4B, 0xAE, 0x55, 0xB0, 0x4C, 0xCC, 0x79, 0x40, 0x4D, 0x8E, 0x45, 0xC0, 0x4E, 0xAC, 0x5B, 0x40, +0x4F, 0x6E, 0x27, 0xC0, 0x50, 0x8C, 0x3D, 0x40, 0x51, 0x57, 0x44, 0x40, 0x52, 0x6C, 0x1F, 0x40, +0x53, 0x37, 0x26, 0x40, 0x54, 0x4C, 0x01, 0x40, 0x55, 0x17, 0x08, 0x40, 0x56, 0x2B, 0xE3, 0x40, +0x56, 0xF6, 0xEA, 0x40, 0x58, 0x14, 0xFF, 0xC0, 0x58, 0xD6, 0xCC, 0x40, 0x59, 0xF4, 0xE1, 0xC0, +0x5A, 0xB6, 0xAE, 0x40, 0x5B, 0xD4, 0xC3, 0xC0, 0x5C, 0x9F, 0xCA, 0xC0, 0x5D, 0xB4, 0xA5, 0xC0, +0x5E, 0x7F, 0xAC, 0xC0, 0x5F, 0x94, 0x87, 0xC0, 0x60, 0x5F, 0x8E, 0xC0, 0x61, 0x7D, 0xA4, 0x40, +0x62, 0x3F, 0x70, 0xC0, 0x63, 0x5D, 0x86, 0x40, 0x64, 0x1F, 0x52, 0xC0, 0x65, 0x3D, 0x68, 0x40, +0x66, 0x08, 0x6F, 0x40, 0x67, 0x1D, 0x4A, 0x40, 0x67, 0xE8, 0x51, 0x40, 0x68, 0xFD, 0x2C, 0x40, +0x69, 0xC8, 0x33, 0x40, 0x6A, 0xDD, 0x0E, 0x40, 0x6B, 0xA8, 0x15, 0x40, 0x6C, 0xC6, 0x2A, 0xC0, +0x6D, 0x87, 0xF7, 0x40, 0x6E, 0xA6, 0x0C, 0xC0, 0x6F, 0x67, 0xD9, 0x40, 0x70, 0x85, 0xEE, 0xC0, +0x71, 0x50, 0xF5, 0xC0, 0x72, 0x65, 0xD0, 0xC0, 0x73, 0x30, 0xD7, 0xC0, 0x74, 0x45, 0xB2, 0xC0, +0x75, 0x10, 0xB9, 0xC0, 0x76, 0x2E, 0xCF, 0x40, 0x76, 0xF0, 0x9B, 0xC0, 0x78, 0x0E, 0xB1, 0x40, +0x78, 0xD0, 0x7D, 0xC0, 0x79, 0xEE, 0x93, 0x40, 0x7A, 0xB0, 0x5F, 0xC0, 0x7B, 0xCE, 0x75, 0x40, +0x7C, 0x99, 0x7C, 0x40, 0x7D, 0xAE, 0x57, 0x40, 0x7E, 0x79, 0x5E, 0x40, 0x7F, 0x8E, 0x39, 0x40, +0x01, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, +0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x06, 0x07, 0x04, 0x02, 0x03, 0x05, 0x04, 0x05, 0x04, 0x05, +0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, +0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x05, 0x04, 0x08, 0x09, 0x08, +0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, +0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, +0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, 0x09, 0x08, +0x09, 0x08, 0x09, 0x08, 0x09, 0x00, 0x00, 0x51, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x54, 0x60, 0x00, +0x04, 0x00, 0x00, 0x70, 0x80, 0x01, 0x09, 0x00, 0x00, 0x62, 0x70, 0x00, 0x04, 0x00, 0x00, 0x62, +0x70, 0x00, 0x04, 0x00, 0x00, 0x70, 0x80, 0x01, 0x09, 0x00, 0x00, 0x62, 0x70, 0x01, 0x09, 0x00, +0x00, 0x54, 0x60, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70, 0x01, 0x0F, 0x00, 0x00, 0x54, 0x60, 0x00, +0x15, 0x4E, 0x4D, 0x54, 0x00, 0x4B, 0x52, 0x41, 0x54, 0x00, 0x4B, 0x52, 0x41, 0x53, 0x54, 0x00, +0x4E, 0x4F, 0x56, 0x53, 0x54, 0x00, 0x4E, 0x4F, 0x56, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, +0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0xDB, 0x58, 0x58, 0x01, 0x97, 0x96, 0x72, 0x00, 0x00, 0x00, 0x18, 0x4D, 0x6F, 0x73, 0x63, 0x6F, +0x77, 0x2B, 0x30, 0x33, 0x20, 0x2D, 0x20, 0x4E, 0x6F, 0x76, 0x6F, 0x6B, 0x75, 0x7A, 0x6E, 0x65, +0x74, 0x73, 0x6B, + /* Asia/Novosibirsk */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x52, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, @@ -8611,7 +8576,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x08, 0x00, 0x00, 0x70, 0x80, 0x00, 0x10, 0x00, 0x00, 0x62, 0x70, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x50, 0x4D, 0x54, 0x00, 0x57, 0x49, 0x54, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x43, 0x49, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x89, 0x61, 0x45, 0x01, 0xB9, 0x7C, 0xD5, 0x00, 0x00, 0x00, 0x15, 0x77, 0x65, 0x73, 0x74, +0x00, 0x89, 0x47, 0x3A, 0x01, 0xB9, 0x7C, 0xD5, 0x00, 0x00, 0x00, 0x15, 0x77, 0x65, 0x73, 0x74, 0x20, 0x26, 0x20, 0x63, 0x65, 0x6E, 0x74, 0x72, 0x61, 0x6C, 0x20, 0x42, 0x6F, 0x72, 0x6E, 0x65, 0x6F, @@ -9367,7 +9332,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x48, 0x4D, 0x54, 0x00, 0x41, 0x5A, 0x4F, 0x53, 0x54, 0x00, 0x41, 0x5A, 0x4F, 0x54, 0x00, 0x41, 0x5A, 0x4F, 0x4D, 0x54, 0x00, 0x57, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, -0x01, 0x00, 0xC2, 0xE7, 0xD5, 0x00, 0xED, 0x87, 0x4A, 0x00, 0x00, 0x00, 0x06, 0x41, 0x7A, 0x6F, +0x01, 0x00, 0xC2, 0xE7, 0xD5, 0x00, 0xEB, 0x7E, 0x75, 0x00, 0x00, 0x00, 0x06, 0x41, 0x7A, 0x6F, 0x72, 0x65, 0x73, /* Atlantic/Bermuda */ @@ -9416,7 +9381,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xC3, 0x48, 0x00, 0x00, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x41, 0x53, 0x54, 0x00, 0x41, 0x44, 0x54, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA, 0x96, 0xED, 0x00, 0xB2, 0x2B, 0xFA, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xBA, 0x96, 0xED, 0x00, 0xAF, 0xD5, 0x05, 0x00, 0x00, 0x00, 0x00, /* Atlantic/Canary */ @@ -9464,7 +9429,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x0D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x0E, 0x10, 0x01, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x41, 0x4E, 0x54, 0x00, 0x57, 0x45, 0x54, 0x00, 0x57, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xB4, 0x34, 0xD0, -0x00, 0xFC, 0x61, 0x60, 0x00, 0x00, 0x00, 0x0E, 0x43, 0x61, 0x6E, 0x61, 0x72, 0x79, 0x20, 0x49, +0x00, 0xFB, 0x28, 0xE0, 0x00, 0x00, 0x00, 0x0E, 0x43, 0x61, 0x6E, 0x61, 0x72, 0x79, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, /* Atlantic/Cape_Verde */ @@ -9475,7 +9440,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0xE9, 0xF4, 0x00, 0x00, 0xFF, 0xFF, 0xE3, 0xE0, 0x00, 0x04, 0xFF, 0xFF, 0xF1, 0xF0, 0x01, 0x08, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x56, 0x54, 0x00, 0x43, 0x56, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xA0, 0x17, -0x12, 0x00, 0xF0, 0x59, 0xF2, 0x00, 0x00, 0x00, 0x00, +0x12, 0x00, 0xEE, 0xC6, 0x4D, 0x00, 0x00, 0x00, 0x00, /* Atlantic/Faeroe */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -9564,7 +9529,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0xFF, 0xFF, 0xF9, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x0E, 0x10, 0x01, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x57, 0x45, 0x54, 0x00, 0x57, 0x45, 0x53, 0x54, 0x00, -0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0xE7, 0xF5, 0x82, 0x01, 0x0A, 0xAC, 0x3A, +0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x01, 0x01, 0x00, 0xE7, 0xF5, 0x82, 0x01, 0x08, 0x55, 0x45, 0x00, 0x00, 0x00, 0x00, /* Atlantic/Jan_Mayen */ @@ -9701,7 +9666,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x44, 0x53, 0x54, 0x00, 0x4D, 0x41, 0x44, 0x54, 0x00, 0x4D, 0x41, 0x44, 0x4D, 0x54, 0x00, 0x57, 0x45, 0x53, 0x54, 0x00, 0x57, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xBB, -0x1F, 0xA5, 0x00, 0xFB, 0x9E, 0x10, 0x00, 0x00, 0x00, 0x0F, 0x4D, 0x61, 0x64, 0x65, 0x69, 0x72, +0x1F, 0xA5, 0x00, 0xF8, 0xDE, 0xF0, 0x00, 0x00, 0x00, 0x0F, 0x4D, 0x61, 0x64, 0x65, 0x69, 0x72, 0x61, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, /* Atlantic/Reykjavik */ @@ -9732,13 +9697,13 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x01, 0x04, 0xFF, 0xFF, 0xF1, 0xF0, 0x00, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0D, 0x52, 0x4D, 0x54, 0x00, 0x49, 0x53, 0x53, 0x54, 0x00, 0x49, 0x53, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xEB, 0x36, -0xD8, 0x00, 0xF3, 0xE9, 0x68, 0x00, 0x00, 0x00, 0x00, +0xD8, 0x00, 0xF1, 0x51, 0x58, 0x00, 0x00, 0x00, 0x00, /* Atlantic/South_Georgia */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x47, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0xE3, 0xE0, -0x00, 0x00, 0x47, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x37, 0x56, 0xAA, 0x00, 0xDC, 0x8A, 0x55, +0x00, 0x00, 0x47, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x36, 0x86, 0x55, 0x00, 0xDA, 0xE9, 0xAA, 0x00, 0x00, 0x00, 0x00, /* Atlantic/Stanley */ @@ -9786,7 +9751,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x01, 0x02, 0x01, 0xFF, 0xFF, 0xC9, 0xC4, 0x00, 0x00, 0xFF, 0xFF, 0xD5, 0xD0, 0x01, 0x04, 0xFF, 0xFF, 0xC7, 0xC0, 0x00, 0x09, 0xFF, 0xFF, 0xE3, 0xE0, 0x01, 0x04, 0xFF, 0xFF, 0xD5, 0xD0, 0x00, 0x09, 0x53, 0x4D, 0x54, 0x00, 0x46, 0x4B, 0x53, 0x54, 0x00, 0x46, 0x4B, 0x54, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3C, 0x93, 0xD0, 0x00, 0xBC, 0xFA, 0xE8, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3A, 0x70, 0xEF, 0x00, 0xBA, 0x62, 0xD8, 0x00, 0x00, 0x00, 0x00, /* Atlantic/St_Helena */ @@ -9794,8 +9759,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0xDC, 0x42, 0x9B, 0x58, 0x01, 0xFF, 0xFF, 0xFA, 0xA8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x4A, 0x4D, 0x54, -0x00, 0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0xD6, 0xF2, 0x01, 0x0C, 0x18, -0xD0, 0x00, 0x00, 0x00, 0x00, +0x00, 0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x0A, 0xCD, 0x01, 0x09, 0xF5, +0xF0, 0x00, 0x00, 0x00, 0x00, /* Australia/ACT */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -9899,7 +9864,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, 0x93, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x85, 0x98, 0x00, 0x00, 0x00, 0x00, 0x93, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x85, 0x98, 0x00, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x56, 0xD9, 0x12, 0x01, 0xE6, 0x1E, 0x9D, 0x00, 0x00, 0x00, 0x0F, 0x53, 0x6F, 0x75, +0x00, 0x00, 0x54, 0x0C, 0xED, 0x01, 0xE6, 0x1E, 0x9D, 0x00, 0x00, 0x00, 0x0F, 0x53, 0x6F, 0x75, 0x74, 0x68, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6C, 0x69, 0x61, /* Australia/Brisbane */ @@ -9913,7 +9878,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x00, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x00, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, -0x00, 0x60, 0xD7, 0xAA, 0x01, 0xFC, 0x2B, 0x25, 0x00, 0x00, 0x00, 0x1B, 0x51, 0x75, 0x65, 0x65, +0x00, 0x5F, 0x6B, 0x15, 0x01, 0xFC, 0x2B, 0x25, 0x00, 0x00, 0x00, 0x1B, 0x51, 0x75, 0x65, 0x65, 0x6E, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, @@ -9967,7 +9932,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, 0x93, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x85, 0x98, 0x00, 0x00, 0x00, 0x00, 0x93, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x85, 0x98, 0x00, 0x00, 0x43, 0x53, 0x54, 0x00, 0x00, 0x00, -0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x79, 0xF8, 0x01, 0xEA, 0x7E, 0x68, 0x00, 0x00, +0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x93, 0xC8, 0x01, 0xEA, 0x7E, 0x68, 0x00, 0x00, 0x00, 0x1C, 0x4E, 0x65, 0x77, 0x20, 0x53, 0x6F, 0x75, 0x74, 0x68, 0x20, 0x57, 0x61, 0x6C, 0x65, 0x73, 0x20, 0x2D, 0x20, 0x59, 0x61, 0x6E, 0x63, 0x6F, 0x77, 0x69, 0x6E, 0x6E, 0x61, @@ -10073,7 +10038,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x00, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x00, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x4F, 0x3E, 0x75, 0x01, 0xEE, 0x2E, 0x6A, 0x00, 0x00, 0x00, 0x16, 0x54, 0x61, 0x73, +0x00, 0x00, 0x4C, 0x65, 0x4A, 0x01, 0xEE, 0x2E, 0x6A, 0x00, 0x00, 0x00, 0x16, 0x54, 0x61, 0x73, 0x6D, 0x61, 0x6E, 0x69, 0x61, 0x20, 0x2D, 0x20, 0x4B, 0x69, 0x6E, 0x67, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, @@ -10084,7 +10049,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x9C, 0xBC, 0x27, 0xF8, 0xCB, 0x54, 0xBA, 0x08, 0xCB, 0xC7, 0x5E, 0x78, 0xCC, 0xB7, 0x5D, 0x88, 0xCD, 0xA7, 0x40, 0x78, 0xCE, 0xA0, 0x7A, 0x08, 0xCF, 0x87, 0x22, 0x78, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x00, 0x93, 0xA8, 0x01, 0x00, 0x00, 0x00, 0x85, 0x98, 0x00, 0x00, -0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0xBB, 0x0A, 0x01, 0xDA, 0x4B, 0x45, +0x43, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0x4E, 0x75, 0x01, 0xDA, 0x4B, 0x45, 0x00, 0x00, 0x00, 0x12, 0x4E, 0x6F, 0x72, 0x74, 0x68, 0x65, 0x72, 0x6E, 0x20, 0x54, 0x65, 0x72, 0x72, 0x69, 0x74, 0x6F, 0x72, 0x79, @@ -10099,7 +10064,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x49, 0xCE, 0x5B, 0x14, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x00, 0x00, 0x89, 0x1C, 0x01, 0x00, 0x00, 0x00, 0x7B, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x89, 0x1C, 0x01, 0x00, 0x00, 0x00, 0x7B, 0x0C, 0x00, 0x00, 0x43, 0x57, -0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x1E, 0xD2, 0x01, +0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0xEE, 0xED, 0x01, 0xD7, 0x4B, 0x0A, 0x00, 0x00, 0x00, 0x1E, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6C, 0x69, 0x61, 0x20, 0x2D, 0x20, 0x45, 0x75, 0x63, 0x6C, 0x61, 0x20, 0x61, 0x72, 0x65, 0x61, @@ -10156,7 +10121,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x00, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x00, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x45, 0x53, 0x54, -0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4A, 0x97, 0x0D, 0x01, 0xF3, 0x72, +0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x47, 0xE4, 0xF2, 0x01, 0xF3, 0x72, 0x12, 0x00, 0x00, 0x00, 0x19, 0x54, 0x61, 0x73, 0x6D, 0x61, 0x6E, 0x69, 0x61, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, @@ -10216,7 +10181,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x01, 0x02, 0x03, 0x02, 0x03, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x00, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x00, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x45, 0x53, 0x54, -0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x37, 0xEA, 0x01, 0xF6, 0x03, +0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x67, 0x95, 0x01, 0xF6, 0x03, 0xA0, 0x00, 0x00, 0x00, 0x1C, 0x51, 0x75, 0x65, 0x65, 0x6E, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x20, 0x2D, 0x20, 0x48, 0x6F, 0x6C, 0x69, 0x64, 0x61, 0x79, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, @@ -10263,7 +10228,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xB8, 0x01, 0x04, 0x00, 0x00, 0x93, 0xA8, 0x00, 0x04, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x04, 0x45, 0x53, 0x54, 0x00, 0x4C, 0x48, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x5A, 0xDD, 0xB8, 0x02, 0x05, 0x66, 0x6D, 0x00, 0x00, 0x00, 0x10, 0x4C, 0x6F, 0x72, 0x64, 0x20, +0x59, 0x30, 0x08, 0x02, 0x05, 0x66, 0x6D, 0x00, 0x00, 0x00, 0x10, 0x4C, 0x6F, 0x72, 0x64, 0x20, 0x48, 0x6F, 0x77, 0x65, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, /* Australia/Melbourne */ @@ -10316,7 +10281,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x00, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x00, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x52, 0x1E, 0x22, 0x01, 0xEF, 0xDC, 0x1A, 0x00, 0x00, 0x00, 0x08, 0x56, 0x69, 0x63, +0x00, 0x00, 0x4F, 0xA0, 0x1D, 0x01, 0xEF, 0xDC, 0x1A, 0x00, 0x00, 0x00, 0x08, 0x56, 0x69, 0x63, 0x74, 0x6F, 0x72, 0x69, 0x61, /* Australia/North */ @@ -10392,7 +10357,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x49, 0xCE, 0x65, 0xA0, 0x00, 0x01, 0x00, 0x01, 0x00, 0x01, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x00, 0x00, 0x7E, 0x90, 0x01, 0x00, 0x00, 0x00, 0x70, 0x80, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x90, 0x01, 0x00, 0x00, 0x00, 0x70, 0x80, 0x00, 0x00, 0x57, 0x53, -0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5B, 0x79, 0xF8, 0x01, 0xC3, +0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x93, 0xC8, 0x01, 0xC3, 0x6E, 0x68, 0x00, 0x00, 0x00, 0x22, 0x57, 0x65, 0x73, 0x74, 0x65, 0x72, 0x6E, 0x20, 0x41, 0x75, 0x73, 0x74, 0x72, 0x61, 0x6C, 0x69, 0x61, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, @@ -10512,7 +10477,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x03, 0x02, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x00, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x00, 0x00, 0x9A, 0xB0, 0x01, 0x00, 0x00, 0x00, 0x8C, 0xA0, 0x00, 0x00, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, -0x00, 0x00, 0x58, 0x4C, 0x2A, 0x01, 0xF9, 0x65, 0x82, 0x00, 0x00, 0x00, 0x20, 0x4E, 0x65, 0x77, +0x00, 0x00, 0x55, 0xA7, 0x15, 0x01, 0xF9, 0x65, 0x82, 0x00, 0x00, 0x00, 0x20, 0x4E, 0x65, 0x77, 0x20, 0x53, 0x6F, 0x75, 0x74, 0x68, 0x20, 0x57, 0x61, 0x6C, 0x65, 0x73, 0x20, 0x2D, 0x20, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, @@ -11701,7 +11666,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x3F, 0x73, 0x57, 0x50, 0x40, 0x91, 0x7A, 0xE0, 0x41, 0x5C, 0x73, 0xD0, 0x42, 0x71, 0x5C, 0xE0, 0x43, 0x3C, 0x55, 0xD0, 0x44, 0x51, 0x3E, 0xE0, 0x45, 0x12, 0xFD, 0x50, 0x46, 0x31, 0x20, 0xE0, 0x46, 0xE0, 0x6A, 0x50, 0x48, 0x11, 0x02, 0xE0, 0x48, 0xB7, 0x11, 0xD0, 0x49, 0xF0, 0xE4, 0xE0, -0x4A, 0xBB, 0xDD, 0xD0, 0x4B, 0xDA, 0x01, 0x60, 0x4C, 0xA4, 0xFA, 0x50, 0x4D, 0xB9, 0xE3, 0x60, +0x4A, 0x8D, 0xB9, 0x50, 0x4B, 0xDA, 0x01, 0x60, 0x4C, 0xA4, 0xFA, 0x50, 0x4D, 0xB9, 0xE3, 0x60, 0x4E, 0x84, 0xDC, 0x50, 0x4F, 0x99, 0xC5, 0x60, 0x50, 0x64, 0xBE, 0x50, 0x51, 0x79, 0xA7, 0x60, 0x52, 0x44, 0xA0, 0x50, 0x53, 0x59, 0x89, 0x60, 0x54, 0x24, 0x82, 0x50, 0x55, 0x39, 0x6B, 0x60, 0x56, 0x04, 0x64, 0x50, 0x57, 0x22, 0x87, 0xE0, 0x57, 0xED, 0x80, 0xD0, 0x59, 0x02, 0x69, 0xE0, @@ -12905,7 +12870,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x0E, 0x10, 0x00, 0x04, 0x00, 0x00, 0x0E, 0x10, 0x01, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0C, 0x44, 0x4D, 0x54, 0x00, 0x49, 0x53, 0x54, 0x00, 0x42, 0x53, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xDA, 0xB5, 0x95, 0x01, 0x09, 0xE2, 0x68, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xDA, 0xB5, 0x95, 0x01, 0x09, 0x1F, 0x18, 0x00, 0x00, 0x00, 0x00, /* Europe/Gibraltar */ @@ -12978,7 +12943,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x20, 0x01, 0x11, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x0D, 0x42, 0x53, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x42, 0x44, 0x53, 0x54, 0x00, 0x43, 0x45, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0xC0, 0x76, 0xD5, 0x01, -0x0B, 0x90, 0x18, 0x00, 0x00, 0x00, 0x00, +0x0A, 0x7E, 0xA8, 0x00, 0x00, 0x00, 0x00, /* Europe/Guernsey */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x47, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -13064,7 +13029,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x0E, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x42, 0x53, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x42, 0x44, 0x53, 0x54, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xD4, 0xC8, 0xA7, 0x01, -0x10, 0x6B, 0x95, 0x00, 0x00, 0x00, 0x00, +0x0E, 0xCA, 0xEA, 0x00, 0x00, 0x00, 0x00, /* Europe/Helsinki */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x46, 0x49, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -13196,7 +13161,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x0E, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x42, 0x53, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x42, 0x44, 0x53, 0x54, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xDB, 0xF4, 0x98, 0x01, -0x0D, 0x44, 0x4A, 0x00, 0x00, 0x00, 0x00, +0x0B, 0xD7, 0xB5, 0x00, 0x00, 0x00, 0x00, /* Europe/Istanbul */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x54, 0x52, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -13347,7 +13312,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x0E, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x42, 0x53, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x42, 0x44, 0x53, 0x54, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xD4, 0x66, 0xFF, 0x01, -0x0F, 0xC8, 0xD2, 0x00, 0x00, 0x00, 0x00, +0x0F, 0x6D, 0xAD, 0x00, 0x00, 0x00, 0x00, /* Europe/Kaliningrad */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x52, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -13538,7 +13503,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x4D, 0x54, 0x00, 0x57, 0x45, 0x53, 0x54, 0x00, 0x57, 0x45, 0x54, 0x00, 0x57, 0x45, 0x4D, 0x54, 0x00, 0x43, 0x45, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, -0x00, 0xC4, 0x67, 0xF2, 0x01, 0x05, 0x20, 0xF5, 0x00, 0x00, 0x00, 0x08, 0x6D, 0x61, 0x69, 0x6E, +0x00, 0xC4, 0x67, 0xF2, 0x01, 0x04, 0xB8, 0xCA, 0x00, 0x00, 0x00, 0x08, 0x6D, 0x61, 0x69, 0x6E, 0x6C, 0x61, 0x6E, 0x64, /* Europe/Ljubljana */ @@ -13672,7 +13637,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x0E, 0x10, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x42, 0x53, 0x54, 0x00, 0x47, 0x4D, 0x54, 0x00, 0x42, 0x44, 0x53, 0x54, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0xD7, 0xEC, 0xB1, 0x01, -0x12, 0xD9, 0x6F, 0x00, 0x00, 0x00, 0x00, +0x12, 0x77, 0x90, 0x00, 0x00, 0x00, 0x00, /* Europe/Luxembourg */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4C, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -13806,7 +13771,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x1C, 0x20, 0x01, 0x0E, 0x00, 0x00, 0x0E, 0x10, 0x00, 0x13, 0x57, 0x45, 0x53, 0x54, 0x00, 0x57, 0x45, 0x54, 0x00, 0x57, 0x45, 0x4D, 0x54, 0x00, 0x43, 0x45, 0x53, 0x54, 0x00, 0x43, 0x45, 0x54, 0x00, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x01, 0x01, 0x00, 0xC6, 0xF9, 0x80, 0x01, 0x0F, 0x1F, 0x8D, 0x00, 0x00, 0x00, 0x08, 0x6D, 0x61, +0x01, 0x01, 0x00, 0xC6, 0xF9, 0x80, 0x01, 0x0D, 0x09, 0xB2, 0x00, 0x00, 0x00, 0x08, 0x6D, 0x61, 0x69, 0x6E, 0x6C, 0x61, 0x6E, 0x64, /* Europe/Malta */ @@ -15758,12 +15723,13 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { /* Hongkong */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x85, 0x69, 0x5A, 0xFC, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x47, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x11, 0x85, 0x69, 0x5A, 0xFC, +0xC9, 0xEA, 0x57, 0xB8, 0xCA, 0xDA, 0x3A, 0xA8, 0xCB, 0x4B, 0x78, 0x80, 0xD2, 0x4C, 0x62, 0x70, 0xD3, 0x6A, 0xB7, 0x38, 0xD4, 0x93, 0x4A, 0xA8, 0xD5, 0x42, 0xB0, 0x38, 0xD6, 0x9A, 0xB9, 0xA8, 0xD7, 0x3E, 0x41, 0xB8, 0xD8, 0x2E, 0x24, 0xA8, 0xD8, 0xF9, 0x39, 0xB8, 0xDA, 0x0E, 0x06, 0xA8, 0xDA, 0xD9, 0x1B, 0xB8, 0xDB, 0xED, 0xE8, 0xA8, 0xDC, 0xB8, 0xFD, 0xB8, 0xDD, 0xCD, 0xCA, 0xA8, -0xDE, 0xA2, 0x1A, 0x38, 0xDF, 0xAD, 0xAC, 0xA8, 0xE0, 0x81, 0xFC, 0x38, 0xE1, 0x96, 0xC9, 0x28, +0xDE, 0xA2, 0x1A, 0x38, 0xDF, 0xAC, 0x5B, 0x28, 0xE0, 0x81, 0xFC, 0x38, 0xE1, 0x96, 0xC9, 0x28, 0xE2, 0x4F, 0x69, 0x38, 0xE3, 0x76, 0xAB, 0x28, 0xE4, 0x2F, 0x4B, 0x38, 0xE5, 0x5F, 0xC7, 0xA8, 0xE6, 0x0F, 0x2D, 0x38, 0xE7, 0x3F, 0xA9, 0xA8, 0xE7, 0xF8, 0x49, 0xB8, 0xE9, 0x1F, 0x8B, 0xA8, 0xE9, 0xD8, 0x2B, 0xB8, 0xEA, 0xFF, 0x6D, 0xA8, 0xEB, 0xB8, 0x0D, 0xB8, 0xEC, 0xDF, 0x4F, 0xA8, @@ -15774,17 +15740,17 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFC, 0xCE, 0x5E, 0xB8, 0xFD, 0xBE, 0x41, 0xA8, 0xFE, 0xAE, 0x40, 0xB8, 0xFF, 0x9E, 0x23, 0xA8, 0x00, 0x8E, 0x22, 0xB8, 0x01, 0x7E, 0x05, 0xA8, 0x02, 0x6E, 0x04, 0xB8, 0x03, 0x5D, 0xE7, 0xA8, 0x04, 0x4D, 0xE6, 0xB8, 0x05, 0x47, 0x04, 0x28, 0x06, 0x37, 0x03, 0x38, 0x07, 0x26, 0xE6, 0x28, -0x08, 0x16, 0xE5, 0x38, 0x09, 0x06, 0xC8, 0x28, 0x09, 0xF6, 0xC7, 0x38, 0x0A, 0xE6, 0xAA, 0x28, +0x07, 0x83, 0x3D, 0x38, 0x09, 0x06, 0xC8, 0x28, 0x09, 0xF6, 0xC7, 0x38, 0x0A, 0xE6, 0xAA, 0x28, 0x0B, 0xD6, 0xA9, 0x38, 0x0C, 0xC6, 0x8C, 0x28, 0x0D, 0xB6, 0x8B, 0x38, 0x0E, 0xA6, 0x6E, 0x28, -0x11, 0x9B, 0x39, 0x38, 0x12, 0x6F, 0x6C, 0xA8, 0x13, 0x7B, 0x1B, 0x38, 0x14, 0x4F, 0x4E, 0xA8, +0x11, 0x9B, 0x39, 0x38, 0x12, 0x6F, 0x6C, 0xA8, 0x02, 0x01, 0x02, 0x03, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, -0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x6B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x90, 0x01, -0x04, 0x00, 0x00, 0x70, 0x80, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x48, 0x4B, 0x53, 0x54, 0x00, -0x48, 0x4B, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, -0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, +0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x00, +0x00, 0x6B, 0x04, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x90, 0x01, 0x04, 0x00, 0x00, 0x70, 0x80, 0x00, +0x09, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x48, 0x4B, 0x53, 0x54, 0x00, +0x48, 0x4B, 0x54, 0x00, 0x4A, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, /* HST */ 0x50, 0x48, 0x50, 0x31, 0x00, 0x3F, 0x3F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -15830,7 +15796,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xE2, 0x33, 0xC0, 0xC0, 0xE2, 0xAB, 0xB9, 0x40, 0x01, 0x02, 0x03, 0x00, 0x00, 0x2C, 0x8C, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x04, 0x00, 0x00, 0x38, 0x40, 0x01, 0x08, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x45, 0x41, 0x54, 0x00, 0x45, 0x41, 0x53, 0x54, 0x00, -0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6F, 0x43, 0x12, 0x01, 0x5B, 0x29, 0xB2, +0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x76, 0xED, 0x01, 0x5B, 0x29, 0xB2, 0x00, 0x00, 0x00, 0x00, /* Indian/Chagos */ @@ -15839,21 +15805,21 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x08, 0x89, 0x7E, 0xF7, 0x9C, 0x30, 0xE6, 0xDD, 0xB0, 0x01, 0x02, 0x00, 0x00, 0x43, 0xE4, 0x00, 0x00, 0x00, 0x00, 0x46, 0x50, 0x00, 0x04, 0x00, 0x00, 0x54, 0x60, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x49, 0x4F, 0x54, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7F, 0x28, 0x15, 0x01, 0x81, 0x28, 0x42, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x23, 0xAA, 0x01, 0x81, 0x28, 0x42, 0x00, 0x00, 0x00, 0x00, /* Indian/Christmas */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x58, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x62, 0x70, -0x00, 0x00, 0x43, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xB4, 0xC2, 0x01, 0xB3, 0xF8, 0x12, +0x00, 0x00, 0x43, 0x58, 0x54, 0x00, 0x00, 0x00, 0x00, 0x79, 0x6F, 0x3D, 0x01, 0xB3, 0xF8, 0x12, 0x00, 0x00, 0x00, 0x00, /* Indian/Cocos */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x43, 0x43, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x5B, 0x68, -0x00, 0x00, 0x43, 0x43, 0x54, 0x00, 0x00, 0x00, 0x00, 0x77, 0x45, 0xDA, 0x01, 0xA6, 0x8A, 0x92, +0x00, 0x00, 0x43, 0x43, 0x54, 0x00, 0x00, 0x00, 0x00, 0x76, 0xC3, 0xA5, 0x01, 0xA6, 0x8A, 0x92, 0x00, 0x00, 0x00, 0x00, /* Indian/Comoro */ @@ -15861,7 +15827,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF3, 0xD1, 0xF0, 0x01, 0x00, 0x00, 0x28, 0x90, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x45, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x79, 0x96, 0x4D, 0x01, 0x54, 0xAD, +0x00, 0x45, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x77, 0x80, 0x72, 0x01, 0x54, 0xAD, 0x8A, 0x00, 0x00, 0x00, 0x00, /* Indian/Kerguelen */ @@ -15869,7 +15835,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0xDA, 0x61, 0x62, 0x80, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x50, 0x00, 0x04, 0x7A, 0x7A, 0x7A, -0x00, 0x54, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F, 0x19, 0x6D, 0x01, 0x7D, 0xCD, +0x00, 0x54, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3E, 0x05, 0xD2, 0x01, 0x7D, 0xCD, 0x36, 0x00, 0x00, 0x00, 0x00, /* Indian/Mahe */ @@ -15877,7 +15843,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x88, 0x64, 0xE6, 0x84, 0x01, 0x00, 0x00, 0x33, 0xFC, 0x00, 0x00, 0x00, 0x00, 0x38, 0x40, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x53, 0x43, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x84, 0x3E, 0x2A, 0x01, 0x67, 0x4B, +0x00, 0x53, 0x43, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x82, 0x35, 0x55, 0x01, 0x67, 0x4B, 0x2A, 0x00, 0x00, 0x00, 0x00, /* Indian/Maldives */ @@ -15890,39 +15856,20 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { /* Indian/Mauritius */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4D, 0x55, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x3E, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x0D, 0x89, 0x7F, 0x05, 0x98, -0x18, 0x05, 0xED, 0x40, 0x18, 0xDB, 0x72, 0x30, 0x49, 0x03, 0x96, 0xE0, 0x49, 0xCE, 0x9D, 0xE0, -0x4A, 0xE3, 0x78, 0xE0, 0x4B, 0xAE, 0x7F, 0xE0, 0x4C, 0xCC, 0x95, 0x60, 0x4D, 0x8E, 0x61, 0xE0, -0x4E, 0xAC, 0x77, 0x60, 0x4F, 0x6E, 0x43, 0xE0, 0x50, 0x8C, 0x59, 0x60, 0x51, 0x57, 0x60, 0x60, -0x52, 0x6C, 0x3B, 0x60, 0x53, 0x37, 0x42, 0x60, 0x54, 0x4C, 0x1D, 0x60, 0x55, 0x17, 0x24, 0x60, -0x56, 0x2B, 0xFF, 0x60, 0x56, 0xF7, 0x06, 0x60, 0x58, 0x15, 0x1B, 0xE0, 0x58, 0xD6, 0xE8, 0x60, -0x59, 0xF4, 0xFD, 0xE0, 0x5A, 0xB6, 0xCA, 0x60, 0x5B, 0xD4, 0xDF, 0xE0, 0x5C, 0x9F, 0xE6, 0xE0, -0x5D, 0xB4, 0xC1, 0xE0, 0x5E, 0x7F, 0xC8, 0xE0, 0x5F, 0x94, 0xA3, 0xE0, 0x60, 0x5F, 0xAA, 0xE0, -0x61, 0x7D, 0xC0, 0x60, 0x62, 0x3F, 0x8C, 0xE0, 0x63, 0x5D, 0xA2, 0x60, 0x64, 0x1F, 0x6E, 0xE0, -0x65, 0x3D, 0x84, 0x60, 0x66, 0x08, 0x8B, 0x60, 0x67, 0x1D, 0x66, 0x60, 0x67, 0xE8, 0x6D, 0x60, -0x68, 0xFD, 0x48, 0x60, 0x69, 0xC8, 0x4F, 0x60, 0x6A, 0xDD, 0x2A, 0x60, 0x6B, 0xA8, 0x31, 0x60, -0x6C, 0xC6, 0x46, 0xE0, 0x6D, 0x88, 0x13, 0x60, 0x6E, 0xA6, 0x28, 0xE0, 0x6F, 0x67, 0xF5, 0x60, -0x70, 0x86, 0x0A, 0xE0, 0x71, 0x51, 0x11, 0xE0, 0x72, 0x65, 0xEC, 0xE0, 0x73, 0x30, 0xF3, 0xE0, -0x74, 0x45, 0xCE, 0xE0, 0x75, 0x10, 0xD5, 0xE0, 0x76, 0x2E, 0xEB, 0x60, 0x76, 0xF0, 0xB7, 0xE0, -0x78, 0x0E, 0xCD, 0x60, 0x78, 0xD0, 0x99, 0xE0, 0x79, 0xEE, 0xAF, 0x60, 0x7A, 0xB0, 0x7B, 0xE0, -0x7B, 0xCE, 0x91, 0x60, 0x7C, 0x99, 0x98, 0x60, 0x7D, 0xAE, 0x73, 0x60, 0x7E, 0x79, 0x7A, 0x60, -0x7F, 0x8E, 0x55, 0x60, 0x02, 0x01, 0x02, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, -0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, -0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, -0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, 0x04, 0x03, -0x04, 0x03, 0x00, 0x00, 0x35, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x46, 0x50, 0x01, 0x04, 0x00, 0x00, -0x38, 0x40, 0x00, 0x09, 0x00, 0x00, 0x46, 0x50, 0x01, 0x04, 0x00, 0x00, 0x38, 0x40, 0x00, 0x09, -0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x55, 0x53, 0x54, 0x00, 0x4D, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, -0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6B, 0x10, 0xDA, 0x01, 0x6A, 0x65, 0x70, 0x00, -0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x89, 0x7F, 0x05, 0x98, +0x18, 0x05, 0xED, 0x40, 0x18, 0xDB, 0x72, 0x30, 0x49, 0x03, 0x96, 0xE0, 0x49, 0xCE, 0x8F, 0xD0, +0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x35, 0xE8, 0x00, 0x00, 0x00, 0x00, 0x46, 0x50, 0x01, +0x04, 0x00, 0x00, 0x38, 0x40, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x4D, 0x55, 0x53, 0x54, 0x00, +0x4D, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6A, 0x8E, 0xA5, 0x01, 0x6A, +0x65, 0x70, 0x00, 0x00, 0x00, 0x00, /* Indian/Mayotte */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x59, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xF3, 0xD0, 0x18, 0x01, 0x00, 0x00, 0x2A, 0x68, 0x00, 0x00, 0x00, 0x00, 0x2A, 0x30, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x45, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x78, 0x36, 0xBD, 0x01, 0x57, 0xAD, +0x00, 0x45, 0x41, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x75, 0xD2, 0xC2, 0x01, 0x57, 0xAD, 0xC5, 0x00, 0x00, 0x00, 0x00, /* Indian/Reunion */ @@ -15930,7 +15877,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x91, 0xCC, 0x39, 0x80, 0x01, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x00, 0x00, 0x38, 0x40, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x52, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6C, 0x22, 0x4A, 0x01, 0x67, 0x4B, +0x00, 0x52, 0x45, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x7D, 0x35, 0x01, 0x67, 0x4B, 0x2A, 0x00, 0x00, 0x00, 0x00, /* Iran */ @@ -16497,12 +16444,13 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { /* Pacific/Apia */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x57, 0x53, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0x91, 0x05, 0xFC, 0x00, -0xDA, 0x62, 0x04, 0x38, 0x01, 0x02, 0xFF, 0xFF, 0x5F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x5E, 0x48, -0x00, 0x04, 0xFF, 0xFF, 0x65, 0x50, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x53, 0x41, 0x4D, 0x54, -0x00, 0x57, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x76, 0xC3, 0xA5, 0x00, -0x0E, 0xDA, 0x15, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x12, 0x91, 0x05, 0xFC, 0x00, +0xDA, 0x62, 0x04, 0x38, 0x4A, 0xC8, 0x80, 0x30, 0x4B, 0xAF, 0x28, 0xA0, 0x01, 0x02, 0x03, 0x02, +0xFF, 0xFF, 0x5F, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x5E, 0x48, 0x00, 0x04, 0xFF, 0xFF, 0x65, 0x50, +0x00, 0x09, 0xFF, 0xFF, 0x73, 0x60, 0x01, 0x0D, 0x4C, 0x4D, 0x54, 0x00, 0x53, 0x41, 0x4D, 0x54, +0x00, 0x57, 0x53, 0x54, 0x00, 0x57, 0x53, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x74, 0x38, 0x9A, 0x00, 0x0C, 0x9D, 0x2A, 0x00, 0x00, 0x00, 0x00, /* Pacific/Auckland */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4E, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -16560,7 +16508,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0xA8, 0xC0, 0x01, 0x00, 0x00, 0x00, 0xB6, 0xD0, 0x01, 0x0A, 0x00, 0x00, 0xA8, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xC0, 0x00, 0x00, 0x4E, 0x5A, 0x53, 0x54, 0x00, 0x4E, 0x5A, 0x4D, 0x54, 0x00, 0x4E, 0x5A, 0x44, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x53, 0xB8, 0x4A, 0x02, 0x1D, 0x54, 0xBA, 0x00, 0x00, 0x00, 0x0E, 0x6D, 0x6F, +0x00, 0x00, 0x00, 0x51, 0x13, 0x35, 0x02, 0x1D, 0x54, 0xBA, 0x00, 0x00, 0x00, 0x0E, 0x6D, 0x6F, 0x73, 0x74, 0x20, 0x6C, 0x6F, 0x63, 0x61, 0x74, 0x69, 0x6F, 0x6E, 0x73, /* Pacific/Chatham */ @@ -16609,8 +16557,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x00, 0x00, 0xAB, 0xFC, 0x00, 0x00, 0x00, 0x00, 0xC1, 0x5C, 0x01, 0x04, 0x00, 0x00, 0xB3, 0x4C, 0x00, 0x0A, 0x00, 0x00, 0xB3, 0x4C, 0x00, 0x0A, 0x4C, 0x4D, 0x54, 0x00, 0x43, 0x48, 0x41, 0x44, 0x54, 0x00, 0x43, 0x48, -0x41, 0x53, 0x54, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x49, 0x2A, 0x78, -0x00, 0x06, 0xF1, 0x58, 0x00, 0x00, 0x00, 0x0F, 0x43, 0x68, 0x61, 0x74, 0x68, 0x61, 0x6D, 0x20, +0x41, 0x53, 0x54, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x44, 0x48, +0x00, 0x05, 0x43, 0xA7, 0x00, 0x00, 0x00, 0x0F, 0x43, 0x68, 0x61, 0x74, 0x68, 0x61, 0x6D, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, /* Pacific/Easter */ @@ -16665,7 +16613,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x90, 0x00, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x09, 0xFF, 0xFF, 0xAB, 0xA0, 0x01, 0x09, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x04, 0xFF, 0xFF, 0xB9, 0xB0, 0x01, 0x09, 0x45, 0x4D, 0x54, 0x00, 0x45, 0x41, 0x53, 0x54, 0x00, 0x45, 0x41, 0x53, 0x53, 0x54, 0x00, 0x00, 0x01, 0x01, 0x00, 0x01, 0x01, -0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x60, 0x5B, 0xF8, 0x00, 0x6C, 0xFF, 0xA5, 0x00, 0x00, +0x00, 0x01, 0x01, 0x00, 0x01, 0x01, 0x00, 0x5F, 0xE6, 0xC8, 0x00, 0x6B, 0xAD, 0x1A, 0x00, 0x00, 0x00, 0x1C, 0x45, 0x61, 0x73, 0x74, 0x65, 0x72, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x20, 0x26, 0x20, 0x53, 0x61, 0x6C, 0x61, 0x20, 0x79, 0x20, 0x47, 0x6F, 0x6D, 0x65, 0x7A, @@ -16681,7 +16629,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0x9D, 0xCC, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xC0, 0x01, 0x04, 0x00, 0x00, 0x9A, 0xB0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x56, 0x55, 0x53, 0x54, 0x00, -0x56, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x68, 0x0A, 0x02, 0x13, +0x56, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x5F, 0x35, 0x02, 0x13, 0xA4, 0x42, 0x00, 0x00, 0x00, 0x00, /* Pacific/Enderbury */ @@ -16690,14 +16638,14 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x12, 0x56, 0x04, 0xC0, 0x2F, 0x06, 0x8B, 0x30, 0x01, 0x02, 0xFF, 0xFF, 0x57, 0x40, 0x00, 0x00, 0xFF, 0xFF, 0x65, 0x50, 0x00, 0x00, 0x00, 0x00, 0xB6, 0xD0, 0x00, 0x00, 0x50, 0x48, 0x4F, 0x54, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x84, 0xF4, 0x75, 0x00, 0x0D, 0xDC, 0x2D, 0x00, 0x00, 0x00, 0x0F, 0x50, +0x00, 0x00, 0x00, 0x00, 0x84, 0x8C, 0x4A, 0x00, 0x0D, 0x9B, 0x12, 0x00, 0x00, 0x00, 0x0F, 0x50, 0x68, 0x6F, 0x65, 0x6E, 0x69, 0x78, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, /* Pacific/Fakaofo */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x54, 0x4B, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0x73, 0x60, -0x00, 0x00, 0x54, 0x4B, 0x54, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x27, 0xDA, 0x00, 0x0E, 0x16, 0xC5, +0x00, 0x00, 0x54, 0x4B, 0x54, 0x00, 0x00, 0x00, 0x00, 0x7B, 0x09, 0x65, 0x00, 0x0D, 0x60, 0x7A, 0x00, 0x00, 0x00, 0x00, /* Pacific/Fiji */ @@ -16707,14 +16655,14 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x36, 0x3B, 0x17, 0xE0, 0x36, 0xD7, 0xFA, 0x60, 0x38, 0x24, 0x34, 0x60, 0x38, 0xB7, 0xDC, 0x60, 0x02, 0x01, 0x02, 0x01, 0x02, 0x00, 0x00, 0xA7, 0x44, 0x00, 0x00, 0x00, 0x00, 0xB6, 0xD0, 0x01, 0x04, 0x00, 0x00, 0xA8, 0xC0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x46, 0x4A, 0x53, 0x54, 0x00, -0x46, 0x4A, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x11, 0x15, 0x02, 0x22, +0x46, 0x4A, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6D, 0xA8, 0xEA, 0x02, 0x22, 0xE6, 0x82, 0x00, 0x00, 0x00, 0x00, /* Pacific/Funafuti */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x54, 0x56, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xA8, 0xC0, -0x00, 0x00, 0x54, 0x56, 0x54, 0x00, 0x00, 0x00, 0x00, 0x7D, 0xE9, 0x12, 0x02, 0x24, 0x1F, 0x02, +0x00, 0x00, 0x54, 0x56, 0x54, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x55, 0x6D, 0x02, 0x24, 0x1F, 0x02, 0x00, 0x00, 0x00, 0x00, /* Pacific/Galapagos */ @@ -16723,8 +16671,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x0D, 0xB6, 0xA4, 0x4C, 0x80, 0x1E, 0x18, 0xC4, 0x50, 0x01, 0x02, 0xFF, 0xFF, 0xAC, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xB9, 0xB0, 0x00, 0x04, 0xFF, 0xFF, 0xAB, 0xA0, 0x00, 0x08, 0x4C, 0x4D, 0x54, 0x00, 0x45, 0x43, 0x54, 0x00, -0x47, 0x41, 0x4C, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0xB3, 0xD0, 0x00, -0x8B, 0xC5, 0x40, 0x00, 0x00, 0x00, 0x11, 0x47, 0x61, 0x6C, 0x61, 0x70, 0x61, 0x67, 0x6F, 0x73, +0x47, 0x41, 0x4C, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x87, 0xF4, 0xB0, 0x00, +0x89, 0xF0, 0x80, 0x00, 0x00, 0x00, 0x11, 0x47, 0x61, 0x6C, 0x61, 0x70, 0x61, 0x67, 0x6F, 0x73, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, /* Pacific/Gambier */ @@ -16732,8 +16680,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x94, 0x50, 0x48, 0x04, 0x01, 0xFF, 0xFF, 0x81, 0x7C, 0x00, 0x00, 0xFF, 0xFF, 0x81, 0x70, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x47, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x6F, 0xF5, 0x00, 0x47, -0xA3, 0xD7, 0x00, 0x00, 0x00, 0x0F, 0x47, 0x61, 0x6D, 0x62, 0x69, 0x65, 0x72, 0x20, 0x49, 0x73, +0x00, 0x47, 0x41, 0x4D, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x66, 0x07, 0xCA, 0x00, 0x44, +0xBD, 0xA8, 0x00, 0x00, 0x00, 0x0F, 0x47, 0x61, 0x6D, 0x62, 0x69, 0x65, 0x72, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, /* Pacific/Guadalcanal */ @@ -16741,7 +16689,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x94, 0x4F, 0x33, 0x8C, 0x01, 0x00, 0x00, 0x95, 0xF4, 0x00, 0x00, 0x00, 0x00, 0x9A, 0xB0, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x53, 0x42, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x68, 0xF5, 0x02, 0x07, 0x1A, +0x00, 0x53, 0x42, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xC8, 0x4A, 0x02, 0x07, 0x1A, 0xA0, 0x00, 0x00, 0x00, 0x00, /* Pacific/Guam */ @@ -16761,14 +16709,14 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0x7A, 0x68, 0x01, 0x04, 0xFF, 0xFF, 0x7A, 0x68, 0x01, 0x08, 0xFF, 0xFF, 0x7A, 0x68, 0x01, 0x0C, 0xFF, 0xFF, 0x73, 0x60, 0x00, 0x00, 0x48, 0x53, 0x54, 0x00, 0x48, 0x44, 0x54, 0x00, 0x48, 0x57, 0x54, 0x00, 0x48, 0x50, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, -0x01, 0x00, 0x00, 0xA9, 0xD7, 0x46, 0x00, 0x24, 0x67, 0xA9, 0x00, 0x00, 0x00, 0x06, 0x48, 0x61, +0x01, 0x00, 0x00, 0xA9, 0xD7, 0x46, 0x00, 0x21, 0xC9, 0x16, 0x00, 0x00, 0x00, 0x06, 0x48, 0x61, 0x77, 0x61, 0x69, 0x69, /* Pacific/Johnston */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x55, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0xFF, 0xFF, 0x73, 0x60, -0x00, 0x00, 0x48, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xE3, 0x38, 0x00, 0x11, 0x92, 0xB2, +0x00, 0x00, 0x48, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0xA2, 0xE3, 0x38, 0x00, 0x0F, 0xFF, 0x0D, 0x00, 0x00, 0x00, 0x0E, 0x4A, 0x6F, 0x68, 0x6E, 0x73, 0x74, 0x6F, 0x6E, 0x20, 0x41, 0x74, 0x6F, 0x6C, 0x6C, @@ -16778,7 +16726,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x05, 0x12, 0x55, 0xF2, 0x00, 0x2F, 0x06, 0x7D, 0x20, 0x01, 0x02, 0xFF, 0xFF, 0x6A, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x73, 0x60, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xE0, 0x00, 0x00, 0x4C, 0x49, 0x4E, 0x54, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x00, 0x8C, 0x2D, 0x6A, 0x00, 0x23, 0x9A, 0x95, 0x00, 0x00, 0x00, 0x0C, 0x4C, +0x00, 0x00, 0x00, 0x00, 0x8C, 0x2D, 0x6A, 0x00, 0x22, 0x96, 0x2A, 0x00, 0x00, 0x00, 0x0C, 0x4C, 0x69, 0x6E, 0x65, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, /* Pacific/Kosrae */ @@ -16811,8 +16759,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x94, 0x50, 0x4C, 0x48, 0x01, 0xFF, 0xFF, 0x7D, 0x38, 0x00, 0x00, 0xFF, 0xFF, 0x7A, 0x68, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x4D, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7B, 0x98, 0xA0, 0x00, 0x3F, -0x52, 0xF0, 0x00, 0x00, 0x00, 0x11, 0x4D, 0x61, 0x72, 0x71, 0x75, 0x65, 0x73, 0x61, 0x73, 0x20, +0x00, 0x4D, 0x41, 0x52, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7B, 0x98, 0xA0, 0x00, 0x3D, +0xCC, 0x50, 0x00, 0x00, 0x00, 0x11, 0x4D, 0x61, 0x72, 0x71, 0x75, 0x65, 0x73, 0x61, 0x73, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, /* Pacific/Midway */ @@ -16823,7 +16771,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0x65, 0x50, 0x00, 0x00, 0xFF, 0xFF, 0x73, 0x60, 0x01, 0x04, 0xFF, 0xFF, 0x65, 0x50, 0x00, 0x08, 0xFF, 0xFF, 0x65, 0x50, 0x00, 0x0C, 0x4E, 0x53, 0x54, 0x00, 0x4E, 0x44, 0x54, 0x00, 0x42, 0x53, 0x54, 0x00, 0x53, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0xB4, 0x62, 0x62, 0x00, 0x05, 0x23, 0x1A, 0x00, 0x00, 0x00, 0x0E, 0x4D, 0x69, 0x64, 0x77, +0x00, 0xB4, 0x62, 0x62, 0x00, 0x04, 0x04, 0xA5, 0x00, 0x00, 0x00, 0x0E, 0x4D, 0x69, 0x64, 0x77, 0x61, 0x79, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, /* Pacific/Nauru */ @@ -16833,7 +16781,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xCB, 0xB4, 0xBF, 0x48, 0xD0, 0x42, 0x50, 0x70, 0x11, 0x8B, 0x04, 0xC8, 0x01, 0x02, 0x01, 0x03, 0x00, 0x00, 0x9C, 0x7C, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xB8, 0x00, 0x04, 0x00, 0x00, 0x7E, 0x90, 0x00, 0x08, 0x00, 0x00, 0xA8, 0xC0, 0x00, 0x04, 0x4C, 0x4D, 0x54, 0x00, 0x4E, 0x52, 0x54, 0x00, -0x4A, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x8A, 0x1E, 0x12, +0x4A, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x88, 0x8A, 0x6D, 0x02, 0x11, 0x5A, 0x52, 0x00, 0x00, 0x00, 0x00, /* Pacific/Niue */ @@ -16842,14 +16790,14 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x04, 0xDC, 0x43, 0x35, 0x60, 0x10, 0x74, 0xCA, 0x38, 0x01, 0x02, 0xFF, 0xFF, 0x60, 0xA0, 0x00, 0x00, 0xFF, 0xFF, 0x5E, 0x48, 0x00, 0x00, 0xFF, 0xFF, 0x65, 0x50, 0x00, 0x00, 0x4E, 0x55, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x00, 0x00, 0x6C, 0x5C, 0xE2, 0x00, 0x12, 0x2E, 0xF2, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x6C, 0x4F, 0xDD, 0x00, 0x0F, 0x62, 0xCD, 0x00, 0x00, 0x00, 0x00, /* Pacific/Norfolk */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4E, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0xDC, 0x41, 0xF8, 0x80, 0x01, 0x00, 0x00, 0x9D, 0x80, 0x00, 0x00, 0x00, 0x00, 0xA1, 0xB8, 0x00, 0x04, 0x4E, 0x4D, 0x54, -0x00, 0x4E, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x27, 0xA8, 0x02, 0x12, 0xF4, +0x00, 0x4E, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5D, 0x00, 0x98, 0x02, 0x12, 0xF4, 0x7A, 0x00, 0x00, 0x00, 0x00, /* Pacific/Noumea */ @@ -16861,7 +16809,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x9C, 0x0C, 0x00, 0x00, 0x00, 0x00, 0xA8, 0xC0, 0x01, 0x04, 0x00, 0x00, 0x9A, 0xB0, 0x00, 0x09, 0x00, 0x00, 0xA8, 0xC0, 0x01, 0x04, 0x00, 0x00, 0x9A, 0xB0, 0x00, 0x09, 0x4C, 0x4D, 0x54, 0x00, 0x4E, 0x43, 0x53, 0x54, 0x00, 0x4E, 0x43, 0x54, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, -0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x2A, 0xAA, 0x02, 0x10, 0xA4, 0x08, 0x00, 0x00, 0x00, 0x00, +0x00, 0x00, 0x00, 0x00, 0x00, 0x67, 0x5A, 0x55, 0x02, 0x10, 0xA4, 0x08, 0x00, 0x00, 0x00, 0x00, /* Pacific/Pago_Pago */ @@ -16872,8 +16820,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0xFF, 0xFF, 0x5F, 0xF8, 0x00, 0x00, 0xFF, 0xFF, 0x5E, 0x48, 0x00, 0x04, 0xFF, 0xFF, 0x65, 0x50, 0x00, 0x09, 0xFF, 0xFF, 0x65, 0x50, 0x00, 0x0D, 0xFF, 0xFF, 0x65, 0x50, 0x00, 0x11, 0x4C, 0x4D, 0x54, 0x00, 0x53, 0x41, 0x4D, 0x54, 0x00, 0x4E, 0x53, 0x54, 0x00, 0x42, 0x53, 0x54, 0x00, 0x53, -0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x74, 0x5F, -0xAA, 0x00, 0x10, 0x53, 0xAF, 0x00, 0x00, 0x00, 0x00, +0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x73, 0x8F, +0x55, 0x00, 0x0E, 0x30, 0xD0, 0x00, 0x00, 0x00, 0x00, /* Pacific/Palau */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x50, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -16887,8 +16835,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x35, 0x44, 0x42, 0x08, 0x01, 0xFF, 0xFF, 0x88, 0x78, 0x00, 0x00, 0xFF, 0xFF, 0x8F, 0x80, 0x00, 0x04, 0x50, 0x4E, 0x54, -0x00, 0x50, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x48, 0xAA, 0x00, 0x4C, 0x6B, -0xCD, 0x00, 0x00, 0x00, 0x00, +0x00, 0x50, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x63, 0x14, 0x95, 0x00, 0x4C, 0x2A, +0xB2, 0x00, 0x00, 0x00, 0x00, /* Pacific/Ponape */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x46, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -16902,7 +16850,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x50, 0x48, 0x50, 0x31, 0x01, 0x50, 0x47, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x8C, 0xA0, -0x00, 0x00, 0x50, 0x47, 0x54, 0x00, 0x00, 0x00, 0x00, 0x7C, 0x5B, 0xF0, 0x01, 0xF3, 0x37, 0x7A, +0x00, 0x00, 0x50, 0x47, 0x54, 0x00, 0x00, 0x00, 0x00, 0x7A, 0xD5, 0x50, 0x01, 0xF3, 0x37, 0x7A, 0x00, 0x00, 0x00, 0x00, /* Pacific/Rarotonga */ @@ -16919,7 +16867,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0x02, 0x01, 0xFF, 0xFF, 0x6C, 0x58, 0x00, 0x00, 0xFF, 0xFF, 0x73, 0x60, 0x00, 0x00, 0xFF, 0xFF, 0x7A, 0x68, 0x01, 0x04, 0x43, 0x4B, 0x54, 0x00, 0x43, 0x4B, 0x48, 0x53, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x69, 0xA4, 0x45, 0x00, 0x21, 0x36, 0x9A, 0x00, 0x00, 0x00, 0x00, +0x00, 0x68, 0xED, 0xFA, 0x00, 0x1E, 0xDF, 0xA5, 0x00, 0x00, 0x00, 0x00, /* Pacific/Saipan */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x4D, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -16946,8 +16894,8 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x09, 0x94, 0x50, 0x55, 0xB8, 0x01, 0xFF, 0xFF, 0x73, 0xC8, 0x00, 0x00, 0xFF, 0xFF, 0x73, 0x60, 0x00, 0x04, 0x4C, 0x4D, 0x54, -0x00, 0x54, 0x41, 0x48, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x70, 0x33, 0xF5, 0x00, 0x30, -0x2A, 0xBA, 0x00, 0x00, 0x00, 0x0F, 0x53, 0x6F, 0x63, 0x69, 0x65, 0x74, 0x79, 0x20, 0x49, 0x73, +0x00, 0x54, 0x41, 0x48, 0x54, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6E, 0x93, 0x4A, 0x00, 0x2E, +0x70, 0x05, 0x00, 0x00, 0x00, 0x0F, 0x53, 0x6F, 0x63, 0x69, 0x65, 0x74, 0x79, 0x20, 0x49, 0x73, 0x6C, 0x61, 0x6E, 0x64, 0x73, /* Pacific/Tarawa */ @@ -16967,7 +16915,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0xAD, 0x70, 0x00, 0x00, 0x00, 0x00, 0xB6, 0xD0, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xE0, 0x01, 0x04, 0x00, 0x00, 0xB6, 0xD0, 0x00, 0x00, 0x00, 0x00, 0xC4, 0xE0, 0x01, 0x04, 0x54, 0x4F, 0x54, 0x00, 0x54, 0x4F, 0x53, 0x54, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -0x00, 0x69, 0x8A, 0x3A, 0x00, 0x07, 0xE2, 0x3A, 0x00, 0x00, 0x00, 0x00, +0x00, 0x69, 0x08, 0x05, 0x00, 0x07, 0x60, 0x05, 0x00, 0x00, 0x00, 0x00, /* Pacific/Truk */ 0x50, 0x48, 0x50, 0x31, 0x01, 0x46, 0x4D, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, @@ -16989,7 +16937,7 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x50, 0x48, 0x50, 0x31, 0x01, 0x57, 0x46, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0xA8, 0xC0, -0x00, 0x00, 0x57, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00, 0x75, 0xF3, 0x50, 0x00, 0x06, 0x5B, 0x9A, +0x00, 0x00, 0x57, 0x46, 0x54, 0x00, 0x00, 0x00, 0x00, 0x75, 0x08, 0xF0, 0x00, 0x05, 0xD9, 0x65, 0x00, 0x00, 0x00, 0x00, /* Pacific/Yap */ @@ -18113,4 +18061,4 @@ const unsigned char timelib_timezone_db_data_builtin[257923] = { 0x00, 0x00, 0x55, 0x54, 0x43, 0x00, 0x00, 0x00, 0x00, 0x89, 0x54, 0x40, 0x01, 0x12, 0xA8, 0x80, 0x00, 0x00, 0x00, 0x00, }; -const timelib_tzdb timezonedb_builtin = { "2009.10", 560, timezonedb_idx_builtin, timelib_timezone_db_data_builtin }; +const timelib_tzdb timezonedb_builtin = { "2009.18", 561, timezonedb_idx_builtin, timelib_timezone_db_data_builtin }; diff --git a/ext/date/lib/tm2unixtime.c b/ext/date/lib/tm2unixtime.c index 77ca091df..b013882b4 100644 --- a/ext/date/lib/tm2unixtime.c +++ b/ext/date/lib/tm2unixtime.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tm2unixtime.c,v 1.13.2.3.2.2.2.13 2009/05/03 18:22:40 derick Exp $ */ +/* $Id: tm2unixtime.c 279799 2009-05-03 18:22:40Z derick $ */ #include "timelib.h" diff --git a/ext/date/lib/unixtime2tm.c b/ext/date/lib/unixtime2tm.c index 96bf3618f..465e8bf72 100644 --- a/ext/date/lib/unixtime2tm.c +++ b/ext/date/lib/unixtime2tm.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: unixtime2tm.c,v 1.12.2.4.2.3.2.3 2008/12/31 11:15:35 sebastian Exp $ */ +/* $Id: unixtime2tm.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "timelib.h" diff --git a/ext/date/php_date.c b/ext/date/php_date.c index 9204d8aaa..5b84dbdbb 100644 --- a/ext/date/php_date.c +++ b/ext/date/php_date.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_date.c,v 1.43.2.45.2.51.2.84 2009/06/25 15:07:36 johannes Exp $ */ +/* $Id: php_date.c 289981 2009-10-27 10:41:45Z pajoye $ */ #include "php.h" #include "php_streams.h" @@ -619,6 +619,7 @@ PHP_RINIT_FUNCTION(date) } DATEG(timezone) = NULL; DATEG(tzcache) = NULL; + DATEG(last_errors) = NULL; return SUCCESS; } @@ -636,6 +637,11 @@ PHP_RSHUTDOWN_FUNCTION(date) FREE_HASHTABLE(DATEG(tzcache)); DATEG(tzcache) = NULL; } + if (DATEG(last_errors)) { + timelib_error_container_dtor(DATEG(last_errors)); + DATEG(last_errors) = NULL; + } + return SUCCESS; } /* }}} */ @@ -777,7 +783,6 @@ PHP_MINIT_FUNCTION(date) php_date_global_timezone_db = NULL; php_date_global_timezone_db_enabled = 0; - DATEG(last_errors) = NULL; return SUCCESS; } @@ -849,7 +854,17 @@ static char* guess_timezone(const timelib_tzdb *tzdb TSRMLS_DC) return env; } /* Check config setting for default timezone */ - if (DATEG(default_timezone) && (strlen(DATEG(default_timezone)) > 0) && timelib_timezone_id_is_valid(DATEG(default_timezone), tzdb)) { + if (!DATEG(default_timezone)) { + /* Special case: ext/date wasn't initialized yet */ + zval ztz; + + if (SUCCESS == zend_get_configuration_directive("date.timezone", sizeof("date.timezone"), &ztz) && + Z_TYPE(ztz) == IS_STRING && + Z_STRLEN(ztz) > 0 && + timelib_timezone_id_is_valid(Z_STRVAL(ztz), tzdb)) { + return Z_STRVAL(ztz); + } + } else if (*DATEG(default_timezone) && timelib_timezone_id_is_valid(DATEG(default_timezone), tzdb)) { return DATEG(default_timezone); } #if HAVE_TM_ZONE @@ -2414,7 +2429,7 @@ static int date_initialize(php_date_obj *dateobj, /*const*/ char *time_str, int } timelib_unixtime2local(now, (timelib_sll) time(NULL)); - timelib_fill_holes(dateobj->time, now, 0); + timelib_fill_holes(dateobj->time, now, TIMELIB_NO_CLONE); timelib_update_ts(dateobj->time, tzi); dateobj->time->have_relative = 0; @@ -3270,7 +3285,7 @@ PHP_FUNCTION(timezone_transitions_get) { zval *object, *element; php_timezone_obj *tzobj; - int i, begin = 0, found; + unsigned int i, begin = 0, found; long timestamp_begin = LONG_MIN, timestamp_end = LONG_MAX; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O|ll", &object, date_ce_timezone, ×tamp_begin, ×tamp_end) == FAILURE) { @@ -3927,7 +3942,7 @@ static void php_do_date_sunrise_sunset(INTERNAL_FUNCTION_PARAMETERS, int calc_su } timelib_unixtime2local(t, time); - rs = timelib_astro_rise_set_altitude(t, longitude, latitude, altitude, altitude > -1 ? 1 : 0, &h_rise, &h_set, &rise, &set, &transit); + rs = timelib_astro_rise_set_altitude(t, longitude, latitude, altitude, 1, &h_rise, &h_set, &rise, &set, &transit); timelib_time_dtor(t); if (rs != 0) { diff --git a/ext/date/php_date.h b/ext/date/php_date.h index e55e68a94..37b0af936 100644 --- a/ext/date/php_date.h +++ b/ext/date/php_date.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_date.h,v 1.17.2.11.2.3.2.13 2009/05/31 21:28:38 stas Exp $ */ +/* $Id: php_date.h 281478 2009-05-31 21:28:38Z stas $ */ #ifndef PHP_DATE_H #define PHP_DATE_H diff --git a/ext/date/tests/DatePeriod_wrong_constructor.phpt b/ext/date/tests/DatePeriod_wrong_constructor.phpt new file mode 100644 index 000000000..62e6aa98a --- /dev/null +++ b/ext/date/tests/DatePeriod_wrong_constructor.phpt @@ -0,0 +1,17 @@ +--TEST-- +DatePeriod: Test wrong __construct parameter +--CREDITS-- +Havard Eide +#PHPTestFest2009 Norway 2009-06-09 \o/ +--INI-- +date.timezone=UTC +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught exception 'Exception' with message 'DatePeriod::__construct(): This constructor accepts either (DateTime, DateInterval, int) OR (DateTime, DateInterval, DateTime) OR (string) as arguments.' in %s:%d +Stack trace: +#0 %s(%d): DatePeriod->__construct() +#1 {main} + thrown in %s on line %d \ No newline at end of file diff --git a/ext/date/tests/bug27719.phpt b/ext/date/tests/bug27719.phpt index b86c32422..e18c9267b 100644 --- a/ext/date/tests/bug27719.phpt +++ b/ext/date/tests/bug27719.phpt @@ -4,7 +4,7 @@ Bug #27719 (mktime returns incorrect timestamp for dst days) date.timezone=EST error_reporting=2047 --FILE-- -format($format), "\n"; + +$d = date_create_from_format($format, "03-15-2005 12:22:29.001001 PST"); +echo $d->format($format), "\n"; + +$d = date_create_from_format($format, "03-15-2005 12:22:29.0010 PST"); +var_dump( $d ); +?> +--EXPECT-- +03-15-2005 12:22:29.000000 PST +03-15-2005 12:22:29.001000 PST +bool(false) diff --git a/ext/date/tests/bug48058.phpt b/ext/date/tests/bug48058.phpt index 290d3df0f..46a1918b4 100644 --- a/ext/date/tests/bug48058.phpt +++ b/ext/date/tests/bug48058.phpt @@ -13,12 +13,12 @@ $base_time = '28 Feb 2008 12:00:00'; $dt = date_create( "$base_time +10000000000 years" ); echo date_format( $dt, DATE_ISO8601 ); ?> ---EXPECT-- +--EXPECTF-- array(5) { ["ts"]=> - int(-9223372036854775808) + int(-%d) ["time"]=> - string(33) "-292277022657-01-27T08:29:52+0000" + string(%d) "%s" ["offset"]=> int(3600) ["isdst"]=> diff --git a/ext/date/tests/cal_days_in_month_invalid_calendar.phpt b/ext/date/tests/cal_days_in_month_invalid_calendar.phpt new file mode 100644 index 000000000..3550b91e7 --- /dev/null +++ b/ext/date/tests/cal_days_in_month_invalid_calendar.phpt @@ -0,0 +1,16 @@ +--TEST-- +cal_days_in_month: test invalid parameter +--CREDITS-- +Havard Eide +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--INI-- +date.timezone=UTC +--FILE-- + +--EXPECTF-- +Warning: cal_days_in_month(): invalid calendar ID 99. in %s on line %d + diff --git a/ext/date/tests/cal_days_in_month_invalid_date.phpt b/ext/date/tests/cal_days_in_month_invalid_date.phpt new file mode 100644 index 000000000..031527074 --- /dev/null +++ b/ext/date/tests/cal_days_in_month_invalid_date.phpt @@ -0,0 +1,16 @@ +--TEST-- +cal_days_in_month: test invalid parameter +--CREDITS-- +Havard Eide +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--INI-- +date.timezone=UTC +--FILE-- + +--EXPECTF-- +Warning: cal_days_in_month(): invalid date. in %s on line %d + diff --git a/ext/date/tests/date_sunrise_variation5.phpt b/ext/date/tests/date_sunrise_variation5.phpt index e697836d1..42674789f 100644 --- a/ext/date/tests/date_sunrise_variation5.phpt +++ b/ext/date/tests/date_sunrise_variation5.phpt @@ -113,13 +113,13 @@ bool(false) bool(false) --int 12345-- -string(5) "09:52" -float(9.882%d) -int(1218169377) +string(5) "09:51" +float(9.855%d) +int(1218169278) --int -12345-- string(5) "09:54" -float(9.909%d) +float(9.9097820911118) int(1218169475) --empty array-- diff --git a/ext/date/tests/date_sunset_variation5.phpt b/ext/date/tests/date_sunset_variation5.phpt index 26bf4ccc9..071963362 100644 --- a/ext/date/tests/date_sunset_variation5.phpt +++ b/ext/date/tests/date_sunset_variation5.phpt @@ -113,9 +113,9 @@ bool(false) bool(false) --int 12345-- -string(5) "19:19" -float(19.319%d) -int(1218203349) +string(5) "19:20" +float(19.340%d) +int(1218203424) --int -12345-- bool(false) diff --git a/ext/date/tests/date_timestamp_get.phpt b/ext/date/tests/date_timestamp_get.phpt new file mode 100644 index 000000000..bdd4d047e --- /dev/null +++ b/ext/date/tests/date_timestamp_get.phpt @@ -0,0 +1,20 @@ +--TEST-- +DateTime: Test correct setup and correct DateTime parameter to date_timestamp_get() +--CREDITS-- +Havard Eide +#PHPTestFest2009 Norway 2009-06-09 \o/ +--INI-- +date.timezone=UTC +--FILE-- + +--EXPECTF-- +bool(true) + + + +Warning: date_timestamp_get() expects parameter 1 to be DateTime, integer given in %s on line %d \ No newline at end of file diff --git a/ext/date/tests/strtotime_basic.phpt b/ext/date/tests/strtotime_basic.phpt index 673b9fb45..75f66978a 100644 --- a/ext/date/tests/strtotime_basic.phpt +++ b/ext/date/tests/strtotime_basic.phpt @@ -13,29 +13,29 @@ date_default_timezone_set('UTC'); /* * This is parsed as the "first following Monday OR the current day if it is a Monday" */ -var_dump(date('Y-m-d', strtotime('1 Monday December 2008'))); +var_dump(date('Y-m-d', strtotime('1 Monday December 2008'))); /* * This is parsed as the "second following Monday OR the first following * Monday if the current day is a Monday" */ -var_dump(date('Y-m-d', strtotime('2 Monday December 2008'))); +var_dump(date('Y-m-d', strtotime('2 Monday December 2008'))); /* * This is parsed as the "third following Monday OR the second following * Monday if the current day is a Monday" */ -var_dump(date('Y-m-d', strtotime('3 Monday December 2008'))); +var_dump(date('Y-m-d', strtotime('3 Monday December 2008'))); /* * This is parsed as the "first following Monday after the first Monday in December" */ -var_dump(date('Y-m-d', strtotime('first Monday December 2008'))); +var_dump(date('Y-m-d', strtotime('first Monday December 2008'))); /* * This is parsed as the "second following Monday after the first Monday in December" */ -var_dump(date('Y-m-d', strtotime('second Monday December 2008'))); +var_dump(date('Y-m-d', strtotime('second Monday December 2008'))); /* * This is parsed as the "third following Monday after the first Monday in December" */ -var_dump(date('Y-m-d', strtotime('third Monday December 2008'))); +var_dump(date('Y-m-d', strtotime('third Monday December 2008'))); ?> --EXPECTF-- %string|unicode%(10) "2008-12-01" diff --git a/ext/date/tests/timezone_identifiers_list_wrong_constructor.phpt b/ext/date/tests/timezone_identifiers_list_wrong_constructor.phpt new file mode 100644 index 000000000..5b8493ba1 --- /dev/null +++ b/ext/date/tests/timezone_identifiers_list_wrong_constructor.phpt @@ -0,0 +1,15 @@ +--TEST-- +timezone_identifiers_list: Test that correct notice is given when timezone_identifiers_list is given 4096 as parameter +--CREDITS-- +Havard Eide +#PHPTestFest2009 Norway 2009-06-09 \o/ +--INI-- +error_reporting=E_ALL +date.timezone=UTC +--FILE-- + +--EXPECTF-- +Notice: timezone_identifiers_list(): A two-letter ISO 3166-1 compatible country code is expected in %s on line %d \ No newline at end of file diff --git a/ext/date/tests/timezone_location_get.phpt b/ext/date/tests/timezone_location_get.phpt new file mode 100644 index 000000000..745fc8799 --- /dev/null +++ b/ext/date/tests/timezone_location_get.phpt @@ -0,0 +1,24 @@ +--TEST-- +timezone_location_get: Test that timezone_location_get returns a correct array of information +--CREDITS-- +Havard Eide +#PHPTestFest2009 Norway 2009-06-09 \o/ +--INI-- +date.timezone=UTC +--FILE-- + +--EXPECT-- +array(4) { + ["country_code"]=> + string(2) "NO" + ["latitude"]=> + float(59.91666) + ["longitude"]=> + float(10.75) + ["comments"]=> + string(0) "" +} + diff --git a/ext/dba/config.m4 b/ext/dba/config.m4 index a77adc01b..feed36e25 100644 --- a/ext/dba/config.m4 +++ b/ext/dba/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.70.2.2.2.8.2.2 2007/12/06 14:01:49 helly Exp $ +dnl $Id: config.m4 247692 2007-12-06 14:01:49Z helly $ dnl dnl Suppose we need FlatFile if no support or only CDB is used. diff --git a/ext/dba/config.w32 b/ext/dba/config.w32 index 2239009dc..1f72019f4 100644 --- a/ext/dba/config.w32 +++ b/ext/dba/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.3 2005/02/26 01:05:33 helly Exp $ +// $Id: config.w32 180813 2005-02-26 01:05:33Z helly $ // vim:ft=javascript ARG_WITH("dba", "DBA support", "no"); diff --git a/ext/dba/dba.c b/ext/dba/dba.c index 991c257dd..d59b1f2b1 100644 --- a/ext/dba/dba.c +++ b/ext/dba/dba.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba.c,v 1.111.2.4.2.5.2.10 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dba.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dba/dba_cdb.c b/ext/dba/dba_cdb.c index a436875bb..61c1df5bf 100644 --- a/ext/dba/dba_cdb.c +++ b/ext/dba/dba_cdb.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_cdb.c,v 1.32.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dba_cdb.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dba/dba_db1.c b/ext/dba/dba_db1.c index 7bc348ee9..202ef6918 100755 --- a/ext/dba/dba_db1.c +++ b/ext/dba/dba_db1.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_db1.c,v 1.3.2.1.2.1.2.3 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dba_db1.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dba/dba_db2.c b/ext/dba/dba_db2.c index b12606a3b..6b3111146 100644 --- a/ext/dba/dba_db2.c +++ b/ext/dba/dba_db2.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_db2.c,v 1.39.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dba_db2.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dba/dba_db3.c b/ext/dba/dba_db3.c index a229cb429..3b090ca60 100644 --- a/ext/dba/dba_db3.c +++ b/ext/dba/dba_db3.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_db3.c,v 1.33.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dba_db3.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dba/dba_db4.c b/ext/dba/dba_db4.c index 2c2da4052..bdf9cdfbd 100644 --- a/ext/dba/dba_db4.c +++ b/ext/dba/dba_db4.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_db4.c,v 1.15.2.3.2.1.2.4 2009/05/13 02:14:53 felipe Exp $ */ +/* $Id: dba_db4.c 286636 2009-08-01 23:10:11Z felipe $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -175,7 +175,15 @@ DBA_EXISTS_FUNC(db4) DB4_GKEY; memset(&gval, 0, sizeof(gval)); + + if (info->flags & DBA_PERSISTENT) { + gval.flags |= DB_DBT_MALLOC; + } + if (!dba->dbp->get(dba->dbp, NULL, &gkey, &gval, 0)) { + if (info->flags & DBA_PERSISTENT) { + free(gval.data); + } return SUCCESS; } return FAILURE; diff --git a/ext/dba/dba_dbm.c b/ext/dba/dba_dbm.c index a65510208..9e323694e 100644 --- a/ext/dba/dba_dbm.c +++ b/ext/dba/dba_dbm.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_dbm.c,v 1.29.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dba_dbm.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dba/dba_flatfile.c b/ext/dba/dba_flatfile.c index 617c81bda..849ce3ace 100644 --- a/ext/dba/dba_flatfile.c +++ b/ext/dba/dba_flatfile.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_flatfile.c,v 1.19.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dba_flatfile.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dba/dba_gdbm.c b/ext/dba/dba_gdbm.c index 63ddef82e..d7a0c929f 100644 --- a/ext/dba/dba_gdbm.c +++ b/ext/dba/dba_gdbm.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_gdbm.c,v 1.23.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dba_gdbm.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dba/dba_inifile.c b/ext/dba/dba_inifile.c index bbea05ddb..0cd2f28c9 100644 --- a/ext/dba/dba_inifile.c +++ b/ext/dba/dba_inifile.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_inifile.c,v 1.5.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dba_inifile.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dba/dba_ndbm.c b/ext/dba/dba_ndbm.c index c74d761b4..3860039b4 100644 --- a/ext/dba/dba_ndbm.c +++ b/ext/dba/dba_ndbm.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_ndbm.c,v 1.19.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dba_ndbm.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dba/dba_qdbm.c b/ext/dba/dba_qdbm.c index 94fb9fc67..b3a9c35c4 100755 --- a/ext/dba/dba_qdbm.c +++ b/ext/dba/dba_qdbm.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dba_qdbm.c,v 1.4.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dba_qdbm.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dba/install_cdb.sh b/ext/dba/install_cdb.sh index 82396b922..ce5f3cc85 100755 --- a/ext/dba/install_cdb.sh +++ b/ext/dba/install_cdb.sh @@ -8,7 +8,7 @@ # library which programs can link against. This shell script fills # the gap. # -# $Id: install_cdb.sh,v 1.2 2002/11/04 17:53:04 helly Exp $ +# $Id: install_cdb.sh,v 1.2 2002-11-04 17:53:04 helly Exp $ if test -r "cdb.a" && test -r "auto-str.c" && test -r "byte.a"; then : diff --git a/ext/dba/libcdb/cdb.c b/ext/dba/libcdb/cdb.c index 9fccda705..6d5f3aaf8 100644 --- a/ext/dba/libcdb/cdb.c +++ b/ext/dba/libcdb/cdb.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: cdb.c,v 1.10.2.1.2.3.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: cdb.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ @@ -189,6 +189,6 @@ int cdb_find(struct cdb *c, char *key, unsigned int len TSRMLS_DC) /* {{{ cdb_version */ char *cdb_version() { - return "0.75, $Revision: 1.10.2.1.2.3.2.2 $"; + return "0.75, $Revision: 272370 $"; } /* }}} */ diff --git a/ext/dba/libcdb/cdb.h b/ext/dba/libcdb/cdb.h index 14e6cb3ae..858e9a36c 100644 --- a/ext/dba/libcdb/cdb.h +++ b/ext/dba/libcdb/cdb.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: cdb.h,v 1.7.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: cdb.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ diff --git a/ext/dba/libcdb/cdb_make.c b/ext/dba/libcdb/cdb_make.c index 81e001e3d..180d192c4 100644 --- a/ext/dba/libcdb/cdb_make.c +++ b/ext/dba/libcdb/cdb_make.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: cdb_make.c,v 1.9.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: cdb_make.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ @@ -240,5 +240,5 @@ int cdb_make_finish(struct cdb_make *c TSRMLS_DC) /* {{{ cdb_make_version */ char *cdb_make_version() { - return "0.75, $Revision: 1.9.2.1.2.1.2.2 $"; + return "0.75, $Revision: 272370 $"; } diff --git a/ext/dba/libcdb/cdb_make.h b/ext/dba/libcdb/cdb_make.h index f341124c1..a0fea70ce 100644 --- a/ext/dba/libcdb/cdb_make.h +++ b/ext/dba/libcdb/cdb_make.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: cdb_make.h,v 1.7.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: cdb_make.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ diff --git a/ext/dba/libcdb/uint32.c b/ext/dba/libcdb/uint32.c index a45a3e66c..29df68c4c 100644 --- a/ext/dba/libcdb/uint32.c +++ b/ext/dba/libcdb/uint32.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: uint32.c,v 1.6.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: uint32.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ diff --git a/ext/dba/libcdb/uint32.h b/ext/dba/libcdb/uint32.h index 2675653b9..df31e4c24 100644 --- a/ext/dba/libcdb/uint32.h +++ b/ext/dba/libcdb/uint32.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: uint32.h,v 1.6.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: uint32.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* incorporated from D.J.Bernstein's cdb-0.75 (http://cr.yp.to/cdb.html)*/ diff --git a/ext/dba/libflatfile/flatfile.c b/ext/dba/libflatfile/flatfile.c index fff029b85..16216b4fe 100644 --- a/ext/dba/libflatfile/flatfile.c +++ b/ext/dba/libflatfile/flatfile.c @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: flatfile.c,v 1.14.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: flatfile.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -307,7 +307,7 @@ datum flatfile_nextkey(flatfile *dba TSRMLS_DC) { /* {{{ flatfile_version */ char *flatfile_version() { - return "1.0, $Revision: 1.14.2.1.2.1.2.2 $"; + return "1.0, $Revision: 272370 $"; } /* }}} */ diff --git a/ext/dba/libflatfile/flatfile.h b/ext/dba/libflatfile/flatfile.h index 864903bca..3de35871d 100644 --- a/ext/dba/libflatfile/flatfile.h +++ b/ext/dba/libflatfile/flatfile.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: flatfile.h,v 1.11.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: flatfile.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_LIB_FLATFILE_H #define PHP_LIB_FLATFILE_H diff --git a/ext/dba/libinifile/inifile.c b/ext/dba/libinifile/inifile.c index df4070cfe..acc479248 100644 --- a/ext/dba/libinifile/inifile.c +++ b/ext/dba/libinifile/inifile.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: inifile.c,v 1.14.2.1.2.3.2.3 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: inifile.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -43,7 +43,7 @@ /* {{{ inifile_version */ char *inifile_version() { - return "1.0, $Revision: 1.14.2.1.2.3.2.3 $"; + return "1.0, $Revision: 272370 $"; } /* }}} */ diff --git a/ext/dba/libinifile/inifile.h b/ext/dba/libinifile/inifile.h index 68c167533..81806f1cb 100644 --- a/ext/dba/libinifile/inifile.h +++ b/ext/dba/libinifile/inifile.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: inifile.h,v 1.5.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: inifile.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_LIB_INIFILE_H #define PHP_LIB_INIFILE_H diff --git a/ext/dba/php_dba.h b/ext/dba/php_dba.h index 45f38b9a5..fccb2ee6d 100644 --- a/ext/dba/php_dba.h +++ b/ext/dba/php_dba.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_dba.h,v 1.29.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: php_dba.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_DBA_H #define PHP_DBA_H diff --git a/ext/dba/tests/bug36436.phpt b/ext/dba/tests/bug36436.phpt index 60470660e..4e8daa860 100755 --- a/ext/dba/tests/bug36436.phpt +++ b/ext/dba/tests/bug36436.phpt @@ -3,13 +3,13 @@ Bug #36436 (DBA problem with Berkeley DB4) --SKIPIF-- --FILE-- --FILE-- +--FILE-- + --FILE-- --EXPECTF-- database handler: %s -database file created \ No newline at end of file +database file created diff --git a/ext/dba/tests/dba002.phpt b/ext/dba/tests/dba002.phpt index 3f862e38c..974b09fab 100644 --- a/ext/dba/tests/dba002.phpt +++ b/ext/dba/tests/dba002.phpt @@ -2,12 +2,12 @@ DBA Insert/Fetch Test --SKIPIF-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- --EXPECTF-- database handler: %s -3NYNYY \ No newline at end of file +3NYNYY diff --git a/ext/dba/tests/dba007.phpt b/ext/dba/tests/dba007.phpt index cc84a729c..0f30932fc 100644 --- a/ext/dba/tests/dba007.phpt +++ b/ext/dba/tests/dba007.phpt @@ -2,13 +2,13 @@ DBA Multiple File Creation Test --SKIPIF-- --FILE-- --FILE-- --FILE-- --FILE-- ===DONE=== --EXPECT-- diff --git a/ext/dba/tests/dba_cdb_make.phpt b/ext/dba/tests/dba_cdb_make.phpt index bb41e82fb..b7311f1dd 100644 --- a/ext/dba/tests/dba_cdb_make.phpt +++ b/ext/dba/tests/dba_cdb_make.phpt @@ -5,13 +5,13 @@ magic_quotes_runtime=1 --SKIPIF-- --FILE-- --FILE-- --FILE-- ===DONE=== --EXPECT-- diff --git a/ext/dba/tests/dba_db2.phpt b/ext/dba/tests/dba_db2.phpt index bcc5a9479..89d8a926e 100644 --- a/ext/dba/tests/dba_db2.phpt +++ b/ext/dba/tests/dba_db2.phpt @@ -3,13 +3,13 @@ DBA DB2 handler test --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- diff --git a/ext/dba/tests/dba_db3.phpt b/ext/dba/tests/dba_db3.phpt index c6d04cf02..257c88217 100644 --- a/ext/dba/tests/dba_db3.phpt +++ b/ext/dba/tests/dba_db3.phpt @@ -3,13 +3,13 @@ DBA DB3 handler test --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- diff --git a/ext/dba/tests/dba_db4.phpt b/ext/dba/tests/dba_db4.phpt index fcf089a1e..2c2a7a694 100644 --- a/ext/dba/tests/dba_db4.phpt +++ b/ext/dba/tests/dba_db4.phpt @@ -3,13 +3,13 @@ DBA DB4 handler test --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- diff --git a/ext/dba/tests/dba_dbm.phpt b/ext/dba/tests/dba_dbm.phpt index fdd7b375f..dd1fe1e31 100644 --- a/ext/dba/tests/dba_dbm.phpt +++ b/ext/dba/tests/dba_dbm.phpt @@ -3,13 +3,13 @@ DBA DBM handler test --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- diff --git a/ext/dba/tests/dba_flatfile.phpt b/ext/dba/tests/dba_flatfile.phpt index 2e32b8a32..a85472bbe 100644 --- a/ext/dba/tests/dba_flatfile.phpt +++ b/ext/dba/tests/dba_flatfile.phpt @@ -3,13 +3,13 @@ DBA FlatFile handler test --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- diff --git a/ext/dba/tests/dba_gdbm.phpt b/ext/dba/tests/dba_gdbm.phpt index f9b3e3c60..33d7d2061 100644 --- a/ext/dba/tests/dba_gdbm.phpt +++ b/ext/dba/tests/dba_gdbm.phpt @@ -3,14 +3,14 @@ DBA GDBM handler test --SKIPIF-- --FILE-- diff --git a/ext/dba/tests/dba_inifile.phpt b/ext/dba/tests/dba_inifile.phpt index 9511a8bb4..81ab73879 100644 --- a/ext/dba/tests/dba_inifile.phpt +++ b/ext/dba/tests/dba_inifile.phpt @@ -3,13 +3,13 @@ DBA INIFILE handler test --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- diff --git a/ext/dba/tests/dba_ndbm.phpt b/ext/dba/tests/dba_ndbm.phpt index f7955c581..b0f5542de 100644 --- a/ext/dba/tests/dba_ndbm.phpt +++ b/ext/dba/tests/dba_ndbm.phpt @@ -3,13 +3,13 @@ DBA NDBM handler test --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- diff --git a/ext/dba/tests/dba_qdbm.phpt b/ext/dba/tests/dba_qdbm.phpt index a7c9ab69e..ef216d925 100755 --- a/ext/dba/tests/dba_qdbm.phpt +++ b/ext/dba/tests/dba_qdbm.phpt @@ -3,14 +3,14 @@ DBA QDBM handler test --SKIPIF-- --FILE-- ===DONE=== --EXPECTF-- diff --git a/ext/dba/tests/test.inc b/ext/dba/tests/test.inc index 04f954541..7c4e207b8 100644 --- a/ext/dba/tests/test.inc +++ b/ext/dba/tests/test.inc @@ -1,7 +1,7 @@ diff --git a/ext/dom/attr.c b/ext/dom/attr.c index a3133ff7b..f6f57afb0 100644 --- a/ext/dom/attr.c +++ b/ext/dom/attr.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: attr.c,v 1.18.2.2.2.2.2.12 2009/03/13 13:43:29 rrichards Exp $ */ +/* $Id: attr.c 277102 2009-03-13 13:43:29Z rrichards $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/cdatasection.c b/ext/dom/cdatasection.c index ae98fa9d8..f57e3c4f0 100644 --- a/ext/dom/cdatasection.c +++ b/ext/dom/cdatasection.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: cdatasection.c,v 1.11.2.1.2.1.2.11 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: cdatasection.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/characterdata.c b/ext/dom/characterdata.c index c0b660ff1..9af73a187 100644 --- a/ext/dom/characterdata.c +++ b/ext/dom/characterdata.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: characterdata.c,v 1.15.2.1.2.2.2.9 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: characterdata.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/comment.c b/ext/dom/comment.c index 79127245b..c3888a8bc 100644 --- a/ext/dom/comment.c +++ b/ext/dom/comment.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: comment.c,v 1.11.2.1.2.1.2.11 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: comment.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/config.m4 b/ext/dom/config.m4 index 12d40f28c..89dd4c037 100644 --- a/ext/dom/config.m4 +++ b/ext/dom/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.20.4.1 2007/07/03 17:25:33 sniper Exp $ +dnl $Id: config.m4 239118 2007-07-03 17:25:43Z sniper $ dnl PHP_ARG_ENABLE(dom, whether to enable DOM support, diff --git a/ext/dom/config.w32 b/ext/dom/config.w32 index bec3b81d3..e8237853f 100644 --- a/ext/dom/config.w32 +++ b/ext/dom/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.3.8.1 2008/06/23 18:40:28 pajoye Exp $ +// $Id: config.w32 261548 2008-06-23 18:40:29Z pajoye $ // vim:ft=javascript ARG_WITH("dom", "DOM support", "yes"); diff --git a/ext/dom/document.c b/ext/dom/document.c index ea3d1a825..9fc6290d1 100644 --- a/ext/dom/document.c +++ b/ext/dom/document.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: document.c,v 1.68.2.3.2.5.2.17 2009/06/14 13:13:35 iliaa Exp $ */ +/* $Id: document.c 282119 2009-06-14 13:13:35Z iliaa $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/documentfragment.c b/ext/dom/documentfragment.c index 4bd53104d..c1b3b6490 100644 --- a/ext/dom/documentfragment.c +++ b/ext/dom/documentfragment.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: documentfragment.c,v 1.15.2.1.2.1.2.11 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: documentfragment.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/documenttype.c b/ext/dom/documenttype.c index 20cfdea6e..fcb938f97 100644 --- a/ext/dom/documenttype.c +++ b/ext/dom/documenttype.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: documenttype.c,v 1.15.2.1.2.1.2.4 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: documenttype.c 289439 2009-10-09 18:52:59Z pajoye $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -190,7 +190,6 @@ int dom_documenttype_internal_subset_read(dom_object *obj, zval **retval TSRMLS_ xmlDtdPtr dtdptr; xmlDtd *intsubset; xmlOutputBuffer *buff = NULL; - xmlChar *strintsubset; dtdptr = (xmlDtdPtr) dom_object_get_node(obj); @@ -206,9 +205,8 @@ int dom_documenttype_internal_subset_read(dom_object *obj, zval **retval TSRMLS_ if (buff != NULL) { xmlNodeDumpOutput (buff, NULL, (xmlNodePtr) intsubset, 0, 0, NULL); xmlOutputBufferFlush(buff); - strintsubset = xmlStrndup(buff->buffer->content, buff->buffer->use); + ZVAL_STRINGL(*retval, buff->buffer->content, buff->buffer->use, 1); (void)xmlOutputBufferClose(buff); - ZVAL_STRING(*retval, (char *) strintsubset, 1); return SUCCESS; } } diff --git a/ext/dom/dom_ce.h b/ext/dom/dom_ce.h index 13a408d55..d14b3103e 100644 --- a/ext/dom/dom_ce.h +++ b/ext/dom/dom_ce.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dom_ce.h,v 1.8.2.1.2.1.2.3 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dom_ce.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef DOM_CE_H #define DOM_CE_H diff --git a/ext/dom/dom_fe.h b/ext/dom/dom_fe.h index 1c53d3297..3a052f2ee 100644 --- a/ext/dom/dom_fe.h +++ b/ext/dom/dom_fe.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dom_fe.h,v 1.14.2.1.2.4.2.6 2009/01/13 18:06:48 rrichards Exp $ */ +/* $Id: dom_fe.h 273468 2009-01-13 18:06:48Z rrichards $ */ #ifndef DOM_FE_H #define DOM_FE_H diff --git a/ext/dom/dom_iterators.c b/ext/dom/dom_iterators.c index 1527a7303..e76b4ac79 100644 --- a/ext/dom/dom_iterators.c +++ b/ext/dom/dom_iterators.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dom_iterators.c,v 1.9.2.3.2.5.2.4 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dom_iterators.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/dom_properties.h b/ext/dom/dom_properties.h index b4232fd7f..6fd1bcc3b 100644 --- a/ext/dom/dom_properties.h +++ b/ext/dom/dom_properties.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dom_properties.h,v 1.7.2.1.2.1.2.3 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: dom_properties.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef DOM_PROPERTIES_H #define DOM_PROPERTIES_H diff --git a/ext/dom/domconfiguration.c b/ext/dom/domconfiguration.c index 5e75ea944..5ae0421ac 100644 --- a/ext/dom/domconfiguration.c +++ b/ext/dom/domconfiguration.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: domconfiguration.c,v 1.5.2.1.2.1.2.9 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: domconfiguration.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/domerror.c b/ext/dom/domerror.c index d5e7e7813..330d4af75 100644 --- a/ext/dom/domerror.c +++ b/ext/dom/domerror.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: domerror.c,v 1.6.2.1.2.1.2.4 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: domerror.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/domerrorhandler.c b/ext/dom/domerrorhandler.c index 3696b66b8..a161428e7 100644 --- a/ext/dom/domerrorhandler.c +++ b/ext/dom/domerrorhandler.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: domerrorhandler.c,v 1.5.2.1.2.1.2.8 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: domerrorhandler.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/domexception.c b/ext/dom/domexception.c index cf94be365..9301c11fa 100644 --- a/ext/dom/domexception.c +++ b/ext/dom/domexception.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: domexception.c,v 1.11.2.1.2.1.2.4 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: domexception.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/domimplementation.c b/ext/dom/domimplementation.c index 772218c40..6ec0e6534 100644 --- a/ext/dom/domimplementation.c +++ b/ext/dom/domimplementation.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: domimplementation.c,v 1.15.2.2.2.2.2.9 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: domimplementation.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/domimplementationlist.c b/ext/dom/domimplementationlist.c index 99c5c1cee..144e58af8 100644 --- a/ext/dom/domimplementationlist.c +++ b/ext/dom/domimplementationlist.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: domimplementationlist.c,v 1.6.2.1.2.1.2.8 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: domimplementationlist.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/domimplementationsource.c b/ext/dom/domimplementationsource.c index e376738d2..66248e3ca 100644 --- a/ext/dom/domimplementationsource.c +++ b/ext/dom/domimplementationsource.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: domimplementationsource.c,v 1.5.2.1.2.1.2.8 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: domimplementationsource.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/domlocator.c b/ext/dom/domlocator.c index 6c8baeb67..f40d47d2c 100644 --- a/ext/dom/domlocator.c +++ b/ext/dom/domlocator.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: domlocator.c,v 1.6.2.1.2.1.2.4 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: domlocator.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/domstringlist.c b/ext/dom/domstringlist.c index c6d4ff4cb..d2d787944 100644 --- a/ext/dom/domstringlist.c +++ b/ext/dom/domstringlist.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: domstringlist.c,v 1.6.2.1.2.1.2.8 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: domstringlist.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/element.c b/ext/dom/element.c index b2b7b7d32..69d780fa0 100644 --- a/ext/dom/element.c +++ b/ext/dom/element.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: element.c,v 1.36.2.4.2.8.2.12 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: element.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/entity.c b/ext/dom/entity.c index 1e53ebdcb..7caaab00f 100644 --- a/ext/dom/entity.c +++ b/ext/dom/entity.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: entity.c,v 1.9.2.1.2.1.2.4 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: entity.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/entityreference.c b/ext/dom/entityreference.c index 6d8d7f560..762fc3fd5 100644 --- a/ext/dom/entityreference.c +++ b/ext/dom/entityreference.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: entityreference.c,v 1.12.2.1.2.2.2.10 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: entityreference.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/namednodemap.c b/ext/dom/namednodemap.c index 50c8f027f..2ea88f6ca 100644 --- a/ext/dom/namednodemap.c +++ b/ext/dom/namednodemap.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: namednodemap.c,v 1.15.2.2.2.1.2.8 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: namednodemap.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/namelist.c b/ext/dom/namelist.c index 164e04963..116165e16 100644 --- a/ext/dom/namelist.c +++ b/ext/dom/namelist.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: namelist.c,v 1.7.2.1.2.1.2.8 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: namelist.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/node.c b/ext/dom/node.c index 82366c63c..923757d93 100644 --- a/ext/dom/node.c +++ b/ext/dom/node.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: node.c,v 1.37.2.3.2.8.2.14 2009/03/13 13:43:29 rrichards Exp $ */ +/* $Id: node.c 277102 2009-03-13 13:43:29Z rrichards $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/nodelist.c b/ext/dom/nodelist.c index 84ca08dc4..923db9680 100644 --- a/ext/dom/nodelist.c +++ b/ext/dom/nodelist.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: nodelist.c,v 1.17.2.2.2.2.2.8 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: nodelist.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/notation.c b/ext/dom/notation.c index 84e5bdf42..48171775b 100644 --- a/ext/dom/notation.c +++ b/ext/dom/notation.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: notation.c,v 1.9.2.2.2.1.2.4 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: notation.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/php_dom.c b/ext/dom/php_dom.c index feaf3afeb..214139c5f 100644 --- a/ext/dom/php_dom.c +++ b/ext/dom/php_dom.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_dom.c,v 1.73.2.12.2.12.2.14 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: php_dom.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/php_dom.h b/ext/dom/php_dom.h index 4d2e4b6f1..1e43aa0fd 100644 --- a/ext/dom/php_dom.h +++ b/ext/dom/php_dom.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_dom.h,v 1.28.2.1.2.4.2.5 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: php_dom.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_DOM_H #define PHP_DOM_H diff --git a/ext/dom/processinginstruction.c b/ext/dom/processinginstruction.c index 850001485..8e6d676cf 100644 --- a/ext/dom/processinginstruction.c +++ b/ext/dom/processinginstruction.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: processinginstruction.c,v 1.17.2.1.2.1.2.12 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: processinginstruction.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/string_extend.c b/ext/dom/string_extend.c index cf7a48f7a..8b791dfbf 100644 --- a/ext/dom/string_extend.c +++ b/ext/dom/string_extend.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: string_extend.c,v 1.5.2.1.2.1.2.8 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: string_extend.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/tests/DOMAttr_value_basic_001.phpt b/ext/dom/tests/DOMAttr_value_basic_001.phpt new file mode 100755 index 000000000..2a2b52121 --- /dev/null +++ b/ext/dom/tests/DOMAttr_value_basic_001.phpt @@ -0,0 +1,11 @@ +--TEST-- +Read empty $value. +--CREDIT-- +Jason Bouffard +# TestFest Atlanta 2009-05-14 +--FILE-- +value."\n"; +?> +--EXPECTF-- diff --git a/ext/dom/tests/DOMCharacterData_data_basic_002.phpt b/ext/dom/tests/DOMCharacterData_data_basic_002.phpt new file mode 100644 index 000000000..394b316fa --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_data_basic_002.phpt @@ -0,0 +1,28 @@ +--TEST-- +Create CDATA section and change it using DOMcreateCDATASection +--CREDITS-- +Nic Rosental nicrosental@gmail.com +# TestFest Atlanta 2009-5-28 +--SKIPIF-- + +--FILE-- +createElement('root'); +$document->appendChild($root); + +$cdata = $document->createCDATASection('t'); +$root->appendChild($cdata); +print $document->saveXML()."\n"; + +$cdata->data = 100; +print $document->saveXML()."\n"; + +?> +--EXPECT-- + + + + + diff --git a/ext/dom/tests/DOMCharacterData_length_error_001.phpt b/ext/dom/tests/DOMCharacterData_length_error_001.phpt new file mode 100755 index 000000000..87c9377b3 --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_length_error_001.phpt @@ -0,0 +1,12 @@ +--TEST-- +Invalid State Error when getting length on DOMCharacterData out of content. +--CREDIT-- +Jason Bouffard +# TestFest Atlanta 2009-05-14 +--FILE-- +length; +?> +--EXPECTF-- +Warning: main(): Invalid State Error in %s \ No newline at end of file diff --git a/ext/dom/tests/DOMCharacterData_substringData_basic_001.phpt b/ext/dom/tests/DOMCharacterData_substringData_basic_001.phpt new file mode 100644 index 000000000..b9d73e181 --- /dev/null +++ b/ext/dom/tests/DOMCharacterData_substringData_basic_001.phpt @@ -0,0 +1,21 @@ +--TEST-- +__DOMCharacterData::substringData pull mid section of string +--CREDITS-- +Nic Rosental nicrosental@gmail.com +# TestFest Atlanta 2009-5-28 +--SKIPIF-- + +--FILE-- +createElement('root'); +$document->appendChild($root); + +$cdata = $document->createCDATASection('testfest'); +$root->appendChild($cdata); +print $cdata->substringData(1, 6); + +?> +--EXPECT-- +estfes \ No newline at end of file diff --git a/ext/dom/tests/DOMDocument_config_basic.phpt b/ext/dom/tests/DOMDocument_config_basic.phpt new file mode 100644 index 000000000..947743abe --- /dev/null +++ b/ext/dom/tests/DOMDocument_config_basic.phpt @@ -0,0 +1,26 @@ +--TEST-- +Tests DOMDocument::config read +--CREDITS-- +Chris Snyder +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +config; +echo "Read config:\n"; +var_dump( $test ); + +// note -- will always be null as DOMConfiguration is not implemented in PHP + +echo "Done\n"; +?> +--EXPECT-- +DOMDocument created +Read config: +NULL +Done diff --git a/ext/dom/tests/DOMDocument_createEntityReference_basic.phpt b/ext/dom/tests/DOMDocument_createEntityReference_basic.phpt new file mode 100644 index 000000000..4f4ddf176 --- /dev/null +++ b/ext/dom/tests/DOMDocument_createEntityReference_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMDocument::createEntityReference() should create a new entity reference node +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- +createEntityReference('nbsp'); +$dom->appendChild($ref); +echo $dom->saveXML(); +?> +--EXPECTF-- + +  diff --git a/ext/dom/tests/DOMDocument_documentURI_basic.phpt b/ext/dom/tests/DOMDocument_documentURI_basic.phpt new file mode 100644 index 000000000..e40a42b96 --- /dev/null +++ b/ext/dom/tests/DOMDocument_documentURI_basic.phpt @@ -0,0 +1,39 @@ +--TEST-- +Tests DOMDocument::documentURI read and write +--CREDITS-- +Chris Snyder +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- + + +foo'; +$dom->loadXML($xml); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} +echo "DOMDocument created\n"; + +$test = $dom->documentURI; +echo "Read initial documentURI:\n"; +echo $test."\n"; + +$dom->documentURI = 'http://dom.example.org/example.xml'; +$test = $dom->documentURI; +echo "Set documentURI to a URL, reading again:\n"; +var_dump( $test ); + +echo "Done\n"; +?> +--EXPECTF-- +DOMDocument created +Read initial documentURI: +%s +Set documentURI to a URL, reading again: +string(34) "http://dom.example.org/example.xml" +Done diff --git a/ext/dom/tests/DOMDocument_encoding_basic.phpt b/ext/dom/tests/DOMDocument_encoding_basic.phpt new file mode 100644 index 000000000..9fc099bfe --- /dev/null +++ b/ext/dom/tests/DOMDocument_encoding_basic.phpt @@ -0,0 +1,52 @@ +--TEST-- +DOMDocument::$encoding - read/write tests (dom_document_encoding_read/dom_document_encoding_write) +--CREDITS-- +Hans Zaunere +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +loadXML($xmlstr); + +if( !$dom ) +{ + echo "Error while parsing the document\n"; + exit; +} + +echo "Empty Encoding Read: {$dom->encoding}\n"; + +$ret = $dom->encoding = 'NYPHP DOMinatrix'; +echo "Adding invalid encoding: $ret\n"; + +$ret = $dom->encoding = 'ISO-8859-1'; +echo "Adding ISO-8859-1 encoding: $ret\n"; +echo "ISO-8859-1 Encoding Read: {$dom->encoding}\n"; + +$ret = $dom->encoding = 'UTF-8'; +echo "Adding UTF-8 encoding: $ret\n"; +echo "UTF-8 Encoding Read: {$dom->encoding}\n"; + +$ret = $dom->encoding = 'UTF-16'; +echo "Adding UTF-16 encoding: $ret\n"; +echo "UTF-16 Encoding Read: {$dom->encoding}\n"; + + +?> +--EXPECTF-- +Empty Encoding Read: + +Warning: main(): Invalid Document Encoding in %s on line %d +Adding invalid encoding: NYPHP DOMinatrix +Adding ISO-8859-1 encoding: ISO-8859-1 +ISO-8859-1 Encoding Read: ISO-8859-1 +Adding UTF-8 encoding: UTF-8 +UTF-8 Encoding Read: UTF-8 +Adding UTF-16 encoding: UTF-16 +UTF-16 Encoding Read: UTF-16 + diff --git a/ext/dom/tests/DOMDocument_implementationRead_basic.phpt b/ext/dom/tests/DOMDocument_implementationRead_basic.phpt new file mode 100644 index 000000000..17daddf38 --- /dev/null +++ b/ext/dom/tests/DOMDocument_implementationRead_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +DOMDocument::DOMImplementation - basic test for DomDocument::DOMImplementation +--CREDITS-- +Lev Radin +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +var_dump($doc->implementation); + + +?> +--EXPECTF-- +object(DOMImplementation)#%d (0) { +} + diff --git a/ext/dom/tests/DOMDocument_preserveWhiteSpace_basic.phpt b/ext/dom/tests/DOMDocument_preserveWhiteSpace_basic.phpt new file mode 100644 index 000000000..a772bc856 --- /dev/null +++ b/ext/dom/tests/DOMDocument_preserveWhiteSpace_basic.phpt @@ -0,0 +1,23 @@ +--TEST-- +DOMDocument::$preserveWhiteSpace - test ability to read and write property +--CREDITS-- +Lev Radin +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +var_dump($doc->preserveWhiteSpace); + +$doc->preserveWhiteSpace = false; +var_dump($doc->preserveWhiteSpace); + +?> +--EXPECT-- +bool(true) +bool(false) + diff --git a/ext/dom/tests/DOMDocument_preserveWhiteSpace_variations.phpt b/ext/dom/tests/DOMDocument_preserveWhiteSpace_variations.phpt new file mode 100644 index 000000000..e467f56aa --- /dev/null +++ b/ext/dom/tests/DOMDocument_preserveWhiteSpace_variations.phpt @@ -0,0 +1,40 @@ +--TEST-- +DOMDocument::$preserveWhiteSpace - test ability to read and write property +--CREDITS-- +Lev Radin +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); +echo $doc->saveXML(); + + +echo "\nLoad document with preserveWhiteSpace off\n"; +$doc = new DOMDocument; +$doc->preserveWhiteSpace = false; +$doc->load(dirname(__FILE__)."/book.xml"); +echo $doc->saveXML(); + +?> +--EXPECT-- +Load document with preserveWhiteSpace on + + + + The Grapes of Wrath + John Steinbeck + + + The Pearl + John Steinbeck + + + +Load document with preserveWhiteSpace off + +The Grapes of WrathJohn SteinbeckThe PearlJohn Steinbeck diff --git a/ext/dom/tests/DOMDocument_resolveExternals_basic.phpt b/ext/dom/tests/DOMDocument_resolveExternals_basic.phpt new file mode 100644 index 000000000..ccada3fe9 --- /dev/null +++ b/ext/dom/tests/DOMDocument_resolveExternals_basic.phpt @@ -0,0 +1,49 @@ +--TEST-- +Tests DOMDocument::resoleExternals get and set +--CREDITS-- +Chris Snyder +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- + + +

"Foo"

'; +$dom->loadXML($xml); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} +echo "DOMDocument with external entities created\n"; + +$test = $dom->resolveExternals; +echo "Read initial resolveExternals:\n"; +var_dump( $test ); + +$dom->resolveExternals = TRUE; +$test = $dom->resolveExternals; +echo "Set resolveExternals to TRUE, reading again:\n"; +var_dump( $test ); + +/** + * Don't bother testing the resolveExternals functionality here, it throws warnings on html dtd + * +echo "Reloading xml with resolveExternals turned on\n"; +$dom->loadXML($xml); +$test = $dom->saveXML(); +var_dump( $test ); + */ + +echo "Done"; +?> +--EXPECT-- +DOMDocument with external entities created +Read initial resolveExternals: +bool(false) +Set resolveExternals to TRUE, reading again: +bool(true) +Done \ No newline at end of file diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt new file mode 100644 index 000000000..dd0824b0d --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_basic.phpt @@ -0,0 +1,29 @@ +--TEST-- +DOMDocument::saveHTMLFile() should dump the internal document into a file using HTML formatting +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- +createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +$bytes = $doc->saveHTMLFile($filename); +var_dump($bytes); +echo file_get_contents($filename); +unlink($filename); +?> +--EXPECTF-- +int(126) +This is the title diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_error1.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_error1.phpt new file mode 100644 index 000000000..d4dfbe8fe --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_error1.phpt @@ -0,0 +1,24 @@ +--TEST-- +DOMDocument::saveHTMLFile() should fail if no parameter is given +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- +createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +$doc->saveHTMLFile(); +?> +--EXPECTF-- +Warning: DOMDocument::saveHTMLFile() expects exactly 1 parameter, 0 given in %s on line %d diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_error2.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_error2.phpt new file mode 100644 index 000000000..33e07c641 --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_error2.phpt @@ -0,0 +1,15 @@ +--TEST-- +DOMDocument::saveHTMLFile() should fail if called statically +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Non-static method DOMDocument::saveHTMLFile() cannot be called statically in %s on line %d diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput.phpt new file mode 100644 index 000000000..5aece3780 --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_formatOutput.phpt @@ -0,0 +1,33 @@ +--TEST-- +DOMDocument::saveHTMLFile() should format output on demand +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- +formatOutput = true; +$root = $doc->createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +$bytes = $doc->saveHTMLFile($filename); +var_dump($bytes); +echo file_get_contents($filename); +unlink($filename); +?> +--EXPECTF-- +int(129) + + +This is the title + diff --git a/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt b/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt new file mode 100644 index 000000000..d5c6a797e --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTMLFile_invalid_filename.phpt @@ -0,0 +1,25 @@ +--TEST-- +DOMDocument::saveHTMLFile() should fail with invalid filename +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- +createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +$bytes = $doc->saveHTMLFile($filename); +?> +--EXPECTF-- +Warning: DOMDocument::saveHTMLFile(): Invalid Filename in %s on line %d diff --git a/ext/dom/tests/DOMDocument_saveHTML_basic.phpt b/ext/dom/tests/DOMDocument_saveHTML_basic.phpt new file mode 100644 index 000000000..76f1ed0ab --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTML_basic.phpt @@ -0,0 +1,24 @@ +--TEST-- +DOMDocument::saveHTML() should dump the internal document into a string using HTML formatting +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- +createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +echo $doc->saveHTML(); +?> +--EXPECTF-- +This is the title diff --git a/ext/dom/tests/DOMDocument_saveHTML_error1.phpt b/ext/dom/tests/DOMDocument_saveHTML_error1.phpt new file mode 100644 index 000000000..78718de8e --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTML_error1.phpt @@ -0,0 +1,24 @@ +--TEST-- +DOMDocument::saveHTML() should fail if a parameter is given +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- +createElement('html'); +$root = $doc->appendChild($root); +$head = $doc->createElement('head'); +$head = $root->appendChild($head); +$title = $doc->createElement('title'); +$title = $head->appendChild($title); +$text = $doc->createTextNode('This is the title'); +$text = $title->appendChild($text); +echo $doc->saveHTML(true); +?> +--EXPECTF-- +Warning: DOMDocument::saveHTML() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/dom/tests/DOMDocument_saveHTML_error2.phpt b/ext/dom/tests/DOMDocument_saveHTML_error2.phpt new file mode 100644 index 000000000..614605b34 --- /dev/null +++ b/ext/dom/tests/DOMDocument_saveHTML_error2.phpt @@ -0,0 +1,15 @@ +--TEST-- +DOMDocument::saveHTML() should fail if called statically +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Non-static method DOMDocument::saveHTML() cannot be called statically in %s on line %d diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_basic.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_basic.phpt new file mode 100755 index 000000000..38bc3fa3c --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidateSource_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +DomDocument::schemaValidateSource() - basic +--CREDITS-- +Daniel Convissor +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +$xsd = file_get_contents(dirname(__FILE__)."/book.xsd"); + +$result = $doc->schemaValidateSource($xsd); +var_dump($result); + +?> +--EXPECT-- +bool(true) diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt new file mode 100755 index 000000000..51eb82e32 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error1.phpt @@ -0,0 +1,29 @@ +--TEST-- +DomDocument::schemaValidateSource() - string that is not a schema +--CREDITS-- +Daniel Convissor +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidateSource('string that is not a schema'); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidateSource(): Entity: line 1: parser error : Start tag expected, '<' not found in %s.php on line %d + +Warning: DOMDocument::schemaValidateSource(): string that is not a schema in %s.php on line %d + +Warning: DOMDocument::schemaValidateSource(): ^ in %s.php on line %d + +Warning: DOMDocument::schemaValidateSource(): Failed to parse the XML resource 'in_memory_buffer'. in %s.php on line %d + +Warning: DOMDocument::schemaValidateSource(): Invalid Schema in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt new file mode 100755 index 000000000..41a833b5a --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error2.phpt @@ -0,0 +1,23 @@ +--TEST-- +DomDocument::schemaValidateSource() - non-conforming schema +--CREDITS-- +Daniel Convissor +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +$xsd = file_get_contents(dirname(__FILE__)."/book-non-conforming-schema.xsd"); + +$result = $doc->schemaValidateSource($xsd); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidateSource(): Element 'books': No matching global declaration available for the validation root. in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt new file mode 100755 index 000000000..93dd79260 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error3.phpt @@ -0,0 +1,21 @@ +--TEST-- +DomDocument::schemaValidateSource() - empty string for schema string +--CREDITS-- +Daniel Convissor +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidateSource(''); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidateSource(): Invalid Schema source in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt b/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt new file mode 100755 index 000000000..65c8d8678 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidateSource_error4.phpt @@ -0,0 +1,21 @@ +--TEST-- +DomDocument::schemaValidateSource() - pass no parameters +--CREDITS-- +Daniel Convissor +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidateSource(); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidateSource() expects exactly 1 parameter, 0 given in %s.php on line %d +NULL diff --git a/ext/dom/tests/DOMDocument_schemaValidate_basic.phpt b/ext/dom/tests/DOMDocument_schemaValidate_basic.phpt new file mode 100755 index 000000000..eec790de6 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidate_basic.phpt @@ -0,0 +1,20 @@ +--TEST-- +DomDocument::schemaValidate() - basic +--CREDITS-- +Daniel Convissor +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidate(dirname(__FILE__)."/book.xsd"); +var_dump($result); + +?> +--EXPECT-- +bool(true) diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt new file mode 100755 index 000000000..594c3c429 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidate_error1.phpt @@ -0,0 +1,29 @@ +--TEST-- +DomDocument::schemaValidate() - file that is not a schema +--CREDITS-- +Daniel Convissor +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidate(dirname(__FILE__)."/book-not-a-schema.xsd"); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidate(): %sbook-not-a-schema.xsd:1: parser error : Start tag expected, '<' not found in %s.php on line %d + +Warning: DOMDocument::schemaValidate(): Let's see what happens upon parsing a file that doesn't contain a schema. in %s.php on line %d + +Warning: DOMDocument::schemaValidate(): ^ in %s.php on line %d + +Warning: DOMDocument::schemaValidate(): Failed to parse the XML resource '%sbook-not-a-schema.xsd'. in %s.php on line %d + +Warning: DOMDocument::schemaValidate(): Invalid Schema in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt new file mode 100755 index 000000000..5ffd53365 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidate_error2.phpt @@ -0,0 +1,21 @@ +--TEST-- +DomDocument::schemaValidate() - non-conforming schema file +--CREDITS-- +Daniel Convissor +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidate(dirname(__FILE__)."/book-non-conforming-schema.xsd"); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidate(): Element 'books': No matching global declaration available for the validation root. in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt new file mode 100755 index 000000000..275204f92 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidate_error3.phpt @@ -0,0 +1,21 @@ +--TEST-- +DomDocument::schemaValidate() - empty string for schema file name +--CREDITS-- +Daniel Convissor +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidate(''); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidate(): Invalid Schema source in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt new file mode 100755 index 000000000..d4817deca --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidate_error4.phpt @@ -0,0 +1,21 @@ +--TEST-- +DomDocument::schemaValidate() - pass no parameters +--CREDITS-- +Daniel Convissor +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidate(); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidate() expects exactly 1 parameter, 0 given in %s.php on line %d +NULL diff --git a/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt b/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt new file mode 100755 index 000000000..d3f0658c1 --- /dev/null +++ b/ext/dom/tests/DOMDocument_schemaValidate_error5.phpt @@ -0,0 +1,25 @@ +--TEST-- +DomDocument::schemaValidate() - non-existant schema file +--CREDITS-- +Daniel Convissor +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +$result = $doc->schemaValidate(dirname(__FILE__)."/non-existant-file"); +var_dump($result); + +?> +--EXPECTF-- +Warning: DOMDocument::schemaValidate(): I/O warning : failed to load external entity "%snon-existant-file" in %s.php on line %d + +Warning: DOMDocument::schemaValidate(): Failed to locate the main schema resource at '%s/non-existant-file'. in %s.php on line %d + +Warning: DOMDocument::schemaValidate(): Invalid Schema in %s.php on line %d +bool(false) diff --git a/ext/dom/tests/DOMDocument_standalone_basic.phpt b/ext/dom/tests/DOMDocument_standalone_basic.phpt new file mode 100644 index 000000000..2316a3897 --- /dev/null +++ b/ext/dom/tests/DOMDocument_standalone_basic.phpt @@ -0,0 +1,48 @@ +--TEST-- +Tests DOMDocument::standalone get, set, and functionality +--CREDITS-- +Chris Snyder +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- + + +foo'; +$dom->loadXML($xml); +if(!$dom) { + echo "Error while parsing the document\n"; + exit; +} +echo "Standalone DOMDocument created\n"; + +$test = $dom->standalone; +echo "Read initial standalone:\n"; +var_dump( $test ); + +$dom->standalone = FALSE; +$test = $dom->standalone; +echo "Set standalone to FALSE, reading again:\n"; +var_dump( $test ); + +$test = $dom->saveXML(); +echo "Document is no longer standalone\n"; +var_dump( $test ); + +echo "Done"; +?> +--EXPECT-- +Standalone DOMDocument created +Read initial standalone: +bool(true) +Set standalone to FALSE, reading again: +bool(false) +Document is no longer standalone +string(136) " + +foo +" +Done \ No newline at end of file diff --git a/ext/dom/tests/DOMDocument_strictErrorChecking_basic.phpt b/ext/dom/tests/DOMDocument_strictErrorChecking_basic.phpt new file mode 100644 index 000000000..9ad55a4ad --- /dev/null +++ b/ext/dom/tests/DOMDocument_strictErrorChecking_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +DomDocument::$strictErrorChecking - basic test +--CREDITS-- +Vincent Tsao +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +var_dump($doc->strictErrorChecking); + +$doc->strictErrorChecking = false; +var_dump($doc->strictErrorChecking); + +?> +--EXPECT-- +bool(true) +bool(false) diff --git a/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt b/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt new file mode 100644 index 000000000..b6d94f9de --- /dev/null +++ b/ext/dom/tests/DOMDocument_strictErrorChecking_variation.phpt @@ -0,0 +1,59 @@ +--TEST-- +DomDocument::$strictErrorChecking - ensure turning off actually works +--CREDITS-- +Vincent Tsao +(and Dan Convissor) +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__)."/book.xml"); + +echo "See if strictErrorChecking is on\n"; +var_dump($doc->strictErrorChecking); + +echo "Should throw DOMException when strictErrorChecking is on\n"; +try { + $attr = $doc->createAttribute(0); +} catch (DOMException $e) { + echo "GOOD. DOMException thrown\n"; + echo $e->getMessage() ."\n"; +} catch (Exception $e) { + echo "OOPS. Other exception thrown\n"; +} + + +echo "Turn strictErrorChecking off\n"; +$doc->strictErrorChecking = false; + +echo "See if strictErrorChecking is off\n"; +var_dump($doc->strictErrorChecking); + +echo "Should raise PHP error because strictErrorChecking is off\n"; +try { + $attr = $doc->createAttribute(0); +} catch (DOMException $e) { + echo "OOPS. DOMException thrown\n"; + echo $e->getMessage() ."\n"; +} catch (Exception $e) { + echo "OOPS. Other exception thrown\n"; +} + +?> +--EXPECTF-- +Load document +See if strictErrorChecking is on +bool(true) +Should throw DOMException when strictErrorChecking is on +GOOD. DOMException thrown +Invalid Character Error +Turn strictErrorChecking off +See if strictErrorChecking is off +bool(false) +Should raise PHP error because strictErrorChecking is off + +Warning: DOMDocument::createAttribute(): Invalid Character Error in %sDOMDocument_strictErrorChecking_variation.php on line %d diff --git a/ext/dom/tests/DOMDocument_validate_basic.phpt b/ext/dom/tests/DOMDocument_validate_basic.phpt new file mode 100644 index 000000000..7c0eec8dd --- /dev/null +++ b/ext/dom/tests/DOMDocument_validate_basic.phpt @@ -0,0 +1,31 @@ +--TEST-- +DOMDocument::validate() should validate an internal DTD declaration +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- + + + + + + +]> + +Tove +Jani +Reminder +Don't forget me this weekend +"; +$dom = new DOMDocument('1.0'); +$dom->loadXML($xml); +var_dump($dom->validate()); +?> +--EXPECTF-- +bool(true) diff --git a/ext/dom/tests/DOMDocument_validate_error1.phpt b/ext/dom/tests/DOMDocument_validate_error1.phpt new file mode 100644 index 000000000..8e1e72fe0 --- /dev/null +++ b/ext/dom/tests/DOMDocument_validate_error1.phpt @@ -0,0 +1,16 @@ +--TEST-- +DOMDocument::validate() should fail if any parameter is given +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- +validate(true); +?> +--EXPECTF-- +Warning: DOMDocument::validate() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/dom/tests/DOMDocument_validate_error2.phpt b/ext/dom/tests/DOMDocument_validate_error2.phpt new file mode 100644 index 000000000..fe7e4fc9d --- /dev/null +++ b/ext/dom/tests/DOMDocument_validate_error2.phpt @@ -0,0 +1,15 @@ +--TEST-- +DOMDocument::validate() should fail if called statically +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Fatal error: Non-static method DOMDocument::validate() cannot be called statically in %s on line %d diff --git a/ext/dom/tests/DOMDocument_validate_external_dtd.phpt b/ext/dom/tests/DOMDocument_validate_external_dtd.phpt new file mode 100644 index 000000000..51a044c54 --- /dev/null +++ b/ext/dom/tests/DOMDocument_validate_external_dtd.phpt @@ -0,0 +1,19 @@ +--TEST-- +DOMDocument::validate() should validate an external DTD declaration +--CREDITS-- +Knut Urdalen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- +load(dirname(__FILE__).'/dom.xml'); +var_dump($dom->validate()); +?> +--EXPECTF-- +bool(true) diff --git a/ext/dom/tests/DOMDocument_validate_on_parse_basic.phpt b/ext/dom/tests/DOMDocument_validate_on_parse_basic.phpt new file mode 100644 index 000000000..a95b0a304 --- /dev/null +++ b/ext/dom/tests/DOMDocument_validate_on_parse_basic.phpt @@ -0,0 +1,38 @@ +--TEST-- +DOMDocument::$validateOnParse - read/write tests (dom_document_validate_on_parse_read/dom_document_validate_on_parse_write) +--CREDITS-- +Hans Zaunere +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +loadXML($xmlstr); + +if( !$dom ) +{ + echo "Error while parsing the document\n"; + exit; +} + +echo "Checking documented default value: "; +var_dump($dom->validateOnParse); + +$dom->validateOnParse = TRUE; +echo "Setting validateOnParse to TRUE: "; +var_dump($dom->validateOnParse); + +$dom->validateOnParse = FALSE; +echo "Setting validateOnParse to FALSE: "; +var_dump($dom->validateOnParse); + +?> +--EXPECT-- +Checking documented default value: bool(false) +Setting validateOnParse to TRUE: bool(true) +Setting validateOnParse to FALSE: bool(false) + diff --git a/ext/dom/tests/DOMDocument_validate_on_parse_variation.phpt b/ext/dom/tests/DOMDocument_validate_on_parse_variation.phpt new file mode 100644 index 000000000..6aa390ca9 --- /dev/null +++ b/ext/dom/tests/DOMDocument_validate_on_parse_variation.phpt @@ -0,0 +1,49 @@ +--TEST-- +DOMDocument::$validateOnParse - effectual determination (dom_document_validate_on_parse_read/dom_document_validate_on_parse_write) +--CREDITS-- +Hans Zaunere +# TestFest 2009 NYPHP +--SKIPIF-- + +--FILE-- +resolveExternals = TRUE; + +$dom->validateOnParse = FALSE; +echo "validateOnParse set to FALSE: \n"; +$dom->loadXML($XMLStringGood); +echo "No Error Report Above\n"; + +$BogusElement = $dom->createElement('NYPHP','DOMinatrix'); +$Body = $dom->getElementsByTagName('body')->item(0); +$Body->appendChild($BogusElement); +$XMLStringBad = $dom->saveXML(); + +echo "validateOnParse set to TRUE: \n"; +$dom->validateOnParse = TRUE; +$dom->loadXML($XMLStringBad); +echo "Error Report Above\n"; + +?> +--EXPECTF-- +validateOnParse set to FALSE: +No Error Report Above +validateOnParse set to TRUE: + +Warning: DOMDocument::loadXML(): No declaration for element NYPHP in Entity, line: %d in %s on line %d + +Warning: DOMDocument::loadXML(): Element body content does not follow the DTD, expecting (p | h1 | h2 | h3 | h4 | h5 | h6 | div | ul | ol | dl | pre | hr | blockquote | address | fieldset | table | form | noscript | ins | del | script)*, got (div div div div div NYPHP) in Entity, line: %d in %s on line %d +Error Report Above + diff --git a/ext/dom/tests/book-non-conforming-schema.xsd b/ext/dom/tests/book-non-conforming-schema.xsd new file mode 100755 index 000000000..d1ecbef01 --- /dev/null +++ b/ext/dom/tests/book-non-conforming-schema.xsd @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/ext/dom/tests/book-not-a-schema.xsd b/ext/dom/tests/book-not-a-schema.xsd new file mode 100755 index 000000000..d89e3bbac --- /dev/null +++ b/ext/dom/tests/book-not-a-schema.xsd @@ -0,0 +1 @@ +Let's see what happens upon parsing a file that doesn't contain a schema. diff --git a/ext/dom/tests/book.xsd b/ext/dom/tests/book.xsd new file mode 100755 index 000000000..45986fc4b --- /dev/null +++ b/ext/dom/tests/book.xsd @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/ext/dom/tests/domdocument_createcomment_error_001.phpt b/ext/dom/tests/domdocument_createcomment_error_001.phpt new file mode 100644 index 000000000..5df4e2047 --- /dev/null +++ b/ext/dom/tests/domdocument_createcomment_error_001.phpt @@ -0,0 +1,11 @@ +--TEST-- +DomDocument::CreateComment() - Incorrect Parameters +--CREDITS-- +Clint Priest @ PhpTek09 +--FILE-- +createComment(); +?> +--EXPECTF-- +Warning: DOMDocument::createComment() expects exactly 1 parameter, 0 given in %s \ No newline at end of file diff --git a/ext/dom/tests/domdocument_createentityreference_001.phpt b/ext/dom/tests/domdocument_createentityreference_001.phpt new file mode 100644 index 000000000..15f7df188 --- /dev/null +++ b/ext/dom/tests/domdocument_createentityreference_001.phpt @@ -0,0 +1,13 @@ +--TEST-- +DomDocument::CreateEntityReference() - Creates an entity reference with the appropriate name +--CREDITS-- +Clint Priest @ PhpTek09 +--FILE-- +createEntityReference('Test'); + echo $objRef->nodeName; +?> +--EXPECT-- +Test \ No newline at end of file diff --git a/ext/dom/tests/domdocument_createentityreference_002.phpt b/ext/dom/tests/domdocument_createentityreference_002.phpt new file mode 100644 index 000000000..21d79aa4b --- /dev/null +++ b/ext/dom/tests/domdocument_createentityreference_002.phpt @@ -0,0 +1,12 @@ +--TEST-- +DomDocument::CreateEntityReference() - Empty Arguments +--CREDITS-- +Clint Priest @ PhpTek09 +--FILE-- +createEntityReference(); +?> +--EXPECTF-- +Warning: DOMDocument::createEntityReference() expects exactly 1 parameter, 0 given in %s \ No newline at end of file diff --git a/ext/dom/text.c b/ext/dom/text.c index c9073ea30..c658e1b76 100644 --- a/ext/dom/text.c +++ b/ext/dom/text.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: text.c,v 1.23.2.1.2.4.2.12 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: text.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/typeinfo.c b/ext/dom/typeinfo.c index f7e65a3eb..7c42f906e 100644 --- a/ext/dom/typeinfo.c +++ b/ext/dom/typeinfo.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: typeinfo.c,v 1.6.2.1.2.1.2.4 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: typeinfo.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/userdatahandler.c b/ext/dom/userdatahandler.c index 06979edc9..2b761d78e 100644 --- a/ext/dom/userdatahandler.c +++ b/ext/dom/userdatahandler.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: userdatahandler.c,v 1.6.2.1.2.1.2.4 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: userdatahandler.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/dom/xml_common.h b/ext/dom/xml_common.h index b574fd492..9c3c6fc24 100644 --- a/ext/dom/xml_common.h +++ b/ext/dom/xml_common.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xml_common.h,v 1.23.2.1.2.2.2.4 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: xml_common.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_XML_COMMON_H #define PHP_XML_COMMON_H diff --git a/ext/dom/xpath.c b/ext/dom/xpath.c index 38d23da94..a2fdc13dc 100644 --- a/ext/dom/xpath.c +++ b/ext/dom/xpath.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xpath.c,v 1.26.2.1.2.1.2.13 2009/06/06 02:40:48 mattwil Exp $ */ +/* $Id: xpath.c 281742 2009-06-06 02:40:49Z mattwil $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/enchant/config.m4 b/ext/enchant/config.m4 index f52689adb..8a36ee83c 100755 --- a/ext/enchant/config.m4 +++ b/ext/enchant/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.1 2004/03/08 20:12:12 pajoye Exp $ +dnl $Id: config.m4 289597 2009-10-12 22:35:36Z pajoye $ dnl PHP_ARG_WITH(enchant,for ENCHANT support, @@ -33,4 +33,10 @@ if test "$PHP_ENCHANT" != "no"; then PHP_SUBST(ENCHANT_SHARED_LIBADD) PHP_ADD_LIBRARY_WITH_PATH(enchant, $ENCHANT_LIBDIR, ENCHANT_SHARED_LIBADD) PHP_ADD_INCLUDE($ENCHANT_INCDIR) + PHP_CHECK_LIBRARY(enchant, enchant_broker_set_param, + [ + AC_DEFINE(HAVE_ENCHANT_BROKER_SET_PARAM, 1, [ ]) + AC_DEFINE(ENCHANT_VERSION_STRING, "1.5.x", [ ]) + ], [], [ -L$ENCHANT_LIB $ENCHANT_SHARED_LIBADD]) + fi diff --git a/ext/enchant/config.w32 b/ext/enchant/config.w32 index 99a46731f..f36b7c8e9 100644 --- a/ext/enchant/config.w32 +++ b/ext/enchant/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.3 2009/01/13 13:30:30 pajoye Exp $ +// $Id: config.w32 289597 2009-10-12 22:35:36Z pajoye $ // vim:ft=javascript ARG_WITH("enchant", "Enchant Support", "no"); @@ -9,6 +9,7 @@ if (PHP_ENCHANT == "yes") { CHECK_LIB("libenchant.lib", "enchant", PHP_ENCHANT) ) { EXTENSION("enchant", "enchant.c"); AC_DEFINE('HAVE_ENCHANT', 1, 'Have Enchant support', false); + AC_DEFINE('HAVE_ENCHANT_BROKER_SET_PARAM', 1); ADD_FLAG("CFLAG_ENCHANT", "/D _WIN32"); } else { WARNING('Could not find enchant.h; skipping'); diff --git a/ext/enchant/docs/examples/example1.php b/ext/enchant/docs/examples/example1.php index 9d503f74e..048cc83a1 100644 --- a/ext/enchant/docs/examples/example1.php +++ b/ext/enchant/docs/examples/example1.php @@ -13,7 +13,7 @@ if (enchant_broker_dict_exists($r,$tag)) { $spellerrors = enchant_dict_check($d, "soong"); print_r($dprovides); echo "found $spellerrors spell errors\n"; - if ($spellerrors) { + if (spellerrors) { $suggs = enchant_dict_suggest($d, "soong"); echo "Suggestions for 'soong':"; print_r($suggs); diff --git a/ext/enchant/enchant.c b/ext/enchant/enchant.c index 7c95bf6c7..1a003aa10 100755 --- a/ext/enchant/enchant.c +++ b/ext/enchant/enchant.c @@ -16,23 +16,19 @@ | Ilia Alshanetsky | +----------------------------------------------------------------------+ - $Id: enchant.c,v 1.19.2.3 2009/01/30 00:16:32 felipe Exp $ + $Id: enchant.c 289597 2009-10-12 22:35:36Z pajoye $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif -#ifdef PHP_WIN32 -#include -#include -#endif + #include #include "php.h" #include "php_ini.h" #include "ext/standard/info.h" #include "php_enchant.h" - typedef EnchantBroker * EnchantBrokerPtr; typedef struct _broker_struct enchant_broker; typedef struct _dict_struct enchant_dict; @@ -64,6 +60,9 @@ static int le_enchant_dict; /* If you declare any globals in php_enchant.h uncomment this:*/ /*ZEND_DECLARE_MODULE_GLOBALS(enchant)*/ +#define PHP_ENCHANT_MYSPELL 1 +#define PHP_ENCHANT_ISPELL 2 + /* {{{ arginfo */ ZEND_BEGIN_ARG_INFO(arginfo_enchant_broker_init, 0) ZEND_END_ARG_INFO() @@ -72,6 +71,17 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_free, 0, 0, 1) ZEND_ARG_INFO(0, broker) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_set_dict_path, 0, 0, 3) + ZEND_ARG_INFO(0, broker) + ZEND_ARG_INFO(0, name) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_get_dict_path, 0, 0, 2) + ZEND_ARG_INFO(0, broker) + ZEND_ARG_INFO(0, name) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_enchant_broker_request_dict, 0, 0, 2) ZEND_ARG_INFO(0, broker) ZEND_ARG_INFO(0, tag) @@ -118,6 +128,8 @@ function_entry enchant_functions[] = { PHP_FE(enchant_broker_init, arginfo_enchant_broker_init) PHP_FE(enchant_broker_free, arginfo_enchant_broker_free) PHP_FE(enchant_broker_get_error, arginfo_enchant_broker_free) + PHP_FE(enchant_broker_set_dict_path, arginfo_enchant_broker_set_dict_path) + PHP_FE(enchant_broker_get_dict_path, arginfo_enchant_broker_get_dict_path) PHP_FE(enchant_broker_list_dicts, arginfo_enchant_broker_free) PHP_FE(enchant_broker_request_dict, arginfo_enchant_broker_request_dict) PHP_FE(enchant_broker_request_pwl_dict, arginfo_enchant_broker_request_pwl_dict) @@ -277,7 +289,8 @@ PHP_MINIT_FUNCTION(enchant) { le_enchant_broker = zend_register_list_destructors_ex(php_enchant_broker_free, NULL, "enchant_broker", module_number); le_enchant_dict = zend_register_list_destructors_ex(php_enchant_dict_free, NULL, "enchant_dict", module_number); - + REGISTER_LONG_CONSTANT("ENCHANT_MYSPELL", PHP_ENCHANT_MYSPELL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("ENCHANT_ISPELL", PHP_ENCHANT_ISPELL, CONST_CS | CONST_PERSISTENT); return SUCCESS; } /* }}} */ @@ -309,7 +322,12 @@ PHP_MINFO_FUNCTION(enchant) php_info_print_table_start(); php_info_print_table_header(2, "enchant support", "enabled"); php_info_print_table_row(2, "Version", PHP_ENCHANT_VERSION); - php_info_print_table_row(2, "Revision", "$Revision: 1.19.2.3 $"); +#ifdef ENCHANT_VERSION_STRING + php_info_print_table_row(2, "Libenchant Version", ENCHANT_VERSION_STRING); +#elif defined(HAVE_ENCHANT_BROKER_SET_PARAM) + php_info_print_table_row(2, "Libenchant Version", "1.5.0 or later"); +#endif + php_info_print_table_row(2, "Revision", "$Revision: 289597 $"); php_info_print_table_end(); php_info_print_table_start(); @@ -397,15 +415,101 @@ PHP_FUNCTION(enchant_broker_get_error) } /* }}} */ +#if HAVE_ENCHANT_BROKER_SET_PARAM +/* {{{ proto bool enchant_broker_set_dict_path(resource broker, int dict_type, string value) + Set the directory path for a given backend, works with ispell and myspell */ +PHP_FUNCTION(enchant_broker_set_dict_path) +{ + zval *broker; + enchant_broker *pbroker; + long dict_type; + char *value; + int value_len; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rls", &broker, &dict_type, &value, &value_len) == FAILURE) { + RETURN_FALSE; + } + + if (!value_len) { + RETURN_FALSE; + } + + switch (dict_type) { + case PHP_ENCHANT_MYSPELL: + PHP_ENCHANT_GET_BROKER; + enchant_broker_set_param(pbroker->pbroker, "enchant.myspell.dictionary.path", (const char *)value); + RETURN_TRUE; + break; + + case PHP_ENCHANT_ISPELL: + PHP_ENCHANT_GET_BROKER; + enchant_broker_set_param(pbroker->pbroker, "enchant.ispell.dictionary.path", (const char *)value); + RETURN_TRUE; + break; + + default: + RETURN_FALSE; + } +} +/* }}} */ + + +/* {{{ proto string enchant_broker_get_dict_path(resource broker, int dict_type) + Get the directory path for a given backend, works with ispell and myspell */ +PHP_FUNCTION(enchant_broker_get_dict_path) +{ + zval *broker; + enchant_broker *pbroker; + long dict_type; + char *value; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &broker, &dict_type) == FAILURE) { + RETURN_FALSE; + } + + switch (dict_type) { + case PHP_ENCHANT_MYSPELL: + PHP_ENCHANT_GET_BROKER; + value = enchant_broker_get_param(pbroker->pbroker, "enchant.myspell.dictionary.path"); + break; + + case PHP_ENCHANT_ISPELL: + PHP_ENCHANT_GET_BROKER; + value = enchant_broker_get_param(pbroker->pbroker, "enchant.ispell.dictionary.path"); + break; + + default: + RETURN_FALSE; + } + + RETURN_STRING(value, 1); +} +/* }}} */ +#else +/* {{{ proto bool enchant_broker_set_dict_path(resource broker, int dict_type, string value) + Set the directory path for a given backend, works with ispell and myspell */ +PHP_FUNCTION(enchant_broker_set_dict_path) +{ + RETURN_FALSE; +} +/* }}} */ + + +/* {{{ proto string enchant_broker_get_dict_path(resource broker, int dict_type) + Get the directory path for a given backend, works with ispell and myspell */ +PHP_FUNCTION(enchant_broker_get_dict_path) +{ + RETURN_FALSE; +} +/* }}} */ +#endif + /* {{{ proto string enchant_broker_list_dicts(resource broker) Lists the dictionaries available for the given broker */ PHP_FUNCTION(enchant_broker_list_dicts) { zval *broker; enchant_broker *pbroker; - EnchantDictDescribeFn describetozval = php_enchant_list_dicts_fn; - - char *msg; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &broker) == FAILURE) { RETURN_FALSE; diff --git a/ext/enchant/php_enchant.h b/ext/enchant/php_enchant.h index 1b8712fbb..0f27db94e 100644 --- a/ext/enchant/php_enchant.h +++ b/ext/enchant/php_enchant.h @@ -15,7 +15,7 @@ | Author: Pierre-Alain Joye | +----------------------------------------------------------------------+ - $Id: php_enchant.h,v 1.4.2.1 2009/01/30 00:16:32 felipe Exp $ + $Id: php_enchant.h 289597 2009-10-12 22:35:36Z pajoye $ */ #ifndef PHP_ENCHANT_H @@ -24,7 +24,7 @@ extern zend_module_entry enchant_module_entry; #define phpext_enchant_ptr &enchant_module_entry -#define PHP_ENCHANT_VERSION "1.0.2-dev" +#define PHP_ENCHANT_VERSION "1.1.0" #ifdef PHP_WIN32 #define PHP_ENCHANT_API __declspec(dllexport) @@ -36,9 +36,6 @@ extern zend_module_entry enchant_module_entry; #include "TSRM.h" #endif -static void php_enchant_broker_free(zend_rsrc_list_entry *rsrc TSRMLS_DC); -static void php_enchant_dict_free(zend_rsrc_list_entry *rsrc TSRMLS_DC); - PHP_MINIT_FUNCTION(enchant); PHP_MSHUTDOWN_FUNCTION(enchant); PHP_MINFO_FUNCTION(enchant); @@ -46,6 +43,8 @@ PHP_MINFO_FUNCTION(enchant); PHP_FUNCTION(enchant_broker_init); PHP_FUNCTION(enchant_broker_free); PHP_FUNCTION(enchant_broker_get_error); +PHP_FUNCTION(enchant_broker_set_dict_path); +PHP_FUNCTION(enchant_broker_get_dict_path); PHP_FUNCTION(enchant_broker_list_dicts); PHP_FUNCTION(enchant_broker_request_dict); PHP_FUNCTION(enchant_broker_request_pwl_dict); diff --git a/ext/ereg/config.w32 b/ext/ereg/config.w32 index c153187ef..0ea887e44 100644 --- a/ext/ereg/config.w32 +++ b/ext/ereg/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.2.2.3 2008/05/14 03:13:16 auroraeosrose Exp $ +// $Id: config.w32 259731 2008-05-14 03:13:17Z auroraeosrose $ // vim:ft=javascript ARG_WITH("ereg", "POSIX extended regular expressions", "yes"); diff --git a/ext/ereg/config0.m4 b/ext/ereg/config0.m4 index 59f2d2798..b2cd27916 100644 --- a/ext/ereg/config0.m4 +++ b/ext/ereg/config0.m4 @@ -1,4 +1,4 @@ -dnl $Id: config0.m4,v 1.2.2.2 2007/10/05 15:00:05 jani Exp $ +dnl $Id: config0.m4 243563 2007-10-05 15:00:09Z jani $ dnl config.m4 for extension ereg dnl diff --git a/ext/ereg/ereg.c b/ext/ereg/ereg.c index 29a9b9443..7298626fa 100644 --- a/ext/ereg/ereg.c +++ b/ext/ereg/ereg.c @@ -17,7 +17,7 @@ | Jaakko Hyvtti | +----------------------------------------------------------------------+ */ -/* $Id: ereg.c,v 1.90.2.13 2009/05/28 21:57:24 scottmac Exp $ */ +/* $Id: ereg.c 281350 2009-05-28 21:57:24Z scottmac $ */ #include #include diff --git a/ext/ereg/php_ereg.h b/ext/ereg/php_ereg.h index 70edbbea4..28fd54d72 100644 --- a/ext/ereg/php_ereg.h +++ b/ext/ereg/php_ereg.h @@ -17,7 +17,7 @@ */ -/* $Id: php_ereg.h,v 1.24.2.5 2009/05/28 21:57:24 scottmac Exp $ */ +/* $Id: php_ereg.h 281350 2009-05-28 21:57:24Z scottmac $ */ #ifndef EREG_H #define EREG_H diff --git a/ext/ereg/php_regex.h b/ext/ereg/php_regex.h index 810ecafbf..2ff44a575 100644 --- a/ext/ereg/php_regex.h +++ b/ext/ereg/php_regex.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_regex.h,v 1.20.2.4 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: php_regex.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_REGEX_H #define PHP_REGEX_H diff --git a/ext/ereg/regex/regex.dsw b/ext/ereg/regex/regex.dsw index 24509212d..7b7df8126 100644 --- a/ext/ereg/regex/regex.dsw +++ b/ext/ereg/regex/regex.dsw @@ -1,29 +1,29 @@ -Microsoft Developer Studio Workspace File, Format Version 5.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "regex"=.\regex.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - +Microsoft Developer Studio Workspace File, Format Version 5.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "regex"=.\regex.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/ext/exif/config.m4 b/ext/exif/config.m4 index 633cb4a44..6d1d8c5b2 100644 --- a/ext/exif/config.m4 +++ b/ext/exif/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.8 2002/09/19 20:14:34 derick Exp $ +dnl $Id: config.m4 96181 2002-09-19 20:14:35Z derick $ dnl PHP_ARG_ENABLE(exif, whether to enable EXIF (metadata from images) support, diff --git a/ext/exif/config.w32 b/ext/exif/config.w32 index 8efa93b00..f39ef74b1 100644 --- a/ext/exif/config.w32 +++ b/ext/exif/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.3.6.1 2008/06/23 18:40:28 pajoye Exp $ +// $Id: config.w32 261548 2008-06-23 18:40:29Z pajoye $ // vim:ft=javascript ARG_ENABLE("exif", "exif", "no"); diff --git a/ext/exif/example.php b/ext/exif/example.php index 8f6e31fb9..fb9b5ad3e 100644 --- a/ext/exif/example.php +++ b/ext/exif/example.php @@ -1,7 +1,7 @@ diff --git a/ext/exif/exif.c b/ext/exif/exif.c index 96358f22e..f03c3c173 100644 --- a/ext/exif/exif.c +++ b/ext/exif/exif.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: exif.c,v 1.173.2.5.2.20.2.16 2009/06/12 14:03:35 felipe Exp $ */ +/* $Id: exif.c 287372 2009-08-16 14:32:32Z iliaa $ */ /* ToDos * @@ -138,7 +138,7 @@ const zend_function_entry exif_functions[] = { }; /* }}} */ -#define EXIF_VERSION "1.4 $Id: exif.c,v 1.173.2.5.2.20.2.16 2009/06/12 14:03:35 felipe Exp $" +#define EXIF_VERSION "1.4 $Id: exif.c 287372 2009-08-16 14:32:32Z iliaa $" /* {{{ PHP_MINFO_FUNCTION */ @@ -3238,7 +3238,7 @@ static void exif_process_APP1(image_info_type *ImageInfo, char *CharBuf, size_t { /* Check the APP1 for Exif Identifier Code */ static const uchar ExifHeader[] = {0x45, 0x78, 0x69, 0x66, 0x00, 0x00}; - if (memcmp(CharBuf+2, ExifHeader, 6)) { + if (length <= 8 || memcmp(CharBuf+2, ExifHeader, 6)) { exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Incorrect APP1 Exif Identifier Code"); return; } @@ -3321,8 +3321,14 @@ static int exif_scan_JPEG_header(image_info_type *ImageInfo TSRMLS_DC) } /* Read the length of the section. */ - lh = php_stream_getc(ImageInfo->infile); - ll = php_stream_getc(ImageInfo->infile); + if ((lh = php_stream_getc(ImageInfo->infile)) == EOF) { + EXIF_ERRLOG_CORRUPT(ImageInfo) + return FALSE; + } + if ((ll = php_stream_getc(ImageInfo->infile)) == EOF) { + EXIF_ERRLOG_CORRUPT(ImageInfo) + return FALSE; + } itemlen = (lh << 8) | ll; @@ -3522,6 +3528,10 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse int entry_tag , entry_type; tag_table_type tag_table = exif_get_tag_table(section_index); + if (ImageInfo->ifd_nesting_level > MAX_IFD_NESTING_LEVEL) { + return FALSE; + } + if (ImageInfo->FileSize >= dir_offset+2) { sn = exif_file_sections_add(ImageInfo, M_PSEUDO, 2, NULL); #ifdef EXIF_DEBUG @@ -3665,6 +3675,7 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse #ifdef EXIF_DEBUG exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Next IFD: %s @x%04X", exif_get_sectionname(sub_section_index), entry_offset); #endif + ImageInfo->ifd_nesting_level++; exif_process_IFD_in_TIFF(ImageInfo, entry_offset, sub_section_index TSRMLS_CC); if (section_index!=SECTION_THUMBNAIL && entry_tag==TAG_SUB_IFD) { if (ImageInfo->Thumbnail.filetype != IMAGE_FILETYPE_UNKNOWN @@ -3704,6 +3715,7 @@ static int exif_process_IFD_in_TIFF(image_info_type *ImageInfo, size_t dir_offse #ifdef EXIF_DEBUG exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "Read next IFD (THUMBNAIL) at x%04X", next_offset); #endif + ImageInfo->ifd_nesting_level++; exif_process_IFD_in_TIFF(ImageInfo, next_offset, SECTION_THUMBNAIL TSRMLS_CC); #ifdef EXIF_DEBUG exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_NOTICE, "%s THUMBNAIL @0x%04X + 0x%04X", ImageInfo->Thumbnail.data ? "Ignore" : "Read", ImageInfo->Thumbnail.offset, ImageInfo->Thumbnail.size); @@ -3776,9 +3788,7 @@ static int exif_scan_FILE_header(image_info_type *ImageInfo TSRMLS_DC) } else { exif_error_docref(NULL EXIFERR_CC, ImageInfo, E_WARNING, "Invalid TIFF file"); } - } - else - if (!memcmp(file_header, "MM\x00\x2a", 4)) { + } else if (!memcmp(file_header, "MM\x00\x2a", 4)) { ImageInfo->FileType = IMAGE_FILETYPE_TIFF_MM; ImageInfo->motorola_intel = 1; #ifdef EXIF_DEBUG diff --git a/ext/exif/php_exif.h b/ext/exif/php_exif.h index 49abcb96e..105490e2a 100644 --- a/ext/exif/php_exif.h +++ b/ext/exif/php_exif.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_exif.h,v 1.14.2.1.2.1.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: php_exif.h 272370 2008-12-31 11:15:49Z sebastian $ */ #if HAVE_EXIF extern zend_module_entry exif_module_entry; diff --git a/ext/exif/test.txt b/ext/exif/test.txt index f9d501eca..46703a1fd 100644 --- a/ext/exif/test.txt +++ b/ext/exif/test.txt @@ -4,7 +4,7 @@ * * (c) Marcus Boerger, 2002 * - * $Id: test.txt,v 1.8 2002/03/12 16:43:29 helly Exp $ + * $Id: test.txt 72965 2002-03-12 16:43:29Z helly $ * * Rename the file to test.php and read the instructions. If the * script cannot be executed or does not generate any output check diff --git a/ext/ext_skel_win32.php b/ext/ext_skel_win32.php index ae825c3ee..1675b26be 100644 --- a/ext/ext_skel_win32.php +++ b/ext/ext_skel_win32.php @@ -1,5 +1,5 @@ __tostring) { + ZVAL_FALSE(*value); + return; + } + } + /* Here be strings */ convert_to_string(*value); diff --git a/ext/filter/filter_private.h b/ext/filter/filter_private.h index ee40e0d7c..958169150 100644 --- a/ext/filter/filter_private.h +++ b/ext/filter/filter_private.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: filter_private.h,v 1.12.2.9.2.2 2008/12/31 11:15:36 sebastian Exp $ */ +/* $Id: filter_private.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef FILTER_PRIVATE_H #define FILTER_PRIVATE_H diff --git a/ext/filter/logical_filters.c b/ext/filter/logical_filters.c index e50f54cc1..237ed9d03 100644 --- a/ext/filter/logical_filters.c +++ b/ext/filter/logical_filters.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: logical_filters.c,v 1.1.2.22.2.12 2009/06/10 19:01:17 felipe Exp $ */ +/* $Id: logical_filters.c 284212 2009-07-16 23:29:36Z felipe $ */ #include "php_filter.h" #include "filter_private.h" @@ -472,7 +472,7 @@ void php_filter_validate_url(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ void php_filter_validate_email(PHP_INPUT_FILTER_PARAM_DECL) /* {{{ */ { /* From http://cvs.php.net/co.php/pear/HTML_QuickForm/QuickForm/Rule/Email.php?r=1.4 */ - const char regexp[] = "/^((\\\"[^\\\"\\f\\n\\r\\t\\b]+\\\")|([A-Za-z0-9_\\!\\#\\$\\%\\&\\'\\*\\+\\-\\~\\/\\^\\`\\|\\{\\}]+(\\.[A-Za-z0-9_\\!\\#\\$\\%\\&\\'\\*\\+\\-\\~\\/\\^\\`\\|\\{\\}]*)*))@((\\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9])(([A-Za-z0-9\\-])*([A-Za-z0-9]))?(\\.(?=[A-Za-z\\-]))?)+[A-Za-z\\-]*))$/D"; + const char regexp[] = "/^((\\\"[^\\\"\\f\\n\\r\\t\\b]+\\\")|([A-Za-z0-9_][A-Za-z0-9_\\!\\#\\$\\%\\&\\'\\*\\+\\-\\~\\/\\^\\`\\|\\{\\}]*(\\.[A-Za-z0-9_\\!\\#\\$\\%\\&\\'\\*\\+\\-\\~\\/\\^\\`\\|\\{\\}]*)*))@((\\[(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))\\])|(((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9]))\\.((25[0-5])|(2[0-4][0-9])|([0-1]?[0-9]?[0-9])))|((([A-Za-z0-9])(([A-Za-z0-9\\-])*([A-Za-z0-9]))?(\\.(?=[A-Za-z0-9\\-]))?)+[A-Za-z]+))$/D"; pcre *re = NULL; pcre_extra *pcre_extra = NULL; @@ -529,7 +529,7 @@ static int _php_filter_validate_ipv6(char *str, int str_len TSRMLS_DC) /* {{{ */ int compressed = 0; int blocks = 8; int n; - char *ipv4 = NULL; + char *ipv4; char *end; int ip4elm[4]; char *s = str; @@ -555,24 +555,21 @@ static int _php_filter_validate_ipv6(char *str, int str_len TSRMLS_DC) /* {{{ */ blocks = 6; } - end = ipv4 ? ipv4 : str + str_len; + end = str + str_len; while (str < end) { if (*str == ':') { if (--blocks == 0) { - if ((str+1) == end && ipv4) { - return 1; - } return 0; } if (++str >= end) { - return (ipv4 && ipv4 == str && blocks == 3) || 0; + return 0; } if (*str == ':') { if (compressed || --blocks == 0) { return 0; } - if (++str == end || (ipv4 && ipv4 == str)) { + if (++str == end) { return 1; } compressed = 1; diff --git a/ext/filter/php_filter.h b/ext/filter/php_filter.h index 5b50d0a3b..63416a028 100644 --- a/ext/filter/php_filter.h +++ b/ext/filter/php_filter.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_filter.h,v 1.10.2.2.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_filter.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_FILTER_H #define PHP_FILTER_H diff --git a/ext/filter/sanitizing_filters.c b/ext/filter/sanitizing_filters.c index abebf0ec3..fc0475c64 100644 --- a/ext/filter/sanitizing_filters.c +++ b/ext/filter/sanitizing_filters.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sanitizing_filters.c,v 1.11.2.9.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: sanitizing_filters.c 289438 2009-10-09 17:50:17Z pajoye $ */ #include "php_filter.h" #include "filter_private.h" @@ -275,7 +275,7 @@ void php_filter_unsafe_raw(PHP_INPUT_FILTER_PARAM_DECL) void php_filter_email(PHP_INPUT_FILTER_PARAM_DECL) { /* Check section 6 of rfc 822 http://www.faqs.org/rfcs/rfc822.html */ - const unsigned char allowed_list[] = LOWALPHA HIALPHA DIGIT "!#$%&'*+-/=?^_`{|}~@.[]"; + const unsigned char allowed_list[] = LOWALPHA HIALPHA DIGIT "!#$%&'*+-=?^_`{|}~@.[]"; filter_map map; filter_map_init(&map); diff --git a/ext/filter/tests/016.phpt b/ext/filter/tests/016.phpt index d7e33b800..fbe8f3b3f 100644 --- a/ext/filter/tests/016.phpt +++ b/ext/filter/tests/016.phpt @@ -14,7 +14,12 @@ $values = Array( '@', '[]()/@example.com', 'QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET', -'e.x.a.m.p.l.e.@example.com' +'e.x.a.m.p.l.e.@example.com', +'firstname.lastname@employee.2something.com', +'-@foo.com', +'foo@-.com', +'foo@bar.123', +'foo@bar.-' ); foreach ($values as $value) { var_dump(filter_var($value, FILTER_VALIDATE_EMAIL)); @@ -33,4 +38,9 @@ bool(false) bool(false) string(57) "QWERTYUIOPASDFGHJKLZXCVBNM@QWERTYUIOPASDFGHJKLZXCVBNM.NET" string(26) "e.x.a.m.p.l.e.@example.com" -Done \ No newline at end of file +string(42) "firstname.lastname@employee.2something.com" +bool(false) +bool(false) +bool(false) +bool(false) +Done diff --git a/ext/filter/tests/bug42718.phpt b/ext/filter/tests/bug42718.phpt index 61245ee81..d1ede3f7d 100644 --- a/ext/filter/tests/bug42718.phpt +++ b/ext/filter/tests/bug42718.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #42718 (unsafe_raw filter not applied when configured as default filter) +--XFAIL-- +FILTER_UNSAFE_RAW not applied when configured as default filter, even with flags --SKIPIF-- --INI-- @@ -15,7 +17,6 @@ echo ini_get('filter.default_flags') . "\n"; var_dump(FILTER_FLAG_STRIP_LOW == 4); echo addcslashes($_GET['a'],"\0") . "\n"; ?> ---XFAIL-- --EXPECT-- unsafe_raw 4 diff --git a/ext/filter/tests/bug48762.phpt b/ext/filter/tests/bug48762.phpt new file mode 100644 index 000000000..1737f0a75 --- /dev/null +++ b/ext/filter/tests/bug48762.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #48762 (IPv6 address filter still rejects valid address) +--FILE-- + +--EXPECT-- +string(23) "0b15:23::3:67.98.234.17" +string(19) "::67:78b:34.43.43.2" diff --git a/ext/filter/tests/bug49274.phpt b/ext/filter/tests/bug49274.phpt new file mode 100644 index 000000000..c87e6be1c --- /dev/null +++ b/ext/filter/tests/bug49274.phpt @@ -0,0 +1,10 @@ +--TEST-- +#49274, fatal error when an object does not implement toString +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(false) diff --git a/ext/ftp/config.m4 b/ext/ftp/config.m4 index 3a7bf0794..fb8dd9048 100644 --- a/ext/ftp/config.m4 +++ b/ext/ftp/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.7.20.3 2005/11/01 00:32:21 bfrance Exp $ +dnl $Id: config.m4 199642 2005-11-01 00:32:21Z bfrance $ dnl PHP_ARG_ENABLE(ftp,whether to enable FTP support, diff --git a/ext/ftp/config.w32 b/ext/ftp/config.w32 index 9c663aae7..2b50614b1 100644 --- a/ext/ftp/config.w32 +++ b/ext/ftp/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.1 2003/12/02 23:16:52 wez Exp $ +// $Id: config.w32 242949 2007-09-26 15:44:16Z cvs2svn $ // vim:ft=javascript ARG_ENABLE("ftp", "ftp support", "yes"); diff --git a/ext/ftp/ftp.c b/ext/ftp/ftp.c index 6187f20ec..36c2b0726 100644 --- a/ext/ftp/ftp.c +++ b/ext/ftp/ftp.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: ftp.c,v 1.112.2.4.2.9.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: ftp.c 289416 2009-10-09 14:20:17Z pajoye $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -147,7 +147,7 @@ ftp_open(const char *host, short port, long timeout_sec TSRMLS_DC) size = sizeof(ftp->localaddr); memset(&ftp->localaddr, 0, size); - if (getsockname(ftp->fd, (struct sockaddr*) &ftp->localaddr, &size) == -1) { + if (getsockname(ftp->fd, (struct sockaddr*) &ftp->localaddr, &size) != 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "getsockname failed: %s (%d)", strerror(errno), errno); goto bail; } diff --git a/ext/ftp/ftp.h b/ext/ftp/ftp.h index 3d3b99a06..a8575e29b 100644 --- a/ext/ftp/ftp.h +++ b/ext/ftp/ftp.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: ftp.h,v 1.43.2.1.2.2.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: ftp.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef FTP_H #define FTP_H diff --git a/ext/ftp/php_ftp.c b/ext/ftp/php_ftp.c index 53944491d..57d65ee6f 100644 --- a/ext/ftp/php_ftp.c +++ b/ext/ftp/php_ftp.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ftp.c,v 1.103.2.2.2.2.2.6 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_ftp.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/ftp/php_ftp.h b/ext/ftp/php_ftp.h index 5062a1b8f..cae3f489f 100644 --- a/ext/ftp/php_ftp.h +++ b/ext/ftp/php_ftp.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ftp.h,v 1.29.2.1.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_ftp.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef _INCLUDED_FTP_H #define _INCLUDED_FTP_H diff --git a/ext/ftp/tests/ftp_alloc_basic1.phpt b/ext/ftp/tests/ftp_alloc_basic1.phpt new file mode 100755 index 000000000..b2bdf7440 --- /dev/null +++ b/ext/ftp/tests/ftp_alloc_basic1.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing ftp_alloc returns true +--CREDITS-- +Rodrigo Moyle +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) \ No newline at end of file diff --git a/ext/ftp/tests/ftp_alloc_basic2.phpt b/ext/ftp/tests/ftp_alloc_basic2.phpt new file mode 100755 index 000000000..b9e4253fe --- /dev/null +++ b/ext/ftp/tests/ftp_alloc_basic2.phpt @@ -0,0 +1,23 @@ +--TEST-- +Testing ftp_alloc returns true +--CREDITS-- +Rodrigo Moyle +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) +string(20) "1024 bytes allocated" \ No newline at end of file diff --git a/ext/ftp/tests/ftp_chmod_basic.phpt b/ext/ftp/tests/ftp_chmod_basic.phpt new file mode 100755 index 000000000..baaa25a98 --- /dev/null +++ b/ext/ftp/tests/ftp_chmod_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing ftp_chmod returns file mode +--CREDITS-- +Rodrigo Moyle +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(420) diff --git a/ext/ftp/tests/ftp_exec_basic.phpt b/ext/ftp/tests/ftp_exec_basic.phpt new file mode 100755 index 000000000..4a1f63e38 --- /dev/null +++ b/ext/ftp/tests/ftp_exec_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing ftp_exec returns true +--CREDITS-- +Rodrigo Moyle +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) \ No newline at end of file diff --git a/ext/ftp/tests/ftp_fget_basic1.phpt b/ext/ftp/tests/ftp_fget_basic1.phpt new file mode 100644 index 000000000..475f7183d --- /dev/null +++ b/ext/ftp/tests/ftp_fget_basic1.phpt @@ -0,0 +1,32 @@ +--TEST-- +Testing ftp_fget ignore autoresume if autoseek is switched off +--CREDITS-- +Rodrigo Moyle +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +string(12) "ASCIIFooBar +" diff --git a/ext/ftp/tests/ftp_fget_basic2.phpt b/ext/ftp/tests/ftp_fget_basic2.phpt new file mode 100644 index 000000000..00a26752d --- /dev/null +++ b/ext/ftp/tests/ftp_fget_basic2.phpt @@ -0,0 +1,32 @@ +--TEST-- +Testing ftp_fget autoresume +--CREDITS-- +Rodrigo Moyle +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +string(12) "ASCIIFooBar +" diff --git a/ext/ftp/tests/ftp_fget_basic3.phpt b/ext/ftp/tests/ftp_fget_basic3.phpt new file mode 100644 index 000000000..b7098701a --- /dev/null +++ b/ext/ftp/tests/ftp_fget_basic3.phpt @@ -0,0 +1,32 @@ +--TEST-- +Testing ftp_fget resume parameter +--CREDITS-- +Rodrigo Moyle +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECT-- +bool(true) +string(12) "ASCIIFooBar +" diff --git a/ext/ftp/tests/ftp_nb_fget_basic1.phpt b/ext/ftp/tests/ftp_nb_fget_basic1.phpt new file mode 100644 index 000000000..cac4eec56 --- /dev/null +++ b/ext/ftp/tests/ftp_nb_fget_basic1.phpt @@ -0,0 +1,32 @@ +--TEST-- +Testing ftp_nb_fget ignore autoresume if autoseek is switched off +--CREDITS-- +Rodrigo Moyle +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECT-- +int(2) +string(12) "ASCIIFooBar +" diff --git a/ext/ftp/tests/ftp_nb_fget_basic2.phpt b/ext/ftp/tests/ftp_nb_fget_basic2.phpt new file mode 100644 index 000000000..dc92f4e23 --- /dev/null +++ b/ext/ftp/tests/ftp_nb_fget_basic2.phpt @@ -0,0 +1,32 @@ +--TEST-- +Testing ftp_nb_fget autoresume +--CREDITS-- +Rodrigo Moyle +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECT-- +int(2) +string(12) "ASCIIFooBar +" diff --git a/ext/ftp/tests/ftp_nb_fget_basic3.phpt b/ext/ftp/tests/ftp_nb_fget_basic3.phpt new file mode 100644 index 000000000..d1a87c4f3 --- /dev/null +++ b/ext/ftp/tests/ftp_nb_fget_basic3.phpt @@ -0,0 +1,32 @@ +--TEST-- +Testing ftp_nb_fget resume parameter +--CREDITS-- +Rodrigo Moyle +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECT-- +int(2) +string(12) "ASCIIFooBar +" diff --git a/ext/ftp/tests/ftp_rawlist_basic2.phpt b/ext/ftp/tests/ftp_rawlist_basic2.phpt new file mode 100644 index 000000000..1d9364342 --- /dev/null +++ b/ext/ftp/tests/ftp_rawlist_basic2.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing ftp_rawlist returns false on server error +--CREDITS-- +Rodrigo Moyle +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(false) \ No newline at end of file diff --git a/ext/ftp/tests/ftp_rmdir_basic.phpt b/ext/ftp/tests/ftp_rmdir_basic.phpt new file mode 100755 index 000000000..6626cb4be --- /dev/null +++ b/ext/ftp/tests/ftp_rmdir_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing ftp_rmdir returns true +--CREDITS-- +Rodrigo Moyle +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) \ No newline at end of file diff --git a/ext/ftp/tests/server.inc b/ext/ftp/tests/server.inc index 76198c23d..861788062 100644 --- a/ext/ftp/tests/server.inc +++ b/ext/ftp/tests/server.inc @@ -6,293 +6,405 @@ $context = stream_context_create(array('ssl' => array('local_cert' => dirname(__ for ($i=0; $i<10 && !$socket; ++$i) { $port = rand(50000, 65535); + $socket = stream_socket_server("tcp://127.0.0.1:$port", $errno, $errstr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN, $context); } +//set anther random port that is not the same as $port +do{ + $pasv_port = rand(50000, 65535); +}while($pasv_port == $port); if (!$socket) { die("could not start/bind the ftp server\n"); } -$pid = pcntl_fork(); - -if ($pid) { - -function dump_and_exit($buf) -{ - var_dump($buf); - fclose($GLOBALS['s']); - exit; -} -function anonymous() -{ - return $GLOBALS['user'] === 'anonymous'; -} -/* quick&dirty realpath() like function */ -function change_dir($dir) -{ - global $cwd; - if ($dir[0] == '/') { - $cwd = $dir; - return; - } +$pid = pcntl_fork(); - $cwd = "$cwd/$dir"; - do { - $old = $cwd; - $cwd = preg_replace('@/?[^/]+/\.\.@', '', $cwd); - } while ($old != $cwd); - $cwd = strtr($cwd, array('//' => '/')); - if (!$cwd) $cwd = '/'; +function pasv_listen($action){ + global $pasv_port, $tmp_file; + $tmp_file = 'nm2.php'; + $pid = pcntl_fork(); + if($pid === 0){ + $soc = stream_socket_server("tcp://127.0.0.1:$pasv_port"); + $fs = stream_socket_accept($soc, 3); + switch ($action) { + case 'fget': + case 'get': + //listen for 3 seconds 3 seconds + fputs($fs, "I am passive.\r\n"); + break; + case 'put': + file_put_contents($tmp_file, stream_get_contents($fs)); + break; + case 'list': + fputs($fs, "drwxr-x--- 3 owner group 4096 Jul 12 12:16 .\r\n"); + fputs($fs, "drwxr-x--- 3 owner group 4096 Jul 12 12:16 ..\r\n"); + fputs($fs, "drwxr-x--- 3 owner group 4096 Jul 12 12:16 public_ftp\r\n"); + break; + case 'list_null': + fputs($fs, "\r\n"); + break; + } + fclose($fs); + exit; + } } -$s = stream_socket_accept($socket); -if (!$s) die("Error accepting a new connection\n"); - -fputs($s, "220----- PHP FTP server 0.3 -----\r\n220 Service ready\r\n"); -$buf = fread($s, 2048); - -function user_auth($buf) { - global $user, $s, $ssl, $bug37799; - -if (!empty($ssl)) { - if ($buf !== "AUTH TLS\r\n") { - fputs($s, "500 Syntax error, command unrecognized.\r\n"); - dump_and_exit($buf); - } +if ($pid) { - if (empty($bug37799)) { - fputs($s, "234 auth type accepted\r\n"); - } else { - fputs($s, "666 dummy\r\n"); - fputs($s, "666 bogus msg\r\n"); + function dump_and_exit($buf) + { + var_dump($buf); + fclose($GLOBALS['s']); exit; } - if (!stream_socket_enable_crypto($s, true, STREAM_CRYPTO_METHOD_SSLv23_SERVER)) { - die("SSLv23 handshake failed.\n"); + function anonymous() + { + return $GLOBALS['user'] === 'anonymous'; } - if (!preg_match('/^PBSZ \d+\r\n$/', $buf = fread($s, 2048))) { - fputs($s, "501 bogus data\r\n"); - dump_and_exit($buf); - } + /* quick&dirty realpath() like function */ + function change_dir($dir) + { + global $cwd; - fputs($s, "200 OK\r\n"); - $buf = fread($s, 2048); + if ($dir[0] == '/') { + $cwd = $dir; + return; + } - if ($buf !== "PROT P\r\n") { - fputs($s, "504 Wrong protection.\r\n"); - dump_and_exit($buf); - } + $cwd = "$cwd/$dir"; - fputs($s, "200 OK\r\n"); + do { + $old = $cwd; + $cwd = preg_replace('@/?[^/]+/\.\.@', '', $cwd); + } while ($old != $cwd); - $buf = fread($s, 2048); -} + $cwd = strtr($cwd, array('//' => '/')); + if (!$cwd) $cwd = '/'; + } -if (!preg_match('/^USER (\w+)\r\n$/', $buf, $m)) { - fputs($s, "500 Syntax error, command unrecognized.\r\n"); - dump_and_exit($buf); -} -$user = $m[1]; -if ($user !== 'user' && $user !== 'anonymous') { - fputs($s, "530 Not logged in.\r\n"); - fclose($s); - exit; -} + $s = stream_socket_accept($socket); -if (anonymous()) { - fputs($s, "230 Anonymous user logged in\r\n"); + if (!$s) die("Error accepting a new connection\n"); -} else { - fputs($s, "331 User name ok, need password\r\n"); + fputs($s, "220----- PHP FTP server 0.3 -----\r\n220 Service ready\r\n"); + $buf = fread($s, 2048); - if (!preg_match('/^PASS (\w+)\r\n$/', $buf = fread($s, 100), $m)) { - fputs($s, "500 Syntax error, command unrecognized.\r\n"); - dump_and_exit($buf); - } - $pass = $m[1]; - if ($pass === 'pass') { - fputs($s, "230 User logged in\r\n"); - } else { - fputs($s, "530 Not logged in.\r\n"); - fclose($s); - exit; - } -} -} + function user_auth($buf) { + global $user, $s, $ssl, $bug37799; -user_auth($buf); + if (!empty($ssl)) { + if ($buf !== "AUTH TLS\r\n") { + fputs($s, "500 Syntax error, command unrecognized.\r\n"); + dump_and_exit($buf); + } -$cwd = '/'; -$num_bogus_cmds = 0; + if (empty($bug37799)) { + fputs($s, "234 auth type accepted\r\n"); + } else { + fputs($s, "666 dummy\r\n"); + fputs($s, "666 bogus msg\r\n"); + exit; + } -while($buf = fread($s, 4098)) { - if (!empty($bogus)) { - fputs($s, "502 Command not implemented (".$num_bogus_cmds++.").\r\n"); + if (!stream_socket_enable_crypto($s, true, STREAM_CRYPTO_METHOD_SSLv23_SERVER)) { + die("SSLv23 handshake failed.\n"); + } - } else if ($buf === "HELP\r\n") { - fputs($s, "214-There is help available for the following commands:\r\n"); - fputs($s, " USER\r\n"); - fputs($s, " HELP\r\n"); - fputs($s, "214 end of list\r\n"); + if (!preg_match('/^PBSZ \d+\r\n$/', $buf = fread($s, 2048))) { + fputs($s, "501 bogus data\r\n"); + dump_and_exit($buf); + } - } elseif ($buf === "HELP HELP\r\n") { - fputs($s, "214 Syntax: HELP [ ] \r\n"); + fputs($s, "200 OK\r\n"); + $buf = fread($s, 2048); - } elseif ($buf === "PWD\r\n") { - fputs($s, "257 \"$cwd\" is current directory.\r\n"); + if ($buf !== "PROT P\r\n") { + fputs($s, "504 Wrong protection.\r\n"); + dump_and_exit($buf); + } - } elseif ($buf === "CDUP\r\n") { - change_dir('..'); - fputs($s, "250 CDUP command successful.\r\n"); + fputs($s, "200 OK\r\n"); - } elseif ($buf === "SYST\r\n") { - if (isset($bug27809)) { - fputs($s, "215 OS/400 is the remote operating system. The TCP/IP version is \"V5R2M0\"\r\n"); - } else { - fputs($s, "215 UNIX Type: L8.\r\n"); + $buf = fread($s, 2048); } - } elseif ($buf === "TYPE A\r\n") { - $ascii = true; - fputs($s, "200 OK\r\n"); - - } elseif ($buf === "TYPE I\r\n") { - $ascii = false; - fputs($s, "200 OK\r\n"); - - } elseif ($buf === "QUIT\r\n") { - break; - - } elseif (preg_match("~^PORT (\d+),(\d+),(\d+),(\d+),(\d+),(\d+)\r\n$~", $buf, $m)) { - $host = "$m[1].$m[2].$m[3].$m[4]"; - $port = ((int)$m[5] << 8) + (int)$m[6]; - fputs($s, "200 OK.\r\n"); + if (!preg_match('/^USER (\w+)\r\n$/', $buf, $m)) { + fputs($s, "500 Syntax error, command unrecognized.\r\n"); + dump_and_exit($buf); + } + $user = $m[1]; + if ($user !== 'user' && $user !== 'anonymous') { + fputs($s, "530 Not logged in.\r\n"); + fclose($s); + exit; + } - } elseif (preg_match("~^STOR ([\w/.-]+)\r\n$~", $buf, $m)) { - fputs($s, "150 File status okay; about to open data connection\r\n"); + if (anonymous()) { + fputs($s, "230 Anonymous user logged in\r\n"); - if (!$fs = stream_socket_client("tcp://$host:$port")) { - fputs($s, "425 Can't open data connection\r\n"); - continue; + } else { + fputs($s, "331 User name ok, need password\r\n"); + + if (!preg_match('/^PASS (\w+)\r\n$/', $buf = fread($s, 100), $m)) { + fputs($s, "500 Syntax error, command unrecognized.\r\n"); + dump_and_exit($buf); + } + + $pass = $m[1]; + if ($pass === 'pass') { + fputs($s, "230 User logged in\r\n"); + } else { + fputs($s, "530 Not logged in.\r\n"); + fclose($s); + exit; + } } + } - $data = stream_get_contents($fs); - $orig = file_get_contents(dirname(__FILE__).'/'.$m[1]); + user_auth($buf); - if (isset($ascii) && !$ascii && $orig === $data) { - fputs($s, "226 Closing data Connection.\r\n"); + $cwd = '/'; + $num_bogus_cmds = 0; - } elseif ((!empty($ascii) || isset($bug39583)) && $data === strtr($orig, array("\r\n" => "\n", "\r" => "\n", "\n" => "\r\n"))) { - fputs($s, "226 Closing data Connection.\r\n"); + while($buf = fread($s, 4098)) { + if (!empty($bogus)) { + fputs($s, "502 Command not implemented (".$num_bogus_cmds++.").\r\n"); - } else { - var_dump($data); - var_dump($orig); - fputs($s, "552 Requested file action aborted.\r\n"); - } - fclose($fs); + } else if ($buf === "HELP\r\n") { + fputs($s, "214-There is help available for the following commands:\r\n"); + fputs($s, " USER\r\n"); + fputs($s, " HELP\r\n"); + fputs($s, "214 end of list\r\n"); - } elseif (preg_match("~^CWD ([A-Za-z./]+)\r\n$~", $buf, $m)) { - change_dir($m[1]); - fputs($s, "250 CWD command successful.\r\n"); + } elseif ($buf === "HELP HELP\r\n") { + fputs($s, "214 Syntax: HELP [ ] \r\n"); - } elseif (preg_match("~^NLST(?: ([A-Za-z./]+))?\r\n$~", $buf, $m)) { + } elseif ($buf === "PWD\r\n") { + fputs($s, "257 \"$cwd\" is current directory.\r\n"); - if (isset($m[1]) && $m[1] === 'bogusdir') { - fputs($s, "250 $m[1]: No such file or directory\r\n"); - continue; - } + } elseif ($buf === "CDUP\r\n") { + change_dir('..'); + fputs($s, "250 CDUP command successful.\r\n"); - // there are some servers that don't open the ftp-data socket if there's nothing to send - if (isset($bug39458) && isset($m[1]) && $m[1] === 'emptydir') { - fputs($s, "226 Transfer complete.\r\n"); - continue; - } + } elseif ($buf === "SYST\r\n") { + if (isset($bug27809)) { + fputs($s, "215 OS/400 is the remote operating system. The TCP/IP version is \"V5R2M0\"\r\n"); + } else { + fputs($s, "215 UNIX Type: L8.\r\n"); + } - fputs($s, "150 File status okay; about to open data connection\r\n"); + } elseif ($buf === "TYPE A\r\n") { + $ascii = true; + fputs($s, "200 OK\r\n"); - if (!$fs = stream_socket_client("tcp://$host:$port")) { - fputs($s, "425 Can't open data connection\r\n"); - continue; - } + } elseif ($buf === "TYPE I\r\n") { + $ascii = false; + fputs($s, "200 OK\r\n"); - if (empty($m[1]) || $m[1] !== 'emptydir') { - fputs($fs, "file1\r\nfile1\r\nfile\nb0rk\r\n"); - } + } elseif ($buf === "QUIT\r\n") { + break; - fputs($s, "226 Closing data Connection.\r\n"); - fclose($fs); + } elseif (preg_match("~^PORT (\d+),(\d+),(\d+),(\d+),(\d+),(\d+)\r\n$~", $buf, $m)) { + $host = "$m[1].$m[2].$m[3].$m[4]"; + $port = ((int)$m[5] << 8) + (int)$m[6]; + fputs($s, "200 OK.\r\n"); + + } elseif (preg_match("~^STOR ([\w/.-]+)\r\n$~", $buf, $m)) { + fputs($s, "150 File status okay; about to open data connection\r\n"); + + if(empty($pasv)) + { + if (!$fs = stream_socket_client("tcp://$host:$port")) { + fputs($s, "425 Can't open data connection\r\n"); + continue; + } + + $data = stream_get_contents($fs); + $orig = file_get_contents(dirname(__FILE__).'/'.$m[1]); + + + if (isset($ascii) && !$ascii && $orig === $data) { + fputs($s, "226 Closing data Connection.\r\n"); + + } elseif ((!empty($ascii) || isset($bug39583)) && $data === strtr($orig, array("\r\n" => "\n", "\r" => "\n", "\n" => "\r\n"))) { + fputs($s, "226 Closing data Connection.\r\n"); + + } else { + var_dump($data); + var_dump($orig); + fputs($s, "552 Requested file action aborted.\r\n"); + } + fclose($fs); + }else{ + $data = file_get_contents('nm2.php'); + $orig = file_get_contents(dirname(__FILE__).'/'.$m[1]); + if ( $orig === $data) { + fputs($s, "226 Closing data Connection.\r\n"); + + } else { + var_dump($data); + var_dump($orig); + fputs($s, "552 Requested file action aborted.\r\n"); + } + } + + } elseif (preg_match("~^CWD ([A-Za-z./]+)\r\n$~", $buf, $m)) { + change_dir($m[1]); + fputs($s, "250 CWD command successful.\r\n"); + + } elseif (preg_match("~^NLST(?: ([A-Za-z./]+))?\r\n$~", $buf, $m)) { + + if (isset($m[1]) && $m[1] === 'bogusdir') { + fputs($s, "250 $m[1]: No such file or directory\r\n"); + continue; + } + + // there are some servers that don't open the ftp-data socket if there's nothing to send + if (isset($bug39458) && isset($m[1]) && $m[1] === 'emptydir') { + fputs($s, "226 Transfer complete.\r\n"); + continue; + } + + fputs($s, "150 File status okay; about to open data connection\r\n"); + + if (!$fs = stream_socket_client("tcp://$host:$port")) { + fputs($s, "425 Can't open data connection\r\n"); + continue; + } + + if (empty($m[1]) || $m[1] !== 'emptydir') { + fputs($fs, "file1\r\nfile1\r\nfile\nb0rk\r\n"); + } - } elseif (preg_match("~^MKD ([A-Za-z./]+)\r\n$~", $buf, $m)) { - if (isset($bug7216)) { - fputs($s, "257 OK.\r\n"); - } else { - fputs($s, "257 \"/path/to/ftproot$cwd$m[1]\" created.\r\n"); - } + fputs($s, "226 Closing data Connection.\r\n"); + fclose($fs); - } elseif (preg_match('/^USER /', $buf)) { - user_auth($buf); + } elseif (preg_match("~^MKD ([A-Za-z./]+)\r\n$~", $buf, $m)) { + if (isset($bug7216)) { + fputs($s, "257 OK.\r\n"); + } else { + fputs($s, "257 \"/path/to/ftproot$cwd$m[1]\" created.\r\n"); + } - } elseif (preg_match('/^MDTM ([\w\h]+)/', $buf, $matches)) { - switch ($matches [1]){ - case "A": + } elseif (preg_match('/^USER /', $buf)) { + user_auth($buf); + + } elseif (preg_match('/^MDTM ([\w\h]+)/', $buf, $matches)) { + switch ($matches [1]){ + case "A": fputs($s, "213 19980615100045.014\r\n"); break; - case "B": + case "B": fputs($s, "213 19980615100045.014\r\n"); break; - case "C": + case "C": fputs($s, "213 19980705132316\r\n"); break; - case "19990929043300 File6": + case "19990929043300 File6": fputs($s, "213 19991005213102\r\n"); break; - default : + default : fputs($s, "550 No file named \"{$matches [1]}\"\r\n"); break; - } - }elseif (preg_match('/^RETR ([\w\h]+)/', $buf, $matches)) { - if (!$fs = stream_socket_client("tcp://$host:$port")) { - fputs($s, "425 Can't open data connection\r\n"); - continue; - } + } + }elseif (preg_match('/^RETR ([\w\h]+)/', $buf, $matches)) { + if(!empty($pasv)){ + ; + } + else if (!$fs = stream_socket_client("tcp://$host:$port")) { + fputs($s, "425 Can't open data connection\r\n"); + continue; + } + switch($matches[1]){ - case "a story": - fputs($s, "150 File status okay; about to open data connection.\r\n"); - fputs($fs, "For sale: baby shoes, never worn.\r\n"); - fputs($s, "226 Closing data Connection.\r\n"); - break; - case "binary data": - fputs($s, "150 File status okay; about to open data connection.\r\n"); - $transfer_type = $ascii? 'ASCII' : 'BINARY' ; - fputs($fs, $transfer_type."Foo\0Bar\r\n"); - fputs($s, "226 Closing data Connection.\r\n"); - break; - default: - fputs($s, "550 {$matches[1]}: No such file or directory \r\n"); - break; - } - fclose($fs); - } - else { - fputs($s, "500 Syntax error, command unrecognized.\r\n"); - dump_and_exit($buf); - } -} -fclose($s); -exit; + case "pasv": + fputs($s, "150 File status okay; about to open data connection.\r\n"); + //the data connection is handled in another forked process + // called from outside this while loop + fputs($s, "226 Closing data Connection.\r\n"); + break; + case "a story": + fputs($s, "150 File status okay; about to open data connection.\r\n"); + fputs($fs, "For sale: baby shoes, never worn.\r\n"); + fputs($s, "226 Closing data Connection.\r\n"); + break; + case "binary data": + fputs($s, "150 File status okay; about to open data connection.\r\n"); + $transfer_type = $ascii? 'ASCII' : 'BINARY' ; + fputs($fs, $transfer_type."Foo\0Bar\r\n"); + fputs($s, "226 Closing data Connection.\r\n"); + break; + case "fget": + fputs($s, "150 File status okay; about to open data connection.\r\n"); + $transfer_type = $ascii? 'ASCII' : 'BINARY' ; + fputs($fs, $transfer_type."FooBar\r\n"); + fputs($s, "226 Closing data Connection.\r\n"); + break; + case "fgetresume": + fputs($s, "150 File status okay; about to open data connection.\r\n"); + $transfer_type = $ascii? 'ASCII' : 'BINARY' ; + fputs($fs, "Bar\r\n"); + fputs($s, "226 Closing data Connection.\r\n"); + break; + default: + fputs($s, "550 {$matches[1]}: No such file or directory \r\n"); + break; + } + if(isset($fs)) + fclose($fs); + + + }elseif (preg_match('/^PASV/', $buf, $matches)) { + $port = $pasv_port; + $p2 = $port % ((int) 1 << 8); + $p1 = ($port-$p2)/((int) 1 << 8); + $host = "127.0.0.1"; + fputs($s, "227 Entering Passive Mode. (127,0,0,1,{$p1},{$p2})\r\n"); + + + } elseif (preg_match('/^SITE EXEC/', $buf, $matches)) { + fputs($s, "200 OK\r\n"); + + } elseif (preg_match('/^RMD/', $buf, $matches)) { + fputs($s, "250 OK\r\n"); + + } elseif (preg_match('/^SITE CHMOD/', $buf, $matches)) { + fputs($s, "200 OK\r\n"); + + } elseif (preg_match('/^ALLO (\d+)/', $buf, $matches)) { + fputs($s, "200 " . $matches[1] . " bytes allocated\r\n"); + + }elseif (preg_match('/^LIST www\//', $buf, $matches)) { + fputs($s, "150 Opening ASCII mode data connection for file list\r\n"); + fputs($s, "226 Transfer complete\r\n"); + + }elseif (preg_match('/^LIST no_exists\//', $buf, $matches)) { + fputs($s, "425 Error establishing connection\r\n"); + + }elseif (preg_match('/^REST \d+/', $buf, $matches)) { + fputs($s, "350 OK\r\n"); + } + + else { + fputs($s, "500 Syntax error, command unrecognized.\r\n"); + dump_and_exit($buf); + } + } + fclose($s); + exit; } fclose($socket); -?> +?> \ No newline at end of file diff --git a/ext/gd/config.m4 b/ext/gd/config.m4 index e433be7e2..1997594ab 100644 --- a/ext/gd/config.m4 +++ b/ext/gd/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.154.2.1.2.6.2.8 2009/05/27 08:18:23 pajoye Exp $ +dnl $Id: config.m4 281216 2009-05-27 08:18:24Z pajoye $ dnl dnl diff --git a/ext/gd/config.w32 b/ext/gd/config.w32 index 2e25ec845..491f9a9c4 100644 --- a/ext/gd/config.w32 +++ b/ext/gd/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.10.4.4.2.15 2009/05/27 08:18:23 pajoye Exp $ +// $Id: config.w32 281216 2009-05-27 08:18:24Z pajoye $ // vim:ft=javascript ARG_WITH("gd", "Bundled GD support", "yes,shared"); diff --git a/ext/gd/gd.c b/ext/gd/gd.c index e418a70a5..8853e61a3 100644 --- a/ext/gd/gd.c +++ b/ext/gd/gd.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: gd.c,v 1.312.2.20.2.32.2.43 2009/06/19 22:15:28 kalle Exp $ */ +/* $Id: gd.c 282455 2009-06-19 22:15:28Z kalle $ */ /* gd 1.2 is copyright 1994, 1995, Quest Protein Database Center, Cold Spring Harbor Labs. */ diff --git a/ext/gd/gd_ctx.c b/ext/gd/gd_ctx.c index 464f07705..e4961cf79 100644 --- a/ext/gd/gd_ctx.c +++ b/ext/gd/gd_ctx.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: gd_ctx.c,v 1.22.2.5.2.3.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: gd_ctx.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_gd.h" diff --git a/ext/gd/gdcache.c b/ext/gd/gdcache.c index 598ec811d..695f289d2 100644 --- a/ext/gd/gdcache.c +++ b/ext/gd/gdcache.c @@ -1,5 +1,5 @@ /* - * $Id: gdcache.c,v 1.10.6.1 2008/07/18 01:16:25 scottmac Exp $ + * $Id: gdcache.c 262909 2008-07-18 01:16:25Z scottmac $ * * Caches of pointers to user structs in which the least-recently-used * element is replaced in the event of a cache miss after the cache has diff --git a/ext/gd/gdcache.h b/ext/gd/gdcache.h index 033aaefe1..13ed963ea 100644 --- a/ext/gd/gdcache.h +++ b/ext/gd/gdcache.h @@ -1,5 +1,5 @@ /* - * $Id: gdcache.h,v 1.4 2003/12/28 21:08:46 iliaa Exp $ + * $Id: gdcache.h 242949 2007-09-26 15:44:16Z cvs2svn $ * * Caches of pointers to user structs in which the least-recently-used * element is replaced in the event of a cache miss after the cache has diff --git a/ext/gd/libgd/gd.c b/ext/gd/libgd/gd.c index d66bbbfad..a0ea6f198 100644 --- a/ext/gd/libgd/gd.c +++ b/ext/gd/libgd/gd.c @@ -595,7 +595,7 @@ void gdImageColorTransparent (gdImagePtr im, int color) if (im->transparent != -1) { im->alpha[im->transparent] = gdAlphaOpaque; } - if (color > -1 && colorcolorsTotal && color<=gdMaxColors) { + if (color > -1 && color < im->colorsTotal && color < gdMaxColors) { im->alpha[color] = gdAlphaTransparent; } else { return; @@ -1093,8 +1093,7 @@ void gdImageLine (gdImagePtr im, int x1, int y1, int x2, int y2, int color) int w, wstart; int thick = im->thick; - if (color == gdAntiAliased) - { + if (color == gdAntiAliased) { /* gdAntiAliased passed as color: use the much faster, much cheaper and equally attractive gdImageAALine implementation. That @@ -1191,7 +1190,7 @@ TBB: but watch out for /0! */ } else { /* More-or-less vertical. use wid for horizontal stroke */ /* 2.0.12: Michael Schwartz: divide rather than multiply; - TBB: but watch out for /0! */ + TBB: but watch out for /0! */ double as = sin (atan2 (dy, dx)); if (as != 0) { wid = thick / as; @@ -1359,7 +1358,7 @@ void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col) x = x1 << 16; y = y1 << 16; inc = (dy * 65536) / dx; - while ((x >> 16) < x2) { + while ((x >> 16) <= x2) { gdImageSetAAPixelColor(im, x >> 16, y >> 16, col, (y >> 8) & 0xFF); if ((y >> 16) + 1 < im->sy) { gdImageSetAAPixelColor(im, x >> 16, (y >> 16) + 1,col, (~y >> 8) & 0xFF); @@ -1381,7 +1380,7 @@ void gdImageAALine (gdImagePtr im, int x1, int y1, int x2, int y2, int col) x = x1 << 16; y = y1 << 16; inc = (dx * 65536) / dy; - while ((y>>16) < y2) { + while ((y>>16) <= y2) { gdImageSetAAPixelColor(im, x >> 16, y >> 16, col, (x >> 8) & 0xFF); if ((x >> 16) + 1 < im->sx) { gdImageSetAAPixelColor(im, (x >> 16) + 1, (y >> 16),col, (~x >> 8) & 0xFF); @@ -1681,27 +1680,26 @@ void gdImageFilledArc (gdImagePtr im, int cx, int cy, int w, int h, int s, int e if ((s % 360) == (e % 360)) { s = 0; e = 360; - } else { - if (s > 360) { - s = s % 360; - } - - if (e > 360) { - e = e % 360; - } + } else { + if (s > 360) { + s = s % 360; + } - while (s < 0) { - s += 360; - } + if (e > 360) { + e = e % 360; + } - while (e < s) { - e += 360; - } + while (s < 0) { + s += 360; + } - if (s == e) { + while (e < s) { + e += 360; + } + if (s == e) { s = 0; e = 360; - } - } + } + } for (i = s; i <= e; i++) { int x, y; @@ -1987,7 +1985,7 @@ static void _gdImageFillTiled(gdImagePtr im, int x, int y, int nc) oc = gdImageGetPixel(im, x, y); -/* required! */ + /* required! */ FILL_PUSH(y,x,x,1); /* seed segment (popped 1st) */ FILL_PUSH(y+1, x, x, -1); @@ -2114,33 +2112,40 @@ void gdImageFilledRectangle (gdImagePtr im, int x1, int y1, int x2, int y2, int { int x, y; - /* Nick Atty: limit the points at the edge. Note that this also - * nicely kills any plotting for rectangles completely outside the - * window as it makes the tests in the for loops fail - */ - if (x1 < 0) { - x1 = 0; - } - if (x1 > gdImageSX(im)) { - x1 = gdImageSX(im); - } - if(y1 < 0) { - y1 = 0; - } - if (y1 > gdImageSY(im)) { - y1 = gdImageSY(im); + + if (x1 == x2 && y1 == y2) { + gdImageSetPixel(im, x1, y1, color); + return; } + if (x1 > x2) { x = x1; x1 = x2; x2 = x; } + if (y1 > y2) { y = y1; y1 = y2; y2 = y; } + if (x1 < 0) { + x1 = 0; + } + + if (x2 >= gdImageSX(im)) { + x2 = gdImageSX(im) - 1; + } + + if (y1 < 0) { + y1 = 0; + } + + if (y2 >= gdImageSY(im)) { + y2 = gdImageSY(im) - 1; + } + for (y = y1; (y <= y2); y++) { for (x = x1; (x <= x2); x++) { gdImageSetPixel (im, x, y, color); @@ -2301,7 +2306,6 @@ void gdImageCopyMergeGray (gdImagePtr dst, gdImagePtr src, int dstX, int dstY, i for (x = srcX; (x < (srcX + w)); x++) { int nc; c = gdImageGetPixel (src, x, y); - /* Added 7/24/95: support transparent copies */ if (gdImageGetTransparent(src) == c) { tox++; diff --git a/ext/gd/libgd/gd_compat.c b/ext/gd/libgd/gd_compat.c index bba62341c..473ea203e 100644 --- a/ext/gd/libgd/gd_compat.c +++ b/ext/gd/libgd/gd_compat.c @@ -14,7 +14,7 @@ int gdJpegGetVersionInt() return JPEG_LIB_VERSION; } -int gdJpegGetVersionString() +const char * gdJpegGetVersionString() { switch(JPEG_LIB_VERSION) { case 62: diff --git a/ext/gd/libgd/gd_compat.h b/ext/gd/libgd/gd_compat.h index 022d0a889..c084a0069 100644 --- a/ext/gd/libgd/gd_compat.h +++ b/ext/gd/libgd/gd_compat.h @@ -8,7 +8,7 @@ #endif const char * gdPngGetVersionString(); -int gdJpegGetVersionString(); +const char * gdJpegGetVersionString(); int gdJpegGetVersionInt(); int overflow2(int a, int b); diff --git a/ext/gd/libgd/gd_gd.c b/ext/gd/libgd/gd_gd.c index 55587d43e..81a957d41 100644 --- a/ext/gd/libgd/gd_gd.c +++ b/ext/gd/libgd/gd_gd.c @@ -39,6 +39,9 @@ int _gdGetColors (gdIOCtx * in, gdImagePtr im, int gd2xFlag) if (!gdGetWord(&im->colorsTotal, in)) { goto fail1; } + if (im->colorsTotal > gdMaxColors) { + goto fail1; + } } /* Int to accommodate truecolor single-color transparency */ if (!gdGetInt(&im->transparent, in)) { diff --git a/ext/gd/libgd/gdft.c b/ext/gd/libgd/gdft.c index 73cbb8dce..ffac3ebf6 100644 --- a/ext/gd/libgd/gdft.c +++ b/ext/gd/libgd/gdft.c @@ -785,6 +785,7 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi int len, i = 0, ch; int x1 = 0, y1 = 0; int xb = x, yb = y; + int yd = 0; font_t *font; fontkey_t fontkey; char *next; @@ -919,6 +920,7 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi } #endif + i = 0; while (*next) { ch = *next; @@ -934,6 +936,7 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi } /* newlines */ if (ch == '\n') { + if (!*(++next)) break; /* 2.0.13: reset penf.x. Christopher J. Grayce */ penf.x = 0; penf.y -= (long)(face->size->metrics.height * linespace); @@ -942,9 +945,9 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi y1 = (int)(- penf.y * cos_a + 32) / 64; xb = x + x1; yb = y + y1; + yd = 0; pen.x = pen.y = 0; previous = 0; /* clear kerning flag */ - next++; continue; } @@ -1058,11 +1061,17 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi glyph_bbox.xMax += slot->metrics.horiAdvance; } if (!i) { /* if first character, init BB corner values */ + yd = slot->metrics.height - slot->metrics.horiBearingY; bbox.xMin = glyph_bbox.xMin; bbox.yMin = glyph_bbox.yMin; bbox.xMax = glyph_bbox.xMax; bbox.yMax = glyph_bbox.yMax; } else { + FT_Pos desc; + + if ( (desc = (slot->metrics.height - slot->metrics.horiBearingY)) > yd) { + yd = desc; + } if (bbox.xMin > glyph_bbox.xMin) { bbox.xMin = glyph_bbox.xMin; } @@ -1119,15 +1128,18 @@ gdImageStringFTEx (gdImage * im, int *brect, int fg, char *fontlist, double ptsi normbox.xMax = bbox.xMax - bbox.xMin; normbox.yMax = bbox.yMax - bbox.yMin; + brect[0] = brect[2] = brect[4] = brect[6] = (int) (yd * sin_a); + brect[1] = brect[3] = brect[5] = brect[7] = (int)(- yd * cos_a); + /* rotate bounding rectangle */ - brect[0] = (int) (normbox.xMin * cos_a - normbox.yMin * sin_a); - brect[1] = (int) (normbox.xMin * sin_a + normbox.yMin * cos_a); - brect[2] = (int) (normbox.xMax * cos_a - normbox.yMin * sin_a); - brect[3] = (int) (normbox.xMax * sin_a + normbox.yMin * cos_a); - brect[4] = (int) (normbox.xMax * cos_a - normbox.yMax * sin_a); - brect[5] = (int) (normbox.xMax * sin_a + normbox.yMax * cos_a); - brect[6] = (int) (normbox.xMin * cos_a - normbox.yMax * sin_a); - brect[7] = (int) (normbox.xMin * sin_a + normbox.yMax * cos_a); + brect[0] += (int) (normbox.xMin * cos_a - normbox.yMin * sin_a); + brect[1] += (int) (normbox.xMin * sin_a + normbox.yMin * cos_a); + brect[2] += (int) (normbox.xMax * cos_a - normbox.yMin * sin_a); + brect[3] += (int) (normbox.xMax * sin_a + normbox.yMin * cos_a); + brect[4] += (int) (normbox.xMax * cos_a - normbox.yMax * sin_a); + brect[5] += (int) (normbox.xMax * sin_a + normbox.yMax * cos_a); + brect[6] += (int) (normbox.xMin * cos_a - normbox.yMax * sin_a); + brect[7] += (int) (normbox.xMin * sin_a + normbox.yMax * cos_a); /* scale, round and offset brect */ brect[0] = xb + gdroundupdown(brect[0], d2 > 0); diff --git a/ext/gd/libgd/xbm.c b/ext/gd/libgd/xbm.c index 4be7ec8c1..983163ae5 100644 --- a/ext/gd/libgd/xbm.c +++ b/ext/gd/libgd/xbm.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xbm.c,v 1.7.2.2.2.2.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: xbm.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include #include diff --git a/ext/gd/php_gd.h b/ext/gd/php_gd.h index cefe4ca92..d2970ce0c 100644 --- a/ext/gd/php_gd.h +++ b/ext/gd/php_gd.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_gd.h,v 1.59.2.3.2.5.2.9 2009/05/27 08:18:24 pajoye Exp $ */ +/* $Id: php_gd.h 281216 2009-05-27 08:18:24Z pajoye $ */ #ifndef PHP_GD_H #define PHP_GD_H diff --git a/ext/gd/tests/bug42434.phpt b/ext/gd/tests/bug42434.phpt new file mode 100644 index 000000000..cede1ac17 --- /dev/null +++ b/ext/gd/tests/bug42434.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #42434 (ImageLine w/ antialias = 1px shorter) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +DONE \ No newline at end of file diff --git a/ext/gd/tests/bug43073.phpt b/ext/gd/tests/bug43073.phpt new file mode 100644 index 000000000..df4ffe37e --- /dev/null +++ b/ext/gd/tests/bug43073.phpt @@ -0,0 +1,48 @@ +--TEST-- +Bug #43073 (TrueType bounding box is wrong for angle<>0) +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECTF-- +(500, 402), (610, 402), (610, 376), (500, 376) +(492, 363), (591, 322), (580, 295), (480, 336) +(470, 331), (548, 254), (527, 233), (449, 310) +(439, 309), (483, 202), (461, 193), (416, 299) +(401, 300), (401, 183), (381, 183), (381, 300) +(362, 307), (316, 195), (291, 205), (337, 318) +(330, 329), (246, 244), (224, 265), (308, 350) +(308, 360), (202, 316), (190, 344), (296, 388) +(300, 399), (186, 399), (186, 425), (300, 425) +(306, 437), (195, 483), (206, 510), (318, 464) +(328, 469), (240, 557), (260, 578), (349, 491) +(359, 491), (312, 607), (334, 616), (382, 501) +(398, 500), (398, 618), (418, 618), (418, 500) +(436, 493), (483, 607), (507, 597), (461, 482) +(468, 471), (555, 558), (577, 538), (490, 450) +(490, 440), (600, 485), (611, 457), (502, 412) diff --git a/ext/gd/tests/bug48555.phpt b/ext/gd/tests/bug48555.phpt index a505f0033..f2030fece 100644 --- a/ext/gd/tests/bug48555.phpt +++ b/ext/gd/tests/bug48555.phpt @@ -3,16 +3,17 @@ Bug #48555 (ImageFTBBox() differs from previous versions for texts with new line --SKIPIF-- --FILE-- --EXPECTF-- -Top without line-break: -15 -Top with line-break: -15 +Top without line-break: -14 +Top with line-break: -14 diff --git a/ext/gd/tests/bug48732.phpt b/ext/gd/tests/bug48732.phpt new file mode 100644 index 000000000..f8cb5e2ba --- /dev/null +++ b/ext/gd/tests/bug48732.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #48732 (TTF Bounding box wrong for letters below baseline) +--SKIPIF-- + +--FILE-- + +--CLEAN-- + +--EXPECTF-- +Left Bottom: (0, 47) diff --git a/ext/gd/tests/bug48801.phpt b/ext/gd/tests/bug48801.phpt new file mode 100644 index 000000000..a6a9874ab --- /dev/null +++ b/ext/gd/tests/bug48801.phpt @@ -0,0 +1,22 @@ +--TEST-- +Bug #48801 (Problem with imagettfbbox) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +(-1, 15) +(155, 15) +(155, -48) +(-1, -48) diff --git a/ext/gd/tests/crafted.gd2 b/ext/gd/tests/crafted.gd2 new file mode 100644 index 000000000..45c944cc2 Binary files /dev/null and b/ext/gd/tests/crafted.gd2 differ diff --git a/ext/gd/tests/crafted_gd2.phpt b/ext/gd/tests/crafted_gd2.phpt new file mode 100644 index 000000000..7bcbc4e68 --- /dev/null +++ b/ext/gd/tests/crafted_gd2.phpt @@ -0,0 +1,16 @@ +--TEST-- +Test max colors for a gd image. +--SKIPIF-- + +--FILE-- + +--EXPECTF-- + +Warning: imagecreatefromgd(): '%scrafted.gd2' is not a valid GD file in %s on line %d + diff --git a/ext/gd/tests/gd_info_error.phpt b/ext/gd/tests/gd_info_error.phpt index 07cabdf52..15a26e4a4 100644 --- a/ext/gd/tests/gd_info_error.phpt +++ b/ext/gd/tests/gd_info_error.phpt @@ -1,38 +1,38 @@ ---TEST-- -Test gd_info() function : error conditions - with more than expected number of arguments ---SKIPIF-- - ---FILE-- - -===DONE=== ---EXPECTF-- -*** Testing gd_info() : error conditions *** - --- Testing gd_info() function with more than expected number of arguments -- - -Warning: gd_info() expects exactly 0 parameters, 1 given in %s on line %d -bool(false) - -Warning: gd_info() expects exactly 0 parameters, 2 given in %s on line %d -bool(false) +--TEST-- +Test gd_info() function : error conditions - with more than expected number of arguments +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing gd_info() : error conditions *** + +-- Testing gd_info() function with more than expected number of arguments -- + +Warning: gd_info() expects exactly 0 parameters, 1 given in %s on line %d +bool(false) + +Warning: gd_info() expects exactly 0 parameters, 2 given in %s on line %d +bool(false) ===DONE=== \ No newline at end of file diff --git a/ext/gd/tests/gd_info_variation1.phpt b/ext/gd/tests/gd_info_variation1.phpt index e77f6fb01..a725f6554 100644 --- a/ext/gd/tests/gd_info_variation1.phpt +++ b/ext/gd/tests/gd_info_variation1.phpt @@ -1,50 +1,50 @@ ---TEST-- -Test gd_info() function : variation - Checking all the values in returned array ---SKIPIF-- - ---FILE-- - -===DONE=== ---EXPECTF-- -*** Testing gd_info() : variation *** -array(%d) { - ["GD Version"]=> - string(%d) %a - ["FreeType Support"]=> - bool%a - ["T1Lib Support"]=> - bool%a - ["GIF Read Support"]=> - bool%a - ["GIF Create Support"]=> - bool%a - ["JPEG Support"]=> - bool%a - ["PNG Support"]=> - bool%a - ["WBMP Support"]=> - bool%a - ["XPM Support"]=> - bool%a - ["XBM Support"]=> - bool%a - ["JIS-mapped Japanese Font Support"]=> - bool%a -} +--TEST-- +Test gd_info() function : variation - Checking all the values in returned array +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing gd_info() : variation *** +array(%d) { + ["GD Version"]=> + string(%d) %a + ["FreeType Support"]=> + bool%a + ["T1Lib Support"]=> + bool%a + ["GIF Read Support"]=> + bool%a + ["GIF Create Support"]=> + bool%a + ["JPEG Support"]=> + bool%a + ["PNG Support"]=> + bool%a + ["WBMP Support"]=> + bool%a + ["XPM Support"]=> + bool%a + ["XBM Support"]=> + bool%a + ["JIS-mapped Japanese Font Support"]=> + bool%a +} ===DONE=== \ No newline at end of file diff --git a/ext/gd/tests/gif.phpt b/ext/gd/tests/gif.phpt index dd71a5404..2a3687ad7 100644 --- a/ext/gd/tests/gif.phpt +++ b/ext/gd/tests/gif.phpt @@ -2,7 +2,7 @@ gif in/out --SKIPIF-- -===DONE=== ---EXPECTF-- -*** Testing image_type_to_mime_type() : error conditions *** - --- Testing image_type_to_mime_type() function with Zero arguments -- - -Warning: image_type_to_mime_type() expects exactly 1 parameter, 0 given in %simage_type_to_mime_type_error.php on line 13 -NULL - --- Testing image_type_to_mime_type() function with more than expected no. of arguments -- - -Warning: image_type_to_mime_type() expects exactly 1 parameter, 2 given in %simage_type_to_mime_type_error.php on line 17 -NULL +--TEST-- +Test image_type_to_mime_type() function : error conditions - Pass incorrect number of arguments +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing image_type_to_mime_type() : error conditions *** + +-- Testing image_type_to_mime_type() function with Zero arguments -- + +Warning: image_type_to_mime_type() expects exactly 1 parameter, 0 given in %simage_type_to_mime_type_error.php on line 13 +NULL + +-- Testing image_type_to_mime_type() function with more than expected no. of arguments -- + +Warning: image_type_to_mime_type() expects exactly 1 parameter, 2 given in %simage_type_to_mime_type_error.php on line 17 +NULL ===DONE=== \ No newline at end of file diff --git a/ext/gd/tests/image_type_to_mime_type_variation1.phpt b/ext/gd/tests/image_type_to_mime_type_variation1.phpt index 81851979e..0023b7125 100644 --- a/ext/gd/tests/image_type_to_mime_type_variation1.phpt +++ b/ext/gd/tests/image_type_to_mime_type_variation1.phpt @@ -1,152 +1,152 @@ ---TEST-- -Test image_type_to_mime_type() function : usage variations - Pass different data types as imagetype ---FILE-- - 'red', 'item' => 'pen'), - - // null data - NULL, - null, - - // boolean data - true, - false, - TRUE, - FALSE, - - // empty data - "", - '', - - // string data - "string", - 'string', - - // object data - new MyClass(), - - // undefined data - @$undefined_var, - - // unset data - @$unset_var, -); - -// loop through each element of the array for imagetype -$iterator = 1; -foreach($values as $value) { - echo "\n-- Iteration $iterator --\n"; - var_dump( image_type_to_mime_type($value) ); - $iterator++; -}; -?> -===DONE=== ---EXPECTF-- -*** Testing image_type_to_mime_type() : usage variations *** - --- Iteration 1 -- -string(24) "application/octet-stream" - --- Iteration 2 -- -string(24) "application/octet-stream" - --- Iteration 3 -- -string(24) "application/octet-stream" - --- Iteration 4 -- -string(24) "application/octet-stream" - --- Iteration 5 -- -string(24) "application/octet-stream" - --- Iteration 6 -- - -Warning: image_type_to_mime_type() expects parameter 1 to be long, array given in %s on line %d -NULL - --- Iteration 7 -- - -Warning: image_type_to_mime_type() expects parameter 1 to be long, array given in %s on line %d -NULL - --- Iteration 8 -- -string(24) "application/octet-stream" - --- Iteration 9 -- -string(24) "application/octet-stream" - --- Iteration 10 -- -string(9) "image/gif" - --- Iteration 11 -- -string(24) "application/octet-stream" - --- Iteration 12 -- -string(9) "image/gif" - --- Iteration 13 -- -string(24) "application/octet-stream" - --- Iteration 14 -- - -Warning: image_type_to_mime_type() expects parameter 1 to be long, string given in %s on line %d -NULL - --- Iteration 15 -- - -Warning: image_type_to_mime_type() expects parameter 1 to be long, string given in %s on line %d -NULL - --- Iteration 16 -- - -Warning: image_type_to_mime_type() expects parameter 1 to be long, string given in %s on line %d -NULL - --- Iteration 17 -- - -Warning: image_type_to_mime_type() expects parameter 1 to be long, string given in %s on line %d -NULL - --- Iteration 18 -- - -Warning: image_type_to_mime_type() expects parameter 1 to be long, object given in %s on line %d -NULL - --- Iteration 19 -- -string(24) "application/octet-stream" - --- Iteration 20 -- -string(24) "application/octet-stream" +--TEST-- +Test image_type_to_mime_type() function : usage variations - Pass different data types as imagetype +--FILE-- + 'red', 'item' => 'pen'), + + // null data + NULL, + null, + + // boolean data + true, + false, + TRUE, + FALSE, + + // empty data + "", + '', + + // string data + "string", + 'string', + + // object data + new MyClass(), + + // undefined data + @$undefined_var, + + // unset data + @$unset_var, +); + +// loop through each element of the array for imagetype +$iterator = 1; +foreach($values as $value) { + echo "\n-- Iteration $iterator --\n"; + var_dump( image_type_to_mime_type($value) ); + $iterator++; +}; +?> +===DONE=== +--EXPECTF-- +*** Testing image_type_to_mime_type() : usage variations *** + +-- Iteration 1 -- +string(24) "application/octet-stream" + +-- Iteration 2 -- +string(24) "application/octet-stream" + +-- Iteration 3 -- +string(24) "application/octet-stream" + +-- Iteration 4 -- +string(24) "application/octet-stream" + +-- Iteration 5 -- +string(24) "application/octet-stream" + +-- Iteration 6 -- + +Warning: image_type_to_mime_type() expects parameter 1 to be long, array given in %s on line %d +NULL + +-- Iteration 7 -- + +Warning: image_type_to_mime_type() expects parameter 1 to be long, array given in %s on line %d +NULL + +-- Iteration 8 -- +string(24) "application/octet-stream" + +-- Iteration 9 -- +string(24) "application/octet-stream" + +-- Iteration 10 -- +string(9) "image/gif" + +-- Iteration 11 -- +string(24) "application/octet-stream" + +-- Iteration 12 -- +string(9) "image/gif" + +-- Iteration 13 -- +string(24) "application/octet-stream" + +-- Iteration 14 -- + +Warning: image_type_to_mime_type() expects parameter 1 to be long, string given in %s on line %d +NULL + +-- Iteration 15 -- + +Warning: image_type_to_mime_type() expects parameter 1 to be long, string given in %s on line %d +NULL + +-- Iteration 16 -- + +Warning: image_type_to_mime_type() expects parameter 1 to be long, string given in %s on line %d +NULL + +-- Iteration 17 -- + +Warning: image_type_to_mime_type() expects parameter 1 to be long, string given in %s on line %d +NULL + +-- Iteration 18 -- + +Warning: image_type_to_mime_type() expects parameter 1 to be long, object given in %s on line %d +NULL + +-- Iteration 19 -- +string(24) "application/octet-stream" + +-- Iteration 20 -- +string(24) "application/octet-stream" ===DONE=== \ No newline at end of file diff --git a/ext/gd/tests/image_type_to_mime_type_variation2.phpt b/ext/gd/tests/image_type_to_mime_type_variation2.phpt index 63a035a4a..141bc576f 100644 --- a/ext/gd/tests/image_type_to_mime_type_variation2.phpt +++ b/ext/gd/tests/image_type_to_mime_type_variation2.phpt @@ -1,80 +1,80 @@ ---TEST-- -Test image_type_to_mime_type() function : usage variations - Pass decimal, octal, and hexadecimal values as imagetype ---FILE-- - -===DONE=== ---EXPECT-- -*** Testing image_type_to_mime_type() : usage variations *** - --- Iteration 1 -- -string(24) "application/octet-stream" - --- Iteration 2 -- -string(9) "image/gif" - --- Iteration 3 -- -string(24) "application/octet-stream" - --- Iteration 4 -- -string(24) "application/octet-stream" - --- Iteration 5 -- -string(10) "image/jpeg" - --- Iteration 6 -- -string(10) "image/tiff" - --- Iteration 7 -- -string(24) "application/octet-stream" - --- Iteration 8 -- -string(24) "application/octet-stream" - --- Iteration 9 -- -string(24) "application/octet-stream" - --- Iteration 10 -- -string(9) "image/gif" - --- Iteration 11 -- -string(24) "application/octet-stream" - --- Iteration 12 -- -string(24) "application/octet-stream" -===DONE=== +--TEST-- +Test image_type_to_mime_type() function : usage variations - Pass decimal, octal, and hexadecimal values as imagetype +--FILE-- + +===DONE=== +--EXPECT-- +*** Testing image_type_to_mime_type() : usage variations *** + +-- Iteration 1 -- +string(24) "application/octet-stream" + +-- Iteration 2 -- +string(9) "image/gif" + +-- Iteration 3 -- +string(24) "application/octet-stream" + +-- Iteration 4 -- +string(24) "application/octet-stream" + +-- Iteration 5 -- +string(10) "image/jpeg" + +-- Iteration 6 -- +string(10) "image/tiff" + +-- Iteration 7 -- +string(24) "application/octet-stream" + +-- Iteration 8 -- +string(24) "application/octet-stream" + +-- Iteration 9 -- +string(24) "application/octet-stream" + +-- Iteration 10 -- +string(9) "image/gif" + +-- Iteration 11 -- +string(24) "application/octet-stream" + +-- Iteration 12 -- +string(24) "application/octet-stream" +===DONE=== diff --git a/ext/gd/tests/imageantialias_error1.phpt b/ext/gd/tests/imageantialias_error1.phpt new file mode 100755 index 000000000..53fe0cc66 --- /dev/null +++ b/ext/gd/tests/imageantialias_error1.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource in imageantialias() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageantialias(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imageantialias_error2.phpt b/ext/gd/tests/imageantialias_error2.phpt new file mode 100755 index 000000000..8dad8bd11 --- /dev/null +++ b/ext/gd/tests/imageantialias_error2.phpt @@ -0,0 +1,23 @@ +--TEST-- +Testing wrong parameter passing in imageantialias() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(true) diff --git a/ext/gd/tests/imagearc_basic.phpt b/ext/gd/tests/imagearc_basic.phpt new file mode 100755 index 000000000..4647dd1e3 --- /dev/null +++ b/ext/gd/tests/imagearc_basic.phpt @@ -0,0 +1,28 @@ +--TEST-- +Testing imagearc() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +f18ad8001afefee2e9b8c08d6884425b diff --git a/ext/gd/tests/imagearc_error1.phpt b/ext/gd/tests/imagearc_error1.phpt new file mode 100755 index 000000000..423f0356a --- /dev/null +++ b/ext/gd/tests/imagearc_error1.phpt @@ -0,0 +1,29 @@ +--TEST-- +Testing wrong param passing imagearc() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagearc() expects exactly 8 parameters, 7 given in %s on line %d +abebb25b5a2813cfbf92f1f24365786a diff --git a/ext/gd/tests/imagearc_variation1.phpt b/ext/gd/tests/imagearc_variation1.phpt new file mode 100755 index 000000000..568d3a6d4 --- /dev/null +++ b/ext/gd/tests/imagearc_variation1.phpt @@ -0,0 +1,28 @@ +--TEST-- +Testing passing negative end angle to imagearc() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +ed2c8427a9922dfd8a105f10a88a0d20 diff --git a/ext/gd/tests/imagearc_variation2.phpt b/ext/gd/tests/imagearc_variation2.phpt new file mode 100755 index 000000000..045c68e61 --- /dev/null +++ b/ext/gd/tests/imagearc_variation2.phpt @@ -0,0 +1,28 @@ +--TEST-- +Testing passing negative start angle to imagearc() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +463b4aea9d9acfab30016ee92613c779 diff --git a/ext/gd/tests/imagechar_basic.phpt b/ext/gd/tests/imagechar_basic.phpt new file mode 100644 index 000000000..7e5fa931b --- /dev/null +++ b/ext/gd/tests/imagechar_basic.phpt @@ -0,0 +1,25 @@ +--TEST-- +Testing imagechar() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +e94962ac28ad03bd4142cb1abe9ef98b diff --git a/ext/gd/tests/imagechar_error1.phpt b/ext/gd/tests/imagechar_error1.phpt new file mode 100644 index 000000000..373d3042e --- /dev/null +++ b/ext/gd/tests/imagechar_error1.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-resource parameter 1 of imagechar() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagechar() expects parameter 1 to be resource, %s given in %s on line %d diff --git a/ext/gd/tests/imagechar_error2.phpt b/ext/gd/tests/imagechar_error2.phpt new file mode 100644 index 000000000..02a95994f --- /dev/null +++ b/ext/gd/tests/imagechar_error2.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-image resource parameter 1 of imagechar() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagechar(): supplied resource is not a valid Image resource in %s on line %d diff --git a/ext/gd/tests/imagechar_error3.phpt b/ext/gd/tests/imagechar_error3.phpt new file mode 100644 index 000000000..aec65e9cf --- /dev/null +++ b/ext/gd/tests/imagechar_error3.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 2 of imagechar() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagechar() expects parameter 2 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagechar_error4.phpt b/ext/gd/tests/imagechar_error4.phpt new file mode 100644 index 000000000..a9485f7bb --- /dev/null +++ b/ext/gd/tests/imagechar_error4.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 3 of imagechar() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagechar() expects parameter 3 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagechar_error5.phpt b/ext/gd/tests/imagechar_error5.phpt new file mode 100644 index 000000000..8670d1947 --- /dev/null +++ b/ext/gd/tests/imagechar_error5.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 4 of imagechar() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagechar() expects parameter 4 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagechar_error6.phpt b/ext/gd/tests/imagechar_error6.phpt new file mode 100644 index 000000000..eaef2f88c --- /dev/null +++ b/ext/gd/tests/imagechar_error6.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-string parameter 5 of imagechar() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagechar() expects parameter 5 to be string%S, %s given in %s on line %d diff --git a/ext/gd/tests/imagechar_error7.phpt b/ext/gd/tests/imagechar_error7.phpt new file mode 100644 index 000000000..fae23a71e --- /dev/null +++ b/ext/gd/tests/imagechar_error7.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 6 of imagechar() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagechar() expects parameter 6 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagecharup_basic.phpt b/ext/gd/tests/imagecharup_basic.phpt new file mode 100644 index 000000000..54c8dfaa4 --- /dev/null +++ b/ext/gd/tests/imagecharup_basic.phpt @@ -0,0 +1,25 @@ +--TEST-- +Testing imagecharup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +79b48d5cef6d489bb68573df0296d775 diff --git a/ext/gd/tests/imagecharup_error1.phpt b/ext/gd/tests/imagecharup_error1.phpt new file mode 100644 index 000000000..e0b3e318a --- /dev/null +++ b/ext/gd/tests/imagecharup_error1.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-resource parameter 1 of imagecharup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecharup() expects parameter 1 to be resource, %s given in %s on line %d diff --git a/ext/gd/tests/imagecharup_error2.phpt b/ext/gd/tests/imagecharup_error2.phpt new file mode 100644 index 000000000..b78dc9221 --- /dev/null +++ b/ext/gd/tests/imagecharup_error2.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-image resource parameter 1 of imagecharup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecharup(): supplied resource is not a valid Image resource in %s on line %d diff --git a/ext/gd/tests/imagecharup_error3.phpt b/ext/gd/tests/imagecharup_error3.phpt new file mode 100644 index 000000000..7e811bade --- /dev/null +++ b/ext/gd/tests/imagecharup_error3.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 2 of imagecharup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecharup() expects parameter 2 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagecharup_error4.phpt b/ext/gd/tests/imagecharup_error4.phpt new file mode 100644 index 000000000..f76fdaca8 --- /dev/null +++ b/ext/gd/tests/imagecharup_error4.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 3 of imagecharup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecharup() expects parameter 3 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagecharup_error5.phpt b/ext/gd/tests/imagecharup_error5.phpt new file mode 100644 index 000000000..b56525933 --- /dev/null +++ b/ext/gd/tests/imagecharup_error5.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 4 of imagecharup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecharup() expects parameter 4 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagecharup_error6.phpt b/ext/gd/tests/imagecharup_error6.phpt new file mode 100644 index 000000000..a1f12f1ea --- /dev/null +++ b/ext/gd/tests/imagecharup_error6.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-string parameter 5 of imagecharup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecharup() expects parameter 5 to be string%S, %s given in %s on line %d diff --git a/ext/gd/tests/imagecharup_error7.phpt b/ext/gd/tests/imagecharup_error7.phpt new file mode 100644 index 000000000..b61189a54 --- /dev/null +++ b/ext/gd/tests/imagecharup_error7.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 6 of imagecharup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecharup() expects parameter 6 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagecolorallocatealpha_basic.phpt b/ext/gd/tests/imagecolorallocatealpha_basic.phpt new file mode 100644 index 000000000..720c50098 --- /dev/null +++ b/ext/gd/tests/imagecolorallocatealpha_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +Testing imagecolorallocatealpha() +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(32) "b856a0b1a15efe0f79551ebbb5651fe8" +int(842163455) \ No newline at end of file diff --git a/ext/gd/tests/imagecolorallocatealpha_error1.phpt b/ext/gd/tests/imagecolorallocatealpha_error1.phpt new file mode 100644 index 000000000..a9030248b --- /dev/null +++ b/ext/gd/tests/imagecolorallocatealpha_error1.phpt @@ -0,0 +1,25 @@ +--TEST-- +Testing imagecolorallocatealpha(): Wrong types for parameter 1 +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolorallocatealpha(): supplied resource is not a valid Image resource in %s on line %d + +Warning: imagecolorallocatealpha() expects parameter 1 to be resource, %s given in %s on line %d + +Warning: imagecolorallocatealpha() expects parameter 1 to be resource, array given in %s on line %d + +Warning: imagecolorallocatealpha() expects parameter 1 to be resource, null given in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagecolorallocatealpha_error2.phpt b/ext/gd/tests/imagecolorallocatealpha_error2.phpt new file mode 100644 index 000000000..ba9e5de69 --- /dev/null +++ b/ext/gd/tests/imagecolorallocatealpha_error2.phpt @@ -0,0 +1,22 @@ +--TEST-- +Testing imagecolorallocatealpha(): Wrong types for parameter 2 +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolorallocatealpha() expects parameter 2 to be long, %s given in %s on line %d + +Warning: imagecolorallocatealpha() expects parameter 2 to be long, array given in %s on line %d + +Warning: imagecolorallocatealpha() expects parameter 2 to be long, resource given in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagecolorallocatealpha_error3.phpt b/ext/gd/tests/imagecolorallocatealpha_error3.phpt new file mode 100644 index 000000000..ee8f646e7 --- /dev/null +++ b/ext/gd/tests/imagecolorallocatealpha_error3.phpt @@ -0,0 +1,22 @@ +--TEST-- +Testing imagecolorallocatealpha(): Wrong types for parameter 3 +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolorallocatealpha() expects parameter 3 to be long, %s given in %s on line %d + +Warning: imagecolorallocatealpha() expects parameter 3 to be long, array given in %s on line %d + +Warning: imagecolorallocatealpha() expects parameter 3 to be long, resource given in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagecolorallocatealpha_error4.phpt b/ext/gd/tests/imagecolorallocatealpha_error4.phpt new file mode 100644 index 000000000..2b5b47189 --- /dev/null +++ b/ext/gd/tests/imagecolorallocatealpha_error4.phpt @@ -0,0 +1,22 @@ +--TEST-- +Testing imagecolorallocatealpha(): Wrong types for parameter 4 +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolorallocatealpha() expects parameter 4 to be long, %s given in %s on line %d + +Warning: imagecolorallocatealpha() expects parameter 4 to be long, array given in %s on line %d + +Warning: imagecolorallocatealpha() expects parameter 4 to be long, resource given in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagecolorallocatealpha_error5.phpt b/ext/gd/tests/imagecolorallocatealpha_error5.phpt new file mode 100644 index 000000000..2d77833e9 --- /dev/null +++ b/ext/gd/tests/imagecolorallocatealpha_error5.phpt @@ -0,0 +1,22 @@ +--TEST-- +Testing imagecolorallocatealpha(): Wrong types for parameter 5 +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolorallocatealpha() expects parameter 5 to be long, %s given in %s on line %d + +Warning: imagecolorallocatealpha() expects parameter 5 to be long, array given in %s on line %d + +Warning: imagecolorallocatealpha() expects parameter 5 to be long, resource given in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagecolordeallocate_basic.phpt b/ext/gd/tests/imagecolordeallocate_basic.phpt new file mode 100644 index 000000000..3c80c690f --- /dev/null +++ b/ext/gd/tests/imagecolordeallocate_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing imagecolordeallocate() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) diff --git a/ext/gd/tests/imagecolordeallocate_error1.phpt b/ext/gd/tests/imagecolordeallocate_error1.phpt new file mode 100644 index 000000000..6d642d4a2 --- /dev/null +++ b/ext/gd/tests/imagecolordeallocate_error1.phpt @@ -0,0 +1,22 @@ +--TEST-- +Testing imagecolordeallocate() of GD library with invalid resource type +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolordeallocate(): supplied resource is not a valid Image resource in %s on line %d diff --git a/ext/gd/tests/imagecolordeallocate_error2.phpt b/ext/gd/tests/imagecolordeallocate_error2.phpt new file mode 100644 index 000000000..989e0fd97 --- /dev/null +++ b/ext/gd/tests/imagecolordeallocate_error2.phpt @@ -0,0 +1,19 @@ +--TEST-- +Testing imagecolordeallocate() of GD library with no resource +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolordeallocate() expects parameter 1 to be resource, %s given %s on line %d diff --git a/ext/gd/tests/imagecolordeallocate_error3.phpt b/ext/gd/tests/imagecolordeallocate_error3.phpt new file mode 100644 index 000000000..8000218ad --- /dev/null +++ b/ext/gd/tests/imagecolordeallocate_error3.phpt @@ -0,0 +1,22 @@ +--TEST-- +Testing imagecolordeallocate() of GD library with Out of range intergers (Above) +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolordeallocate(): Color index 101 out of range in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagecolordeallocate_error4.phpt b/ext/gd/tests/imagecolordeallocate_error4.phpt new file mode 100644 index 000000000..7aaeffebe --- /dev/null +++ b/ext/gd/tests/imagecolordeallocate_error4.phpt @@ -0,0 +1,22 @@ +--TEST-- +Testing imagecolordeallocate() of GD library with Out of range intergers (Below) +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolordeallocate(): Color index -1 out of range in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagecolormatch_basic.phpt b/ext/gd/tests/imagecolormatch_basic.phpt new file mode 100755 index 000000000..1d188121b --- /dev/null +++ b/ext/gd/tests/imagecolormatch_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +Basic test imagecolormatch() of GD library +--CREDITS-- +Paulo Alves de Sousa Filho +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(true) diff --git a/ext/gd/tests/imagecolormatch_error1.phpt b/ext/gd/tests/imagecolormatch_error1.phpt new file mode 100755 index 000000000..9750a8b24 --- /dev/null +++ b/ext/gd/tests/imagecolormatch_error1.phpt @@ -0,0 +1,18 @@ +--TEST-- +Send only 1 parameter imagecolormatch() of GD library +--CREDITS-- +Paulo Alves de Sousa Filho +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolormatch() expects exactly 2 parameters, %d given in %s on line %d +NULL diff --git a/ext/gd/tests/imagecolormatch_error2.phpt b/ext/gd/tests/imagecolormatch_error2.phpt new file mode 100755 index 000000000..bdb3c2460 --- /dev/null +++ b/ext/gd/tests/imagecolormatch_error2.phpt @@ -0,0 +1,20 @@ +--TEST-- +Send not TrueColor to Image 1 parameter imagecolormatch() of GD library +--CREDITS-- +Paulo Alves de Sousa Filho +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolormatch(): Image1 must be TrueColor in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagecolormatch_error3.phpt b/ext/gd/tests/imagecolormatch_error3.phpt new file mode 100755 index 000000000..8793e1522 --- /dev/null +++ b/ext/gd/tests/imagecolormatch_error3.phpt @@ -0,0 +1,20 @@ +--TEST-- +Send not TrueColor to Image 1 parameter imagecolormatch() of GD library +--CREDITS-- +Paulo Alves de Sousa Filho +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolormatch(): Image2 must be Palette in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagecolormatch_error4.phpt b/ext/gd/tests/imagecolormatch_error4.phpt new file mode 100755 index 000000000..0bfe767c2 --- /dev/null +++ b/ext/gd/tests/imagecolormatch_error4.phpt @@ -0,0 +1,20 @@ +--TEST-- +using different image sizes imagecolormatch() of GD library +--CREDITS-- +Paulo Alves de Sousa Filho +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecolormatch(): Image1 and Image2 must be the same size in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagecolorset_basic.phpt b/ext/gd/tests/imagecolorset_basic.phpt new file mode 100755 index 000000000..a1776ff50 --- /dev/null +++ b/ext/gd/tests/imagecolorset_basic.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test imagecolorset() function : basic functionality +--CREDITS-- +Erick Belluci Tedeschi +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +6f2002aafb57b2d275fad6a6258d7476 diff --git a/ext/gd/tests/imageconvolution_basic.phpt b/ext/gd/tests/imageconvolution_basic.phpt new file mode 100755 index 000000000..5a9aa8f95 --- /dev/null +++ b/ext/gd/tests/imageconvolution_basic.phpt @@ -0,0 +1,33 @@ +--TEST-- +Testing imageconvolution() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +594576a2a2a689447ffc07eb5a73f09b diff --git a/ext/gd/tests/imageconvolution_error1.phpt b/ext/gd/tests/imageconvolution_error1.phpt new file mode 100755 index 000000000..5dc250a85 --- /dev/null +++ b/ext/gd/tests/imageconvolution_error1.phpt @@ -0,0 +1,27 @@ +--TEST-- +Testing wrong param passing imageconvolution() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageconvolution() expects exactly 4 parameters, 3 given in %s on line %d +bool(false) diff --git a/ext/gd/tests/imageconvolution_error2.phpt b/ext/gd/tests/imageconvolution_error2.phpt new file mode 100755 index 000000000..5161c198c --- /dev/null +++ b/ext/gd/tests/imageconvolution_error2.phpt @@ -0,0 +1,26 @@ +--TEST-- +Testing wrong array size 2x3 in imageconvolution() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageconvolution(): You must have 3x3 array in %s on line %d +bool(false) diff --git a/ext/gd/tests/imageconvolution_error3.phpt b/ext/gd/tests/imageconvolution_error3.phpt new file mode 100755 index 000000000..df6b148bd --- /dev/null +++ b/ext/gd/tests/imageconvolution_error3.phpt @@ -0,0 +1,27 @@ +--TEST-- +Testing wrong array size 3x2 in imageconvolution() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageconvolution(): You must have 3x3 array in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagecopymerge_basic.phpt b/ext/gd/tests/imagecopymerge_basic.phpt new file mode 100755 index 000000000..85f116262 --- /dev/null +++ b/ext/gd/tests/imagecopymerge_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +Testing imagecopymerge() of GD library +--CREDITS-- +Cleston Viel Vieira de Sousa +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(true) diff --git a/ext/gd/tests/imagecopymerge_error.phpt b/ext/gd/tests/imagecopymerge_error.phpt new file mode 100755 index 000000000..e43bf6945 --- /dev/null +++ b/ext/gd/tests/imagecopymerge_error.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing wrong parameter passing imagecopymerge() of GD library +--CREDITS-- +Cleston Viel Vieira de Sousa +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecopymerge() expects exactly 9 parameters, 0 given in %s on line %d diff --git a/ext/gd/tests/imagecreatetruecolor_basic.phpt b/ext/gd/tests/imagecreatetruecolor_basic.phpt new file mode 100644 index 000000000..5c85f5238 --- /dev/null +++ b/ext/gd/tests/imagecreatetruecolor_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +Testing imagecreatetruecolor() of GD library +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECT-- +5a8fe9864cbd20e5dbe730c77f30db95 diff --git a/ext/gd/tests/imagecreatetruecolor_error1.phpt b/ext/gd/tests/imagecreatetruecolor_error1.phpt new file mode 100644 index 000000000..e161688ce --- /dev/null +++ b/ext/gd/tests/imagecreatetruecolor_error1.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing imagecreatetruecolor(): error on non-long parameters +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecreatetruecolor() expects parameter 1 to be long, %s given in %s on line %d + +Warning: imagecreatetruecolor() expects parameter 2 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagecreatetruecolor_error2.phpt b/ext/gd/tests/imagecreatetruecolor_error2.phpt new file mode 100644 index 000000000..e4de7e382 --- /dev/null +++ b/ext/gd/tests/imagecreatetruecolor_error2.phpt @@ -0,0 +1,24 @@ +--TEST-- +Testing imagecreatetruecolor(): error on out of bound parameters +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecreatetruecolor(): Invalid image dimensions in %s on line %d + +Warning: imagecreatetruecolor(): Invalid image dimensions in %s on line %d + +Warning: imagecreatetruecolor(): Invalid image dimensions in %s on line %d + +Warning: imagecreatetruecolor(): Invalid image dimensions in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagecreatetruecolor_error3.phpt b/ext/gd/tests/imagecreatetruecolor_error3.phpt new file mode 100644 index 000000000..332cdef3a --- /dev/null +++ b/ext/gd/tests/imagecreatetruecolor_error3.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing imagecreatetruecolor(): error on wrong parameter count +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagecreatetruecolor() expects exactly 2 parameters, 0 given in %s on line %d + +Warning: imagecreatetruecolor() expects exactly 2 parameters, 1 given in %s on line %d + +Warning: imagecreatetruecolor() expects exactly 2 parameters, 3 given in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imageellipse_basic.phpt b/ext/gd/tests/imageellipse_basic.phpt new file mode 100755 index 000000000..bfd0b79f5 --- /dev/null +++ b/ext/gd/tests/imageellipse_basic.phpt @@ -0,0 +1,27 @@ +--TEST-- +Testing imageellipse() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +d8b9bc2ca224bd68569413f4617f8e1f diff --git a/ext/gd/tests/imageellipse_error1.phpt b/ext/gd/tests/imageellipse_error1.phpt new file mode 100755 index 000000000..aa8ad789d --- /dev/null +++ b/ext/gd/tests/imageellipse_error1.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing wrong param passing imageellipse() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageellipse() expects parameter 1 to be resource, %s given in %s on line %d diff --git a/ext/gd/tests/imageellipse_error2.phpt b/ext/gd/tests/imageellipse_error2.phpt new file mode 100755 index 000000000..5b65bf8a5 --- /dev/null +++ b/ext/gd/tests/imageellipse_error2.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing wrong param passing imageellipse() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageellipse() expects parameter 2 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imageellipse_error3.phpt b/ext/gd/tests/imageellipse_error3.phpt new file mode 100755 index 000000000..cbac2f0e7 --- /dev/null +++ b/ext/gd/tests/imageellipse_error3.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing wrong param passing imageellipse() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageellipse() expects parameter 3 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imageellipse_error4.phpt b/ext/gd/tests/imageellipse_error4.phpt new file mode 100755 index 000000000..dec2e0fbd --- /dev/null +++ b/ext/gd/tests/imageellipse_error4.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing wrong param passing imageellipse() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageellipse() expects parameter 4 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imageellipse_error5.phpt b/ext/gd/tests/imageellipse_error5.phpt new file mode 100755 index 000000000..4272470c6 --- /dev/null +++ b/ext/gd/tests/imageellipse_error5.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing wrong param passing imageellipse() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageellipse() expects parameter 5 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imageellipse_error6.phpt b/ext/gd/tests/imageellipse_error6.phpt new file mode 100755 index 000000000..8628525b6 --- /dev/null +++ b/ext/gd/tests/imageellipse_error6.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing wrong param passing imageellipse() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageellipse() expects parameter 6 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imageellipse_error7.phpt b/ext/gd/tests/imageellipse_error7.phpt new file mode 100755 index 000000000..23f1eeeab --- /dev/null +++ b/ext/gd/tests/imageellipse_error7.phpt @@ -0,0 +1,20 @@ +--TEST-- +Testing wrong param passing imageellipse() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageellipse(): supplied resource is not a valid Image resource in %s on line %d diff --git a/ext/gd/tests/imageellipse_error8.phpt b/ext/gd/tests/imageellipse_error8.phpt new file mode 100755 index 000000000..3fefb56bd --- /dev/null +++ b/ext/gd/tests/imageellipse_error8.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing wrong param passing imageellipse() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageellipse() expects exactly 6 parameters, %d given in %s on line %d diff --git a/ext/gd/tests/imagefilledarc_basic.phpt b/ext/gd/tests/imagefilledarc_basic.phpt new file mode 100755 index 000000000..9ff9bd371 --- /dev/null +++ b/ext/gd/tests/imagefilledarc_basic.phpt @@ -0,0 +1,28 @@ +--TEST-- +Testing imagefilledarc() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +894f394c7f2e2364642ef27fea6bfc33 diff --git a/ext/gd/tests/imagefilledarc_error1.phpt b/ext/gd/tests/imagefilledarc_error1.phpt new file mode 100755 index 000000000..b2bc4172d --- /dev/null +++ b/ext/gd/tests/imagefilledarc_error1.phpt @@ -0,0 +1,29 @@ +--TEST-- +Testing wrong param passing imagefilledarc() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilledarc() expects exactly 9 parameters, 8 given in %s on line %d +abebb25b5a2813cfbf92f1f24365786a diff --git a/ext/gd/tests/imagefilledarc_variation1.phpt b/ext/gd/tests/imagefilledarc_variation1.phpt new file mode 100755 index 000000000..2dec1ead2 --- /dev/null +++ b/ext/gd/tests/imagefilledarc_variation1.phpt @@ -0,0 +1,28 @@ +--TEST-- +Testing passing negative end angle to imagefilledarc() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +b77bbb8207e5adbebfcc8bd1c4074305 diff --git a/ext/gd/tests/imagefilledarc_variation2.phpt b/ext/gd/tests/imagefilledarc_variation2.phpt new file mode 100755 index 000000000..5c8ffba00 --- /dev/null +++ b/ext/gd/tests/imagefilledarc_variation2.phpt @@ -0,0 +1,28 @@ +--TEST-- +Testing passing negative start angle to imagefilledarc() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +b8b572812b3c85678f6c38c4ecca7619 diff --git a/ext/gd/tests/imagefilltoborder_basic.phpt b/ext/gd/tests/imagefilltoborder_basic.phpt new file mode 100755 index 000000000..80b84d2c6 --- /dev/null +++ b/ext/gd/tests/imagefilltoborder_basic.phpt @@ -0,0 +1,33 @@ +--TEST-- +Testing imagefilltoborder() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +847ec236f1c4d14c465306c8408550fc diff --git a/ext/gd/tests/imagefilltoborder_error1.phpt b/ext/gd/tests/imagefilltoborder_error1.phpt new file mode 100755 index 000000000..9412da739 --- /dev/null +++ b/ext/gd/tests/imagefilltoborder_error1.phpt @@ -0,0 +1,26 @@ +--TEST-- +Testing wrong param passing imagefilltoborder() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilltoborder() expects parameter 1 to be resource, %s given in %s on line %d diff --git a/ext/gd/tests/imagefilltoborder_error2.phpt b/ext/gd/tests/imagefilltoborder_error2.phpt new file mode 100755 index 000000000..dcbf90470 --- /dev/null +++ b/ext/gd/tests/imagefilltoborder_error2.phpt @@ -0,0 +1,26 @@ +--TEST-- +Testing wrong param passing imagefilltoborder() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilltoborder() expects parameter 2 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagefilltoborder_error3.phpt b/ext/gd/tests/imagefilltoborder_error3.phpt new file mode 100755 index 000000000..73f6cf7b8 --- /dev/null +++ b/ext/gd/tests/imagefilltoborder_error3.phpt @@ -0,0 +1,26 @@ +--TEST-- +Testing wrong param passing imagefilltoborder() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilltoborder() expects parameter 3 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagefilltoborder_error4.phpt b/ext/gd/tests/imagefilltoborder_error4.phpt new file mode 100755 index 000000000..a5073d80b --- /dev/null +++ b/ext/gd/tests/imagefilltoborder_error4.phpt @@ -0,0 +1,26 @@ +--TEST-- +Testing wrong param passing imagefilltoborder() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilltoborder() expects parameter 4 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagefilltoborder_error5.phpt b/ext/gd/tests/imagefilltoborder_error5.phpt new file mode 100755 index 000000000..eff344a78 --- /dev/null +++ b/ext/gd/tests/imagefilltoborder_error5.phpt @@ -0,0 +1,26 @@ +--TEST-- +Testing wrong param passing imagefilltoborder() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilltoborder() expects parameter 5 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagefilltoborder_error6.phpt b/ext/gd/tests/imagefilltoborder_error6.phpt new file mode 100755 index 000000000..b5ce53b0d --- /dev/null +++ b/ext/gd/tests/imagefilltoborder_error6.phpt @@ -0,0 +1,29 @@ +--TEST-- +Testing wrong param passing imagefilltoborder() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilltoborder(): supplied resource is not a valid Image resource in %s on line %d + + diff --git a/ext/gd/tests/imagefilltoborder_error7.phpt b/ext/gd/tests/imagefilltoborder_error7.phpt new file mode 100755 index 000000000..aeb7d8262 --- /dev/null +++ b/ext/gd/tests/imagefilltoborder_error7.phpt @@ -0,0 +1,26 @@ +--TEST-- +Testing wrong param passing imagefilltoborder() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilltoborder() expects exactly 5 parameters, %d given in %s on line %d diff --git a/ext/gd/tests/imagefilter_error1.phpt b/ext/gd/tests/imagefilter_error1.phpt new file mode 100755 index 000000000..fb96ae32b --- /dev/null +++ b/ext/gd/tests/imagefilter_error1.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter passing in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: Wrong parameter count for imagefilter() in %s on line %d +NULL diff --git a/ext/gd/tests/imagefilter_error10.phpt b/ext/gd/tests/imagefilter_error10.phpt new file mode 100755 index 000000000..8b4121162 --- /dev/null +++ b/ext/gd/tests/imagefilter_error10.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource of EMBOSS in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error11.phpt b/ext/gd/tests/imagefilter_error11.phpt new file mode 100755 index 000000000..9b1cf4d92 --- /dev/null +++ b/ext/gd/tests/imagefilter_error11.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource passing of EDGEDETECT in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error12.phpt b/ext/gd/tests/imagefilter_error12.phpt new file mode 100755 index 000000000..33fee28e6 --- /dev/null +++ b/ext/gd/tests/imagefilter_error12.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource of COLORIZE in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error13.phpt b/ext/gd/tests/imagefilter_error13.phpt new file mode 100755 index 000000000..687d148be --- /dev/null +++ b/ext/gd/tests/imagefilter_error13.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing wrong parameter value of COLORIZE in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(true) diff --git a/ext/gd/tests/imagefilter_error14.phpt b/ext/gd/tests/imagefilter_error14.phpt new file mode 100755 index 000000000..64103954d --- /dev/null +++ b/ext/gd/tests/imagefilter_error14.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter type of COLORIZE in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter() expects parameter 3 to be long, %unicode_string_optional% given in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error15.phpt b/ext/gd/tests/imagefilter_error15.phpt new file mode 100755 index 000000000..87a412e4c --- /dev/null +++ b/ext/gd/tests/imagefilter_error15.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource of CONTRAST in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error16.phpt b/ext/gd/tests/imagefilter_error16.phpt new file mode 100755 index 000000000..2a84c2f78 --- /dev/null +++ b/ext/gd/tests/imagefilter_error16.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter type of CONTRAST in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter() expects parameter 3 to be long, %unicode_string_optional% given in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error17.phpt b/ext/gd/tests/imagefilter_error17.phpt new file mode 100755 index 000000000..adafc3e5e --- /dev/null +++ b/ext/gd/tests/imagefilter_error17.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource of GRAYSCALE in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error18.phpt b/ext/gd/tests/imagefilter_error18.phpt new file mode 100755 index 000000000..b636bfc07 --- /dev/null +++ b/ext/gd/tests/imagefilter_error18.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource of NEGATE in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error19.phpt b/ext/gd/tests/imagefilter_error19.phpt new file mode 100755 index 000000000..e36b817aa --- /dev/null +++ b/ext/gd/tests/imagefilter_error19.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter type of BRIGHTNESS in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter() expects parameter 3 to be long, %unicode_string_optional% given in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error2.phpt b/ext/gd/tests/imagefilter_error2.phpt new file mode 100755 index 000000000..62ac6620c --- /dev/null +++ b/ext/gd/tests/imagefilter_error2.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter passing in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter() expects parameter 2 to be long, %unicode_string_optional% given in %s on line %d +NULL diff --git a/ext/gd/tests/imagefilter_error20.phpt b/ext/gd/tests/imagefilter_error20.phpt new file mode 100755 index 000000000..f3db724ac --- /dev/null +++ b/ext/gd/tests/imagefilter_error20.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource of BRIGHTNESS in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error3.phpt b/ext/gd/tests/imagefilter_error3.phpt new file mode 100755 index 000000000..67f6c199f --- /dev/null +++ b/ext/gd/tests/imagefilter_error3.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter passing of PIXELATE in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter() expects parameter 3 to be long, %unicode_string_optional% given in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error4.phpt b/ext/gd/tests/imagefilter_error4.phpt new file mode 100755 index 000000000..babb37e0a --- /dev/null +++ b/ext/gd/tests/imagefilter_error4.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource of PIXELATE in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error5.phpt b/ext/gd/tests/imagefilter_error5.phpt new file mode 100755 index 000000000..a7d944342 --- /dev/null +++ b/ext/gd/tests/imagefilter_error5.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter passing of SMOOTH in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter() expects parameter 3 to be double, %unicode_string_optional% given in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error6.phpt b/ext/gd/tests/imagefilter_error6.phpt new file mode 100755 index 000000000..05dd187a2 --- /dev/null +++ b/ext/gd/tests/imagefilter_error6.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource of SMOOTH in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error7.phpt b/ext/gd/tests/imagefilter_error7.phpt new file mode 100755 index 000000000..6c08e5acf --- /dev/null +++ b/ext/gd/tests/imagefilter_error7.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource of MEAN_REMOVAL in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error8.phpt b/ext/gd/tests/imagefilter_error8.phpt new file mode 100755 index 000000000..57c3168f7 --- /dev/null +++ b/ext/gd/tests/imagefilter_error8.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource of SELECTIVE_BLUR in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefilter_error9.phpt b/ext/gd/tests/imagefilter_error9.phpt new file mode 100755 index 000000000..a74ea643c --- /dev/null +++ b/ext/gd/tests/imagefilter_error9.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing wrong parameter resource of GAUSSIAN_BLUR in imagefilter() of GD library +--CREDITS-- +Guilherme Blanco +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefilter(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imagefontheight_basic.phpt b/ext/gd/tests/imagefontheight_basic.phpt new file mode 100644 index 000000000..bfcd0bb27 --- /dev/null +++ b/ext/gd/tests/imagefontheight_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +Testing imagefontheight() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(8) +int(13) +int(13) +int(16) +int(15) diff --git a/ext/gd/tests/imagefontheight_error1.phpt b/ext/gd/tests/imagefontheight_error1.phpt new file mode 100644 index 000000000..88d177164 --- /dev/null +++ b/ext/gd/tests/imagefontheight_error1.phpt @@ -0,0 +1,15 @@ +--TEST-- +Testing error on string parameter for imagefontheight() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefontheight() expects parameter 1 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagefontwidth_basic.phpt b/ext/gd/tests/imagefontwidth_basic.phpt new file mode 100644 index 000000000..0a9df5209 --- /dev/null +++ b/ext/gd/tests/imagefontwidth_basic.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing imagefontwidth() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(5) +int(6) +int(7) +int(8) +int(9) +bool(true) diff --git a/ext/gd/tests/imagefontwidth_error1.phpt b/ext/gd/tests/imagefontwidth_error1.phpt new file mode 100644 index 000000000..dd80034fc --- /dev/null +++ b/ext/gd/tests/imagefontwidth_error1.phpt @@ -0,0 +1,15 @@ +--TEST-- +Testing error on string parameter for imagefontwidth() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagefontwidth() expects parameter 1 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagegammacorrect_basic.phpt b/ext/gd/tests/imagegammacorrect_basic.phpt new file mode 100644 index 000000000..b568728e7 --- /dev/null +++ b/ext/gd/tests/imagegammacorrect_basic.phpt @@ -0,0 +1,32 @@ +--TEST-- +Testing imagegammacorrect() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +30639772903913594bc665743e1b9ab8 diff --git a/ext/gd/tests/imagegammacorrect_error1.phpt b/ext/gd/tests/imagegammacorrect_error1.phpt new file mode 100644 index 000000000..fdcdec8be --- /dev/null +++ b/ext/gd/tests/imagegammacorrect_error1.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error with non-resource paramenter of imagegammacorrect() of GD library, +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagegammacorrect() expects parameter 1 to be resource, %s given in %s on line %d diff --git a/ext/gd/tests/imagegammacorrect_error2.phpt b/ext/gd/tests/imagegammacorrect_error2.phpt new file mode 100644 index 000000000..604d7da79 --- /dev/null +++ b/ext/gd/tests/imagegammacorrect_error2.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error with non-Image resource paramenter of imagegammacorrect() of GD library, +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagegammacorrect(): supplied resource is not a valid Image resource in %s on line %d diff --git a/ext/gd/tests/imagegammacorrect_error3.phpt b/ext/gd/tests/imagegammacorrect_error3.phpt new file mode 100644 index 000000000..fd680aa13 --- /dev/null +++ b/ext/gd/tests/imagegammacorrect_error3.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error with non-double first paramenter of imagegammacorrect() of GD library, +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagegammacorrect() expects parameter 2 to be double, %s given in %s on line %d diff --git a/ext/gd/tests/imagegammacorrect_error4.phpt b/ext/gd/tests/imagegammacorrect_error4.phpt new file mode 100644 index 000000000..5476d4c85 --- /dev/null +++ b/ext/gd/tests/imagegammacorrect_error4.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error with non-double second paramenter of imagegammacorrect() of GD library, +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagegammacorrect() expects parameter 3 to be double, %s given in %s on line %d diff --git a/ext/gd/tests/imagegammacorrect_variation1.phpt b/ext/gd/tests/imagegammacorrect_variation1.phpt new file mode 100644 index 000000000..cda96c628 --- /dev/null +++ b/ext/gd/tests/imagegammacorrect_variation1.phpt @@ -0,0 +1,32 @@ +--TEST-- +Testing imagegammacorrect() of GD library with non TrueColor image +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +7716c0905ae08bd84b4d6cba8969a42e diff --git a/ext/gd/tests/imageinterlace_basic.phpt b/ext/gd/tests/imageinterlace_basic.phpt new file mode 100755 index 000000000..657b256d6 --- /dev/null +++ b/ext/gd/tests/imageinterlace_basic.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing imageinterlace() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(0) diff --git a/ext/gd/tests/imageinterlace_error1.phpt b/ext/gd/tests/imageinterlace_error1.phpt new file mode 100755 index 000000000..5c871e7bb --- /dev/null +++ b/ext/gd/tests/imageinterlace_error1.phpt @@ -0,0 +1,20 @@ +--TEST-- +Testing passing no parameters to imageinterlace() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageinterlace() expects at least 1 parameter, 0 given in %s on line %d +NULL diff --git a/ext/gd/tests/imageinterlace_error2.phpt b/ext/gd/tests/imageinterlace_error2.phpt new file mode 100755 index 000000000..808c88a31 --- /dev/null +++ b/ext/gd/tests/imageinterlace_error2.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing resource that is not a image to imageinterlace() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageinterlace(): supplied resource is not a valid Image resource in %s on line %d +bool(false) diff --git a/ext/gd/tests/imageinterlace_variation1.phpt b/ext/gd/tests/imageinterlace_variation1.phpt new file mode 100755 index 000000000..2c224ef41 --- /dev/null +++ b/ext/gd/tests/imageinterlace_variation1.phpt @@ -0,0 +1,20 @@ +--TEST-- +Testing setting the interlace bit on with imageinterlace() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(1) +int(1) diff --git a/ext/gd/tests/imageinterlace_variation2.phpt b/ext/gd/tests/imageinterlace_variation2.phpt new file mode 100755 index 000000000..b4735dcfb --- /dev/null +++ b/ext/gd/tests/imageinterlace_variation2.phpt @@ -0,0 +1,24 @@ +--TEST-- +Testing setting the interlace bit off with imageinterlace() of GD library +--CREDITS-- +Edgar Ferreira da Silva +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(0) +int(0) diff --git a/ext/gd/tests/imageistruecolor_basic.phpt b/ext/gd/tests/imageistruecolor_basic.phpt new file mode 100644 index 000000000..a78aaa46e --- /dev/null +++ b/ext/gd/tests/imageistruecolor_basic.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing imageistruecolor() of GD library +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) \ No newline at end of file diff --git a/ext/gd/tests/imageistruecolor_error1.phpt b/ext/gd/tests/imageistruecolor_error1.phpt new file mode 100644 index 000000000..06453b7d3 --- /dev/null +++ b/ext/gd/tests/imageistruecolor_error1.phpt @@ -0,0 +1,24 @@ +--TEST-- +Testing imageistruecolor(): wrong parameters +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imageistruecolor() expects parameter 1 to be resource, string given in %s on line %d + +Warning: imageistruecolor(): supplied resource is not a valid Image resource in %s on line %d + +Warning: imageistruecolor() expects parameter 1 to be resource, array given in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagelayereffect_basic.phpt b/ext/gd/tests/imagelayereffect_basic.phpt new file mode 100644 index 000000000..6dbc8600c --- /dev/null +++ b/ext/gd/tests/imagelayereffect_basic.phpt @@ -0,0 +1,27 @@ +--TEST-- +Testing imagelayereffect() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +5a8fe9864cbd20e5dbe730c77f30db95 diff --git a/ext/gd/tests/imagelayereffect_error1.phpt b/ext/gd/tests/imagelayereffect_error1.phpt new file mode 100644 index 000000000..ad457103c --- /dev/null +++ b/ext/gd/tests/imagelayereffect_error1.phpt @@ -0,0 +1,16 @@ +--TEST-- +Testing imagelayereffect() with invalid resource of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagelayereffect() expects parameter 1 to be resource, %s given in %s on line %d diff --git a/ext/gd/tests/imagelayereffect_error2.phpt b/ext/gd/tests/imagelayereffect_error2.phpt new file mode 100644 index 000000000..7fb993969 --- /dev/null +++ b/ext/gd/tests/imagelayereffect_error2.phpt @@ -0,0 +1,18 @@ +--TEST-- +Testing imagelayereffect() wth invalid effect of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagelayereffect() expects parameter 2 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagelayereffect_error3.phpt b/ext/gd/tests/imagelayereffect_error3.phpt new file mode 100644 index 000000000..9f9918633 --- /dev/null +++ b/ext/gd/tests/imagelayereffect_error3.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing imagelayereffect() with invalid resource of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagelayereffect(): supplied resource is not a valid Image resource in %s on line %d diff --git a/ext/gd/tests/imagerectangle_basic.phpt b/ext/gd/tests/imagerectangle_basic.phpt new file mode 100755 index 000000000..0574ad35c --- /dev/null +++ b/ext/gd/tests/imagerectangle_basic.phpt @@ -0,0 +1,27 @@ +--TEST-- +Testing imagerectangle() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +282aaecfdd50091821d63093d9bb1bb9 \ No newline at end of file diff --git a/ext/gd/tests/imagerectangle_error1.phpt b/ext/gd/tests/imagerectangle_error1.phpt new file mode 100755 index 000000000..2b4235e85 --- /dev/null +++ b/ext/gd/tests/imagerectangle_error1.phpt @@ -0,0 +1,19 @@ +--TEST-- +Testing wrong param passing imagerectangle() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagerectangle() expects parameter 1 to be resource, %s given in %s on line %d diff --git a/ext/gd/tests/imagerectangle_error2.phpt b/ext/gd/tests/imagerectangle_error2.phpt new file mode 100755 index 000000000..c6e740214 --- /dev/null +++ b/ext/gd/tests/imagerectangle_error2.phpt @@ -0,0 +1,19 @@ +--TEST-- +Testing wrong param passing imagerectangle() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagerectangle(): supplied resource is not a valid Image resource in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagerectangle_error3.phpt b/ext/gd/tests/imagerectangle_error3.phpt new file mode 100755 index 000000000..d5dd4c1d8 --- /dev/null +++ b/ext/gd/tests/imagerectangle_error3.phpt @@ -0,0 +1,19 @@ +--TEST-- +Testing wrong param passing imagerectangle() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagerectangle() expects parameter 2 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagerectangle_error4.phpt b/ext/gd/tests/imagerectangle_error4.phpt new file mode 100755 index 000000000..7ecc4167a --- /dev/null +++ b/ext/gd/tests/imagerectangle_error4.phpt @@ -0,0 +1,19 @@ +--TEST-- +Testing wrong param passing imagerectangle() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagerectangle() expects parameter 3 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagerectangle_error5.phpt b/ext/gd/tests/imagerectangle_error5.phpt new file mode 100755 index 000000000..b4288d270 --- /dev/null +++ b/ext/gd/tests/imagerectangle_error5.phpt @@ -0,0 +1,19 @@ +--TEST-- +Testing wrong param passing imagerectangle() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagerectangle() expects parameter 4 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagerectangle_error6.phpt b/ext/gd/tests/imagerectangle_error6.phpt new file mode 100755 index 000000000..aab378e55 --- /dev/null +++ b/ext/gd/tests/imagerectangle_error6.phpt @@ -0,0 +1,19 @@ +--TEST-- +Testing wrong param passing imagerectangle() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagerectangle() expects parameter 5 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagerectangle_error7.phpt b/ext/gd/tests/imagerectangle_error7.phpt new file mode 100755 index 000000000..f6ed778db --- /dev/null +++ b/ext/gd/tests/imagerectangle_error7.phpt @@ -0,0 +1,19 @@ +--TEST-- +Testing wrong param passing imagerectangle() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagerectangle() expects parameter 6 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagerectangle_error8.phpt b/ext/gd/tests/imagerectangle_error8.phpt new file mode 100755 index 000000000..361de69cd --- /dev/null +++ b/ext/gd/tests/imagerectangle_error8.phpt @@ -0,0 +1,19 @@ +--TEST-- +Testing wrong param passing imagerectangle() of GD library +--CREDITS-- +Ivan Rosolen +#testfest PHPSP on 2009-06-30 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagerectangle() expects exactly 6 parameters, %d given in %s on line %d diff --git a/ext/gd/tests/imagesetbrush_basic.phpt b/ext/gd/tests/imagesetbrush_basic.phpt new file mode 100755 index 000000000..790184ddc --- /dev/null +++ b/ext/gd/tests/imagesetbrush_basic.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test imagesetbrush() function : basic functionality +--CREDITS-- +Erick Belluci Tedeschi +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +8168577c0d1fe6d9d11397cb15263d82 diff --git a/ext/gd/tests/imagesetthickness_basic.phpt b/ext/gd/tests/imagesetthickness_basic.phpt new file mode 100644 index 000000000..a8b079bed --- /dev/null +++ b/ext/gd/tests/imagesetthickness_basic.phpt @@ -0,0 +1,34 @@ +--TEST-- +Testing imagetruecolortopalette() of GD library +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECT-- +93c3077f1bdc372cd0b0db96db282985 \ No newline at end of file diff --git a/ext/gd/tests/imagesetthickness_error1.phpt b/ext/gd/tests/imagesetthickness_error1.phpt new file mode 100644 index 000000000..0aed3a1f2 --- /dev/null +++ b/ext/gd/tests/imagesetthickness_error1.phpt @@ -0,0 +1,22 @@ +--TEST-- +Testing imagetruecolortopalette(): wrong types for first parameter +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagesetthickness() expects parameter 1 to be resource, %s given in %s on line %d + +Warning: imagesetthickness() expects parameter 1 to be resource, array given in %s on line %d + +Warning: imagesetthickness(): supplied resource is not a valid Image resource in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagesetthickness_error2.phpt b/ext/gd/tests/imagesetthickness_error2.phpt new file mode 100644 index 000000000..4c8924e46 --- /dev/null +++ b/ext/gd/tests/imagesetthickness_error2.phpt @@ -0,0 +1,24 @@ +--TEST-- +Testing imagetruecolortopalette(): wrong types for second parameter +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagesetthickness() expects parameter 2 to be long, string given in %s on line %d + +Warning: imagesetthickness() expects parameter 2 to be long, array given in %s on line %d + +Warning: imagesetthickness() expects parameter 2 to be long, resource given in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagestring_basic.phpt b/ext/gd/tests/imagestring_basic.phpt new file mode 100644 index 000000000..adc68a67f --- /dev/null +++ b/ext/gd/tests/imagestring_basic.phpt @@ -0,0 +1,25 @@ +--TEST-- +Testing imagestring() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +d0d2fe757400cb7846b36a8c34b41e4a diff --git a/ext/gd/tests/imagestring_error1.phpt b/ext/gd/tests/imagestring_error1.phpt new file mode 100644 index 000000000..b31f74ebf --- /dev/null +++ b/ext/gd/tests/imagestring_error1.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-resource parameter 1 of imagestring() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestring() expects parameter 1 to be resource, %s given in %s on line %d diff --git a/ext/gd/tests/imagestring_error2.phpt b/ext/gd/tests/imagestring_error2.phpt new file mode 100644 index 000000000..d6146f708 --- /dev/null +++ b/ext/gd/tests/imagestring_error2.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-image resource parameter 1 of imagestring() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestring(): supplied resource is not a valid Image resource in %s on line %d diff --git a/ext/gd/tests/imagestring_error3.phpt b/ext/gd/tests/imagestring_error3.phpt new file mode 100644 index 000000000..d9a9e47d2 --- /dev/null +++ b/ext/gd/tests/imagestring_error3.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 2 of imagestring() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestring() expects parameter 2 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagestring_error4.phpt b/ext/gd/tests/imagestring_error4.phpt new file mode 100644 index 000000000..40330b17b --- /dev/null +++ b/ext/gd/tests/imagestring_error4.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 3 of imagestring() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestring() expects parameter 3 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagestring_error5.phpt b/ext/gd/tests/imagestring_error5.phpt new file mode 100644 index 000000000..6f45c55a6 --- /dev/null +++ b/ext/gd/tests/imagestring_error5.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 4 of imagestring() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestring() expects parameter 4 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagestring_error6.phpt b/ext/gd/tests/imagestring_error6.phpt new file mode 100644 index 000000000..29bc79d4f --- /dev/null +++ b/ext/gd/tests/imagestring_error6.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-string parameter 5 of imagestring() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestring() expects parameter 5 to be string%S, %s given in %s on line %d diff --git a/ext/gd/tests/imagestring_error7.phpt b/ext/gd/tests/imagestring_error7.phpt new file mode 100644 index 000000000..75ab2f6af --- /dev/null +++ b/ext/gd/tests/imagestring_error7.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 6 of imagestring() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestring() expects parameter 6 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagestringup_basic.phpt b/ext/gd/tests/imagestringup_basic.phpt new file mode 100644 index 000000000..0c748b6aa --- /dev/null +++ b/ext/gd/tests/imagestringup_basic.phpt @@ -0,0 +1,25 @@ +--TEST-- +Testing imagestringup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +7c28016adcf620b772af2a8655b87bd2 diff --git a/ext/gd/tests/imagestringup_error1.phpt b/ext/gd/tests/imagestringup_error1.phpt new file mode 100644 index 000000000..14477273b --- /dev/null +++ b/ext/gd/tests/imagestringup_error1.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-resource parameter 1 of imagestringup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestringup() expects parameter 1 to be resource, %s given in %s on line %d diff --git a/ext/gd/tests/imagestringup_error2.phpt b/ext/gd/tests/imagestringup_error2.phpt new file mode 100644 index 000000000..d1d5aa26a --- /dev/null +++ b/ext/gd/tests/imagestringup_error2.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-image resource parameter 1 of imagestringup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestringup(): supplied resource is not a valid Image resource in %s on line %d diff --git a/ext/gd/tests/imagestringup_error3.phpt b/ext/gd/tests/imagestringup_error3.phpt new file mode 100644 index 000000000..27e9007d3 --- /dev/null +++ b/ext/gd/tests/imagestringup_error3.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 2 of imagestringup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestringup() expects parameter 2 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagestringup_error4.phpt b/ext/gd/tests/imagestringup_error4.phpt new file mode 100644 index 000000000..af2b8c05f --- /dev/null +++ b/ext/gd/tests/imagestringup_error4.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 3 of imagestringup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestringup() expects parameter 3 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagestringup_error5.phpt b/ext/gd/tests/imagestringup_error5.phpt new file mode 100644 index 000000000..6f45c55a6 --- /dev/null +++ b/ext/gd/tests/imagestringup_error5.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 4 of imagestring() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestring() expects parameter 4 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagestringup_error6.phpt b/ext/gd/tests/imagestringup_error6.phpt new file mode 100644 index 000000000..ac6fe4a88 --- /dev/null +++ b/ext/gd/tests/imagestringup_error6.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-string parameter 5 of imagestringup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestringup() expects parameter 5 to be string%S, %s given in %s on line %d diff --git a/ext/gd/tests/imagestringup_error7.phpt b/ext/gd/tests/imagestringup_error7.phpt new file mode 100644 index 000000000..396f2ddd6 --- /dev/null +++ b/ext/gd/tests/imagestringup_error7.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing error on non-long parameter 6 of imagestringup() of GD library +--CREDITS-- +Rafael Dohms +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagestringup() expects parameter 6 to be long, %s given in %s on line %d diff --git a/ext/gd/tests/imagetruecolortopalette_basic.phpt b/ext/gd/tests/imagetruecolortopalette_basic.phpt new file mode 100644 index 000000000..b0a0394b5 --- /dev/null +++ b/ext/gd/tests/imagetruecolortopalette_basic.phpt @@ -0,0 +1,31 @@ +--TEST-- +Testing imagetruecolortopalette() of GD library +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(true) +0843f63ab2f9fddedd69b0b421686bc5 \ No newline at end of file diff --git a/ext/gd/tests/imagetruecolortopalette_error1.phpt b/ext/gd/tests/imagetruecolortopalette_error1.phpt new file mode 100644 index 000000000..ecafa158b --- /dev/null +++ b/ext/gd/tests/imagetruecolortopalette_error1.phpt @@ -0,0 +1,26 @@ +--TEST-- +Testing imagetruecolortopalette(): wrong parameters for parameter 1 +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagetruecolortopalette(): supplied resource is not a valid Image resource in %s on line %d + +Warning: imagetruecolortopalette() expects parameter 1 to be resource, %s given in %s on line %d + +Warning: imagetruecolortopalette() expects parameter 1 to be resource, array given in %s on line %d + +Warning: imagetruecolortopalette() expects parameter 1 to be resource, null given in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagetruecolortopalette_error2.phpt b/ext/gd/tests/imagetruecolortopalette_error2.phpt new file mode 100644 index 000000000..cb7004caa --- /dev/null +++ b/ext/gd/tests/imagetruecolortopalette_error2.phpt @@ -0,0 +1,22 @@ +--TEST-- +Testing imagetruecolortopalette(): wrong parameters for parameter 2 +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagetruecolortopalette() expects parameter 2 to be boolean, resource given in %s on line %d + +Warning: imagetruecolortopalette() expects parameter 2 to be boolean, array given in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagetruecolortopalette_error3.phpt b/ext/gd/tests/imagetruecolortopalette_error3.phpt new file mode 100644 index 000000000..d65a99501 --- /dev/null +++ b/ext/gd/tests/imagetruecolortopalette_error3.phpt @@ -0,0 +1,28 @@ +--TEST-- +Testing imagetruecolortopalette(): wrong parameters for parameter 3 +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagetruecolortopalette() expects parameter 3 to be long, string given in %s on line %d + +Warning: imagetruecolortopalette() expects parameter 3 to be long, resource given in %s on line %d + +Warning: imagetruecolortopalette() expects parameter 3 to be long, array given in %s on line %d + +Warning: imagetruecolortopalette(): Number of colors has to be greater than zero in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/imagetruecolortopalette_error4.phpt b/ext/gd/tests/imagetruecolortopalette_error4.phpt new file mode 100644 index 000000000..b9661e3b8 --- /dev/null +++ b/ext/gd/tests/imagetruecolortopalette_error4.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing imagetruecolortopalette(): out of range parameter 3 +--CREDITS-- +Rafael Dohms +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: imagetruecolortopalette(): Number of colors has to be greater than zero in %s on line %d + +Warning: imagetruecolortopalette(): Number of colors has to be greater than zero in %s on line %d \ No newline at end of file diff --git a/ext/gd/tests/jpeg2wbmp_error1.phpt b/ext/gd/tests/jpeg2wbmp_error1.phpt new file mode 100755 index 000000000..d0496cc82 --- /dev/null +++ b/ext/gd/tests/jpeg2wbmp_error1.phpt @@ -0,0 +1,42 @@ +--TEST-- +Test jpeg2wbmp() function : wrong threshold value param +--CREDITS-- +Levi Fukumori +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: jpeg2wbmp(): Invalid threshold value '9' in %s on line %d + +Warning: jpeg2wbmp(): Invalid threshold value '-1' in %s on line %d +--CLEAN-- + diff --git a/ext/gd/tests/jpeg2wbmp_error2.phpt b/ext/gd/tests/jpeg2wbmp_error2.phpt new file mode 100755 index 000000000..692dcb842 --- /dev/null +++ b/ext/gd/tests/jpeg2wbmp_error2.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test jpeg2wbmp() function : wrong origin filename param +--CREDITS-- +Levi Fukumori +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: jpeg2wbmp(): Unable to open '' for reading in %s on line %d + +Warning: jpeg2wbmp(): Unable to open '' for reading in %s on line %d + +Warning: jpeg2wbmp(): Unable to open '' for reading in %s on line %d +--CLEAN-- + diff --git a/ext/gd/tests/jpeg2wbmp_error3.phpt b/ext/gd/tests/jpeg2wbmp_error3.phpt new file mode 100755 index 000000000..df436c8cc --- /dev/null +++ b/ext/gd/tests/jpeg2wbmp_error3.phpt @@ -0,0 +1,43 @@ +--TEST-- +Test jpeg2wbmp() function : wrong destination filename param +--CREDITS-- +Levi Fukumori +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: jpeg2wbmp(): Unable to open '' for writing in %s on line %d + +Warning: jpeg2wbmp(): Unable to open '' for writing in %s on line %d + +Warning: jpeg2wbmp(): Unable to open '' for writing in %s on line %d +--CLEAN-- + diff --git a/ext/gd/tests/png2wbmp_error1.phpt b/ext/gd/tests/png2wbmp_error1.phpt new file mode 100755 index 000000000..1e9d717d9 --- /dev/null +++ b/ext/gd/tests/png2wbmp_error1.phpt @@ -0,0 +1,42 @@ +--TEST-- +Test png2wbmp() function : wrong threshold value param +--CREDITS-- +Levi Fukumori +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: png2wbmp(): Invalid threshold value '9' in %s on line %d + +Warning: png2wbmp(): Invalid threshold value '-1' in %s on line %d +--CLEAN-- + diff --git a/ext/gd/tests/png2wbmp_error2.phpt b/ext/gd/tests/png2wbmp_error2.phpt new file mode 100755 index 000000000..ba8e43e7f --- /dev/null +++ b/ext/gd/tests/png2wbmp_error2.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test png2wbmp() function : wrong origin filename param +--CREDITS-- +Levi Fukumori +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: png2wbmp(): Unable to open '' for reading in %s on line %d + +Warning: png2wbmp(): Unable to open '' for reading in %s on line %d + +Warning: png2wbmp(): Unable to open '' for reading in %s on line %d +--CLEAN-- + diff --git a/ext/gd/tests/png2wbmp_error3.phpt b/ext/gd/tests/png2wbmp_error3.phpt new file mode 100755 index 000000000..1e33f59b1 --- /dev/null +++ b/ext/gd/tests/png2wbmp_error3.phpt @@ -0,0 +1,43 @@ +--TEST-- +Test png2wbmp() function : wrong destination filename param +--CREDITS-- +Levi Fukumori +#testfest PHPSP on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: png2wbmp(): Unable to open '' for writing in %s on line %d + +Warning: png2wbmp(): Unable to open '' for writing in %s on line %d + +Warning: png2wbmp(): Unable to open '' for writing in %s on line %d +--CLEAN-- + diff --git a/ext/gd/tests/test8859.ttf b/ext/gd/tests/test8859.ttf index ccdc23a59..dff237cd2 100644 Binary files a/ext/gd/tests/test8859.ttf and b/ext/gd/tests/test8859.ttf differ diff --git a/ext/gd/tests/truecolor.phpt b/ext/gd/tests/truecolor.phpt deleted file mode 100644 index 9e30cbe29..000000000 --- a/ext/gd/tests/truecolor.phpt +++ /dev/null @@ -1,19 +0,0 @@ ---TEST-- -imageistruecolor, truecolortopalette ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -ok -ok -ok diff --git a/ext/gettext/config.m4 b/ext/gettext/config.m4 index b439540dd..83942a344 100644 --- a/ext/gettext/config.m4 +++ b/ext/gettext/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.15 2005/05/29 23:16:41 sniper Exp $ +dnl $Id: config.m4 187290 2005-05-29 23:17:16Z sniper $ dnl PHP_ARG_WITH(gettext,for GNU gettext support, diff --git a/ext/gettext/config.w32 b/ext/gettext/config.w32 index a3a9fd07d..c54086aae 100644 --- a/ext/gettext/config.w32 +++ b/ext/gettext/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.2.4.1.4.1 2008/08/01 21:20:08 pajoye Exp $ +// $Id: config.w32 264053 2008-08-01 21:20:08Z pajoye $ // vim:ft=javascript ARG_WITH("gettext", "gettext support", "no"); diff --git a/ext/gettext/gettext.c b/ext/gettext/gettext.c index 76fd771f1..7a5f8d204 100644 --- a/ext/gettext/gettext.c +++ b/ext/gettext/gettext.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: gettext.c,v 1.46.2.2.2.4.2.10 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: gettext.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/gettext/php_gettext.h b/ext/gettext/php_gettext.h index 954240d92..926b87742 100644 --- a/ext/gettext/php_gettext.h +++ b/ext/gettext/php_gettext.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_gettext.h,v 1.20.2.1.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_gettext.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_GETTEXT_H #define PHP_GETTEXT_H diff --git a/ext/gettext/tests/gettext_basic.phpt b/ext/gettext/tests/gettext_basic.phpt index 2bbc3806f..d95730dd1 100644 --- a/ext/gettext/tests/gettext_basic.phpt +++ b/ext/gettext/tests/gettext_basic.phpt @@ -10,7 +10,7 @@ Gettext basic test } ?> --FILE-- - --FILE-- - --FILE-- -state >> 24) & 0xff); - digest[2] = (unsigned char) ((context->state >> 16) & 0xff); - digest[1] = (unsigned char) ((context->state >> 8) & 0xff); - digest[0] = (unsigned char) (context->state & 0xff); + digest[0] = (unsigned char) ((context->state >> 24) & 0xff); + digest[1] = (unsigned char) ((context->state >> 16) & 0xff); + digest[2] = (unsigned char) ((context->state >> 8) & 0xff); + digest[3] = (unsigned char) (context->state & 0xff); context->state = 0; } diff --git a/ext/hash/hash_crc32.c b/ext/hash/hash_crc32.c index 8803f6ab1..cbce06653 100644 --- a/ext/hash/hash_crc32.c +++ b/ext/hash/hash_crc32.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: hash_crc32.c,v 1.2.2.3.2.2.2.4 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: hash_crc32.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_hash.h" #include "php_hash_crc32.h" diff --git a/ext/hash/hash_gost.c b/ext/hash/hash_gost.c index 016035b49..dfc507877 100644 --- a/ext/hash/hash_gost.c +++ b/ext/hash/hash_gost.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: hash_gost.c,v 1.2.2.3.2.2.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: hash_gost.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_hash.h" #include "php_hash_gost.h" diff --git a/ext/hash/hash_haval.c b/ext/hash/hash_haval.c index 70c1f98d7..b21f53dab 100644 --- a/ext/hash/hash_haval.c +++ b/ext/hash/hash_haval.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: hash_haval.c,v 1.4.2.3.2.2.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: hash_haval.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_hash.h" #include "php_hash_haval.h" diff --git a/ext/hash/hash_md.c b/ext/hash/hash_md.c index 5b2550063..6423aefe0 100644 --- a/ext/hash/hash_md.c +++ b/ext/hash/hash_md.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: hash_md.c,v 1.6.2.4.2.3.2.4 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: hash_md.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_hash.h" #include "php_hash_md.h" diff --git a/ext/hash/hash_ripemd.c b/ext/hash/hash_ripemd.c index 076bd02f7..a3e9972a6 100644 --- a/ext/hash/hash_ripemd.c +++ b/ext/hash/hash_ripemd.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: hash_ripemd.c,v 1.5.2.3.2.3.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: hash_ripemd.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* Heavily borrowed from md5.c & sha1.c of PHP archival fame Note that ripemd laughs in the face of logic and uses diff --git a/ext/hash/hash_salsa.c b/ext/hash/hash_salsa.c index 1f5a7e40b..0b1446606 100644 --- a/ext/hash/hash_salsa.c +++ b/ext/hash/hash_salsa.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: hash_salsa.c,v 1.3.2.3.2.2.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: hash_salsa.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_hash.h" #include "php_hash_salsa.h" diff --git a/ext/hash/hash_sha.c b/ext/hash/hash_sha.c index 4f23ceb44..177919db1 100644 --- a/ext/hash/hash_sha.c +++ b/ext/hash/hash_sha.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: hash_sha.c,v 1.10.2.3.2.2.2.4 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: hash_sha.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_hash.h" #include "php_hash_sha.h" diff --git a/ext/hash/hash_snefru.c b/ext/hash/hash_snefru.c index 927354600..56a5aaa9c 100644 --- a/ext/hash/hash_snefru.c +++ b/ext/hash/hash_snefru.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: hash_snefru.c,v 1.3.2.3.2.2.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: hash_snefru.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_hash.h" #include "php_hash_snefru.h" diff --git a/ext/hash/hash_tiger.c b/ext/hash/hash_tiger.c index e100d6ec7..eba5226c0 100644 --- a/ext/hash/hash_tiger.c +++ b/ext/hash/hash_tiger.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: hash_tiger.c,v 1.4.2.4.2.3.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: hash_tiger.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_hash.h" #include "php_hash_tiger.h" diff --git a/ext/hash/hash_whirlpool.c b/ext/hash/hash_whirlpool.c index 8b53ec6ba..18947f50a 100644 --- a/ext/hash/hash_whirlpool.c +++ b/ext/hash/hash_whirlpool.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: hash_whirlpool.c,v 1.3.2.3.2.2.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: hash_whirlpool.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_hash.h" diff --git a/ext/hash/php_hash.h b/ext/hash/php_hash.h index 4db814608..93e57be87 100644 --- a/ext/hash/php_hash.h +++ b/ext/hash/php_hash.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash.h,v 1.13.2.7.2.3.2.6 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_H #define PHP_HASH_H diff --git a/ext/hash/php_hash_adler32.h b/ext/hash/php_hash_adler32.h index 7c2a7816b..4d1e86c84 100644 --- a/ext/hash/php_hash_adler32.h +++ b/ext/hash/php_hash_adler32.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_adler32.h,v 1.3.2.3.2.1.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_adler32.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_ADLER32_H #define PHP_HASH_ADLER32_H diff --git a/ext/hash/php_hash_crc32.h b/ext/hash/php_hash_crc32.h index 8f7a45d4e..d41f7e33c 100644 --- a/ext/hash/php_hash_crc32.h +++ b/ext/hash/php_hash_crc32.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_crc32.h,v 1.3.2.3.2.1.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_crc32.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_CRC32_H #define PHP_HASH_CRC32_H diff --git a/ext/hash/php_hash_crc32_tables.h b/ext/hash/php_hash_crc32_tables.h index 5c8a95263..5a4d82fe4 100644 --- a/ext/hash/php_hash_crc32_tables.h +++ b/ext/hash/php_hash_crc32_tables.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_crc32_tables.h,v 1.2.2.3.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_crc32_tables.h 272370 2008-12-31 11:15:49Z sebastian $ */ static const php_hash_uint32 crc32_table[] = { 0x0, 0x04c11db7, 0x09823b6e, 0x0d4326d9, 0x130476dc, 0x17c56b6b, diff --git a/ext/hash/php_hash_gost.h b/ext/hash/php_hash_gost.h index de2f527ab..ac025eb17 100644 --- a/ext/hash/php_hash_gost.h +++ b/ext/hash/php_hash_gost.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_gost.h,v 1.2.2.4.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_gost.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_GOST_H #define PHP_HASH_GOST_H diff --git a/ext/hash/php_hash_haval.h b/ext/hash/php_hash_haval.h index 26be4bf25..267548644 100644 --- a/ext/hash/php_hash_haval.h +++ b/ext/hash/php_hash_haval.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_haval.h,v 1.2.2.3.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_haval.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_HAVAL_H #define PHP_HASH_HAVAL_H diff --git a/ext/hash/php_hash_md.h b/ext/hash/php_hash_md.h index 401acd978..7256032de 100644 --- a/ext/hash/php_hash_md.h +++ b/ext/hash/php_hash_md.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_md.h,v 1.2.2.4.2.2.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_md.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_MD_H #define PHP_HASH_MD_H diff --git a/ext/hash/php_hash_ripemd.h b/ext/hash/php_hash_ripemd.h index dda8a9c70..41680deec 100644 --- a/ext/hash/php_hash_ripemd.h +++ b/ext/hash/php_hash_ripemd.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_ripemd.h,v 1.2.2.3.2.2.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_ripemd.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_RIPEMD_H #define PHP_HASH_RIPEMD_H diff --git a/ext/hash/php_hash_salsa.h b/ext/hash/php_hash_salsa.h index 0a9babe7b..57609c74c 100644 --- a/ext/hash/php_hash_salsa.h +++ b/ext/hash/php_hash_salsa.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_salsa.h,v 1.4.2.4.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_salsa.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_SALSA_H #define PHP_HASH_SALSA_H diff --git a/ext/hash/php_hash_sha.h b/ext/hash/php_hash_sha.h index 290b30da3..4dcc785da 100644 --- a/ext/hash/php_hash_sha.h +++ b/ext/hash/php_hash_sha.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_sha.h,v 1.3.2.3.2.1.2.3 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_sha.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_SHA_H #define PHP_HASH_SHA_H diff --git a/ext/hash/php_hash_snefru.h b/ext/hash/php_hash_snefru.h index 47580aa84..7d472108d 100644 --- a/ext/hash/php_hash_snefru.h +++ b/ext/hash/php_hash_snefru.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_snefru.h,v 1.2.2.4.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_snefru.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_SNEFRU_H #define PHP_HASH_SNEFRU_H diff --git a/ext/hash/php_hash_snefru_tables.h b/ext/hash/php_hash_snefru_tables.h index 86f6e5c8a..94304ceed 100644 --- a/ext/hash/php_hash_snefru_tables.h +++ b/ext/hash/php_hash_snefru_tables.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_snefru_tables.h,v 1.3.2.3.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_snefru_tables.h 272370 2008-12-31 11:15:49Z sebastian $ */ static const php_hash_uint32 tables[16][256]= { diff --git a/ext/hash/php_hash_tiger.h b/ext/hash/php_hash_tiger.h index 1411cf5f4..70b6b683e 100644 --- a/ext/hash/php_hash_tiger.h +++ b/ext/hash/php_hash_tiger.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_tiger.h,v 1.3.2.3.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_tiger.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_TIGER_H #define PHP_HASH_TIGER_H diff --git a/ext/hash/php_hash_tiger_tables.h b/ext/hash/php_hash_tiger_tables.h index dc7e70b01..9de52a73a 100644 --- a/ext/hash/php_hash_tiger_tables.h +++ b/ext/hash/php_hash_tiger_tables.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_tiger_tables.h,v 1.2.2.3.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_tiger_tables.h 272370 2008-12-31 11:15:49Z sebastian $ */ #define t1 (table) #define t2 (table+256) diff --git a/ext/hash/php_hash_types.h b/ext/hash/php_hash_types.h index 34f045654..9cb50b93f 100644 --- a/ext/hash/php_hash_types.h +++ b/ext/hash/php_hash_types.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_types.h,v 1.2.2.4.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_types.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_TYPES_H #define PHP_HASH_TYPES_H diff --git a/ext/hash/php_hash_whirlpool.h b/ext/hash/php_hash_whirlpool.h index 539e49765..841c5ab32 100644 --- a/ext/hash/php_hash_whirlpool.h +++ b/ext/hash/php_hash_whirlpool.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_whirlpool.h,v 1.2.2.4.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_whirlpool.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_WHIRLPOOL_H #define PHP_HASH_WHIRLPOOL_H diff --git a/ext/hash/php_hash_whirlpool_tables.h b/ext/hash/php_hash_whirlpool_tables.h index a2cb00d2d..562455877 100644 --- a/ext/hash/php_hash_whirlpool_tables.h +++ b/ext/hash/php_hash_whirlpool_tables.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_hash_whirlpool_tables.h,v 1.1.2.3.2.1.2.2 2008/12/31 11:15:37 sebastian Exp $ */ +/* $Id: php_hash_whirlpool_tables.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HASH_WHIRLPOOL_TABLES_H #define PHP_HASH_WHIRLPOOL_TABLES_H diff --git a/ext/hash/tests/adler32.phpt b/ext/hash/tests/adler32.phpt index acfcc2b27..eab2a3f1f 100644 --- a/ext/hash/tests/adler32.phpt +++ b/ext/hash/tests/adler32.phpt @@ -13,10 +13,10 @@ echo hash('adler32', 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012345 echo hash('adler32', '12345678901234567890123456789012345678901234567890123456789012345678901234567890'), "\n"; ?> --EXPECT-- -01000000 -62006200 -27014d02 -86057529 -200b8690 -0c15db8a -6910b697 +00000001 +00620062 +024d0127 +29750586 +90860b20 +8adb150c +97b61069 diff --git a/ext/hash/tests/hash_copy_001.phpt b/ext/hash/tests/hash_copy_001.phpt index 5c0e8ee49..ffc87c3a8 100644 --- a/ext/hash/tests/hash_copy_001.phpt +++ b/ext/hash/tests/hash_copy_001.phpt @@ -71,8 +71,8 @@ string(64) "fbe88daa74c89b9e29468fa3cd3a657d31845e21bb58dd3f8d806f5179a85c26" string(64) "fbe88daa74c89b9e29468fa3cd3a657d31845e21bb58dd3f8d806f5179a85c26" string(64) "5820c7c4a0650587538b30ef4099f2b5993069758d5c847a552e6ef7360766a5" string(64) "5820c7c4a0650587538b30ef4099f2b5993069758d5c847a552e6ef7360766a5" -string(8) "28097c6f" -string(8) "28097c6f" +string(8) "6f7c0928" +string(8) "6f7c0928" string(8) "e5cfc160" string(8) "e5cfc160" string(8) "69147a4e" @@ -155,8 +155,8 @@ string(64) "fbe88daa74c89b9e29468fa3cd3a657d31845e21bb58dd3f8d806f5179a85c26" string(64) "614ca924864fa0e8fa309aa0944e047d5edbfd4964a35858f4d8ec66a0fb88b0" string(64) "5820c7c4a0650587538b30ef4099f2b5993069758d5c847a552e6ef7360766a5" string(64) "a00961e371287c71c527a41c14564f13b6ed12ac7cd9d5f5dfb3542a25e28d3b" -string(8) "28097c6f" -string(8) "471714d9" +string(8) "6f7c0928" +string(8) "d9141747" string(8) "e5cfc160" string(8) "59f8d3d2" string(8) "69147a4e" diff --git a/ext/hash/tests/hash_file_basic1.phpt b/ext/hash/tests/hash_file_basic1.phpt index 5a7f47603..0e177e909 100644 --- a/ext/hash/tests/hash_file_basic1.phpt +++ b/ext/hash/tests/hash_file_basic1.phpt @@ -61,7 +61,7 @@ unlink($file); ===Done=== --EXPECTF-- *** Testing hash_file() : basic functionality *** -adler32: 2e2287ff +adler32: ff87222e crc32: 61664d33 gost: d9e65f0c0c2ef944e4f8a01f4a46365c4f33a2853756878182a7f03e1490a4cd haval128,3: 8bb81269aca8b7f87829020d76a4e841 @@ -79,7 +79,7 @@ sha512: 1f42adaf938fbf136e381b164bae5f984c7f9fe60c82728bd889c14f187c7d63e81a0305 snefru: d414b2345d3e7fa1a31c044cf334bfc1fec24d89e464411998d579d24663895f tiger192,3: c6fa75a0be4ecf7afa3cafb4e2a08efc3a40534c0e46b971 whirlpool: 4248b149e000477269a4a5f1a84d97cfc3d0199b7aaf505913e6f010a6f83276029d11a9ad545374bc710eb59c7d958985023ab886ffa9ec9a23852844c764ec -adler32(raw): 2e2287ff +adler32(raw): ff87222e md5(raw): 704bf818448f5bbb94061332d2c889aa sha256(raw): a0f5702fa5d3670b80033d668e8732b70550392abb53841355447f8bb0f72245 -===Done=== \ No newline at end of file +===Done=== diff --git a/ext/hash/tests/hash_hmac_basic.phpt b/ext/hash/tests/hash_hmac_basic.phpt index 645135149..801e99a31 100644 --- a/ext/hash/tests/hash_hmac_basic.phpt +++ b/ext/hash/tests/hash_hmac_basic.phpt @@ -42,7 +42,7 @@ echo "sha256(raw): " . bin2hex(hash_hmac('sha256', $content, $key, TRUE)) . "\n" ===Done=== --EXPECTF-- *** Testing hash_hmac() : basic functionality *** -adler32: 9e033311 +adler32: 12c803f7 crc32: 96859101 gost: a4a3c80bdf3f8665bf07376a34dc9c1b11af7c813f4928f62e39f0c0dc564dad haval128,3: 82cd0f4bd36729b5c80c33efa8c13ac5 @@ -60,7 +60,7 @@ sha512: 7de05636b18e2b0ca3427e03f53074af3a48a7b9df226daba4f22324c570638e7d7b2643 snefru: 67af483046f9cf16fe19f9087929ccfc6ad176ade3290b4d33f43e0ddb07e711 tiger192,3: 82779797cdc439e886884953ba21fa38e35679041e95ee27 whirlpool: 4a0f1582b21b7aff59bfba7f9c29131c69741b2ce80acdc7d314040f3b768cf5a17e30b74cceb86fbc6b34b1692e0addd5bfd7cfc043d40c0621f1b97e26fa49 -adler32(raw): 9e033311 +adler32(raw): 12c803f7 md5(raw): 2a632783e2812cf23de100d7d6a463ae sha256(raw): 49bde3496b9510a17d0edd8a4b0ac70148e32a1d51e881ec76faa96534125838 -===Done=== \ No newline at end of file +===Done=== diff --git a/ext/hash/tests/hash_hmac_file_basic.phpt b/ext/hash/tests/hash_hmac_file_basic.phpt index bd5c4137b..c8caf71c2 100644 --- a/ext/hash/tests/hash_hmac_file_basic.phpt +++ b/ext/hash/tests/hash_hmac_file_basic.phpt @@ -70,7 +70,7 @@ unlink($file); ===Done=== --EXPECTF-- *** Testing hash_hmac_file() : basic functionality *** -adler32: 9f037811 +adler32: 0f8c02f9 crc32: f2a60b9c gost: 94c39a40d5db852a8dc3d24e37eebf2d53e3d711457c59cd02b614f792a9d918 haval128,3: e8fcff647f1a675acb429130fb94a17e @@ -88,7 +88,7 @@ sha512: d460aabdf0353655059ed0d408efa91f19c4cda46acc2a4e0adf4764b06951c899fbb2ed snefru: 7b79787e1c1d926b6cc98327f05c5d04ba6227ab51c1398661861196016ef34c tiger192,3: 5577f21e2af269fff41e023db30e2b01bfd8b8f669177929 whirlpool: 37a0fbb90547690d5e5e11c046f6654ffdb7bab15e16d9d79c7d85765cc4bdcbfd9df8db7a3ce9558f3f244fead00ca29cf05297f75596555195a0683f15d69f -adler32(raw): 9f037811 +adler32(raw): 0f8c02f9 md5(raw): 8bddf39dd1c566c27acc7fa85ec36acf sha256(raw): 9135286ca4c84dec711e4b831f6cd39e672e5ff93d011321274eb76733cc1e40 Error cases: @@ -98,4 +98,4 @@ Warning: hash_hmac_file() expects at least 3 parameters, 0 given in %s on line % Warning: hash_hmac_file() expects at least 3 parameters, 2 given in %s on line %d Warning: hash_hmac_file() expects at most 4 parameters, 5 given in %s on line %d -===Done=== \ No newline at end of file +===Done=== diff --git a/ext/iconv/config.m4 b/ext/iconv/config.m4 index bdf0e9bc3..13e03710b 100644 --- a/ext/iconv/config.m4 +++ b/ext/iconv/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.33.2.4.2.1.2.1 2007/12/04 11:27:25 tony2001 Exp $ +dnl $Id: config.m4 247585 2007-12-04 11:27:25Z tony2001 $ dnl PHP_ARG_WITH(iconv, for iconv support, diff --git a/ext/iconv/config.w32 b/ext/iconv/config.w32 index 45574a72e..cd800f354 100644 --- a/ext/iconv/config.w32 +++ b/ext/iconv/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.6.6.1 2008/07/06 16:59:13 pajoye Exp $ +// $Id: config.w32 262128 2008-07-06 16:59:13Z pajoye $ // vim: ft=javascript ARG_WITH("iconv", "iconv support", "yes"); diff --git a/ext/iconv/iconv.c b/ext/iconv/iconv.c index 8f8da5df9..e5ef4b38a 100644 --- a/ext/iconv/iconv.c +++ b/ext/iconv/iconv.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: iconv.c,v 1.124.2.8.2.20.2.14 2009/03/17 05:31:04 moriyoshi Exp $ */ +/* $Id: iconv.c 277327 2009-03-17 05:31:04Z moriyoshi $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/iconv/php_iconv.h b/ext/iconv/php_iconv.h index 8e7cd2fd9..a19e56f7b 100644 --- a/ext/iconv/php_iconv.h +++ b/ext/iconv/php_iconv.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Revision: 1.28.2.2.2.2.2.5 $ */ +/* $Revision: 272370 $ */ #ifndef PHP_ICONV_H #define PHP_ICONV_H diff --git a/ext/iconv/tests/bug16069.phpt b/ext/iconv/tests/bug16069.phpt deleted file mode 100644 index 81fc235e2..000000000 --- a/ext/iconv/tests/bug16069.phpt +++ /dev/null @@ -1,22 +0,0 @@ ---TEST-- -Bug #16069 (ICONV transliteration failure) ---SKIPIF-- - ---INI-- -error_reporting=2039 ---FILE-- - ---EXPECT-- -ߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥСߥС(맥) diff --git a/ext/iconv/tests/iconv_get_encoding_basic.phpt b/ext/iconv/tests/iconv_get_encoding_basic.phpt new file mode 100644 index 000000000..83efd1586 --- /dev/null +++ b/ext/iconv/tests/iconv_get_encoding_basic.phpt @@ -0,0 +1,76 @@ +--TEST-- +iconv_get_encoding() parameter tests +--CREDITS-- +Oystein Rose +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(5) "UTF-8" +string(5) "UTF-8" +string(5) "UTF-8" +array(3) { + ["input_encoding"]=> + string(5) "UTF-8" + ["output_encoding"]=> + string(5) "UTF-8" + ["internal_encoding"]=> + string(5) "UTF-8" +} +bool(false) +array(3) { + ["input_encoding"]=> + string(5) "UTF-8" + ["output_encoding"]=> + string(5) "UTF-8" + ["internal_encoding"]=> + string(5) "UTF-8" +} +string(10) "ISO-8859-1" +string(10) "ISO-8859-1" +string(10) "ISO-8859-1" +array(3) { + ["input_encoding"]=> + string(10) "ISO-8859-1" + ["output_encoding"]=> + string(10) "ISO-8859-1" + ["internal_encoding"]=> + string(10) "ISO-8859-1" +} +bool(false) +array(3) { + ["input_encoding"]=> + string(10) "ISO-8859-1" + ["output_encoding"]=> + string(10) "ISO-8859-1" + ["internal_encoding"]=> + string(10) "ISO-8859-1" +} diff --git a/ext/iconv/tests/ob_iconv_handler-charset-length-cve-2007-4840.phpt b/ext/iconv/tests/ob_iconv_handler-charset-length-cve-2007-4840.phpt index 8cf54b732..fd01d83ca 100755 --- a/ext/iconv/tests/ob_iconv_handler-charset-length-cve-2007-4840.phpt +++ b/ext/iconv/tests/ob_iconv_handler-charset-length-cve-2007-4840.phpt @@ -2,6 +2,8 @@ ob_iconv_handler() charset parameter length checks (CVE-2007-4840) --SKIPIF-- +--INI-- +memory_limit=256M --FILE-- | +----------------------------------------------------------------------+ */ -/* $Id: php_imap.c,v 1.208.2.7.2.26.2.50 2009/06/22 14:09:55 pajoye Exp $ */ +/* $Id: php_imap.c 289435 2009-10-09 17:38:19Z pajoye $ */ #define IMAP41 @@ -487,6 +487,7 @@ const zend_function_entry imap_functions[] = { PHP_FE(imap_delete, arginfo_imap_delete) PHP_FE(imap_undelete, arginfo_imap_undelete) PHP_FE(imap_check, arginfo_imap_check) + PHP_FE(imap_listscan, arginfo_imap_listscan) PHP_FE(imap_mail_copy, arginfo_imap_mail_copy) PHP_FE(imap_mail_move, arginfo_imap_mail_move) PHP_FE(imap_mail_compose, arginfo_imap_mail_compose) @@ -597,7 +598,10 @@ static void mail_close_it(zend_rsrc_list_entry *rsrc TSRMLS_DC) { pils *imap_le_struct = (pils *)rsrc->ptr; - mail_close_full(imap_le_struct->imap_stream, imap_le_struct->flags); + /* Do not try to close prototype streams */ + if (!(imap_le_struct->flags & OP_PROTOTYPE)) { + mail_close_full(imap_le_struct->imap_stream, imap_le_struct->flags); + } if (IMAPG(imap_user)) { efree(IMAPG(imap_user)); @@ -1154,6 +1158,9 @@ static void php_imap_do_open(INTERNAL_FUNCTION_PARAMETERS, int persistent) cl_flags = CL_EXPUNGE; flags ^= PHP_EXPUNGE; } + if (flags & OP_PROTOTYPE) { + cl_flags |= OP_PROTOTYPE; + } } if (IMAPG(imap_user)) { diff --git a/ext/imap/php_imap.h b/ext/imap/php_imap.h index 59e2bbc26..5b7524b86 100644 --- a/ext/imap/php_imap.h +++ b/ext/imap/php_imap.h @@ -27,7 +27,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_imap.h,v 1.32.2.2.2.1.2.5 2009/05/05 01:22:44 jani Exp $ */ +/* $Id: php_imap.h 279937 2009-05-05 01:22:44Z jani $ */ #ifndef PHP_IMAP_H #define PHP_IMAP_H diff --git a/ext/imap/tests/bug46918.phpt b/ext/imap/tests/bug46918.phpt index 6456f2570..351becaf0 100644 --- a/ext/imap/tests/bug46918.phpt +++ b/ext/imap/tests/bug46918.phpt @@ -1,5 +1,11 @@ --TEST-- Bug #46918 (imap_rfc822_parse_adrlist host part not filled in correctly) +--SKIPIF-- + --FILE-- ---FILE-- - ---EXPECTF-- -Checking with no parameters - -Warning: imap_body() expects at least 2 parameters, 0 given in %s on line %d -Checking with incorrect parameter type - -Warning: imap_body() expects at least 2 parameters, 1 given in %s on line %d - -Warning: imap_body() expects at least 2 parameters, 1 given in %s on line %d +--TEST-- +imap_body() incorrect parameter count +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Checking with no parameters + +Warning: imap_body() expects at least 2 parameters, 0 given in %s on line %d +Checking with incorrect parameter type + +Warning: imap_body() expects at least 2 parameters, 1 given in %s on line %d + +Warning: imap_body() expects at least 2 parameters, 1 given in %s on line %d diff --git a/ext/imap/tests/imap_expunge_error.phpt b/ext/imap/tests/imap_expunge_error.phpt index 85ae2cccc..d99dcf0ff 100644 --- a/ext/imap/tests/imap_expunge_error.phpt +++ b/ext/imap/tests/imap_expunge_error.phpt @@ -1,27 +1,27 @@ ---TEST-- -imap_num_recent() incorrect parameter count ---CREDITS-- -Paul Sohier -#phptestfest utrecht ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Checking with no parameters - -Warning: imap_num_recent() expects exactly 1 parameter, 0 given in %s on line %d -Checking with incorrect parameter type - -Warning: imap_num_recent() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d - -Warning: imap_num_recent() expects parameter 1 to be resource, boolean given in %s on line %d +--TEST-- +imap_num_recent() incorrect parameter count +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Checking with no parameters + +Warning: imap_num_recent() expects exactly 1 parameter, 0 given in %s on line %d +Checking with incorrect parameter type + +Warning: imap_num_recent() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d + +Warning: imap_num_recent() expects parameter 1 to be resource, boolean given in %s on line %d diff --git a/ext/imap/tests/imap_gc_error.phpt b/ext/imap/tests/imap_gc_error.phpt index 368cbcee4..c0830c000 100644 --- a/ext/imap/tests/imap_gc_error.phpt +++ b/ext/imap/tests/imap_gc_error.phpt @@ -1,28 +1,28 @@ ---TEST-- -imap_gc() incorrect parameter count ---CREDITS-- -Paul Sohier -#phptestfest utrecht ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Checking with no parameters - -Warning: imap_gc() expects exactly 2 parameters, 0 given in %s on line %d -Checking with incorrect parameter type - -Warning: imap_gc() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d - -Warning: imap_gc() expects parameter 1 to be resource, boolean given in %s on line %d +--TEST-- +imap_gc() incorrect parameter count +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Checking with no parameters + +Warning: imap_gc() expects exactly 2 parameters, 0 given in %s on line %d +Checking with incorrect parameter type + +Warning: imap_gc() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d + +Warning: imap_gc() expects parameter 1 to be resource, boolean given in %s on line %d diff --git a/ext/imap/tests/imap_headers.phpt b/ext/imap/tests/imap_headers.phpt index 60733dd03..93c51f9a2 100644 --- a/ext/imap/tests/imap_headers.phpt +++ b/ext/imap/tests/imap_headers.phpt @@ -1,28 +1,28 @@ ---TEST-- -imap_headers() incorrect parameter count ---CREDITS-- -Paul Sohier -#phptestfest utrecht ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Checking with no parameters - -Warning: imap_headers() expects exactly 1 parameter, 0 given in %s on line %d -Checking with incorrect parameter type - -Warning: imap_headers() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d - -Warning: imap_headers() expects parameter 1 to be resource, boolean given in %s on line %d - +--TEST-- +imap_headers() incorrect parameter count +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Checking with no parameters + +Warning: imap_headers() expects exactly 1 parameter, 0 given in %s on line %d +Checking with incorrect parameter type + +Warning: imap_headers() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d + +Warning: imap_headers() expects parameter 1 to be resource, boolean given in %s on line %d + diff --git a/ext/imap/tests/imap_num_msg_error.phpt b/ext/imap/tests/imap_num_msg_error.phpt index 4b1bd02a2..6c4f50e02 100644 --- a/ext/imap/tests/imap_num_msg_error.phpt +++ b/ext/imap/tests/imap_num_msg_error.phpt @@ -1,28 +1,28 @@ ---TEST-- -imap_num_msg() incorrect parameter count ---CREDITS-- -Paul Sohier -#phptestfest utrecht ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Checking with no parameters - -Warning: imap_num_msg() expects exactly 1 parameter, 0 given in %s on line %d -Checking with incorrect parameter type - -Warning: imap_num_msg() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d - -Warning: imap_num_msg() expects parameter 1 to be resource, boolean given in %s on line %d - +--TEST-- +imap_num_msg() incorrect parameter count +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Checking with no parameters + +Warning: imap_num_msg() expects exactly 1 parameter, 0 given in %s on line %d +Checking with incorrect parameter type + +Warning: imap_num_msg() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d + +Warning: imap_num_msg() expects parameter 1 to be resource, boolean given in %s on line %d + diff --git a/ext/imap/tests/imap_num_recent_error.phpt b/ext/imap/tests/imap_num_recent_error.phpt index b52bd54ae..e723473b7 100644 --- a/ext/imap/tests/imap_num_recent_error.phpt +++ b/ext/imap/tests/imap_num_recent_error.phpt @@ -1,27 +1,27 @@ ---TEST-- -imap_expunge() incorrect parameter count ---CREDITS-- -Paul Sohier -#phptestfest utrecht ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Checking with no parameters - -Warning: imap_expunge() expects exactly 1 parameter, 0 given in %s on line %d -Checking with incorrect parameter type - -Warning: imap_expunge() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d - -Warning: imap_expunge() expects parameter 1 to be resource, boolean given in %s on line %d +--TEST-- +imap_expunge() incorrect parameter count +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Checking with no parameters + +Warning: imap_expunge() expects exactly 1 parameter, 0 given in %s on line %d +Checking with incorrect parameter type + +Warning: imap_expunge() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d + +Warning: imap_expunge() expects parameter 1 to be resource, boolean given in %s on line %d diff --git a/ext/imap/tests/imap_open_error.phpt b/ext/imap/tests/imap_open_error.phpt index 583df2f1f..7934ee2ef 100644 --- a/ext/imap/tests/imap_open_error.phpt +++ b/ext/imap/tests/imap_open_error.phpt @@ -1,42 +1,42 @@ ---TEST-- -imap_open() incorrect parameter count ---CREDITS-- -Paul Sohier -#phptestfest utrecht ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Checking with no parameters - -Warning: imap_open() expects at least 3 parameters, 0 given in %s on line %d - -Warning: imap_open() expects at least 3 parameters, 1 given in %s on line %d - -Warning: imap_open() expects at least 3 parameters, 2 given in %s on line %d - -Warning: imap_open() expects at least 3 parameters, 1 given in %s on line %d - -Warning: imap_open() expects at least 3 parameters, 2 given in %s on line %d -Checking with incorrect parameters - -Warning: imap_open(): Couldn't open stream in %s on line %d - -Warning: imap_open(): Couldn't open stream in %s on line %d - -Notice: Unknown: Can't open mailbox : no such mailbox (errflg=2) in Unknown on line 0 +--TEST-- +imap_open() incorrect parameter count +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Checking with no parameters + +Warning: imap_open() expects at least 3 parameters, 0 given in %s on line %d + +Warning: imap_open() expects at least 3 parameters, 1 given in %s on line %d + +Warning: imap_open() expects at least 3 parameters, 2 given in %s on line %d + +Warning: imap_open() expects at least 3 parameters, 1 given in %s on line %d + +Warning: imap_open() expects at least 3 parameters, 2 given in %s on line %d +Checking with incorrect parameters + +Warning: imap_open(): Couldn't open stream in %s on line %d + +Warning: imap_open(): Couldn't open stream in %s on line %d + +Notice: Unknown: Can't open mailbox : no such mailbox (errflg=2) in Unknown on line 0 diff --git a/ext/imap/tests/imap_ping_error.phpt b/ext/imap/tests/imap_ping_error.phpt index f72481766..7c87867bd 100644 --- a/ext/imap/tests/imap_ping_error.phpt +++ b/ext/imap/tests/imap_ping_error.phpt @@ -1,27 +1,27 @@ ---TEST-- -imap_ping() incorrect parameter count ---CREDITS-- -Paul Sohier -#phptestfest utrecht ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Checking with no parameters - -Warning: imap_ping() expects exactly 1 parameter, 0 given in %s on line %d -Checking with incorrect parameter type - -Warning: imap_ping() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d - -Warning: imap_ping() expects parameter 1 to be resource, boolean given in %s on line %d +--TEST-- +imap_ping() incorrect parameter count +--CREDITS-- +Paul Sohier +#phptestfest utrecht +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Checking with no parameters + +Warning: imap_ping() expects exactly 1 parameter, 0 given in %s on line %d +Checking with incorrect parameter type + +Warning: imap_ping() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d + +Warning: imap_ping() expects parameter 1 to be resource, boolean given in %s on line %d diff --git a/ext/interbase/config.m4 b/ext/interbase/config.m4 index b1f812a92..96f3fe78c 100644 --- a/ext/interbase/config.m4 +++ b/ext/interbase/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.20.6.2 2007/07/31 13:02:00 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(interbase,for InterBase support, diff --git a/ext/interbase/config.w32 b/ext/interbase/config.w32 index e5933bbd9..357220bef 100644 --- a/ext/interbase/config.w32 +++ b/ext/interbase/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.7 2004/05/12 14:29:42 abies Exp $ +// $Id: config.w32 158415 2004-05-12 14:29:42Z abies $ // vim:ft=javascript ARG_WITH("interbase", "InterBase support", "no"); diff --git a/ext/interbase/ibase_blobs.c b/ext/interbase/ibase_blobs.c index 669eac682..bbbddbd8d 100644 --- a/ext/interbase/ibase_blobs.c +++ b/ext/interbase/ibase_blobs.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: ibase_blobs.c,v 1.9.2.1.2.3.2.2 2008/12/31 11:15:38 sebastian Exp $ */ +/* $Id: ibase_blobs.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/interbase/ibase_events.c b/ext/interbase/ibase_events.c index 04deef397..51ff0ccff 100644 --- a/ext/interbase/ibase_events.c +++ b/ext/interbase/ibase_events.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: ibase_events.c,v 1.8.2.1.2.1.2.6 2008/12/31 11:15:38 sebastian Exp $ */ +/* $Id: ibase_events.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/interbase/ibase_query.c b/ext/interbase/ibase_query.c index bf83facdd..6ef830144 100644 --- a/ext/interbase/ibase_query.c +++ b/ext/interbase/ibase_query.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: ibase_query.c,v 1.23.2.1.2.10.2.10 2009/01/11 23:52:29 iliaa Exp $ */ +/* $Id: ibase_query.c 286330 2009-07-25 23:37:47Z kalle $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -1031,8 +1031,7 @@ static int _php_ibase_exec(INTERNAL_FUNCTION_PARAMETERS, ibase_result **ib_resul if (affected_rows) { RETVAL_LONG(affected_rows); } else { - /* this return value evaluates to bool(true) and to int(0) */ - RETVAL_STRINGL("0 ",2,1); + RETVAL_TRUE; } break; } diff --git a/ext/interbase/ibase_service.c b/ext/interbase/ibase_service.c index 4b86a4dee..0801afccd 100644 --- a/ext/interbase/ibase_service.c +++ b/ext/interbase/ibase_service.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: ibase_service.c,v 1.11.2.2.2.5.2.3 2008/12/31 11:15:38 sebastian Exp $ */ +/* $Id: ibase_service.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/interbase/interbase.c b/ext/interbase/interbase.c index 44b3da2b8..054c4abd6 100644 --- a/ext/interbase/interbase.c +++ b/ext/interbase/interbase.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: interbase.c,v 1.225.2.4.2.7.2.11 2008/12/31 11:15:38 sebastian Exp $ */ +/* $Id: interbase.c 284159 2009-07-16 00:04:59Z rasmus $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -861,8 +861,8 @@ static char const dpb_args[] = { int _php_ibase_attach_db(char **args, int *len, long *largs, isc_db_handle *db TSRMLS_DC) { - short i, dpb_len, buf_len = 256; - char dpb_buffer[256] = { isc_dpb_version1 }, *dpb; + short i, dpb_len, buf_len = 257-2; /* version byte at the front, and a null at the end */ + char dpb_buffer[257] = { isc_dpb_version1, 0 }, *dpb; dpb = dpb_buffer + 1; diff --git a/ext/interbase/interbase.rc b/ext/interbase/interbase.rc index b5e3f755c..a42bb3f68 100644 --- a/ext/interbase/interbase.rc +++ b/ext/interbase/interbase.rc @@ -1,81 +1,81 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2007 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.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: Ard Biesheuvel | - +----------------------------------------------------------------------+ - */ - -/* $Id: interbase.rc,v 1.7.2.1.2.1 2007/01/01 19:32:10 iliaa Exp $ */ - -#ifdef APSTUDIO_INVOKED -#error This file cannot be opened from the Visual Studio IDE -#endif - -#include "resource.h" - -#define APSTUDIO_READONLY_SYMBOLS -#include "winres.h" -#undef APSTUDIO_READONLY_SYMBOLS - -#include "php_version.h" - -#ifdef _DEBUG -# define BUILD_TYPE "Debug" -#else -# define BUILD_TYPE "Release" -#endif - -#include -#include "interbase.c" - -#ifdef FB_SQLDA -#define CLIENT_LIB "fbclient.dll" -#else -#define CLIENT_LIB "gds32.dll" -#endif - -#ifndef _MAC - -VS_VERSION_INFO VERSIONINFO - FILEVERSION PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,0 - PRODUCTVERSION PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,0 -#ifndef _DEBUG - FILEFLAGS 0x0L -#else - FILEFLAGS 0x1L -#endif - FILEFLAGSMASK 0x3fL - FILEOS VOS__WINDOWS32 - FILETYPE VFT_DLL - FILESUBTYPE VFT2_UNKNOWN -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "000004b0" - BEGIN - VALUE "FileDescription", "PHP Interbase module\0" - VALUE "FileVersion", PHP_VERSION "\0" - VALUE "LegalCopyright", "Copyright 2003 The PHP Group\0" - VALUE "Build Type", BUILD_TYPE "\0" - VALUE "Client Library", CLIENT_LIB "\0" - VALUE "URL", "http://www.php.net\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0, 1200 - END -END - -#endif // !_MAC +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2007 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.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: Ard Biesheuvel | + +----------------------------------------------------------------------+ + */ + +/* $Id: interbase.rc 242949 2007-09-26 15:44:16Z cvs2svn $ */ + +#ifdef APSTUDIO_INVOKED +#error This file cannot be opened from the Visual Studio IDE +#endif + +#include "resource.h" + +#define APSTUDIO_READONLY_SYMBOLS +#include "winres.h" +#undef APSTUDIO_READONLY_SYMBOLS + +#include "php_version.h" + +#ifdef _DEBUG +# define BUILD_TYPE "Debug" +#else +# define BUILD_TYPE "Release" +#endif + +#include +#include "interbase.c" + +#ifdef FB_SQLDA +#define CLIENT_LIB "fbclient.dll" +#else +#define CLIENT_LIB "gds32.dll" +#endif + +#ifndef _MAC + +VS_VERSION_INFO VERSIONINFO + FILEVERSION PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,0 + PRODUCTVERSION PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,0 +#ifndef _DEBUG + FILEFLAGS 0x0L +#else + FILEFLAGS 0x1L +#endif + FILEFLAGSMASK 0x3fL + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "000004b0" + BEGIN + VALUE "FileDescription", "PHP Interbase module\0" + VALUE "FileVersion", PHP_VERSION "\0" + VALUE "LegalCopyright", "Copyright 2003 The PHP Group\0" + VALUE "Build Type", BUILD_TYPE "\0" + VALUE "Client Library", CLIENT_LIB "\0" + VALUE "URL", "http://www.php.net\0" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x0, 1200 + END +END + +#endif // !_MAC diff --git a/ext/interbase/php_ibase_includes.h b/ext/interbase/php_ibase_includes.h index 3d9f4e3ef..4f0216420 100755 --- a/ext/interbase/php_ibase_includes.h +++ b/ext/interbase/php_ibase_includes.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ibase_includes.h,v 1.16.2.1.2.1.2.3 2008/12/31 11:15:38 sebastian Exp $ */ +/* $Id: php_ibase_includes.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_IBASE_INCLUDES_H #define PHP_IBASE_INCLUDES_H diff --git a/ext/interbase/php_ibase_udf.c b/ext/interbase/php_ibase_udf.c index f671e0986..2816e950c 100644 --- a/ext/interbase/php_ibase_udf.c +++ b/ext/interbase/php_ibase_udf.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ibase_udf.c,v 1.9.2.1.2.2.2.4 2009/06/05 18:50:32 mattwil Exp $ */ +/* $Id: php_ibase_udf.c 281727 2009-06-05 18:50:32Z mattwil $ */ /** * This UDF library adds the ability to call PHP functions from SQL diff --git a/ext/interbase/php_interbase.h b/ext/interbase/php_interbase.h index dbb86e9e6..785cee865 100644 --- a/ext/interbase/php_interbase.h +++ b/ext/interbase/php_interbase.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_interbase.h,v 1.71.2.1.2.1.2.2 2008/12/31 11:15:38 sebastian Exp $ */ +/* $Id: php_interbase.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_INTERBASE_H #define PHP_INTERBASE_H diff --git a/ext/interbase/tests/002.phpt b/ext/interbase/tests/002.phpt index a255d1a1d..7a367ae22 100644 --- a/ext/interbase/tests/002.phpt +++ b/ext/interbase/tests/002.phpt @@ -3,7 +3,7 @@ InterBase: connect, close and pconnect --SKIPIF-- --FILE-- - --FILE-- - --FILE-- - --FILE-- - --FILE-- - --FILE-- - --FILE-- - diff --git a/ext/intl/doc/common_api.php b/ext/intl/doc/common_api.php index 76ba9d88c..ce2329fe3 100755 --- a/ext/intl/doc/common_api.php +++ b/ext/intl/doc/common_api.php @@ -54,5 +54,3 @@ function intl_is_failure($code) {} * @return string Error code name. */ function intl_error_name($code) {} - -?> diff --git a/ext/intl/doc/datefmt_api.php b/ext/intl/doc/datefmt_api.php index 37249292b..0c5002e28 100755 --- a/ext/intl/doc/datefmt_api.php +++ b/ext/intl/doc/datefmt_api.php @@ -434,6 +434,3 @@ class DateFormatter { * @return string Description of the last error. */ function datefmt_get_error_message($fmt) {} - - -?> diff --git a/ext/intl/doc/formatter_api.php b/ext/intl/doc/formatter_api.php index c75596e4c..754b16c62 100755 --- a/ext/intl/doc/formatter_api.php +++ b/ext/intl/doc/formatter_api.php @@ -498,5 +498,3 @@ function numfmt_get_error_code($formatter) {} * @return string Description of the last occured error. */ function numfmt_get_error_message($formatter) {} - -?> diff --git a/ext/intl/doc/locale_api.php b/ext/intl/doc/locale_api.php index b16e36aa5..c6c41ede0 100755 --- a/ext/intl/doc/locale_api.php +++ b/ext/intl/doc/locale_api.php @@ -42,7 +42,7 @@ class Locale { * The following static members are used with the getLocale methods of * the various locale affected classes, such as numfmt. */ - const DEFAULT_LOCALE = default_locale; + const DEFAULT_LOCALE = null; /** * identifiers for the actual locale, valid locale @@ -59,13 +59,13 @@ class Locale { /** * Valid locale tag and subtag values */ - LANG_TAG = "language"; - EXTLANG_TAG = "extlang"; - SCRIPT_TAG = "script"; - REGION_TAG = "region"; - VARIANT_TAG = "variant"; - GRANDFATHERED_LANG_TAG = "grandfathered"; - PRIVATE_TAG = "private"; + const LANG_TAG = "language"; + const EXTLANG_TAG = "extlang"; + const SCRIPT_TAG = "script"; + const REGION_TAG = "region"; + const VARIANT_TAG = "variant"; + const GRANDFATHERED_LANG_TAG = "grandfathered"; + const PRIVATE_TAG = "private"; ############################################################################# @@ -206,9 +206,10 @@ class Locale { * * @param string $langtag the language tag to check * @param string $locale the language range to check against + * @param bool $canonicalize Canonicalize parameters? * @return boolean 'true' if $locale matches $langtag 'false' otherwise */ - public static function filterMatches($langtag, $locale) {} + public static function filterMatches($langtag, $locale, $canonicalize) {} /** * Searchs the items in $langtag for the best match to the language @@ -263,7 +264,7 @@ class Locale { * * @return string the current runtime locale */ - public static function locale_get_default() {} + function locale_get_default() {} /** * sets the default runtime locale to $locale @@ -273,7 +274,7 @@ class Locale { * locale identifier. UAX #35 extensions are accepted. * @return boolean 'true' if okay, 'false' if an error */ - public static function locale_set_default($locale) {} + function locale_set_default($locale) {} /** @@ -283,7 +284,7 @@ class Locale { * @return string the language code associated with the language * or null in case of error. */ - public static function locale_get_primary_language($locale) {} + function locale_get_primary_language($locale) {} /** @@ -292,7 +293,7 @@ class Locale { * @param string $locale the locale to extract the script code from * @return string the script subtag for the locale or null if not present */ - public static function locale_get_script($locale) {} + function locale_get_script($locale) {} /** @@ -301,7 +302,7 @@ class Locale { * @param string $locale the locale to extract the region code from * @return string the region subtag for the locale or null if not present */ - public static function locale_get_region($locale) {} + function locale_get_region($locale) {} /** @@ -311,7 +312,7 @@ class Locale { * @return array the array containing the list of all variants * subtag for the locale or null if not present */ - public static function locale_get_all_variants($locale) {} + function locale_get_all_variants($locale) {} /** @@ -320,7 +321,7 @@ class Locale { * @param string $locale the locale to extract the keywords from * @return array associative array containing the keyword-value pairs for this locale */ - public static function locale_get_keywords($locale) {} + function locale_get_keywords($locale) {} /** @@ -332,7 +333,7 @@ class Locale { * @return string display name of the locale in the format * appropriate for $in_locale. */ - public static function locale_get_display_name($locale, $in_locale = null) {} + function locale_get_display_name($locale, $in_locale = null) {} /** @@ -344,7 +345,7 @@ class Locale { * @return string display name of the language for the $locale in the format * appropriate for $in_locale. */ - public static function locale_get_display_language($lang, $in_locale = null) {} + function locale_get_display_language($lang, $in_locale = null) {} /** * Returns an appropriately localized display name for script of the input locale @@ -355,7 +356,7 @@ class Locale { * @return string display name of the script for the $locale in the format * appropriate for $in_locale. */ - public static function locale_get_display_script($script, $in_locale = null) {} + function locale_get_display_script($script, $in_locale = null) {} /** @@ -367,7 +368,7 @@ class Locale { * @return string display name of the region for the $locale in the format * appropriate for $in_locale. */ - public static function locale_get_display_region($region, $in_locale = null) {} + function locale_get_display_region($region, $in_locale = null) {} /** @@ -379,7 +380,7 @@ class Locale { * @return string display name of the variant for the $locale in the format * appropriate for $in_locale. */ - public static function locale_get_display_variant($variant, $in_locale = null) {} + function locale_get_display_variant($variant, $in_locale = null) {} /** @@ -388,9 +389,10 @@ class Locale { * * @param string $langtag the language tag to check * @param string $locale the language range to check against + * @param bool $canonicalize Canonicalize parameters? * @return boolean 'true' if $locale matches $langtag 'false' otherwise */ - public static function locale_filter_matches($langtag, $locale) {} + function locale_filter_matches($langtag, $locale, $canonicalize) {} /** * Searchs the items in $langtag for the best match to the language @@ -403,7 +405,7 @@ class Locale { * @return string closest matching language tag, $default, * or empty string */ - public static function locale_lookup(array $langtag, $locale, $default = null) {} + function locale_lookup(array $langtag, $locale, $default = null) {} /** @@ -415,7 +417,7 @@ class Locale { * * @return string the corresponding locale identifier. */ - public static function locale_compose_locale(array $subtags) {} + function locale_compose_locale(array $subtags) {} /** @@ -427,6 +429,6 @@ class Locale { * the keys identify the particular locale ID subtags, * and the values are the associated subtag values. */ - public static function locale_parse_locale($locale) {} + function locale_parse_locale($locale) {} ?> diff --git a/ext/intl/idn/idn.c b/ext/intl/idn/idn.c index c5f1a70ad..ca7e9e7ba 100644 --- a/ext/intl/idn/idn.c +++ b/ext/intl/idn/idn.c @@ -15,7 +15,7 @@ | Author: Pierre A. Joye | +----------------------------------------------------------------------+ */ -/* $Id: idn.c,v 1.1.2.2 2009/05/10 13:26:38 bjori Exp $ */ +/* $Id: idn.c 283618 2009-07-06 23:48:27Z stas $ */ /* {{{ includes */ #ifdef HAVE_CONFIG_H @@ -67,7 +67,7 @@ static void php_intl_idn_to(INTERNAL_FUNCTION_PARAMETERS, int mode) UChar converted[MAXPATHLEN]; int32_t converted_ret_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ll", (char **)&domain, &domain_len, &option, &status) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", (char **)&domain, &domain_len, &option) == FAILURE) { return; } @@ -121,8 +121,8 @@ static void php_intl_idn_to(INTERNAL_FUNCTION_PARAMETERS, int mode) RETURN_STRINGL(((char *)converted_utf8), converted_utf8_len, 0); } -/* {{{ proto int idn_to_ascii(string domain[, int options [, int status]]) - Converts a UTF-8 domain to ASCII, as defined in the IDNA RFC */ +/* {{{ proto int idn_to_ascii(string domain[, int options]) + Converts an Unicode domain to ASCII representation, as defined in the IDNA RFC */ PHP_FUNCTION(idn_to_ascii) { php_intl_idn_to(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTL_IDN_TO_ASCII); @@ -130,8 +130,8 @@ PHP_FUNCTION(idn_to_ascii) /* }}} */ -/* {{{ proto int idn_to_utf8(string domain[, int options[, int status]]) - Converts a UTF-8 domain to ASCII, as defined in the IDNA RFC */ +/* {{{ proto int idn_to_utf8(string domain[, int options]) + Converts an ASCII representation of the domain to Unicode (UTF-8), as defined in the IDNA RFC */ PHP_FUNCTION(idn_to_utf8) { php_intl_idn_to(INTERNAL_FUNCTION_PARAM_PASSTHRU, INTL_IDN_TO_UTF8); diff --git a/ext/intl/idn/idn.h b/ext/intl/idn/idn.h index c738f4e5d..ee3b84768 100644 --- a/ext/intl/idn/idn.h +++ b/ext/intl/idn/idn.h @@ -15,7 +15,7 @@ | Author: Pierre A. Joye | +----------------------------------------------------------------------+ */ -/* $Id: idn.h,v 1.1.2.1 2009/01/26 22:30:57 pajoye Exp $ s*/ +/* $Id: idn.h 274679 2009-01-26 22:30:57Z pajoye $ s*/ #ifndef IDN_IDN_H #define IDN_IDN_H diff --git a/ext/intl/intl_error.c b/ext/intl/intl_error.c index 44f668b19..79ae153bb 100755 --- a/ext/intl/intl_error.c +++ b/ext/intl/intl_error.c @@ -103,6 +103,9 @@ void intl_error_set_custom_msg( intl_error* err, char* msg, int copyMsg TSRMLS_D if( !msg ) return; + if(!err && INTL_G(error_level)) { + php_error_docref(NULL TSRMLS_CC, INTL_G(error_level), "%s", msg); + } if( !err && !( err = intl_g_error_get( TSRMLS_C ) ) ) return; diff --git a/ext/intl/locale/locale.c b/ext/intl/locale/locale.c index a2f1cd6d1..9c3b4e1c5 100755 --- a/ext/intl/locale/locale.c +++ b/ext/intl/locale/locale.c @@ -14,7 +14,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: locale.c,v 1.1.2.2 2008/08/03 11:33:44 jani Exp $ */ +/* $Id: locale.c 264111 2008-08-03 11:33:45Z jani $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/intl/locale/locale.h b/ext/intl/locale/locale.h index 452fcbb42..1661d8849 100755 --- a/ext/intl/locale/locale.h +++ b/ext/intl/locale/locale.h @@ -14,7 +14,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: locale.h,v 1.1.2.2 2008/08/03 11:33:45 jani Exp $ */ +/* $Id: locale.h 264111 2008-08-03 11:33:45Z jani $ */ #ifndef LOCALE_LOCALE_H #define LOCALE_LOCALE_H diff --git a/ext/intl/locale/locale_class.c b/ext/intl/locale/locale_class.c index 3a93fa434..7cde68892 100755 --- a/ext/intl/locale/locale_class.c +++ b/ext/intl/locale/locale_class.c @@ -14,7 +14,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: locale_class.c,v 1.1.2.7 2008/11/17 11:27:56 felipe Exp $ */ +/* $Id: locale_class.c 269153 2008-11-17 11:28:01Z felipe $ */ #include #include "php_intl.h" diff --git a/ext/intl/locale/locale_class.h b/ext/intl/locale/locale_class.h index 0bf3592c1..bf0b933a1 100755 --- a/ext/intl/locale/locale_class.h +++ b/ext/intl/locale/locale_class.h @@ -14,7 +14,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: locale_class.h,v 1.1.2.2 2008/08/03 11:33:45 jani Exp $ */ +/* $Id: locale_class.h 264111 2008-08-03 11:33:45Z jani $ */ #ifndef LOCALE_CLASS_H #define LOCALE_CLASS_H diff --git a/ext/intl/locale/locale_methods.c b/ext/intl/locale/locale_methods.c index b47b171f2..9abdcdf3f 100755 --- a/ext/intl/locale/locale_methods.c +++ b/ext/intl/locale/locale_methods.c @@ -14,7 +14,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: locale_methods.c,v 1.1.2.7 2008/08/03 11:33:45 jani Exp $ */ +/* $Id: locale_methods.c 283367 2009-07-02 22:36:16Z stas $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -145,16 +145,16 @@ static char* getPreferredTag(char* gf_tag) static int getStrrtokenPos(char* str, int savedPos) { int result =-1; - int i=0; + int i; - for( i=savedPos; i>=0 ;i--){ - if( isIDSeparator(*(str+i)) ){ + for(i=savedPos-1; i>=0; i--) { + if(isIDSeparator(*(str+i)) ){ /* delimiter found; check for singleton */ - if( isIDSeparator(*(str+i-2)) ){ + if(i>=2 && isIDSeparator(*(str+i-2)) ){ /* a singleton; so send the position of token before the singleton */ - result = i-3; + result = i-2; } else { - result = i-1; + result = i; } break; } @@ -512,25 +512,6 @@ static void get_icu_disp_value_src_php( char* tag_name, INTERNAL_FUNCTION_PARAME RETURN_FALSE; } } - -/* - int singletonPos = 0; - //Handle singletons - if( (strcmp(tag_name , LOC_LANG_TAG)==0) && isIDPrefix(loc_name) ){ - //return mod_loc_name; - } else { - singletonPos = getSingletonPos( loc_name ); - if( singletonPos == 0){ - //singleton at start of script, region , variant etc. - //or invalid singleton at start of language - RETURN_FALSE; - }else if(singletonPos > 0){ - //singleton at some position except at start - //strip off the singleton and rest of the loc_name - mod_loc_name = estrndup( loc_name , singletonPos-1); - } - } -*/ } /* end of if != LOC_CANONICAL_TAG */ if( mod_loc_name==NULL ){ @@ -1187,7 +1168,7 @@ PHP_FUNCTION(locale_get_all_variants) /* }}} */ /*{{{ -* Converts to lower case and also replaces all hyphuns with the underscore +* Converts to lower case and also replaces all hyphens with the underscore */ static int strToMatch(char* str ,char *retstr) { @@ -1196,7 +1177,7 @@ static int strToMatch(char* str ,char *retstr) int result = 0; int len = 0; - if( (!str) || strlen(str) ==0){ + if( (!str) || str[0] == '\0'){ return result; } else { anchor = retstr; @@ -1221,11 +1202,11 @@ static int strToMatch(char* str ,char *retstr) } /* }}} */ -/* {{{ proto static boolean Locale::filterMatches(string $langtag, string $locale) +/* {{{ proto static boolean Locale::filterMatches(string $langtag, string $locale[, bool $canonicalize]) * Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm */ /* }}} */ -/* {{{ proto boolean locale_filter_matches(string $langtag, string $locale) +/* {{{ proto boolean locale_filter_matches(string $langtag, string $locale[, bool $canonicalize]) * Checks if a $langtag filter matches with $locale according to RFC 4647's basic filtering algorithm */ PHP_FUNCTION(locale_filter_matches) @@ -1250,7 +1231,7 @@ PHP_FUNCTION(locale_filter_matches) intl_error_reset( NULL TSRMLS_CC ); - if(zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "ssb", + if(zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &lang_tag, &lang_tag_len , &loc_range , &loc_range_len , &boolCanonical) == FAILURE) { @@ -1396,38 +1377,36 @@ static void array_cleanup( char* arr[] , int arr_size) { int i=0; for( i=0; i< arr_size; i++ ){ - if( arr[i] ){ - efree( arr[i]); + if( arr[i*2] ){ + efree( arr[i*2]); } } - + efree(arr); } +#define LOOKUP_CLEAN_RETURN(value) array_cleanup(cur_arr, cur_arr_len); return (value) /* {{{ * returns the lookup result to lookup_loc_range_src_php * internal function */ -static char* lookup_loc_range(char* loc_range, HashTable* hash_arr , int isCanonical TSRMLS_DC) +static char* lookup_loc_range(char* loc_range, HashTable* hash_arr, int canonicalize TSRMLS_DC) { - int cur_arr_ind = 0; - int i = 0; - int cur_arr_len = 0; - int result = 0; + int i = 0; + int cur_arr_len = 0; + int result = 0; - char* lang_tag = NULL; - zval** ele_value = NULL; - char* cur_arr[MAX_NO_LOOKUP_LANG_TAG] ; + char* lang_tag = NULL; + zval** ele_value = NULL; + char** cur_arr = NULL; - char* loc_range_to_cmp = NULL; - char* cur_loc_range = NULL; - char* can_loc_range = NULL; - int saved_pos = 0; + char* cur_loc_range = NULL; + char* can_loc_range = NULL; + int saved_pos = 0; - char* return_value = NULL; - UErrorCode status = U_ZERO_ERROR; - char* empty_result = ""; + char* return_value = NULL; - /* convert the array to lowercase , also replace hyphuns with the underscore and store it in cur_arr */ + cur_arr = ecalloc(zend_hash_num_elements(hash_arr)*2, sizeof(char *)); + /* convert the array to lowercase , also replace hyphens with the underscore and store it in cur_arr */ for(zend_hash_internal_pointer_reset(hash_arr); zend_hash_has_more_elements(hash_arr) == SUCCESS; zend_hash_move_forward(hash_arr)) { @@ -1436,163 +1415,115 @@ static char* lookup_loc_range(char* loc_range, HashTable* hash_arr , int isCanon /* Should never actually fail since the key is known to exist.*/ continue; } - if( Z_TYPE_PP(ele_value)!= IS_STRING ){ + if(Z_TYPE_PP(ele_value)!= IS_STRING) { /* element value is not a string */ - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "lookup_loc_range: array element is not a string ", - 0 TSRMLS_CC ); - return NULL; - } else { - if( lang_tag ){ - efree( lang_tag ); - } - lang_tag = estrdup(Z_STRVAL_PP(ele_value) ); - - if( isCanonical ==0 ){ - /* +1 for the terminating '\0' */ - cur_arr[cur_arr_ind] = ecalloc(1, strlen(lang_tag)+1 ); - result = strToMatch(lang_tag, cur_arr[cur_arr_ind]) ; - } else { - cur_arr[cur_arr_ind] = estrdup(lang_tag); - } - - if( cur_arr_ind < MAX_NO_LOOKUP_LANG_TAG ){ - cur_arr_ind++ ; - } else { - break; - } + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: locale array element is not a string", 0 TSRMLS_CC); + LOOKUP_CLEAN_RETURN(NULL); + } + cur_arr[cur_arr_len*2] = estrndup(Z_STRVAL_PP(ele_value), Z_STRLEN_PP(ele_value)); + result = strToMatch(Z_STRVAL_PP(ele_value), cur_arr[cur_arr_len*2]); + if(result == 0) { + intl_error_set(NULL, U_ILLEGAL_ARGUMENT_ERROR, "lookup_loc_range: unable to canonicalize lang_tag", 0 TSRMLS_CC); + LOOKUP_CLEAN_RETURN(NULL); } + cur_arr[cur_arr_len*2+1] = Z_STRVAL_PP(ele_value); + cur_arr_len++ ; } /* end of for */ - if( lang_tag ){ - efree( lang_tag ); - } - - cur_arr_len = cur_arr_ind; - /* Canonicalize array elements */ - if( isCanonical ==1 ){ - for( i=0; i< cur_arr_ind; i++ ){ - lang_tag =get_icu_value_internal( cur_arr[i] , LOC_CANONICALIZE_TAG , &result , 0); - efree( cur_arr[i] ); - cur_arr[i] = ecalloc(1, strlen(lang_tag)+1 ); - result = strToMatch(lang_tag, cur_arr[i]) ; - efree( lang_tag); - if( result ==0) { - intl_error_set( NULL, status, - "locale_lookup : unable to canonicalize lang_tag" , 0 TSRMLS_CC ); - if( lang_tag ){ - efree( lang_tag ); + if(canonicalize) { + for(i=0; i 0) { + for(i=0; i< cur_arr_len; i++){ + if(cur_arr[i*2] != NULL && strlen(cur_arr[i*2]) == saved_pos && strncmp(cur_loc_range, cur_arr[i*2], saved_pos) == 0) { /* Match found */ - return_value = estrdup( cur_arr[i] ); - if ( cur_loc_range ){ - efree( cur_loc_range ); - } - if( loc_range_to_cmp){ - efree(loc_range_to_cmp); - } - if( can_loc_range ){ - efree( can_loc_range ); - } - array_cleanup( cur_arr , cur_arr_len ); - return return_value; + return_value = estrdup(canonicalize?cur_arr[i*2]:cur_arr[i*2+1]); + efree(cur_loc_range); + LOOKUP_CLEAN_RETURN(return_value); } } - saved_pos = getStrrtokenPos( cur_loc_range , saved_pos ); - } - - if( loc_range_to_cmp){ - efree(loc_range_to_cmp); - } - if ( cur_loc_range ){ - efree( cur_loc_range ); + saved_pos = getStrrtokenPos(cur_loc_range, saved_pos); } - if( can_loc_range ){ - efree( can_loc_range ); - } - array_cleanup( cur_arr , cur_arr_len ); /* Match not found */ - return empty_result; - + efree(cur_loc_range); + LOOKUP_CLEAN_RETURN(NULL); } /* }}} */ -/* {{{ proto string Locale::lookup(array $langtag, $locale[, $default = null]) +/* {{{ proto string Locale::lookup(array $langtag, string $locale[, bool $canonicalize[, string $default = null]]) * Searchs the items in $langtag for the best match to the language * range */ /* }}} */ -/* {{{ proto string locale_lookup(array $langtag, $locale[, $default = null]) +/* {{{ proto string locale_lookup(array $langtag, string $locale[, bool $canonicalize[, string $default = null]]) * Searchs the items in $langtag for the best match to the language * range */ PHP_FUNCTION(locale_lookup) { - char* fallback_loc = NULL; - int fallback_loc_len = 0; - char* loc_range = NULL; - int loc_range_len = 0; + char* fallback_loc = NULL; + int fallback_loc_len = 0; + char* loc_range = NULL; + int loc_range_len = 0; - zval* arr = NULL; + zval* arr = NULL; HashTable* hash_arr = NULL; - zend_bool boolCanonical = 0; - + zend_bool boolCanonical = 0; char* result =NULL; intl_error_reset( NULL TSRMLS_CC ); - if(zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "asb|s", - &arr,&loc_range,&loc_range_len,&boolCanonical, - &fallback_loc,&fallback_loc_len) == FAILURE) - { - intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, - "locale_lookup: unable to parse input params", 0 TSRMLS_CC ); - + if(zend_parse_parameters( ZEND_NUM_ARGS() TSRMLS_CC, "as|bs", &arr, &loc_range, &loc_range_len, + &boolCanonical, &fallback_loc, &fallback_loc_len) == FAILURE) { + intl_error_set( NULL, U_ILLEGAL_ARGUMENT_ERROR, "locale_lookup: unable to parse input params", 0 TSRMLS_CC ); RETURN_NULL(); } @@ -1600,25 +1531,22 @@ PHP_FUNCTION(locale_lookup) loc_range = INTL_G(default_locale); } - /* MAKE_STD_ZVAL(hash_arr); */ - hash_arr = HASH_OF( arr ); + hash_arr = HASH_OF(arr); - if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 ){ + if( !hash_arr || zend_hash_num_elements( hash_arr ) == 0 ) { RETURN_EMPTY_STRING(); - } - else{ - result = lookup_loc_range( loc_range ,hash_arr ,(boolCanonical?1:0) TSRMLS_CC); - + } + + result = lookup_loc_range(loc_range, hash_arr, boolCanonical TSRMLS_CC); if(result == NULL || result[0] == '\0') { if( fallback_loc ) { - result = estrndup( fallback_loc , fallback_loc_len); + result = estrndup(fallback_loc, fallback_loc_len); } else { RETURN_EMPTY_STRING(); } } -} - RETVAL_STRINGL( result, strlen(result), 0); + RETVAL_STRINGL(result, strlen(result), 0); } /* }}} */ diff --git a/ext/intl/locale/locale_methods.h b/ext/intl/locale/locale_methods.h index f7096a35f..9d1dcfde5 100755 --- a/ext/intl/locale/locale_methods.h +++ b/ext/intl/locale/locale_methods.h @@ -14,7 +14,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: locale_methods.h,v 1.1.2.3 2008/08/03 11:33:45 jani Exp $ */ +/* $Id: locale_methods.h 264111 2008-08-03 11:33:45Z jani $ */ #ifndef LOCALE_METHODS_H #define LOCALE_METHODS_H diff --git a/ext/intl/php_intl.c b/ext/intl/php_intl.c index 13f36fd03..831ace4d5 100755 --- a/ext/intl/php_intl.c +++ b/ext/intl/php_intl.c @@ -454,6 +454,7 @@ zend_function_entry intl_functions[] = { /* {{{ INI Settings */ PHP_INI_BEGIN() STD_PHP_INI_ENTRY(LOCALE_INI_NAME, NULL, PHP_INI_ALL, OnUpdateStringUnempty, default_locale, zend_intl_globals, intl_globals) + STD_PHP_INI_ENTRY("intl.error_level", "0", PHP_INI_ALL, OnUpdateLong, error_level, zend_intl_globals, intl_globals) PHP_INI_END() /* }}} */ diff --git a/ext/intl/php_intl.h b/ext/intl/php_intl.h index 92663444e..61455b6fb 100755 --- a/ext/intl/php_intl.h +++ b/ext/intl/php_intl.h @@ -45,6 +45,7 @@ ZEND_BEGIN_MODULE_GLOBALS(intl) collator_compare_func_t compare_func; UBreakIterator* grapheme_iterator; intl_error g_error; + long error_level; ZEND_END_MODULE_GLOBALS(intl) /* Macro to access request-wide global variables. */ diff --git a/ext/intl/tests/bug48227.phpt b/ext/intl/tests/bug48227.phpt index 8f633c737..0ac0d5e55 100644 --- a/ext/intl/tests/bug48227.phpt +++ b/ext/intl/tests/bug48227.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #48227 (NumberFormatter::format leaks memory) +--SKIPIF-- + --FILE-- +--FILE-- + +--EXPECT-- +xn--tst-qla.de +t%C3%A4st.de \ No newline at end of file diff --git a/ext/intl/tests/locale_lookup.phpt b/ext/intl/tests/locale_lookup.phpt index 08f92ffc4..f0affafa6 100755 --- a/ext/intl/tests/locale_lookup.phpt +++ b/ext/intl/tests/locale_lookup.phpt @@ -71,19 +71,19 @@ ut_run(); loc_range:de-de lang_tags: de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2 -lookup result:de_de +lookup result:de-DE Canonical lookup result:de_de -------------- loc_range:sl_IT lang_tags: de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2 -lookup result:sl_it +lookup result:sl_IT Canonical lookup result:sl_it -------------- loc_range:sl_IT_Nedis lang_tags: de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2 -lookup result:sl_it +lookup result:sl_IT Canonical lookup result:sl_it -------------- loc_range:jbo @@ -95,5 +95,5 @@ Canonical lookup result:jbo loc_range:art-lojban lang_tags: de-DEVA,de-DE-1996,de-DE,zh_Hans,de-CH-1996,sl_IT,sl_IT_nedis-a-kirti-x-xyz,sl_IT_rozaj,sl_IT_NEDIS_ROJAZ_1901,i-enochian,sgn-CH-de,art-lojban,i-lux,art-lojban,jbo,en_sl_IT,zh-Hant-CN-x-prv1-prv2 -lookup result:art_lojban -Canonical lookup result:jbo \ No newline at end of file +lookup result:art-lojban +Canonical lookup result:jbo diff --git a/ext/intl/tests/ut_common.inc b/ext/intl/tests/ut_common.inc index 454bbaa53..4f2036123 100755 --- a/ext/intl/tests/ut_common.inc +++ b/ext/intl/tests/ut_common.inc @@ -1,388 +1,388 @@ -compare( $str1, $str2 ) : collator_compare( $coll, $str1, $str2 ); -} -function ut_coll_sort( $coll, &$arr, $sort_flag = Collator::SORT_REGULAR ) -{ - return $GLOBALS['oo-mode'] ? $coll->sort( $arr, $sort_flag ) : collator_sort( $coll, $arr, $sort_flag ); -} -function ut_coll_sort_with_sort_keys( $coll, &$arr ) -{ - return $GLOBALS['oo-mode'] ? $coll->sortWithSortKeys( $arr ) : collator_sort_with_sort_keys( $coll, $arr ); -} -function ut_coll_asort( $coll, &$arr, $sort_flag = Collator::SORT_REGULAR ) -{ - return $GLOBALS['oo-mode'] ? $coll->asort( $arr, $sort_flag ) : collator_asort( $coll, $arr, $sort_flag ); -} -function ut_coll_get_locale( $coll, $type ) -{ - return $GLOBALS['oo-mode'] ? $coll->getLocale( $type ) : collator_get_locale( $coll, $type ); -} -function ut_coll_get_display_name( $obj_loc, $disp_loc ) -{ - return $GLOBALS['oo-mode'] ? Collator::getDisplayName( $obj_loc, $disp_loc ) : collator_get_display_name( $obj_loc, $disp_loc ); -} -function ut_coll_get_available_locales() -{ - return $GLOBALS['oo-mode'] ? Collator::getAvailableLocales() : collator_get_available_locales(); -} -function ut_coll_get_attribute( $coll, $attr ) -{ - return $GLOBALS['oo-mode'] ? $coll->getAttribute( $attr ) : collator_get_attribute( $coll, $attr ); -} -function ut_coll_get_strength( $coll ) -{ - return $GLOBALS['oo-mode'] ? $coll->getStrength() : collator_get_strength( $coll ); -} -function ut_coll_set_strength( $coll, $strength ) -{ - return $GLOBALS['oo-mode'] ? $coll->setStrength( $strength ) : collator_set_strength( $coll, $strength ); -} -function ut_coll_set_attribute( $coll, $attr, $val ) -{ - return $GLOBALS['oo-mode'] ? $coll->setAttribute( $attr, $val ) : collator_set_attribute( $coll, $attr, $val ); -} -function ut_coll_get_variable_top( $coll ) -{ - return $GLOBALS['oo-mode'] ? $coll->getVariableTop() : collator_get_variable_top( $coll ); -} -function ut_coll_set_variable_top( $coll, $var_top ) -{ - return $GLOBALS['oo-mode'] ? $coll->setVariableTop( $var_top ) : collator_set_variable_top( $coll, $var_top ); -} -function ut_coll_restore_variable_top( $coll, $var_top ) -{ - return $GLOBALS['oo-mode'] ? $coll->restoreVariableTop( $var_top ) : collator_restore_variable_top( $coll, $var_top ); -} -function ut_coll_get_error_code( $coll ) -{ - return $GLOBALS['oo-mode'] ? $coll->getErrorCode() : collator_get_error_code( $coll ); -} -function ut_coll_get_error_message( $coll ) -{ - return $GLOBALS['oo-mode'] ? $coll->getErrorMessage() : collator_get_error_message( $coll ); -} -function ut_coll_get_default() -{ - return $GLOBALS['oo-mode'] ? Collator::getDefault() : collator_get_default(); -} -function ut_coll_set_default( $coll ) -{ - return $GLOBALS['oo-mode'] ? Collator::setDefault( $coll ) : collator_set_default( $coll ); -} - -/* - * Wrappers around NumberFormatter methods to run them in either OO- or procedural mode. - */ - -// FIXME: incomplete list - -function ut_nfmt_create( $locale, $style, $pattern = null ) -{ - return $GLOBALS['oo-mode'] ? new NumberFormatter( $locale, $style, $pattern ) : numfmt_create( $locale, $style, $pattern ); -} -function ut_nfmt_format( $fmt, $number, $type = null ) -{ - return $GLOBALS['oo-mode'] ? $fmt->format( $number, $type ) : numfmt_format( $fmt, $number, $type ); -} -function ut_nfmt_parse( $fmt, $string, $type = NumberFormatter::TYPE_DOUBLE, &$position = null ) -{ - if(is_null($position)) { - return $GLOBALS['oo-mode'] ? $fmt->parse( $string, $type ) : numfmt_parse( $fmt, $string, $type ); - } else { - return $GLOBALS['oo-mode'] ? $fmt->parse( $string, $type, $position ) : numfmt_parse( $fmt, $string, $type, $position ); - } -} -function ut_nfmt_format_currency( $fmt, $number, $currency ) -{ - return $GLOBALS['oo-mode'] ? $fmt->formatCurrency( $number, $currency ) : numfmt_format_currency( $fmt, $number, $currency ); -} -function ut_nfmt_parse_currency( $fmt, $string, &$currency, &$position = null ) -{ - if(is_null($position)) { - return $GLOBALS['oo-mode'] ? $fmt->parseCurrency( $string, $currency ) : numfmt_parse_currency( $fmt, $string, $currency ); - } else { - return $GLOBALS['oo-mode'] ? $fmt->parseCurrency( $string, $currency, $position ) : numfmt_parse_currency( $fmt, $string, $currency, $position ); - } -} -function ut_nfmt_set_attribute( $fmt, $attribute, $value ) -{ - return $GLOBALS['oo-mode'] ? $fmt->setAttribute( $attribute, $value ) : numfmt_set_attribute( $fmt, $attribute, $value ); -} -function ut_nfmt_set_text_attribute( $fmt, $attribute, $value ) -{ - return $GLOBALS['oo-mode'] ? $fmt->setTextAttribute( $attribute, $value ) : numfmt_set_text_attribute( $fmt, $attribute, $value ); -} -function ut_nfmt_set_symbol( $fmt, $attribute, $value ) -{ - return $GLOBALS['oo-mode'] ? $fmt->setSymbol( $attribute, $value ) : numfmt_set_symbol( $fmt, $attribute, $value ); -} -function ut_nfmt_set_pattern( $fmt, $pattern ) -{ - return $GLOBALS['oo-mode'] ? $fmt->setPattern( $pattern ) : numfmt_set_pattern( $fmt, $pattern ); -} -function ut_nfmt_get_attribute( $fmt, $attribute ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getAttribute( $attribute ) : numfmt_get_attribute( $fmt, $attribute ); -} -function ut_nfmt_get_text_attribute( $fmt, $attribute ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getTextAttribute( $attribute ) : numfmt_get_text_attribute( $fmt, $attribute ); -} -function ut_nfmt_get_symbol( $fmt, $attribute ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getSymbol( $attribute ) : numfmt_get_symbol( $fmt, $attribute ); -} -function ut_nfmt_get_pattern( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getPattern() : numfmt_get_pattern( $fmt ); -} -function ut_nfmt_get_locale( $fmt, $type = 0 ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getLocale( $type ) : numfmt_get_locale( $fmt, $type ); -} -function ut_nfmt_get_error_code( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getErrorCode() : numfmt_get_error_code( $fmt ); -} -function ut_nfmt_get_error_message( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getErrorMessage() : numfmt_get_error_message( $fmt ); -} - -function ut_norm_normalize( $str, $form ) -{ - return $GLOBALS['oo-mode'] ? Normalizer::normalize( $str, $form ) : normalizer_normalize( $str, $form ); -} -function ut_norm_is_normalized( $str, $form ) -{ - return $GLOBALS['oo-mode'] ? Normalizer::isNormalized( $str, $form ) : normalizer_is_normalized( $str, $form ); -} - -/* - * Wrappers around Collator methods to run them in either OO- or procedural mode. - */ - -function ut_loc_get_default( ) -{ - return $GLOBALS['oo-mode'] ? Locale::getDefault( ) : locale_get_default(); -} -function ut_loc_set_default( $locale ) -{ - return $GLOBALS['oo-mode'] ? Locale::setDefault( $locale ) : locale_set_default( $locale ); -} -function ut_loc_get_primary_language( $locale ) -{ - return $GLOBALS['oo-mode'] ? Locale::getPrimaryLanguage( $locale ) : locale_get_primary_language( $locale ); -} -function ut_loc_get_script( $locale ) -{ - return $GLOBALS['oo-mode'] ? Locale::getScript( $locale ) : locale_get_script( $locale ); -} -function ut_loc_get_region( $locale ) -{ - return $GLOBALS['oo-mode'] ? Locale::getRegion( $locale ) : locale_get_region( $locale ); -} -function ut_loc_get_keywords( $locale ) -{ - return $GLOBALS['oo-mode'] ? Locale::getKeywords( $locale ) : locale_get_keywords( $locale ); -} -function ut_loc_get_display_name( $locale , $dispLocale ) -{ - return $GLOBALS['oo-mode'] ? Locale::getDisplayName( $locale , $dispLocale ) : locale_get_display_name( $locale , $dispLocale ); -} -function ut_loc_get_display_language( $locale , $dispLocale ) -{ - return $GLOBALS['oo-mode'] ? Locale::getDisplayLanguage( $locale , $dispLocale ) : locale_get_display_language( $locale , $dispLocale ); -} -function ut_loc_get_display_script( $locale , $dispLocale ) -{ - return $GLOBALS['oo-mode'] ? Locale::getDisplayScript( $locale , $dispLocale ) : locale_get_display_script( $locale , $dispLocale ); -} -function ut_loc_get_display_region( $locale, $dispLocale ) -{ - return $GLOBALS['oo-mode'] ? Locale::getDisplayRegion( $locale, $dispLocale ) : locale_get_display_region( $locale, $dispLocale ); -} -function ut_loc_get_display_variant( $locale , $dispLocale ) -{ - return $GLOBALS['oo-mode'] ? Locale::getDisplayVariant( $locale , $dispLocale ) : locale_get_display_variant( $locale, $dispLocale ); -} -function ut_loc_locale_compose( $loc_parts_arr ) -{ - return $GLOBALS['oo-mode'] ? Locale::composeLocale( $loc_parts_arr ) : locale_compose( $loc_parts_arr ); -} -function ut_loc_locale_parse( $locale ) -{ - return $GLOBALS['oo-mode'] ? Locale::parseLocale( $locale ) : locale_parse($locale ); -} -function ut_loc_locale_get_all_variants( $locale ) -{ - return $GLOBALS['oo-mode'] ? Locale::getAllVariants( $locale ) : locale_get_all_variants( $locale ); -} -function ut_loc_locale_filter_matches( $lang_tag,$loc_range ,$isCanonical) -{ - return $GLOBALS['oo-mode'] ? Locale::filterMatches( $lang_tag,$loc_range ,$isCanonical) : locale_filter_matches( $lang_tag,$loc_range ,$isCanonical); -} -function ut_loc_canonicalize( $locale ) -{ - return $GLOBALS['oo-mode'] ? Locale::canonicalize( $locale ) : locale_canonicalize( $locale ); -} -function ut_loc_locale_lookup( $lang_tag_arr,$loc_range,$isCanonical,$default_loc) -{ - return $GLOBALS['oo-mode'] ? Locale::lookup( $lang_tag_arr,$loc_range,$isCanonical,$default_loc ) : locale_lookup( $lang_tag_arr,$loc_range,$isCanonical,$default_loc ); -} -function ut_loc_accept_http($http) { - return $GLOBALS['oo-mode'] ? Locale::acceptFromHttp($http):locale_accept_from_http($http); -} -/* MessageFormatter functions */ -function ut_msgfmt_create( $locale, $pattern) -{ - return $GLOBALS['oo-mode'] ? MessageFormatter::create( $locale, $pattern ) : msgfmt_create( $locale, $pattern ); -} -function ut_msgfmt_format( $fmt, $args ) -{ - return $GLOBALS['oo-mode'] ? $fmt->format( $args ) : msgfmt_format( $fmt, $args); -} -function ut_msgfmt_parse( $fmt, $string) -{ - return $GLOBALS['oo-mode'] ? $fmt->parse( $string) : msgfmt_parse( $fmt, $string); -} -function ut_msgfmt_format_message( $locale, $pattern, $args ) -{ - return $GLOBALS['oo-mode'] ? MessageFormatter::formatMessage( $locale, $pattern, $args ) : msgfmt_format_message( $locale, $pattern, $args ); -} -function ut_msgfmt_parse_message( $locale, $pattern, $string ) -{ - return $GLOBALS['oo-mode'] ? MessageFormatter::parseMessage( $locale, $pattern, $string ) : msgfmt_parse_message( $locale, $pattern, $string ); -} -function ut_msgfmt_set_pattern( $fmt, $pattern ) -{ - return $GLOBALS['oo-mode'] ? $fmt->setPattern( $pattern ) : msgfmt_set_pattern( $fmt, $pattern ); -} -function ut_msgfmt_get_pattern( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getPattern() : msgfmt_get_pattern( $fmt ); -} -function ut_msgfmt_get_locale( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getLocale( ) : msgfmt_get_locale( $fmt ); -} -function ut_msgfmt_get_error_code( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getErrorCode() : msgfmt_get_error_code( $fmt ); -} -function ut_msgfmt_get_error_message( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getErrorMessage() : msgfmt_get_error_message( $fmt ); -} -/* IntlDateFormatter functions */ -function ut_datefmt_create( $locale, $datetype, $timetype, $timezone = null, $calendar = null ,$pattern = null) -{ - return $GLOBALS['oo-mode'] ? datefmt_create( $locale, $datetype, $timetype, $timezone, $calendar ,$pattern ) : datefmt_create( $locale, $datetype, $timetype, $timezone, $calendar ,$pattern); -} -function ut_datefmt_get_datetype( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getDateType( ) : datefmt_get_datetype( $fmt ); -} -function ut_datefmt_get_timetype( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getTimeType( ) : datefmt_get_timetype( $fmt ); -} -function ut_datefmt_get_calendar( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getCalendar( ) : datefmt_get_calendar( $fmt ); -} -function ut_datefmt_set_calendar( $fmt ,$calendar ) -{ - return $GLOBALS['oo-mode'] ? $fmt->setCalendar( $calendar ) : datefmt_set_calendar( $fmt , $calendar ); -} -function ut_datefmt_get_timezone_id( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getTimeZoneId( ) : datefmt_get_timezone_id( $fmt ); -} -function ut_datefmt_set_timezone_id( $fmt ,$timezone_id ) -{ - return $GLOBALS['oo-mode'] ? $fmt->setTimeZoneId( $timezone_id ) : datefmt_set_timezone_id( $fmt ,$timezone_id); -} -function ut_datefmt_get_pattern( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->getPattern() : datefmt_get_pattern( $fmt ); -} -function ut_datefmt_set_pattern( $fmt , $pattern ) -{ - return $GLOBALS['oo-mode'] ? $fmt->setPattern( $pattern ) : datefmt_set_pattern( $fmt , $pattern); -} -function ut_datefmt_get_locale( $fmt ,$type=ULOC_ACTUAL_LOCALE) -{ - return $GLOBALS['oo-mode'] ? $fmt->getLocale($type ) : datefmt_get_locale( $fmt ,$type); -} -function ut_datefmt_is_lenient( $fmt ) -{ - return $GLOBALS['oo-mode'] ? $fmt->isLenient() : datefmt_is_lenient( $fmt ); -} -function ut_datefmt_set_lenient( $fmt , $lenient ) -{ - return $GLOBALS['oo-mode'] ? $fmt->setLenient( $lenient ) : datefmt_set_lenient( $fmt , $lenient); -} -function ut_datefmt_format( $fmt , $value ) -{ - return $GLOBALS['oo-mode'] ? $fmt->format( $value ) : datefmt_format( $fmt , $value); -} -function ut_datefmt_parse( $fmt , $value , &$parse_pos=0 ) -{ - return $GLOBALS['oo-mode'] ? $fmt->parse( $value ,$parse_pos ) : datefmt_parse( $fmt , $value,$parse_pos); -} -function ut_datefmt_localtime( $fmt , $value , &$parse_pos=0 ) -{ - return $GLOBALS['oo-mode'] ? $fmt->localtime( $value , $parse_pos ) : datefmt_localtime( $fmt , $value , $parse_pos ); -} -?> +compare( $str1, $str2 ) : collator_compare( $coll, $str1, $str2 ); +} +function ut_coll_sort( $coll, &$arr, $sort_flag = Collator::SORT_REGULAR ) +{ + return $GLOBALS['oo-mode'] ? $coll->sort( $arr, $sort_flag ) : collator_sort( $coll, $arr, $sort_flag ); +} +function ut_coll_sort_with_sort_keys( $coll, &$arr ) +{ + return $GLOBALS['oo-mode'] ? $coll->sortWithSortKeys( $arr ) : collator_sort_with_sort_keys( $coll, $arr ); +} +function ut_coll_asort( $coll, &$arr, $sort_flag = Collator::SORT_REGULAR ) +{ + return $GLOBALS['oo-mode'] ? $coll->asort( $arr, $sort_flag ) : collator_asort( $coll, $arr, $sort_flag ); +} +function ut_coll_get_locale( $coll, $type ) +{ + return $GLOBALS['oo-mode'] ? $coll->getLocale( $type ) : collator_get_locale( $coll, $type ); +} +function ut_coll_get_display_name( $obj_loc, $disp_loc ) +{ + return $GLOBALS['oo-mode'] ? Collator::getDisplayName( $obj_loc, $disp_loc ) : collator_get_display_name( $obj_loc, $disp_loc ); +} +function ut_coll_get_available_locales() +{ + return $GLOBALS['oo-mode'] ? Collator::getAvailableLocales() : collator_get_available_locales(); +} +function ut_coll_get_attribute( $coll, $attr ) +{ + return $GLOBALS['oo-mode'] ? $coll->getAttribute( $attr ) : collator_get_attribute( $coll, $attr ); +} +function ut_coll_get_strength( $coll ) +{ + return $GLOBALS['oo-mode'] ? $coll->getStrength() : collator_get_strength( $coll ); +} +function ut_coll_set_strength( $coll, $strength ) +{ + return $GLOBALS['oo-mode'] ? $coll->setStrength( $strength ) : collator_set_strength( $coll, $strength ); +} +function ut_coll_set_attribute( $coll, $attr, $val ) +{ + return $GLOBALS['oo-mode'] ? $coll->setAttribute( $attr, $val ) : collator_set_attribute( $coll, $attr, $val ); +} +function ut_coll_get_variable_top( $coll ) +{ + return $GLOBALS['oo-mode'] ? $coll->getVariableTop() : collator_get_variable_top( $coll ); +} +function ut_coll_set_variable_top( $coll, $var_top ) +{ + return $GLOBALS['oo-mode'] ? $coll->setVariableTop( $var_top ) : collator_set_variable_top( $coll, $var_top ); +} +function ut_coll_restore_variable_top( $coll, $var_top ) +{ + return $GLOBALS['oo-mode'] ? $coll->restoreVariableTop( $var_top ) : collator_restore_variable_top( $coll, $var_top ); +} +function ut_coll_get_error_code( $coll ) +{ + return $GLOBALS['oo-mode'] ? $coll->getErrorCode() : collator_get_error_code( $coll ); +} +function ut_coll_get_error_message( $coll ) +{ + return $GLOBALS['oo-mode'] ? $coll->getErrorMessage() : collator_get_error_message( $coll ); +} +function ut_coll_get_default() +{ + return $GLOBALS['oo-mode'] ? Collator::getDefault() : collator_get_default(); +} +function ut_coll_set_default( $coll ) +{ + return $GLOBALS['oo-mode'] ? Collator::setDefault( $coll ) : collator_set_default( $coll ); +} + +/* + * Wrappers around NumberFormatter methods to run them in either OO- or procedural mode. + */ + +// FIXME: incomplete list + +function ut_nfmt_create( $locale, $style, $pattern = null ) +{ + return $GLOBALS['oo-mode'] ? new NumberFormatter( $locale, $style, $pattern ) : numfmt_create( $locale, $style, $pattern ); +} +function ut_nfmt_format( $fmt, $number, $type = null ) +{ + return $GLOBALS['oo-mode'] ? $fmt->format( $number, $type ) : numfmt_format( $fmt, $number, $type ); +} +function ut_nfmt_parse( $fmt, $string, $type = NumberFormatter::TYPE_DOUBLE, &$position = null ) +{ + if(is_null($position)) { + return $GLOBALS['oo-mode'] ? $fmt->parse( $string, $type ) : numfmt_parse( $fmt, $string, $type ); + } else { + return $GLOBALS['oo-mode'] ? $fmt->parse( $string, $type, $position ) : numfmt_parse( $fmt, $string, $type, $position ); + } +} +function ut_nfmt_format_currency( $fmt, $number, $currency ) +{ + return $GLOBALS['oo-mode'] ? $fmt->formatCurrency( $number, $currency ) : numfmt_format_currency( $fmt, $number, $currency ); +} +function ut_nfmt_parse_currency( $fmt, $string, &$currency, &$position = null ) +{ + if(is_null($position)) { + return $GLOBALS['oo-mode'] ? $fmt->parseCurrency( $string, $currency ) : numfmt_parse_currency( $fmt, $string, $currency ); + } else { + return $GLOBALS['oo-mode'] ? $fmt->parseCurrency( $string, $currency, $position ) : numfmt_parse_currency( $fmt, $string, $currency, $position ); + } +} +function ut_nfmt_set_attribute( $fmt, $attribute, $value ) +{ + return $GLOBALS['oo-mode'] ? $fmt->setAttribute( $attribute, $value ) : numfmt_set_attribute( $fmt, $attribute, $value ); +} +function ut_nfmt_set_text_attribute( $fmt, $attribute, $value ) +{ + return $GLOBALS['oo-mode'] ? $fmt->setTextAttribute( $attribute, $value ) : numfmt_set_text_attribute( $fmt, $attribute, $value ); +} +function ut_nfmt_set_symbol( $fmt, $attribute, $value ) +{ + return $GLOBALS['oo-mode'] ? $fmt->setSymbol( $attribute, $value ) : numfmt_set_symbol( $fmt, $attribute, $value ); +} +function ut_nfmt_set_pattern( $fmt, $pattern ) +{ + return $GLOBALS['oo-mode'] ? $fmt->setPattern( $pattern ) : numfmt_set_pattern( $fmt, $pattern ); +} +function ut_nfmt_get_attribute( $fmt, $attribute ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getAttribute( $attribute ) : numfmt_get_attribute( $fmt, $attribute ); +} +function ut_nfmt_get_text_attribute( $fmt, $attribute ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getTextAttribute( $attribute ) : numfmt_get_text_attribute( $fmt, $attribute ); +} +function ut_nfmt_get_symbol( $fmt, $attribute ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getSymbol( $attribute ) : numfmt_get_symbol( $fmt, $attribute ); +} +function ut_nfmt_get_pattern( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getPattern() : numfmt_get_pattern( $fmt ); +} +function ut_nfmt_get_locale( $fmt, $type = 0 ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getLocale( $type ) : numfmt_get_locale( $fmt, $type ); +} +function ut_nfmt_get_error_code( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getErrorCode() : numfmt_get_error_code( $fmt ); +} +function ut_nfmt_get_error_message( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getErrorMessage() : numfmt_get_error_message( $fmt ); +} + +function ut_norm_normalize( $str, $form ) +{ + return $GLOBALS['oo-mode'] ? Normalizer::normalize( $str, $form ) : normalizer_normalize( $str, $form ); +} +function ut_norm_is_normalized( $str, $form ) +{ + return $GLOBALS['oo-mode'] ? Normalizer::isNormalized( $str, $form ) : normalizer_is_normalized( $str, $form ); +} + +/* + * Wrappers around Collator methods to run them in either OO- or procedural mode. + */ + +function ut_loc_get_default( ) +{ + return $GLOBALS['oo-mode'] ? Locale::getDefault( ) : locale_get_default(); +} +function ut_loc_set_default( $locale ) +{ + return $GLOBALS['oo-mode'] ? Locale::setDefault( $locale ) : locale_set_default( $locale ); +} +function ut_loc_get_primary_language( $locale ) +{ + return $GLOBALS['oo-mode'] ? Locale::getPrimaryLanguage( $locale ) : locale_get_primary_language( $locale ); +} +function ut_loc_get_script( $locale ) +{ + return $GLOBALS['oo-mode'] ? Locale::getScript( $locale ) : locale_get_script( $locale ); +} +function ut_loc_get_region( $locale ) +{ + return $GLOBALS['oo-mode'] ? Locale::getRegion( $locale ) : locale_get_region( $locale ); +} +function ut_loc_get_keywords( $locale ) +{ + return $GLOBALS['oo-mode'] ? Locale::getKeywords( $locale ) : locale_get_keywords( $locale ); +} +function ut_loc_get_display_name( $locale , $dispLocale ) +{ + return $GLOBALS['oo-mode'] ? Locale::getDisplayName( $locale , $dispLocale ) : locale_get_display_name( $locale , $dispLocale ); +} +function ut_loc_get_display_language( $locale , $dispLocale ) +{ + return $GLOBALS['oo-mode'] ? Locale::getDisplayLanguage( $locale , $dispLocale ) : locale_get_display_language( $locale , $dispLocale ); +} +function ut_loc_get_display_script( $locale , $dispLocale ) +{ + return $GLOBALS['oo-mode'] ? Locale::getDisplayScript( $locale , $dispLocale ) : locale_get_display_script( $locale , $dispLocale ); +} +function ut_loc_get_display_region( $locale, $dispLocale ) +{ + return $GLOBALS['oo-mode'] ? Locale::getDisplayRegion( $locale, $dispLocale ) : locale_get_display_region( $locale, $dispLocale ); +} +function ut_loc_get_display_variant( $locale , $dispLocale ) +{ + return $GLOBALS['oo-mode'] ? Locale::getDisplayVariant( $locale , $dispLocale ) : locale_get_display_variant( $locale, $dispLocale ); +} +function ut_loc_locale_compose( $loc_parts_arr ) +{ + return $GLOBALS['oo-mode'] ? Locale::composeLocale( $loc_parts_arr ) : locale_compose( $loc_parts_arr ); +} +function ut_loc_locale_parse( $locale ) +{ + return $GLOBALS['oo-mode'] ? Locale::parseLocale( $locale ) : locale_parse($locale ); +} +function ut_loc_locale_get_all_variants( $locale ) +{ + return $GLOBALS['oo-mode'] ? Locale::getAllVariants( $locale ) : locale_get_all_variants( $locale ); +} +function ut_loc_locale_filter_matches( $lang_tag,$loc_range ,$isCanonical) +{ + return $GLOBALS['oo-mode'] ? Locale::filterMatches( $lang_tag,$loc_range ,$isCanonical) : locale_filter_matches( $lang_tag,$loc_range ,$isCanonical); +} +function ut_loc_canonicalize( $locale ) +{ + return $GLOBALS['oo-mode'] ? Locale::canonicalize( $locale ) : locale_canonicalize( $locale ); +} +function ut_loc_locale_lookup( $lang_tag_arr,$loc_range,$isCanonical,$default_loc) +{ + return $GLOBALS['oo-mode'] ? Locale::lookup( $lang_tag_arr,$loc_range,$isCanonical,$default_loc ) : locale_lookup( $lang_tag_arr,$loc_range,$isCanonical,$default_loc ); +} +function ut_loc_accept_http($http) { + return $GLOBALS['oo-mode'] ? Locale::acceptFromHttp($http):locale_accept_from_http($http); +} +/* MessageFormatter functions */ +function ut_msgfmt_create( $locale, $pattern) +{ + return $GLOBALS['oo-mode'] ? MessageFormatter::create( $locale, $pattern ) : msgfmt_create( $locale, $pattern ); +} +function ut_msgfmt_format( $fmt, $args ) +{ + return $GLOBALS['oo-mode'] ? $fmt->format( $args ) : msgfmt_format( $fmt, $args); +} +function ut_msgfmt_parse( $fmt, $string) +{ + return $GLOBALS['oo-mode'] ? $fmt->parse( $string) : msgfmt_parse( $fmt, $string); +} +function ut_msgfmt_format_message( $locale, $pattern, $args ) +{ + return $GLOBALS['oo-mode'] ? MessageFormatter::formatMessage( $locale, $pattern, $args ) : msgfmt_format_message( $locale, $pattern, $args ); +} +function ut_msgfmt_parse_message( $locale, $pattern, $string ) +{ + return $GLOBALS['oo-mode'] ? MessageFormatter::parseMessage( $locale, $pattern, $string ) : msgfmt_parse_message( $locale, $pattern, $string ); +} +function ut_msgfmt_set_pattern( $fmt, $pattern ) +{ + return $GLOBALS['oo-mode'] ? $fmt->setPattern( $pattern ) : msgfmt_set_pattern( $fmt, $pattern ); +} +function ut_msgfmt_get_pattern( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getPattern() : msgfmt_get_pattern( $fmt ); +} +function ut_msgfmt_get_locale( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getLocale( ) : msgfmt_get_locale( $fmt ); +} +function ut_msgfmt_get_error_code( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getErrorCode() : msgfmt_get_error_code( $fmt ); +} +function ut_msgfmt_get_error_message( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getErrorMessage() : msgfmt_get_error_message( $fmt ); +} +/* IntlDateFormatter functions */ +function ut_datefmt_create( $locale, $datetype, $timetype, $timezone = null, $calendar = null ,$pattern = null) +{ + return $GLOBALS['oo-mode'] ? datefmt_create( $locale, $datetype, $timetype, $timezone, $calendar ,$pattern ) : datefmt_create( $locale, $datetype, $timetype, $timezone, $calendar ,$pattern); +} +function ut_datefmt_get_datetype( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getDateType( ) : datefmt_get_datetype( $fmt ); +} +function ut_datefmt_get_timetype( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getTimeType( ) : datefmt_get_timetype( $fmt ); +} +function ut_datefmt_get_calendar( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getCalendar( ) : datefmt_get_calendar( $fmt ); +} +function ut_datefmt_set_calendar( $fmt ,$calendar ) +{ + return $GLOBALS['oo-mode'] ? $fmt->setCalendar( $calendar ) : datefmt_set_calendar( $fmt , $calendar ); +} +function ut_datefmt_get_timezone_id( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getTimeZoneId( ) : datefmt_get_timezone_id( $fmt ); +} +function ut_datefmt_set_timezone_id( $fmt ,$timezone_id ) +{ + return $GLOBALS['oo-mode'] ? $fmt->setTimeZoneId( $timezone_id ) : datefmt_set_timezone_id( $fmt ,$timezone_id); +} +function ut_datefmt_get_pattern( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->getPattern() : datefmt_get_pattern( $fmt ); +} +function ut_datefmt_set_pattern( $fmt , $pattern ) +{ + return $GLOBALS['oo-mode'] ? $fmt->setPattern( $pattern ) : datefmt_set_pattern( $fmt , $pattern); +} +function ut_datefmt_get_locale( $fmt ,$type=ULOC_ACTUAL_LOCALE) +{ + return $GLOBALS['oo-mode'] ? $fmt->getLocale($type ) : datefmt_get_locale( $fmt ,$type); +} +function ut_datefmt_is_lenient( $fmt ) +{ + return $GLOBALS['oo-mode'] ? $fmt->isLenient() : datefmt_is_lenient( $fmt ); +} +function ut_datefmt_set_lenient( $fmt , $lenient ) +{ + return $GLOBALS['oo-mode'] ? $fmt->setLenient( $lenient ) : datefmt_set_lenient( $fmt , $lenient); +} +function ut_datefmt_format( $fmt , $value ) +{ + return $GLOBALS['oo-mode'] ? $fmt->format( $value ) : datefmt_format( $fmt , $value); +} +function ut_datefmt_parse( $fmt , $value , &$parse_pos=0 ) +{ + return $GLOBALS['oo-mode'] ? $fmt->parse( $value ,$parse_pos ) : datefmt_parse( $fmt , $value,$parse_pos); +} +function ut_datefmt_localtime( $fmt , $value , &$parse_pos=0 ) +{ + return $GLOBALS['oo-mode'] ? $fmt->localtime( $value , $parse_pos ) : datefmt_localtime( $fmt , $value , $parse_pos ); +} +?> diff --git a/ext/json/JSON_parser.h b/ext/json/JSON_parser.h index 771ba967a..746190bb3 100644 --- a/ext/json/JSON_parser.h +++ b/ext/json/JSON_parser.h @@ -24,6 +24,7 @@ enum error_codes { PHP_JSON_ERROR_STATE_MISMATCH, PHP_JSON_ERROR_CTRL_CHAR, PHP_JSON_ERROR_SYNTAX, + PHP_JSON_ERROR_UTF8 }; extern JSON_parser new_JSON_parser(int depth); diff --git a/ext/json/config.m4 b/ext/json/config.m4 index f650da84b..7de45b284 100644 --- a/ext/json/config.m4 +++ b/ext/json/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.3.2.4.2.1 2009/06/23 13:09:34 johannes Exp $ +dnl $Id: config.m4 282645 2009-06-23 13:09:34Z johannes $ dnl PHP_ARG_ENABLE(json, whether to enable JavaScript Object Serialization support, diff --git a/ext/json/config.w32 b/ext/json/config.w32 index 0cc79dc00..f8fb0de74 100644 --- a/ext/json/config.w32 +++ b/ext/json/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.2.2.1 2006/07/22 15:33:02 rrichards Exp $ +// $Id: config.w32 216887 2006-07-22 15:33:02Z rrichards $ // vim:ft=javascript ARG_ENABLE("json", "JavaScript Object Serialization support", "yes"); diff --git a/ext/json/json.c b/ext/json/json.c index 09a37bb56..1c2d63e40 100644 --- a/ext/json/json.c +++ b/ext/json/json.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: json.c,v 1.9.2.19.2.24 2009/06/24 17:39:52 felipe Exp $ */ +/* $Id: json.c 286385 2009-07-27 03:43:38Z scottmac $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -301,6 +301,7 @@ static void json_escape_string(smart_str *buf, char *s, int len, int options TSR efree(utf16); } if (len < 0) { + JSON_G(error_code) = PHP_JSON_ERROR_UTF8; if (!PG(display_errors)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid UTF-8 sequence in argument"); } @@ -411,8 +412,9 @@ static void json_escape_string(smart_str *buf, char *s, int len, int options TSR } /* }}} */ -PHPAPI void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC) /* {{{ */ +PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC) /* {{{ */ { + JSON_G(error_code) = PHP_JSON_ERROR_NONE; switch (Z_TYPE_P(val)) { case IS_NULL: @@ -467,7 +469,7 @@ PHPAPI void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC) /* } /* }}} */ -PHPAPI void php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, long depth TSRMLS_DC) /* {{{ */ +PHP_JSON_API void php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, long depth TSRMLS_DC) /* {{{ */ { int utf16_len; zval *z; diff --git a/ext/json/php_json.h b/ext/json/php_json.h index 52a8ee527..dacacc1b3 100644 --- a/ext/json/php_json.h +++ b/ext/json/php_json.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_json.h,v 1.8.2.2.2.7 2009/05/31 18:55:10 andrei Exp $ */ +/* $Id: php_json.h 283185 2009-06-30 17:52:21Z stas $ */ #ifndef PHP_JSON_H #define PHP_JSON_H @@ -27,6 +27,12 @@ extern zend_module_entry json_module_entry; #define phpext_json_ptr &json_module_entry +#if defined(PHP_WIN32) && defined(JSON_EXPORTS) +#define PHP_JSON_API __declspec(dllexport) +#else +#define PHP_JSON_API PHPAPI +#endif + #ifdef ZTS #include "TSRM.h" #endif @@ -41,8 +47,8 @@ ZEND_END_MODULE_GLOBALS(json) # define JSON_G(v) (json_globals.v) #endif -PHPAPI void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC); -PHPAPI void php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, long depth TSRMLS_DC); +PHP_JSON_API void php_json_encode(smart_str *buf, zval *val, int options TSRMLS_DC); +PHP_JSON_API void php_json_decode(zval *return_value, char *str, int str_len, zend_bool assoc, long depth TSRMLS_DC); #endif /* PHP_JSON_H */ diff --git a/ext/ldap/config.m4 b/ext/ldap/config.m4 index 15af99999..9d8086232 100644 --- a/ext/ldap/config.m4 +++ b/ext/ldap/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.39.2.6.2.2 2007/08/08 11:37:44 nlopess Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl AC_DEFUN([PHP_LDAP_CHECKS], [ diff --git a/ext/ldap/config.w32 b/ext/ldap/config.w32 index 2450f5c2f..f521fe574 100644 --- a/ext/ldap/config.w32 +++ b/ext/ldap/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.2.4.1.2.1 2008/07/31 18:04:49 pajoye Exp $ +// $Id: config.w32 263930 2008-07-31 18:04:49Z pajoye $ // vim:ft=javascript ARG_WITH("ldap", "LDAP support", "no"); diff --git a/ext/ldap/ldap.c b/ext/ldap/ldap.c index b214b9967..4a8941cf1 100644 --- a/ext/ldap/ldap.c +++ b/ext/ldap/ldap.c @@ -23,7 +23,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: ldap.c,v 1.161.2.3.2.11.2.30 2009/06/25 15:19:29 johannes Exp $ */ +/* $Id: ldap.c 287897 2009-08-30 15:33:59Z iliaa $ */ #define IS_EXT_MODULE #ifdef HAVE_CONFIG_H @@ -117,6 +117,7 @@ static void _free_ldap_result_entry(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ if (entry->ber != NULL) { ber_free(entry->ber, 0); + entry->ber = NULL; } zend_list_delete(entry->id); efree(entry); @@ -224,7 +225,7 @@ PHP_MINFO_FUNCTION(ldap) php_info_print_table_start(); php_info_print_table_row(2, "LDAP Support", "enabled"); - php_info_print_table_row(2, "RCS Version", "$Id: ldap.c,v 1.161.2.3.2.11.2.30 2009/06/25 15:19:29 johannes Exp $"); + php_info_print_table_row(2, "RCS Version", "$Id: ldap.c 287897 2009-08-30 15:33:59Z iliaa $"); if (LDAPG(max_links) == -1) { snprintf(tmp, 31, "%ld/unlimited", LDAPG(num_links)); @@ -585,59 +586,36 @@ static void php_set_opts(LDAP *ldap, int sizelimit, int timelimit, int deref, in */ static void php_ldap_do_search(INTERNAL_FUNCTION_PARAMETERS, int scope) { - zval **link, **base_dn, **filter, **attrs, **attr, **attrsonly, **sizelimit, **timelimit, **deref; - char *ldap_base_dn = NULL; - char *ldap_filter = NULL; - char **ldap_attrs = NULL; + zval *link, *base_dn, **filter, *attrs, **attr; + long attrsonly, sizelimit, timelimit, deref; + char *ldap_base_dn = NULL, *ldap_filter = NULL, **ldap_attrs = NULL; ldap_linkdata *ld = NULL; LDAPMessage *ldap_res; - int ldap_attrsonly = 0; - int ldap_sizelimit = -1; - int ldap_timelimit = -1; - int ldap_deref = -1; - int old_ldap_sizelimit = -1; - int old_ldap_timelimit = -1; - int old_ldap_deref = -1; - int num_attribs = 0; - int i, errno; - int myargcount = ZEND_NUM_ARGS(); - int ret = 1; - - if (zend_parse_parameters(myargcount TSRMLS_CC, "ZZZ|ZZZZZ", &link, &base_dn, &filter, &attrs, &attrsonly, + int ldap_attrsonly = 0, ldap_sizelimit = -1, ldap_timelimit = -1, ldap_deref = -1; + int old_ldap_sizelimit = -1, old_ldap_timelimit = -1, old_ldap_deref = -1; + int num_attribs = 0, ret = 1, i, errno, argcount = ZEND_NUM_ARGS(); + + if (zend_parse_parameters(argcount TSRMLS_CC, "zzZ|allll", &link, &base_dn, &filter, &attrs, &attrsonly, &sizelimit, &timelimit, &deref) == FAILURE) { return; } /* Reverse -> fall through */ - switch (myargcount) { - case 8 : - convert_to_long_ex(deref); - ldap_deref = Z_LVAL_PP(deref); - - case 7 : - convert_to_long_ex(timelimit); - ldap_timelimit = Z_LVAL_PP(timelimit); - - case 6 : - convert_to_long_ex(sizelimit); - ldap_sizelimit = Z_LVAL_PP(sizelimit); - - case 5 : - convert_to_long_ex(attrsonly); - ldap_attrsonly = Z_LVAL_PP(attrsonly); - - case 4 : - if (Z_TYPE_PP(attrs) != IS_ARRAY) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Expected Array as last element"); - ret = 0; - goto cleanup; - } - - num_attribs = zend_hash_num_elements(Z_ARRVAL_PP(attrs)); + switch (argcount) { + case 8: + ldap_deref = deref; + case 7: + ldap_timelimit = timelimit; + case 6: + ldap_sizelimit = sizelimit; + case 5: + ldap_attrsonly = attrsonly; + case 4: + num_attribs = zend_hash_num_elements(Z_ARRVAL_P(attrs)); ldap_attrs = safe_emalloc((num_attribs+1), sizeof(char *), 0); for (i = 0; ilink, ldap_base_dn, scope, ldap_filter, ldap_attrs, ldap_attrsonly); lds[i] = ld; - zend_hash_move_forward(Z_ARRVAL_PP(link)); + zend_hash_move_forward(Z_ARRVAL_P(link)); } array_init(return_value); @@ -765,11 +737,11 @@ cleanup_parallel: ldap_filter = Z_STRVAL_PP(filter); /* If anything else than string is passed, ldap_base_dn = NULL */ - if (Z_TYPE_PP(base_dn) == IS_STRING) { - ldap_base_dn = Z_STRVAL_PP(base_dn); + if (Z_TYPE_P(base_dn) == IS_STRING) { + ldap_base_dn = Z_STRVAL_P(base_dn); } - ld = (ldap_linkdata *) zend_fetch_resource(link TSRMLS_CC, -1, "ldap link", NULL, 1, le_link); + ld = (ldap_linkdata *) zend_fetch_resource(&link TSRMLS_CC, -1, "ldap link", NULL, 1, le_link); if (ld == NULL) { ret = 0; goto cleanup; @@ -819,7 +791,7 @@ cleanup: } /* }}} */ -/* {{{ proto resource ldap_read(resource link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]]) +/* {{{ proto resource ldap_read(resource|array link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]]) Read an entry */ PHP_FUNCTION(ldap_read) { @@ -827,7 +799,7 @@ PHP_FUNCTION(ldap_read) } /* }}} */ -/* {{{ proto resource ldap_list(resource link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]]) +/* {{{ proto resource ldap_list(resource|array link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]]) Single-level search */ PHP_FUNCTION(ldap_list) { @@ -835,7 +807,7 @@ PHP_FUNCTION(ldap_list) } /* }}} */ -/* {{{ proto resource ldap_search(resource link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]]) +/* {{{ proto resource ldap_search(resource|array link, string base_dn, string filter [, array attrs [, int attrsonly [, int sizelimit [, int timelimit [, int deref]]]]]) Search LDAP tree under base_dn */ PHP_FUNCTION(ldap_search) { @@ -1378,7 +1350,7 @@ static void php_ldap_do_modify(INTERNAL_FUNCTION_PARAMETERS, int oper) RETVAL_FALSE; } else RETVAL_TRUE; } else { - if ((i = ldap_modify_s(ld->link, dn, ldap_mods)) != LDAP_SUCCESS) { + if ((i = ldap_modify_ext_s(ld->link, dn, ldap_mods, NULL, NULL)) != LDAP_SUCCESS) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Modify: %s", ldap_err2string(i)); RETVAL_FALSE; } else RETVAL_TRUE; diff --git a/ext/ldap/php_ldap.h b/ext/ldap/php_ldap.h index c81f9d80e..c30218a70 100644 --- a/ext/ldap/php_ldap.h +++ b/ext/ldap/php_ldap.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ldap.h,v 1.32.2.1.2.2.2.3 2008/12/31 11:15:38 sebastian Exp $ */ +/* $Id: php_ldap.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_LDAP_H #define PHP_LDAP_H diff --git a/ext/ldap/tests/README b/ext/ldap/tests/README new file mode 100644 index 000000000..7dccd270f --- /dev/null +++ b/ext/ldap/tests/README @@ -0,0 +1,53 @@ +Most tests here relies on the availability of an LDAP server configured with TLS. + +Client/Server configuration: +=========================================================== +OpenLDAP 2.3.43 has been used with the configuration below. + +Notes: +1. A self signed certificate can be generated using: + $ openssl req -newkey rsa:1024 -x509 -nodes -out server.pem -keyout server.pem -days 3650 + It is used for testing ldap_start_tls(), which also requires "TLS_REQCERT never" in client configuration +2. An empty LDAP structure is required for the tests to be PASSed + +(/etc/openldap/)slapd.conf: +----------------------------------------------------------- +TLSCACertificateFile /etc/openldap/ssl/server.pem +TLSCertificateFile /etc/openldap/ssl/server.pem +TLSCertificateKeyFile /etc/openldap/ssl/server.pem +TLSVerifyClient never + +# hdb is used instead of bdb as it enables the usage of referrals & aliases +database hdb +suffix "dc=my-domain,dc=com" +checkpoint 32 30 +rootdn "cn=Manager,dc=my-domain,dc=com" +rootpw secret +directory /var/lib/openldap-data +index objectClass eq + +authz-regexp + uid=Manager,cn=digest-md5,cn=auth + cn=Manager,dc=my-domain,dc=com + + +(/etc/openldap/)ldap.conf: +----------------------------------------------------------- +TLS_REQCERT never + +Tests configuration: +=========================================================== +The following environment variables may be defined: +LDAP_TEST_HOST (default: localhost) Host to connect to +LDAP_TEST_PORT (default: 389) Port to connect to +LDAP_TEST_USER (default: cn=Manager,dc=my-domain,dc=com) DN used for binding +LDAP_TEST_SASL_USER (default: Manager) SASL user used for SASL binding +LDAP_TEST_PASSWD (default: secret) Password used for plain and SASL binding +LDAP_TEST_OPT_PROTOCOL_VERSION (default: 3) Version of LDAP protocol to use +LDAP_TEST_SKIP_BIND_FAILURE (default: true) Whether to fail the test or not in case binding fails + +Credits: +=========================================================== +Davide Mendolia +Patrick Allaert + diff --git a/ext/ldap/tests/bug48696.phpt b/ext/ldap/tests/bug48696.phpt index 3cef186a3..8d25b6723 100644 --- a/ext/ldap/tests/bug48696.phpt +++ b/ext/ldap/tests/bug48696.phpt @@ -1,5 +1,10 @@ --TEST-- Bug #48696 (ldap_read() segfaults with invalid parameters) +--SKIPIF-- + --FILE-- +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", + )), + ldap_get_entries( + $link, + ldap_search($link, "dc=my-domain,dc=com", "(o=my-domain)") + ) +); +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +array(2) { + ["count"]=> + int(1) + [0]=> + array(8) { + ["objectclass"]=> + array(4) { + ["count"]=> + int(3) + [0]=> + string(3) "top" + [1]=> + string(8) "dcObject" + [2]=> + string(12) "organization" + } + [0]=> + string(11) "objectclass" + ["dc"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [1]=> + string(2) "dc" + ["o"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [2]=> + string(1) "o" + ["count"]=> + int(3) + ["dn"]=> + string(19) "dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_add_error.phpt b/ext/ldap/tests/ldap_add_error.phpt new file mode 100644 index 000000000..d17db6bfa --- /dev/null +++ b/ext/ldap/tests/ldap_add_error.phpt @@ -0,0 +1,136 @@ +--TEST-- +ldap_add() - Add operation that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + "val", + )), + ldap_error($link), + ldap_errno($link) +); + +// Duplicate entry +for ($i = 0; $i < 2; $i++) + var_dump( + ldap_add($link, "dc=my-domain,dc=com", array( + "objectClass" => array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", + )) + ); +var_dump(ldap_error($link), ldap_errno($link)); + +// Wrong array indexes +var_dump( + ldap_add($link, "dc=my-domain2,dc=com", array( + "objectClass" => array( + 0 => "top", + 2 => "dcObject", + 5 => "organization"), + "dc" => "my-domain", + "o" => "my-domain", + )) + /* Is this correct behaviour to still have "Already exists" as error/errno? + , + ldap_error($link), + ldap_errno($link) + */ +); + +// Invalid attribute +var_dump( + ldap_add($link, "dc=my-domain,dc=com", array( + "objectClass" => array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", + "weirdAttr" => "weirdVal", + )), + ldap_error($link), + ldap_errno($link) +); + +var_dump( + ldap_add($link, "dc=my-domain,dc=com", array(array( "Oops" + ))) + /* Is this correct behaviour to still have "Undefined attribute type" as error/errno? + , + ldap_error($link), + ldap_errno($link) + */ +); +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_add() expects exactly 3 parameters, 0 given in %s on line %d +NULL + +Warning: ldap_add() expects exactly 3 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_add() expects exactly 3 parameters, 2 given in %s on line %d +NULL + +Warning: ldap_add() expects exactly 3 parameters, 4 given in %s on line %d +NULL + +Warning: ldap_add(): Add: Protocol error in %s on line %d +bool(false) + +Warning: ldap_add(): Add: Invalid DN syntax in %s on line %d +bool(false) +string(17) "Invalid DN syntax" +int(34) +bool(true) + +Warning: ldap_add(): Add: Already exists in %s on line %d +bool(false) +string(14) "Already exists" +int(68) + +Warning: ldap_add(): Value array must have consecutive indices 0, 1, ... in %s on line %d +bool(false) + +Warning: ldap_add(): Add: Undefined attribute type in %s on line %d +bool(false) +string(24) "Undefined attribute type" +int(17) + +Warning: ldap_add(): Unknown attribute in the data in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_bind_basic.phpt b/ext/ldap/tests/ldap_bind_basic.phpt new file mode 100644 index 000000000..bac8d0d11 --- /dev/null +++ b/ext/ldap/tests/ldap_bind_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +ldap_bind() - Basic anonymous binding +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +bool(true) +===DONE=== diff --git a/ext/ldap/tests/ldap_bind_error.phpt b/ext/ldap/tests/ldap_bind_error.phpt new file mode 100644 index 000000000..a569ce692 --- /dev/null +++ b/ext/ldap/tests/ldap_bind_error.phpt @@ -0,0 +1,35 @@ +--TEST-- +ldap_bind() - Binding that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_bind() expects at most 3 parameters, 4 given in %s on line %d +bool(false) + +Warning: ldap_bind(): Unable to bind to server: Invalid credentials in %s on line %d +bool(false) + +Warning: ldap_bind(): Unable to bind to server: Invalid DN syntax in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_bind_variation.phpt b/ext/ldap/tests/ldap_bind_variation.phpt new file mode 100644 index 000000000..64abf6cbb --- /dev/null +++ b/ext/ldap/tests/ldap_bind_variation.phpt @@ -0,0 +1,19 @@ +--TEST-- +ldap_bind() - Advanced binding +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +bool(true) +===DONE=== diff --git a/ext/ldap/tests/ldap_compare_basic.phpt b/ext/ldap/tests/ldap_compare_basic.phpt new file mode 100644 index 000000000..b0c5e97fb --- /dev/null +++ b/ext/ldap/tests/ldap_compare_basic.phpt @@ -0,0 +1,31 @@ +--TEST-- +ldap_compare() - Basic ldap_compare test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_compare_error.phpt b/ext/ldap/tests/ldap_compare_error.phpt new file mode 100644 index 000000000..28127578f --- /dev/null +++ b/ext/ldap/tests/ldap_compare_error.phpt @@ -0,0 +1,55 @@ +--TEST-- +ldap_compare() - Testing ldap_compare() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_compare() expects exactly 4 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_compare() expects exactly 4 parameters, 2 given in %s on line %d +NULL + +Warning: ldap_compare() expects exactly 4 parameters, 3 given in %s on line %d +NULL + +Warning: ldap_compare() expects exactly 4 parameters, 5 given in %s on line %d +NULL + +Warning: ldap_compare(): Compare: No such object in %s on line %d +int(-1) +string(14) "No such object" +int(32) +===DONE=== diff --git a/ext/ldap/tests/ldap_connect_basic.phpt b/ext/ldap/tests/ldap_connect_basic.phpt new file mode 100644 index 000000000..26133a6b2 --- /dev/null +++ b/ext/ldap/tests/ldap_connect_basic.phpt @@ -0,0 +1,18 @@ +--TEST-- +ldap_connect() - Basic connection +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +resource(%d) of type (ldap link) +===DONE=== diff --git a/ext/ldap/tests/ldap_connect_error.phpt b/ext/ldap/tests/ldap_connect_error.phpt new file mode 100644 index 000000000..fa28fcf07 --- /dev/null +++ b/ext/ldap/tests/ldap_connect_error.phpt @@ -0,0 +1,31 @@ +--TEST-- +ldap_connect() - Connection errors +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--INI-- +ldap.max_links=1 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_connect() expects at most 2 parameters, 3 given in %s on line %d +bool(false) + +Warning: ldap_connect(): Could not create session handle: %s in %s on line %d +bool(false) + +Warning: ldap_connect(): Too many open links (1) in %s on line %d +===DONE=== diff --git a/ext/ldap/tests/ldap_connect_variation.phpt b/ext/ldap/tests/ldap_connect_variation.phpt new file mode 100644 index 000000000..09b07e778 --- /dev/null +++ b/ext/ldap/tests/ldap_connect_variation.phpt @@ -0,0 +1,39 @@ +--TEST-- +ldap_connect() - Variation +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +resource(%d) of type (ldap link) +resource(%d) of type (ldap link) +resource(%d) of type (ldap link) +resource(%d) of type (ldap link) +resource(%d) of type (ldap link) +===DONE=== diff --git a/ext/ldap/tests/ldap_count_entries_basic.phpt b/ext/ldap/tests/ldap_count_entries_basic.phpt new file mode 100644 index 000000000..a03f0596e --- /dev/null +++ b/ext/ldap/tests/ldap_count_entries_basic.phpt @@ -0,0 +1,28 @@ +--TEST-- +ldap_count_entries() - Basic counting LDAP entries +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +int(3) +===DONE=== diff --git a/ext/ldap/tests/ldap_count_entries_error.phpt b/ext/ldap/tests/ldap_count_entries_error.phpt new file mode 100644 index 000000000..552625a7e --- /dev/null +++ b/ext/ldap/tests/ldap_count_entries_error.phpt @@ -0,0 +1,23 @@ +--TEST-- +ldap_count_entries() - Testing counting LDAP entries that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_count_entries() expects exactly 2 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_count_entries(): supplied resource is not a valid ldap result resource in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_delete_basic.phpt b/ext/ldap/tests/ldap_delete_basic.phpt new file mode 100644 index 000000000..145738478 --- /dev/null +++ b/ext/ldap/tests/ldap_delete_basic.phpt @@ -0,0 +1,40 @@ +--TEST-- +ldap_delete() - Basic delete operation +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", +)); + +var_dump( + ldap_delete($link, "dc=my-domain,dc=com"), + @ldap_search($link, "dc=my-domain,dc=com", "(o=my-domain)") +); +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_delete_error.phpt b/ext/ldap/tests/ldap_delete_error.phpt new file mode 100644 index 000000000..6ef997bb0 --- /dev/null +++ b/ext/ldap/tests/ldap_delete_error.phpt @@ -0,0 +1,62 @@ +--TEST-- +ldap_delete() - Delete operation that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_delete() expects exactly 2 parameters, 0 given in %s on line %d +NULL + +Warning: ldap_delete() expects exactly 2 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_delete() expects exactly 2 parameters, 3 given in %s on line %d +NULL + +Warning: ldap_delete(): Delete: Invalid DN syntax in %s on line %d +bool(false) +string(17) "Invalid DN syntax" +int(34) + +Warning: ldap_delete(): Delete: No such object in %s on line %d +bool(false) +string(14) "No such object" +int(32) +===DONE=== diff --git a/ext/ldap/tests/ldap_err2str_basic.phpt b/ext/ldap/tests/ldap_err2str_basic.phpt new file mode 100644 index 000000000..0ecad0340 --- /dev/null +++ b/ext/ldap/tests/ldap_err2str_basic.phpt @@ -0,0 +1,15 @@ +--TEST-- +ldap_err2str() - Basic error number to string conversion +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +string(14) "Protocol error" +===DONE=== diff --git a/ext/ldap/tests/ldap_err2str_error.phpt b/ext/ldap/tests/ldap_err2str_error.phpt new file mode 100644 index 000000000..0f768d2d6 --- /dev/null +++ b/ext/ldap/tests/ldap_err2str_error.phpt @@ -0,0 +1,28 @@ +--TEST-- +ldap_err2str() - Incorrect usage of number to string conversion +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_err2str() expects exactly 1 parameter, 0 given in %s on line %d +NULL + +Warning: ldap_err2str() expects exactly 1 parameter, 2 given in %s on line %d +NULL + +Warning: ldap_err2str() expects parameter 1 to be long, %unicode_string_optional% given in %s on line %d +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_errno_basic.phpt b/ext/ldap/tests/ldap_errno_basic.phpt new file mode 100644 index 000000000..4b02ac6d6 --- /dev/null +++ b/ext/ldap/tests/ldap_errno_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +ldap_errno() - Basic ldap_errno() operation +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", +)); + +var_dump( + ldap_errno($link) +); +?> +===DONE=== +--EXPECT-- +int(34) +===DONE=== diff --git a/ext/ldap/tests/ldap_errno_error.phpt b/ext/ldap/tests/ldap_errno_error.phpt new file mode 100644 index 000000000..a05876c88 --- /dev/null +++ b/ext/ldap/tests/ldap_errno_error.phpt @@ -0,0 +1,23 @@ +--TEST-- +ldap_errno() - ldap_errno() operation that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_errno() expects exactly 1 parameter, 0 given in %s on line %d +NULL + +Warning: ldap_errno() expects exactly 1 parameter, 2 given in %s on line %d +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_error_basic.phpt b/ext/ldap/tests/ldap_error_basic.phpt new file mode 100644 index 000000000..64e4ef617 --- /dev/null +++ b/ext/ldap/tests/ldap_error_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +ldap_error() - Basic ldap_error() operation +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", +)); + +var_dump( + ldap_error($link) +); +?> +===DONE=== +--EXPECT-- +string(17) "Invalid DN syntax" +===DONE=== diff --git a/ext/ldap/tests/ldap_error_error.phpt b/ext/ldap/tests/ldap_error_error.phpt new file mode 100644 index 000000000..e74eacf00 --- /dev/null +++ b/ext/ldap/tests/ldap_error_error.phpt @@ -0,0 +1,23 @@ +--TEST-- +ldap_error() - ldap_error() operation that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_error() expects exactly 1 parameter, 0 given in %s on line %d +NULL + +Warning: ldap_error() expects exactly 1 parameter, 2 given in %s on line %d +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_first_attribute_basic.phpt b/ext/ldap/tests/ldap_first_attribute_basic.phpt new file mode 100644 index 000000000..8e506fae8 --- /dev/null +++ b/ext/ldap/tests/ldap_first_attribute_basic.phpt @@ -0,0 +1,31 @@ +--TEST-- +ldap_first_attribute() - Basic ldap_first_attribute test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +string(11) "objectClass" +===DONE=== diff --git a/ext/ldap/tests/ldap_first_attribute_error.phpt b/ext/ldap/tests/ldap_first_attribute_error.phpt new file mode 100644 index 000000000..f7016c539 --- /dev/null +++ b/ext/ldap/tests/ldap_first_attribute_error.phpt @@ -0,0 +1,23 @@ +--TEST-- +ldap_first_attribute() - Testing ldap_first_attribute() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_first_attribute() expects %s 2 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_first_attribute(): supplied resource is not a valid ldap result entry resource in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_first_entry_basic.phpt b/ext/ldap/tests/ldap_first_entry_basic.phpt new file mode 100644 index 000000000..9b658227e --- /dev/null +++ b/ext/ldap/tests/ldap_first_entry_basic.phpt @@ -0,0 +1,37 @@ +--TEST-- +ldap_first_entry() - Basic ldap_first_entry test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +resource(%d) of type (ldap result entry) +array(2) { + [0]=> + string(7) "testSN%d" + ["count"]=> + int(1) +} +===DONE=== diff --git a/ext/ldap/tests/ldap_first_entry_error.phpt b/ext/ldap/tests/ldap_first_entry_error.phpt new file mode 100644 index 000000000..9f232e0e8 --- /dev/null +++ b/ext/ldap/tests/ldap_first_entry_error.phpt @@ -0,0 +1,27 @@ +--TEST-- +ldap_first_entry() - Testing ldap_first_entry() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_first_entry() expects exactly 2 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_first_entry() expects exactly 2 parameters, 3 given in %s on line %d +NULL + +Warning: ldap_first_entry(): supplied resource is not a valid ldap result resource in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_first_reference_basic.phpt b/ext/ldap/tests/ldap_first_reference_basic.phpt new file mode 100644 index 000000000..d7834896a --- /dev/null +++ b/ext/ldap/tests/ldap_first_reference_basic.phpt @@ -0,0 +1,43 @@ +--TEST-- +ldap_first_reference() - Basic ldap_first_reference test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + array("extensibleObject", "referral"), + "cn" => "userref", + "ref" => "cn=userA,dc=my-domain,dc=com", +)); +ldap_set_option($link, LDAP_OPT_DEREF, LDAP_DEREF_NEVER); +$result = ldap_search($link, "dc=my-domain,dc=com", "(cn=*)"); +var_dump($ref = ldap_first_reference($link, $result)); +$refs = null; +ldap_parse_reference($link, $ref, $refs); +var_dump($refs); +?> +===DONE=== +--CLEAN-- + "2.16.840.1.113730.3.4.2"))); +ldap_delete($link, "cn=userref,dc=my-domain,dc=com"); +remove_dummy_data($link); +?> +--EXPECTF-- +resource(%d) of type (ldap result entry) +array(1) { + [0]=> + string(28) "cn=userA,dc=my-domain,dc=com" +} +===DONE=== diff --git a/ext/ldap/tests/ldap_first_reference_error.phpt b/ext/ldap/tests/ldap_first_reference_error.phpt new file mode 100644 index 000000000..d5541e10f --- /dev/null +++ b/ext/ldap/tests/ldap_first_reference_error.phpt @@ -0,0 +1,27 @@ +--TEST-- +ldap_first_reference() - Testing ldap_first_reference() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_first_reference() expects exactly 2 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_first_reference() expects exactly 2 parameters, 3 given in %s on line %d +NULL + +Warning: ldap_first_reference(): supplied resource is not a valid ldap result resource in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_free_result_basic.phpt b/ext/ldap/tests/ldap_free_result_basic.phpt new file mode 100644 index 000000000..33e47d6ea --- /dev/null +++ b/ext/ldap/tests/ldap_free_result_basic.phpt @@ -0,0 +1,28 @@ +--TEST-- +ldap_free_result() - Basic ldap_free_result tests +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +===DONE=== diff --git a/ext/ldap/tests/ldap_free_result_error.phpt b/ext/ldap/tests/ldap_free_result_error.phpt new file mode 100644 index 000000000..05623d62d --- /dev/null +++ b/ext/ldap/tests/ldap_free_result_error.phpt @@ -0,0 +1,23 @@ +--TEST-- +ldap_free_result() - Testing ldap_free_result() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_free_result(): supplied resource is not a valid ldap result resource in %s on line %d +bool(false) + +Warning: ldap_free_result() expects exactly 1 parameter, 2 given in %s on line %d +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_get_attributes_basic.phpt b/ext/ldap/tests/ldap_get_attributes_basic.phpt new file mode 100644 index 000000000..82074c592 --- /dev/null +++ b/ext/ldap/tests/ldap_get_attributes_basic.phpt @@ -0,0 +1,65 @@ +--TEST-- +ldap_get_attributes() - Basic ldap_get_attributes test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +array(7) { + ["objectClass"]=> + array(4) { + ["count"]=> + int(3) + [0]=> + string(3) "top" + [1]=> + string(8) "dcObject" + [2]=> + string(12) "organization" + } + [0]=> + string(11) "objectClass" + ["dc"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [1]=> + string(2) "dc" + ["o"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [2]=> + string(1) "o" + ["count"]=> + int(3) +} +===DONE=== diff --git a/ext/ldap/tests/ldap_get_attributes_error.phpt b/ext/ldap/tests/ldap_get_attributes_error.phpt new file mode 100644 index 000000000..465ba4fd7 --- /dev/null +++ b/ext/ldap/tests/ldap_get_attributes_error.phpt @@ -0,0 +1,23 @@ +--TEST-- +ldap_get_attributes() - Testing ldap_get_attributes() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_get_attributes() expects exactly 2 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_get_attributes(): supplied resource is not a valid ldap result entry resource in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_get_dn_basic.phpt b/ext/ldap/tests/ldap_get_dn_basic.phpt new file mode 100644 index 000000000..e70e7bf6c --- /dev/null +++ b/ext/ldap/tests/ldap_get_dn_basic.phpt @@ -0,0 +1,31 @@ +--TEST-- +ldap_get_dn() - Basic ldap_get_dn test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +string(19) "dc=my-domain,dc=com" +===DONE=== diff --git a/ext/ldap/tests/ldap_get_dn_error.phpt b/ext/ldap/tests/ldap_get_dn_error.phpt new file mode 100644 index 000000000..71df6a3da --- /dev/null +++ b/ext/ldap/tests/ldap_get_dn_error.phpt @@ -0,0 +1,23 @@ +--TEST-- +ldap_get_dn() - Testing ldap_get_dn() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_get_dn() expects exactly 2 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_get_dn(): supplied resource is not a valid ldap result entry resource in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_get_entries_basic.phpt b/ext/ldap/tests/ldap_get_entries_basic.phpt new file mode 100644 index 000000000..90dbb2614 --- /dev/null +++ b/ext/ldap/tests/ldap_get_entries_basic.phpt @@ -0,0 +1,74 @@ +--TEST-- +ldap_get_entries() - Basic modify operation +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +array(2) { + ["count"]=> + int(1) + [0]=> + array(8) { + ["objectclass"]=> + array(4) { + ["count"]=> + int(3) + [0]=> + string(3) "top" + [1]=> + string(8) "dcObject" + [2]=> + string(12) "organization" + } + [0]=> + string(11) "objectclass" + ["dc"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [1]=> + string(2) "dc" + ["o"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [2]=> + string(1) "o" + ["count"]=> + int(3) + ["dn"]=> + string(19) "dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_get_entries_error.phpt b/ext/ldap/tests/ldap_get_entries_error.phpt new file mode 100644 index 000000000..b728dd254 --- /dev/null +++ b/ext/ldap/tests/ldap_get_entries_error.phpt @@ -0,0 +1,33 @@ +--TEST-- +ldap_get_entries() - ldap_get_entries() operation that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_get_entries() expects exactly 2 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_get_entries() expects exactly 2 parameters, 3 given in %s on line %d +NULL + +Warning: ldap_get_entries() expects parameter 2 to be resource, %unicode_string_optional% given in %s on line %d +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_get_entries_variation.phpt b/ext/ldap/tests/ldap_get_entries_variation.phpt new file mode 100644 index 000000000..92c49740c --- /dev/null +++ b/ext/ldap/tests/ldap_get_entries_variation.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test ldap_get_entries() function - variation: used on empty search +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_get_option_basic.phpt b/ext/ldap/tests/ldap_get_option_basic.phpt new file mode 100644 index 000000000..3136a5acb --- /dev/null +++ b/ext/ldap/tests/ldap_get_option_basic.phpt @@ -0,0 +1,25 @@ +--TEST-- +ldap_get_option() - Basic ldap_get_option() operation +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +bool(true) +int(3) +===DONE=== diff --git a/ext/ldap/tests/ldap_get_option_error.phpt b/ext/ldap/tests/ldap_get_option_error.phpt new file mode 100644 index 000000000..cf7a0e5d4 --- /dev/null +++ b/ext/ldap/tests/ldap_get_option_error.phpt @@ -0,0 +1,40 @@ +--TEST-- +ldap_get_option() - ldap_get_option() operation that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_get_option() expects exactly 3 parameters, 0 given in %s on line %d +NULL + +Warning: ldap_get_option() expects exactly 3 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_get_option() expects exactly 3 parameters, 2 given in %s on line %d +NULL + +Warning: ldap_get_option() expects exactly 3 parameters, 4 given in %s on line %d +NULL +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_get_option_variation.phpt b/ext/ldap/tests/ldap_get_option_variation.phpt new file mode 100644 index 000000000..da71d8903 --- /dev/null +++ b/ext/ldap/tests/ldap_get_option_variation.phpt @@ -0,0 +1,66 @@ +--TEST-- +ldap_get_option() - More ldap_get_option() operations +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + "1.2.752.58.10.1", "iscritical" => true), + array("oid" => "1.2.752.58.1.10", "value" => "magic"), +); + +ldap_set_option($link, LDAP_OPT_DEREF, LDAP_DEREF_NEVER); +ldap_set_option($link, LDAP_OPT_SIZELIMIT, 123); +ldap_set_option($link, LDAP_OPT_TIMELIMIT, 33); +ldap_set_option($link, LDAP_OPT_NETWORK_TIMEOUT, 44); +ldap_set_option($link, LDAP_OPT_REFERRALS, false); +ldap_set_option($link, LDAP_OPT_SERVER_CONTROLS, $controls); +ldap_set_option($link, LDAP_OPT_CLIENT_CONTROLS, $controls); +ldap_set_option($link, LDAP_OPT_RESTART, false); + +var_dump( + ldap_get_option($link, LDAP_OPT_DEREF, $option), + $option, + ldap_get_option($link, LDAP_OPT_SIZELIMIT, $option), + $option, + ldap_get_option($link, LDAP_OPT_TIMELIMIT, $option), + $option, + ldap_get_option($link, LDAP_OPT_NETWORK_TIMEOUT, $option), + $option, + ldap_get_option($link, LDAP_OPT_REFERRALS, $option), + $option, + ldap_get_option($link, LDAP_OPT_RESTART, $option), + $option, + ldap_get_option($link, LDAP_OPT_SERVER_CONTROLS, $option), + $option, + ldap_get_option($link, LDAP_OPT_CLIENT_CONTROLS, $option), + $option +); +?> +===DONE=== +--EXPECT-- +bool(true) +int(0) +bool(true) +int(123) +bool(true) +int(33) +bool(true) +int(44) +bool(true) +int(0) +bool(true) +int(0) +bool(false) +int(0) +bool(false) +int(0) +===DONE=== diff --git a/ext/ldap/tests/ldap_get_values_len_basic.phpt b/ext/ldap/tests/ldap_get_values_len_basic.phpt new file mode 100644 index 000000000..ed8461427 --- /dev/null +++ b/ext/ldap/tests/ldap_get_values_len_basic.phpt @@ -0,0 +1,36 @@ +--TEST-- +ldap_get_values_len() - Basic ldap_get_values_len test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +array(2) { + [0]=> + string(9) "my-domain" + ["count"]=> + int(1) +} +===DONE=== diff --git a/ext/ldap/tests/ldap_get_values_len_error.phpt b/ext/ldap/tests/ldap_get_values_len_error.phpt new file mode 100644 index 000000000..8caea1479 --- /dev/null +++ b/ext/ldap/tests/ldap_get_values_len_error.phpt @@ -0,0 +1,45 @@ +--TEST-- +ldap_get_values_len() - Testing ldap_get_values_len() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_get_values_len() expects exactly 3 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_get_values_len() expects exactly 3 parameters, 2 given in %s on line %d +NULL + +Warning: ldap_get_values_len() expects exactly 3 parameters, 4 given in %s on line %d +NULL + +Warning: ldap_get_values_len(): Cannot get the value(s) of attribute %s in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_list_basic.phpt b/ext/ldap/tests/ldap_list_basic.phpt new file mode 100644 index 000000000..1993f30f1 --- /dev/null +++ b/ext/ldap/tests/ldap_list_basic.phpt @@ -0,0 +1,150 @@ +--TEST-- +ldap_list() test +--CREDITS-- +Davide Mendolia +Patrick Allaert +Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +resource(%d) of type (ldap result) +array(3) { + ["count"]=> + int(2) + [0]=> + array(14) { + ["objectclass"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "person" + } + [0]=> + string(11) "objectclass" + ["cn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(5) "userA" + } + [1]=> + string(2) "cn" + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN1" + } + [2]=> + string(2) "sn" + ["userpassword"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(4) "oops" + } + [3]=> + string(12) "userpassword" + ["telephonenumber"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(14) "xx-xx-xx-xx-xx" + } + [4]=> + string(15) "telephonenumber" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "user A" + } + [5]=> + string(11) "description" + ["count"]=> + int(6) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } + [1]=> + array(12) { + ["objectclass"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "person" + } + [0]=> + string(11) "objectclass" + ["cn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(5) "userB" + } + [1]=> + string(2) "cn" + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN2" + } + [2]=> + string(2) "sn" + ["userpassword"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(15) "oopsIDitItAgain" + } + [3]=> + string(12) "userpassword" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "user B" + } + [4]=> + string(11) "description" + ["count"]=> + int(5) + ["dn"]=> + string(28) "cn=userB,dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_list_error.phpt b/ext/ldap/tests/ldap_list_error.phpt new file mode 100644 index 000000000..d234d0aa3 --- /dev/null +++ b/ext/ldap/tests/ldap_list_error.phpt @@ -0,0 +1,35 @@ +--TEST-- +ldap_list() - operation that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_list() expects at least 3 parameters, 0 given in %s on line %d +NULL + +Warning: ldap_list() expects at least 3 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_list() expects at least 3 parameters, 2 given in %s on line %d +NULL + +Warning: ldap_list() expects at most 8 parameters, 9 given in %s on line %d +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_mod_add_basic.phpt b/ext/ldap/tests/ldap_mod_add_basic.phpt new file mode 100644 index 000000000..8c8164cfa --- /dev/null +++ b/ext/ldap/tests/ldap_mod_add_basic.phpt @@ -0,0 +1,90 @@ +--TEST-- +ldap_mod_add() - Basic modify operation +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + "Domain description", +); + +var_dump( + ldap_mod_add($link, "dc=my-domain,dc=com", $entry), + ldap_get_entries( + $link, + ldap_search($link, "dc=my-domain,dc=com", "(Description=Domain description)") + ) +); +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +array(2) { + ["count"]=> + int(1) + [0]=> + array(10) { + ["objectclass"]=> + array(4) { + ["count"]=> + int(3) + [0]=> + string(3) "top" + [1]=> + string(8) "dcObject" + [2]=> + string(12) "organization" + } + [0]=> + string(11) "objectclass" + ["dc"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [1]=> + string(2) "dc" + ["o"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [2]=> + string(1) "o" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(18) "Domain description" + } + [3]=> + string(11) "description" + ["count"]=> + int(4) + ["dn"]=> + string(19) "dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_mod_add_error.phpt b/ext/ldap/tests/ldap_mod_add_error.phpt new file mode 100644 index 000000000..4ba1ef9bb --- /dev/null +++ b/ext/ldap/tests/ldap_mod_add_error.phpt @@ -0,0 +1,83 @@ +--TEST-- +ldap_mod_add() - ldap_mod_add() operations that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", +); + +ldap_add($link, "dc=my-domain,dc=com", $entry); + +$entry2 = $entry; +$entry2["dc"] = "Wrong Domain"; + +var_dump(ldap_mod_add($link, "dc=my-domain,dc=com", $entry2)); + +$entry2 = $entry; +$entry2["weirdAttribute"] = "weirdVal"; + +var_dump(ldap_mod_add($link, "dc=my-domain,dc=com", $entry2)); +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_mod_add() expects exactly 3 parameters, 0 given in %s on line %d +NULL + +Warning: ldap_mod_add() expects exactly 3 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_mod_add() expects exactly 3 parameters, 2 given in %s on line %d +NULL + +Warning: ldap_mod_add() expects exactly 3 parameters, 4 given in %s on line %d +NULL + +Warning: ldap_mod_add(): Modify: No such object in %s on line %d +bool(false) + +Warning: ldap_mod_add(): Modify: Invalid DN syntax in %s on line %d +bool(false) + +Warning: ldap_mod_add(): Modify: Type or value exists in %s on line %d +bool(false) + +Warning: ldap_mod_add(): Modify: Undefined attribute type in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_mod_del_basic.phpt b/ext/ldap/tests/ldap_mod_del_basic.phpt new file mode 100644 index 000000000..0d002bd15 --- /dev/null +++ b/ext/ldap/tests/ldap_mod_del_basic.phpt @@ -0,0 +1,40 @@ +--TEST-- +ldap_mod_del() - Basic modify operation +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + "user A" +); + +var_dump( + ldap_mod_del($link, "cn=userA,dc=my-domain,dc=com", $entry), + ldap_get_entries( + $link, + ldap_search($link, "dc=my-domain,dc=com", "(description=user A)") + ) +); +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_mod_del_error.phpt b/ext/ldap/tests/ldap_mod_del_error.phpt new file mode 100644 index 000000000..71bac9f28 --- /dev/null +++ b/ext/ldap/tests/ldap_mod_del_error.phpt @@ -0,0 +1,62 @@ +--TEST-- +ldap_mod_del() - ldap_mod_del() operations that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_mod_del() expects exactly 3 parameters, 0 given in %s on line %d +NULL + +Warning: ldap_mod_del() expects exactly 3 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_mod_del() expects exactly 3 parameters, 2 given in %s on line %d +NULL + +Warning: ldap_mod_del() expects exactly 3 parameters, 4 given in %s on line %d +NULL + +Warning: ldap_mod_del(): Modify: No such object in %s on line %d +bool(false) + +Warning: ldap_mod_del(): Modify: Invalid DN syntax in %s on line %d +bool(false) + +Warning: ldap_mod_del(): Unknown attribute in the data in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_mod_replace_basic.phpt b/ext/ldap/tests/ldap_mod_replace_basic.phpt new file mode 100644 index 000000000..d1670ec02 --- /dev/null +++ b/ext/ldap/tests/ldap_mod_replace_basic.phpt @@ -0,0 +1,59 @@ +--TEST-- +ldap_mod_replace() - Basic modify operation +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + "user X" +); + +var_dump( + ldap_mod_replace($link, "cn=userA,dc=my-domain,dc=com", $entry), + ldap_get_entries( + $link, + ldap_search($link, "dc=my-domain,dc=com", "(description=user X)", array("description")) + ) +); +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +array(2) { + ["count"]=> + int(1) + [0]=> + array(4) { + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "user X" + } + [0]=> + string(11) "description" + ["count"]=> + int(1) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_mod_replace_error.phpt b/ext/ldap/tests/ldap_mod_replace_error.phpt new file mode 100644 index 000000000..0409e3e38 --- /dev/null +++ b/ext/ldap/tests/ldap_mod_replace_error.phpt @@ -0,0 +1,62 @@ +--TEST-- +ldap_mod_replace() - ldap_mod_replace() operations that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_mod_replace() expects exactly 3 parameters, 0 given in %s on line %d +NULL + +Warning: ldap_mod_replace() expects exactly 3 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_mod_replace() expects exactly 3 parameters, 2 given in %s on line %d +NULL + +Warning: ldap_mod_replace() expects exactly 3 parameters, 4 given in %s on line %d +NULL + +Warning: ldap_mod_replace(): Modify: No such object in %s on line %d +bool(false) + +Warning: ldap_mod_replace(): Modify: Invalid DN syntax in %s on line %d +bool(false) + +Warning: ldap_mod_replace(): Unknown attribute in the data in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_modify_basic.phpt b/ext/ldap/tests/ldap_modify_basic.phpt new file mode 100644 index 000000000..74bd83129 --- /dev/null +++ b/ext/ldap/tests/ldap_modify_basic.phpt @@ -0,0 +1,96 @@ +--TEST-- +ldap_modify() - Basic modify operation +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", + "description" => "Domain description", +); + +var_dump( + ldap_modify($link, "dc=my-domain,dc=com", $entry), + ldap_get_entries( + $link, + ldap_search($link, "dc=my-domain,dc=com", "(Description=Domain description)") + ) +); +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +array(2) { + ["count"]=> + int(1) + [0]=> + array(10) { + ["objectclass"]=> + array(4) { + ["count"]=> + int(3) + [0]=> + string(3) "top" + [1]=> + string(8) "dcObject" + [2]=> + string(12) "organization" + } + [0]=> + string(11) "objectclass" + ["dc"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [1]=> + string(2) "dc" + ["o"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [2]=> + string(1) "o" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(18) "Domain description" + } + [3]=> + string(11) "description" + ["count"]=> + int(4) + ["dn"]=> + string(19) "dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_modify_error.phpt b/ext/ldap/tests/ldap_modify_error.phpt new file mode 100644 index 000000000..78a721218 --- /dev/null +++ b/ext/ldap/tests/ldap_modify_error.phpt @@ -0,0 +1,83 @@ +--TEST-- +ldap_modify() - Modify operations that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + array( + "top", + "dcObject", + "organization"), + "dc" => "my-domain", + "o" => "my-domain", +); + +ldap_add($link, "dc=my-domain,dc=com", $entry); + +$entry2 = $entry; +$entry2["dc"] = "Wrong Domain"; + +var_dump(ldap_modify($link, "dc=my-domain,dc=com", $entry2)); + +$entry2 = $entry; +$entry2["weirdAttribute"] = "weirdVal"; + +var_dump(ldap_modify($link, "dc=my-domain,dc=com", $entry2)); +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_modify() expects exactly 3 parameters, 0 given in %s on line %d +NULL + +Warning: ldap_modify() expects exactly 3 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_modify() expects exactly 3 parameters, 2 given in %s on line %d +NULL + +Warning: ldap_modify() expects exactly 3 parameters, 4 given in %s on line %d +NULL + +Warning: ldap_modify(): Modify: No such object in %s on line %d +bool(false) + +Warning: ldap_modify(): Modify: Invalid DN syntax in %s on line %d +bool(false) + +Warning: ldap_modify(): Modify: Naming violation in %s on line %d +bool(false) + +Warning: ldap_modify(): Modify: Undefined attribute type in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_next_attribute_basic.phpt b/ext/ldap/tests/ldap_next_attribute_basic.phpt new file mode 100644 index 000000000..0fab78a70 --- /dev/null +++ b/ext/ldap/tests/ldap_next_attribute_basic.phpt @@ -0,0 +1,36 @@ +--TEST-- +ldap_next_attribute() - Basic ldap_next_attribute test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +string(%d) "%s" +string(%d) "%s" +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_next_attribute_error.phpt b/ext/ldap/tests/ldap_next_attribute_error.phpt new file mode 100644 index 000000000..c58a5602a --- /dev/null +++ b/ext/ldap/tests/ldap_next_attribute_error.phpt @@ -0,0 +1,40 @@ +--TEST-- +ldap_next_attribute() - Testing ldap_next_attribute() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_next_attribute() expects %s 2 parameters, 1 given in %s on line %d + +Warning: ldap_next_attribute(): supplied resource is not a valid ldap result entry resource in %s on line %d + +Warning: ldap_next_attribute(): called before calling ldap_first_attribute() or no attributes found in result entry in %s on line %d +NULL +bool(false) +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_next_entry_basic.phpt b/ext/ldap/tests/ldap_next_entry_basic.phpt new file mode 100644 index 000000000..3209df6a0 --- /dev/null +++ b/ext/ldap/tests/ldap_next_entry_basic.phpt @@ -0,0 +1,40 @@ +--TEST-- +ldap_next_entry() - Basic ldap_first_entry test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +resource(%d) of type (ldap result entry) +array(2) { + [0]=> + string(7) "testSN%d" + ["count"]=> + int(1) +} +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_next_entry_error.phpt b/ext/ldap/tests/ldap_next_entry_error.phpt new file mode 100644 index 000000000..59e9cdcab --- /dev/null +++ b/ext/ldap/tests/ldap_next_entry_error.phpt @@ -0,0 +1,27 @@ +--TEST-- +ldap_next_entry() - Testing ldap_next_entry() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_next_entry() expects exactly 2 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_next_entry() expects exactly 2 parameters, 3 given in %s on line %d +NULL + +Warning: ldap_next_entry(): supplied resource is not a valid ldap result entry resource in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_next_reference_basic.phpt b/ext/ldap/tests/ldap_next_reference_basic.phpt new file mode 100644 index 000000000..d0fa31d9c --- /dev/null +++ b/ext/ldap/tests/ldap_next_reference_basic.phpt @@ -0,0 +1,49 @@ +--TEST-- +ldap_next_reference() - Basic ldap_next_reference test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + array("extensibleObject", "referral"), + "cn" => "userref", + "ref" => "cn=userA,dc=my-domain,dc=com", +)); +ldap_add($link, "cn=userref2,dc=my-domain,dc=com", array( + "objectClass" => array("extensibleObject", "referral"), + "cn" => "userref2", + "ref" => "cn=userB,dc=my-domain,dc=com", +)); +ldap_set_option($link, LDAP_OPT_DEREF, LDAP_DEREF_NEVER); +$result = ldap_search($link, "dc=my-domain,dc=com", "(cn=*)"); +$ref = ldap_first_reference($link, $result); +var_dump($ref2 = ldap_next_reference($link, $ref)); +ldap_parse_reference($link, $ref2, $refs); +var_dump($refs); +?> +===DONE=== +--CLEAN-- + "2.16.840.1.113730.3.4.2"))); +ldap_delete($link, "cn=userref,dc=my-domain,dc=com"); +ldap_delete($link, "cn=userref2,dc=my-domain,dc=com"); +remove_dummy_data($link); +?> +--EXPECTF-- +resource(%d) of type (ldap result entry) +array(1) { + [0]=> + string(28) "cn=userB,dc=my-domain,dc=com" +} +===DONE=== diff --git a/ext/ldap/tests/ldap_next_reference_error.phpt b/ext/ldap/tests/ldap_next_reference_error.phpt new file mode 100644 index 000000000..0e47c5ef5 --- /dev/null +++ b/ext/ldap/tests/ldap_next_reference_error.phpt @@ -0,0 +1,27 @@ +--TEST-- +ldap_next_reference() - Testing ldap_next_reference() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_next_reference() expects exactly 2 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_next_reference() expects exactly 2 parameters, 3 given in %s on line %d +NULL + +Warning: ldap_next_reference(): supplied resource is not a valid ldap result entry resource in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_parse_reference_basic.phpt b/ext/ldap/tests/ldap_parse_reference_basic.phpt new file mode 100644 index 000000000..2bacd428a --- /dev/null +++ b/ext/ldap/tests/ldap_parse_reference_basic.phpt @@ -0,0 +1,45 @@ +--TEST-- +ldap_parse_reference() - Basic ldap_parse_reference test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + array("extensibleObject", "referral"), + "cn" => "userref", + "ref" => "cn=userA,dc=my-domain,dc=com", +)); +ldap_set_option($link, LDAP_OPT_DEREF, LDAP_DEREF_NEVER); +$result = ldap_search($link, "dc=my-domain,dc=com", "(cn=*)"); +$ref = ldap_first_reference($link, $result); +$refs = null; +var_dump( + ldap_parse_reference($link, $ref, $refs), + $refs +); +?> +===DONE=== +--CLEAN-- + "2.16.840.1.113730.3.4.2"))); +ldap_delete($link, "cn=userref,dc=my-domain,dc=com"); +remove_dummy_data($link); +?> +--EXPECTF-- +bool(true) +array(1) { + [0]=> + string(28) "cn=userA,dc=my-domain,dc=com" +} +===DONE=== diff --git a/ext/ldap/tests/ldap_parse_reference_error.phpt b/ext/ldap/tests/ldap_parse_reference_error.phpt new file mode 100644 index 000000000..9d180e717 --- /dev/null +++ b/ext/ldap/tests/ldap_parse_reference_error.phpt @@ -0,0 +1,31 @@ +--TEST-- +ldap_parse_reference() - ldap_parse_reference() operations that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_parse_reference() expects exactly 3 parameters, 2 given in %s on line %d + +Warning: ldap_parse_reference(): supplied resource is not a valid ldap result entry resource in %s on line %d + +Warning: ldap_parse_reference() expects exactly 3 parameters, 4 given in %s on line %d +NULL +bool(false) +NULL +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_parse_result_basic.phpt b/ext/ldap/tests/ldap_parse_result_basic.phpt new file mode 100644 index 000000000..1646d59c9 --- /dev/null +++ b/ext/ldap/tests/ldap_parse_result_basic.phpt @@ -0,0 +1,47 @@ +--TEST-- +ldap_parse_result() - Basic ldap_parse_result test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + array("extensibleObject", "referral"), + "cn" => "userref", + "ref" => "cn=userA,dc=my-domain,dc=com", +)); +$result = ldap_search($link, "cn=userref,dc=my-domain,dc=com", "(cn=user*)"); +$errcode = $dn = $errmsg = $refs = null; +var_dump( + ldap_parse_result($link, $result, $errcode, $dn, $errmsg, $refs), + $errcode, $dn, $errmsg, $refs +); +?> +===DONE=== +--CLEAN-- + "2.16.840.1.113730.3.4.2"))); +ldap_delete($link, "cn=userref,dc=my-domain,dc=com"); +remove_dummy_data($link); +?> +--EXPECT-- +bool(true) +int(10) +string(30) "cn=userref,dc=my-domain,dc=com" +string(0) "" +array(1) { + [0]=> + string(28) "cn=userA,dc=my-domain,dc=com" +} +===DONE=== diff --git a/ext/ldap/tests/ldap_parse_result_error.phpt b/ext/ldap/tests/ldap_parse_result_error.phpt new file mode 100644 index 000000000..33f86f40b --- /dev/null +++ b/ext/ldap/tests/ldap_parse_result_error.phpt @@ -0,0 +1,17 @@ +--TEST-- +ldap_parse_result() - Testing ldap_parse_result() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_parse_result() expects at least 3 parameters, 2 given in %s on line %d +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_read_basic.phpt b/ext/ldap/tests/ldap_read_basic.phpt new file mode 100644 index 000000000..04d03d986 --- /dev/null +++ b/ext/ldap/tests/ldap_read_basic.phpt @@ -0,0 +1,75 @@ +--TEST-- +ldap_read() test +--CREDITS-- +Davide Mendolia +Patrick Allaert +Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +resource(%d) of type (ldap result) +array(2) { + ["count"]=> + int(1) + [0]=> + array(8) { + ["objectclass"]=> + array(4) { + ["count"]=> + int(3) + [0]=> + string(3) "top" + [1]=> + string(8) "dcObject" + [2]=> + string(12) "organization" + } + [0]=> + string(11) "objectclass" + ["dc"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [1]=> + string(2) "dc" + ["o"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [2]=> + string(1) "o" + ["count"]=> + int(3) + ["dn"]=> + string(19) "dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_read_error.phpt b/ext/ldap/tests/ldap_read_error.phpt new file mode 100644 index 000000000..649658aa7 --- /dev/null +++ b/ext/ldap/tests/ldap_read_error.phpt @@ -0,0 +1,35 @@ +--TEST-- +ldap_read() - operation that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_read() expects at least 3 parameters, 0 given in %s on line %d +NULL + +Warning: ldap_read() expects at least 3 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_read() expects at least 3 parameters, 2 given in %s on line %d +NULL + +Warning: ldap_read() expects at most 8 parameters, 9 given in %s on line %d +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_rename_basic.phpt b/ext/ldap/tests/ldap_rename_basic.phpt new file mode 100644 index 000000000..135769d1d --- /dev/null +++ b/ext/ldap/tests/ldap_rename_basic.phpt @@ -0,0 +1,62 @@ +--TEST-- +ldap_rename() - Basic ldap_rename test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +array(2) { + ["count"]=> + int(1) + [0]=> + array(6) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN1" + } + [0]=> + string(2) "sn" + ["cn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(5) "userZ" + } + [1]=> + string(2) "cn" + ["count"]=> + int(2) + ["dn"]=> + string(28) "cn=userZ,dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_rename_error.phpt b/ext/ldap/tests/ldap_rename_error.phpt new file mode 100644 index 000000000..57ca3571b --- /dev/null +++ b/ext/ldap/tests/ldap_rename_error.phpt @@ -0,0 +1,21 @@ +--TEST-- +ldap_rename() - Testing ldap_rename() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_rename() expects exactly 5 parameters, 1 given in %s on line %d +NULL +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_sasl_bind_basic.phpt b/ext/ldap/tests/ldap_sasl_bind_basic.phpt new file mode 100644 index 000000000..6ed14a5b1 --- /dev/null +++ b/ext/ldap/tests/ldap_sasl_bind_basic.phpt @@ -0,0 +1,20 @@ +--TEST-- +ldap_sasl_bind() - Basic anonymous binding +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--EXPECT-- +bool(true) +===DONE=== diff --git a/ext/ldap/tests/ldap_sasl_bind_error.phpt b/ext/ldap/tests/ldap_sasl_bind_error.phpt new file mode 100644 index 000000000..180066bb2 --- /dev/null +++ b/ext/ldap/tests/ldap_sasl_bind_error.phpt @@ -0,0 +1,53 @@ +--TEST-- +ldap_sasl_bind() - Binding that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_sasl_bind() expects at least 1 parameter, 0 given in %s on line %d +bool(false) + +Warning: ldap_sasl_bind(): Unable to bind to server: Invalid DN syntax in %s on line %d +bool(false) + +Warning: ldap_sasl_bind(): Unable to bind to server: Invalid credentials in %s on line %d +bool(false) + +Warning: ldap_sasl_bind(): Unable to bind to server: Invalid credentials in %s on line %d +bool(false) + +Warning: ldap_sasl_bind(): Unable to bind to server: Insufficient access in %s on line %d +bool(false) + +Warning: ldap_sasl_bind(): Unable to bind to server: Invalid DN syntax in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_search_basic.phpt b/ext/ldap/tests/ldap_search_basic.phpt new file mode 100644 index 000000000..e6cebf2c5 --- /dev/null +++ b/ext/ldap/tests/ldap_search_basic.phpt @@ -0,0 +1,194 @@ +--TEST-- +ldap_search() test +--CREDITS-- +Davide Mendolia +Patrick Allaert +Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +resource(%d) of type (ldap result) +array(4) { + ["count"]=> + int(3) + [0]=> + array(14) { + ["objectclass"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "person" + } + [0]=> + string(11) "objectclass" + ["cn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(5) "userA" + } + [1]=> + string(2) "cn" + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN1" + } + [2]=> + string(2) "sn" + ["userpassword"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(4) "oops" + } + [3]=> + string(12) "userpassword" + ["telephonenumber"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(14) "xx-xx-xx-xx-xx" + } + [4]=> + string(15) "telephonenumber" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "user A" + } + [5]=> + string(11) "description" + ["count"]=> + int(6) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } + [1]=> + array(12) { + ["objectclass"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "person" + } + [0]=> + string(11) "objectclass" + ["cn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(5) "userB" + } + [1]=> + string(2) "cn" + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN2" + } + [2]=> + string(2) "sn" + ["userpassword"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(15) "oopsIDitItAgain" + } + [3]=> + string(12) "userpassword" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "user B" + } + [4]=> + string(11) "description" + ["count"]=> + int(5) + ["dn"]=> + string(28) "cn=userB,dc=my-domain,dc=com" + } + [2]=> + array(10) { + ["objectclass"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "person" + } + [0]=> + string(11) "objectclass" + ["cn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(5) "userC" + } + [1]=> + string(2) "cn" + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN3" + } + [2]=> + string(2) "sn" + ["userpassword"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(17) "0r1g1na1 passw0rd" + } + [3]=> + string(12) "userpassword" + ["count"]=> + int(4) + ["dn"]=> + string(37) "cn=userC,cn=userB,dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_search_error.phpt b/ext/ldap/tests/ldap_search_error.phpt new file mode 100644 index 000000000..c03bd2ca8 --- /dev/null +++ b/ext/ldap/tests/ldap_search_error.phpt @@ -0,0 +1,62 @@ +--TEST-- +ldap_search() - operation that should fail +--CREDITS-- +Davide Mendolia +Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + 'top')); +var_dump($result); + +$result = ldap_search(array(), $dn, $filter, array('top')); +var_dump($result); + +$result = ldap_search(array($link, $link), array($dn), $filter, array('top')); +var_dump($result); + +$result = ldap_search(array($link, $link), $dn, array($filter), array('top')); +var_dump($result); +?> +===DONE=== +--EXPECTF-- +Warning: ldap_search() expects at least 3 parameters, 0 given in %s on line %d +NULL + +Warning: ldap_search(): Search: No such object in %s on line %d +bool(false) + +Warning: ldap_search() expects parameter 4 to be array, null given in %s on line %d +NULL + +Warning: ldap_search(): Array initialization wrong in %s on line %d +bool(false) + +Warning: ldap_search(): No links in link array in %s on line %d +bool(false) + +Warning: ldap_search(): Base must either be a string, or an array with the same number of elements as the links array in %s on line %d +bool(false) + +Warning: ldap_search(): Filter must either be a string, or an array with the same number of elements as the links array in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_search_variation1.phpt b/ext/ldap/tests/ldap_search_variation1.phpt new file mode 100644 index 000000000..d56f5bdc9 --- /dev/null +++ b/ext/ldap/tests/ldap_search_variation1.phpt @@ -0,0 +1,56 @@ +--TEST-- +ldap_search() test +--CREDITS-- +Davide Mendolia +Patrick Allaert +Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +resource(%d) of type (ldap result) +array(2) { + ["count"]=> + int(1) + [0]=> + array(4) { + ["dc"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(9) "my-domain" + } + [0]=> + string(2) "dc" + ["count"]=> + int(1) + ["dn"]=> + string(19) "dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_search_variation2.phpt b/ext/ldap/tests/ldap_search_variation2.phpt new file mode 100644 index 000000000..791c5e9bc --- /dev/null +++ b/ext/ldap/tests/ldap_search_variation2.phpt @@ -0,0 +1,80 @@ +--TEST-- +ldap_search() test +--CREDITS-- +Davide Mendolia +Patrick Allaert +Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +resource(%d) of type (ldap result) +array(4) { + ["count"]=> + int(3) + [0]=> + array(4) { + ["sn"]=> + array(1) { + ["count"]=> + int(0) + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } + [1]=> + array(4) { + ["sn"]=> + array(1) { + ["count"]=> + int(0) + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(28) "cn=userB,dc=my-domain,dc=com" + } + [2]=> + array(4) { + ["sn"]=> + array(1) { + ["count"]=> + int(0) + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(37) "cn=userC,cn=userB,dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_search_variation3.phpt b/ext/ldap/tests/ldap_search_variation3.phpt new file mode 100644 index 000000000..ab7b22282 --- /dev/null +++ b/ext/ldap/tests/ldap_search_variation3.phpt @@ -0,0 +1,108 @@ +--TEST-- +ldap_search() test +--CREDITS-- +Davide Mendolia +Patrick Allaert +Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +resource(%d) of type (ldap result) +array(4) { + ["count"]=> + int(3) + [0]=> + array(4) { + ["sn"]=> + array(1) { + ["count"]=> + int(0) + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } + [1]=> + array(4) { + ["sn"]=> + array(1) { + ["count"]=> + int(0) + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(28) "cn=userB,dc=my-domain,dc=com" + } + [2]=> + array(4) { + ["sn"]=> + array(1) { + ["count"]=> + int(0) + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(37) "cn=userC,cn=userB,dc=my-domain,dc=com" + } +} + +Warning: ldap_search(): Partial search results returned: Sizelimit exceeded in %s on line %d +resource(%d) of type (ldap result) +array(2) { + ["count"]=> + int(1) + [0]=> + array(4) { + ["sn"]=> + array(1) { + ["count"]=> + int(0) + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_search_variation4.phpt b/ext/ldap/tests/ldap_search_variation4.phpt new file mode 100644 index 000000000..787468e0f --- /dev/null +++ b/ext/ldap/tests/ldap_search_variation4.phpt @@ -0,0 +1,55 @@ +--TEST-- +ldap_search() test +--CREDITS-- +Davide Mendolia +Patrick Allaert +Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_search(): Partial search results returned: Sizelimit exceeded in %s on line %d +resource(%d) of type (ldap result) +array(2) { + ["count"]=> + int(1) + [0]=> + array(4) { + ["sn"]=> + array(1) { + ["count"]=> + int(0) + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_search_variation5.phpt b/ext/ldap/tests/ldap_search_variation5.phpt new file mode 100644 index 000000000..d50854c65 --- /dev/null +++ b/ext/ldap/tests/ldap_search_variation5.phpt @@ -0,0 +1,105 @@ +--TEST-- +ldap_search() test +--CREDITS-- +Davide Mendolia +Patrick Allaert +Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +Warning: ldap_search(): Partial search results returned: Sizelimit exceeded in %s on line %d +resource(%d) of type (ldap result) +array(2) { + ["count"]=> + int(1) + [0]=> + array(4) { + ["sn"]=> + array(1) { + ["count"]=> + int(0) + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } +} + +Warning: ldap_search(): Partial search results returned: Sizelimit exceeded in %s on line %d +resource(%d) of type (ldap result) +array(2) { + ["count"]=> + int(1) + [0]=> + array(4) { + ["sn"]=> + array(1) { + ["count"]=> + int(0) + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } +} + +Warning: ldap_search(): Partial search results returned: Sizelimit exceeded in %s on line %d +resource(%d) of type (ldap result) +array(2) { + ["count"]=> + int(1) + [0]=> + array(4) { + ["sn"]=> + array(1) { + ["count"]=> + int(0) + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_search_variation6.phpt b/ext/ldap/tests/ldap_search_variation6.phpt new file mode 100644 index 000000000..a29e4524d --- /dev/null +++ b/ext/ldap/tests/ldap_search_variation6.phpt @@ -0,0 +1,230 @@ +--TEST-- +ldap_search() test +--CREDITS-- +Davide Mendolia +Patrick Allaert +Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +array(2) { + [0]=> + resource(%d) of type (ldap result) + [1]=> + resource(%d) of type (ldap result) +} +array(4) { + ["count"]=> + int(3) + [0]=> + array(14) { + ["objectclass"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "person" + } + [0]=> + string(11) "objectclass" + ["cn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(5) "userA" + } + [1]=> + string(2) "cn" + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN1" + } + [2]=> + string(2) "sn" + ["userpassword"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(4) "oops" + } + [3]=> + string(12) "userpassword" + ["telephonenumber"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(14) "xx-xx-xx-xx-xx" + } + [4]=> + string(15) "telephonenumber" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "user A" + } + [5]=> + string(11) "description" + ["count"]=> + int(6) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } + [1]=> + array(12) { + ["objectclass"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "person" + } + [0]=> + string(11) "objectclass" + ["cn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(5) "userB" + } + [1]=> + string(2) "cn" + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN2" + } + [2]=> + string(2) "sn" + ["userpassword"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(15) "oopsIDitItAgain" + } + [3]=> + string(12) "userpassword" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "user B" + } + [4]=> + string(11) "description" + ["count"]=> + int(5) + ["dn"]=> + string(28) "cn=userB,dc=my-domain,dc=com" + } + [2]=> + array(10) { + ["objectclass"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "person" + } + [0]=> + string(11) "objectclass" + ["cn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(5) "userC" + } + [1]=> + string(2) "cn" + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN3" + } + [2]=> + string(2) "sn" + ["userpassword"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(17) "0r1g1na1 passw0rd" + } + [3]=> + string(12) "userpassword" + ["count"]=> + int(4) + ["dn"]=> + string(37) "cn=userC,cn=userB,dc=my-domain,dc=com" + } +} +bool(true) +array(2) { + [0]=> + resource(%d) of type (ldap result) + [1]=> + resource(%d) of type (ldap result) +} +NULL +NULL +array(2) { + [0]=> + resource(%d) of type (ldap result) + [1]=> + resource(%d) of type (ldap result) +} +NULL +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_set_option_basic.phpt b/ext/ldap/tests/ldap_set_option_basic.phpt new file mode 100644 index 000000000..de25e59c2 --- /dev/null +++ b/ext/ldap/tests/ldap_set_option_basic.phpt @@ -0,0 +1,23 @@ +--TEST-- +ldap_set_option() - Basic ldap_set_option() operation +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +bool(true) +int(3) +===DONE=== diff --git a/ext/ldap/tests/ldap_set_option_error.phpt b/ext/ldap/tests/ldap_set_option_error.phpt new file mode 100644 index 000000000..f319c7e6d --- /dev/null +++ b/ext/ldap/tests/ldap_set_option_error.phpt @@ -0,0 +1,66 @@ +--TEST-- +ldap_set_option() - ldap_set_option() operation that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + "1.2.752.58.10.1", "iscritical" => true), + array("xid" => "1.2.752.58.1.10", "value" => "magic"), + ), + array( + array("oid" => "1.2.752.58.10.1", "iscritical" => true), + array("oid" => "1.2.752.58.1.10", "value" => "magic"), + "weird" + ), + array( + ), +); + +// Too few parameters +var_dump(ldap_set_option()); +var_dump(ldap_set_option($link)); +var_dump(ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION)); + +// Too many parameters +var_dump(ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, 3, "Additional data")); + +var_dump(ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, 10)); + +foreach ($controls as $control) + var_dump(ldap_set_option($link, LDAP_OPT_SERVER_CONTROLS, $control)); + +var_dump(ldap_set_option($link, 999999, 999999)); +?> +===DONE=== +--EXPECTF-- +Warning: ldap_set_option() expects exactly 3 parameters, 0 given in %s on line %d +NULL + +Warning: ldap_set_option() expects exactly 3 parameters, 1 given in %s on line %d +NULL + +Warning: ldap_set_option() expects exactly 3 parameters, 2 given in %s on line %d +NULL + +Warning: ldap_set_option() expects exactly 3 parameters, 4 given in %s on line %d +NULL +bool(false) + +Warning: ldap_set_option(): Control must have an oid key in %s on line %d +bool(false) + +Warning: ldap_set_option(): The array value must contain only arrays, where each array is a control in %s on line %d +bool(false) + +Warning: ldap_set_option(): Expected non-empty array value for this option in %s on line %d +bool(false) +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_set_option_variation.phpt b/ext/ldap/tests/ldap_set_option_variation.phpt new file mode 100644 index 000000000..6e082beb0 --- /dev/null +++ b/ext/ldap/tests/ldap_set_option_variation.phpt @@ -0,0 +1,84 @@ +--TEST-- +ldap_set_option() - More ldap_set_option() operations +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + "1.2.752.58.10.1", "iscritical" => true), + array("oid" => "1.2.752.58.1.10", "value" => "magic"), +); + +var_dump(ldap_set_option($link, LDAP_OPT_DEREF, LDAP_DEREF_ALWAYS)); +ldap_get_option($link, LDAP_OPT_DEREF, $option); +var_dump( + $option === LDAP_DEREF_ALWAYS, + ldap_set_option($link, LDAP_OPT_SIZELIMIT, 123) +); +ldap_get_option($link, LDAP_OPT_SIZELIMIT, $option); +var_dump( + $option, + ldap_set_option($link, LDAP_OPT_TIMELIMIT, 33) +); +ldap_get_option($link, LDAP_OPT_TIMELIMIT, $option); +var_dump( + $option, + ldap_set_option($link, LDAP_OPT_NETWORK_TIMEOUT, 44) +); +ldap_get_option($link, LDAP_OPT_NETWORK_TIMEOUT, $option); +var_dump( + $option, + ldap_set_option($link, LDAP_OPT_REFERRALS, true) +); +ldap_get_option($link, LDAP_OPT_REFERRALS, $option); +var_dump( + (bool) $option, + ldap_set_option($link, LDAP_OPT_RESTART, false) +); +ldap_get_option($link, LDAP_OPT_RESTART, $option); +var_dump( + (bool) $option, + ldap_set_option($link, LDAP_OPT_SERVER_CONTROLS, $controls) +); +ldap_get_option($link, LDAP_OPT_SERVER_CONTROLS, $option); +var_dump( + $option, + ldap_set_option($link, LDAP_OPT_CLIENT_CONTROLS, $controls) +); +ldap_get_option($link, LDAP_OPT_CLIENT_CONTROLS, $option); +var_dump( + $option, + ldap_set_option($link, LDAP_OPT_MATCHED_DN, "dc=test,dc=com") +); +ldap_get_option($link, LDAP_OPT_MATCHED_DN, $option); +var_dump($option); +?> +===DONE=== +--EXPECT-- +bool(true) +bool(true) +bool(true) +int(123) +bool(true) +int(33) +bool(true) +int(44) +bool(true) +bool(true) +bool(true) +bool(false) +bool(true) +int(0) +bool(true) +int(0) +bool(true) +string(14) "dc=test,dc=com" +===DONE=== diff --git a/ext/ldap/tests/ldap_set_rebind_proc_basic.phpt b/ext/ldap/tests/ldap_set_rebind_proc_basic.phpt new file mode 100644 index 000000000..428b8d8f0 --- /dev/null +++ b/ext/ldap/tests/ldap_set_rebind_proc_basic.phpt @@ -0,0 +1,34 @@ +--TEST-- +ldap_set_rebind_proc() - Basic ldap_set_rebind_proc test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--EXPECT-- +bool(true) +bool(true) +===DONE=== diff --git a/ext/ldap/tests/ldap_set_rebind_proc_error.phpt b/ext/ldap/tests/ldap_set_rebind_proc_error.phpt new file mode 100644 index 000000000..3b4cd69cf --- /dev/null +++ b/ext/ldap/tests/ldap_set_rebind_proc_error.phpt @@ -0,0 +1,40 @@ +--TEST-- +ldap_set_rebind_proc() - Testing ldap_set_rebind_proc() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_set_rebind_proc() expects exactly 2 parameters, 1 given in %s on line %d +bool(false) + +Warning: ldap_set_rebind_proc() expects exactly 2 parameters, 3 given in %s on line %d +bool(false) + +Warning: ldap_set_rebind_proc(): Two arguments expected for 'rebind_proc_inexistant' to be a valid callback in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_sort_basic.phpt b/ext/ldap/tests/ldap_sort_basic.phpt new file mode 100644 index 000000000..f6ee5d198 --- /dev/null +++ b/ext/ldap/tests/ldap_sort_basic.phpt @@ -0,0 +1,200 @@ +--TEST-- +ldap_sort() - Basic ldap_sort test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + "person", + "cn" => "userC", + "sn" => "zzz", + "userPassword" => "oops", + "description" => "a user", +)); +ldap_add($link, "cn=userD,dc=my-domain,dc=com", array( + "objectclass" => "person", + "cn" => "userD", + "sn" => "aaa", + "userPassword" => "oops", + "description" => "another user", +)); +ldap_add($link, "cn=userE,dc=my-domain,dc=com", array( + "objectclass" => "person", + "cn" => "userE", + "sn" => "a", + "userPassword" => "oops", + "description" => "yet another user", +)); +$result = ldap_search($link, "dc=my-domain,dc=com", "(objectclass=person)", array("sn", "description")); +var_dump( + ldap_sort($link, $result, "sn"), + ldap_get_entries($link, $result) +); +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +array(7) { + ["count"]=> + int(6) + [0]=> + array(6) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(1) "a" + } + [0]=> + string(2) "sn" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(16) "yet another user" + } + [1]=> + string(11) "description" + ["count"]=> + int(2) + ["dn"]=> + string(28) "cn=userE,dc=my-domain,dc=com" + } + [1]=> + array(6) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(3) "aaa" + } + [0]=> + string(2) "sn" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(12) "another user" + } + [1]=> + string(11) "description" + ["count"]=> + int(2) + ["dn"]=> + string(28) "cn=userD,dc=my-domain,dc=com" + } + [2]=> + array(6) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN1" + } + [0]=> + string(2) "sn" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "user A" + } + [1]=> + string(11) "description" + ["count"]=> + int(2) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } + [3]=> + array(6) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN2" + } + [0]=> + string(2) "sn" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "user B" + } + [1]=> + string(11) "description" + ["count"]=> + int(2) + ["dn"]=> + string(28) "cn=userB,dc=my-domain,dc=com" + } + [4]=> + array(4) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN3" + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(37) "cn=userC,cn=userB,dc=my-domain,dc=com" + } + [5]=> + array(6) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(3) "zzz" + } + [0]=> + string(2) "sn" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "a user" + } + [1]=> + string(11) "description" + ["count"]=> + int(2) + ["dn"]=> + string(28) "cn=userC,dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_sort_error.phpt b/ext/ldap/tests/ldap_sort_error.phpt new file mode 100644 index 000000000..6eb409073 --- /dev/null +++ b/ext/ldap/tests/ldap_sort_error.phpt @@ -0,0 +1,35 @@ +--TEST-- +ldap_sort() - Testing ldap_sort() that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_sort() expects exactly 3 parameters, 1 given in %s on line %d +bool(false) + +Warning: ldap_sort() expects exactly 3 parameters, 2 given in %s on line %d +bool(false) + +Warning: ldap_sort() expects exactly 3 parameters, 4 given in %s on line %d +bool(false) + +Warning: ldap_sort() expects parameter 3 to be %binary_string_optional%, resource given in %s on line %d +bool(false) + +Warning: ldap_sort(): Supplied resource is not a valid ldap result resource in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_sort_variation.phpt b/ext/ldap/tests/ldap_sort_variation.phpt new file mode 100644 index 000000000..e1affe82f --- /dev/null +++ b/ext/ldap/tests/ldap_sort_variation.phpt @@ -0,0 +1,200 @@ +--TEST-- +ldap_sort() - Basic ldap_sort test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + "person", + "cn" => "userC", + "sn" => "zzz", + "userPassword" => "oops", + "description" => "a user", +)); +ldap_add($link, "cn=userD,dc=my-domain,dc=com", array( + "objectclass" => "person", + "cn" => "userD", + "sn" => "aaa", + "userPassword" => "oops", + "description" => "another user", +)); +ldap_add($link, "cn=userE,dc=my-domain,dc=com", array( + "objectclass" => "person", + "cn" => "userE", + "sn" => "a", + "userPassword" => "oops", + "description" => "yet another user", +)); +$result = ldap_search($link, "dc=my-domain,dc=com", "(objectclass=person)", array("sn", "description")); +var_dump( + ldap_sort($link, $result, "description"), + ldap_get_entries($link, $result) +); +?> +===DONE=== +--CLEAN-- + +--EXPECT-- +bool(true) +array(7) { + ["count"]=> + int(6) + [0]=> + array(4) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN3" + } + [0]=> + string(2) "sn" + ["count"]=> + int(1) + ["dn"]=> + string(37) "cn=userC,cn=userB,dc=my-domain,dc=com" + } + [1]=> + array(6) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(3) "zzz" + } + [0]=> + string(2) "sn" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "a user" + } + [1]=> + string(11) "description" + ["count"]=> + int(2) + ["dn"]=> + string(28) "cn=userC,dc=my-domain,dc=com" + } + [2]=> + array(6) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(3) "aaa" + } + [0]=> + string(2) "sn" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(12) "another user" + } + [1]=> + string(11) "description" + ["count"]=> + int(2) + ["dn"]=> + string(28) "cn=userD,dc=my-domain,dc=com" + } + [3]=> + array(6) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN1" + } + [0]=> + string(2) "sn" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "user A" + } + [1]=> + string(11) "description" + ["count"]=> + int(2) + ["dn"]=> + string(28) "cn=userA,dc=my-domain,dc=com" + } + [4]=> + array(6) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(7) "testSN2" + } + [0]=> + string(2) "sn" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(6) "user B" + } + [1]=> + string(11) "description" + ["count"]=> + int(2) + ["dn"]=> + string(28) "cn=userB,dc=my-domain,dc=com" + } + [5]=> + array(6) { + ["sn"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(1) "a" + } + [0]=> + string(2) "sn" + ["description"]=> + array(2) { + ["count"]=> + int(1) + [0]=> + string(16) "yet another user" + } + [1]=> + string(11) "description" + ["count"]=> + int(2) + ["dn"]=> + string(28) "cn=userE,dc=my-domain,dc=com" + } +} +===DONE=== diff --git a/ext/ldap/tests/ldap_start_tls_basic.phpt b/ext/ldap/tests/ldap_start_tls_basic.phpt new file mode 100644 index 000000000..3ae50bef5 --- /dev/null +++ b/ext/ldap/tests/ldap_start_tls_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +ldap_start_tls() - Basic ldap_start_tls test +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +bool(true) +===DONE=== diff --git a/ext/ldap/tests/ldap_start_tls_error.phpt b/ext/ldap/tests/ldap_start_tls_error.phpt new file mode 100644 index 000000000..686f5331a --- /dev/null +++ b/ext/ldap/tests/ldap_start_tls_error.phpt @@ -0,0 +1,27 @@ +--TEST-- +ldap_start_tls() - Binding that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_start_tls() expects exactly 1 parameter, 0 given in %s on line %d +NULL + +Warning: ldap_start_tls() expects exactly 1 parameter, 2 given in %s on line %d +NULL +===DONE=== diff --git a/ext/ldap/tests/ldap_unbind_basic.phpt b/ext/ldap/tests/ldap_unbind_basic.phpt new file mode 100644 index 000000000..addfac559 --- /dev/null +++ b/ext/ldap/tests/ldap_unbind_basic.phpt @@ -0,0 +1,20 @@ +--TEST-- +ldap_unbind() - Basic ldap_unbind() operation +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--EXPECT-- +bool(true) +===DONE=== diff --git a/ext/ldap/tests/ldap_unbind_error.phpt b/ext/ldap/tests/ldap_unbind_error.phpt new file mode 100644 index 000000000..19b4ad594 --- /dev/null +++ b/ext/ldap/tests/ldap_unbind_error.phpt @@ -0,0 +1,42 @@ +--TEST-- +ldap_unbind() - ldap_unbind() operations that should fail +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--EXPECTF-- +Warning: ldap_unbind() expects exactly 1 parameter, 0 given in %s on line %d +bool(false) + +Warning: ldap_unbind() expects exactly 1 parameter, 2 given in %s on line %d +bool(false) + +Warning: ldap_unbind() expects parameter 1 to be resource, %unicode_string_optional% given in %s on line %d +bool(false) +bool(true) + +Warning: ldap_unbind(): %d is not a valid ldap link resource in %s on line %d +bool(false) +===DONE=== diff --git a/ext/ldap/tests/ldap_unbind_variation.phpt b/ext/ldap/tests/ldap_unbind_variation.phpt new file mode 100644 index 000000000..377018c58 --- /dev/null +++ b/ext/ldap/tests/ldap_unbind_variation.phpt @@ -0,0 +1,34 @@ +--TEST-- +ldap_unbind() - Variation of ldap_unbind() function using ldap_set_rebind_proc() +--CREDITS-- +Patrick Allaert +# Belgian PHP Testfest 2009 +--SKIPIF-- + + +--FILE-- + +===DONE=== +--EXPECT-- +bool(true) +===DONE=== diff --git a/ext/libxml/config.w32 b/ext/libxml/config.w32 index 8fa9f29b6..221f96300 100644 --- a/ext/libxml/config.w32 +++ b/ext/libxml/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.8.6.5 2008/08/25 21:04:30 rrichards Exp $ +// $Id: config.w32 265497 2008-08-25 21:04:30Z rrichards $ // vim:ft=javascript ARG_WITH("libxml", "LibXML support", "yes"); diff --git a/ext/libxml/config0.m4 b/ext/libxml/config0.m4 index e5974983c..4cd4cfce4 100644 --- a/ext/libxml/config0.m4 +++ b/ext/libxml/config0.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config0.m4,v 1.3.4.1 2007/07/03 17:25:33 sniper Exp $ +dnl $Id: config0.m4 239118 2007-07-03 17:25:43Z sniper $ dnl PHP_ARG_ENABLE(libxml, whether to enable LIBXML support, diff --git a/ext/libxml/libxml.c b/ext/libxml/libxml.c index 407074b5c..c1c046712 100644 --- a/ext/libxml/libxml.c +++ b/ext/libxml/libxml.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: libxml.c,v 1.32.2.7.2.15.2.13 2009/06/23 13:44:24 bjori Exp $ */ +/* $Id: libxml.c 282654 2009-06-23 13:44:24Z bjori $ */ #define IS_EXT_MODULE diff --git a/ext/libxml/php_libxml.h b/ext/libxml/php_libxml.h index 7dffbd836..8a1082273 100644 --- a/ext/libxml/php_libxml.h +++ b/ext/libxml/php_libxml.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_libxml.h,v 1.15.2.2.2.6.2.4 2008/12/31 11:15:38 sebastian Exp $ */ +/* $Id: php_libxml.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_LIBXML_H #define PHP_LIBXML_H diff --git a/ext/mbstring/config.m4 b/ext/mbstring/config.m4 index 49c65bec0..ad0c16c41 100644 --- a/ext/mbstring/config.m4 +++ b/ext/mbstring/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.58.2.4.2.11.2.8 2009/04/20 15:39:48 jani Exp $ +dnl $Id: config.m4 279059 2009-04-20 15:39:48Z jani $ dnl AC_DEFUN([PHP_MBSTRING_ADD_SOURCES], [ diff --git a/ext/mbstring/config.w32 b/ext/mbstring/config.w32 index e208f4f62..ca1ef2315 100644 --- a/ext/mbstring/config.w32 +++ b/ext/mbstring/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.10.2.1.2.4.2.5 2009/06/12 16:15:51 kalle Exp $ +// $Id: config.w32 282040 2009-06-12 16:15:51Z kalle $ // vim:ft=javascript ARG_ENABLE("mbstring", "multibyte string functions", "no"); diff --git a/ext/mbstring/libmbfl/README b/ext/mbstring/libmbfl/README index 476a589aa..a4a2ef28b 100644 --- a/ext/mbstring/libmbfl/README +++ b/ext/mbstring/libmbfl/README @@ -5,4 +5,4 @@ See LICENSE and DISCLAIMER for licensing information. See the file INSTALL for building and installation instructions. -# $Id: README,v 1.4 2005/02/20 22:18:07 moriyoshi Exp $ +# $Id: README 180252 2005-02-20 22:18:09Z moriyoshi $ diff --git a/ext/mbstring/libmbfl/filters/mbfilter_htmlent.c b/ext/mbstring/libmbfl/filters/mbfilter_htmlent.c index 6c6654a1b..0163520f5 100644 --- a/ext/mbstring/libmbfl/filters/mbfilter_htmlent.c +++ b/ext/mbstring/libmbfl/filters/mbfilter_htmlent.c @@ -186,18 +186,58 @@ int mbfl_filt_conv_html_dec(int c, mbfl_convert_filter *filter) } } else { if (c == ';') { - buffer[filter->status] = 0; if (buffer[1]=='#') { - /* numeric entity */ - for (pos=2; posstatus; pos++) { - ent = ent*10 + (buffer[pos] - '0'); + if (filter->status > 2 && (buffer[2] == 'x' || buffer[2] == 'X')) { + if (filter->status > 3) { + /* numeric entity */ + for (pos=3; posstatus; pos++) { + int v = buffer[pos]; + if (v >= '0' && v <= '9') { + v = v - '0'; + } else if (v >= 'A' && v <= 'F') { + v = v - 'A' + 10; + } else if (v >= 'a' && v <= 'f') { + v = v - 'a' + 10; + } else { + ent = -1; + break; + } + ent = ent * 16 + v; + } + } else { + ent = -1; + } + } else { + /* numeric entity */ + if (filter->status > 2) { + for (pos=2; posstatus; pos++) { + int v = buffer[pos]; + if (v >= '0' && v <= '9') { + v = v - '0'; + } else { + ent = -1; + break; + } + ent = ent*10 + v; + } + } else { + ent = -1; + } + } + if (ent >= 0 && ent < 0x110000) { + CK((*filter->output_function)(ent, filter->data)); + } else { + for (pos = 0; pos < filter->status; pos++) { + CK((*filter->output_function)(buffer[pos], filter->data)); + } + CK((*filter->output_function)(c, filter->data)); } - CK((*filter->output_function)(ent, filter->data)); filter->status = 0; /*php_error_docref("ref.mbstring" TSRMLS_CC, E_NOTICE, "mbstring decoded '%s'=%d", buffer, ent);*/ } else { /* named entity */ - entity = (mbfl_html_entity_entry *)mbfl_html_entity_list; + buffer[filter->status] = 0; + entity = (mbfl_html_entity_entry *)mbfl_html_entity_list; while (entity->name) { if (!strcmp(buffer+1, entity->name)) { ent = entity->code; diff --git a/ext/mbstring/libmbfl/filters/mk_sb_tbl.awk b/ext/mbstring/libmbfl/filters/mk_sb_tbl.awk index 6d49a9ea7..0faf1cd46 100755 --- a/ext/mbstring/libmbfl/filters/mk_sb_tbl.awk +++ b/ext/mbstring/libmbfl/filters/mk_sb_tbl.awk @@ -1,6 +1,6 @@ #!/usr/bin/awk -f # -# $Id: mk_sb_tbl.awk,v 1.2 2005/02/21 07:57:08 moriyoshi Exp $ +# $Id: mk_sb_tbl.awk 180308 2005-02-21 07:57:08Z moriyoshi $ # # Description: a script that generates a single byte code set to Unicode # mapping table. diff --git a/ext/mbstring/libmbfl/mbfl.rc b/ext/mbstring/libmbfl/mbfl.rc index 0ee7d97da..d885c624d 100644 --- a/ext/mbstring/libmbfl/mbfl.rc +++ b/ext/mbstring/libmbfl/mbfl.rc @@ -1,4 +1,4 @@ -/* $Id: mbfl.rc,v 1.5.6.1 2008/07/05 06:52:04 hirokawa Exp $ */ +/* $Id: mbfl.rc 262042 2008-07-05 06:52:04Z hirokawa $ */ 1 VERSIONINFO FILEVERSION 1,0,2,0 PRODUCTVERSION 1,0,2,0 diff --git a/ext/mbstring/libmbfl/mbfl/mk_eaw_tbl.awk b/ext/mbstring/libmbfl/mbfl/mk_eaw_tbl.awk index c9fdf7c5d..de2b7e0be 100644 --- a/ext/mbstring/libmbfl/mbfl/mk_eaw_tbl.awk +++ b/ext/mbstring/libmbfl/mbfl/mk_eaw_tbl.awk @@ -1,6 +1,6 @@ #!/usr/bin/awk -f # -# $Id: mk_eaw_tbl.awk,v 1.2 2005/02/20 22:18:08 moriyoshi Exp $ +# $Id: mk_eaw_tbl.awk 180252 2005-02-20 22:18:09Z moriyoshi $ # # Description: a script to generate east asian width table. # diff --git a/ext/mbstring/mb_gpc.c b/ext/mbstring/mb_gpc.c index 5e6d0ac17..b7dfd57dd 100644 --- a/ext/mbstring/mb_gpc.c +++ b/ext/mbstring/mb_gpc.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mb_gpc.c,v 1.17.2.2.2.3.2.3 2009/03/15 20:42:56 moriyoshi Exp $ */ +/* $Id: mb_gpc.c 284727 2009-07-24 23:48:58Z moriyoshi $ */ /* {{{ includes */ #ifdef HAVE_CONFIG_H @@ -59,7 +59,7 @@ MBSTRING_API SAPI_TREAT_DATA_FUNC(mbstr_treat_data) enum mbfl_no_encoding detected; php_mb_encoding_handler_info_t info; - { + if (arg != PARSE_STRING) { char *value = zend_ini_string("mbstring.internal_encoding", sizeof("mbstring.internal_encoding"), 0); _php_mb_ini_mbstring_internal_encoding_set(value, value ? strlen(value): 0 TSRMLS_CC); } diff --git a/ext/mbstring/mb_gpc.h b/ext/mbstring/mb_gpc.h index fdeb595d0..81d75d544 100644 --- a/ext/mbstring/mb_gpc.h +++ b/ext/mbstring/mb_gpc.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mb_gpc.h,v 1.5.2.1 2006/01/01 12:50:08 sniper Exp $ */ +/* $Id: mb_gpc.h 242949 2007-09-26 15:44:16Z cvs2svn $ */ /* {{{ includes */ #ifdef HAVE_CONFIG_H diff --git a/ext/mbstring/mbstring.c b/ext/mbstring/mbstring.c index 5f581f75f..3e46e8239 100644 --- a/ext/mbstring/mbstring.c +++ b/ext/mbstring/mbstring.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mbstring.c,v 1.224.2.22.2.25.2.55 2009/05/27 13:42:17 tony2001 Exp $ */ +/* $Id: mbstring.c 281226 2009-05-27 13:42:17Z tony2001 $ */ /* * PHP 4 Multibyte String module "mbstring" diff --git a/ext/mbstring/mbstring.h b/ext/mbstring/mbstring.h index be7ac2bf3..ee0f8b8d2 100644 --- a/ext/mbstring/mbstring.h +++ b/ext/mbstring/mbstring.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mbstring.h,v 1.66.2.4.2.5.2.11 2009/03/15 20:42:56 moriyoshi Exp $ */ +/* $Id: mbstring.h 277211 2009-03-15 20:42:56Z moriyoshi $ */ /* * PHP 4 Multibyte String module "mbstring" (currently only for Japanese) diff --git a/ext/mbstring/php_mbregex.c b/ext/mbstring/php_mbregex.c index 67538f2df..a3c577848 100644 --- a/ext/mbstring/php_mbregex.c +++ b/ext/mbstring/php_mbregex.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_mbregex.c,v 1.53.2.1.2.4.2.14 2009/06/05 18:50:32 mattwil Exp $ */ +/* $Id: php_mbregex.c 281727 2009-06-05 18:50:32Z mattwil $ */ #ifdef HAVE_CONFIG_H diff --git a/ext/mbstring/php_mbregex.h b/ext/mbstring/php_mbregex.h index c2b5df5ba..c9201df3f 100644 --- a/ext/mbstring/php_mbregex.h +++ b/ext/mbstring/php_mbregex.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_mbregex.h,v 1.12.2.1.2.1.2.9 2008/12/31 11:15:38 sebastian Exp $ */ +/* $Id: php_mbregex.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef _PHP_MBREGEX_H #define _PHP_MBREGEX_H diff --git a/ext/mbstring/tests/bug46806.phpt b/ext/mbstring/tests/bug46806.phpt new file mode 100644 index 000000000..eec44b523 --- /dev/null +++ b/ext/mbstring/tests/bug46806.phpt @@ -0,0 +1,16 @@ +--TEST-- +Bug #46806 (mb_wtrimwidth cutting to early) +--CREDITS-- +Sebastian Schürmann +sebs@php.net +Testfest 2009 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +he... +hello diff --git a/ext/mbstring/tests/bug48645.phpt b/ext/mbstring/tests/bug48645.phpt new file mode 100644 index 000000000..6185442cc --- /dev/null +++ b/ext/mbstring/tests/bug48645.phpt @@ -0,0 +1,162 @@ +--TEST-- +Bug #48645 (mb_convert_encoding() doesn't understand hexadecimal html-entities) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(2) "00" +string(2) "01" +string(2) "02" +string(2) "03" +string(2) "04" +string(2) "05" +string(2) "06" +string(2) "07" +string(2) "08" +string(2) "09" +string(2) "0a" +string(2) "0b" +string(2) "0c" +string(2) "0d" +string(2) "0e" +string(2) "0f" +string(2) "0a" +string(2) "0b" +string(2) "0c" +string(2) "0d" +string(2) "0e" +string(2) "0f" +string(10) "2623782f3b" +string(10) "2623783a3b" +string(10) "262378403b" +string(10) "262378603b" +string(10) "262378473b" +string(10) "262378673b" +string(8) "2623783b" +string(2) "00" +string(2) "01" +string(2) "02" +string(2) "03" +string(2) "04" +string(2) "05" +string(2) "06" +string(2) "07" +string(2) "08" +string(2) "09" +string(2) "0a" +string(2) "0b" +string(2) "0c" +string(2) "0d" +string(2) "0e" +string(2) "0f" +string(2) "0a" +string(2) "0b" +string(2) "0c" +string(2) "0d" +string(2) "0e" +string(2) "0f" +string(10) "2623582f3b" +string(10) "2623583a3b" +string(10) "262358403b" +string(10) "262358603b" +string(10) "262358473b" +string(10) "262358673b" +string(8) "2623583b" +string(2) "00" +string(2) "01" +string(2) "02" +string(2) "03" +string(2) "04" +string(2) "05" +string(2) "06" +string(2) "07" +string(2) "08" +string(2) "09" +string(8) "26232f3b" +string(8) "26233a3b" +string(6) "26233b" +string(8) "f48fbfbf" +string(20) "2623783131303030303b" +string(8) "f48fbfbf" +string(20) "2623583131303030303b" +string(8) "f48fbfbf" +string(20) "2623313131343131323b" diff --git a/ext/mbstring/tests/mb_convert_kana.phpt b/ext/mbstring/tests/mb_convert_kana.phpt new file mode 100644 index 000000000..b3bffb61d --- /dev/null +++ b/ext/mbstring/tests/mb_convert_kana.phpt @@ -0,0 +1,60 @@ +--TEST-- +Testing mb_convert_kana() function +--SKIPIF-- + +--FILE-- + ' . mb_convert_kana($zenKakuA, 'AZKH', 'utf-8'); +echo "\n"; +echo $zenKakuB . ' => ' . mb_convert_kana($zenKakuB, 'azkh', 'utf-8'); +echo "\n"; +echo $zenKakuC . ' => ' . mb_convert_kana($zenKakuC, 'azkh', 'utf-8'); +echo "\n"; +echo $zenKakuD . ' => ' . mb_convert_kana($zenKakuD, 'azkh', 'utf-8'); +echo "\n"; +echo $zenKakuE . ' => ' . mb_convert_kana($zenKakuE, 'azkh', 'utf-8'); +echo "\n"; +echo $zenKakuF . ' => ' . mb_convert_kana($zenKakuF, 'azkh', 'utf-8'); +echo "\n"; +echo "\n"; +echo $hanKakuA . ' => ' . mb_convert_kana($hanKakuA, 'AZKH', 'utf-8'); +echo "\n"; +echo $hanKakuB . ' => ' . mb_convert_kana($hanKakuB, 'AZKH', 'utf-8'); +echo "\n"; +echo $hanKakuC . ' => ' . mb_convert_kana($hanKakuC, 'AZKH', 'utf-8'); +echo "\n"; +echo $hanKakuD . ' => ' . mb_convert_kana($hanKakuD, 'AZKH', 'utf-8'); +?> +--EXPECT-- +ァアィイゥウェエォオカガキギク => ァアィイゥウェエォオカガキギク +グケゲコゴサザシジスズセゼソゾタ => グケゲコゴサザシジスズセゼソゾタ +ダチヂッツヅテデトドナニヌネノハ => ダチヂッツヅテデトドナニヌネノハ +バパヒビピフブプヘベペホボポマミ => バパヒビピフブプヘベペホボポマミ +ムメモャヤュユョヨラリルレロヮワ => ムメモャヤュユョヨラリルレロワワ +ヰヱヲンヴヵヶヷヸヹヺ・ーヽヾ => イエヲンヴヵヶヷヸヹヺ・ーヽヾ + +⦆。「」、・ヲァィゥェォャュョッ => ⦆。「」、・ヲァィゥェォャュョッ +ーアイウエオカキクケコサシスセソ => ーアイウエオカキクケコサシスセソ +タチツテトナニヌネノハヒフヘホマ => タチツテトナニヌネノハヒフヘホマ +ミムメモヤユヨラリルレロワン゙゚ => ミムメモヤユヨラリルレロワン゛゜ + +--CREDITS-- +Jason Easter +PHPUG Würzburg +Testfest 2009 2009-06-20 diff --git a/ext/mbstring/tests/mb_decode_numericentity.phpt b/ext/mbstring/tests/mb_decode_numericentity.phpt new file mode 100644 index 000000000..6008ef9a9 --- /dev/null +++ b/ext/mbstring/tests/mb_decode_numericentity.phpt @@ -0,0 +1,21 @@ +--TEST-- +Test mb_decode_numericentity() function : Convert HTML-Entities to UTF-8 +--SKIPIF-- + +--FILE-- + +--EXPECT-- +¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +ƒΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρςστυφχψωϑϒϖ•…′″‾⁄℘ℑℜ™ℵ←↑→↓↔↵⇐⇑⇒⇓⇔∀∂∃∅∇∈∉∋∏∑−∗√∝∞∠∧∨∩∪∫∴∼≅≈≠≡≤≥⊂⊃⊄⊆⊇⊕⊗⊥⋅⌈⌉⌊⌋〈〉◊♠♣♥♦ +aŒbœcŠdše€fg diff --git a/ext/mbstring/tests/mb_encode_numericentity.phpt b/ext/mbstring/tests/mb_encode_numericentity.phpt new file mode 100644 index 000000000..dffb41966 --- /dev/null +++ b/ext/mbstring/tests/mb_encode_numericentity.phpt @@ -0,0 +1,22 @@ +--TEST-- +Test mb_encode_numericentity() function : Convert UTF-8 to HTML-Entities +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ +ƒΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρςστυφχψωϑϒϖ•…′″‾⁄℘ℑℜ™ℵ←↑→↓↔↵⇐⇑⇒⇓⇔∀∂∃∅∇∈∉∋∏∑−∗√∝∞∠∧∨∩∪∫∴∼≅≈≠≡≤≥⊂⊃⊄⊆⊇⊕⊗⊥⋅⌈⌉⌊⌋〈〉◊♠♣♥♦ +aŒbœcŠdše€fg diff --git a/ext/mbstring/tests/mb_ereg3.phpt b/ext/mbstring/tests/mb_ereg3.phpt new file mode 100644 index 000000000..abec3e7ad --- /dev/null +++ b/ext/mbstring/tests/mb_ereg3.phpt @@ -0,0 +1,44 @@ +--TEST-- +mb_ereg() returning matches +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +int(-1) +int(-1) +array(1) { + [0]=> + string(2) "-1" +} +int(-1) +int(-1) +array(1) { + [0]=> + string(2) "-1" +} + +Warning: mbereg_search_init() expects parameter 3 to be %binary_string_optional%, array given in %s on line %d +int(-1) +int(-1) +array(1) { + [0]=> + string(2) "-1" +} +Done diff --git a/ext/mbstring/tests/mb_ereg4.phpt b/ext/mbstring/tests/mb_ereg4.phpt new file mode 100644 index 000000000..8dca4358f --- /dev/null +++ b/ext/mbstring/tests/mb_ereg4.phpt @@ -0,0 +1,44 @@ +--TEST-- +mb_ereg() returning matches +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +int(-1) +int(-1) +array(1) { + [0]=> + string(2) "-1" +} +int(-1) +int(-1) +array(1) { + [0]=> + string(2) "-1" +} + +Warning: mbereg_search_init() expects parameter 3 to be string, array given in %s on line %d +int(-1) +int(-1) +array(1) { + [0]=> + string(2) "-1" +} +Done diff --git a/ext/mbstring/tests/mb_ereg_search.phpt b/ext/mbstring/tests/mb_ereg_search.phpt new file mode 100755 index 000000000..4df54c482 --- /dev/null +++ b/ext/mbstring/tests/mb_ereg_search.phpt @@ -0,0 +1,39 @@ +--TEST-- +Testing mb_ereg_search() function +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(9) "中国abc" +string(3) "abc" +string(6) "字符" +string(5) "china" +string(6) "string" diff --git a/ext/mbstring/tests/mb_ereg_search_pos.phpt b/ext/mbstring/tests/mb_ereg_search_pos.phpt new file mode 100644 index 000000000..fcd98e16c --- /dev/null +++ b/ext/mbstring/tests/mb_ereg_search_pos.phpt @@ -0,0 +1,31 @@ +--TEST-- +mb_ereg_search_pos() # a test for the basic function of mb_ereg_search_pos +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(2) { + [0]=> + int(5) + [1]=> + int(6) +} + + diff --git a/ext/mbstring/tests/mb_ereg_search_regs.phpt b/ext/mbstring/tests/mb_ereg_search_regs.phpt new file mode 100644 index 000000000..2cc55a7bd --- /dev/null +++ b/ext/mbstring/tests/mb_ereg_search_regs.phpt @@ -0,0 +1,28 @@ +--TEST-- +Funktionstest mb_ereg_search_regs() +--SKIPIF-- + +--FILE-- + +--EXPECT-- +array(1) { + [0]=> + string(4) "ов" +} diff --git a/ext/mbstring/tests/mb_eregi.phpt b/ext/mbstring/tests/mb_eregi.phpt new file mode 100644 index 000000000..ced6fadcd --- /dev/null +++ b/ext/mbstring/tests/mb_eregi.phpt @@ -0,0 +1,20 @@ +--TEST-- +mb_eregi() and invalid arguments +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(1) +bool(false) +int(1) diff --git a/ext/mbstring/tests/mb_eregi_invalid_arguments.phpt b/ext/mbstring/tests/mb_eregi_invalid_arguments.phpt new file mode 100644 index 000000000..ced6fadcd --- /dev/null +++ b/ext/mbstring/tests/mb_eregi_invalid_arguments.phpt @@ -0,0 +1,20 @@ +--TEST-- +mb_eregi() and invalid arguments +--SKIPIF-- + +--FILE-- + +--EXPECT-- +int(1) +bool(false) +int(1) diff --git a/ext/mbstring/tests/mb_eregi_replace.phpt b/ext/mbstring/tests/mb_eregi_replace.phpt new file mode 100644 index 000000000..dd6162c25 --- /dev/null +++ b/ext/mbstring/tests/mb_eregi_replace.phpt @@ -0,0 +1,37 @@ +--TEST-- +Testing mb_eregi_replace() function +--SKIPIF-- + +--FILE-- +"i","ц"=>"c","у"=>"u","к"=>"k","е"=>"e","н"=>"n", + "г"=>"g","ш"=>"sh","щ"=>"sh","з"=>"z","х"=>"x","ъ"=>"\'", + "ф"=>"f","ы"=>"i","в"=>"v","а"=>"a","п"=>"p","р"=>"r", + "о"=>"o","л"=>"l","д"=>"d","ж"=>"zh","э"=>"ie","ё"=>"e", + "я"=>"ya","ч"=>"ch","с"=>"c","м"=>"m","и"=>"i","т"=>"t", + "ь"=>"\'","б"=>"b","ю"=>"yu", + "Й"=>"I","Ц"=>"C","У"=>"U","К"=>"K","Е"=>"E","Н"=>"N", + "Г"=>"G","Ш"=>"SH","Щ"=>"SH","З"=>"Z","Х"=>"X","Ъ"=>"\'", + "Ф"=>"F","Ы"=>"I","В"=>"V","А"=>"A","П"=>"P","Р"=>"R", + "О"=>"O","Л"=>"L","Д"=>"D","Ж"=>"ZH","Э"=>"IE","Ё"=>"E", + "Я"=>"YA","Ч"=>"CH","С"=>"C","М"=>"M","И"=>"I","Т"=>"T", + "Ь"=>"\'","Б"=>"B","Ю"=>"YU", + ); + + foreach($replacement as $i=>$u) { + $st = mb_eregi_replace($i,$u,$st); + } + return $st; +} + +echo do_translit("Фуцк"); +?> +--EXPECT-- +Fuck +--CREDITS-- +Testfest Wuerzburg 2009-06-20 diff --git a/ext/mcrypt/TODO b/ext/mcrypt/TODO index e11f28b36..2cb56e1fc 100644 --- a/ext/mcrypt/TODO +++ b/ext/mcrypt/TODO @@ -1,4 +1,4 @@ -/* $Id: TODO,v 1.3 2003/12/19 15:29:34 derick Exp $ */ +/* $Id: TODO 242949 2007-09-26 15:44:16Z cvs2svn $ */ ToDo: - Convert to zend_parse_parameters diff --git a/ext/mcrypt/config.m4 b/ext/mcrypt/config.m4 index c6e979217..c45cf1bda 100644 --- a/ext/mcrypt/config.m4 +++ b/ext/mcrypt/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.31.4.1 2006/12/23 17:58:47 derick Exp $ +dnl $Id: config.m4 225644 2006-12-23 17:58:47Z derick $ dnl AC_DEFUN([PHP_MCRYPT_CHECK_VERSION],[ diff --git a/ext/mcrypt/config.w32 b/ext/mcrypt/config.w32 index 16ab00730..2e23c776a 100644 --- a/ext/mcrypt/config.w32 +++ b/ext/mcrypt/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.2.8.3 2008/08/05 17:20:10 pajoye Exp $ +// $Id: config.w32 264237 2008-08-05 17:20:10Z pajoye $ // vim:ft=javascript ARG_WITH("mcrypt", "mcrypt support", "no"); diff --git a/ext/mcrypt/mcrypt.c b/ext/mcrypt/mcrypt.c index 2a28bf609..c06bfb303 100644 --- a/ext/mcrypt/mcrypt.c +++ b/ext/mcrypt/mcrypt.c @@ -16,7 +16,7 @@ | Derick Rethans | +----------------------------------------------------------------------+ */ -/* $Id: mcrypt.c,v 1.91.2.3.2.11.2.18 2009/06/06 02:40:48 mattwil Exp $ */ +/* $Id: mcrypt.c 289433 2009-10-09 17:28:52Z pajoye $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -780,6 +780,7 @@ PHP_FUNCTION(mcrypt_generic_deinit) php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not terminate encryption specifier"); RETURN_FALSE } + pm->init = 0; RETURN_TRUE } /* }}} */ diff --git a/ext/mcrypt/php_mcrypt.h b/ext/mcrypt/php_mcrypt.h index 92ce8364b..95610560d 100644 --- a/ext/mcrypt/php_mcrypt.h +++ b/ext/mcrypt/php_mcrypt.h @@ -16,7 +16,7 @@ | Derick Rethans | +----------------------------------------------------------------------+ */ -/* $Id: php_mcrypt.h,v 1.26.2.1.2.2.2.4 2008/12/31 11:15:38 sebastian Exp $ */ +/* $Id: php_mcrypt.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_MCRYPT_H #define PHP_MCRYPT_H diff --git a/ext/mcrypt/tests/bug49738.phpt b/ext/mcrypt/tests/bug49738.phpt new file mode 100644 index 000000000..8f01bec49 --- /dev/null +++ b/ext/mcrypt/tests/bug49738.phpt @@ -0,0 +1,13 @@ +--TEST-- +Bug #49738 (calling mcrypt after mcrypt_generic_deinit crashes) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: mcrypt_generic(): Operation disallowed prior to mcrypt_generic_init(). in %sbug49738.php on line 5 diff --git a/ext/mssql/config.m4 b/ext/mssql/config.m4 index 530b17f23..c26f7c758 100644 --- a/ext/mssql/config.m4 +++ b/ext/mssql/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.9.2.2.2.1.2.1 2008/10/04 12:55:21 felipe Exp $ +dnl $Id: config.m4 266961 2008-10-04 12:55:21Z felipe $ dnl PHP_ARG_WITH(mssql,for MSSQL support via FreeTDS, diff --git a/ext/mssql/config.w32 b/ext/mssql/config.w32 index 0955f9cdc..9c43816d2 100644 --- a/ext/mssql/config.w32 +++ b/ext/mssql/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.7 2005/01/18 22:38:24 fmk Exp $ +// $Id: config.w32 177602 2005-01-18 22:38:24Z fmk $ // vim:ft=javascript ARG_WITH("mssql", "mssql support", "no"); diff --git a/ext/mssql/php_mssql.c b/ext/mssql/php_mssql.c index 0f6abf1c5..74d89dd6d 100644 --- a/ext/mssql/php_mssql.c +++ b/ext/mssql/php_mssql.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_mssql.c,v 1.152.2.13.2.4.2.23 2009/05/26 12:35:46 felipe Exp $ */ +/* $Id: php_mssql.c 284145 2009-07-15 19:09:15Z rasmus $ */ #ifdef COMPILE_DL_MSSQL #define HAVE_MSSQL 1 @@ -550,6 +550,17 @@ static void php_mssql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent) return; } + /* Limit strings to 255 chars to prevent overflow issues in underlying libraries */ + if(host_len>255) { + host[255] = '\0'; + } + if(user_len>255) { + user[255] = '\0'; + } + if(passwd_len>255) { + passwd[255] = '\0'; + } + switch(ZEND_NUM_ARGS()) { case 0: diff --git a/ext/mssql/php_mssql.h b/ext/mssql/php_mssql.h index 6a06bc839..2622d36d2 100644 --- a/ext/mssql/php_mssql.h +++ b/ext/mssql/php_mssql.h @@ -17,7 +17,7 @@ */ -/* $Id: php_mssql.h,v 1.42.2.3.2.1.2.4 2009/05/26 12:32:00 felipe Exp $ */ +/* $Id: php_mssql.h 281162 2009-05-26 12:32:00Z felipe $ */ #ifndef PHP_MSSQL_H #define PHP_MSSQL_H diff --git a/ext/mysql/config.m4 b/ext/mysql/config.m4 index 9b6ebf840..47e9083fc 100644 --- a/ext/mysql/config.m4 +++ b/ext/mysql/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.67.2.1.2.1.2.4 2008/07/21 12:58:51 andrey Exp $ +dnl $Id: config.m4 263087 2008-07-21 12:58:51Z andrey $ dnl AC_DEFUN([MYSQL_LIB_CHK], [ diff --git a/ext/mysql/config.w32 b/ext/mysql/config.w32 index 0a4e6617a..eb3ab0476 100644 --- a/ext/mysql/config.w32 +++ b/ext/mysql/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.2.6.6 2008/06/23 18:40:28 pajoye Exp $ +// $Id: config.w32 261548 2008-06-23 18:40:29Z pajoye $ // vim:ft=javascript ARG_WITH("mysql", "MySQL support", "no"); diff --git a/ext/mysql/php_mysql.c b/ext/mysql/php_mysql.c index 64fe0eaa6..9c109316b 100644 --- a/ext/mysql/php_mysql.c +++ b/ext/mysql/php_mysql.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_mysql.c,v 1.213.2.6.2.16.2.37 2009/05/20 08:30:12 kalle Exp $ */ +/* $Id: php_mysql.c 289630 2009-10-14 13:51:25Z johannes $ */ /* TODO: * @@ -971,6 +971,7 @@ PHP_FUNCTION(mysql_pconnect) Close a MySQL connection */ PHP_FUNCTION(mysql_close) { + int resource_id; zval *mysql_link=NULL; php_mysql_conn *mysql; @@ -984,24 +985,25 @@ PHP_FUNCTION(mysql_close) ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, NULL, MySG(default_link), "MySQL-Link", le_link, le_plink); } + resource_id = mysql_link ? Z_RESVAL_P(mysql_link) : MySG(default_link); + PHPMY_UNBUFFERED_QUERY_CHECK(); #ifdef MYSQL_USE_MYSQLND { int tmp; - if ((mysql = zend_list_find(Z_RESVAL_P(mysql_link), &tmp)) && tmp == le_plink) { + if ((mysql = zend_list_find(resource_id, &tmp)) && tmp == le_plink) { mysqlnd_end_psession(mysql->conn); } } #endif - if (mysql_link) { /* explicit resource number */ - PHPMY_UNBUFFERED_QUERY_CHECK(); - zend_list_delete(Z_RESVAL_P(mysql_link)); - } + zend_list_delete(resource_id); if (!mysql_link || (mysql_link && Z_RESVAL_P(mysql_link)==MySG(default_link))) { - PHPMY_UNBUFFERED_QUERY_CHECK(); - zend_list_delete(MySG(default_link)); MySG(default_link) = -1; + if (mysql_link) { + /* on an explicit close of the default connection it had a refcount of 2 so we need one more call */ + zend_list_delete(resource_id); + } } RETURN_TRUE; @@ -1970,7 +1972,7 @@ static void php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, int result_type, } } - if ((result_type & MYSQL_BOTH) == 0) { + if (result_type & ~MYSQL_BOTH) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH"); result_type = MYSQL_BOTH; } @@ -2147,6 +2149,11 @@ PHP_FUNCTION(mysql_fetch_array) } ZEND_FETCH_RESOURCE(result, MYSQL_RES *, &mysql_result, -1, "MySQL result", le_result); + if (mode & ~MYSQL_BOTH) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH"); + mode = MYSQL_BOTH; + } + mysqlnd_fetch_into(result, mode, return_value, MYSQLND_MYSQL); #endif } diff --git a/ext/mysql/php_mysql.h b/ext/mysql/php_mysql.h index 77f6d76b6..33c3b2ed5 100644 --- a/ext/mysql/php_mysql.h +++ b/ext/mysql/php_mysql.h @@ -17,7 +17,7 @@ */ -/* $Id: php_mysql.h,v 1.37.2.1.2.2.2.4 2008/12/31 11:15:38 sebastian Exp $ */ +/* $Id: php_mysql.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_MYSQL_H #define PHP_MYSQL_H diff --git a/ext/mysql/php_mysql_structs.h b/ext/mysql/php_mysql_structs.h index 5295275d4..d74eadc04 100644 --- a/ext/mysql/php_mysql_structs.h +++ b/ext/mysql/php_mysql_structs.h @@ -18,7 +18,7 @@ */ -/* $Id: php_mysql_structs.h,v 1.1.2.7 2008/12/31 11:15:38 sebastian Exp $ */ +/* $Id: php_mysql_structs.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_MYSQL_STRUCTS_H #define PHP_MYSQL_STRUCTS_H diff --git a/ext/mysql/tests/001.phpt b/ext/mysql/tests/001.phpt index de3957190..6f2e284de 100755 --- a/ext/mysql/tests/001.phpt +++ b/ext/mysql/tests/001.phpt @@ -25,9 +25,6 @@ mysql_close($db); var_dump($test); print "done!"; ?> ---EXPECT-- -string(2) "11" +--EXPECTF-- +%unicode|string%(2) "11" done! ---UEXPECTF-- -unicode(2) "11" -done! \ No newline at end of file diff --git a/ext/mysql/tests/002.phpt b/ext/mysql/tests/002.phpt index 9c1250104..8355c5f11 100755 --- a/ext/mysql/tests/002.phpt +++ b/ext/mysql/tests/002.phpt @@ -32,6 +32,10 @@ mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- resource(%d) of type (mysql link) bool(true) @@ -39,42 +43,19 @@ bool(true) bool(true) resource(%d) of type (mysql result) array(3) { - ["col1"]=> - string(1) "1" - ["col2"]=> - string(3) "foo" - ["col3"]=> - string(3) "bar" + [%u|b%"col1"]=> + %unicode|string%(1) "1" + [%u|b%"col2"]=> + %unicode|string%(3) "foo" + [%u|b%"col3"]=> + %unicode|string%(3) "bar" } array(3) { - ["col1"]=> - string(1) "2" - ["col2"]=> - string(3) "foo" - ["col3"]=> - string(3) "bar" + [%u|b%"col1"]=> + %unicode|string%(1) "2" + [%u|b%"col2"]=> + %unicode|string%(3) "foo" + [%u|b%"col3"]=> + %unicode|string%(3) "bar" } done! ---UEXPECTF-- -resource(%d) of type (mysql link) -bool(true) -bool(true) -bool(true) -resource(%d) of type (mysql result) -array(3) { - [u"col1"]=> - unicode(1) "1" - [u"col2"]=> - unicode(3) "foo" - [u"col3"]=> - unicode(3) "bar" -} -array(3) { - [u"col1"]=> - unicode(1) "2" - [u"col2"]=> - unicode(3) "foo" - [u"col3"]=> - unicode(3) "bar" -} -done! \ No newline at end of file diff --git a/ext/mysql/tests/003.phpt b/ext/mysql/tests/003.phpt index 0c3717b29..2d0b68b9f 100755 --- a/ext/mysql/tests/003.phpt +++ b/ext/mysql/tests/003.phpt @@ -52,65 +52,38 @@ mysql_free_result($res); mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- ==stdClass== object(stdClass)#%d (1) { - ["a"]=> - string(3) "one" + [%u|b%"a"]=> + %unicode|string%(3) "one" } object(stdClass)#%d (1) { - ["a"]=> - string(3) "two" + [%u|b%"a"]=> + %unicode|string%(3) "two" } object(stdClass)#%d (1) { - ["a"]=> - string(5) "three" + [%u|b%"a"]=> + %unicode|string%(5) "three" } ==class24== class24::__construct object(class24)#%d (1) { - ["a"]=> - string(3) "one" + [%u|b%"a"]=> + %unicode|string%(3) "one" } class24::__construct object(class24)#%d (1) { - ["a"]=> - string(3) "two" + [%u|b%"a"]=> + %unicode|string%(3) "two" } class24::__construct object(class24)#%d (1) { - ["a"]=> - string(5) "three" + [%u|b%"a"]=> + %unicode|string%(5) "three" } done! ---UEXPECTF-- -==stdClass== -object(stdClass)#%d (1) { - [u"a"]=> - unicode(3) "one" -} -object(stdClass)#%d (1) { - [u"a"]=> - unicode(3) "two" -} -object(stdClass)#%d (1) { - [u"a"]=> - unicode(5) "three" -} -==class24== -class24::__construct -object(class24)#%d (1) { - [u"a"]=> - unicode(3) "one" -} -class24::__construct -object(class24)#%d (1) { - [u"a"]=> - unicode(3) "two" -} -class24::__construct -object(class24)#%d (1) { - [u"a"]=> - unicode(5) "three" -} -done! \ No newline at end of file diff --git a/ext/mysql/tests/bug47438.phpt b/ext/mysql/tests/bug47438.phpt index 700c6d801..11f0ff33b 100644 --- a/ext/mysql/tests/bug47438.phpt +++ b/ext/mysql/tests/bug47438.phpt @@ -16,7 +16,7 @@ if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) mysql_select_db($db, $link); mysql_query("DROP TABLE IF EXISTS test_47438", $link); mysql_query("CREATE TABLE test_47438 (a INT, b INT, c INT)", $link); -mysql_query("INSERT INTO test_47438 VALUES (10, 11, 12), (20, 21, 22)", $link); +mysql_query("INSERT INTO test_47438 VALUES (10, 11, 12), (20, 21, 22)", $link); $result = mysql_query("SELECT * FROM test_47438", $link); mysql_field_seek($result, 1); @@ -31,6 +31,20 @@ while($i +--CLEAN-- + --EXPECT-- 0.a diff --git a/ext/mysql/tests/bug48754.phpt b/ext/mysql/tests/bug48754.phpt new file mode 100644 index 000000000..fb322f461 --- /dev/null +++ b/ext/mysql/tests/bug48754.phpt @@ -0,0 +1,92 @@ +--TEST-- +Bug #48754 (mysql_close() crash php when no handle specified) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Explicit connection on close +Expect same thread id for $link and default conn: bool(true) +resource(%d) of type (mysql link) +resource(%d) of type (Unknown) + +Warning: mysql_close(): no MySQL-Link resource supplied in %s on line %d + +Closing default link +Expect same thread id for $link and default conn but not the previous: bool(true) +resource(%d) of type (mysql link) +resource(%d) of type (mysql link) +resource(%d) of type (Unknown) + +Explicit resource and pconnect +resource(%d) of type (mysql link persistent) +resource(%d) of type (Unknown) + +Warning: mysql_close(): no MySQL-Link resource supplied in %s on line %d + +Default link and pconnect +resource(%d) of type (mysql link persistent) +resource(%d) of type (mysql link persistent) +resource(%d) of type (Unknown) diff --git a/ext/mysql/tests/clean_table.inc b/ext/mysql/tests/clean_table.inc new file mode 100644 index 000000000..e53245b43 --- /dev/null +++ b/ext/mysql/tests/clean_table.inc @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/ext/mysql/tests/connect.inc b/ext/mysql/tests/connect.inc index 70017b9e2..86c0ee674 100755 --- a/ext/mysql/tests/connect.inc +++ b/ext/mysql/tests/connect.inc @@ -20,14 +20,17 @@ if (!function_exists('sys_get_temp_dir')) { } /* wrapper to simplify test porting */ -function my_mysql_connect($host, $user, $passwd, $db, $port, $socket) { +function my_mysql_connect($host, $user, $passwd, $db, $port, $socket, $flags = NULL) { + global $connect_flags; + + $flags = ($flags === NULL) ? $connect_flags : $flags; if ($socket) $host = sprintf("%s:%s", $host, $socket); else if ($port) $host = sprintf("%s:%s", $host, $port); - if (!$link = mysql_connect($host, $user, $passwd, true)) { + if (!$link = mysql_connect($host, $user, $passwd, true, $flags)) { printf("[000-a] Cannot connect using host '%s', user '%s', password '****', [%d] %s\n", $host, $user, $passwd, mysql_errno(), mysql_error()); @@ -55,6 +58,7 @@ $db = getenv("MYSQL_TEST_DB") ? getenv("MYSQL_TEST_DB") : "test"; $engine = getenv("MYSQL_TEST_ENGINE") ? getenv("MYSQL_TEST_ENGINE") : "MyISAM"; $socket = getenv("MYSQL_TEST_SOCKET") ? getenv("MYSQL_TEST_SOCKET") : null; $skip_on_connect_failure = getenv("MYSQL_TEST_SKIP_CONNECT_FAILURE") ? getenv("MYSQL_TEST_SKIP_CONNECT_FAILURE") : true; +$connect_flags = getenv("MYSQL_TEST_CONNECT_FLAGS") ? (int)getenv("MYSQL_TEST_CONNECT_FLAGS") : 0; /* Development setting: test experimal features and/or feature requests that never worked before? */ $TEST_EXPERIMENTAL = (in_array(getenv("MYSQL_TEST_EXPERIMENTAL"), array(0, 1))) ? diff --git a/ext/mysql/tests/mysql_affected_rows.phpt b/ext/mysql/tests/mysql_affected_rows.phpt index 9e2da44e3..ce16a7748 100644 --- a/ext/mysql/tests/mysql_affected_rows.phpt +++ b/ext/mysql/tests/mysql_affected_rows.phpt @@ -4,6 +4,7 @@ mysql_affected_rows() --FILE-- +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysql/tests/mysql_client_encoding.phpt b/ext/mysql/tests/mysql_client_encoding.phpt index 399b1e870..8aa67a03a 100644 --- a/ext/mysql/tests/mysql_client_encoding.phpt +++ b/ext/mysql/tests/mysql_client_encoding.phpt @@ -50,7 +50,7 @@ if ($link_enc !== $tmp['charset']) { } } -if (ini_get('unicode.semantics') && function_exists('is_unicode')) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && function_exists('is_unicode')) { // unicode mode if (!is_unicode($default_link_enc) || !is_unicode($link_enc)) { printf("[010] No unicode returned!\n"); diff --git a/ext/mysql/tests/mysql_connect.phpt b/ext/mysql/tests/mysql_connect.phpt index ad10ea7f7..be094cce2 100644 --- a/ext/mysql/tests/mysql_connect.phpt +++ b/ext/mysql/tests/mysql_connect.phpt @@ -20,17 +20,23 @@ if (!$link = mysql_connect($myhost, $user, $passwd, true)) mysql_close($link); +if (!$link = mysql_connect($myhost, $user, $passwd, true)) + printf("[003] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $myhost, $user, $db, $port, $socket); + +mysql_close(); + if ($link = mysql_connect($myhost, $user . 'unknown_really', $passwd . 'non_empty', true)) - printf("[003] Can connect to the server using host=%s/%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", + printf("[004] Can connect to the server using host=%s/%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", $host, $myhost, $user . 'unknown_really', $db, $port, $socket); if (false !== $link) -printf("[004] Expecting boolean/false, got %s/%s\n", gettype($link), $link); +printf("[005] Expecting boolean/false, got %s/%s\n", gettype($link), $link); // Run the following tests without an anoynmous MySQL user and use a password for the test user! ini_set('mysql.default_socket', $socket); if (!is_resource($link = mysql_connect($host, $user, $passwd, true))) { - printf("[005] Usage of mysql.default_socket failed\n"); + printf("[006] Usage of mysql.default_socket failed\n"); } else { mysql_close($link); } @@ -39,58 +45,55 @@ if (!ini_get('sql.safe_mode')) { ini_set('mysql.default_port', $port); if (!is_resource($link = mysql_connect($host, $user, $passwd, true))) { - printf("[006] Usage of mysql.default_port failed\n"); + printf("[007] Usage of mysql.default_port failed\n"); } else { mysql_close($link); } ini_set('mysql.default_password', $passwd); if (!is_resource($link = mysql_connect($myhost, $user))) { - printf("[007] Usage of mysql.default_password failed\n"); + printf("[008] Usage of mysql.default_password failed\n"); } else { mysql_close($link); } ini_set('mysql.default_user', $user); if (!is_resource($link = mysql_connect($myhost))) { - printf("[008] Usage of mysql.default_user failed\n"); + printf("[009] Usage of mysql.default_user failed\n"); } else { mysql_close($link); } ini_set('mysql.default_host', $myhost); if (!is_resource($link = mysql_connect())) { - printf("[009] Usage of mysql.default_host failed\n") ; + printf("[010] Usage of mysql.default_host failed\n") ; } else { mysql_close($link); } + if (!is_resource($link = mysql_connect()) || !is_resource($link2 = mysql_connect())) { + printf("[011] Usage of mysql.default_host failed\n") ; + } else { + mysql_close(); + mysql_close($link2); + } + if (!stristr(PHP_OS, 'win') && !stristr(PHP_OS, 'netware')) { ini_set('mysql.default_port', -1); if (putenv(sprintf('MYSQL_TCP_PORT=%d', $port))) { if (!is_resource($link = mysql_connect())) { - printf("[010] Usage of env MYSQL_TCP_PORT failed\n") ; + printf("[012] Usage of env MYSQL_TCP_PORT failed\n") ; } else { mysql_close($link); } } else if (putenv(sprintf('MYSQL_TCP_PORT=%d', $port + 1))) { if (!is_resource($link = mysql_connect())) { - printf("[011] Usage of env MYSQL_TCP_PORT=%d should have failed\n", $port + 1) ; + printf("[013] Usage of env MYSQL_TCP_PORT=%d should have failed\n", $port + 1) ; mysql_close($link); } } } } -/* we don't care if we can connect or not, this is just to test the different connect syntax variants */ -$myhost = sprintf('%s:%d', $host, $port ); -if ($link = mysql_connect($myhost, $user, $passwd, true)) - mysql_close($link); - -/* interesting, isn't it? */ -$myhost = sprintf('%s:%d', $host, $port , $socket); -if ($link = mysql_connect($myhost, $user, $passwd, true)) - mysql_close($link); - print "done!"; ?> --EXPECTF-- diff --git a/ext/mysql/tests/mysql_create_db.phpt b/ext/mysql/tests/mysql_create_db.phpt index 0a5d30e97..bc91964f5 100644 --- a/ext/mysql/tests/mysql_create_db.phpt +++ b/ext/mysql/tests/mysql_create_db.phpt @@ -40,5 +40,17 @@ if (!mysql_query("DROP DATABASE mysqlcreatedb", $link)) print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysql/tests/mysql_data_seek.phpt b/ext/mysql/tests/mysql_data_seek.phpt index 687af1136..46a0f86bd 100644 --- a/ext/mysql/tests/mysql_data_seek.phpt +++ b/ext/mysql/tests/mysql_data_seek.phpt @@ -62,6 +62,10 @@ mysql_close($link); print "done!\n"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysql_data_seek(): Offset 4 is invalid for MySQL result index %d (or the query data is unbuffered) in %s on line %d diff --git a/ext/mysql/tests/mysql_db_name.phpt b/ext/mysql/tests/mysql_db_name.phpt index b1a03ed2c..be4f604d9 100644 --- a/ext/mysql/tests/mysql_db_name.phpt +++ b/ext/mysql/tests/mysql_db_name.phpt @@ -34,7 +34,7 @@ if (false !== ($tmp = mysql_db_name($res, $num + 1))) printf("[006] Expecting boolean/false, got %s/%s. [%d] %s\n", gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); -$unicode = (boolean)ini_get('unicode.semantics'); +$unicode = (boolean)(version_compare(PHP_VERSION, '5.9.9', '>') == 1); for ($i = 0; $i < $num; $i++) { if ('' === ($dbname = mysql_db_name($res, $i))) printf("[%03d] Got empty database name! [%d] %s\n", diff --git a/ext/mysql/tests/mysql_db_query.phpt b/ext/mysql/tests/mysql_db_query.phpt index 8adf48171..bb837dd6c 100644 --- a/ext/mysql/tests/mysql_db_query.phpt +++ b/ext/mysql/tests/mysql_db_query.phpt @@ -32,7 +32,7 @@ $row = mysql_fetch_assoc($res); if (1 != $row['id']) printf("[005] Expecting record 1/a, got record %s/%s\n", $row['id'], $row['label']); -if (ini_get('unicode.semantics') && !is_unicode($row['label'])) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($row['label'])) { printf("[006] No unicode returned! [%d] %s\n", mysql_errno($link), mysql_error($link)); var_inspect($row); } @@ -47,7 +47,7 @@ $row = mysql_fetch_assoc($res); if (1 != $row['id']) printf("[008] Expecting record 1/a, got record %s/%s\n", $row['id'], $row['label']); -if (ini_get('unicode.semantics') && !is_unicode($row['label'])) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($row['label'])) { printf("[009] No unicode returned! [%d] %s\n", mysql_errno(), mysql_error()); var_inspect($row); } @@ -57,5 +57,9 @@ mysql_close($link); print "done!\n"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysql/tests/mysql_drop_db.phpt b/ext/mysql/tests/mysql_drop_db.phpt index fb42f7b22..bd729e7ab 100644 --- a/ext/mysql/tests/mysql_drop_db.phpt +++ b/ext/mysql/tests/mysql_drop_db.phpt @@ -39,5 +39,17 @@ mysql_close($link); print "done!\n"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysql/tests/mysql_errno.phpt b/ext/mysql/tests/mysql_errno.phpt index 7a9e85fb3..8cfa7bd33 100644 --- a/ext/mysql/tests/mysql_errno.phpt +++ b/ext/mysql/tests/mysql_errno.phpt @@ -50,6 +50,10 @@ if ($link = @mysql_connect($host . '_unknown', $user . '_unknown', $passwd, true print "done!"; ?> +--CLEAN-- + --EXPECTF-- int(0) int(%d) diff --git a/ext/mysql/tests/mysql_error.phpt b/ext/mysql/tests/mysql_error.phpt index b64982a42..aae448017 100644 --- a/ext/mysql/tests/mysql_error.phpt +++ b/ext/mysql/tests/mysql_error.phpt @@ -39,7 +39,7 @@ $tmp = mysql_error($link); if (!is_string($tmp) || !preg_match("/Table '\w*\.test' doesn't exist/su", $tmp)) printf("[006] Expecting string/[Table... doesn't exit], got %s/%s. [%d] %s\n", gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); -if (ini_get('unicode.semantics') && !is_unicode($tmp)) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp)) { printf("[007] Expecting Unicode error message!\n"); var_inspect($tmp); } @@ -57,6 +57,10 @@ if ('' == mysql_error()) print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysql_error(): %d is not a valid MySQL-Link resource in %s on line %d bool(false) diff --git a/ext/mysql/tests/mysql_escape_string.phpt b/ext/mysql/tests/mysql_escape_string.phpt index 1badea890..45bf26978 100644 --- a/ext/mysql/tests/mysql_escape_string.phpt +++ b/ext/mysql/tests/mysql_escape_string.phpt @@ -23,20 +23,11 @@ var_dump(mysql_escape_string("foo" . chr(0) . "bar")); print "done!"; ?> --EXPECTF-- -string(31) "Am I a unicode string in PHP 6?" -string(2) "\\" -string(2) "\"" -string(2) "\'" -string(2) "\n" -string(2) "\r" -string(8) "foo\0bar" +%unicode|string%(31) "Am I a unicode string in PHP 6?" +%unicode|string%(2) "\\" +%unicode|string%(2) "\"" +%unicode|string%(2) "\'" +%unicode|string%(2) "\n" +%unicode|string%(2) "\r" +%unicode|string%(8) "foo\0bar" done! ---UEXPECTF-- -unicode(31) "Am I a unicode string in PHP 6?" -unicode(2) "\\" -unicode(2) "\"" -unicode(2) "\'" -unicode(2) "\n" -unicode(2) "\r" -unicode(8) "foo\0bar" -done! \ No newline at end of file diff --git a/ext/mysql/tests/mysql_fetch_array.phpt b/ext/mysql/tests/mysql_fetch_array.phpt index 729523514..635e6d109 100644 --- a/ext/mysql/tests/mysql_fetch_array.phpt +++ b/ext/mysql/tests/mysql_fetch_array.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_fetch_array() --SKIPIF-- - --FILE-- @@ -56,7 +56,7 @@ exit(1); do { $illegal_mode = mt_rand(0, 10000); } while (in_array($illegal_mode, array(MYSQL_ASSOC, MYSQL_NUM, MYSQL_BOTH))); -$tmp = @mysql_fetch_array($res, $illegal_mode); +$tmp = mysql_fetch_array($res, $illegal_mode); if (!is_array($tmp)) printf("[013] Expecting array, got %s/%s. [%d] %s\n", gettype($tmp), $tmp, mysql_errno($link), mysql_error($link)); @@ -277,155 +277,85 @@ printf("[015] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); print "done!"; ?> +--CLEAN-- + --EXPECTF-- [005] array(4) { [0]=> - string(1) "1" - ["id"]=> - string(1) "1" + %unicode|string%(1) "1" + [%u|b%"id"]=> + %unicode|string%(1) "1" [1]=> - string(1) "a" - ["label"]=> - string(1) "a" + %unicode|string%(1) "a" + [%u|b%"label"]=> + %unicode|string%(1) "a" } [006] array(2) { [0]=> - string(1) "2" + %unicode|string%(1) "2" [1]=> - string(1) "b" + %unicode|string%(1) "b" } [007] array(4) { [0]=> - string(1) "3" - ["id"]=> - string(1) "3" + %unicode|string%(1) "3" + [%u|b%"id"]=> + %unicode|string%(1) "3" [1]=> - string(1) "c" - ["label"]=> - string(1) "c" + %unicode|string%(1) "c" + [%u|b%"label"]=> + %unicode|string%(1) "c" } [008] array(2) { - ["id"]=> - string(1) "4" - ["label"]=> - string(1) "d" + [%u|b%"id"]=> + %unicode|string%(1) "4" + [%u|b%"label"]=> + %unicode|string%(1) "d" } [009] array(4) { [0]=> - string(1) "5" - ["id"]=> - string(1) "5" + %unicode|string%(1) "5" + [%u|b%"id"]=> + %unicode|string%(1) "5" [1]=> - string(1) "e" - ["label"]=> - string(1) "e" + %unicode|string%(1) "e" + [%u|b%"label"]=> + %unicode|string%(1) "e" } [011] array(11) { [0]=> - string(1) "1" - ["a"]=> - string(1) "2" + %unicode|string%(1) "1" + [%u|b%"a"]=> + %unicode|string%(1) "2" [1]=> - string(1) "2" + %unicode|string%(1) "2" [2]=> - string(1) "3" - ["c"]=> - string(1) "3" + %unicode|string%(1) "3" + [%u|b%"c"]=> + %unicode|string%(1) "3" [3]=> - string(1) "4" - ["C"]=> - string(1) "4" + %unicode|string%(1) "4" + [%u|b%"C"]=> + %unicode|string%(1) "4" [4]=> NULL - ["d"]=> + [%u|b%"d"]=> NULL [5]=> - string(1) "1" - ["e"]=> - string(1) "1" + %unicode|string%(1) "1" + [%u|b%"e"]=> + %unicode|string%(1) "1" } -Warning: mysql_fetch_array(): %d is not a valid MySQL result resource in %s on line %d -done! ---UEXPECTF-- -[005] -array(4) { - [0]=> - unicode(1) "1" - [u"id"]=> - unicode(1) "1" - [1]=> - unicode(1) "a" - [u"label"]=> - unicode(1) "a" -} -[006] -array(2) { - [0]=> - unicode(1) "2" - [1]=> - unicode(1) "b" -} -[007] -array(4) { - [0]=> - unicode(1) "3" - [u"id"]=> - unicode(1) "3" - [1]=> - unicode(1) "c" - [u"label"]=> - unicode(1) "c" -} -[008] -array(2) { - [u"id"]=> - unicode(1) "4" - [u"label"]=> - unicode(1) "d" -} -[009] -array(4) { - [0]=> - unicode(1) "5" - [u"id"]=> - unicode(1) "5" - [1]=> - unicode(1) "e" - [u"label"]=> - unicode(1) "e" -} -[011] -array(11) { - [0]=> - unicode(1) "1" - [u"a"]=> - unicode(1) "2" - [1]=> - unicode(1) "2" - [2]=> - unicode(1) "3" - [u"c"]=> - unicode(1) "3" - [3]=> - unicode(1) "4" - [u"C"]=> - unicode(1) "4" - [4]=> - NULL - [u"d"]=> - NULL - [5]=> - unicode(1) "1" - [u"e"]=> - unicode(1) "1" -} +Warning: mysql_fetch_array(): The result type should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH in %s on line %d Warning: mysql_fetch_array(): %d is not a valid MySQL result resource in %s on line %d done! diff --git a/ext/mysql/tests/mysql_fetch_assoc.phpt b/ext/mysql/tests/mysql_fetch_assoc.phpt index 4479a2ab3..3c5ca79b2 100644 --- a/ext/mysql/tests/mysql_fetch_assoc.phpt +++ b/ext/mysql/tests/mysql_fetch_assoc.phpt @@ -58,81 +58,46 @@ mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- [005] array(2) { - ["id"]=> - string(1) "1" - ["label"]=> - string(1) "a" -} -[006] -bool(false) -[008] -array(5) { - ["a"]=> - string(1) "2" - ["c"]=> - string(1) "3" - ["C"]=> - string(1) "4" - ["d"]=> - NULL - ["e"]=> - string(1) "1" -} - -Warning: mysql_fetch_assoc(): %d is not a valid MySQL result resource in %s on line %d -[010] -array(5) { - ["id"]=> - string(1) "1" - ["label"]=> - string(1) "a" - ["_id"]=> - string(1) "1" - ["_label"]=> - string(2) "aa" - ["_foo"]=> - NULL -} -done! ---UEXPECTF-- -[005] -array(2) { - [u"id"]=> - unicode(1) "1" - [u"label"]=> - unicode(1) "a" + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" } [006] bool(false) [008] array(5) { - [u"a"]=> - unicode(1) "2" - [u"c"]=> - unicode(1) "3" - [u"C"]=> - unicode(1) "4" - [u"d"]=> + [%u|b%"a"]=> + %unicode|string%(1) "2" + [%u|b%"c"]=> + %unicode|string%(1) "3" + [%u|b%"C"]=> + %unicode|string%(1) "4" + [%u|b%"d"]=> NULL - [u"e"]=> - unicode(1) "1" + [%u|b%"e"]=> + %unicode|string%(1) "1" } Warning: mysql_fetch_assoc(): %d is not a valid MySQL result resource in %s on line %d [010] array(5) { - [u"id"]=> - unicode(1) "1" - [u"label"]=> - unicode(1) "a" - [u"_id"]=> - unicode(1) "1" - [u"_label"]=> - unicode(2) "aa" - [u"_foo"]=> + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" + [%u|b%"_id"]=> + %unicode|string%(1) "1" + [%u|b%"_label"]=> + %unicode|string%(2) "aa" + [%u|b%"_foo"]=> NULL } done! diff --git a/ext/mysql/tests/mysql_fetch_field.phpt b/ext/mysql/tests/mysql_fetch_field.phpt index c46335f9d..65c44edc5 100644 --- a/ext/mysql/tests/mysql_fetch_field.phpt +++ b/ext/mysql/tests/mysql_fetch_field.phpt @@ -39,13 +39,13 @@ require_once('skipifconnectfailure.inc'); if (!$res = mysql_query("SELECT id AS ID, label FROM test AS TEST ORDER BY id LIMIT 1", $link)) { printf("[005] [%d] %s\n", mysql_errno($link), mysql_error($link)); } - if (false !== ($tmp = mysql_fetch_field($res, PHP_INT_MAX * 2))) - printf("[006] Expecting boolean/false got %s/%s\n", gettype($tmp), $tmp); + if (false !== ($tmp = mysql_fetch_field($res, PHP_INT_MAX - 1))) + printf("[006] Expecting boolean/false got %s/%s\n", gettype($tmp), var_export($tmp, true)); mysql_free_result($res); if (false !== ($tmp = mysql_fetch_field($res))) - printf("[007] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); + printf("[007] Expecting boolean/false, got %s/%s\n", gettype($tmp), var_export($tmp, true)); $types = array( 'BIT' => array(1, 'int'), @@ -124,189 +124,81 @@ require_once('skipifconnectfailure.inc'); printf("[017] [%d] %s\n", mysql_errno($link), mysql_error($link)); } $res = mysql_list_fields($db, 'test'); - while ($tmp = mysql_fetch_field($res)) - if ($tmp->name == 'id') + $found = false; + while ($tmp = mysql_fetch_field($res)) { + if ($tmp->name == 'id') { + printf("Fetch field from mysql_list_fields result set.\n"); + $found = true; var_dump($tmp); + } + } + if (!$found) + printf("[018] mysqli_list_fields result set processing has failed.\n"); mysql_free_result($res); mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- object(stdClass)#%d (13) { - ["name"]=> - string(2) "ID" - ["table"]=> - string(4) "TEST" - ["def"]=> - string(0) "" - ["max_length"]=> - int(1) - ["not_null"]=> - int(1) - ["primary_key"]=> - int(1) - ["multiple_key"]=> - int(0) - ["unique_key"]=> - int(0) - ["numeric"]=> - int(1) - ["blob"]=> - int(0) - ["type"]=> - string(3) "int" - ["unsigned"]=> - int(0) - ["zerofill"]=> - int(0) -} -object(stdClass)#%d (13) { - ["name"]=> - string(5) "label" - ["table"]=> - string(4) "TEST" - ["def"]=> - string(0) "" - ["max_length"]=> - int(1) - ["not_null"]=> - int(0) - ["primary_key"]=> - int(0) - ["multiple_key"]=> - int(0) - ["unique_key"]=> - int(0) - ["numeric"]=> - int(0) - ["blob"]=> - int(0) - ["type"]=> - string(6) "string" - ["unsigned"]=> - int(0) - ["zerofill"]=> - int(0) -} -bool(false) - -Warning: mysql_fetch_field(): Bad field offset in %s on line %d - -Warning: mysql_fetch_field(): %d is not a valid MySQL result resource in %s on line %d -object(stdClass)#%d (13) { - ["name"]=> - string(2) "id" - ["table"]=> - string(4) "test" - ["def"]=> - string(0) "" - ["max_length"]=> - int(1) - ["not_null"]=> - int(0) - ["primary_key"]=> - int(0) - ["multiple_key"]=> - int(0) - ["unique_key"]=> - int(0) - ["numeric"]=> - int(1) - ["blob"]=> - int(0) - ["type"]=> - string(3) "int" - ["unsigned"]=> - int(0) - ["zerofill"]=> - int(0) -} -object(stdClass)#%d (13) { - ["name"]=> - string(2) "id" - ["table"]=> - string(4) "test" - ["def"]=> - string(1) "1" - ["max_length"]=> - int(0) - ["not_null"]=> - int(0) - ["primary_key"]=> - int(0) - ["multiple_key"]=> - int(0) - ["unique_key"]=> - int(0) - ["numeric"]=> - int(1) - ["blob"]=> - int(0) - ["type"]=> - string(3) "int" - ["unsigned"]=> - int(0) - ["zerofill"]=> - int(0) -} -done! ---UEXPECTF-- -object(stdClass)#%d (13) { - [u"name"]=> - unicode(2) "ID" - [u"table"]=> - unicode(4) "TEST" - [u"def"]=> - unicode(0) "" - [u"max_length"]=> + [%u|b%"name"]=> + %unicode|string%(2) "ID" + [%u|b%"table"]=> + %unicode|string%(4) "TEST" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> int(1) - [u"not_null"]=> + [%u|b%"not_null"]=> int(1) - [u"primary_key"]=> + [%u|b%"primary_key"]=> int(1) - [u"multiple_key"]=> + [%u|b%"multiple_key"]=> int(0) - [u"unique_key"]=> + [%u|b%"unique_key"]=> int(0) - [u"numeric"]=> + [%u|b%"numeric"]=> int(1) - [u"blob"]=> + [%u|b%"blob"]=> int(0) - [u"type"]=> - unicode(3) "int" - [u"unsigned"]=> + [%u|b%"type"]=> + %unicode|string%(3) "int" + [%u|b%"unsigned"]=> int(0) - [u"zerofill"]=> + [%u|b%"zerofill"]=> int(0) } object(stdClass)#%d (13) { - [u"name"]=> - unicode(5) "label" - [u"table"]=> - unicode(4) "TEST" - [u"def"]=> - unicode(0) "" - [u"max_length"]=> + [%u|b%"name"]=> + %unicode|string%(5) "label" + [%u|b%"table"]=> + %unicode|string%(4) "TEST" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> int(1) - [u"not_null"]=> + [%u|b%"not_null"]=> int(0) - [u"primary_key"]=> + [%u|b%"primary_key"]=> int(0) - [u"multiple_key"]=> + [%u|b%"multiple_key"]=> int(0) - [u"unique_key"]=> + [%u|b%"unique_key"]=> int(0) - [u"numeric"]=> + [%u|b%"numeric"]=> int(0) - [u"blob"]=> + [%u|b%"blob"]=> int(0) - [u"type"]=> - unicode(6) "string" - [u"unsigned"]=> + [%u|b%"type"]=> + %unicode|string%(6) "string" + [%u|b%"unsigned"]=> int(0) - [u"zerofill"]=> + [%u|b%"zerofill"]=> int(0) } bool(false) @@ -315,59 +207,60 @@ Warning: mysql_fetch_field(): Bad field offset in %s on line %d Warning: mysql_fetch_field(): %d is not a valid MySQL result resource in %s on line %d object(stdClass)#%d (13) { - [u"name"]=> - unicode(2) "id" - [u"table"]=> - unicode(4) "test" - [u"def"]=> - unicode(0) "" - [u"max_length"]=> + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> int(1) - [u"not_null"]=> + [%u|b%"not_null"]=> int(0) - [u"primary_key"]=> + [%u|b%"primary_key"]=> int(0) - [u"multiple_key"]=> + [%u|b%"multiple_key"]=> int(0) - [u"unique_key"]=> + [%u|b%"unique_key"]=> int(0) - [u"numeric"]=> + [%u|b%"numeric"]=> int(1) - [u"blob"]=> + [%u|b%"blob"]=> int(0) - [u"type"]=> - unicode(3) "int" - [u"unsigned"]=> + [%u|b%"type"]=> + %unicode|string%(3) "int" + [%u|b%"unsigned"]=> int(0) - [u"zerofill"]=> + [%u|b%"zerofill"]=> int(0) } +Fetch field from mysql_list_fields result set. object(stdClass)#%d (13) { - [u"name"]=> - unicode(2) "id" - [u"table"]=> - unicode(4) "test" - [u"def"]=> - unicode(1) "1" - [u"max_length"]=> + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(1) "1" + [%u|b%"max_length"]=> int(0) - [u"not_null"]=> + [%u|b%"not_null"]=> int(0) - [u"primary_key"]=> + [%u|b%"primary_key"]=> int(0) - [u"multiple_key"]=> + [%u|b%"multiple_key"]=> int(0) - [u"unique_key"]=> + [%u|b%"unique_key"]=> int(0) - [u"numeric"]=> + [%u|b%"numeric"]=> int(1) - [u"blob"]=> + [%u|b%"blob"]=> int(0) - [u"type"]=> - unicode(3) "int" - [u"unsigned"]=> + [%u|b%"type"]=> + %unicode|string%(3) "int" + [%u|b%"unsigned"]=> int(0) - [u"zerofill"]=> + [%u|b%"zerofill"]=> int(0) } done! diff --git a/ext/mysql/tests/mysql_fetch_lengths.phpt b/ext/mysql/tests/mysql_fetch_lengths.phpt index 4b181765b..4793e2649 100644 --- a/ext/mysql/tests/mysql_fetch_lengths.phpt +++ b/ext/mysql/tests/mysql_fetch_lengths.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_fetch_lengths() --SKIPIF-- - --FILE-- @@ -34,6 +34,10 @@ var_dump(mysql_fetch_lengths($res)); mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(2) { [0]=> diff --git a/ext/mysql/tests/mysql_fetch_object.phpt b/ext/mysql/tests/mysql_fetch_object.phpt index cc20f738b..c11631e04 100644 --- a/ext/mysql/tests/mysql_fetch_object.phpt +++ b/ext/mysql/tests/mysql_fetch_object.phpt @@ -77,91 +77,26 @@ var_dump(mysql_fetch_object($res, 'this_class_does_not_exist')); mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- object(stdClass)#%d (2) { - ["ID"]=> - string(1) "1" - ["label"]=> - string(1) "a" -} -object(mysql_fetch_object_test)#%d (4) { - ["a"]=> - NULL - ["b"]=> - NULL - ["ID"]=> - string(1) "2" - ["label"]=> - string(1) "b" -} - -Warning: Missing argument 1 for mysql_fetch_object_construct::__construct() in %s on line %d - -Warning: Missing argument 2 for mysql_fetch_object_construct::__construct() in %s on line %d - -Notice: Undefined variable: a in %s on line %d - -Notice: Undefined variable: b in %s on line %d -object(mysql_fetch_object_construct)#%d (4) { - ["a"]=> - NULL - ["b"]=> - NULL - ["ID"]=> - string(1) "3" - ["label"]=> - string(1) "c" -} - -Warning: Missing argument 2 for mysql_fetch_object_construct::__construct() in %s on line %d - -Notice: Undefined variable: b in %s on line %d -object(mysql_fetch_object_construct)#%d (4) { - ["a"]=> - string(1) "a" - ["b"]=> - NULL - ["ID"]=> - string(1) "4" - ["label"]=> - string(1) "d" -} -object(mysql_fetch_object_construct)#%d (4) { - ["a"]=> - string(1) "a" - ["b"]=> - string(1) "b" - ["ID"]=> - string(1) "5" - ["label"]=> - string(1) "e" -} -bool(false) -bool(false) -bool(false) -bool(false) -bool(false) - -Warning: mysql_fetch_object(): %d is not a valid MySQL result resource in %s on line %d -bool(false) - -Fatal error: Class 'this_class_does_not_exist' not found in %s on line %d ---UEXPECTF-- -object(stdClass)#%d (2) { - [u"ID"]=> - unicode(1) "1" - [u"label"]=> - unicode(1) "a" + [%u|b%"ID"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" } object(mysql_fetch_object_test)#%d (4) { - [u"a"]=> + [%u|b%"a"]=> NULL - [u"b"]=> + [%u|b%"b"]=> NULL - [u"ID"]=> - unicode(1) "2" - [u"label"]=> - unicode(1) "b" + [%u|b%"ID"]=> + %unicode|string%(1) "2" + [%u|b%"label"]=> + %unicode|string%(1) "b" } Warning: Missing argument 1 for mysql_fetch_object_construct::__construct() in %s on line %d @@ -172,38 +107,38 @@ Notice: Undefined variable: a in %s on line %d Notice: Undefined variable: b in %s on line %d object(mysql_fetch_object_construct)#%d (4) { - [u"a"]=> + [%u|b%"a"]=> NULL - [u"b"]=> + [%u|b%"b"]=> NULL - [u"ID"]=> - unicode(1) "3" - [u"label"]=> - unicode(1) "c" + [%u|b%"ID"]=> + %unicode|string%(1) "3" + [%u|b%"label"]=> + %unicode|string%(1) "c" } Warning: Missing argument 2 for mysql_fetch_object_construct::__construct() in %s on line %d Notice: Undefined variable: b in %s on line %d object(mysql_fetch_object_construct)#%d (4) { - [u"a"]=> - unicode(1) "a" - [u"b"]=> + [%u|b%"a"]=> + %unicode|string%(1) "a" + [%u|b%"b"]=> NULL - [u"ID"]=> - unicode(1) "4" - [u"label"]=> - unicode(1) "d" + [%u|b%"ID"]=> + %unicode|string%(1) "4" + [%u|b%"label"]=> + %unicode|string%(1) "d" } object(mysql_fetch_object_construct)#%d (4) { - [u"a"]=> - unicode(1) "a" - [u"b"]=> - unicode(1) "b" - [u"ID"]=> - unicode(1) "5" - [u"label"]=> - unicode(1) "e" + [%u|b%"a"]=> + %unicode|string%(1) "a" + [%u|b%"b"]=> + %unicode|string%(1) "b" + [%u|b%"ID"]=> + %unicode|string%(1) "5" + [%u|b%"label"]=> + %unicode|string%(1) "e" } bool(false) bool(false) diff --git a/ext/mysql/tests/mysql_fetch_row.phpt b/ext/mysql/tests/mysql_fetch_row.phpt index d9fff217a..8d6b9585b 100644 --- a/ext/mysql/tests/mysql_fetch_row.phpt +++ b/ext/mysql/tests/mysql_fetch_row.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_fetch_row() --SKIPIF-- - --FILE-- @@ -36,31 +36,21 @@ var_dump(mysql_fetch_row($res)); mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- [004] array(2) { [0]=> - string(1) "1" - [1]=> - string(1) "a" -} -[005] -bool(false) - -Warning: mysql_fetch_row(): %d is not a valid MySQL result resource in %s on line %d -bool(false) -done! ---UEXPECTF-- -[004] -array(2) { - [0]=> - unicode(1) "1" + %unicode|string%(1) "1" [1]=> - unicode(1) "a" + %unicode|string%(1) "a" } [005] bool(false) Warning: mysql_fetch_row(): %d is not a valid MySQL result resource in %s on line %d bool(false) -done! +done! \ No newline at end of file diff --git a/ext/mysql/tests/mysql_field_flags.phpt b/ext/mysql/tests/mysql_field_flags.phpt index c609123cc..6489affc1 100644 --- a/ext/mysql/tests/mysql_field_flags.phpt +++ b/ext/mysql/tests/mysql_field_flags.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_field_flags() --SKIPIF-- - --FILE-- @@ -32,7 +32,7 @@ if (false !== ($tmp = mysql_field_flags($res, -1))) if (!is_string($tmp = mysql_field_flags($res, 0)) || empty($tmp)) printf("[006] Expecting non empty string, got %s/%s\n", gettype($tmp), $tmp); -if (ini_get('unicode.semantics') && !is_unicode($tmp)) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp)) { printf("[007] Check the unicode support!\n"); var_inspect($tmp); } @@ -53,11 +53,11 @@ $tables = array( 'label' => array(($version < 500) ? 'multiple_key' : 'unique_key') ), 'labela INT, label2 CHAR(1), KEY keyname (labela, label2)' => array( - array('labela, label2', '1, "a"'), + array('labela, label2', "1, 'a'"), 'labela' => array('multiple_key'), ), 'label1 BLOB' => array( - array('label1', '"blob"'), + array('label1', "'blob'"), 'label1' => array('blob', 'binary'), ), 'label1 INT UNSIGNED' => array( @@ -70,15 +70,15 @@ $tables = array( 'unsigned'), ), 'label1 ENUM("a", "b")' => array( - array('label1', '"a"'), + array('label1', "'a'"), 'label1' => array('enum'), ), 'label1 SET("a", "b")' => array( - array('label1', '"a"'), + array('label1', "'a'"), 'label1' => array('set'), ), 'label1 TIMESTAMP' => array( - array('label1', sprintf('"%s"', @date("Y-m-d H:i:s"))), + array('label1', sprintf("'%s'", @date("Y-m-d H:i:s"))), 'label1' => array( 'timestamp', 'unsigned', @@ -135,6 +135,10 @@ var_dump(mysql_field_flags($res, 0)); mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysql_field_flags() expects exactly 2 parameters, 1 given in %s on line %d diff --git a/ext/mysql/tests/mysql_field_len.phpt b/ext/mysql/tests/mysql_field_len.phpt index a81e36a68..a740c6243 100644 --- a/ext/mysql/tests/mysql_field_len.phpt +++ b/ext/mysql/tests/mysql_field_len.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_field_len() --SKIPIF-- - --FILE-- @@ -42,6 +42,10 @@ var_dump(mysql_field_len($res, 0)); mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysql_field_len() expects exactly 2 parameters, 1 given in %s on line %d diff --git a/ext/mysql/tests/mysql_field_name.phpt b/ext/mysql/tests/mysql_field_name.phpt index aeb516c8b..c87ac188f 100644 --- a/ext/mysql/tests/mysql_field_name.phpt +++ b/ext/mysql/tests/mysql_field_name.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_field_name() --SKIPIF-- - --FILE-- @@ -41,22 +41,15 @@ var_dump(mysql_field_name($res, 0)); mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysql_field_name() expects exactly 2 parameters, 1 given in %s on line %d Warning: mysql_field_name(): Field -1 is invalid for MySQL result index %d in %s on line %d -string(2) "id" - -Warning: mysql_field_name(): Field 2 is invalid for MySQL result index %d in %s on line %d - -Warning: mysql_field_name(): %d is not a valid MySQL result resource in %s on line %d -bool(false) -done! ---UEXPECTF-- -Warning: Wrong parameter count for mysql_field_name() in %s on line %d - -Warning: mysql_field_name(): Field -1 is invalid for MySQL result index %d in %s on line %d -unicode(2) "id" +%unicode|string%(2) "id" Warning: mysql_field_name(): Field 2 is invalid for MySQL result index %d in %s on line %d diff --git a/ext/mysql/tests/mysql_field_seek.phpt b/ext/mysql/tests/mysql_field_seek.phpt index e5105d984..7e8b313c8 100644 --- a/ext/mysql/tests/mysql_field_seek.phpt +++ b/ext/mysql/tests/mysql_field_seek.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_field_seek() --SKIPIF-- - --FILE-- @@ -39,190 +39,97 @@ var_dump(mysql_field_seek($res, 0)); mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysql_field_seek(): Field -1 is invalid for MySQL result index %d in %s on line %d bool(false) object(stdClass)#%d (13) { - ["name"]=> - string(2) "id" - ["table"]=> - string(4) "test" - ["def"]=> - string(0) "" - ["max_length"]=> - int(1) - ["not_null"]=> - int(1) - ["primary_key"]=> - int(1) - ["multiple_key"]=> - int(0) - ["unique_key"]=> - int(0) - ["numeric"]=> - int(1) - ["blob"]=> - int(0) - ["type"]=> - string(3) "int" - ["unsigned"]=> - int(0) - ["zerofill"]=> - int(0) -} -bool(true) -object(stdClass)#%d (13) { - ["name"]=> - string(2) "id" - ["table"]=> - string(4) "test" - ["def"]=> - string(0) "" - ["max_length"]=> - int(1) - ["not_null"]=> - int(1) - ["primary_key"]=> - int(1) - ["multiple_key"]=> - int(0) - ["unique_key"]=> - int(0) - ["numeric"]=> - int(1) - ["blob"]=> - int(0) - ["type"]=> - string(3) "int" - ["unsigned"]=> - int(0) - ["zerofill"]=> - int(0) -} -bool(true) -object(stdClass)#%d (13) { - ["name"]=> - string(5) "label" - ["table"]=> - string(4) "test" - ["def"]=> - string(0) "" - ["max_length"]=> - int(1) - ["not_null"]=> - int(0) - ["primary_key"]=> - int(0) - ["multiple_key"]=> - int(0) - ["unique_key"]=> - int(0) - ["numeric"]=> - int(0) - ["blob"]=> - int(0) - ["type"]=> - string(6) "string" - ["unsigned"]=> - int(0) - ["zerofill"]=> - int(0) -} - -Warning: mysql_field_seek(): Field %d is invalid for MySQL result index %d in %s on line %d -bool(false) -bool(false) - -Warning: mysql_field_seek(): %d is not a valid MySQL result resource in %s on line %d -bool(false) -done! ---UEXPECTF-- -Warning: mysql_field_seek(): Field -1 is invalid for MySQL result index %d in %s on line %d -bool(false) -object(stdClass)#%d (13) { - [u"name"]=> - unicode(2) "id" - [u"table"]=> - unicode(4) "test" - [u"def"]=> - unicode(0) "" - [u"max_length"]=> + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> int(1) - [u"not_null"]=> + [%u|b%"not_null"]=> int(1) - [u"primary_key"]=> + [%u|b%"primary_key"]=> int(1) - [u"multiple_key"]=> + [%u|b%"multiple_key"]=> int(0) - [u"unique_key"]=> + [%u|b%"unique_key"]=> int(0) - [u"numeric"]=> + [%u|b%"numeric"]=> int(1) - [u"blob"]=> + [%u|b%"blob"]=> int(0) - [u"type"]=> - unicode(3) "int" - [u"unsigned"]=> + [%u|b%"type"]=> + %unicode|string%(3) "int" + [%u|b%"unsigned"]=> int(0) - [u"zerofill"]=> + [%u|b%"zerofill"]=> int(0) } bool(true) object(stdClass)#%d (13) { - [u"name"]=> - unicode(2) "id" - [u"table"]=> - unicode(4) "test" - [u"def"]=> - unicode(0) "" - [u"max_length"]=> + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> int(1) - [u"not_null"]=> + [%u|b%"not_null"]=> int(1) - [u"primary_key"]=> + [%u|b%"primary_key"]=> int(1) - [u"multiple_key"]=> + [%u|b%"multiple_key"]=> int(0) - [u"unique_key"]=> + [%u|b%"unique_key"]=> int(0) - [u"numeric"]=> + [%u|b%"numeric"]=> int(1) - [u"blob"]=> + [%u|b%"blob"]=> int(0) - [u"type"]=> - unicode(3) "int" - [u"unsigned"]=> + [%u|b%"type"]=> + %unicode|string%(3) "int" + [%u|b%"unsigned"]=> int(0) - [u"zerofill"]=> + [%u|b%"zerofill"]=> int(0) } bool(true) object(stdClass)#%d (13) { - [u"name"]=> - unicode(5) "label" - [u"table"]=> - unicode(4) "test" - [u"def"]=> - unicode(0) "" - [u"max_length"]=> + [%u|b%"name"]=> + %unicode|string%(5) "label" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> int(1) - [u"not_null"]=> + [%u|b%"not_null"]=> int(0) - [u"primary_key"]=> + [%u|b%"primary_key"]=> int(0) - [u"multiple_key"]=> + [%u|b%"multiple_key"]=> int(0) - [u"unique_key"]=> + [%u|b%"unique_key"]=> int(0) - [u"numeric"]=> + [%u|b%"numeric"]=> int(0) - [u"blob"]=> + [%u|b%"blob"]=> int(0) - [u"type"]=> - unicode(6) "string" - [u"unsigned"]=> + [%u|b%"type"]=> + %unicode|string%(6) "string" + [%u|b%"unsigned"]=> int(0) - [u"zerofill"]=> + [%u|b%"zerofill"]=> int(0) } diff --git a/ext/mysql/tests/mysql_field_table.phpt b/ext/mysql/tests/mysql_field_table.phpt index 5e552f8ee..707d1df98 100644 --- a/ext/mysql/tests/mysql_field_table.phpt +++ b/ext/mysql/tests/mysql_field_table.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_field_table() --SKIPIF-- - --FILE-- @@ -41,22 +41,15 @@ var_dump(mysql_field_table($res, 0)); mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysql_field_table() expects exactly 2 parameters, 1 given in %s on line %d Warning: mysql_field_table(): Field -1 is invalid for MySQL result index %d in %s on line %d -string(4) "test" - -Warning: mysql_field_table(): Field 2 is invalid for MySQL result index %d in %s on line %d - -Warning: mysql_field_table(): %d is not a valid MySQL result resource in %s on line %d -bool(false) -done! ---UEXPECTF-- -Warning: Wrong parameter count for mysql_field_table() in %s on line %d - -Warning: mysql_field_table(): Field -1 is invalid for MySQL result index %d in %s on line %d -unicode(4) "test" +%unicode|string%(4) "test" Warning: mysql_field_table(): Field 2 is invalid for MySQL result index %d in %s on line %d diff --git a/ext/mysql/tests/mysql_field_type.phpt b/ext/mysql/tests/mysql_field_type.phpt index 2a72e2de8..c737b4e3f 100644 --- a/ext/mysql/tests/mysql_field_type.phpt +++ b/ext/mysql/tests/mysql_field_type.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_field_type() --SKIPIF-- - --FILE-- @@ -41,22 +41,15 @@ var_dump(mysql_field_type($res, 0)); mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysql_field_type() expects exactly 2 parameters, 1 given in %s on line %d Warning: mysql_field_type(): Field -1 is invalid for MySQL result index %d in %s on line %d -string(3) "int" - -Warning: mysql_field_type(): Field 2 is invalid for MySQL result index %d in %s on line %d - -Warning: mysql_field_type(): %d is not a valid MySQL result resource in %s on line %d -bool(false) -done! ---UEXPECTF-- -Warning: Wrong parameter count for mysql_field_type() in %s on line %d - -Warning: mysql_field_type(): Field -1 is invalid for MySQL result index %d in %s on line %d -unicode(3) "int" +%unicode|string%(3) "int" Warning: mysql_field_type(): Field 2 is invalid for MySQL result index %d in %s on line %d diff --git a/ext/mysql/tests/mysql_free_result.phpt b/ext/mysql/tests/mysql_free_result.phpt index 5a02ecff3..fe132d8c2 100644 --- a/ext/mysql/tests/mysql_free_result.phpt +++ b/ext/mysql/tests/mysql_free_result.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_free_result() --SKIPIF-- - --FILE-- @@ -39,6 +39,10 @@ if ($tmp = sys_get_temp_dir()) { mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- bool(true) diff --git a/ext/mysql/tests/mysql_get_client_info.phpt b/ext/mysql/tests/mysql_get_client_info.phpt index 2f8c62c91..95de0ad5e 100644 --- a/ext/mysql/tests/mysql_get_client_info.phpt +++ b/ext/mysql/tests/mysql_get_client_info.phpt @@ -8,7 +8,7 @@ include "connect.inc"; if (!is_string($info = mysql_get_client_info()) || ('' === $info)) printf("[001] Expecting string/any_non_empty, got %s/%s\n", gettype($info), $info); -if (ini_get('unicode.semantics') && !is_unicode($info)) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($info)) { printf("[002] Expecting Unicode!\n"); var_inspect($info); } diff --git a/ext/mysql/tests/mysql_get_host_info.phpt b/ext/mysql/tests/mysql_get_host_info.phpt index d0ee6803a..443910c31 100644 --- a/ext/mysql/tests/mysql_get_host_info.phpt +++ b/ext/mysql/tests/mysql_get_host_info.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_get_host_info() --SKIPIF-- - --FILE-- @@ -25,7 +25,7 @@ if ($def_info !== $info) { var_dump($info); } -if (ini_get('unicode.semantics') && !is_unicode($info)) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($info)) { printf("[005] Expecting Unicode error message!\n"); var_inspect($info); } @@ -36,5 +36,9 @@ if (!is_null($tmp = @mysql_get_host_info($link, "too many arguments"))) { print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysql/tests/mysql_get_proto_info.phpt b/ext/mysql/tests/mysql_get_proto_info.phpt index 3dae99314..043fb6204 100644 --- a/ext/mysql/tests/mysql_get_proto_info.phpt +++ b/ext/mysql/tests/mysql_get_proto_info.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_get_proto_info() --SKIPIF-- - --FILE-- @@ -26,5 +26,9 @@ if (NULL !== ($tmp = @mysql_get_proto_info('too many', 'arguments'))) print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysql/tests/mysql_get_server_info.phpt b/ext/mysql/tests/mysql_get_server_info.phpt index 83b9c35f4..e806335e2 100644 --- a/ext/mysql/tests/mysql_get_server_info.phpt +++ b/ext/mysql/tests/mysql_get_server_info.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_get_server_info() --SKIPIF-- - --FILE-- @@ -25,7 +25,7 @@ if ($def_info !== $info) { var_dump($info); } -if (ini_get('unicode.semantics') && !is_unicode($info)) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($info)) { printf("[005] Expecting Unicode error message!\n"); var_inspect($info); } diff --git a/ext/mysql/tests/mysql_info.phpt b/ext/mysql/tests/mysql_info.phpt index 6cb058f18..464578c8a 100644 --- a/ext/mysql/tests/mysql_info.phpt +++ b/ext/mysql/tests/mysql_info.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_info() --SKIPIF-- - --FILE-- @@ -16,13 +16,13 @@ if (NULL !== ($tmp = @mysql_info(NULL))) printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); require "table.inc"; -if (!$res = mysql_query('INSERT INTO test(id, label) VALUES (100, "a")', $link)) +if (!$res = mysql_query("INSERT INTO test(id, label) VALUES (100, 'a')", $link)) printf("[003] [%d] %s\n", mysql_errno($link), mysql_error($link)); if (false !== ($tmp = mysql_info($link))) printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); -if (!$res = mysql_query('INSERT INTO test(id, label) VALUES (101, "a"), (102, "b")', $link)) +if (!$res = mysql_query("INSERT INTO test(id, label) VALUES (101, 'a'), (102, 'b')", $link)) printf("[005] [%d] %s\n", mysql_errno($link), mysql_error($link)); if (!is_string($tmp = mysql_info($link)) || ('' == $tmp)) @@ -40,13 +40,13 @@ if (!$res = mysql_query('ALTER TABLE test MODIFY label CHAR(2)', $link)) if (!is_string($tmp = mysql_info($link)) || ('' == $tmp)) printf("[010] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); -if (!$res = mysql_query('UPDATE test SET label = "b" WHERE id >= 100', $link)) +if (!$res = mysql_query("UPDATE test SET label = 'b' WHERE id >= 100", $link)) printf("[011] [%d] %s\n", mysql_errno($link), mysql_error($link)); if (!is_string($tmp = mysql_info($link)) || ('' == $tmp)) printf("[012] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); -if (ini_get('unicode.semantics') && !is_unicode($tmp)) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp)) { printf("[013] Expecting Unicode!\n"); var_inspect($info); } @@ -65,5 +65,9 @@ if ($def_tmp !== $tmp) { print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysql/tests/mysql_insert_id.phpt b/ext/mysql/tests/mysql_insert_id.phpt index 832f370b5..678245c2c 100644 --- a/ext/mysql/tests/mysql_insert_id.phpt +++ b/ext/mysql/tests/mysql_insert_id.phpt @@ -1,9 +1,10 @@ --TEST-- mysql_insert_id() --SKIPIF-- - --FILE-- +--CLEAN-- + --EXPECTF-- Warning: mysql_insert_id(): %d is not a valid MySQL-Link resource in %s on line %d bool(false) diff --git a/ext/mysql/tests/mysql_list_dbs.phpt b/ext/mysql/tests/mysql_list_dbs.phpt index 7c8828d7a..3e12ce550 100644 --- a/ext/mysql/tests/mysql_list_dbs.phpt +++ b/ext/mysql/tests/mysql_list_dbs.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_list_dbs() --SKIPIF-- - --FILE-- @@ -27,7 +27,7 @@ if (!$num = mysql_num_rows($res)) printf("[004] Empty database list? [%d] %s\n", mysql_errno($link), mysql_error($link)); $row = mysql_fetch_array($res, MYSQL_NUM); -if (ini_get('unicode.semantics') && !is_unicode($row[0])) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($row[0])) { printf("[005] Check for unicode support\n"); var_inspect($row); } @@ -46,5 +46,9 @@ mysql_close($link); print "done!\n"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysql/tests/mysql_list_fields.phpt b/ext/mysql/tests/mysql_list_fields.phpt index 87b3cf6b8..e0b3fd5e3 100644 --- a/ext/mysql/tests/mysql_list_fields.phpt +++ b/ext/mysql/tests/mysql_list_fields.phpt @@ -1,33 +1,79 @@ --TEST-- mysql_list_fields() --SKIPIF-- - --FILE-- +--CLEAN-- + --EXPECTF-- +[006] [%d] %s +bool(false) +Field Offset 0 +mysql_field_flags()%s +mysql_field_len(): 11 +mysql_field_name(): id +mysql_field_type(): int +Field Offset 1 +mysql_field_flags()%s +mysql_field_len(): 1 +mysql_field_name(): label +mysql_field_type(): string done! diff --git a/ext/mysql/tests/mysql_list_processes.phpt b/ext/mysql/tests/mysql_list_processes.phpt index 9cf51db61..b0c71ad1b 100644 --- a/ext/mysql/tests/mysql_list_processes.phpt +++ b/ext/mysql/tests/mysql_list_processes.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_list_processes() --SKIPIF-- - --FILE-- @@ -24,7 +24,7 @@ if (!$num = mysql_num_rows($res)) printf("[003] Empty process list? [%d] %s\n", mysql_errno($link), mysql_error($link)); $row = mysql_fetch_array($res, MYSQL_NUM); -if (ini_get('unicode.semantics') && !is_unicode($row[0])) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($row[0])) { printf("[004] Check for unicode support\n"); var_inspect($row); } @@ -38,7 +38,7 @@ if (!$num = mysql_num_rows($res)) printf("[006] Empty process list? [%d] %s\n", mysql_errno(), mysql_error()); $row = mysql_fetch_array($res, MYSQL_NUM); -if (ini_get('unicode.semantics') && !is_unicode($row[0])) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($row[0])) { printf("[007] Check for unicode support\n"); var_inspect($row); } diff --git a/ext/mysql/tests/mysql_list_tables.phpt b/ext/mysql/tests/mysql_list_tables.phpt index 820ad378a..cf0b1a636 100644 --- a/ext/mysql/tests/mysql_list_tables.phpt +++ b/ext/mysql/tests/mysql_list_tables.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_list_tables() --SKIPIF-- - --FILE-- @@ -77,5 +77,9 @@ mysql_close($link); print "done!\n"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysql/tests/mysql_max_persistent.phpt b/ext/mysql/tests/mysql_max_persistent.phpt index 498b5c5d3..ac35cd178 100644 --- a/ext/mysql/tests/mysql_max_persistent.phpt +++ b/ext/mysql/tests/mysql_max_persistent.phpt @@ -4,15 +4,9 @@ mysql_[p]connect() - max_links/max_persistent +--CLEAN-- + --EXPECTF-- Warning: mysql_pconnect(): Too many open persistent links (1) in %s on line %d [020] Cannot connect using host '%s', user '%s', password '****', [0] 0 diff --git a/ext/mysql/tests/mysql_mysqlnd_read_timeout_long.phpt b/ext/mysql/tests/mysql_mysqlnd_read_timeout_long.phpt new file mode 100644 index 000000000..d54cb5070 --- /dev/null +++ b/ext/mysql/tests/mysql_mysqlnd_read_timeout_long.phpt @@ -0,0 +1,37 @@ +--TEST-- +mysqlnd.net_read_timeout > default_socket_timeout +--SKIPIF-- + +--INI-- +default_socket_timeout=1 +mysqlnd.net_read_timeout=12 +max_execution_time=12 +--FILE-- + +--EXPECTF-- +array(1) { + [%u|b%"SLEEP(6)"]=> + %unicode|string%(1) "0" +} +done! \ No newline at end of file diff --git a/ext/mysql/tests/mysql_num_fields.phpt b/ext/mysql/tests/mysql_num_fields.phpt index 3ec305ea2..0dad5f771 100644 --- a/ext/mysql/tests/mysql_num_fields.phpt +++ b/ext/mysql/tests/mysql_num_fields.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_num_fields() --SKIPIF-- - --FILE-- @@ -47,6 +47,10 @@ mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysql_num_fields(): %d is not a valid MySQL result resource in %s on line %d done! diff --git a/ext/mysql/tests/mysql_num_rows.phpt b/ext/mysql/tests/mysql_num_rows.phpt index d93b4e2ff..1f68b4d60 100644 --- a/ext/mysql/tests/mysql_num_rows.phpt +++ b/ext/mysql/tests/mysql_num_rows.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_num_rows() --SKIPIF-- - --FILE-- @@ -57,6 +57,10 @@ if ($res = mysql_query('SELECT COUNT(id) AS num FROM test', $link)) { mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysql_num_rows() expects parameter 1 to be resource, boolean given in %s on line %d diff --git a/ext/mysql/tests/mysql_pconn_disable.phpt b/ext/mysql/tests/mysql_pconn_disable.phpt index 9ec44234a..dfb04eeef 100644 --- a/ext/mysql/tests/mysql_pconn_disable.phpt +++ b/ext/mysql/tests/mysql_pconn_disable.phpt @@ -52,6 +52,10 @@ mysql.max_links=2 print "done!"; ?> +--CLEAN-- + --EXPECTF-- [001] Can connect to the server. [002] Can fetch data using persistent connection! Data = '1' diff --git a/ext/mysql/tests/mysql_pconn_kill.phpt b/ext/mysql/tests/mysql_pconn_kill.phpt index df863bb79..8543e39d6 100755 --- a/ext/mysql/tests/mysql_pconn_kill.phpt +++ b/ext/mysql/tests/mysql_pconn_kill.phpt @@ -1,7 +1,7 @@ --TEST-- mysql_pconnect() - killing persitent connection --SKIPIF-- - @@ -24,7 +24,7 @@ mysql.max_persistent=2 printf("[001] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $myhost, $user, $db, $port, $socket); mysql_select_db($db, $plink); - + $pthread_id = mysql_thread_id($plink); $thread_id = mysql_thread_id($link); @@ -40,8 +40,8 @@ mysql.max_persistent=2 printf("[003] Cannot find regular connection thread in process list, [%d] %s\n", mysql_errno($link), mysql_error($link)); if (!isset($processlist[$pthread_id])) printf("[004] Cannot find persistent connection thread in process list, [%d] %s\n", mysql_errno($link), mysql_error($link)); - - if (!mysql_query(sprintf("KILL %d", $pthread_id), $link)) + + if (!mysql_query(sprintf("KILL %d", $pthread_id), $link)) printf("[005] Cannot kill persistent connection thread, [%d] %s\n", mysql_errno($link), mysql_error($link)); while (1) { @@ -64,7 +64,7 @@ mysql.max_persistent=2 mysql_close($plink); - if (!($plink = mysql_pconnect($myhost, $user, $passwd))) + if (!($plink = mysql_pconnect($myhost, $user, $passwd))) printf("[009] Cannot create new persistent connection, [%d] %s\n", mysql_errno(), mysql_error()); mysql_select_db($db, $plink); @@ -82,7 +82,7 @@ mysql.max_persistent=2 printf("[012] Cannot connect to the server using host=%s/%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $myhost, $user, $db, $port, $socket); mysql_select_db($db, $link2); - if (!mysql_query(sprintf("KILL %d", $thread_id), $link2)) + if (!mysql_query(sprintf("KILL %d", $thread_id), $link2)) printf("[013] Cannot kill regular connection thread, [%d] %s\n", mysql_errno($link2), mysql_error($link2)); if (!($link = mysql_connect($myhost, $user, $passwd, true))) @@ -101,6 +101,10 @@ mysql.max_persistent=2 mysql_close($link2); print "done!"; ?> +--CLEAN-- + --EXPECTF-- bool(true) done! diff --git a/ext/mysql/tests/mysql_pconn_max_links.phpt b/ext/mysql/tests/mysql_pconn_max_links.phpt index b5b0a3a56..1d39e98b4 100644 --- a/ext/mysql/tests/mysql_pconn_max_links.phpt +++ b/ext/mysql/tests/mysql_pconn_max_links.phpt @@ -4,7 +4,7 @@ Persistent connections and mysql.max_persistent --INI-- -mysql.max_links=2 -mysql.max_persistent=1 +mysql.max_links=3 +mysql.max_persistent=2 mysql.allow_persistent=1 --FILE-- enabled'), 500); if (!preg_match('@Active Persistent Links\s+=>\s+(\d+)@ismU', $phpinfo, $matches)) - printf("[011] Cannot get # active persistent links from phpinfo()"); + printf("[012] Cannot get # active persistent links from phpinfo()\n"); $num_plinks_kill = $matches[1]; - if ($num_plinks_kill >= $num_plinks) - printf("[012] Statistics seems to be wrong, got %d active persistent links, expecting < %d links", + if ($num_plinks_kill > $num_plinks) + printf("[013] Statistics seems to be wrong, got %d active persistent links, expecting < %d links\n", $num_plinks_kill, $num_plinks); // The first connection has been closed, the last pconnect() was unable to connect -> no connection open // We must be able to connect because max_persistent limit has not been reached if (!$plink = mysql_pconnect($host, 'pcontest', 'newpass')) - printf("[013] Cannot connect using the second DB, [%d] %s\n", - mysql_errno(), mysql_error()); + die(sprintf("[014] Cannot connect using the second DB, [%d] %s\n", + mysql_errno(), mysql_error())); if (!mysql_select_db($db, $plink)) - printf("[014] [%d] %s\n", mysql_errno($plink), mysql_error($plink)); + printf("[015] [%d] %s\n", mysql_errno($plink), mysql_error($plink)); if (!$res = mysql_query('SELECT id, label FROM test WHERE id = 1', $plink)) - printf("[015] Cannot run query on persistent connection of second DB user, [%d] %s\n", + printf("[016] Cannot run query on persistent connection of second DB user, [%d] %s\n", mysql_errno($plink), mysql_error($plink)); if (!$row = mysql_fetch_assoc($res)) - printf("[016] Cannot run fetch result, [%d] %s\n", + printf("[017] Cannot run fetch result, [%d] %s\n", mysql_errno($plink), mysql_error($plink)); mysql_free_result($res); var_dump($row); - mysql_query('REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest', $link); - mysql_query('DROP USER pcontest', $link); + mysql_query(sprintf('REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@"%s"', mysql_real_escape_string($host, $link)), $link); + mysql_query(sprintf('DROP USER pcontest@"%s"', mysql_real_escape_string($host, $link)), $link); mysql_close($link); print "done!"; ?> ---EXPECTF-- -array(2) { - ["id"]=> - string(1) "1" - ["label"]=> - string(1) "a" -} -array(2) { - ["id"]=> - string(1) "1" - ["label"]=> - string(1) "a" +--CLEAN-- + +--EXPECTF-- array(2) { - [u"id"]=> - unicode(1) "1" - [u"label"]=> - unicode(1) "a" + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" } array(2) { - [u"id"]=> - unicode(1) "1" - [u"label"]=> - unicode(1) "a" + [%u|b%"id"]=> + %unicode|string%(1) "1" + [%u|b%"label"]=> + %unicode|string%(1) "a" } done! diff --git a/ext/mysql/tests/mysql_phpinfo.phpt b/ext/mysql/tests/mysql_phpinfo.phpt index 1778e48d2..a57e42e6b 100644 --- a/ext/mysql/tests/mysql_phpinfo.phpt +++ b/ext/mysql/tests/mysql_phpinfo.phpt @@ -73,4 +73,4 @@ if ($IS_MYSQLND) { print "done!"; ?> --EXPECTF-- -done! \ No newline at end of file +done! diff --git a/ext/mysql/tests/mysql_ping.phpt b/ext/mysql/tests/mysql_ping.phpt index 2e4130e33..edf18c439 100644 --- a/ext/mysql/tests/mysql_ping.phpt +++ b/ext/mysql/tests/mysql_ping.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_ping() --SKIPIF-- - --FILE-- @@ -37,6 +37,10 @@ if (false !== ($tmp = mysql_ping($link))) print "done!"; ?> +--CLEAN-- + --EXPECTF-- bool(true) bool(true) diff --git a/ext/mysql/tests/mysql_query.phpt b/ext/mysql/tests/mysql_query.phpt index d1d4dfb8e..a5978a6c1 100644 --- a/ext/mysql/tests/mysql_query.phpt +++ b/ext/mysql/tests/mysql_query.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_query() --SKIPIF-- - --FILE-- @@ -26,26 +26,26 @@ if (NULL !== ($tmp = @mysql_query("SELECT 1 AS a", $link, "foo"))) if (false !== ($tmp = mysql_query('THIS IS NOT SQL', $link))) printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); -if (false !== ($tmp = mysql_query('SELECT "this is sql but with backslash g"\g', $link))) +if (false !== ($tmp = mysql_query("SELECT 'this is sql but with backslash g'\g", $link))) printf("[005] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); if ((0 === mysql_errno($link)) || ('' == mysql_error($link))) printf("[006] mysql_errno()/mysql_error should return some error\n"); -if (!$res = mysql_query('SELECT "this is sql but with semicolon" AS valid ; ', $link)) +if (!$res = mysql_query("SELECT 'this is sql but with semicolon' AS valid ; ", $link)) printf("[007] [%d] %s\n", mysql_errno($link), mysql_error($link)); var_dump(mysql_fetch_assoc($res)); mysql_free_result($res); -if (!$res = mysql_query('SELECT "a" AS ""', $link)) +if (!$res = mysql_query("SELECT 'a' AS ''", $link)) printf("[007a] [%d] %s\n", mysql_errno($link), mysql_error($link)); var_dump($tmp = mysql_fetch_assoc($res)); var_dump($tmp[""]); mysql_free_result($res); -if (false !== ($res = mysql_query('SELECT "this is sql but with semicolon" AS valid ; SHOW VARIABLES', $link))) +if (false !== ($res = mysql_query("SELECT 'this is sql but with semicolon' AS valid ; SHOW VARIABLES", $link))) printf("[008] [%d] %s\n", mysql_errno($link), mysql_error($link)); if (mysql_query('DROP PROCEDURE IF EXISTS p', $link)) { @@ -58,7 +58,7 @@ if (mysql_query('DROP PROCEDURE IF EXISTS p', $link)) { printf("[009] Result seems wrong, dumping\n"); var_dump($tmp); } - if (ini_get('unicode.semantics') && !is_unicode($tmp['p_version'])) { + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp['p_version'])) { printf("[010] Expecting unicode string, dumping\n"); var_dump($tmp); } @@ -75,7 +75,7 @@ if (mysql_query('DROP PROCEDURE IF EXISTS p', $link)) { printf("[012] Result seems wrong, dumping\n"); var_dump($tmp); } - if (ini_get('unicode.semantics') && !is_unicode($tmp['f_version'])) { + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp['f_version'])) { printf("[013] Expecting unicode string, dumping\n"); var_dump($tmp); } @@ -92,29 +92,36 @@ if (false !== ($tmp = mysql_query("SELECT id FROM test", $link))) print "done!"; ?> ---EXPECTF-- -array(1) { - ["valid"]=> - string(30) "this is sql but with semicolon" +--CLEAN-- + - string(1) "a" + +if (!mysql_query('DROP TABLE IF EXISTS test', $link)) { + printf("[clean] Failed to drop test table: [%d] %s\n", mysql_errno($link), mysql_error($link)); } -string(1) "a" -Warning: mysql_query(): %d is not a valid MySQL-Link resource in %s on line %d -done! ---UEXPECTF-- +/* MySQL server may not support this - ignore errors */ +@mysql_query('DROP PROCEDURE IF EXISTS p', $link); +@mysql_query('DROP FUNCTION IF EXISTS f', $link); + +mysql_close($link); +?> +--EXPECTF-- array(1) { - [u"valid"]=> - unicode(30) "this is sql but with semicolon" + [%u|b%"valid"]=> + %unicode|string%(30) "this is sql but with semicolon" } array(1) { - [u""]=> - unicode(1) "a" + [%u|b%""]=> + %unicode|string%(1) "a" } -unicode(1) "a" +%unicode|string%(1) "a" Warning: mysql_query(): %d is not a valid MySQL-Link resource in %s on line %d done! diff --git a/ext/mysql/tests/mysql_query_load_data_openbasedir.phpt b/ext/mysql/tests/mysql_query_load_data_openbasedir.phpt index 9561ece70..577ede375 100644 --- a/ext/mysql/tests/mysql_query_load_data_openbasedir.phpt +++ b/ext/mysql/tests/mysql_query_load_data_openbasedir.phpt @@ -52,7 +52,7 @@ if (file_exists('./simple.csv')) if (!$fp = fopen('./simple.csv', 'w')) printf("[003] Cannot open CSV file\n"); -if (ini_get('unicode.semantics')) { +if (version_compare(PHP_VERSION, '5.9.9', '>') >= 0) { if (!fwrite($fp, (binary)"'97';'x';\n") || !fwrite($fp, (binary)"'98';'y';\n") || !fwrite($fp, (binary)"99;'z';\n")) { diff --git a/ext/mysql/tests/mysql_real_escape_string.phpt b/ext/mysql/tests/mysql_real_escape_string.phpt index 511da068b..2789ad276 100644 --- a/ext/mysql/tests/mysql_real_escape_string.phpt +++ b/ext/mysql/tests/mysql_real_escape_string.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_real_escape_string() --SKIPIF-- - --FILE-- @@ -33,20 +33,11 @@ assert($tmp === mysql_real_escape_string("foo" . chr(0) . "bar")); print "done!"; ?> --EXPECTF-- -string(31) "Am I a unicode string in PHP 6?" -string(2) "\\" -string(2) "\"" -string(2) "\'" -string(2) "\n" -string(2) "\r" -string(8) "foo\0bar" +%unicode|string%(31) "Am I a unicode string in PHP 6?" +%unicode|string%(2) "\\" +%unicode|string%(2) "\"" +%unicode|string%(2) "\'" +%unicode|string%(2) "\n" +%unicode|string%(2) "\r" +%unicode|string%(8) "foo\0bar" done! ---UEXPECTF-- -unicode(31) "Am I a unicode string in PHP 6?" -unicode(2) "\\" -unicode(2) "\"" -unicode(2) "\'" -unicode(2) "\n" -unicode(2) "\r" -unicode(8) "foo\0bar" -done! \ No newline at end of file diff --git a/ext/mysql/tests/mysql_result.phpt b/ext/mysql/tests/mysql_result.phpt index 4217b2e39..2c7c61854 100644 --- a/ext/mysql/tests/mysql_result.phpt +++ b/ext/mysql/tests/mysql_result.phpt @@ -60,6 +60,10 @@ var_dump(mysql_result($res, 0)); mysql_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysql_result(): Unable to jump to row -1 on MySQL result index %d in %s on line %d bool(false) @@ -73,12 +77,12 @@ bool(false) Warning: mysql_result(): Bad column offset specified in %s on line %d bool(false) valid fields -string(1) "1" -string(1) "a" -string(1) "1" -string(1) "1" -string(1) "a" -string(1) "a" +%unicode|string%(1) "1" +%unicode|string%(1) "a" +%unicode|string%(1) "1" +%unicode|string%(1) "1" +%unicode|string%(1) "a" +%unicode|string%(1) "a" some invalid fields Warning: mysql_result(): unknown not found in MySQL result index %d in %s on line %d @@ -93,7 +97,7 @@ bool(false) Warning: mysql_result(): _test. not found in MySQL result index %d in %s on line %d bool(false) _id -string(1) "1" +%unicode|string%(1) "1" _label string(2) "aa" _foo @@ -108,51 +112,3 @@ bool(false) Warning: mysql_result(): %d is not a valid MySQL result resource in %s on line %d bool(false) done! ---UEXPECTF-- -Warning: mysql_result(): Unable to jump to row -1 on MySQL result index %d in %s on line %d -bool(false) - -Warning: mysql_result(): Unable to jump to row 2 on MySQL result index %d in %s on line %d -bool(false) - -Warning: mysql_result(): Bad column offset specified in %s on line %d -bool(false) - -Warning: mysql_result(): Bad column offset specified in %s on line %d -bool(false) -valid fields -unicode(1) "1" -unicode(1) "a" -unicode(1) "1" -unicode(1) "1" -unicode(1) "a" -unicode(1) "a" -some invalid fields - -Warning: mysql_result(): unknown not found in MySQL result index %d in %s on line %d -bool(false) - -Warning: mysql_result(): _test. not found in MySQL result index %d in %s on line %d -bool(false) - -Warning: mysql_result(): not found in MySQL result index %d in %s on line %d -bool(false) - -Warning: mysql_result(): _test. not found in MySQL result index %d in %s on line %d -bool(false) -_id -unicode(1) "1" -_label -string(2) "aa" -_foo -NULL - -Warning: mysql_result(): test.id not found in MySQL result index %d in %s on line %d -bool(false) - -Warning: mysql_result(): test.label not found in MySQL result index %d in %s on line %d -bool(false) - -Warning: mysql_result(): %d is not a valid MySQL result resource in %s on line %d -bool(false) -done! \ No newline at end of file diff --git a/ext/mysql/tests/mysql_select_db.phpt b/ext/mysql/tests/mysql_select_db.phpt index 3391fa6e9..211e34222 100644 --- a/ext/mysql/tests/mysql_select_db.phpt +++ b/ext/mysql/tests/mysql_select_db.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_select_db() --SKIPIF-- - --FILE-- @@ -66,13 +66,7 @@ if (false !== ($tmp = mysql_select_db($db, $link))) print "done!\n"; ?> --EXPECTF-- -string(%d) "%s" -bool(false) - -Warning: mysql_select_db(): %d is not a valid MySQL-Link resource in %s on line %d -done! ---UEXPECTF-- -unicode(%d) "%s" +%unicode|string%(%d) "%s" bool(false) Warning: mysql_select_db(): %d is not a valid MySQL-Link resource in %s on line %d diff --git a/ext/mysql/tests/mysql_set_charset.phpt b/ext/mysql/tests/mysql_set_charset.phpt index 0fbff44e8..953323b49 100644 --- a/ext/mysql/tests/mysql_set_charset.phpt +++ b/ext/mysql/tests/mysql_set_charset.phpt @@ -4,6 +4,11 @@ mysql_set_charset() - STUB, function usage not recommended ') == 1) { + die('skip set character set not functional with PHP 6 (fomerly PHP 6 && unicode.semantics=On)'); +} + if (!function_exists('mysql_set_charset')) die("skip Function not available"); ?> @@ -33,7 +38,7 @@ if (!$link = my_mysql_connect($host, $user, $passwd, $db, $port, $socket)) /* unicode mode should throw a warning */ $tmp = mysql_set_charset('uFt8', $link); -if (ini_get('unicode.semantics')) +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) $expect = false; else $expect = true; @@ -54,6 +59,3 @@ print "done!"; ?> --EXPECTF-- done! ---UEXPECTF-- -Warning: mysql_set_charset(): Character set %s is not supported when running PHP with unicode.semantics=On. in %s on line %d -done! \ No newline at end of file diff --git a/ext/mysql/tests/mysql_stat.phpt b/ext/mysql/tests/mysql_stat.phpt index bc5be9540..288c53f06 100644 --- a/ext/mysql/tests/mysql_stat.phpt +++ b/ext/mysql/tests/mysql_stat.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_stat() --SKIPIF-- - --FILE-- @@ -25,7 +25,7 @@ if ((!is_string($stat = mysql_stat($link))) || ('' === $stat)) printf("[003] Expecting non empty string, got %s/'%s', [%d] %s\n", gettype($stat), $stat, mysql_errno($link), mysql_error($link)); -if (ini_get('unicode.semantics') && !is_unicode($stat)) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($stat)) { printf("[004] Expecting Unicode error message!\n"); var_inspect($stat); } diff --git a/ext/mysql/tests/mysql_tablename.phpt b/ext/mysql/tests/mysql_tablename.phpt index 684734a7d..2415e4fda 100644 --- a/ext/mysql/tests/mysql_tablename.phpt +++ b/ext/mysql/tests/mysql_tablename.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_tablename() --SKIPIF-- - --FILE-- @@ -45,18 +45,7 @@ print "done!"; Warning: mysql_tablename() expects at least 2 parameters, 1 given in %s on line %d Warning: mysql_tablename(): Unable to jump to row -1 on MySQL result index %d in %s on line %d -string(1) "1" - -Warning: mysql_tablename(): Unable to jump to row 2 on MySQL result index %d in %s on line %d - -Warning: mysql_tablename(): %d is not a valid MySQL result resource in %s on line %d -bool(false) -done! ---UEXPECTF-- -Warning: Wrong parameter count for mysql_tablename() in %s on line %d - -Warning: mysql_tablename(): Unable to jump to row -1 on MySQL result index %d in %s on line %d -unicode(1) "1" +%unicode|string%(1) "1" Warning: mysql_tablename(): Unable to jump to row 2 on MySQL result index %d in %s on line %d diff --git a/ext/mysql/tests/mysql_trace_mode.phpt b/ext/mysql/tests/mysql_trace_mode.phpt index af08e68b3..622f41306 100644 --- a/ext/mysql/tests/mysql_trace_mode.phpt +++ b/ext/mysql/tests/mysql_trace_mode.phpt @@ -10,12 +10,11 @@ mysql.trace_mode=1 error_reporting=E_ALL | E_NOTICE | E_STRICT --FILE-- +--CLEAN-- + --EXPECTF-- -Deprecated: mysql_db_query(): This function is deprecated; use mysql_query() instead%sin %s on line %d +Deprecated: mysql_db_query(): %s -Deprecated: mysql_escape_string(): This function is deprecated; use mysql_real_escape_string() instead. in %s on line %d +Deprecated: mysql_escape_string(): %s I don\'t mind character sets, do I?\n Warning: mysql_query(): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'BOGUS_SQL' at line 1 in %s on line %d done! diff --git a/ext/mysql/tests/mysql_unbuffered_query.phpt b/ext/mysql/tests/mysql_unbuffered_query.phpt index 6701ce52a..ad9b4fbc5 100644 --- a/ext/mysql/tests/mysql_unbuffered_query.phpt +++ b/ext/mysql/tests/mysql_unbuffered_query.phpt @@ -1,8 +1,8 @@ --TEST-- mysql_unbuffered_query() --SKIPIF-- - --FILE-- @@ -23,19 +23,19 @@ if (NULL !== ($tmp = @mysql_unbuffered_query("SELECT 1 AS a", $link, "foo"))) if (false !== ($tmp = mysql_unbuffered_query('THIS IS NOT SQL', $link))) printf("[003] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); -if (false !== ($tmp = mysql_unbuffered_query('SELECT "this is sql but with backslash g"\g', $link))) +if (false !== ($tmp = mysql_unbuffered_query("SELECT 'this is sql but with backslash g'\g", $link))) printf("[004] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); if ((0 === mysql_errno($link)) || ('' == mysql_error($link))) printf("[005] mysql_errno()/mysql_error should return some error\n"); -if (!$res = mysql_unbuffered_query('SELECT "this is sql but with semicolon" AS valid ; ', $link)) +if (!$res = mysql_unbuffered_query("SELECT 'this is sql but with semicolon' AS valid ; ", $link)) printf("[006] [%d] %s\n", mysql_errno($link), mysql_error($link)); var_dump(mysql_fetch_assoc($res)); mysql_free_result($res); -if (false !== ($res = mysql_unbuffered_query('SELECT "this is sql but with semicolon" AS valid ; SHOW VARIABLES', $link))) +if (false !== ($res = mysql_unbuffered_query("SELECT 'this is sql but with semicolon' AS valid ; SHOW VARIABLES", $link))) printf("[007] [%d] %s\n", mysql_errno($link), mysql_error($link)); if (mysql_unbuffered_query('DROP PROCEDURE IF EXISTS p', $link)) { @@ -48,7 +48,7 @@ if (mysql_unbuffered_query('DROP PROCEDURE IF EXISTS p', $link)) { printf("[008] Result seems wrong, dumping\n"); var_dump($tmp); } - if (ini_get('unicode.semantics') && !is_unicode($tmp['p_version'])) { + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp['p_version'])) { printf("[009] Expecting unicode string, dumping\n"); var_dump($tmp); } @@ -65,7 +65,7 @@ if (mysql_unbuffered_query('DROP PROCEDURE IF EXISTS p', $link)) { printf("[011] Result seems wrong, dumping\n"); var_dump($tmp); } - if (ini_get('unicode.semantics') && !is_unicode($tmp['f_version'])) { + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp['f_version'])) { printf("[012] Expecting unicode string, dumping\n"); var_dump($tmp); } @@ -86,23 +86,30 @@ if (false !== ($tmp = mysql_unbuffered_query("SELECT id FROM test", $link))) print "done!"; ?> ---EXPECTF-- -array(1) { - ["valid"]=> - string(30) "this is sql but with semicolon" +--CLEAN-- + +--EXPECTF-- array(1) { - [u"valid"]=> - unicode(30) "this is sql but with semicolon" + [%u|b%"valid"]=> + %unicode|string%(30) "this is sql but with semicolon" } bool(true) resource(%d) of type (mysql result) diff --git a/ext/mysql/tests/skipifconnectfailure.inc b/ext/mysql/tests/skipifconnectfailure.inc index e586a33f3..a57c7dbd5 100755 --- a/ext/mysql/tests/skipifconnectfailure.inc +++ b/ext/mysql/tests/skipifconnectfailure.inc @@ -6,7 +6,7 @@ if ($skip_on_connect_failure) { else if ($port) $myhost = sprintf("%s:%s", $host, $port); - if (!$link = @mysql_connect($myhost, $user, $passwd, true)) + if (!$link = @mysql_connect($myhost, $user, $passwd, true, $connect_flags)) die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysql_errno(), mysql_error())); if (!@mysql_select_db($db, $link)) diff --git a/ext/mysql/tests/skipifdefaultconnectfailure.inc b/ext/mysql/tests/skipifdefaultconnectfailure.inc new file mode 100755 index 000000000..99f390515 --- /dev/null +++ b/ext/mysql/tests/skipifdefaultconnectfailure.inc @@ -0,0 +1,11 @@ + diff --git a/ext/mysql/tests/table.inc b/ext/mysql/tests/table.inc index ddfbe430c..18c858d91 100644 --- a/ext/mysql/tests/table.inc +++ b/ext/mysql/tests/table.inc @@ -1,5 +1,5 @@ \ No newline at end of file +?> diff --git a/ext/mysqli/config.m4 b/ext/mysqli/config.m4 index 40c3d056c..f84470401 100644 --- a/ext/mysqli/config.m4 +++ b/ext/mysqli/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.22.2.1.2.2.2.5 2009/05/29 13:09:46 andrey Exp $ +dnl $Id: config.m4 286640 2009-08-02 01:07:38Z jani $ dnl config.m4 for extension mysqli PHP_ARG_WITH(mysqli, for MySQLi support, @@ -62,7 +62,7 @@ elif test "$PHP_MYSQLI" != "no"; then $MYSQLI_LIBLINE ]) dnl - dnl Check the library for mysql_stmt_store_result + dnl Check the library for mysql_stmt_next_result dnl PHP_CHECK_LIBRARY($MYSQL_LIB_NAME, mysql_stmt_next_result, [ diff --git a/ext/mysqli/config.w32 b/ext/mysqli/config.w32 index 4f530ed40..1545d3875 100644 --- a/ext/mysqli/config.w32 +++ b/ext/mysqli/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.7.6.5 2008/06/23 18:40:29 pajoye Exp $ +// $Id: config.w32 261548 2008-06-23 18:40:29Z pajoye $ // vim:ft=javascript // Note: The extension name is "mysqli", you enable it with "--with-mysqli". diff --git a/ext/mysqli/mysqli.c b/ext/mysqli/mysqli.c index ff493d876..a3407b9d4 100644 --- a/ext/mysqli/mysqli.c +++ b/ext/mysqli/mysqli.c @@ -17,7 +17,7 @@ | Ulf Wendel | +----------------------------------------------------------------------+ - $Id: mysqli.c,v 1.72.2.16.2.17.2.38 2009/01/22 21:01:55 johannes Exp $ + $Id: mysqli.c 289630 2009-10-14 13:51:25Z johannes $ */ #ifdef HAVE_CONFIG_H @@ -32,6 +32,7 @@ #include "ext/standard/php_string.h" #include "php_mysqli_structs.h" #include "zend_exceptions.h" +#include "ext/mysqlnd/mysqlnd_portability.h" ZEND_DECLARE_MODULE_GLOBALS(mysqli) static PHP_GINIT_FUNCTION(mysqli); @@ -337,7 +338,6 @@ zval *mysqli_read_property(zval *object, zval *member, int type TSRMLS_DC) zval *retval; mysqli_object *obj; mysqli_prop_handler *hnd; - zend_object_handlers *std_hnd; int ret; ret = FAILURE; @@ -363,7 +363,7 @@ zval *mysqli_read_property(zval *object, zval *member, int type TSRMLS_DC) retval = EG(uninitialized_zval_ptr); } } else { - std_hnd = zend_get_std_object_handlers(); + zend_object_handlers * std_hnd = zend_get_std_object_handlers(); retval = std_hnd->read_property(object, member, type TSRMLS_CC); } @@ -380,7 +380,6 @@ void mysqli_write_property(zval *object, zval *member, zval *value TSRMLS_DC) zval tmp_member; mysqli_object *obj; mysqli_prop_handler *hnd; - zend_object_handlers *std_hnd; int ret; if (member->type != IS_STRING) { @@ -403,7 +402,7 @@ void mysqli_write_property(zval *object, zval *member, zval *value TSRMLS_DC) zval_ptr_dtor(&value); } } else { - std_hnd = zend_get_std_object_handlers(); + zend_object_handlers * std_hnd = zend_get_std_object_handlers(); std_hnd->write_property(object, member, value TSRMLS_CC); } @@ -460,6 +459,9 @@ static int mysqli_object_has_property(zval *object, zval *member, int has_set_ex default: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for has_set_exists"); } + } else { + zend_object_handlers * std_hnd = zend_get_std_object_handlers(); + ret = std_hnd->has_property(object, member, has_set_exists TSRMLS_CC); } return ret; } /* }}} */ @@ -1199,12 +1201,37 @@ void php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAMETERS, int override_flags MAKE_STD_ZVAL(res); - /* check if we need magic quotes */ - if (PG(magic_quotes_runtime)) { - Z_TYPE_P(res) = IS_STRING; - Z_STRVAL_P(res) = php_addslashes(row[i], field_len[i], &Z_STRLEN_P(res), 0 TSRMLS_CC); - } else { - ZVAL_STRINGL(res, row[i], field_len[i], 1); +#if MYSQL_VERSION_ID > 50002 + if (mysql_fetch_field_direct(result, i)->type == MYSQL_TYPE_BIT) { + my_ulonglong llval; + char tmp[22]; + switch (field_len[i]) { + case 8:llval = (my_ulonglong) bit_uint8korr(row[i]);break; + case 7:llval = (my_ulonglong) bit_uint7korr(row[i]);break; + case 6:llval = (my_ulonglong) bit_uint6korr(row[i]);break; + case 5:llval = (my_ulonglong) bit_uint5korr(row[i]);break; + case 4:llval = (my_ulonglong) bit_uint4korr(row[i]);break; + case 3:llval = (my_ulonglong) bit_uint3korr(row[i]);break; + case 2:llval = (my_ulonglong) bit_uint2korr(row[i]);break; + case 1:llval = (my_ulonglong) uint1korr(row[i]);break; + } + /* even though lval is declared as unsigned, the value + * may be negative. Therefor we cannot use MYSQLI_LLU_SPEC and must + * use MYSQLI_LL_SPEC. + */ + snprintf(tmp, sizeof(tmp), (mysql_fetch_field_direct(result, i)->flags & UNSIGNED_FLAG)? MYSQLI_LLU_SPEC : MYSQLI_LL_SPEC, llval); + ZVAL_STRING(res, tmp, 1); + } else +#endif + { + + /* check if we need magic quotes */ + if (PG(magic_quotes_runtime)) { + Z_TYPE_P(res) = IS_STRING; + Z_STRVAL_P(res) = php_addslashes(row[i], field_len[i], &Z_STRLEN_P(res), 0 TSRMLS_CC); + } else { + ZVAL_STRINGL(res, row[i], field_len[i], 1); + } } if (fetchtype & MYSQLI_NUM) { diff --git a/ext/mysqli/mysqli_api.c b/ext/mysqli/mysqli_api.c index 29389e189..b87b741a1 100644 --- a/ext/mysqli/mysqli_api.c +++ b/ext/mysqli/mysqli_api.c @@ -17,7 +17,7 @@ | Ulf Wendel | +----------------------------------------------------------------------+ - $Id: mysqli_api.c,v 1.118.2.22.2.16.2.28 2009/05/29 13:09:46 andrey Exp $ + $Id: mysqli_api.c 289630 2009-10-14 13:51:25Z johannes $ */ #ifdef HAVE_CONFIG_H @@ -31,6 +31,7 @@ #include "php_globals.h" #include "ext/standard/info.h" #include "php_mysqli_structs.h" +#include "ext/mysqlnd/mysqlnd_portability.h" /* {{{ proto mixed mysqli_affected_rows(object link) Get number of affected rows in previous MySQL operation */ @@ -356,6 +357,7 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, bind[ofs].is_null = &stmt->result.is_null[ofs]; bind[ofs].buffer_length = stmt->result.buf[ofs].buflen; bind[ofs].is_unsigned = (stmt->stmt->fields[ofs].flags & UNSIGNED_FLAG) ? 1 : 0; + bind[ofs].length = &stmt->result.buf[ofs].output_len; break; case MYSQL_TYPE_DATE: @@ -370,6 +372,7 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_TIMESTAMP: case MYSQL_TYPE_DECIMAL: + case MYSQL_TYPE_GEOMETRY: #ifdef FIELD_TYPE_NEWDECIMAL case MYSQL_TYPE_NEWDECIMAL: #endif @@ -395,7 +398,9 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, different lengths and you will see that we get different lengths in stmt->stmt->fields[ofs].length The just take 256 and saves us from realloc-ing. */ - stmt->result.buf[ofs].buflen = 256; + stmt->result.buf[ofs].buflen = + (stmt->stmt->fields) ? (stmt->stmt->fields[ofs].length) ? stmt->stmt->fields[ofs].length + 1: 256: 256; + } else { /* the user has called store_result(). if he does not there is no way to determine the @@ -409,7 +414,7 @@ mysqli_stmt_bind_result_do_bind(MY_STMT *stmt, zval ***args, unsigned int argc, bind[ofs].buffer = stmt->result.buf[ofs].val; bind[ofs].is_null = &stmt->result.is_null[ofs]; bind[ofs].buffer_length = stmt->result.buf[ofs].buflen; - bind[ofs].length = &stmt->result.buf[ofs].buflen; + bind[ofs].length = &stmt->result.buf[ofs].output_len; break; } default: @@ -732,7 +737,7 @@ PHP_FUNCTION(mysqli_stmt_execute) for (i = 0; i < stmt->param.var_cnt; i++) { for (j = i + 1; j < stmt->param.var_cnt; j++) { /* Oops, someone binding the same variable - clone */ - if (stmt->param.vars[j] == stmt->param.vars[i]) { + if (stmt->param.vars[j] == stmt->param.vars[i] && stmt->param.vars[i]) { php_mysqli_stmt_copy_it(&copies, stmt->param.vars[i], stmt->param.var_cnt, i); break; } @@ -877,9 +882,29 @@ void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS) ZVAL_DOUBLE(stmt->result.vars[i], *(double *)stmt->result.buf[i].val); break; case IS_STRING: - if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG) { + if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_LONGLONG +#if MYSQL_VERSION_ID > 50002 + || stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT +#endif + ) { my_bool uns= (stmt->stmt->fields[i].flags & UNSIGNED_FLAG)? 1:0; - llval= *(my_ulonglong *) stmt->result.buf[i].val; +#if MYSQL_VERSION_ID > 50002 + if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) { + switch (stmt->result.buf[i].output_len) { + case 8:llval = (my_ulonglong) bit_uint8korr(stmt->result.buf[i].val);break; + case 7:llval = (my_ulonglong) bit_uint7korr(stmt->result.buf[i].val);break; + case 6:llval = (my_ulonglong) bit_uint6korr(stmt->result.buf[i].val);break; + case 5:llval = (my_ulonglong) bit_uint5korr(stmt->result.buf[i].val);break; + case 4:llval = (my_ulonglong) bit_uint4korr(stmt->result.buf[i].val);break; + case 3:llval = (my_ulonglong) bit_uint3korr(stmt->result.buf[i].val);break; + case 2:llval = (my_ulonglong) bit_uint2korr(stmt->result.buf[i].val);break; + case 1:llval = (my_ulonglong) uint1korr(stmt->result.buf[i].val);break; + } + } else +#endif + { + llval= *(my_ulonglong *) stmt->result.buf[i].val; + } #if SIZEOF_LONG==8 if (uns && llval > 9223372036854775807L) { #elif SIZEOF_LONG==4 @@ -898,14 +923,7 @@ void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS) } else { ZVAL_LONG(stmt->result.vars[i], llval); } - } -#if MYSQL_VERSION_ID > 50002 - else if (stmt->stmt->bind[i].buffer_type == MYSQL_TYPE_BIT) { - llval = *(my_ulonglong *)stmt->result.buf[i].val; - ZVAL_LONG(stmt->result.vars[i], llval); - } -#endif - else { + } else { #if defined(MYSQL_DATA_TRUNCATED) && MYSQL_VERSION_ID > 50002 if (ret == MYSQL_DATA_TRUNCATED && *(stmt->stmt->bind[i].error) != 0) { /* result was truncated */ @@ -916,7 +934,7 @@ void mysqli_stmt_fetch_libmysql(INTERNAL_FUNCTION_PARAMETERS) { #endif ZVAL_STRINGL(stmt->result.vars[i], stmt->result.buf[i].val, - stmt->result.buf[i].buflen, 1); + stmt->result.buf[i].output_len, 1); } } break; @@ -1483,8 +1501,7 @@ PHP_FUNCTION(mysqli_next_result) { } /* }}} */ - -#ifdef HAVE_STMT_NEXT_RESULT +#if defined(HAVE_STMT_NEXT_RESULT) && defined(MYSQLI_USE_MYSQLND) /* {{{ proto bool mysqli_stmt_next_result(object link) check if there any more query results from a multi query */ PHP_FUNCTION(mysqli_stmt_more_results) @@ -1519,7 +1536,7 @@ PHP_FUNCTION(mysqli_stmt_next_result) { "whether to call this function/method"); } - RETURN_BOOL(!mysqlnd_stmt_next_result(stmt->stmt)); + RETURN_BOOL(!mysql_stmt_next_result(stmt->stmt)); } /* }}} */ #endif @@ -2098,7 +2115,6 @@ PHP_FUNCTION(mysqli_stmt_attr_set) long mode_in; ulong mode; ulong attr; - int rc; if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Oll", &mysql_stmt, mysqli_stmt_class_entry, &attr, &mode_in) == FAILURE) { return; @@ -2111,7 +2127,11 @@ PHP_FUNCTION(mysqli_stmt_attr_set) } mode = mode_in; - if ((rc = mysql_stmt_attr_set(stmt->stmt, attr, (void *)&mode))) { +#if !defined(MYSQLI_USE_MYSQLND) + if (FALSE == mysql_stmt_attr_set(stmt->stmt, attr, (void *)&mode)) { +#else + if (FAIL == mysql_stmt_attr_set(stmt->stmt, attr, (void *)&mode)) { +#endif RETURN_FALSE; } RETURN_TRUE; @@ -2282,7 +2302,8 @@ PHP_FUNCTION(mysqli_stmt_store_result) for (i = mysql_stmt_field_count(stmt->stmt) - 1; i >=0; --i) { if (stmt->stmt->fields && (stmt->stmt->fields[i].type == MYSQL_TYPE_BLOB || stmt->stmt->fields[i].type == MYSQL_TYPE_MEDIUM_BLOB || - stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB)) + stmt->stmt->fields[i].type == MYSQL_TYPE_LONG_BLOB || + stmt->stmt->fields[i].type == MYSQL_TYPE_GEOMETRY)) { my_bool tmp=1; mysql_stmt_attr_set(stmt->stmt, STMT_ATTR_UPDATE_MAX_LENGTH, &tmp); diff --git a/ext/mysqli/mysqli_fe.c b/ext/mysqli/mysqli_fe.c index 087b75a8a..90238984b 100644 --- a/ext/mysqli/mysqli_fe.c +++ b/ext/mysqli/mysqli_fe.c @@ -15,7 +15,7 @@ | Author: Georg Richter | +----------------------------------------------------------------------+ - $Id: mysqli_fe.c,v 1.49.2.5.2.1.2.14 2009/01/22 21:01:56 johannes Exp $ + $Id: mysqli_fe.c 274296 2009-01-22 21:01:58Z johannes $ */ #ifdef HAVE_CONFIG_H diff --git a/ext/mysqli/mysqli_nonapi.c b/ext/mysqli/mysqli_nonapi.c index 203534f3d..c56485b4a 100644 --- a/ext/mysqli/mysqli_nonapi.c +++ b/ext/mysqli/mysqli_nonapi.c @@ -17,7 +17,7 @@ | Ulf Wendel | +----------------------------------------------------------------------+ - $Id: mysqli_nonapi.c,v 1.54.2.7.2.5.2.21 2009/01/27 15:35:34 johannes Exp $ + $Id: mysqli_nonapi.c 290608 2009-11-12 17:48:36Z johannes $ */ #ifdef HAVE_CONFIG_H @@ -46,7 +46,11 @@ static void php_mysqli_set_error(long mysql_errno, char *mysql_err TSRMLS_DC) if (MyG(error_msg)) { efree(MyG(error_msg)); } - MyG(error_msg) = estrdup(mysql_err); + if(mysql_err && *mysql_err) { + MyG(error_msg) = estrdup(mysql_err); + } else { + MyG(error_msg) = NULL; + } } /* }}} */ @@ -217,7 +221,7 @@ void mysqli_common_connect(INTERNAL_FUNCTION_PARAMETERS, zend_bool is_real_conne MyG(num_active_persistent) + MyG(num_inactive_persistent)); goto err; } - if (!is_real_connect && !mysql->mysql) { + if (!mysql->mysql) { #if !defined(MYSQLI_USE_MYSQLND) if (!(mysql->mysql = mysql_init(NULL))) { #else diff --git a/ext/mysqli/mysqli_prop.c b/ext/mysqli/mysqli_prop.c index 021d86d4d..40899f575 100644 --- a/ext/mysqli/mysqli_prop.c +++ b/ext/mysqli/mysqli_prop.c @@ -15,7 +15,7 @@ | Author: Georg Richter | +----------------------------------------------------------------------+ - $Id: mysqli_prop.c,v 1.23.2.5.2.2.2.13 2009/05/27 15:05:28 andrey Exp $ + $Id: mysqli_prop.c 281235 2009-05-27 15:05:28Z andrey $ */ #ifdef HAVE_CONFIG_H diff --git a/ext/mysqli/mysqli_report.c b/ext/mysqli/mysqli_report.c index e0efd9e59..1c5f916a6 100644 --- a/ext/mysqli/mysqli_report.c +++ b/ext/mysqli/mysqli_report.c @@ -15,7 +15,7 @@ | Author: Georg Richter | +----------------------------------------------------------------------+ - $Id: mysqli_report.c,v 1.11.2.2.2.2.2.3 2008/12/31 11:15:39 sebastian Exp $ + $Id: mysqli_report.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H diff --git a/ext/mysqli/mysqli_report.h b/ext/mysqli/mysqli_report.h index 96805a0d0..679108f97 100644 --- a/ext/mysqli/mysqli_report.h +++ b/ext/mysqli/mysqli_report.h @@ -15,7 +15,7 @@ | Author: Georg Richter | +----------------------------------------------------------------------+ - $Id: mysqli_report.h,v 1.5.2.1.2.1.2.2 2008/12/31 11:15:39 sebastian Exp $ + $Id: mysqli_report.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef __HAVE_MYSQLI_PROFILER_H__ diff --git a/ext/mysqli/php_mysqli.h b/ext/mysqli/php_mysqli.h index 52b5cab81..773b7f25a 100644 --- a/ext/mysqli/php_mysqli.h +++ b/ext/mysqli/php_mysqli.h @@ -17,7 +17,7 @@ | Ulf Wendel | +----------------------------------------------------------------------+ - $Id: php_mysqli.h,v 1.54.2.7.2.6.2.5 2008/12/31 11:15:39 sebastian Exp $ + $Id: php_mysqli.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_MYSQLI_H diff --git a/ext/mysqli/php_mysqli_structs.h b/ext/mysqli/php_mysqli_structs.h index 10ae64717..789850bb1 100644 --- a/ext/mysqli/php_mysqli_structs.h +++ b/ext/mysqli/php_mysqli_structs.h @@ -15,7 +15,7 @@ | Author: Georg Richter | +----------------------------------------------------------------------+ - $Id: php_mysqli_structs.h,v 1.4.2.20 2009/05/27 20:05:37 andrey Exp $ + $Id: php_mysqli_structs.h 289630 2009-10-14 13:51:25Z johannes $ */ #ifndef PHP_MYSQLI_STRUCTS_H @@ -73,8 +73,9 @@ enum mysqli_status { }; typedef struct { - ulong buflen; char *val; + ulong buflen; + ulong output_len; ulong type; } VAR_BUFFER; diff --git a/ext/mysqli/tests/001.phpt b/ext/mysqli/tests/001.phpt index 77f3dcbd1..4e19d8109 100644 --- a/ext/mysqli/tests/001.phpt +++ b/ext/mysqli/tests/001.phpt @@ -1,8 +1,8 @@ --TEST-- mysqli connect --SKIPIF-- - @@ -13,25 +13,25 @@ require_once('skipifconnectfailure.inc'); $test = ""; /*** test mysqli_connect localhost:port ***/ - $link = mysqli_connect($host, $user, $passwd, "", $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, "", $port, $socket); $test .= ($link) ? "1" : "0"; mysqli_close($link); /*** test mysqli_real_connect ***/ $link = mysqli_init(); - $test.= (mysqli_real_connect($link, $host, $user, $passwd, "", $port, $socket) ) + $test.= (my_mysqli_real_connect($link, $host, $user, $passwd, "", $port, $socket) ) ? "1" : "0"; mysqli_close($link); /*** test mysqli_real_connect with db ***/ $link = mysqli_init(); - $test .= (mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) + $test .= (my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) ? "1" : "0"; mysqli_close($link); /*** test mysqli_real_connect with port ***/ $link = mysqli_init(); - $test .= (mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) + $test .= (my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) ? "1":"0"; mysqli_close($link); @@ -40,7 +40,7 @@ require_once('skipifconnectfailure.inc'); if (!$link = mysqli_init()) printf("[001 + %d] mysqli_init() failed, [%d] %s\n", $i, mysqli_connect_errno(), mysqli_connect_error()); - if (!mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) printf("[002 + %d] mysqli_real_connect() failed, [%d] %s\n", $i, mysqli_connect_errno(), mysqli_connect_error()); mysqli_close($link); @@ -49,7 +49,7 @@ require_once('skipifconnectfailure.inc'); /*** test mysqli_real_connect compressed ***/ /* $link = mysqli_init(); - $test .= (mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, MYSQLI_CLIENT_COMPRESS)) + $test .= (my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, MYSQLI_CLIENT_COMPRESS)) ? "1" : "0"; mysqli_close($link); */ diff --git a/ext/mysqli/tests/002.phpt b/ext/mysqli/tests/002.phpt index c41a070bf..6bbdecfdc 100644 --- a/ext/mysqli/tests/002.phpt +++ b/ext/mysqli/tests/002.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); if (!mysqli_query($link, "DROP TABLE IF EXISTS test_fetch_null")) @@ -46,6 +46,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(11) { [0]=> diff --git a/ext/mysqli/tests/003.phpt b/ext/mysqli/tests/003.phpt index 5a8d13c02..e22fec143 100644 --- a/ext/mysqli/tests/003.phpt +++ b/ext/mysqli/tests/003.phpt @@ -9,7 +9,7 @@ require_once('skipifconnectfailure.inc'); +--CLEAN-- + --EXPECTF-- array(7) { [0]=> diff --git a/ext/mysqli/tests/004.phpt b/ext/mysqli/tests/004.phpt index d4d318fc3..1eae99df7 100644 --- a/ext/mysqli/tests/004.phpt +++ b/ext/mysqli/tests/004.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include ("connect.inc"); /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -47,6 +47,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(2) { [0]=> diff --git a/ext/mysqli/tests/005.phpt b/ext/mysqli/tests/005.phpt index 0ceabafaa..728f45e06 100644 --- a/ext/mysqli/tests/005.phpt +++ b/ext/mysqli/tests/005.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -32,11 +32,25 @@ require_once('skipifconnectfailure.inc'); var_dump($test); + /* this will crash with libmysql from PHP 5.0.6 (or earlier) to 5.3.0 */ + mysqli_fetch($stmt); + mysqli_stmt_close($stmt); mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(2) { [0]=> diff --git a/ext/mysqli/tests/006.phpt b/ext/mysqli/tests/006.phpt index b11760c6d..a10e22c44 100644 --- a/ext/mysqli/tests/006.phpt +++ b/ext/mysqli/tests/006.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!mysqli_query($link, "SET sql_mode=''")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -45,6 +45,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECT-- array(7) { [0]=> diff --git a/ext/mysqli/tests/007.phpt b/ext/mysqli/tests/007.phpt index f0a144686..fe266bf1b 100644 --- a/ext/mysqli/tests/007.phpt +++ b/ext/mysqli/tests/007.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!mysqli_query($link, "SET sql_mode=''")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -45,6 +45,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECT-- array(7) { [0]=> diff --git a/ext/mysqli/tests/008.phpt b/ext/mysqli/tests/008.phpt index 00ac730ba..685110f08 100644 --- a/ext/mysqli/tests/008.phpt +++ b/ext/mysqli/tests/008.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!mysqli_query($link, "SET sql_mode=''")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -45,6 +45,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECT-- array(7) { [0]=> diff --git a/ext/mysqli/tests/009.phpt b/ext/mysqli/tests/009.phpt index 4ed87950e..0584a14cf 100644 --- a/ext/mysqli/tests/009.phpt +++ b/ext/mysqli/tests/009.phpt @@ -14,7 +14,7 @@ mysqli fetch bigint values (ok to fail with 4.1.x) include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!mysqli_query($link, "SET sql_mode=''")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -78,7 +78,20 @@ mysqli fetch bigint values (ok to fail with 4.1.x) mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(8) { [0]=> diff --git a/ext/mysqli/tests/010.phpt b/ext/mysqli/tests/010.phpt index 13752b1ab..de22c0824 100644 --- a/ext/mysqli/tests/010.phpt +++ b/ext/mysqli/tests/010.phpt @@ -12,7 +12,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!mysqli_query($link, "SET sql_mode=''")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -48,6 +48,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECT-- array(7) { [0]=> diff --git a/ext/mysqli/tests/011.phpt b/ext/mysqli/tests/011.phpt index ace0a88b9..4c4ff7706 100644 --- a/ext/mysqli/tests/011.phpt +++ b/ext/mysqli/tests/011.phpt @@ -12,7 +12,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -45,6 +45,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(8) { [0]=> diff --git a/ext/mysqli/tests/012.phpt b/ext/mysqli/tests/012.phpt index 5f2e4d1dd..2ce810400 100644 --- a/ext/mysqli/tests/012.phpt +++ b/ext/mysqli/tests/012.phpt @@ -12,7 +12,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -44,6 +44,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(8) { [0]=> diff --git a/ext/mysqli/tests/013.phpt b/ext/mysqli/tests/013.phpt index fc8211b2b..8c123d1ab 100644 --- a/ext/mysqli/tests/013.phpt +++ b/ext/mysqli/tests/013.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!mysqli_query($link, "DROP TABLE IF EXISTS test_bind_result")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -56,6 +56,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- ok done! \ No newline at end of file diff --git a/ext/mysqli/tests/014.phpt b/ext/mysqli/tests/014.phpt index eb2b7322e..cd7fa19c7 100644 --- a/ext/mysqli/tests/014.phpt +++ b/ext/mysqli/tests/014.phpt @@ -5,7 +5,7 @@ mysqli autocommit/commit/rollback require_once('skipif.inc'); require_once('skipifconnectfailure.inc'); include "connect.inc"; - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!$result = mysqli_query($link, "SHOW VARIABLES LIKE 'have_innodb'")) { die("skip Cannot check for required InnoDB suppot"); } @@ -22,7 +22,7 @@ mysqli autocommit/commit/rollback --FILE-- +--CLEAN-- + --EXPECTF-- Num_of_rows=1 array(2) { diff --git a/ext/mysqli/tests/015.phpt b/ext/mysqli/tests/015.phpt index 8eaddfc84..b3af0142a 100644 --- a/ext/mysqli/tests/015.phpt +++ b/ext/mysqli/tests/015.phpt @@ -5,7 +5,7 @@ mysqli autocommit/commit/rollback with innodb require_once('skipif.inc'); require_once('skipifconnectfailure.inc'); include "connect.inc"; - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $result = mysqli_query($link, "SHOW VARIABLES LIKE 'have_innodb'"); $row = mysqli_fetch_row($result); mysqli_free_result($result); @@ -19,7 +19,7 @@ mysqli autocommit/commit/rollback with innodb +--CLEAN-- + --EXPECTF-- array(2) { [0]=> diff --git a/ext/mysqli/tests/016.phpt b/ext/mysqli/tests/016.phpt index 286df398d..c8046de9a 100644 --- a/ext/mysqli/tests/016.phpt +++ b/ext/mysqli/tests/016.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!mysqli_query($link, "SET @dummy='foobar'")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); diff --git a/ext/mysqli/tests/017.phpt b/ext/mysqli/tests/017.phpt index d201c7b80..7220b4ef0 100644 --- a/ext/mysqli/tests/017.phpt +++ b/ext/mysqli/tests/017.phpt @@ -11,7 +11,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!$stmt = mysqli_prepare($link, "SELECT md5('bar'), database(), 'foo'")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); diff --git a/ext/mysqli/tests/018.phpt b/ext/mysqli/tests/018.phpt index c5c60c7ae..1a8d76208 100644 --- a/ext/mysqli/tests/018.phpt +++ b/ext/mysqli/tests/018.phpt @@ -1,8 +1,8 @@ --TEST-- mysqli fetch system variables --SKIPIF-- - --FILE-- @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!mysqli_query($link, "SET AUTOCOMMIT=0")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); diff --git a/ext/mysqli/tests/019.phpt b/ext/mysqli/tests/019.phpt index 30a55aa3c..f3741a5d3 100644 --- a/ext/mysqli/tests/019.phpt +++ b/ext/mysqli/tests/019.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!mysqli_query($link, "DROP TABLE IF EXISTS insert_read")) printf("[001] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); @@ -55,6 +55,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(11) { [0]=> diff --git a/ext/mysqli/tests/020.phpt b/ext/mysqli/tests/020.phpt index 9035cceb9..f313a616a 100644 --- a/ext/mysqli/tests/020.phpt +++ b/ext/mysqli/tests/020.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); mysqli_query($link, "SET sql_mode=''"); @@ -67,6 +67,17 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(7) { [0]=> diff --git a/ext/mysqli/tests/021.phpt b/ext/mysqli/tests/021.phpt index 28e2800a0..3843566ea 100644 --- a/ext/mysqli/tests/021.phpt +++ b/ext/mysqli/tests/021.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -38,6 +38,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(2) { [0]=> diff --git a/ext/mysqli/tests/022.phpt b/ext/mysqli/tests/022.phpt index 36fdd7cee..5c448b9c1 100644 --- a/ext/mysqli/tests/022.phpt +++ b/ext/mysqli/tests/022.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -43,6 +43,17 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(2) { [0]=> diff --git a/ext/mysqli/tests/023.phpt b/ext/mysqli/tests/023.phpt index 4613a2c47..d3d4762a6 100644 --- a/ext/mysqli/tests/023.phpt +++ b/ext/mysqli/tests/023.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); mysqli_query($link, "SET sql_mode=''"); @@ -52,6 +52,17 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECT-- array(7) { [0]=> diff --git a/ext/mysqli/tests/024.phpt b/ext/mysqli/tests/024.phpt index e5bcdaf47..7dd540853 100644 --- a/ext/mysqli/tests/024.phpt +++ b/ext/mysqli/tests/024.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); mysqli_query($link, "SET sql_mode=''"); @@ -52,6 +52,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECT-- array(7) { [0]=> diff --git a/ext/mysqli/tests/025.phpt b/ext/mysqli/tests/025.phpt index 8f419ae35..9c076dfae 100644 --- a/ext/mysqli/tests/025.phpt +++ b/ext/mysqli/tests/025.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); mysqli_query($link, "SET sql_mode=''"); @@ -57,6 +57,17 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECT-- array(7) { [0]=> diff --git a/ext/mysqli/tests/026.phpt b/ext/mysqli/tests/026.phpt index 597a16d12..57fe33e00 100644 --- a/ext/mysqli/tests/026.phpt +++ b/ext/mysqli/tests/026.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); mysqli_query($link, "SET sql_mode=''"); @@ -43,6 +43,18 @@ require_once('skipifconnectfailure.inc'); mysqli_query($link, "DROP TABLE IF EXISTS test_bind_fetch"); mysqli_close($link); print "done!"; +?> +--CLEAN-- + --EXPECTF-- array(2) { [0]=> diff --git a/ext/mysqli/tests/027.phpt b/ext/mysqli/tests/027.phpt index c52c73e61..0926b70e2 100644 --- a/ext/mysqli/tests/027.phpt +++ b/ext/mysqli/tests/027.phpt @@ -1,8 +1,8 @@ --TEST-- function test: mysqli_stat --SKIPIF-- - --FILE-- @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $status = mysqli_stat($link); diff --git a/ext/mysqli/tests/028.phpt b/ext/mysqli/tests/028.phpt index a518b7dad..6c4425e2b 100644 --- a/ext/mysqli/tests/028.phpt +++ b/ext/mysqli/tests/028.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $cset = substr(mysqli_character_set_name($link),0,6); diff --git a/ext/mysqli/tests/029.phpt b/ext/mysqli/tests/029.phpt index b282e7c2e..bfc54bcc6 100644 --- a/ext/mysqli/tests/029.phpt +++ b/ext/mysqli/tests/029.phpt @@ -10,11 +10,11 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); - mysqli_query($link, "DROP TABLE IF EXISTS exists general_test"); + mysqli_query($link, "DROP TABLE IF EXISTS general_test"); mysqli_query($link, "CREATE TABLE general_test (a INT)"); mysqli_query($link, "INSERT INTO general_test VALUES (1),(2),(3)"); @@ -22,10 +22,21 @@ require_once('skipifconnectfailure.inc'); var_dump($afc); - mysqli_query($link, "DROP TABLE IF EXISTS exists general_test"); + mysqli_query($link, "DROP TABLE IF EXISTS general_test"); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECT-- int(3) done! \ No newline at end of file diff --git a/ext/mysqli/tests/030.phpt b/ext/mysqli/tests/030.phpt index af0210c87..656946fb6 100644 --- a/ext/mysqli/tests/030.phpt +++ b/ext/mysqli/tests/030.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $errno = mysqli_errno($link); var_dump($errno); diff --git a/ext/mysqli/tests/031.phpt b/ext/mysqli/tests/031.phpt index cf70e9bca..9f632cb42 100644 --- a/ext/mysqli/tests/031.phpt +++ b/ext/mysqli/tests/031.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $error = mysqli_error($link); var_dump($error); diff --git a/ext/mysqli/tests/032.phpt b/ext/mysqli/tests/032.phpt index e6e03477f..386883d0e 100644 --- a/ext/mysqli/tests/032.phpt +++ b/ext/mysqli/tests/032.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -26,6 +26,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- %unicode|string%(38) "Records: 3 Duplicates: 0 Warnings: 0" done! \ No newline at end of file diff --git a/ext/mysqli/tests/033.phpt b/ext/mysqli/tests/033.phpt index 081be99a2..ade0bb832 100644 --- a/ext/mysqli/tests/033.phpt +++ b/ext/mysqli/tests/033.phpt @@ -11,7 +11,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $hinfo = mysqli_get_host_info($link); diff --git a/ext/mysqli/tests/034.phpt b/ext/mysqli/tests/034.phpt index c195d7bff..cc415344c 100644 --- a/ext/mysqli/tests/034.phpt +++ b/ext/mysqli/tests/034.phpt @@ -1,8 +1,8 @@ --TEST-- function test: mysqli_get_proto_info --SKIPIF-- - @@ -11,7 +11,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $pinfo = mysqli_get_proto_info($link); diff --git a/ext/mysqli/tests/035.phpt b/ext/mysqli/tests/035.phpt index 58f0246df..7b621aa22 100644 --- a/ext/mysqli/tests/035.phpt +++ b/ext/mysqli/tests/035.phpt @@ -1,8 +1,8 @@ --TEST-- function test: mysqli_get_server_info --SKIPIF-- - --FILE-- @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $sinfo = substr(mysqli_get_server_info($link),0,1); diff --git a/ext/mysqli/tests/036.phpt b/ext/mysqli/tests/036.phpt index 45b5fda5a..4e68b6c2a 100644 --- a/ext/mysqli/tests/036.phpt +++ b/ext/mysqli/tests/036.phpt @@ -14,7 +14,7 @@ function test: mysqli_insert_id() include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -42,6 +42,17 @@ function test: mysqli_insert_id() mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECT-- array(2) { [0]=> diff --git a/ext/mysqli/tests/037.phpt b/ext/mysqli/tests/037.phpt index cb721e08a..856bdc698 100644 --- a/ext/mysqli/tests/037.phpt +++ b/ext/mysqli/tests/037.phpt @@ -11,7 +11,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -32,6 +32,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECT-- array(2) { [0]=> diff --git a/ext/mysqli/tests/038.phpt b/ext/mysqli/tests/038.phpt index bc3c54419..7be16f449 100644 --- a/ext/mysqli/tests/038.phpt +++ b/ext/mysqli/tests/038.phpt @@ -11,7 +11,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -33,5 +33,16 @@ require_once('skipifconnectfailure.inc'); mysqli_query($link, "DROP TABLE IF EXISTS test_result"); mysqli_close($link); ?> +--CLEAN-- + --EXPECT-- int(2) diff --git a/ext/mysqli/tests/039.phpt b/ext/mysqli/tests/039.phpt index 173c19222..9ed7ef9ea 100644 --- a/ext/mysqli/tests/039.phpt +++ b/ext/mysqli/tests/039.phpt @@ -11,7 +11,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_real_query($link, "SHOW VARIABLES"); diff --git a/ext/mysqli/tests/040.phpt b/ext/mysqli/tests/040.phpt index 675d34518..6b115166b 100644 --- a/ext/mysqli/tests/040.phpt +++ b/ext/mysqli/tests/040.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -31,6 +31,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECT-- int(1) done! \ No newline at end of file diff --git a/ext/mysqli/tests/041.phpt b/ext/mysqli/tests/041.phpt index 81bd808c4..aac91f86a 100644 --- a/ext/mysqli/tests/041.phpt +++ b/ext/mysqli/tests/041.phpt @@ -1,8 +1,8 @@ --TEST-- function test: mysqli_warning_count() --SKIPIF-- - --FILE-- @@ -11,7 +11,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); mysqli_query($link, "DROP TABLE IF EXISTS test_warnings"); @@ -22,6 +22,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECT-- int(1) done! \ No newline at end of file diff --git a/ext/mysqli/tests/042.phpt b/ext/mysqli/tests/042.phpt index 401006b39..9d79f148c 100644 --- a/ext/mysqli/tests/042.phpt +++ b/ext/mysqli/tests/042.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); mysqli_query($link, "SET sql_mode=''"); @@ -48,6 +48,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!" ?> +--CLEAN-- + --EXPECTF-- object(stdClass)#%d (7) { [%u|b%"c1"]=> diff --git a/ext/mysqli/tests/043.phpt b/ext/mysqli/tests/043.phpt index 0cf3e3749..51b2a91ff 100644 --- a/ext/mysqli/tests/043.phpt +++ b/ext/mysqli/tests/043.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -40,6 +40,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(1) { [0]=> diff --git a/ext/mysqli/tests/044.phpt b/ext/mysqli/tests/044.phpt index 0a2495b9c..9d227f49e 100644 --- a/ext/mysqli/tests/044.phpt +++ b/ext/mysqli/tests/044.phpt @@ -1,8 +1,8 @@ --TEST-- mysqli_get_server_version --SKIPIF-- - --FILE-- @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $i = mysqli_get_server_version($link); diff --git a/ext/mysqli/tests/045.phpt b/ext/mysqli/tests/045.phpt index a1ef9ec40..d5ee5ad2b 100644 --- a/ext/mysqli/tests/045.phpt +++ b/ext/mysqli/tests/045.phpt @@ -7,7 +7,7 @@ mysqli_bind_result (SHOW) require_once('skipifconnectfailure.inc'); include "connect.inc"; - $link = mysqli_connect($host, $user, $passwd); + $link = my_mysqli_connect($host, $user, $passwd); $stmt = mysqli_prepare($link, "SHOW VARIABLES LIKE 'port'"); mysqli_execute($stmt); @@ -23,7 +23,7 @@ mysqli_bind_result (SHOW) include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $stmt = mysqli_prepare($link, "SHOW VARIABLES LIKE 'port'"); mysqli_execute($stmt); @@ -31,7 +31,7 @@ mysqli_bind_result (SHOW) mysqli_bind_result($stmt, $c1, $c2); mysqli_fetch($stmt); mysqli_stmt_close($stmt); - if (ini_get("unicode.semantics") && mysqli_get_server_version($link) < 50000) { + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && mysqli_get_server_version($link) < 50000) { /* variables are binary */ settype($c1, "unicode"); settype($c2, "unicode"); diff --git a/ext/mysqli/tests/046.phpt b/ext/mysqli/tests/046.phpt index a08a9349e..cf7739210 100644 --- a/ext/mysqli/tests/046.phpt +++ b/ext/mysqli/tests/046.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -34,6 +34,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECT-- bool(true) done! \ No newline at end of file diff --git a/ext/mysqli/tests/047.phpt b/ext/mysqli/tests/047.phpt index 172f2ef1d..3401418e9 100644 --- a/ext/mysqli/tests/047.phpt +++ b/ext/mysqli/tests/047.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -45,6 +45,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- === fetch_fields === array(2) { diff --git a/ext/mysqli/tests/048.phpt b/ext/mysqli/tests/048.phpt index a63b0a3a9..5ab60e5a5 100644 --- a/ext/mysqli/tests/048.phpt +++ b/ext/mysqli/tests/048.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $mysql = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $mysql = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $mysql->select_db($db); $mysql->query("DROP TABLE IF EXISTS test_fetch_null"); @@ -40,6 +40,17 @@ require_once('skipifconnectfailure.inc'); $mysql->close(); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(11) { [0]=> diff --git a/ext/mysqli/tests/049.phpt b/ext/mysqli/tests/049.phpt index afd237654..eb977a8b6 100644 --- a/ext/mysqli/tests/049.phpt +++ b/ext/mysqli/tests/049.phpt @@ -11,7 +11,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $mysql = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $mysql = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $mysql->select_db($db); $result = $mysql->query("SELECT DATABASE()"); @@ -19,6 +19,8 @@ require_once('skipifconnectfailure.inc'); $result->close(); var_dump($row); + if ($row[0] != $db) + printf("[001] Expecting '%s' got '%s'\n", $db, $row[0]); $mysql->close(); print "done!"; diff --git a/ext/mysqli/tests/050.phpt b/ext/mysqli/tests/050.phpt index ee1c20322..ba668f0a8 100644 --- a/ext/mysqli/tests/050.phpt +++ b/ext/mysqli/tests/050.phpt @@ -1,8 +1,8 @@ --TEST-- non freed statement test --SKIPIF-- - --FILE-- @@ -12,7 +12,7 @@ require_once('skipifconnectfailure.inc'); /************************ * non freed stamement ************************/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $stmt = mysqli_prepare($link, "SELECT CURRENT_USER()"); mysqli_execute($stmt); diff --git a/ext/mysqli/tests/051.phpt b/ext/mysqli/tests/051.phpt index 8ff75d59b..82665156d 100644 --- a/ext/mysqli/tests/051.phpt +++ b/ext/mysqli/tests/051.phpt @@ -1,8 +1,8 @@ --TEST-- free statement after close --SKIPIF-- - --FILE-- @@ -12,7 +12,7 @@ require_once('skipifconnectfailure.inc'); /************************ * free statement after close ************************/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $stmt1 = mysqli_prepare($link, "SELECT CURRENT_USER()"); mysqli_execute($stmt1); diff --git a/ext/mysqli/tests/052.phpt b/ext/mysqli/tests/052.phpt index 95fdc2f27..f280d8406 100644 --- a/ext/mysqli/tests/052.phpt +++ b/ext/mysqli/tests/052.phpt @@ -1,18 +1,18 @@ --TEST-- call statement after close --SKIPIF-- - --FILE-- --FILE-- --FILE-- --FILE-- +--CLEAN-- + --EXPECTF-- bool(true) bool(true) diff --git a/ext/mysqli/tests/058.phpt b/ext/mysqli/tests/058.phpt index ae8b69b79..d1a90a004 100644 --- a/ext/mysqli/tests/058.phpt +++ b/ext/mysqli/tests/058.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -48,6 +48,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(4) { [0]=> diff --git a/ext/mysqli/tests/059.phpt b/ext/mysqli/tests/059.phpt index 8eadbd9e8..4897981cf 100644 --- a/ext/mysqli/tests/059.phpt +++ b/ext/mysqli/tests/059.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); @@ -41,6 +41,17 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- %unicode|string%(6) "foobar" done! \ No newline at end of file diff --git a/ext/mysqli/tests/060.phpt b/ext/mysqli/tests/060.phpt index 0162873c8..f1c20bfa1 100644 --- a/ext/mysqli/tests/060.phpt +++ b/ext/mysqli/tests/060.phpt @@ -16,7 +16,7 @@ require_once('skipifconnectfailure.inc'); } /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, $db); mysqli_query($link, "SET sql_mode=''"); @@ -42,6 +42,17 @@ require_once('skipifconnectfailure.inc'); echo "Done\n"; ?> +--CLEAN-- + --EXPECTF-- test_class::__construct(1,2) object(test_class)#%d (7) { diff --git a/ext/mysqli/tests/061.phpt b/ext/mysqli/tests/061.phpt index 03b3d84f3..e40f3a273 100644 --- a/ext/mysqli/tests/061.phpt +++ b/ext/mysqli/tests/061.phpt @@ -17,7 +17,7 @@ if (!function_exists('mysqli_set_local_infile_handler')) } /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); /* create temporary file */ $filename = dirname(__FILE__) . "061.csv"; @@ -49,9 +49,20 @@ if (!function_exists('mysqli_set_local_infile_handler')) unlink($filename); print "done!"; ?> ---EXPECT-- +--CLEAN-- + +--EXPECTF-- foo-bar %unicode|string%-%unicode|string% rab-oof %unicode|string%-%unicode|string% -done! \ No newline at end of file +done! diff --git a/ext/mysqli/tests/062.phpt b/ext/mysqli/tests/062.phpt index 738b2ec8c..043855365 100644 --- a/ext/mysqli/tests/062.phpt +++ b/ext/mysqli/tests/062.phpt @@ -9,7 +9,7 @@ require_once('skipifconnectfailure.inc'); real_query("SELECT 'foo' FROM DUAL"); diff --git a/ext/mysqli/tests/063.phpt b/ext/mysqli/tests/063.phpt index fbbdacd59..9b42ab7fb 100644 --- a/ext/mysqli/tests/063.phpt +++ b/ext/mysqli/tests/063.phpt @@ -9,7 +9,7 @@ require_once('skipifconnectfailure.inc'); execute(); diff --git a/ext/mysqli/tests/064.phpt b/ext/mysqli/tests/064.phpt index 729fb6b45..a308e4ab2 100644 --- a/ext/mysqli/tests/064.phpt +++ b/ext/mysqli/tests/064.phpt @@ -1,15 +1,15 @@ --TEST-- -NULL binding +NULL binding --SKIPIF-- - --FILE-- execute(); diff --git a/ext/mysqli/tests/065.phpt b/ext/mysqli/tests/065.phpt index 9819f2613..d0f1d1629 100644 --- a/ext/mysqli/tests/065.phpt +++ b/ext/mysqli/tests/065.phpt @@ -16,7 +16,7 @@ if (version_compare(PHP_VERSION, '5.9.9', '>') == 1) { --FILE-- @@ -11,7 +11,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; /*** test mysqli_connect 127.0.0.1 ***/ - $mysql = new mysqli($host, $user, $passwd, $db, $port, $socket); + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); $mysql->query("DROP TABLE IF EXISTS test_warnings"); @@ -28,6 +28,17 @@ require_once('skipifconnectfailure.inc'); $mysql->close(); print "done!"; ?> +--CLEAN-- + --EXPECT-- Warning done! diff --git a/ext/mysqli/tests/067.phpt b/ext/mysqli/tests/067.phpt index da372607c..f57149518 100644 --- a/ext/mysqli/tests/067.phpt +++ b/ext/mysqli/tests/067.phpt @@ -6,7 +6,7 @@ function test: nested selects (cursors) require_once('skipifconnectfailure.inc'); include "connect.inc"; - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) die("skip Cannot connect to check required version"); /* skip cursor test for versions < 50004 */ @@ -30,7 +30,7 @@ function test: nested selects (cursors) } include "connect.inc"; - $mysql = new mysqli($host, $user, $passwd, $db, $port, $socket); + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); if ((!$IS_MYSQLND && mysqli_get_client_version() < 50009) || (mysqli_get_server_version($mysql) < 50009)) { @@ -64,5 +64,18 @@ function test: nested selects (cursors) $mysql->close(); var_dump($cnt); ?> +--CLEAN-- + --EXPECT-- int(63) \ No newline at end of file diff --git a/ext/mysqli/tests/069.phpt b/ext/mysqli/tests/069.phpt index c6b498e8a..404b6ab10 100644 --- a/ext/mysqli/tests/069.phpt +++ b/ext/mysqli/tests/069.phpt @@ -9,7 +9,7 @@ require_once('skipifconnectfailure.inc'); multi_query('SELECT 1;SELECT 2'); do { $res = $mysql->store_result(); diff --git a/ext/mysqli/tests/070.phpt b/ext/mysqli/tests/070.phpt index 3064ac11e..eee512513 100644 --- a/ext/mysqli/tests/070.phpt +++ b/ext/mysqli/tests/070.phpt @@ -1,15 +1,15 @@ --TEST-- mysqli ping --SKIPIF-- - --FILE-- ping()); $mysql->close(); print "done!"; diff --git a/ext/mysqli/tests/071.phpt b/ext/mysqli/tests/071.phpt index e2fcaf18a..8888fb170 100644 --- a/ext/mysqli/tests/071.phpt +++ b/ext/mysqli/tests/071.phpt @@ -1,8 +1,8 @@ --TEST-- mysqli thread_id & kill --SKIPIF-- - @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); ping()); @@ -20,7 +20,7 @@ require_once('skipifconnectfailure.inc'); $mysql->close(); - $mysql = new mysqli($host, $user, $passwd, $db, $port, $socket); + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); var_dump(mysqli_ping($mysql)); diff --git a/ext/mysqli/tests/072.phpt b/ext/mysqli/tests/072.phpt index db05d5d22..637014b29 100644 --- a/ext/mysqli/tests/072.phpt +++ b/ext/mysqli/tests/072.phpt @@ -9,7 +9,7 @@ require_once('skipifconnectfailure.inc'); query("DROP TABLE IF EXISTS not_exists"); diff --git a/ext/mysqli/tests/074.phpt b/ext/mysqli/tests/074.phpt index 0d935d35d..883655bc5 100644 --- a/ext/mysqli/tests/074.phpt +++ b/ext/mysqli/tests/074.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include "connect.inc"; - $mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket); + $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); var_dump($mysqli->autocommit(false)); $result = $mysqli->query("SELECT @@autocommit"); diff --git a/ext/mysqli/tests/bug31668.phpt b/ext/mysqli/tests/bug31668.phpt index b9a958955..cdca551f2 100644 --- a/ext/mysqli/tests/bug31668.phpt +++ b/ext/mysqli/tests/bug31668.phpt @@ -11,7 +11,7 @@ error_reporting = E_ALL & ~E_STRICT multi_query('SELECT 1;SELECT 2'); do { $res = $mysql->store_result(); @@ -25,7 +25,7 @@ error_reporting = E_ALL & ~E_STRICT var_dump($mysql->error, __LINE__); $mysql->close(); - $mysql = new mysqli($host, $user, $passwd, $db, $port, $socket); + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); $mysql->multi_query('SELECT 1;SELECT 2'); do { $res = $mysql->store_result(); diff --git a/ext/mysqli/tests/bug32405.phpt b/ext/mysqli/tests/bug32405.phpt index 7754f60a9..24bcdb4d0 100644 --- a/ext/mysqli/tests/bug32405.phpt +++ b/ext/mysqli/tests/bug32405.phpt @@ -1,8 +1,8 @@ --TEST-- Bug #32405 (mysqli->fetch() is returning bad data) --SKIPIF-- - --FILE-- @@ -10,10 +10,10 @@ require_once('skipifconnectfailure.inc'); include ("connect.inc"); /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_select_db($link, "test"); mysqli_query($link, "SET sql_mode=''"); - + /* two fields are needed. the problem does not occur with 1 field only selected. */ $link->query("CREATE TABLE test_users(user_id int(10) unsigned NOT NULL auto_increment, login varchar(50) default '', PRIMARY KEY (user_id))"); $link->query('INSERT INTO test_users VALUES (NULL, "user1"), (NULL, "user2"), (NULL, "user3"), (NULL, "user4")'); @@ -31,6 +31,17 @@ require_once('skipifconnectfailure.inc'); mysqli_query($link,"DROP TABLE test_users"); mysqli_close($link); ?> +--CLEAN-- + --EXPECTF-- int(1) %s(5) "user1" diff --git a/ext/mysqli/tests/bug33090.phpt b/ext/mysqli/tests/bug33090.phpt index d7d569698..c95043c55 100644 --- a/ext/mysqli/tests/bug33090.phpt +++ b/ext/mysqli/tests/bug33090.phpt @@ -1,8 +1,8 @@ --TEST-- Bug #33090 (mysql_prepare doesn't return an error) --SKIPIF-- - --FILE-- @@ -10,13 +10,13 @@ require_once('skipifconnectfailure.inc'); include ("connect.inc"); /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, null, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, null, $port, $socket); mysqli_select_db($link, $db); if (!($link->prepare("this makes no sense"))) { printf("%d\n", $link->errno); printf("%s\n", $link->sqlstate); - } + } $link->close(); ?> --EXPECT-- diff --git a/ext/mysqli/tests/bug34785.phpt b/ext/mysqli/tests/bug34785.phpt index 2130ccaf3..18dd4c356 100644 --- a/ext/mysqli/tests/bug34785.phpt +++ b/ext/mysqli/tests/bug34785.phpt @@ -1,8 +1,8 @@ --TEST-- Bug #34785 (Can not properly subclass mysqli_stmt) --SKIPIF-- - --FILE-- @@ -24,7 +24,7 @@ require_once('skipifconnectfailure.inc'); } /*** test mysqli_connect 127.0.0.1 ***/ - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); mysqli_query($link, "SET sql_mode=''"); $stmt = new my_stmt($link, "SELECT 'foo' FROM DUAL"); diff --git a/ext/mysqli/tests/bug34810.phpt b/ext/mysqli/tests/bug34810.phpt index ed98e1e5a..fac805312 100644 --- a/ext/mysqli/tests/bug34810.phpt +++ b/ext/mysqli/tests/bug34810.phpt @@ -12,14 +12,14 @@ class DbConnection { public function connect() { include "connect.inc"; - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); var_dump($link); $link = mysqli_init(); /* @ is to supress 'Property access is not allowed yet' */ @var_dump($link); - $mysql = new mysqli($host, $user, $passwd, $db, $port, $socket); + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); $mysql->query("DROP TABLE IF EXISTS test_warnings"); $mysql->query("CREATE TABLE test_warnings (a int not null)"); $mysql->query("SET sql_mode=''"); @@ -33,6 +33,17 @@ $db->connect(); echo "Done\n"; ?> +--CLEAN-- + --EXPECTF-- object(mysqli)#%d (%d) { [%u|b%"affected_rows"]=> diff --git a/ext/mysqli/tests/bug35103.phpt b/ext/mysqli/tests/bug35103.phpt index b94366203..9c137b554 100644 --- a/ext/mysqli/tests/bug35103.phpt +++ b/ext/mysqli/tests/bug35103.phpt @@ -1,8 +1,8 @@ --TEST-- Bug #35103 (Bad handling of unsigned bigint) --SKIPIF-- - --FILE-- @@ -14,7 +14,7 @@ DROP TABLE test_buint; EOSQL; include "connect.inc"; - $mysql = new mysqli($host, $user, $passwd, $db, $port, $socket); + $mysql = new my_mysqli($host, $user, $passwd, $db, $port, $socket); $mysql->query("DROP TABLE IF EXISTS test_bint"); $mysql->query("CREATE TABLE test_bint (a bigint(20) default NULL) ENGINE=MYISAM"); $mysql->query("INSERT INTO test_bint VALUES (9223372036854775807),(-9223372036854775808),(-2147483648),(-2147483649),(-2147483647),(2147483647),(2147483648),(2147483649)"); @@ -22,7 +22,7 @@ EOSQL; $mysql->query("DROP TABLE IF EXISTS test_buint"); $mysql->query("CREATE TABLE test_buint (a bigint(20) unsigned default NULL)"); $mysql->query("INSERT INTO test_buint VALUES (18446744073709551615),(9223372036854775807),(9223372036854775808),(2147483647),(2147483649),(4294967295)"); - + $stmt = $mysql->prepare("SELECT a FROM test_bint ORDER BY a"); $stmt->bind_result($v); $stmt->execute(); @@ -51,6 +51,17 @@ EOSQL; $mysql->close(); ?> +--CLEAN-- + --EXPECT-- BIG INT SIGNED, TEST -9223372036854775808 diff --git a/ext/mysqli/tests/bug35517.phpt b/ext/mysqli/tests/bug35517.phpt index fb7f9d19c..c769eed1f 100644 --- a/ext/mysqli/tests/bug35517.phpt +++ b/ext/mysqli/tests/bug35517.phpt @@ -9,7 +9,7 @@ require_once('skipifconnectfailure.inc'); query("CREATE TABLE temp (id INT UNSIGNED NOT NULL)"); $mysql->query("INSERT INTO temp (id) VALUES (3000000897),(3800001532),(3900002281),(3100059612)"); @@ -37,6 +37,17 @@ require_once('skipifconnectfailure.inc'); $mysql->close(); print "done!"; ?> +--CLEAN-- + --EXPECTF-- 3000000897 3800001532 diff --git a/ext/mysqli/tests/bug35759.phpt b/ext/mysqli/tests/bug35759.phpt index ca8622d3a..39b21c476 100644 --- a/ext/mysqli/tests/bug35759.phpt +++ b/ext/mysqli/tests/bug35759.phpt @@ -1,8 +1,8 @@ --TEST-- Bug #35759 (mysqli_stmt_bind_result() makes huge allocation when column empty) --SKIPIF-- - --FILE-- @@ -24,11 +24,11 @@ EOSQL; while (++$i < $col_num) { $create .= ", a$i MEDIUMBLOB NOT NULL DEFAULT ''"; } - $create .= ")"; - + $create .= ")"; + $mysql->query($create); $mysql->query("INSERT INTO blobby (a0) VALUES ('')"); - + $stmt = $mysql->prepare("SELECT * FROM blobby"); $stmt->execute(); $stmt->store_result(); @@ -37,7 +37,7 @@ EOSQL; } call_user_func_array(array($stmt, "bind_result"), $params); $stmt->fetch(); - + $stmt->close(); $mysql->query("DROP TABLE blobby"); @@ -45,5 +45,16 @@ EOSQL; $mysql->close(); echo "OK\n"; ?> +--CLEAN-- + --EXPECT-- OK diff --git a/ext/mysqli/tests/bug36420.phpt b/ext/mysqli/tests/bug36420.phpt index 49804e18a..54657a700 100644 --- a/ext/mysqli/tests/bug36420.phpt +++ b/ext/mysqli/tests/bug36420.phpt @@ -1,15 +1,15 @@ --TEST-- Bug #36420 (segfault when access result->num_rows after calling result->close()) --SKIPIF-- - --FILE-- query('select 1'); @@ -21,7 +21,7 @@ echo $result->num_rows; echo "Done\n"; ?> ---EXPECTF-- +--EXPECTF-- Warning: main(): Couldn't fetch mysqli_result in %s on line %d Warning: main(): Couldn't fetch mysqli_result in %s on line %d diff --git a/ext/mysqli/tests/bug36745.phpt b/ext/mysqli/tests/bug36745.phpt index eef65d8aa..511eaf38f 100644 --- a/ext/mysqli/tests/bug36745.phpt +++ b/ext/mysqli/tests/bug36745.phpt @@ -1,8 +1,8 @@ --TEST-- Bug #36745 (LOAD DATA LOCAL INFILE doesn't return correct error message) --SKIPIF-- - --FILE-- @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); include ("connect.inc"); /*** test mysqli_connect 127.0.0.1 ***/ - $mysql = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $mysql = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $mysql->query("DROP TABLE IF EXISTS litest"); $mysql->query("CREATE TABLE litest (a VARCHAR(20))"); @@ -21,6 +21,17 @@ require_once('skipifconnectfailure.inc'); $mysql->close(); printf("Done"); ?> +--CLEAN-- + --EXPECTF-- %s(%d) "%s" Done diff --git a/ext/mysqli/tests/bug36802.phpt b/ext/mysqli/tests/bug36802.phpt index b276a0a97..d7144bdda 100644 --- a/ext/mysqli/tests/bug36802.phpt +++ b/ext/mysqli/tests/bug36802.phpt @@ -4,16 +4,13 @@ Bug #36802 (crashes with with mysqli_set_charset()) --FILE-- query("SELECT 'foo' FROM DUAL"); - /* following operations should work */ + /* following operations should work */ $x[2] = ($mysql->client_version > 0); $x[3] = $mysql->errno; $mysql->close(); - - var_dump($x); ?> diff --git a/ext/mysqli/tests/bug36949.phpt b/ext/mysqli/tests/bug36949.phpt index 9362d7ff3..39909f9ef 100644 --- a/ext/mysqli/tests/bug36949.phpt +++ b/ext/mysqli/tests/bug36949.phpt @@ -1,8 +1,8 @@ --TEST-- Bug #36949 (invalid internal mysqli objects dtor) --SKIPIF-- - --FILE-- @@ -47,6 +47,17 @@ class B { $A = new A(); $B = new B(); ?> +--CLEAN-- + --EXPECTF-- %d%d%d%d-%d%d-%d%d %d%d:%d%d:%d%d
%d%d%d%d-%d%d-%d%d %d%d:%d%d:%d%d
diff --git a/ext/mysqli/tests/bug37090.phpt b/ext/mysqli/tests/bug37090.phpt index 003ace9d1..7e8b4931b 100644 --- a/ext/mysqli/tests/bug37090.phpt +++ b/ext/mysqli/tests/bug37090.phpt @@ -7,7 +7,7 @@ require_once('skipifconnectfailure.inc'); if (!function_exists('mysqli_set_charset')) { die('skip mysqli_set_charset() not available'); } -if (ini_get('unicode.semantics')) { +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) { die("skip Functionality not available in unicode mode"); } ?> @@ -15,7 +15,7 @@ if (ini_get('unicode.semantics')) { set_charset("latin1"); diff --git a/ext/mysqli/tests/bug38710.phpt b/ext/mysqli/tests/bug38710.phpt index 490810cbc..280a51a6f 100755 --- a/ext/mysqli/tests/bug38710.phpt +++ b/ext/mysqli/tests/bug38710.phpt @@ -1,15 +1,15 @@ --TEST-- Bug #38710 (data leakage because of nonexisting boundary checking in statements) --SKIPIF-- - --FILE-- stmt_init(); $qry->prepare("SELECT REPEAT('a',100000)"); $qry->execute(); @@ -20,5 +20,5 @@ if ($text !== str_repeat('a', ($IS_MYSQLND || mysqli_get_server_version($db) > 5 } echo "Done"; ?> ---EXPECTF-- +--EXPECTF-- Done \ No newline at end of file diff --git a/ext/mysqli/tests/bug42378.phpt b/ext/mysqli/tests/bug42378.phpt index fcdd7e0da..b3fd7ca52 100644 --- a/ext/mysqli/tests/bug42378.phpt +++ b/ext/mysqli/tests/bug42378.phpt @@ -152,7 +152,7 @@ memory_limit=83886080 return true; } - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect - [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); @@ -181,6 +181,10 @@ memory_limit=83886080 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- FLOAT FORMAT(col1, 0) diff --git a/ext/mysqli/tests/bug42548.phpt b/ext/mysqli/tests/bug42548.phpt index 64c2ba31e..c9950be3a 100644 --- a/ext/mysqli/tests/bug42548.phpt +++ b/ext/mysqli/tests/bug42548.phpt @@ -5,7 +5,7 @@ Bug #42548 PROCEDURE xxx can't return a result set in the given context (works i require_once('skipif.inc'); require_once('skipifconnectfailure.inc'); require_once('connect.inc'); -if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); } if (mysqli_get_server_version($link) <= 50000) { @@ -50,6 +50,16 @@ $mysqli->query("DROP PROCEDURE p1") or die($mysqli->error); $mysqli->close(); print "done!"; ?> +--CLEAN-- + --EXPECT-- Array ( diff --git a/ext/mysqli/tests/bug44897.phpt b/ext/mysqli/tests/bug44897.phpt index 058468c10..92fc0a2e2 100644 --- a/ext/mysqli/tests/bug44897.phpt +++ b/ext/mysqli/tests/bug44897.phpt @@ -10,7 +10,7 @@ if (!stristr(mysqli_get_client_info(), 'mysqlnd')) require_once('skipifconnectfailure.inc'); require_once('connect.inc'); -if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); } if (mysqli_get_server_version($link) <= 50000) { @@ -72,5 +72,19 @@ if (mysqli_get_server_version($link) <= 50000) { print "done!"; ?> +--CLEAN-- + + --EXPECTF-- done! diff --git a/ext/mysqli/tests/bug45019.phpt b/ext/mysqli/tests/bug45019.phpt index ae5301f73..b8828c742 100644 --- a/ext/mysqli/tests/bug45019.phpt +++ b/ext/mysqli/tests/bug45019.phpt @@ -33,103 +33,20 @@ require_once('skipifconnectfailure.inc'); $index = 0; while ($stmt->fetch()) { + /* NOTE: libmysql - http://bugs.mysql.com/bug.php?id=47483 */ if ($data[$index] != $column1) { - printf("[004] Row %d, expecting %s/%s got %s/%s\n", - $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + if ($IS_MYSQLND || $index != 1) { + printf("[004] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } else { + if ($column1 != "thre") + printf("[005] Got '%s'. Please check if http://bugs.mysql.com/bug.php?id=47483 has been fixed and adapt tests bug45019.phpt/mysqli_ps_select_union.phpt", $column1); + } } $index++; } $stmt->close(); - // Regular (non-prepared) queries - print "Mixing CAST('somestring'AS CHAR), integer and CAST(integer AS CHAR)...\n"; - if (!($res = $link->query("SELECT 1 AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST(2 AS CHAR)"))) - printf("[005] [%d] %s\n", $link->errno, $link->error); - - $data = array(); - while ($row = $res->fetch_assoc()) { - $data[] = $row['column1']; - } - $res->free(); - - // Prepared Statements - if (!($stmt = $link->prepare("SELECT 1 AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST(2 AS CHAR)"))) - printf("[006] [%d] %s\n", $link->errno, $link->error); - - $column1 = null; - if (!$stmt->execute() || !$stmt->bind_result($column1)) - printf("[007] [%d] %s\n", $stmt->errno, $stmt->error); - - $index = 0; - while ($stmt->fetch()) { - if ($data[$index] != $column1) { - printf("[008] Row %d, expecting %s/%s got %s/%s\n", - $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); - } - var_dump($column1); - $index++; - } - $stmt->close(); - - print "Using integer only...\n"; - if (!($res = $link->query("SELECT 1 AS column1 UNION SELECT 303 UNION SELECT 2"))) - printf("[009] [%d] %s\n", $link->errno, $link->error); - - $data = array(); - while ($row = $res->fetch_assoc()) { - $data[] = $row['column1']; - } - $res->free(); - - // Prepared Statements - if (!($stmt = $link->prepare("SELECT 1 AS column1 UNION SELECT 303 UNION SELECT 2"))) - printf("[010] [%d] %s\n", $link->errno, $link->error); - - $column1 = null; - if (!$stmt->bind_result($column1) || !$stmt->execute()) - printf("[011] [%d] %s\n", $stmt->errno, $stmt->error); - - $index = 0; - while ($stmt->fetch()) { - if ($data[$index] != $column1) { - printf("[012] Row %d, expecting %s/%s got %s/%s\n", - $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); - } - var_dump($column1); - $index++; - } - $stmt->close(); - - print "Testing bind_param(), strings only...\n"; - $two = 'two'; - $three = 'three'; - if (!($stmt = $link->prepare("SELECT 'one' AS column1 UNION SELECT ? UNION SELECT ?"))) - printf("[013] [%d] %s\n", $stmt->errno, $stmt->error); - - $column1 = null; - if (!$stmt->bind_param('ss', $three, $two) || !$stmt->bind_result($column1) || !$stmt->execute()) - printf("[014] [%d] %s\n", $stmt->errno, $stmt->error); - - while ($stmt->fetch()) { - var_dump($column1); - } - $stmt->close(); - - print "Testing bind_param(), strings only, with CAST AS CHAR...\n"; - $two = 'two'; - $three = 'three beers are more than enough'; - if (!($stmt = $link->prepare("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST(? AS CHAR) UNION SELECT CAST(? AS CHAR)"))) - printf("[013] [%d] %s\n", $stmt->errno, $stmt->error); - - $column1 = null; - if (!$stmt->bind_param('ss', $three, $two) || !$stmt->bind_result($column1) || !$stmt->execute()) - printf("[014] [%d] %s\n", $stmt->errno, $stmt->error); - - while ($stmt->fetch()) { - var_dump($column1); - } - $stmt->close(); - $link->close(); print "done!"; @@ -139,20 +56,4 @@ Using CAST('somestring' AS CHAR)... %unicode|string%(3) "one" %unicode|string%(5) "three" %unicode|string%(3) "two" -Mixing CAST('somestring'AS CHAR), integer and CAST(integer AS CHAR)... -%unicode|string%(1) "1" -%unicode|string%(5) "three" -%unicode|string%(1) "2" -Using integer only... -int(1) -int(303) -int(2) -Testing bind_param(), strings only... -%unicode|string%(3) "one" -%unicode|string%(5) "three" -%unicode|string%(3) "two" -Testing bind_param(), strings only, with CAST AS CHAR... -%unicode|string%(3) "one" -%unicode|string%(32) "three beers are more than enough" -%unicode|string%(3) "two" done! diff --git a/ext/mysqli/tests/bug45289.phpt b/ext/mysqli/tests/bug45289.phpt index 2c6bbe974..50775b55c 100644 --- a/ext/mysqli/tests/bug45289.phpt +++ b/ext/mysqli/tests/bug45289.phpt @@ -7,25 +7,34 @@ require_once('skipifconnectfailure.inc'); ?> --FILE-- close(); + + $link = mysqli_init(); + if (!($link->real_connect($host, $user, $passwd, $db, $port, $socket))) + printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", + $host, $user, $db, $port, $socket); + $id = 1; if (!($stmt = $link->prepare('SELECT id, label FROM test WHERE id=? LIMIT 1'))) - printf("[001] [%d] %s\n", $link->errno, $link->error); + printf("[002] [%d] %s\n", $link->errno, $link->error); if (!$stmt->bind_param('i', $id) || !$stmt->execute()) - printf("[002] [%d] %s\n", $stmt->errno, $stmt->error); + printf("[003] [%d] %s\n", $stmt->errno, $stmt->error); if ($res = $link->store_result()) { - printf("[003] Can store result!\n"); + if ($IS_MYSQLND) + printf("[004] Can store result!\n"); + else + printf("[004] [007] http://bugs.mysql.com/bug.php?id=47485\n"); } else { - printf("[003] [%d] %s\n", $link->errno, $link->error); + printf("[004] [%d] %s\n", $link->errno, $link->error); } - - var_dump($res->fetch_assoc()); +?> +--CLEAN-- + --EXPECTF-- -[003] [0%s - -Fatal error: Call to a member function fetch_assoc() on a non-object in %s on line %d +[004] [0%s diff --git a/ext/mysqli/tests/bug46614.phpt b/ext/mysqli/tests/bug46614.phpt new file mode 100644 index 000000000..9e7822271 --- /dev/null +++ b/ext/mysqli/tests/bug46614.phpt @@ -0,0 +1,30 @@ +--TEST-- +Bug #46614 (Extended MySQLi class gives incorrect empty() result) +--SKIPIF-- + +--FILE-- +extData[] = 'Bar'; + return empty($this->extData); + } +} + +include ("connect.inc"); +$MySQL_Ext = new MySQL_Ext($host, $user, $passwd, $db, $port, $socket); + +$isEmpty = $MySQL_Ext->isEmpty(); +var_dump($isEmpty); +?> +--EXPECT-- +bool(false) diff --git a/ext/mysqli/tests/bug47050.phpt b/ext/mysqli/tests/bug47050.phpt index 65b677aed..0358802ba 100644 --- a/ext/mysqli/tests/bug47050.phpt +++ b/ext/mysqli/tests/bug47050.phpt @@ -12,7 +12,7 @@ if (!defined("MYSQLI_ASYNC")) { query("SELECT 'test'", MYSQLI_ASYNC); diff --git a/ext/mysqli/tests/bug48909.phpt b/ext/mysqli/tests/bug48909.phpt new file mode 100644 index 000000000..55c85a686 --- /dev/null +++ b/ext/mysqli/tests/bug48909.phpt @@ -0,0 +1,39 @@ +--TEST-- +Bug #48909 (Segmentation fault in mysqli_stmt_execute) +--SKIPIF-- + +--FILE-- +query("DROP TABLE IF EXISTS test") || + !$link->query(sprintf("CREATE TABLE test(id INT, label varchar(255)) ENGINE = %s", $engine))) + printf("[002] [%d] %s\n", $link->errno, $link->error); + + if (!$stmt = $link->prepare("INSERT INTO test(id, label) VALUES (?, ?)")) + printf("[003] [%d] %s\n", $link->errno, $link->error); + + if (!$stmt->bind_param("bb",$bvar, $bvar)) + printf("[004] [%d] %s\n", $stmt->errno, $stmt->error); + + if (!$stmt->execute()) + printf("[005] [%d] %s\n", $stmt->errno, $stmt->error); + + $stmt->close(); + $link->close(); + + echo "done"; +?> +--CLEAN-- + +--EXPECTF-- +done \ No newline at end of file diff --git a/ext/mysqli/tests/bug49027.phpt b/ext/mysqli/tests/bug49027.phpt new file mode 100644 index 000000000..35434bdd2 --- /dev/null +++ b/ext/mysqli/tests/bug49027.phpt @@ -0,0 +1,62 @@ +--TEST-- +Bug #49027 (mysqli_options() doesn't work when using mysqlnd) +--SKIPIF-- + +--FILE-- +query("SELECT 42")->fetch_row()); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test") || + !mysqli_query($link, sprintf("CREATE TABLE test(id INT) ENGINE=%s", $engine))) { + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + } + + mysqli_close($link); + + $link = mysqli_init(); + if (!mysqli_options($link, MYSQLI_INIT_COMMAND, "INSERT INTO test(id) VALUES(1)")) { + printf("[004] Cannot set INIT_COMMAND\n"); + } + + if (!my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)) { + printf("[005] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + } + + if (!$res = mysqli_query($link, "SELECT id FROM test")) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + var_dump(mysqli_fetch_assoc($res)); + + mysqli_free_result($res); + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- + +--EXPECTF-- +array(1) { + [0]=> + %unicode|string%(2) "42" +} +array(1) { + [%u|b%"id"]=> + %unicode|string%(1) "1" +} +done! diff --git a/ext/mysqli/tests/bug49442.phpt b/ext/mysqli/tests/bug49442.phpt new file mode 100644 index 000000000..5323a28ed --- /dev/null +++ b/ext/mysqli/tests/bug49442.phpt @@ -0,0 +1,119 @@ +--TEST-- +Bug #49422 (mysqlnd: mysqli_real_connect() and LOAD DATA INFILE crash) +--SKIPIF-- + +--INI-- +mysqli.allow_local_infile=1 +mysqli.allow_persistent=1 +mysqli.max_persistent=1 +--FILE-- + +--CLEAN-- + +--EXPECTF-- +array(2) { + [%u|b%"id"]=> + %unicode|string%(2) "97" + [%u|b%"label"]=> + %unicode|string%(1) "x" +} +array(2) { + [%u|b%"id"]=> + %unicode|string%(2) "98" + [%u|b%"label"]=> + %unicode|string%(1) "y" +} +array(2) { + [%u|b%"id"]=> + %unicode|string%(2) "99" + [%u|b%"label"]=> + %unicode|string%(1) "z" +} +done! \ No newline at end of file diff --git a/ext/mysqli/tests/clean_table.inc b/ext/mysqli/tests/clean_table.inc new file mode 100644 index 000000000..716cc8441 --- /dev/null +++ b/ext/mysqli/tests/clean_table.inc @@ -0,0 +1,14 @@ + \ No newline at end of file diff --git a/ext/mysqli/tests/connect.inc b/ext/mysqli/tests/connect.inc index 9bb9836b7..ad2428647 100644 --- a/ext/mysqli/tests/connect.inc +++ b/ext/mysqli/tests/connect.inc @@ -16,6 +16,7 @@ $engine = getenv("MYSQL_TEST_ENGINE") ? getenv("MYSQL_TEST_ENGINE") : "MyISAM"; $socket = getenv("MYSQL_TEST_SOCKET") ? getenv("MYSQL_TEST_SOCKET") : null; $skip_on_connect_failure = getenv("MYSQL_TEST_SKIP_CONNECT_FAILURE") ? getenv("MYSQL_TEST_SKIP_CONNECT_FAILURE") : true; + $connect_flags = getenv("MYSQL_TEST_CONNECT_FLAGS") ? (int)getenv("MYSQL_TEST_CONNECT_FLAGS") : 0; /* Development setting: test experimal features and/or feature requests that never worked before? */ $TEST_EXPERIMENTAL = (in_array(getenv("MYSQL_TEST_EXPERIMENTAL"), array(0, 1))) ? @@ -26,11 +27,31 @@ if (!$IS_MYSQLND) { $MYSQLND_VERSION = NULL; } else { + /* + The formatting of the version reported by mysqli_get_client_info() + has changed significantly in the past. To get tests working properly + with PHP 5.3.0 and up, we set everything that looks like prior to + PHP 5.3.0 to version 5.0.4 = 5 * 10000 + 0 * 100 + 4 = 50004. + PHP 5.3.0 reports mysqlnd 5.0.5 dev (= 5 * 10000 + 0 * 100 + 5 = 50005. + */ if (preg_match('@Revision:\s+(\d+)\s*\$@ism', mysqli_get_client_info(), $matches)) { - $MYSQLND_VERSION = (int)$matches[1]; + /* something prior to PHP 5.3.0 */ + $MYSQLND_VERSION = 50004; + } else if (preg_match('@^mysqlnd (\d+)\.(\d+)\.(\d+).*@ism', mysqli_get_client_info(), $matches)) { + /* formatting schema used by PHP 5.3.0 */ + $MYSQLND_VERSION = (int)$matches[1] * 10000 + (int)$matches[2] * 100 + (int)$matches[3]; + } else if (preg_match('@^mysqlnd/PHP 6.0.0-dev@ism', mysqli_get_client_info(), $matches)) { + /* + PHP 6.0 at the time of the first PHP 5.3.0 release. + HEAD and 5.3 have been in sync when 5.3.0 was released. + It is at least 5.0.5-dev. + */ + $MYSQLND_VERSION = 50005; } else { + /* unknown */ $MYSQLND_VERSION = -1; } + } if (!function_exists('sys_get_temp_dir')) { @@ -52,4 +73,54 @@ return FALSE; } } + + /** + * Whenever possible, please use this wrapper to make testing ot MYSQLI_CLIENT_COMPRESS (and potentially SSL) possible + * + * @param enable_env_flags Enable setting of connection flags through env(MYSQL_TEST_CONNECT_FLAGS)? + */ + function my_mysqli_connect($host, $user, $passwd, $db, $port, $socket, $enable_env_flags = true) { + global $connect_flags; + + $flags = ($enable_env_flags) ? $connect_flags : false; + + if ($flags !== false) { + $link = mysqli_init(); + if (!mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, $flags)) + $link = false; + } else { + $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + } + + return $link; + } + + /** + * Whenever possible, please use this wrapper to make testing ot MYSQLI_CLIENT_COMPRESS (and potentially SSL) possible + * + * @param enable_env_flags Enable setting of connection flags through env(MYSQL_TEST_CONNECT_FLAGS) + */ + function my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, $flags = 0, $enable_env_flags = true) { + global $connect_flags; + + if ($enable_env_flags) + $flags & $connect_flags; + + return mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket, $flags); + } + + class my_mysqli extends mysqli { + public function __construct($host, $user, $passwd, $db, $port, $socket, $enable_env_flags = true) { + global $connect_flags; + + $flags = ($enable_env_flags) ? $connect_flags : false; + + if ($flags !== false) { + parent::init(); + $this->real_connect($host, $user, $passwd, $db, $port, $socket, $flags); + } else { + parent::__construct($host, $user, $passwd, $db, $port, $socket); + } + } + } ?> \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_affected_rows.phpt b/ext/mysqli/tests/mysqli_affected_rows.phpt index 24762cc99..6cb5451c0 100644 --- a/ext/mysqli/tests/mysqli_affected_rows.phpt +++ b/ext/mysqli/tests/mysqli_affected_rows.phpt @@ -22,7 +22,7 @@ mysqli_affected_rows() if (!is_null($tmp = @mysqli_affected_rows($link, $link))) printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[004] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -127,5 +127,9 @@ mysqli_affected_rows() print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_affected_rows_oo.phpt b/ext/mysqli/tests/mysqli_affected_rows_oo.phpt index bdbb790b1..07b7bcb48 100644 --- a/ext/mysqli/tests/mysqli_affected_rows_oo.phpt +++ b/ext/mysqli/tests/mysqli_affected_rows_oo.phpt @@ -14,7 +14,7 @@ mysqli->affected_rows if (NULL !== ($tmp = @$mysqli->affected_rows)) printf("[000a] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) { + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) { printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); } @@ -106,5 +106,9 @@ mysqli->affected_rows print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_autocommit.phpt b/ext/mysqli/tests/mysqli_autocommit.phpt index f409baadc..cdd555976 100644 --- a/ext/mysqli/tests/mysqli_autocommit.phpt +++ b/ext/mysqli/tests/mysqli_autocommit.phpt @@ -7,7 +7,7 @@ mysqli_autocommit() require_once('connect.inc'); require_once('skipifconnectfailure.inc'); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { die(sprintf("skip Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket)); } @@ -40,7 +40,7 @@ mysqli_autocommit() if (!is_null($tmp = @mysqli_autocommit($link, $link, $link))) printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[004] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); } @@ -148,5 +148,9 @@ mysqli_autocommit() print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysqli/tests/mysqli_autocommit_oo.phpt b/ext/mysqli/tests/mysqli_autocommit_oo.phpt index 006a5d4ba..8f2c4b472 100644 --- a/ext/mysqli/tests/mysqli_autocommit_oo.phpt +++ b/ext/mysqli/tests/mysqli_autocommit_oo.phpt @@ -7,7 +7,7 @@ mysqli->autocommit() require_once('skipifconnectfailure.inc'); require_once('connect.inc'); - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) { + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) { printf("skip Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); exit(1); @@ -31,7 +31,7 @@ mysqli->autocommit() autocommit() print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_change_user.phpt b/ext/mysqli/tests/mysqli_change_user.phpt index dce00eba6..d889ec820 100644 --- a/ext/mysqli/tests/mysqli_change_user.phpt +++ b/ext/mysqli/tests/mysqli_change_user.phpt @@ -2,7 +2,7 @@ mysqli_change_user() --SKIPIF-- @@ -28,7 +28,7 @@ require_once('skipifconnectfailure.inc'); if (!is_null($tmp = @mysqli_change_user($link, $link, $link, $link, $link))) printf("[005] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[006] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); diff --git a/ext/mysqli/tests/mysqli_change_user_get_lock.phpt b/ext/mysqli/tests/mysqli_change_user_get_lock.phpt index 437e39304..4cc071d7a 100644 --- a/ext/mysqli/tests/mysqli_change_user_get_lock.phpt +++ b/ext/mysqli/tests/mysqli_change_user_get_lock.phpt @@ -70,7 +70,7 @@ sleep(5); /* Ok, let's try a NEW connection and a NEW lock! */ mysqli_close($link); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[010] Cannot open new connection, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); @@ -93,6 +93,10 @@ sleep(5); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Testing GET_LOCK()... ... lock 'phptest_%d' acquired by thread %d diff --git a/ext/mysqli/tests/mysqli_change_user_insert_id.phpt b/ext/mysqli/tests/mysqli_change_user_insert_id.phpt index bbdfc578b..83efb5149 100644 --- a/ext/mysqli/tests/mysqli_change_user_insert_id.phpt +++ b/ext/mysqli/tests/mysqli_change_user_insert_id.phpt @@ -7,7 +7,7 @@ require_once('skipifemb.inc'); require_once('skipifconnectfailure.inc'); require_once('connect.inc'); if (!$IS_MYSQLND) { - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) die("skip Can't test server version, might hit known bugs http://bugs.mysql.com/bug.php?id=30472, http://bugs.mysql.com/bug.php?id=45184"); if (mysqli_get_client_version($link) <= 50135) /* TODO - check wich version got the patch */ @@ -20,7 +20,7 @@ if (!$IS_MYSQLND) { +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt b/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt index 43fa433d0..e40154ce1 100644 --- a/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt +++ b/ext/mysqli/tests/mysqli_change_user_locks_temporary.phpt @@ -12,7 +12,7 @@ die("skip - is the server still buggy?"); require_once('connect.inc'); require_once('table.inc'); - if (!$link2 = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot create second connection handle, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); @@ -99,5 +99,9 @@ die("skip - is the server still buggy?"); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysqli/tests/mysqli_change_user_oo.phpt b/ext/mysqli/tests/mysqli_change_user_oo.phpt index cb7bcf7e8..61444ae23 100644 --- a/ext/mysqli/tests/mysqli_change_user_oo.phpt +++ b/ext/mysqli/tests/mysqli_change_user_oo.phpt @@ -18,7 +18,7 @@ if (!$IS_MYSQLND && (mysqli_get_server_version($link) < 50118 && mysqli_get_serv $link = NULL; $tmp = NULL; - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); diff --git a/ext/mysqli/tests/mysqli_change_user_prepared_statements.phpt b/ext/mysqli/tests/mysqli_change_user_prepared_statements.phpt index aa8eb4176..6a37b6b44 100644 --- a/ext/mysqli/tests/mysqli_change_user_prepared_statements.phpt +++ b/ext/mysqli/tests/mysqli_change_user_prepared_statements.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_change_user_set_names.phpt b/ext/mysqli/tests/mysqli_change_user_set_names.phpt index d734ee886..362873c84 100644 --- a/ext/mysqli/tests/mysqli_change_user_set_names.phpt +++ b/ext/mysqli/tests/mysqli_change_user_set_names.phpt @@ -6,7 +6,7 @@ require_once('skipif.inc'); require_once('skipifemb.inc'); require_once('skipifconnectfailure.inc'); -if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) die(sprintf("skip [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); if (!$res = mysqli_query($link, 'SELECT version() AS server_version')) @@ -25,7 +25,7 @@ if ($version[0] <= 4 && $version[1] < 1) ') == 1) { $tmp = NULL; $link = NULL; - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -100,5 +100,9 @@ if (version_compare(PHP_VERSION, '5.9.9', '>') == 1) { print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysqli/tests/mysqli_character_set_name.phpt b/ext/mysqli/tests/mysqli_character_set_name.phpt index 03bc31159..9a40099fe 100644 --- a/ext/mysqli/tests/mysqli_character_set_name.phpt +++ b/ext/mysqli/tests/mysqli_character_set_name.phpt @@ -1,8 +1,8 @@ --TEST-- mysqli_chararcter_set_name(), mysql_client_encoding() [alias] --SKIPIF-- - @@ -23,7 +23,7 @@ require_once('skipifconnectfailure.inc'); if (!is_null($tmp = @mysqli_character_set_name($link, $link, $link))) printf("[003] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[005] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); diff --git a/ext/mysqli/tests/mysqli_character_set_name_oo.phpt b/ext/mysqli/tests/mysqli_character_set_name_oo.phpt index 018a90ad8..a56cf6ae8 100644 --- a/ext/mysqli/tests/mysqli_character_set_name_oo.phpt +++ b/ext/mysqli/tests/mysqli_character_set_name_oo.phpt @@ -1,7 +1,7 @@ --TEST-- mysqli_chararcter_set_name(), mysql_client_encoding() [alias] --SKIPIF-- - --FILE-- unknown = $unknown; printf("setting mysqli->unknown, mysqli_unknown = '%s'\n", @$mysqli->unknown); - $mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket); + $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); printf("\nAccess hidden properties for MYSLQI_STATUS_INITIALIZED (TODO documentation):\n"); assert(mysqli_connect_error() === $mysqli->connect_error); printf("mysqli->connect_error = '%s'/%s ('%s'/%s)\n", diff --git a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt index 51dc05ed5..802e52433 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_reflection.phpt @@ -15,8 +15,8 @@ Those tests go into the details and are aimed to be a development tool, no more. */ if (!$IS_MYSQLND) die("skip Test has been written for the latest version of mysqlnd only"); -if ($MYSQLND_VERSION < 576) - die("skip Test requires mysqlnd Revision 576 or newer"); +if ($MYSQLND_VERSION < 50004) + die("skip Test requires mysqlnd Revision 5.0.4 or newer"); ?> --FILE-- @@ -423,6 +423,22 @@ Modifiers: 256 Number of Parameters: 0 Number of Required Parameters: 0 +Inspecting method 'poll' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + Inspecting method 'prepare' isFinal: no isAbstract: no @@ -503,6 +519,38 @@ Modifiers: 256 Number of Parameters: 0 Number of Required Parameters: 0 +Inspecting method 'reap_async_query' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + +Inspecting method 'refresh' +isFinal: no +isAbstract: no +isPublic: yes +isPrivate: no +isProtected: no +isStatic: no +isConstructor: no +isDestructor: no +isInternal: yes +isUserDefined: no +returnsReference: no +Modifiers: 256 +Number of Parameters: 0 +Number of Required Parameters: 0 + Inspecting method 'rollback' isFinal: no isAbstract: no @@ -799,5 +847,4 @@ Default property 'server_version' Default property 'sqlstate' Default property 'thread_id' Default property 'warning_count' -done! - +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt b/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt index de4fb87ca..b327fe656 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_result_interface.phpt @@ -11,11 +11,11 @@ require_once('skipifconnectfailure.inc'); require('connect.inc'); require('table.inc'); - $mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket); + $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); $mysqli_result = $mysqli->query('SELECT * FROM test'); $row = $mysqli_result->fetch_row(); - $link = mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); $res = mysqli_query($link, 'SELECT * FROM test'); assert(mysqli_fetch_row($res) === $row); diff --git a/ext/mysqli/tests/mysqli_class_mysqli_result_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_result_reflection.phpt index 5f26d1eb5..cf5973249 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_result_reflection.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_result_reflection.phpt @@ -17,8 +17,8 @@ Those tests go into the details and are aimed to be a development tool, no more. */ if (!$IS_MYSQLND) die("skip Test has been written for the latest version of mysqlnd only"); -if ($MYSQLND_VERSION < 576) - die("skip Test requires mysqlnd Revision 576 or newer"); +if ($MYSQLND_VERSION < 50004) + die("skip Test requires mysqlnd Revision 5.0.4 or newer"); ?> --FILE-- unknown = '13' Prepare using the constructor: -Warning: mysqli_stmt::__construct() expects parameter 2 to be string, object given in %s on line %d +Warning: mysqli_stmt::__construct() expects parameter 2 to be %binary_string_optional%, object given in %s on line %d done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_class_mysqli_warning.phpt b/ext/mysqli/tests/mysqli_class_mysqli_warning.phpt index 0d1d3a017..62f01cac6 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_warning.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_warning.phpt @@ -21,7 +21,7 @@ if (!$TEST_EXPERIMENTAL) $mysqli = new mysqli(); $warning = new mysqli_warning($mysqli); - $mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket); + $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); $stmt = new mysqli_stmt($mysqli); $warning = new mysqli_warning($stmt); @@ -32,7 +32,7 @@ if (!$TEST_EXPERIMENTAL) $warning = new mysqli_warning($obj); include("table.inc"); - $mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket); + $mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket); $res = $mysqli->query('INSERT INTO test(id, label) VALUES (1, "zz")'); $warning = mysqli_get_warnings($mysqli); @@ -89,6 +89,10 @@ if (!$TEST_EXPERIMENTAL) print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: Wrong parameter count for mysqli_warning::mysqli_warning() in %s on line %d diff --git a/ext/mysqli/tests/mysqli_class_mysqli_warning_reflection.phpt b/ext/mysqli/tests/mysqli_class_mysqli_warning_reflection.phpt index cb690437a..dc0c14e6e 100644 --- a/ext/mysqli/tests/mysqli_class_mysqli_warning_reflection.phpt +++ b/ext/mysqli/tests/mysqli_class_mysqli_warning_reflection.phpt @@ -16,8 +16,8 @@ Those tests go into the details and are aimed to be a development tool, no more. */ if (!$IS_MYSQLND) die("skip Test has been written for the latest version of mysqlnd only"); -if ($MYSQLND_VERSION < 576) - die("skip Test requires mysqlnd Revision 576 or newer"); +if ($MYSQLND_VERSION < 50004) + die("skip Test requires mysqlnd Revision 5.0.4 or newer"); ?> --FILE-- --FILE-- @@ -19,7 +19,7 @@ require_once('skipifconnectfailure.inc'); if (!is_null($tmp = @mysqli_close($link, $link))) printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); diff --git a/ext/mysqli/tests/mysqli_close_oo.phpt b/ext/mysqli/tests/mysqli_close_oo.phpt index 706767458..c3d6a9397 100644 --- a/ext/mysqli/tests/mysqli_close_oo.phpt +++ b/ext/mysqli/tests/mysqli_close_oo.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_close() --SKIPIF-- - --FILE-- @@ -13,7 +13,7 @@ require_once('skipifconnectfailure.inc'); $tmp = NULL; $link = NULL; - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); diff --git a/ext/mysqli/tests/mysqli_commit.phpt b/ext/mysqli/tests/mysqli_commit.phpt index e19e63564..6a3c1e86c 100644 --- a/ext/mysqli/tests/mysqli_commit.phpt +++ b/ext/mysqli/tests/mysqli_commit.phpt @@ -1,12 +1,12 @@ --TEST-- mysqli_commit() --SKIPIF-- - +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_commit_oo.phpt b/ext/mysqli/tests/mysqli_commit_oo.phpt index 7323db78f..8d072999c 100644 --- a/ext/mysqli/tests/mysqli_commit_oo.phpt +++ b/ext/mysqli/tests/mysqli_commit_oo.phpt @@ -1,11 +1,11 @@ --TEST-- mysqli_commit() --SKIPIF-- -commit())) printf("[013] Expecting NULL got %s/%s\n", gettype($tmp), $tmp); - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -80,5 +80,9 @@ if ($row[1] == "DISABLED" || $row[1] == "NO") { print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_connect_errno.phpt b/ext/mysqli/tests/mysqli_connect_errno.phpt index f1b1d7b01..b48a75ef8 100644 --- a/ext/mysqli/tests/mysqli_connect_errno.phpt +++ b/ext/mysqli/tests/mysqli_connect_errno.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_connect_errno() --SKIPIF-- - --FILE-- @@ -17,7 +17,7 @@ require_once('skipifconnectfailure.inc'); if (0 !== ($tmp = @mysqli_connect_errno($link))) printf("[001] Expecting integer/0, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -26,10 +26,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - $link = @mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket); + $link = @my_mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket); if (false !== $link) printf("[004] Connect to the server should fail using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s, expecting boolean/false, got %s/%s\n", - $host, $user . 'unknown_really', $db, $port, $socket, gettype($link), $link); + $host, $user . 'unknown_really', $db, $port, $socket, gettype($link), var_export($link, true)); if (0 === ($tmp = mysqli_connect_errno())) printf("[005] Expecting integer/any non-zero, got %s/%s\n", gettype($tmp), $tmp); diff --git a/ext/mysqli/tests/mysqli_connect_error.phpt b/ext/mysqli/tests/mysqli_connect_error.phpt index 5016acf24..e65dc0eb0 100644 --- a/ext/mysqli/tests/mysqli_connect_error.phpt +++ b/ext/mysqli/tests/mysqli_connect_error.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_connect_error() --SKIPIF-- - --FILE-- @@ -17,7 +17,7 @@ require_once('skipifconnectfailure.inc'); if (!is_null($tmp = @mysqli_connect_error($link))) printf("[001] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -26,7 +26,7 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if ($link = @mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + if ($link = @my_mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) printf("[003] Connect to the server should fail using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", $host, $user . 'unknown_really', $db, $port, $socket); diff --git a/ext/mysqli/tests/mysqli_connect_twice.phpt b/ext/mysqli/tests/mysqli_connect_twice.phpt index debc435b0..7c6a726b2 100644 --- a/ext/mysqli/tests/mysqli_connect_twice.phpt +++ b/ext/mysqli/tests/mysqli_connect_twice.phpt @@ -10,14 +10,14 @@ require_once('skipifconnectfailure.inc'); --FILE-- $consts) { foreach ($consts as $name => $value) { if (stristr($name, 'mysqli')) { - if ('mysqli' !== $group) + if ('mysqli' != $group) printf("found constant '%s' in group '%s'. expecting group 'mysqli'\n", $name, $group); } } diff --git a/ext/mysqli/tests/mysqli_data_seek.phpt b/ext/mysqli/tests/mysqli_data_seek.phpt index d25347ade..cb54c8003 100644 --- a/ext/mysqli/tests/mysqli_data_seek.phpt +++ b/ext/mysqli/tests/mysqli_data_seek.phpt @@ -63,6 +63,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d diff --git a/ext/mysqli/tests/mysqli_data_seek_oo.phpt b/ext/mysqli/tests/mysqli_data_seek_oo.phpt index 40fabe1ce..e75a04f36 100644 --- a/ext/mysqli/tests/mysqli_data_seek_oo.phpt +++ b/ext/mysqli/tests/mysqli_data_seek_oo.phpt @@ -72,6 +72,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_result::data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d diff --git a/ext/mysqli/tests/mysqli_debug.phpt b/ext/mysqli/tests/mysqli_debug.phpt index da41894b1..2b754eac3 100644 --- a/ext/mysqli/tests/mysqli_debug.phpt +++ b/ext/mysqli/tests/mysqli_debug.phpt @@ -61,5 +61,9 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) print "done!"; ?> +--CLEAN-- + --EXPECTF-- done%s diff --git a/ext/mysqli/tests/mysqli_debug_append.phpt b/ext/mysqli/tests/mysqli_debug_append.phpt index 671b3821e..f15365f2e 100644 --- a/ext/mysqli/tests/mysqli_debug_append.phpt +++ b/ext/mysqli/tests/mysqli_debug_append.phpt @@ -82,5 +82,9 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) if ($IS_MYSQLND) print "libmysql/DBUG package prints some debug info here." ?> +--CLEAN-- + --EXPECTF-- done%s diff --git a/ext/mysqli/tests/mysqli_debug_ini.phpt b/ext/mysqli/tests/mysqli_debug_ini.phpt index 7581385a9..859a44c32 100644 --- a/ext/mysqli/tests/mysqli_debug_ini.phpt +++ b/ext/mysqli/tests/mysqli_debug_ini.phpt @@ -15,8 +15,8 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) die("skip: debug functionality not enabled"); require_once('connect.inc'); -if (!$IS_MYSQLND || ($MYSQLND_VERSION < 940)) - die("skip needs mysqlnd version/revision 940+"); +if (!$IS_MYSQLND || ($MYSQLND_VERSION < 50004)) + die("skip needs mysqlnd version/revision 5.0.4"); if (!$fp = @fopen('/tmp/mysqli_debug_phpt.trace', 'w')) die("skip PHP cannot create a file in /tmp/mysqli_debug_phpt"); diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt index db9ceb382..9b43e15bd 100644 --- a/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt +++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_control_string.phpt @@ -218,6 +218,10 @@ if (defined('MYSQLI_DEBUG_TRACE_ENABLED') && !MYSQLI_DEBUG_TRACE_ENABLED) print "libmysql/DBUG package prints some debug info here."; @unlink($trace_file); ?> +--CLEAN-- + --EXPECTF-- [083][control string 'n:O,/tmp/mysqli_debug_phpt.trace'] Trace file has not been written. done%s diff --git a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt index fc9f7a802..8ecf516ca 100644 --- a/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt +++ b/ext/mysqli/tests/mysqli_debug_mysqlnd_only.phpt @@ -120,5 +120,9 @@ if (!$IS_MYSQLND) @unlink($trace_file); print "done!"; ?> +--CLEAN-- + --EXPECTF-- -done! +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt b/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt index 80a37f8f9..79f081f50 100644 --- a/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt +++ b/ext/mysqli/tests/mysqli_disable_reads_from_master.phpt @@ -23,7 +23,7 @@ if (!function_exists('mysqli_disable_reads_from_master')) { if (NULL !== ($tmp = @mysqli_disable_reads_from_master($link))) printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); } @@ -38,6 +38,10 @@ if (!function_exists('mysqli_disable_reads_from_master')) { print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_disable_reads_from_master(): Couldn't fetch mysqli in %s on line %d done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_driver.phpt b/ext/mysqli/tests/mysqli_driver.phpt index 765fee527..a2d1437a2 100644 --- a/ext/mysqli/tests/mysqli_driver.phpt +++ b/ext/mysqli/tests/mysqli_driver.phpt @@ -46,7 +46,7 @@ require_once('skipifconnectfailure.inc'); $ok = false; try { - if ($link = mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + if ($link = my_mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) printf("[007] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", $host, $user . 'unknown_really', $db, $port, $socket); mysqli_close($link); @@ -75,14 +75,14 @@ require_once('skipifconnectfailure.inc'); $driver->report_mode = MYSQLI_REPORT_OFF; - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[016] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); mysqli_query($link, "NO_SQL"); mysqli_close($link); $driver->report_mode = MYSQLI_REPORT_ERROR; - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[017] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); mysqli_query($link, "NO_SQL"); mysqli_close($link); diff --git a/ext/mysqli/tests/mysqli_dump_debug_info.phpt b/ext/mysqli/tests/mysqli_dump_debug_info.phpt index d93738edc..fe253e1cf 100644 --- a/ext/mysqli/tests/mysqli_dump_debug_info.phpt +++ b/ext/mysqli/tests/mysqli_dump_debug_info.phpt @@ -19,7 +19,7 @@ require_once('skipifconnectfailure.inc'); if (NULL !== ($tmp = @mysqli_dump_debug_info($link))) printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); exit(1); diff --git a/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt b/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt index 2228f3d6c..171ed5650 100644 --- a/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt +++ b/ext/mysqli/tests/mysqli_enable_reads_from_master.phpt @@ -1,8 +1,8 @@ --TEST-- mysqli_enable_reads_from_master() --SKIPIF-- - @@ -19,7 +19,7 @@ require_once('skipifconnectfailure.inc'); if (!is_null($tmp = @mysqli_errno($link))) printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); } diff --git a/ext/mysqli/tests/mysqli_errno_oo.phpt b/ext/mysqli/tests/mysqli_errno_oo.phpt index 09f7d6ed3..032f70a87 100644 --- a/ext/mysqli/tests/mysqli_errno_oo.phpt +++ b/ext/mysqli/tests/mysqli_errno_oo.phpt @@ -1,8 +1,8 @@ --TEST-- $mysqli->errno --SKIPIF-- - diff --git a/ext/mysqli/tests/mysqli_error.phpt b/ext/mysqli/tests/mysqli_error.phpt index 8a2a749a6..517388045 100644 --- a/ext/mysqli/tests/mysqli_error.phpt +++ b/ext/mysqli/tests/mysqli_error.phpt @@ -1,8 +1,8 @@ --TEST-- mysqli_error() --SKIPIF-- - @@ -19,7 +19,7 @@ require_once('skipifconnectfailure.inc'); if (!is_null($tmp = @mysqli_error($link))) printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); } diff --git a/ext/mysqli/tests/mysqli_error_unicode.phpt b/ext/mysqli/tests/mysqli_error_unicode.phpt index 09ab5a999..8789f89e8 100644 --- a/ext/mysqli/tests/mysqli_error_unicode.phpt +++ b/ext/mysqli/tests/mysqli_error_unicode.phpt @@ -24,7 +24,7 @@ require_once('skipifconnectfailure.inc'); $host, $user, $db, $port, $socket); } - if (!ini_get("unicode.semantics")) { + if (!(version_compare(PHP_VERSION, '5.9.9', '>') == 1)) { mysqli_query($link, "set names utf8"); } diff --git a/ext/mysqli/tests/mysqli_explain_metadata.phpt b/ext/mysqli/tests/mysqli_explain_metadata.phpt index a8cc59d7c..5bfb001a1 100644 --- a/ext/mysqli/tests/mysqli_explain_metadata.phpt +++ b/ext/mysqli/tests/mysqli_explain_metadata.phpt @@ -151,5 +151,9 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysqli/tests/mysqli_fetch_all.phpt b/ext/mysqli/tests/mysqli_fetch_all.phpt index 0a8a7dec2..26401e7cc 100644 --- a/ext/mysqli/tests/mysqli_fetch_all.phpt +++ b/ext/mysqli/tests/mysqli_fetch_all.phpt @@ -297,6 +297,10 @@ if (!function_exists('mysqli_fetch_all')) print "done!"; ?> +--CLEAN-- + --EXPECTF-- [005] array(2) { diff --git a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt index e891f08d5..297d92ac7 100644 --- a/ext/mysqli/tests/mysqli_fetch_all_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_all_oo.phpt @@ -18,7 +18,7 @@ if (!function_exists('mysqli_fetch_all')) $mysqli = new mysqli(); - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -300,6 +300,10 @@ if (!function_exists('mysqli_fetch_all')) print "done!"; ?> +--CLEAN-- + --EXPECTF-- [005] array(2) { diff --git a/ext/mysqli/tests/mysqli_fetch_array_assoc.phpt b/ext/mysqli/tests/mysqli_fetch_array_assoc.phpt index 99d573200..d85eb9e6f 100644 --- a/ext/mysqli/tests/mysqli_fetch_array_assoc.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array_assoc.phpt @@ -28,6 +28,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- [002] array(2) { diff --git a/ext/mysqli/tests/mysqli_fetch_array_large.phpt b/ext/mysqli/tests/mysqli_fetch_array_large.phpt new file mode 100644 index 000000000..aa8c76871 --- /dev/null +++ b/ext/mysqli/tests/mysqli_fetch_array_large.phpt @@ -0,0 +1,150 @@ +--TEST-- +mysqli_fetch_array() - large packages (to test compression) +--SKIPIF-- + +--FILE-- + 0) ? parse_memory_limit(ini_get('memory_limit')) : pow(2, 32); + + /* try to respect php.ini but make run time a soft limit */ + $max_runtime = (ini_get('max_execution_time') > 0) ? ini_get('max_execution_time') : 30; + set_time_limit(0); + + do { + if ($package_size > $limit) { + printf("stop: memory limit - %s vs. %s\n", $package_size, $limit); + break; + } + + $start = microtime(true); + if (!mysqli_fetch_array_large($offset++, $link, $package_size)) { + printf("stop: packet size - %d\n", $package_size); + break; + } + + $duration = microtime(true) - $start; + $max_runtime -= $duration; + if ($max_runtime < ($duration * 3)) { + /* likely the next iteration will not be within max_execution_time */ + printf("stop: time limit - %2.2fs\n", $max_runtime); + break; + } + + $package_size += $package_size; + + } while (true); + + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- + +--EXPECTF-- +stop: %s +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt b/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt index 6c8e58a88..c9ed7ccac 100644 --- a/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array_many_rows.phpt @@ -108,5 +108,9 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_array_oo.phpt b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt index e7e7d12d8..fcabb5903 100644 --- a/ext/mysqli/tests/mysqli_fetch_array_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_array_oo.phpt @@ -14,7 +14,7 @@ require_once('skipifconnectfailure.inc'); $link = NULL; require('table.inc'); - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -273,6 +273,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- [005] array(4) { diff --git a/ext/mysqli/tests/mysqli_fetch_assoc.phpt b/ext/mysqli/tests/mysqli_fetch_assoc.phpt index 6ea05caf6..6aaed3eb1 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc.phpt @@ -67,6 +67,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- [005] array(2) { diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt index dc01154da..d9bdcfad3 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_bit.phpt @@ -34,7 +34,7 @@ mysqli_fetch_assoc() - BIT return $bin; } - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -109,5 +109,9 @@ mysqli_fetch_assoc() - BIT mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt index 3ba0218a3..e9a746ec0 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_oo.phpt @@ -20,7 +20,7 @@ require_once('skipifconnectfailure.inc'); printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); require('table.inc'); - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -54,6 +54,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- [005] array(2) { diff --git a/ext/mysqli/tests/mysqli_fetch_assoc_zerofill.phpt b/ext/mysqli/tests/mysqli_fetch_assoc_zerofill.phpt index 35bbfb7ba..ce7e82dc0 100644 --- a/ext/mysqli/tests/mysqli_fetch_assoc_zerofill.phpt +++ b/ext/mysqli/tests/mysqli_fetch_assoc_zerofill.phpt @@ -70,5 +70,9 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_field.phpt b/ext/mysqli/tests/mysqli_fetch_field.phpt index 57952967f..dba9f2f55 100644 --- a/ext/mysqli/tests/mysqli_fetch_field.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field.phpt @@ -56,6 +56,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- object(stdClass)#%d (11) { [%u|b%"name"]=> diff --git a/ext/mysqli/tests/mysqli_fetch_field_direct.phpt b/ext/mysqli/tests/mysqli_fetch_field_direct.phpt index 2eb7cd28d..5b4dc5671 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_direct.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_direct.phpt @@ -40,6 +40,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_fetch_field_direct(): Field offset is invalid for resultset in %s on line %d bool(false) diff --git a/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt b/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt index a8ad58e00..f1075139e 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_direct_oo.phpt @@ -20,7 +20,7 @@ require_once('skipifconnectfailure.inc'); require('table.inc'); - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -49,6 +49,10 @@ require_once('skipifconnectfailure.inc'); $mysqli->close(); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_result::fetch_field_direct(): Field offset is invalid for resultset in %s on line %d bool(false) diff --git a/ext/mysqli/tests/mysqli_fetch_field_flags.phpt b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt index 9c74408c2..6f1cea20c 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_flags.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_flags.phpt @@ -7,7 +7,7 @@ require_once('skipifemb.inc'); require_once('skipifconnectfailure.inc'); require_once('connect.inc'); -if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) die(printf("skip: [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error())); if (mysqli_get_server_version($link) < 50041) @@ -101,7 +101,7 @@ mysqli_close($link); return array($expected_flags, $unexpected_flags, $found_flags); } - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); foreach ($columns as $column_def => $expected_flags) { @@ -229,5 +229,9 @@ mysqli_close($link); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_field_oo.phpt b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt index d7e255b83..2c169ed3f 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_oo.phpt @@ -44,6 +44,10 @@ require_once('skipifconnectfailure.inc'); $mysqli->close(); print "done!"; ?> +--CLEAN-- + --EXPECTF-- object(stdClass)#%d (11) { [%u|b%"name"]=> diff --git a/ext/mysqli/tests/mysqli_fetch_field_types.phpt b/ext/mysqli/tests/mysqli_fetch_field_types.phpt index fa9825354..ae18f0ca6 100644 --- a/ext/mysqli/tests/mysqli_fetch_field_types.phpt +++ b/ext/mysqli/tests/mysqli_fetch_field_types.phpt @@ -115,5 +115,9 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_fetch_fields.phpt b/ext/mysqli/tests/mysqli_fetch_fields.phpt index de21d2cd6..0acec5477 100644 --- a/ext/mysqli/tests/mysqli_fetch_fields.phpt +++ b/ext/mysqli/tests/mysqli_fetch_fields.phpt @@ -37,6 +37,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- object(stdClass)#%d (11) { [%u|b%"name"]=> diff --git a/ext/mysqli/tests/mysqli_fetch_lengths.phpt b/ext/mysqli/tests/mysqli_fetch_lengths.phpt index 054bfcb29..71c234922 100644 --- a/ext/mysqli/tests/mysqli_fetch_lengths.phpt +++ b/ext/mysqli/tests/mysqli_fetch_lengths.phpt @@ -36,6 +36,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- bool(false) array(2) { diff --git a/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt b/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt index 3689c69fc..ef7d7622f 100644 --- a/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_lengths_oo.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); close(); print "done!"; ?> +--CLEAN-- + + --EXPECTF-- NULL array(2) { diff --git a/ext/mysqli/tests/mysqli_fetch_object.phpt b/ext/mysqli/tests/mysqli_fetch_object.phpt index 39cfd0518..f164c4e19 100644 --- a/ext/mysqli/tests/mysqli_fetch_object.phpt +++ b/ext/mysqli/tests/mysqli_fetch_object.phpt @@ -131,6 +131,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: Missing argument 1 for mysqli_fetch_object_construct::__construct() in %s on line %d diff --git a/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt b/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt index 9fc795a10..fc7efe4b2 100644 --- a/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt +++ b/ext/mysqli/tests/mysqli_fetch_object_no_constructor.phpt @@ -44,6 +44,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- No exception with PHP: object(mysqli_fetch_object_test)#%d (%d) { diff --git a/ext/mysqli/tests/mysqli_fetch_object_no_object.phpt b/ext/mysqli/tests/mysqli_fetch_object_no_object.phpt index a9173d093..c76742226 100644 --- a/ext/mysqli/tests/mysqli_fetch_object_no_object.phpt +++ b/ext/mysqli/tests/mysqli_fetch_object_no_object.phpt @@ -19,6 +19,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- %s(6) "object" done! diff --git a/ext/mysqli/tests/mysqli_fetch_object_oo.phpt b/ext/mysqli/tests/mysqli_fetch_object_oo.phpt index fe3434cf6..10b39e2ec 100644 --- a/ext/mysqli/tests/mysqli_fetch_object_oo.phpt +++ b/ext/mysqli/tests/mysqli_fetch_object_oo.phpt @@ -19,7 +19,7 @@ require_once('skipifconnectfailure.inc'); printf("[001] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); require('table.inc'); - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -105,6 +105,10 @@ require_once('skipifconnectfailure.inc'); $mysqli->close(); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: Missing argument 1 for mysqli_fetch_object_construct::__construct() in %s on line %d diff --git a/ext/mysqli/tests/mysqli_fetch_row.phpt b/ext/mysqli/tests/mysqli_fetch_row.phpt index 6723fdb65..bb44fd418 100644 --- a/ext/mysqli/tests/mysqli_fetch_row.phpt +++ b/ext/mysqli/tests/mysqli_fetch_row.phpt @@ -37,6 +37,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- [004] array(3) { diff --git a/ext/mysqli/tests/mysqli_field_count.phpt b/ext/mysqli/tests/mysqli_field_count.phpt index be8c3075d..5c63b86f6 100644 --- a/ext/mysqli/tests/mysqli_field_count.phpt +++ b/ext/mysqli/tests/mysqli_field_count.phpt @@ -47,6 +47,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- int(0) int(2) diff --git a/ext/mysqli/tests/mysqli_field_seek.phpt b/ext/mysqli/tests/mysqli_field_seek.phpt index 207471974..9d17f1a75 100644 --- a/ext/mysqli/tests/mysqli_field_seek.phpt +++ b/ext/mysqli/tests/mysqli_field_seek.phpt @@ -101,6 +101,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_field_seek(): Invalid field offset in %s on line %d bool(false) diff --git a/ext/mysqli/tests/mysqli_field_tell.phpt b/ext/mysqli/tests/mysqli_field_tell.phpt index 81626346a..9609a7c5d 100644 --- a/ext/mysqli/tests/mysqli_field_tell.phpt +++ b/ext/mysqli/tests/mysqli_field_tell.phpt @@ -54,6 +54,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- int(0) diff --git a/ext/mysqli/tests/mysqli_fork.phpt b/ext/mysqli/tests/mysqli_fork.phpt index d5d8ad11f..7e5aac928 100644 --- a/ext/mysqli/tests/mysqli_fork.phpt +++ b/ext/mysqli/tests/mysqli_fork.phpt @@ -13,7 +13,7 @@ if (!function_exists('posix_getpid')) die("skip POSIX functions not available"); require_once('connect.inc'); -if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { die(sprintf("skip Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket)); } @@ -68,7 +68,7 @@ if ($row[1] == "DISABLED" || $row[1] == "NO") { gettype($errno), $errno, gettype($error), $error); mysqli_close($link); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[005] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -97,7 +97,7 @@ if ($row[1] == "DISABLED" || $row[1] == "NO") { case 0: /* child */ - if (!($plink = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) || !mysqli_autocommit($plink, true)) + if (!($plink = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) || !mysqli_autocommit($plink, true)) exit(mysqli_errno($plink)); $sql = sprintf("INSERT INTO messages(pid, sender, msg) VALUES (%d, 'child', '%%s')", posix_getpid()); @@ -141,7 +141,7 @@ if ($row[1] == "DISABLED" || $row[1] == "NO") { default: /* parent */ - if (!$plink = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$plink = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[010] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -221,7 +221,7 @@ if ($row[1] == "DISABLED" || $row[1] == "NO") { mysqli_free_result($res); mysqli_close($link); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[018] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -234,6 +234,20 @@ if ($row[1] == "DISABLED" || $row[1] == "NO") { print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(1) { ["message"]=> diff --git a/ext/mysqli/tests/mysqli_free_result.phpt b/ext/mysqli/tests/mysqli_free_result.phpt index 32f57078d..145435358 100644 --- a/ext/mysqli/tests/mysqli_free_result.phpt +++ b/ext/mysqli/tests/mysqli_free_result.phpt @@ -51,6 +51,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- a NULL diff --git a/ext/mysqli/tests/mysqli_get_cache_stats.phpt b/ext/mysqli/tests/mysqli_get_cache_stats.phpt index c9dcc0959..d49e399bb 100644 --- a/ext/mysqli/tests/mysqli_get_cache_stats.phpt +++ b/ext/mysqli/tests/mysqli_get_cache_stats.phpt @@ -1,5 +1,10 @@ --TEST-- mysqli_get_cache_stats() +--XFAIL-- +zval caching has been temporarily disabled for the 5.3.0 release +--INI-- +mysqlnd.collect_statistics="1" +mysqlnd.collect_memory_statistics="1" --SKIPIF-- +--CLEAN-- + --EXPECTF-- array(7) { [%u|b%"put_hits"]=> diff --git a/ext/mysqli/tests/mysqli_get_cache_stats_free_buffered.phpt b/ext/mysqli/tests/mysqli_get_cache_stats_free_buffered.phpt index 969a21be9..0bb90fa71 100644 --- a/ext/mysqli/tests/mysqli_get_cache_stats_free_buffered.phpt +++ b/ext/mysqli/tests/mysqli_get_cache_stats_free_buffered.phpt @@ -1,5 +1,10 @@ --TEST-- mysqli_get_cache_stats() - freeing for buffered result sets +--XFAIL-- +zval caching has been temporarily disabled for the 5.3.0 release +--INI-- +mysqlnd.collect_statistics="1" +mysqlnd.collect_memory_statistics="1" --SKIPIF-- +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_cache_stats_off.phpt b/ext/mysqli/tests/mysqli_get_cache_stats_off.phpt new file mode 100644 index 000000000..4b0bab240 --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_cache_stats_off.phpt @@ -0,0 +1,64 @@ +--TEST-- +mysqli_get_cache_stats() - disabled via php.ini +--INI-- +mysqlnd.collect_statistics="0" +mysqlnd.collect_memory_statistics="0" +--SKIPIF-- + +--FILE-- + true); + foreach ($before as $k => $v) { + if (isset($ignore[$k])) + continue; + + if ($before[$k] != $after[$k]) + printf("[004] Statistics have changed - %s: %s => %s\n", $ + $k, $before[$k], $after[$k]); + } + + $ignore = array("size" => true, "free_items" => true, "references" => true); + foreach ($after as $k => $v) { + if ($v != 0 && !isset($ignore[$k])) { + printf("[005] Field %s should not have any other value but 0, got %s.\n", + $k, $v); + } + } + + mysqli_close($link); + + print "done!"; +?> +--CLEAN-- + +--EXPECTF-- +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_charset.phpt b/ext/mysqli/tests/mysqli_get_charset.phpt index 128e07f82..314853dc0 100644 --- a/ext/mysqli/tests/mysqli_get_charset.phpt +++ b/ext/mysqli/tests/mysqli_get_charset.phpt @@ -106,6 +106,10 @@ if (!function_exists('mysqli_get_charset')) print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_get_charset(): Couldn't fetch mysqli in %s on line %d done! diff --git a/ext/mysqli/tests/mysqli_get_client_stats.phpt b/ext/mysqli/tests/mysqli_get_client_stats.phpt index dd1ccfdea..ed75f7bc5 100644 --- a/ext/mysqli/tests/mysqli_get_client_stats.phpt +++ b/ext/mysqli/tests/mysqli_get_client_stats.phpt @@ -91,7 +91,7 @@ mysqlnd.collect_memory_statistics=1 var_dump($info); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); exit(1); @@ -118,7 +118,7 @@ mysqlnd.collect_memory_statistics=1 mysqli_get_client_stats_assert_eq('result_set_queries', $new_info, $info, $test_counter); /* we need to skip this test in unicode - we send set names utf8 during mysql_connect */ - if (!ini_get("unicode.semantics")) + if (!(version_compare(PHP_VERSION, '5.9.9', '>') == 1)) mysqli_get_client_stats_assert_eq('non_result_set_queries', $new_info, $info, $test_counter); mysqli_get_client_stats_assert_eq('buffered_sets', $new_info, $info, $test_counter); mysqli_get_client_stats_assert_eq('unbuffered_sets', $new_info, $info, $test_counter); @@ -840,6 +840,8 @@ mysqlnd.collect_memory_statistics=1 mysqli_get_client_stats_assert_eq('buffered_sets', $new_info, (string)($info['buffered_sets'] + 1), $test_counter, 'mysqli_use_result()'); $info = $new_info; + mysqli_close($link); + /* no_index_used @@ -858,8 +860,34 @@ mysqlnd.collect_memory_statistics=1 print "done!"; ?> +--CLEAN-- + --EXPECTF-- -array(119) { +array(121) { [%u|b%"bytes_sent"]=> %unicode|string%(1) "0" [%u|b%"bytes_received"]=> @@ -1005,9 +1033,9 @@ array(119) { [%u|b%"mem_malloc_ammount"]=> %unicode|string%(1) "0" [%u|b%"mem_calloc_count"]=> - %unicode|string%(1) "0" + %unicode|string%(%d) "%d" [%u|b%"mem_calloc_ammount"]=> - %unicode|string%(1) "0" + %unicode|string%(%d) "%d" [%u|b%"mem_realloc_count"]=> %unicode|string%(1) "0" [%u|b%"mem_realloc_ammount"]=> @@ -1098,6 +1126,10 @@ array(119) { %unicode|string%(1) "0" [%u|b%"proto_binary_fetched_other"]=> %unicode|string%(1) "0" + [%u|b%"init_command_executed_count"]=> + %unicode|string%(1) "0" + [%u|b%"init_command_failed_count"]=> + %unicode|string%(1) "0" } Testing buffered normal... Testing buffered normal... - SELECT id, label FROM test diff --git a/ext/mysqli/tests/mysqli_get_client_stats_implicit_free.phpt b/ext/mysqli/tests/mysqli_get_client_stats_implicit_free.phpt index 6d835abd8..880ee321f 100644 --- a/ext/mysqli/tests/mysqli_get_client_stats_implicit_free.phpt +++ b/ext/mysqli/tests/mysqli_get_client_stats_implicit_free.phpt @@ -36,6 +36,10 @@ mysqlnd.collect_memory_statistics=1 print "done!"; ?> +--CLEAN-- + --EXPECTF-- BEGINNING: implicit_free_result = %d END: implicit_free_result = %d diff --git a/ext/mysqli/tests/mysqli_get_client_stats_off.phpt b/ext/mysqli/tests/mysqli_get_client_stats_off.phpt index 8a731ca74..e2dff9bef 100644 --- a/ext/mysqli/tests/mysqli_get_client_stats_off.phpt +++ b/ext/mysqli/tests/mysqli_get_client_stats_off.phpt @@ -15,24 +15,34 @@ mysqlnd.collect_memory_statistics=0 --FILE-- $v) if ($v != 0) { - printf("[002] Field %s should not have any other value but 0, got %s.\n", + printf("[003] Field %s should not have any other value but 0, got %s.\n", $k, $v); } mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_client_stats_ps.phpt b/ext/mysqli/tests/mysqli_get_client_stats_ps.phpt index fea641b81..d12957b11 100644 --- a/ext/mysqli/tests/mysqli_get_client_stats_ps.phpt +++ b/ext/mysqli/tests/mysqli_get_client_stats_ps.phpt @@ -89,6 +89,10 @@ mysqlnd.collect_memory_statistics=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- BEGINNING: rows_fetched_from_client_ps_unbuffered = %d BEGINNING: rows_fetched_from_client_ps_buffered = %d diff --git a/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt b/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt index 9dd802db0..0358656ab 100644 --- a/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt +++ b/ext/mysqli/tests/mysqli_get_client_stats_skipped.phpt @@ -1,5 +1,8 @@ --TEST-- mysqli_get_client_stats() - skipped rows +--INI-- +mysqlnd.collect_statistics="1" +mysqlnd.collect_memory_statistics="1" --SKIPIF-- get_connection_stats()) || empty($info)) + printf("[006] Expecting array/any_non_empty, got %s/%s\n", gettype($info), $info); + + foreach ($info as $k => &$v) { + if (strpos($k, "mem_") === 0) { + $v = 0; + } + } + + if ($info !== $info2) { + printf("[007] The hashes should be identical except of the memory related fields\n"); var_dump($info); var_dump($info2); } @@ -48,19 +66,23 @@ if (!function_exists('mysqli_get_connection_stats')) { include "table.inc"; if (!is_array($info = mysqli_get_connection_stats($link)) || empty($info)) - printf("[006] Expecting array/any_non_empty, got %s/%s\n", gettype($info), $info); + printf("[008] Expecting array/any_non_empty, got %s/%s\n", gettype($info), $info); if (!is_array($info2 = mysqli_get_client_stats()) || empty($info2)) - printf("[007] Expecting array/any_non_empty, got %s/%s\n", gettype($info2), $info2); + printf("[009] Expecting array/any_non_empty, got %s/%s\n", gettype($info2), $info2); // assuming the test is run in a plain-vanilla CLI environment if ($info === $info2) { - printf("[008] The hashes should not be identical\n"); + printf("[010] The hashes should not be identical\n"); var_dump($info); var_dump($info2); } print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysqli/tests/mysqli_get_connection_stats_off.phpt b/ext/mysqli/tests/mysqli_get_connection_stats_off.phpt new file mode 100644 index 000000000..4897063c1 --- /dev/null +++ b/ext/mysqli/tests/mysqli_get_connection_stats_off.phpt @@ -0,0 +1,53 @@ +--TEST-- +mysqli_get_connection_stats() - disable via php.ini +--INI-- +mysqlnd.collect_statistics="0" +mysqlnd.collect_memory_statistics="0" +--SKIPIF-- + +--FILE-- + $v) + if ($v != 0) { + printf("[004] Field %s should not have any other value but 0, got %s.\n", + $k, $v); + } + + mysqli_close($link); + print "done!"; +?> +--EXPECTF-- +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_host_info.phpt b/ext/mysqli/tests/mysqli_get_host_info.phpt index f76cc7002..63fdad28b 100644 --- a/ext/mysqli/tests/mysqli_get_host_info.phpt +++ b/ext/mysqli/tests/mysqli_get_host_info.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_get_host_info() --SKIPIF-- - --FILE-- @@ -22,5 +22,9 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_server_info.phpt b/ext/mysqli/tests/mysqli_get_server_info.phpt index 69dfe8763..f10cc4cfa 100644 --- a/ext/mysqli/tests/mysqli_get_server_info.phpt +++ b/ext/mysqli/tests/mysqli_get_server_info.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_get_server_info() --SKIPIF-- - --FILE-- @@ -25,5 +25,9 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_get_warnings.phpt b/ext/mysqli/tests/mysqli_get_warnings.phpt index 2583bf94b..1472f297f 100644 --- a/ext/mysqli/tests/mysqli_get_warnings.phpt +++ b/ext/mysqli/tests/mysqli_get_warnings.phpt @@ -25,7 +25,7 @@ if (!$TEST_EXPERIMENTAL) if (!is_null($tmp = @mysqli_get_warnings(''))) printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[003] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); } @@ -84,7 +84,7 @@ if (!$TEST_EXPERIMENTAL) mysqli_close($link); - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) printf("[021] Cannot create mysqli object: [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); if (!$mysqli->query("DROP TABLE IF EXISTS t1")) @@ -103,7 +103,7 @@ if (!$TEST_EXPERIMENTAL) printf("[026] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); /* Yes, I really want to check if the object property is empty */ - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) printf("[027] Cannot create mysqli object: [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); $warning = new mysqli_warning($mysqli); @@ -113,7 +113,7 @@ if (!$TEST_EXPERIMENTAL) if ('' != ($tmp = $warning->message)) printf("[029] Expecting string/empty, got %s/%s\n", gettype($tmp), $tmp); - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) printf("[030] Cannot create mysqli object: [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); if (!$mysqli->query("DROP TABLE IF EXISTS t1")) @@ -129,7 +129,7 @@ if (!$TEST_EXPERIMENTAL) $warning = new mysqli_warning($mysqli); $i = 1; while ($warning->next() && ('' != ($tmp = $warning->message))) { - if (ini_get('unicode.semantics') && !is_unicode($tmp)) + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1) && !is_unicode($tmp)) printf("[033a] Warning should have been a unicode string, got %s/%s", gettype($tmp), $tmp); $i++; } @@ -143,5 +143,18 @@ if (!$TEST_EXPERIMENTAL) print "done!"; ?> + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_info.phpt b/ext/mysqli/tests/mysqli_info.phpt index 8760f2177..caa7c9010 100644 --- a/ext/mysqli/tests/mysqli_info.phpt +++ b/ext/mysqli/tests/mysqli_info.phpt @@ -85,7 +85,7 @@ require_once('skipifconnectfailure.inc'); } if (!is_string($tmp = mysqli_info($link)) || ('' == $tmp)) - printf("[015] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); + printf("[016] Expecting string/any_non_empty, got %s/%s\n", gettype($tmp), $tmp); unlink($file); } while (false); @@ -93,5 +93,9 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_insert_id.phpt b/ext/mysqli/tests/mysqli_insert_id.phpt index 398432672..a5491bf97 100644 --- a/ext/mysqli/tests/mysqli_insert_id.phpt +++ b/ext/mysqli/tests/mysqli_insert_id.phpt @@ -130,6 +130,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_insert_id(): Couldn't fetch mysqli in %s on line %d NULL diff --git a/ext/mysqli/tests/mysqli_insert_id_variation.phpt b/ext/mysqli/tests/mysqli_insert_id_variation.phpt index 94f996475..1717b309c 100644 --- a/ext/mysqli/tests/mysqli_insert_id_variation.phpt +++ b/ext/mysqli/tests/mysqli_insert_id_variation.phpt @@ -9,7 +9,7 @@ require_once('skipifconnectfailure.inc'); insert_id || $i != mysqli_insert_id($link)) { $link->query("DROP TABLE IF EXISTS test_insert_id_var"); echo "DONE"; ---EXPECTF-- -DONE +?> +--CLEAN-- + +--EXPECTF-- +DONE \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_kill.phpt b/ext/mysqli/tests/mysqli_kill.phpt index 0d79f8f88..64daad88e 100644 --- a/ext/mysqli/tests/mysqli_kill.phpt +++ b/ext/mysqli/tests/mysqli_kill.phpt @@ -52,7 +52,7 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[009] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); mysqli_kill($link, -1); @@ -64,7 +64,7 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); mysqli_close($link); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[011] Cannot connect, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); mysqli_change_user($link, "This might work if you accept anonymous users in your setup", "password", $db); mysqli_kill($link, -1); @@ -73,6 +73,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_kill(): processid should have positive value in %s on line %d %unicode|string%(%d) "%s" diff --git a/ext/mysqli/tests/mysqli_max_links.phpt b/ext/mysqli/tests/mysqli_max_links.phpt index a9a798022..7f4941940 100644 --- a/ext/mysqli/tests/mysqli_max_links.phpt +++ b/ext/mysqli/tests/mysqli_max_links.phpt @@ -20,7 +20,7 @@ mysqli.max_links=1 $links = array(); for ($i = 1; $i <= 5; $i++) - if ($links[$i] = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if ($links[$i] = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[%03d] One link is already open, it should not be possible to open more, [%d] %s, [%d] %s\n", $i, mysqli_connect_errno(), mysqli_connect_error(), mysqli_errno($links[$i]), mysqli_error($links[$i])); @@ -36,19 +36,23 @@ mysqli.max_links=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- bool(true) int(1) -Warning: mysqli_connect(): Too many open links (1) in %s on line %d +Warning: mysqli_%sonnect(): Too many open links (1) in %s on line %d -Warning: mysqli_connect(): Too many open links (1) in %s on line %d +Warning: mysqli_%sonnect(): Too many open links (1) in %s on line %d -Warning: mysqli_connect(): Too many open links (1) in %s on line %d +Warning: mysqli_%sonnect(): Too many open links (1) in %s on line %d -Warning: mysqli_connect(): Too many open links (1) in %s on line %d +Warning: mysqli_%sonnect(): Too many open links (1) in %s on line %d -Warning: mysqli_connect(): Too many open links (1) in %s on line %d +Warning: mysqli_%sonnect(): Too many open links (1) in %s on line %d Warning: mysqli_query() expects parameter 1 to be mysqli, boolean given in %s on line %d diff --git a/ext/mysqli/tests/mysqli_more_results.phpt b/ext/mysqli/tests/mysqli_more_results.phpt index 1f1216884..49de0d7fa 100644 --- a/ext/mysqli/tests/mysqli_more_results.phpt +++ b/ext/mysqli/tests/mysqli_more_results.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_more_results() --SKIPIF-- - --FILE-- @@ -95,6 +95,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- [004] bool(false) diff --git a/ext/mysqli/tests/mysqli_multi_query.phpt b/ext/mysqli/tests/mysqli_multi_query.phpt index f28479bb4..dd26fd71b 100644 --- a/ext/mysqli/tests/mysqli_multi_query.phpt +++ b/ext/mysqli/tests/mysqli_multi_query.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_multi_query() --SKIPIF-- - --FILE-- @@ -146,6 +146,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- [006] 3 [008] 0 diff --git a/ext/mysqli/tests/mysqli_mysqli_result_invalid_mode.phpt b/ext/mysqli/tests/mysqli_mysqli_result_invalid_mode.phpt index 5bd78a9c1..29ff65780 100644 --- a/ext/mysqli/tests/mysqli_mysqli_result_invalid_mode.phpt +++ b/ext/mysqli/tests/mysqli_mysqli_result_invalid_mode.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_result(), invalid mode --SKIPIF-- - --FILE-- @@ -21,6 +21,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_result::__construct(): Invalid value for resultmode in %s on line %d done! diff --git a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt new file mode 100644 index 000000000..67a5ab6d5 --- /dev/null +++ b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout.phpt @@ -0,0 +1,36 @@ +--TEST-- +mysqlnd.net_read_timeout limit check +--SKIPIF-- + +--INI-- +default_socket_timeout=60 +max_execution_time=60 +mysqlnd.net_read_timeout=1 +--FILE-- + +--EXPECTF-- +Warning: mysqli_query(): MySQL server has gone away in %s on line %d + +Warning: mysqli_query(): Error reading result set's header in %s on line %d +[002] [%d] %s +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout_long.phpt b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout_long.phpt new file mode 100644 index 000000000..637fd1629 --- /dev/null +++ b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout_long.phpt @@ -0,0 +1,37 @@ +--TEST-- +mysqlnd.net_read_timeout > default_socket_timeout +--SKIPIF-- + +--INI-- +default_socket_timeout=1 +mysqlnd.net_read_timeout=12 +max_execution_time=12 +--FILE-- +fetch_assoc()); + + mysqli_free_result($res); + mysqli_close($link); + + print "done!"; +?> +--EXPECTF-- +array(1) { + [%u|b%"SLEEP(6)"]=> + %unicode|string%(1) "0" +} +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_mysqlnd_read_timeout_zero.phpt b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout_zero.phpt new file mode 100644 index 000000000..f5a13c5f6 --- /dev/null +++ b/ext/mysqli/tests/mysqli_mysqlnd_read_timeout_zero.phpt @@ -0,0 +1,36 @@ +--TEST-- +mysqlnd.net_read_timeout = 0 +--SKIPIF-- + +--INI-- +default_socket_timeout=10 +max_execution_time=10 +mysqlnd.net_read_timeout=0 +--FILE-- +fetch_assoc()); + + mysqli_free_result($res); + mysqli_close($link); + + print "done!"; +?> +--EXPECTF-- +array(1) { + [%u|b%"SLEEP(2)"]=> + %unicode|string%(1) "0" +} +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_next_result.phpt b/ext/mysqli/tests/mysqli_next_result.phpt index 118b8677c..0dc49c72f 100644 --- a/ext/mysqli/tests/mysqli_next_result.phpt +++ b/ext/mysqli/tests/mysqli_next_result.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_next_result() --SKIPIF-- - --FILE-- @@ -114,6 +114,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_next_result(): Couldn't fetch mysqli in %s on line %d NULL diff --git a/ext/mysqli/tests/mysqli_no_reconnect.phpt b/ext/mysqli/tests/mysqli_no_reconnect.phpt index d392b5a1c..aa7b1c3b5 100644 --- a/ext/mysqli/tests/mysqli_no_reconnect.phpt +++ b/ext/mysqli/tests/mysqli_no_reconnect.phpt @@ -13,7 +13,7 @@ mysqli.reconnect=0 require_once("connect.inc"); require_once("table.inc"); - if (!$link2 = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot create second database connection, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); @@ -73,7 +73,7 @@ mysqli.reconnect=0 printf("[011] Executing a query should not be possible, connection should be closed, [%d] %s\n", mysqli_errno($link), mysqli_error($link)); - if (!$link = @mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[012] Cannot create database connection, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); diff --git a/ext/mysqli/tests/mysqli_num_fields.phpt b/ext/mysqli/tests/mysqli_num_fields.phpt index fc99ecf9e..88825573c 100644 --- a/ext/mysqli/tests/mysqli_num_fields.phpt +++ b/ext/mysqli/tests/mysqli_num_fields.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_num_fields() --SKIPIF-- - --FILE-- @@ -48,6 +48,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_num_fields(): Couldn't fetch mysqli_result in %s on line %d done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_num_rows.phpt b/ext/mysqli/tests/mysqli_num_rows.phpt index 70af3c404..f1798cc2c 100644 --- a/ext/mysqli/tests/mysqli_num_rows.phpt +++ b/ext/mysqli/tests/mysqli_num_rows.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_num_rows() --SKIPIF-- - --FILE-- @@ -73,6 +73,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in %s on line %d diff --git a/ext/mysqli/tests/mysqli_options.phpt b/ext/mysqli/tests/mysqli_options.phpt index 2a1e25c29..670f9aca7 100644 --- a/ext/mysqli/tests/mysqli_options.phpt +++ b/ext/mysqli/tests/mysqli_options.phpt @@ -43,7 +43,7 @@ already through other measures. $valid_options[] = constant('MYSQLI_OPT_INT_AND_FLOAT_NATIVE'); if (defined('MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE')) $valid_options[] = constant('MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE'); - + $tmp = NULL; $link = NULL; @@ -85,11 +85,14 @@ already through other measures. !($tmp = mysqli_options($link, constant('MYSQLI_OPT_NUMERIC_AND_DATETIME_AS_UNICODE'), true))) printf("[006] Expecting boolean/true got %s/%s\n", gettype($tmp), $tmp); - for ($flag = -10000; $flag < 10000; $flag++) { - if (in_array($flag, $valid_options)) - continue; - if (FALSE !== ($tmp = mysqli_options($link, $flag, 'definetely not an mysqli_option'))) { - var_dump("SOME_FLAG", $flag, $tmp); + if ($IS_MYSQLND) { + /* Don't do this with libmysql. You may hit options not exported to PHP and cause false positives */ + for ($flag = -10000; $flag < 10000; $flag++) { + if (in_array($flag, $valid_options)) + continue; + if (FALSE !== ($tmp = mysqli_options($link, $flag, 'definetely not an mysqli_option'))) { + var_dump(array("SOME_FLAG" => $flag, "ret" => $tmp)); + } } } @@ -97,7 +100,6 @@ already through other measures. echo "Link closed"; var_dump("MYSQLI_INIT_COMMAND", mysqli_options($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=1')); - var_dump("SOME_RANDOM_FLAG", mysqli_options($link, $flag, 'definetly not an mysqli_option')); print "done!"; ?> --EXPECTF-- @@ -127,8 +129,4 @@ Link closed Warning: mysqli_options(): Couldn't fetch mysqli in %s line %d %s(19) "MYSQLI_INIT_COMMAND" NULL - -Warning: mysqli_options(): Couldn't fetch mysqli in %s line %d -%s(16) "SOME_RANDOM_FLAG" -NULL done! diff --git a/ext/mysqli/tests/mysqli_options_init_command.phpt b/ext/mysqli/tests/mysqli_options_init_command.phpt index 667b58175..2ba2ce461 100644 --- a/ext/mysqli/tests/mysqli_options_init_command.phpt +++ b/ext/mysqli/tests/mysqli_options_init_command.phpt @@ -1,19 +1,78 @@ --TEST-- mysqli_options() --SKIPIF-- - --FILE-- +--CLEAN-- + --EXPECTF-- -done! +Warning: mysqli_real_connect(): (%s/%d): %s in %s on line %d +[010] Cannot connect to the server using %s +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_options_openbasedir.phpt b/ext/mysqli/tests/mysqli_options_openbasedir.phpt index d5a5bf45c..81d8ffef6 100644 --- a/ext/mysqli/tests/mysqli_options_openbasedir.phpt +++ b/ext/mysqli/tests/mysqli_options_openbasedir.phpt @@ -11,7 +11,7 @@ open_basedir="." --FILE-- --EXPECTF-- -Warning: mysqli_connect(): Persistent connections are disabled. Downgrading to normal in %s on line %d +Warning: my_mysqli_connect(): Persistent connections are disabled. Downgrading to normal in %s on line %d -Warning: mysqli_connect(): Persistent connections are disabled. Downgrading to normal in %s on line %d +Warning: my_mysqli_connect(): Persistent connections are disabled. Downgrading to normal in %s on line %d Connecction 1 - SELECT @pcondisabled -> 'Connection 1' Connecction 2 - SELECT @pcondisabled -> '' done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_pconn_kill.phpt b/ext/mysqli/tests/mysqli_pconn_kill.phpt index d25d5321b..297dd4cb6 100755 --- a/ext/mysqli/tests/mysqli_pconn_kill.phpt +++ b/ext/mysqli/tests/mysqli_pconn_kill.phpt @@ -18,7 +18,7 @@ mysqli.max_persistent=2 require_once("table.inc"); $host = 'p:' . $host; - if (!$plink = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$plink = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -66,7 +66,7 @@ mysqli.max_persistent=2 // On PHP side this should do nothing. PHP should not try to close the connection or something. @mysqli_close($plink); - if (!$plink = @mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$plink = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[011] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); if (!$res3 = @mysqli_query($plink, 'SELECT id FROM test ORDER BY id LIMIT 1')) { @@ -79,7 +79,7 @@ mysqli.max_persistent=2 // remove the "p:" from the host variable $host = substr($host, 2); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[013] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); if (!$res4 = mysqli_query($link, 'SELECT id FROM test ORDER BY id LIMIT 1')) @@ -89,5 +89,9 @@ mysqli.max_persistent=2 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_pconn_limits.phpt b/ext/mysqli/tests/mysqli_pconn_limits.phpt index 9f8bfe7d7..84cd11e59 100644 --- a/ext/mysqli/tests/mysqli_pconn_limits.phpt +++ b/ext/mysqli/tests/mysqli_pconn_limits.phpt @@ -28,7 +28,7 @@ mysqli.max_links=-1 mysqli_free_result($res); printf("Regular connection 1 - '%s'\n", $row['_desc']); - if (!$link2 = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[002] Cannot open second regular connection, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); @@ -41,7 +41,7 @@ mysqli.max_links=-1 printf("Regular connection 2 - '%s'\n", $row['_desc']); $host = 'p:' . $host; - if (!$plink = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$plink = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[004] Cannot create persistent connection using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", $host, $user, $db, $port, $socket, mysqli_connect_errno(), mysqli_connect_error()); @@ -54,7 +54,7 @@ mysqli.max_links=-1 mysqli_free_result($res); printf("Persistent connection 1 - '%s'\n", $row['_desc']); - if (!$plink2 = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$plink2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[006] Cannot create persistent connection using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", $host, $user, $db, $port, $socket, mysqli_connect_errno(), mysqli_connect_error()); @@ -68,7 +68,7 @@ mysqli.max_links=-1 printf("Persistent connection 2 - '%s'\n", $row['_desc']); $plink3 = mysqli_init(); - if (!mysqli_real_connect($plink3, $host, $user, $passwd, $db, $port, $socket)) + if (!my_mysqli_real_connect($plink3, $host, $user, $passwd, $db, $port, $socket)) printf("[008] Cannot create persistent connection using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", $host, $user, $db, $port, $socket, mysqli_connect_errno(), mysqli_connect_error()); @@ -88,6 +88,10 @@ mysqli.max_links=-1 mysqli_close($plink3); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Regular connection 1 - 'works..' Regular connection 2 - 'works...' diff --git a/ext/mysqli/tests/mysqli_pconn_max_links.phpt b/ext/mysqli/tests/mysqli_pconn_max_links.phpt index ceac64489..3ccb76136 100644 --- a/ext/mysqli/tests/mysqli_pconn_max_links.phpt +++ b/ext/mysqli/tests/mysqli_pconn_max_links.phpt @@ -11,13 +11,14 @@ Persistent connections and mysqli.max_links die("skip mysqlnd only test"); // we need a second DB user to test for a possible flaw in the ext/mysql[i] code - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) die(sprintf("skip Cannot connect [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); mysqli_query($link, 'DROP USER pcontest'); - mysqli_query($link, 'DROP USER pcontest@localhost'); + mysqli_query($link, 'DROP USER pcontest@localhost'); + if (!mysqli_query($link, 'CREATE USER pcontest@"%" IDENTIFIED BY "pcontest"') || - !mysqli_query($link, 'CREATE USER pcontest@localhost IDENTIFIED BY "pcontest"')) { + !mysqli_query($link, 'CREATE USER pcontest@localhost IDENTIFIED BY "pcontest"')) { printf("skip Cannot create second DB user [%d] %s", mysqli_errno($link), mysqli_error($link)); mysqli_close($link); die("skip CREATE USER failed"); @@ -25,21 +26,20 @@ Persistent connections and mysqli.max_links // we might be able to specify the host using CURRENT_USER(), but... if (!mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'%%'", $db)) || - !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'localhost'", $db))) { + !mysqli_query($link, sprintf("GRANT SELECT ON TABLE %s.test TO pcontest@'localhost'", $db))) { printf("skip Cannot GRANT SELECT to second DB user [%d] %s", mysqli_errno($link), mysqli_error($link)); mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); - mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); - mysqli_query($link, 'DROP USER pcontest@localhost'); + mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); + mysqli_query($link, 'DROP USER pcontest@localhost'); mysqli_query($link, 'DROP USER pcontest'); mysqli_close($link); die("skip GRANT failed"); } - if (!($link_pcontest = @mysqli_connect($host, 'pcontest', 'pcontest', $db, $port, $socket))) { - die(":)"); - mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); - mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); - mysqli_query($link, 'DROP USER pcontest@localhost'); + if (!($link_pcontest = @my_mysqli_connect($host, 'pcontest', 'pcontest', $db, $port, $socket))) { + mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest'); + mysqli_query($link, 'REVOKE ALL PRIVILEGES, GRANT OPTION FROM pcontest@localhost'); + mysqli_query($link, 'DROP USER pcontest@localhost'); mysqli_query($link, 'DROP USER pcontest'); mysqli_close($link); die("skip CONNECT using new user failed"); @@ -54,7 +54,7 @@ mysqli.max_persistent=2 require_once("connect.inc"); require_once('table.inc'); - if (!$plink = mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket)) + if (!$plink = my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket)) printf("[001] Cannot connect using the second DB user created during SKIPIF, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); @@ -107,7 +107,7 @@ mysqli.max_persistent=2 printf("[009] Persistent connection has not been killed\n"); // this fails and we have 0 (<= $num_plinks) connections - if ($plink = @mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket)) + if ($plink = @my_mysqli_connect('p:' . $host, 'pcontest', 'pcontest', $db, $port, $socket)) printf("[010] Can connect using the old password, [%d] %s\n", mysqli_connect_errno($link), mysqli_connect_error($link)); @@ -123,7 +123,7 @@ mysqli.max_persistent=2 if ($num_plinks_kill > $num_plinks) printf("[011] Expecting Active Persistent Links < %d, got %d\n", $num_plinks, $num_plinks_kill); - if (!$plink = mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) + if (!$plink = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) printf("[012] Cannot connect using the new password, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); @@ -137,7 +137,7 @@ mysqli.max_persistent=2 mysqli_free_result($res); var_dump($row); - if ($plink2 = mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) + if ($plink2 = my_mysqli_connect('p:' . $host, 'pcontest', 'newpass', $db, $port, $socket)) printf("[015] Can open more persistent connections than allowed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); @@ -158,6 +158,22 @@ mysqli.max_persistent=2 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(2) { [%u|b%"id"]=> @@ -172,5 +188,5 @@ array(2) { %unicode|string%(1) "a" } -Warning: mysqli_connect(): Too many open persistent links (%d) in %s on line %d +Warning: my_mysqli_connect(): Too many open persistent links (%d) in %s on line %d done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_pconn_reuse.phpt b/ext/mysqli/tests/mysqli_pconn_reuse.phpt index c2808579a..8a43e7c30 100644 --- a/ext/mysqli/tests/mysqli_pconn_reuse.phpt +++ b/ext/mysqli/tests/mysqli_pconn_reuse.phpt @@ -20,7 +20,7 @@ mysqli.max_links=2 include "connect.inc"; $host = 'p:' . $host; - if (!$link1 = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (!$link1 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", $host, $user, $db, $port, $socket, mysqli_connect_errno(), mysqli_connect_error()); } @@ -28,7 +28,7 @@ mysqli.max_links=2 printf("[002] Cannot set user variable to check if we got the same persistent connection, [%d] %s\n", mysqli_errno($link1), mysqli_error($link1)); - if (!$link2 = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", $host, $user, $db, $port, $socket, mysqli_connect_errno(), mysqli_connect_error()); } @@ -63,7 +63,7 @@ mysqli.max_links=2 mysqli_close($link2); /* reuse of existing persistent connection expected! */ - if (!$link2 = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[008] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s, [%d] %s\n", $host, $user, $db, $port, $socket, mysqli_connect_errno(), mysqli_connect_error()); } diff --git a/ext/mysqli/tests/mysqli_pconnect.phpt b/ext/mysqli/tests/mysqli_pconnect.phpt index c499cffba..57b44ebaf 100644 --- a/ext/mysqli/tests/mysqli_pconnect.phpt +++ b/ext/mysqli/tests/mysqli_pconnect.phpt @@ -14,7 +14,7 @@ if (!stristr(mysqli_get_client_info(), 'mysqlnd')) include "connect.inc"; $host = 'p:' . $host; - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -23,7 +23,7 @@ if (!stristr(mysqli_get_client_info(), 'mysqlnd')) $num = 20; $connections = array(); for ($i = 0; $i < $num; $i++) { - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[003] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); $connections[] = $link; } @@ -39,7 +39,7 @@ if (!stristr(mysqli_get_client_info(), 'mysqlnd')) $connections = array(); $num = 20; for ($i = 0; $i < $num; $i++) { - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[004] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); $connections[] = $link; } @@ -55,7 +55,7 @@ if (!stristr(mysqli_get_client_info(), 'mysqlnd')) unset($connections[$index]); } else { $left--; - if (!$connections[$index] = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$connections[$index] = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[004] Connect failed, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); } flush(); diff --git a/ext/mysqli/tests/mysqli_ping.phpt b/ext/mysqli/tests/mysqli_ping.phpt index ff55bc29f..80a2a20a2 100644 --- a/ext/mysqli/tests/mysqli_ping.phpt +++ b/ext/mysqli/tests/mysqli_ping.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_ping() --SKIPIF-- - --FILE-- diff --git a/ext/mysqli/tests/mysqli_poll.phpt b/ext/mysqli/tests/mysqli_poll.phpt index 1bfae4bdb..c691835f3 100644 --- a/ext/mysqli/tests/mysqli_poll.phpt +++ b/ext/mysqli/tests/mysqli_poll.phpt @@ -17,7 +17,7 @@ if (!$IS_MYSQLND) function get_connection() { global $host, $user, $passwd, $db, $port, $socket; - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); return $link; } @@ -53,14 +53,25 @@ if (!$IS_MYSQLND) printf("[009] Expecting int/0 got %s/%s\n", gettype($tmp), var_export($tmp, true)); - function poll_async($offset, $links, $errors, $reject, $exp_ready) { + function poll_async($offset, $link, $links, $errors, $reject, $exp_ready, $use_oo_syntax) { - if ($exp_ready !== ($tmp = mysqli_poll($links, $errors, $reject, 0, 1000))) - printf("[%03d + 1] There should be %d links ready to read from, %d ready\n", - $exp_ready, $tmp); + if ($use_oo_syntax) { + if ($exp_ready !== ($tmp = $link->poll($links, $errors, $reject, 0, 1000))) + printf("[%03d + 1] There should be %d links ready to read from, %d ready\n", + $exp_ready, $tmp); + } else { + if ($exp_ready !== ($tmp = mysqli_poll($links, $errors, $reject, 0, 1000))) + printf("[%03d + 1] There should be %d links ready to read from, %d ready\n", + $exp_ready, $tmp); + } foreach ($links as $mysqli) { - if (is_object($res = mysqli_reap_async_query($mysqli))) { + if ($use_oo_syntax) { + $res = $mysqli->reap_async_query(); + } else { + $res = mysqli_reap_async_query($mysqli); + } + if (is_object($res)) { printf("[%03d + 2] Can fetch resultset although no query has been run!\n", $offset); } else if (mysqli_errno($mysqli) > 0) { printf("[%03d + 3] Error indicated through links array: %d/%s", @@ -85,7 +96,14 @@ if (!$IS_MYSQLND) $links = array($link); $errors = array($link); $reject = array($link); - poll_async(10, $links, $errors, $reject, 0); + poll_async(10, $link, $links, $errors, $reject, 0, false); + mysqli_close($link); + + $link = get_connection(); + $links = array($link); + $errors = array($link); + $reject = array($link); + poll_async(11, $link, $links, $errors, $reject, 0, true); mysqli_close($link); // Connections on which no query has been send - 2 @@ -94,7 +112,7 @@ if (!$IS_MYSQLND) $links = array($link, $link); $errors = array($link, $link); $reject = array(); - poll_async(11, $links, $errors, $reject, 0); + poll_async(12, $link, $links, $errors, $reject, 0, false); // Connections on which no query has been send - 3 // Difference: pass two connections @@ -102,7 +120,7 @@ if (!$IS_MYSQLND) $links = array($link, get_connection()); $errors = array($link, $link); $reject = array(); - poll_async(12, $links, $errors, $reject, 0); + poll_async(13, $link, $links, $errors, $reject, 0, false); // Reference mess... $link = get_connection(); @@ -110,15 +128,16 @@ if (!$IS_MYSQLND) $errors = array($link); $ref_errors =& $errors; $reject = array(); - poll_async(13, $links, $ref_errors, $reject, 0); + poll_async(14, $link, $links, $ref_errors, $reject, 0, false); print "done!"; ?> --EXPECTF-- [010 + 6] Rejecting thread %d: 0/ [011 + 6] Rejecting thread %d: 0/ -[011 + 6] Rejecting thread %d: 0/ [012 + 6] Rejecting thread %d: 0/ [012 + 6] Rejecting thread %d: 0/ [013 + 6] Rejecting thread %d: 0/ +[013 + 6] Rejecting thread %d: 0/ +[014 + 6] Rejecting thread %d: 0/ done! diff --git a/ext/mysqli/tests/mysqli_poll_kill.phpt b/ext/mysqli/tests/mysqli_poll_kill.phpt index 2b31ef7b9..73382b730 100644 --- a/ext/mysqli/tests/mysqli_poll_kill.phpt +++ b/ext/mysqli/tests/mysqli_poll_kill.phpt @@ -17,7 +17,7 @@ if (!$IS_MYSQLND) function get_connection() { global $host, $user, $passwd, $db, $port, $socket; - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); return $link; } diff --git a/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt b/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt index 443259887..56f9182f4 100644 --- a/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt +++ b/ext/mysqli/tests/mysqli_poll_mixing_insert_select.phpt @@ -17,7 +17,7 @@ if (!$IS_MYSQLND) function get_connection() { global $host, $user, $passwd, $db, $port, $socket; - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); return $link; } @@ -153,6 +153,23 @@ if (!$IS_MYSQLND) print "done!"; ?> +--CLEAN-- + + --EXPECTF-- [003] 'SELECT' caused 1064 [003] 'UPDATE test SET id = 101 WHERE id > 3' caused 1062 diff --git a/ext/mysqli/tests/mysqli_poll_reference.phpt b/ext/mysqli/tests/mysqli_poll_reference.phpt index eb14e7404..332f871af 100644 --- a/ext/mysqli/tests/mysqli_poll_reference.phpt +++ b/ext/mysqli/tests/mysqli_poll_reference.phpt @@ -10,13 +10,12 @@ require_once('skipifconnectfailure.inc'); if (!$IS_MYSQLND) die("skip mysqlnd only feature, compile PHP using --with-mysqli=mysqlnd"); -if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) die("skip cannot connect"); -if (mysqli_server_version($link) < 50012)) +if (mysqli_server_version($link) < 50012) die("skip Test needs SQL function SLEEP() available as of MySQL 5.0.12"); -mysqli_close($link); ?> --FILE-- +--CLEAN-- + --EXPECTF-- bool(false) done! diff --git a/ext/mysqli/tests/mysqli_prepare_no_object.phpt b/ext/mysqli/tests/mysqli_prepare_no_object.phpt index de62b5739..3d022f440 100644 --- a/ext/mysqli/tests/mysqli_prepare_no_object.phpt +++ b/ext/mysqli/tests/mysqli_prepare_no_object.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_prepare() - no object on failure --SKIPIF-- - --FILE-- @@ -21,7 +21,7 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); - if (!$mysqli = new mysqli($host, $user, $passwd, $db, $port, $socket)) + if (!$mysqli = new my_mysqli($host, $user, $passwd, $db, $port, $socket)) printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -35,6 +35,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- a) [1065] Query was empty b) [1065] Query was empty diff --git a/ext/mysqli/tests/mysqli_ps_select_union.phpt b/ext/mysqli/tests/mysqli_ps_select_union.phpt new file mode 100644 index 000000000..fed81b309 --- /dev/null +++ b/ext/mysqli/tests/mysqli_ps_select_union.phpt @@ -0,0 +1,275 @@ +--TEST-- +Prepared Statements and SELECT UNION +--SKIPIF-- + +--FILE-- +query("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST('two' AS CHAR)"))) + printf("[001] [%d] %s\n", $link->errno, $link->error); + + $data = array(); + while ($row = $res->fetch_assoc()) { + $data[] = $row['column1']; + var_dump($row['column1']); + } + $res->free(); + + // Prepared Statements + if (!($stmt = $link->prepare("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST('two' AS CHAR)"))) + printf("[002] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + if (!$stmt->execute() || !$stmt->bind_result($column1)) + printf("[003] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[004] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + $index++; + } + $stmt->close(); + + if ($IS_MYSQLND) { + /* + Advantage mysqlnd - + The metadata mysqlnd has availabe after prepare is better than + the one made availabe by the MySQL Client Library (libmysql). + "libmysql" will give wrong results and that is OK - + http://bugs.mysql.com/bug.php?id=47483 + */ + if (!($stmt = $link->prepare("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST('two' AS CHAR)"))) + printf("[005] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + /* Note: bind_result before execute */ + if (!$stmt->bind_result($column1) || !$stmt->execute()) + printf("[006] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[007] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + $index++; + } + $stmt->close(); + } + + // Regular (non-prepared) queries + print "Mixing CAST('somestring'AS CHAR), integer and CAST(integer AS CHAR)...\n"; + if (!($res = $link->query("SELECT 1 AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST(2 AS CHAR)"))) + printf("[008] [%d] %s\n", $link->errno, $link->error); + + $data = array(); + while ($row = $res->fetch_assoc()) { + $data[] = $row['column1']; + } + $res->free(); + + // Prepared Statements + if (!($stmt = $link->prepare("SELECT 1 AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST(2 AS CHAR)"))) + printf("[009] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + if (!$stmt->execute() || !$stmt->bind_result($column1)) + printf("[010] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[011] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + var_dump($column1); + $index++; + } + $stmt->close(); + + if ($IS_MYSQLND) { + /* Advantage mysqlnd - see above... */ + if (!($stmt = $link->prepare("SELECT 1 AS column1 UNION SELECT CAST('three' AS CHAR) UNION SELECT CAST(2 AS CHAR)"))) + printf("[012] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + if (!$stmt->bind_result($column1) || !$stmt->execute()) + printf("[013] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[014] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + $index++; + } + $stmt->close(); + } + + print "Using integer only...\n"; + if (!($res = $link->query("SELECT 1 AS column1 UNION SELECT 303 UNION SELECT 2"))) + printf("[015] [%d] %s\n", $link->errno, $link->error); + + $data = array(); + while ($row = $res->fetch_assoc()) { + $data[] = $row['column1']; + } + $res->free(); + + // Prepared Statements + if (!($stmt = $link->prepare("SELECT 1 AS column1 UNION SELECT 303 UNION SELECT 2"))) + printf("[016] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + if (!$stmt->execute() || !$stmt->bind_result($column1)) + printf("[017] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[018] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + var_dump($column1); + $index++; + } + $stmt->close(); + + if ($IS_MYSQLND) { + /* Advantage mysqlnd - see above */ + if (!($stmt = $link->prepare("SELECT 1 AS column1 UNION SELECT 303 UNION SELECT 2"))) + printf("[019] [%d] %s\n", $link->errno, $link->error); + + $column1 = null; + if (!$stmt->bind_result($column1) || !$stmt->execute()) + printf("[020] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[021] Row %d, expecting %s/%s got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + $index++; + } + $stmt->close(); + } + + print "Testing bind_param(), strings only...\n"; + $two = 'two'; + $three = 'three'; + if (!($stmt = $link->prepare("SELECT 'one' AS column1 UNION SELECT ? UNION SELECT ?"))) + printf("[022] [%d] %s\n", $stmt->errno, $stmt->error); + + $column1 = null; + if (!$stmt->bind_param('ss', $three, $two) || !$stmt->execute() || !$stmt->bind_result($column1)) + printf("[023] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + $data = array(); + while ($stmt->fetch()) { + $data[$index++] = $column1; + var_dump($column1); + } + $stmt->close(); + + if ($IS_MYSQLND) { + /* Advantage mysqlnd - see above */ + $two = 'two'; + $three = 'three'; + if (!($stmt = $link->prepare("SELECT 'one' AS column1 UNION SELECT ? UNION SELECT ?"))) + printf("[024] [%d] %s\n", $stmt->errno, $stmt->error); + + $column1 = null; + if (!$stmt->bind_param('ss', $three, $two) || !$stmt->bind_result($column1) || !$stmt->execute()) + printf("[025] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[26] Row %d, expecting %s/%s, got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + $index++; + } + $stmt->close(); + } + + print "Testing bind_param(), strings only, with CAST AS CHAR...\n"; + $two = 'two'; + $three = 'three beers are more than enough'; + if (!($stmt = $link->prepare("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST(? AS CHAR) UNION SELECT CAST(? AS CHAR)"))) + printf("[027] [%d] %s\n", $stmt->errno, $stmt->error); + + $column1 = null; + if (!$stmt->bind_param('ss', $three, $two) || !$stmt->execute() || !$stmt->bind_result($column1)) + printf("[028] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + $data = array(); + while ($stmt->fetch()) { + $data[$index++] = $column1; + var_dump($column1); + } + $stmt->close(); + + if ($IS_MYSQLND) { + /* Advantage mysqlnd - see above */ + $two = 'two'; + $three = 'three beers are more than enough'; + if (!($stmt = $link->prepare("SELECT CAST('one' AS CHAR) AS column1 UNION SELECT CAST(? AS CHAR) UNION SELECT CAST(? AS CHAR)"))) + printf("[029] [%d] %s\n", $stmt->errno, $stmt->error); + + $column1 = null; + if (!$stmt->bind_param('ss', $three, $two) || !$stmt->bind_result($column1) || !$stmt->execute()) + printf("[030] [%d] %s\n", $stmt->errno, $stmt->error); + + $index = 0; + while ($stmt->fetch()) { + if ($data[$index] != $column1) { + printf("[31] Row %d, expecting %s/%s, got %s/%s\n", + $index + 1, gettype($data[$index]), $data[$index], gettype($column1), $column1); + } + $index++; + } + $stmt->close(); + } + + $link->close(); + + print "done!"; +?> +--EXPECTF-- +Using CAST('somestring' AS CHAR)... +%unicode|string%(3) "one" +%unicode|string%(5) "three" +%unicode|string%(3) "two" +Mixing CAST('somestring'AS CHAR), integer and CAST(integer AS CHAR)... +%unicode|string%(1) "1" +%unicode|string%(5) "three" +%unicode|string%(1) "2" +Using integer only... +int(1) +int(303) +int(2) +Testing bind_param(), strings only... +%unicode|string%(3) "one" +%unicode|string%(5) "three" +%unicode|string%(3) "two" +Testing bind_param(), strings only, with CAST AS CHAR... +%unicode|string%(3) "one" +%unicode|string%(32) "three beers are more than enough" +%unicode|string%(3) "two" +done! diff --git a/ext/mysqli/tests/mysqli_query.phpt b/ext/mysqli/tests/mysqli_query.phpt index 12cba90df..0e45f0388 100644 --- a/ext/mysqli/tests/mysqli_query.phpt +++ b/ext/mysqli/tests/mysqli_query.phpt @@ -112,6 +112,20 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(1) { [%u|b%"valid"]=> diff --git a/ext/mysqli/tests/mysqli_query_local_infile_large.phpt b/ext/mysqli/tests/mysqli_query_local_infile_large.phpt new file mode 100644 index 000000000..306dfceab --- /dev/null +++ b/ext/mysqli/tests/mysqli_query_local_infile_large.phpt @@ -0,0 +1,93 @@ +--TEST-- +mysql_query(LOAD DATA LOCAL INFILE) with large data set (10MB) +--SKIPIF-- + +--INI-- +mysqli.allow_local_infile=1 +--FILE-- +') == 1)) + $bytes += fwrite($fp, (binary)(++$rowno . ";" . $data)); + else + $bytes += fwrite($fp, ++$rowno . ";" . $data); + } + fclose($fp); + printf("Filesize in bytes: %d\nRows: %d\n", $bytes, $rowno); + + include "connect.inc"; + if (!($link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket))) + printf("[002] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); + + if (!mysqli_query($link, "DROP TABLE IF EXISTS test") || + !mysqli_query($link, "CREATE TABLE test(id INT, col1 VARCHAR(255), col2 VARCHAR(255)) ENGINE = " . $engine)) + printf("[003] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if (!mysqli_query($link, sprintf("LOAD DATA LOCAL INFILE '%s' INTO TABLE test FIELDS TERMINATED BY ';'", mysqli_real_escape_string($link, $file)))) + printf("[004] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + if ((!is_string(mysqli_info($link))) || ('' == mysqli_info($link))) { + printf("[005] [%d] %s, mysqli_info not set \n", mysqli_errno($link), mysqli_error($link)); + } + + if (!($res = mysqli_query($link, "SELECT COUNT(*) AS _num FROM test"))) + printf("[006] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $row = mysqli_fetch_assoc($res); + if (($row["_num"] != $rowno)) + printf("[007] Expecting %d rows, found %d\n", $rowno, $row["_num"]); + + mysqli_free_result($res); + + $random = mt_rand(1, $rowno); + if (!$res = mysqli_query($link, "SELECT id, col1, col2 FROM test WHERE id = " . $random)) + printf("[008] [%d] %s\n", mysqli_errno($link), mysqli_error($link)); + + $row = mysqli_fetch_assoc($res); + var_dump($row); + mysqli_free_result($res); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- + +--EXPECTF-- +Filesize in bytes: %d +Rows: %d +array(3) { + [%u|b%"id"]=> + %unicode|string%(%d) "%d" + [%u|b%"col1"]=> + %unicode|string%(127) "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + [%u|b%"col2"]=> + %unicode|string%(127) "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb" +} +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_query_stored_proc.phpt b/ext/mysqli/tests/mysqli_query_stored_proc.phpt index f419205ea..0ca71a40b 100644 --- a/ext/mysqli/tests/mysqli_query_stored_proc.phpt +++ b/ext/mysqli/tests/mysqli_query_stored_proc.phpt @@ -5,7 +5,7 @@ mysqli_query() - Stored Procedures require_once('skipif.inc'); require_once('skipifconnectfailure.inc'); require_once('connect.inc'); -if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); } if (mysqli_get_server_version($link) <= 50000) { @@ -150,6 +150,19 @@ END;')) { mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(2) { [%u|b%"id"]=> diff --git a/ext/mysqli/tests/mysqli_query_unicode.phpt b/ext/mysqli/tests/mysqli_query_unicode.phpt index c05f22a2f..478ccbd30 100644 --- a/ext/mysqli/tests/mysqli_query_unicode.phpt +++ b/ext/mysqli/tests/mysqli_query_unicode.phpt @@ -88,7 +88,7 @@ mysqli_close($link); /* Trying to test what Ramil suggests in http://bugs.mysql.com/bug.php?id=29576 However, this won't work, because we're lacking MYSQLI_SET_CHARSET_NAME. - if (ini_get("unicode.semantics")) { + if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) { if (mysqli_get_server_version() > 50002) { @mysqli_query($link, "DROP USER IF EXISTS 'тест'@'%'"); if (TRUE !== mysqli_query($link, "CREATE USER 'тест'@'%'")) { diff --git a/ext/mysqli/tests/mysqli_real_connect.phpt b/ext/mysqli/tests/mysqli_real_connect.phpt index 8f20c7edd..5e474d6d2 100644 --- a/ext/mysqli/tests/mysqli_real_connect.phpt +++ b/ext/mysqli/tests/mysqli_real_connect.phpt @@ -161,32 +161,37 @@ require_once('skipifconnectfailure.inc'); printf("[025] Usage of mysqli.default_host=p: did not fail\n") ; mysqli_close($link); } + @mysqli_close($link); } @var_dump($link); - if (NULL === ($tmp = mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket))) - printf("[026] Expecting not NULL, got %s/%s\n", gettype($tmp), $tmp); + if (NULL !== ($tmp = mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket))) + printf("[026] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_real_connect(): (%d/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d object(mysqli)#%d (%d) { [%u|b%"affected_rows"]=> NULL [%u|b%"client_info"]=> - %unicode|string%(%d) "%s" + %s [%u|b%"client_version"]=> int(%d) [%u|b%"connect_errno"]=> int(%d) [%u|b%"connect_error"]=> - %unicode|string%(%d) "%s" + %unicode|string%(%d) "%s [%u|b%"errno"]=> - int(%d) + %s [%u|b%"error"]=> - %unicode|string%(%d) "%s" + %s [%u|b%"field_count"]=> NULL [%u|b%"host_info"]=> @@ -208,4 +213,6 @@ object(mysqli)#%d (%d) { [%u|b%"warning_count"]=> NULL } -done! + +Warning: mysqli_real_connect(): Couldn't fetch mysqli in %s on line %d +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_real_connect_pconn.phpt b/ext/mysqli/tests/mysqli_real_connect_pconn.phpt index ad9645177..5dedd47c9 100644 --- a/ext/mysqli/tests/mysqli_real_connect_pconn.phpt +++ b/ext/mysqli/tests/mysqli_real_connect_pconn.phpt @@ -146,6 +146,10 @@ mysqli.max_persistent=10 print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_real_connect(): (%d/%d): Access denied for user '%s'@'%s' (using password: YES) in %s on line %d done! diff --git a/ext/mysqli/tests/mysqli_real_query.phpt b/ext/mysqli/tests/mysqli_real_query.phpt index 92961977f..8e3034415 100644 --- a/ext/mysqli/tests/mysqli_real_query.phpt +++ b/ext/mysqli/tests/mysqli_real_query.phpt @@ -89,6 +89,20 @@ ver_param;')) { print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(1) { [%u|b%"valid"]=> diff --git a/ext/mysqli/tests/mysqli_reconnect.phpt b/ext/mysqli/tests/mysqli_reconnect.phpt index 68cffc3b2..7f05a20d2 100644 --- a/ext/mysqli/tests/mysqli_reconnect.phpt +++ b/ext/mysqli/tests/mysqli_reconnect.phpt @@ -15,7 +15,7 @@ mysqli.reconnect=1 require_once("connect.inc"); require_once("table.inc"); - if (!$link2 = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link2 = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot create second database connection, [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); diff --git a/ext/mysqli/tests/mysqli_report.phpt b/ext/mysqli/tests/mysqli_report.phpt index 7b421014d..dc927997f 100644 --- a/ext/mysqli/tests/mysqli_report.phpt +++ b/ext/mysqli/tests/mysqli_report.phpt @@ -85,7 +85,7 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); /* mysqli_stmt_execute() = mysql_stmt_execute cannot be tested from PHP */ - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[008] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); $stmt = mysqli_stmt_init($link); mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?"); @@ -105,7 +105,7 @@ require_once('skipifconnectfailure.inc'); // Check mysqli_report(MYSQLI_REPORT_OFF); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[010] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); $stmt = mysqli_stmt_init($link); mysqli_stmt_prepare($stmt, "FOO"); @@ -118,7 +118,7 @@ require_once('skipifconnectfailure.inc'); mysqli_stmt_close($stmt); mysqli_close($link); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[011] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); $stmt = mysqli_stmt_init($link); mysqli_stmt_prepare($stmt, "SELECT id FROM test WHERE id > ?"); @@ -139,8 +139,8 @@ require_once('skipifconnectfailure.inc'); already tested php_mysqli_throw_sql_exception() -> - mysqli_real_connect() - mysqli_connect() + my_mysqli_real_connect() + my_mysqli_connect() can't be tested: mysqli_query() via mysql_use_result()/mysql_store_result() */ @@ -149,7 +149,7 @@ require_once('skipifconnectfailure.inc'); try { - if ($link = mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + if ($link = my_mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) printf("[012] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", $host, $user . 'unknown_really', $db, $port, $socket); mysqli_close($link); @@ -162,7 +162,7 @@ require_once('skipifconnectfailure.inc'); if (!$link = mysqli_init()) printf("[014] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); - if ($link = mysqli_real_connect($link, $host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + if ($link = my_mysqli_real_connect($link, $host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) printf("[015] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", $host, $user . 'unknown_really', $db, $port, $socket); mysqli_close($link); @@ -191,7 +191,7 @@ require_once('skipifconnectfailure.inc'); mysqli_report(MYSQLI_REPORT_OFF); mysqli_report(MYSQLI_REPORT_INDEX); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[017] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); // this might cause a warning - no index used @@ -235,7 +235,7 @@ require_once('skipifconnectfailure.inc'); // mysqli_use_result(), mysqli_thread_safe(), mysqli_thread_id() mysqli_report(MYSQLI_REPORT_OFF); mysqli_close($link); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[024] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); if (!$stmt = mysqli_stmt_init($link)) @@ -280,6 +280,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_multi_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'BAR; FOO' at line 1 in %s on line %d diff --git a/ext/mysqli/tests/mysqli_report_wo_ps.phpt b/ext/mysqli/tests/mysqli_report_wo_ps.phpt index 58aae0af1..08909264a 100644 --- a/ext/mysqli/tests/mysqli_report_wo_ps.phpt +++ b/ext/mysqli/tests/mysqli_report_wo_ps.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_report() --SKIPIF-- - --FILE-- @@ -69,7 +69,7 @@ require_once('skipifconnectfailure.inc'); try { - if ($link = mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + if ($link = my_mysqli_connect($host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) printf("[010] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", $host, $user . 'unknown_really', $db, $port, $socket); mysqli_close($link); @@ -82,7 +82,7 @@ require_once('skipifconnectfailure.inc'); if (!$link = mysqli_init()) printf("[012] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); - if ($link = mysqli_real_connect($link, $host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) + if ($link = my_mysqli_real_connect($link, $host, $user . 'unknown_really', $passwd . 'non_empty', $db, $port, $socket)) printf("[013] Can connect to the server using host=%s, user=%s, passwd=***non_empty, dbname=%s, port=%s, socket=%s\n", $host, $user . 'unknown_really', $db, $port, $socket); mysqli_close($link); @@ -92,6 +92,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_multi_query(): (%d/%d): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'BAR; FOO' at line 1 in %s on line %d diff --git a/ext/mysqli/tests/mysqli_result_references.phpt b/ext/mysqli/tests/mysqli_result_references.phpt index fab24a7f9..b6bce0d98 100644 --- a/ext/mysqli/tests/mysqli_result_references.phpt +++ b/ext/mysqli/tests/mysqli_result_references.phpt @@ -39,7 +39,7 @@ require_once('skipifconnectfailure.inc'); mysqli_free_result($res); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -76,6 +76,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(7) refcount(2){ [0]=> diff --git a/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt b/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt index 07dac9ba8..384f85fbb 100644 --- a/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt +++ b/ext/mysqli/tests/mysqli_result_references_mysqlnd.phpt @@ -9,6 +9,9 @@ require_once('skipifconnectfailure.inc'); require_once('connect.inc'); if (!$IS_MYSQLND) die("skip Test for mysqlnd only"); + +if ((version_compare(PHP_VERSION, '5.9.9', '>') == 1)) + die("skip (TODO) PHP 6.0 has a difference debug_zval_dump output format"); ?> --FILE-- @@ -30,6 +33,8 @@ if (!$IS_MYSQLND) $references[$idx]['id_ref'] = &$row['id']; $references[$idx++]['id_copy'] = $row['id']; } + + debug_zval_dump($references); mysqli_free_result($res); if (!(mysqli_real_query($link, "SELECT id, label FROM test ORDER BY id ASC LIMIT 2")) || @@ -52,7 +57,7 @@ if (!$IS_MYSQLND) print "done!"; ?> --EXPECTF-- -array(2) refcount(2){ +array(1) refcount(2){ [0]=> array(4) refcount(1){ [%u|b%"row_ref"]=> @@ -69,6 +74,24 @@ array(2) refcount(2){ [%u|b%"id_copy"]=> %unicode|string%(1) "1" refcount(1) } +} +array(2) refcount(2){ + [0]=> + array(4) refcount(1){ + [%u|b%"row_ref"]=> + &NULL refcount(2) + [%u|b%"row_copy"]=> + array(2) refcount(1){ + [%u|b%"id"]=> + %unicode|string%(1) "1" refcount(1) + [%u|b%"label"]=> + %unicode|string%(1) "a" refcount(1) + } + [%u|b%"id_ref"]=> + %unicode|string%(1) "1" refcount(1) + [%u|b%"id_copy"]=> + %unicode|string%(1) "1" refcount(1) + } [1]=> array(5) refcount(1){ [%u|b%"row_ref"]=> @@ -76,14 +99,14 @@ array(2) refcount(2){ [%u|b%"id"]=> &%unicode|string%(1) "2" refcount(2) [%u|b%"label"]=> - %unicode|string%(1) "b" refcount(3) + %unicode|string%(1) "b" refcount(2) } [%u|b%"row_copy"]=> array(2) refcount(1){ [%u|b%"id"]=> - %unicode|string%(1) "2" refcount(2) + %unicode|string%(1) "2" refcount(1) [%u|b%"label"]=> - %unicode|string%(1) "b" refcount(3) + %unicode|string%(1) "b" refcount(2) } [%u|b%"id_ref"]=> &%unicode|string%(1) "2" refcount(2) diff --git a/ext/mysqli/tests/mysqli_result_unclonable.phpt b/ext/mysqli/tests/mysqli_result_unclonable.phpt index 93cf66321..dfde9a78c 100644 --- a/ext/mysqli/tests/mysqli_result_unclonable.phpt +++ b/ext/mysqli/tests/mysqli_result_unclonable.phpt @@ -1,16 +1,16 @@ --TEST-- Trying to clone mysqli_result object --SKIPIF-- - --FILE-- +--CLEAN-- + --EXPECTF-- Warning: mysqli_rollback(): Couldn't fetch mysqli in %s on line %d done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_select_db.phpt b/ext/mysqli/tests/mysqli_select_db.phpt index c121d6650..bc774cfec 100644 --- a/ext/mysqli/tests/mysqli_select_db.phpt +++ b/ext/mysqli/tests/mysqli_select_db.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_select_db() --SKIPIF-- - --FILE-- @@ -19,7 +19,7 @@ require_once('skipifconnectfailure.inc'); if (!is_null($tmp = @mysqli_select_db($link))) printf("[002] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); diff --git a/ext/mysqli/tests/mysqli_send_query.phpt b/ext/mysqli/tests/mysqli_send_query.phpt index ccddfd233..53cf25093 100755 --- a/ext/mysqli/tests/mysqli_send_query.phpt +++ b/ext/mysqli/tests/mysqli_send_query.phpt @@ -26,7 +26,7 @@ if (!$TEST_EXPERIMENTAL) if (NULL !== ($tmp = @mysqli_send_query($link))) printf("[002] Expecting NULL/NULL, got %s/%s\n", gettype($tmp), $tmp); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { printf("[003] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); } diff --git a/ext/mysqli/tests/mysqli_set_charset.phpt b/ext/mysqli/tests/mysqli_set_charset.phpt index e10b3348b..baf97bd3d 100644 --- a/ext/mysqli/tests/mysqli_set_charset.phpt +++ b/ext/mysqli/tests/mysqli_set_charset.phpt @@ -14,7 +14,7 @@ if (!function_exists('mysqli_set_charset')) die("skip Function not available"); require_once('connect.inc'); -if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) die(sprintf("skip Cannot connect, [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); if (!($res = mysqli_query($link, 'SELECT version() AS server_version')) || @@ -84,7 +84,7 @@ if ((($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin1"', MYSQLI_STOR printf("[011] Expecting boolean/false because of invalid character set, got %s/%s\n", gettype($ret), $ret); mysqli_close($link); - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[012] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -125,6 +125,10 @@ if ((($res = mysqli_query($link, 'SHOW CHARACTER SET LIKE "latin1"', MYSQLI_STOR print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_set_charset(): Couldn't fetch mysqli in %s on line %d done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_set_local_infile_default.phpt b/ext/mysqli/tests/mysqli_set_local_infile_default.phpt index 167fc0f80..dd67bb32a 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_default.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_default.phpt @@ -109,6 +109,10 @@ mysqli.allow_local_infile=1 print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_simple' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt index b876389f1..5cb1459d8 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler.phpt @@ -10,7 +10,7 @@ if (!function_exists('mysqli_set_local_infile_handler')) die("skip - function not available."); require_once('connect.inc'); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -164,6 +164,10 @@ mysqli.allow_local_infile=1 print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_simple' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt index 2ea5ceb0c..ec097fe2b 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_bad_character.phpt @@ -13,7 +13,7 @@ if (!function_exists('mysqli_set_local_infile_handler')) if (!$TEST_EXPERIMENTAL) die("skip - experimental (= unsupported) feature"); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -42,7 +42,7 @@ mysqli.allow_local_infile=1 printf("Callback: %d\n", $invocation++); - $num_chars = (ini_get('unicode.semantics')) ? (floor($buflen / 2) - 10) : ($buflen - 5); + $num_chars = (version_compare(PHP_VERSION, '5.9.9', '>') == 1) ? (floor($buflen / 2) - 10) : ($buflen - 5); $part1 = floor($num_chars / 2); $part2 = $num_chars - $part1; @@ -69,6 +69,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_bad_character' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt index 6c557201b..03f428882 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_buffer_overflow.phpt @@ -13,7 +13,7 @@ require_once('connect.inc'); if (!$TEST_EXPERIMENTAL) die("skip - experimental (= unsupported) feature"); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -54,6 +54,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_buffer_overflow' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt index d9335813b..cb8162db7 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_close_link.phpt @@ -13,7 +13,7 @@ require_once('connect.inc'); if (!$TEST_EXPERIMENTAL) die("skip - experimental (= unsupported) feature"); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -59,6 +59,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_close_link' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt index 4bdb54b1c..7498e64f4 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_closefile.phpt @@ -13,7 +13,7 @@ require_once('connect.inc'); if (!$TEST_EXPERIMENTAL) die("skip - experimental (= unsupported) feature"); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -58,6 +58,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_closefile' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt index 3bdf6bb78..7e2445889 100755 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_closures.phpt @@ -13,7 +13,7 @@ require_once('connect.inc'); if (!$TEST_EXPERIMENTAL) die("skip - experimental (= unsupported) feature"); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -58,6 +58,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'Closure object' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt index efb72d285..3757b61d9 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_kill_link.phpt @@ -10,7 +10,7 @@ if (!function_exists('mysqli_set_local_infile_handler')) die("skip - function not available."); require_once('connect.inc'); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -58,6 +58,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_kill_link' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt index 3b8813aeb..30a3bcc03 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_negative_len.phpt @@ -13,7 +13,7 @@ require_once('connect.inc'); if (!$TEST_EXPERIMENTAL) die("skip - experimental (= unsupported) feature"); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -54,6 +54,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_negative_len' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt index 50be4a593..465dcdb9d 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_nested_call.phpt @@ -13,7 +13,7 @@ require_once('connect.inc'); if (!$TEST_EXPERIMENTAL) die("skip - experimental (= unsupported) feature"); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -101,6 +101,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_report_short_len' Callback - report_short_len(): 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt index 2858e4034..5ea82e93f 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_new_query.phpt @@ -13,7 +13,7 @@ require_once('connect.inc'); if (!$TEST_EXPERIMENTAL) die("skip - experimental (= unsupported) feature"); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -66,6 +66,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_new_query' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt index c92f93762..6354630c0 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_nofileop.phpt @@ -13,7 +13,7 @@ require_once('connect.inc'); if (!$TEST_EXPERIMENTAL) die("skip - experimental (= unsupported) feature"); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -57,6 +57,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_nofileop' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt index a4f20cb75..c30f6ea91 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_openbasedir.phpt @@ -10,7 +10,7 @@ if (!function_exists('mysqli_set_local_infile_handler')) die("skip - function not available."); require_once('connect.inc'); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -101,6 +101,10 @@ done!"; mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: tempnam(): open_basedir restriction in effect. File(%s) is not within the allowed path(s): (%s) in %s on line %d [005 + 1] Cannot create CVS file '' diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt index 22f89fd05..cde8f4b12 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_replace_buffer.phpt @@ -13,7 +13,7 @@ require_once('connect.inc'); if (!$TEST_EXPERIMENTAL) die("skip - experimental (= unsupported) feature"); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -65,6 +65,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_replace_buffer' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt index 78f2fced1..a793ac662 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_short_len.phpt @@ -13,7 +13,7 @@ require_once('connect.inc'); if (!$TEST_EXPERIMENTAL) die("skip - experimental (= unsupported) feature"); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -94,6 +94,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_short_len' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt b/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt index 4a321bf30..c89fc2152 100644 --- a/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt +++ b/ext/mysqli/tests/mysqli_set_local_infile_handler_unregister.phpt @@ -10,7 +10,7 @@ if (!function_exists('mysqli_set_local_infile_handler')) die("skip - function not available."); require_once('connect.inc'); -if (!$link = mysqli_connect($host, $user, $passwb, $db, $port, $socket)) +if (!$link = my_mysqli_connect($host, $user, $passwb, $db, $port, $socket)) die("skip Cannot connect to MySQL"); if (!$res = mysqli_query($link, 'SHOW VARIABLES LIKE "local_infile"')) { @@ -57,6 +57,10 @@ mysqli.allow_local_infile=1 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Callback set to 'callback_unregister' Callback: 0 diff --git a/ext/mysqli/tests/mysqli_set_opt.phpt b/ext/mysqli/tests/mysqli_set_opt.phpt index d5c41827c..21aacd25f 100644 --- a/ext/mysqli/tests/mysqli_set_opt.phpt +++ b/ext/mysqli/tests/mysqli_set_opt.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_set_opt() --SKIPIF-- - --FILE-- @@ -36,7 +36,7 @@ require_once('skipifconnectfailure.inc'); var_dump(mysqli_set_opt($link, MYSQLI_OPT_CONNECT_TIMEOUT, 10)); var_dump(mysqli_set_opt($link, MYSQLI_OPT_LOCAL_INFILE, 1)); var_dump(mysqli_set_opt($link, MYSQLI_INIT_COMMAND, 'SET AUTOCOMMIT=0')); - var_dump(mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)); + var_dump(my_mysqli_real_connect($link, $host, $user, $passwd, $db, $port, $socket)); var_dump(mysqli_set_opt($link, MYSQLI_READ_DEFAULT_GROUP, 'extra_my.cnf')); var_dump(mysqli_set_opt($link, MYSQLI_READ_DEFAULT_FILE, 'extra_my.cnf')); var_dump(mysqli_set_opt($link, MYSQLI_OPT_CONNECT_TIMEOUT, 10)); diff --git a/ext/mysqli/tests/mysqli_set_opt_numeric_and_datetime_as_unicode.phpt b/ext/mysqli/tests/mysqli_set_opt_numeric_and_datetime_as_unicode.phpt index 269e7dcf3..77047a19c 100644 --- a/ext/mysqli/tests/mysqli_set_opt_numeric_and_datetime_as_unicode.phpt +++ b/ext/mysqli/tests/mysqli_set_opt_numeric_and_datetime_as_unicode.phpt @@ -143,5 +143,9 @@ if (!stristr(mysqli_get_client_info(), "mysqlnd")) mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_sqlstate.phpt b/ext/mysqli/tests/mysqli_sqlstate.phpt index cdf0b5eec..0ed39f4ee 100644 --- a/ext/mysqli/tests/mysqli_sqlstate.phpt +++ b/ext/mysqli/tests/mysqli_sqlstate.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_sqlstate() --SKIPIF-- - --FILE-- @@ -35,6 +35,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- NULL %s(5) "00000" diff --git a/ext/mysqli/tests/mysqli_ssl_set.phpt b/ext/mysqli/tests/mysqli_ssl_set.phpt index c53cdf138..e868f34f1 100644 --- a/ext/mysqli/tests/mysqli_ssl_set.phpt +++ b/ext/mysqli/tests/mysqli_ssl_set.phpt @@ -1,9 +1,9 @@ --TEST-- mysqli_ssl_set() - test is a stub! --SKIPIF-- - +--CLEAN-- + --EXPECTF-- [009] [%d] (error message varies with the MySQL Server version, check the error code) diff --git a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt index 6156936f3..abedf56b2 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_get.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_get.phpt @@ -62,5 +62,9 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! diff --git a/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt b/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt index cb7d507eb..26bbf9649 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_get_prefetch.phpt @@ -22,5 +22,9 @@ die("SKIP: prefetch isn't supported at the moment"); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt index c5d88bf27..7bc9882f8 100644 --- a/ext/mysqli/tests/mysqli_stmt_attr_set.phpt +++ b/ext/mysqli/tests/mysqli_stmt_attr_set.phpt @@ -1,5 +1,5 @@ --TEST-- -mysqli_stmt_attr_set() - KNOWN ISSUE: mysqlnd does not check for invalid codes +mysqli_stmt_attr_set() - mysqlnd does not check for invalid codes --SKIPIF-- close(); @@ -259,5 +262,9 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- -done! \ No newline at end of file +done! diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param.phpt index 0b39a1b6d..9aaac9804 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_param.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_param.phpt @@ -370,7 +370,7 @@ require_once('skipifconnectfailure.inc'); printf("[2014] Cannot find row id = %d\n", $values['id']); else if (isset($row['label']) && ($values['label'] != $row['label'])) printf("[2015] Expecting label = %s, got label = %s\n", $values['label'], $row['label']); - + mysqli_free_result($res); } @@ -383,6 +383,10 @@ require_once('skipifconnectfailure.inc'); printf("[021] Expecting NULL, got %s/%s\n", gettype($tmp), $tmp); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_bind_param(): Number of elements in type definition string doesn't match number of bind variables in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt index 8fc9380b3..8f4a989bb 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_param_call_user_func.phpt @@ -328,6 +328,10 @@ if (version_compare(PHP_VERSION, '5.3.0-dev') == -1) print "done!"; ?> +--CLEAN-- + --EXPECTF-- Regular, procedural, using variables int(1) diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param_check_param_no_change.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param_check_param_no_change.phpt index 5aab1a677..a7d36743c 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_param_check_param_no_change.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_param_check_param_no_change.phpt @@ -19,7 +19,7 @@ require_once('skipifconnectfailure.inc'); $foo = new foo; $foo->bar = "фубар"; - echo "Test 1: \n"; + echo "Test 1:\n"; $stmt = $link->prepare("SELECT ? FOO"); var_dump($foo); // here you can see the bar member var beeing a string $stmt->bind_param("s", $foo->bar); @@ -30,11 +30,11 @@ require_once('skipifconnectfailure.inc'); $stmt->free_result(); echo("$one\n\n"); - // it is getting worse. Binding the same var twice with different + // it is getting worse. Binding the same var twice with different // types you can get unexpected results (e.g. binary trash for the // string and misc data for the integer. See next 2 tests. - echo "Test 2: \n"; + echo "Test 2:\n"; $stmt = $link->prepare("SELECT ? FOO, ? BAR"); var_dump($foo); $stmt->bind_param("si", $foo->bar, $foo->bar); @@ -50,7 +50,7 @@ require_once('skipifconnectfailure.inc'); echo("$one - $two\n\n"); - echo "Test 3: \n"; + echo "Test 3:\n"; $stmt = $link->prepare("SELECT ? FOO, ? BAR"); var_dump($foo); $stmt->bind_param("is", $foo->bar, $foo->bar); @@ -60,89 +60,51 @@ require_once('skipifconnectfailure.inc'); $stmt->fetch(); $stmt->free_result(); echo("$one - $two\n\n"); - echo "done!\n"; + echo "done!"; +?> +--CLEAN-- + --EXPECTF-- -Test 1: -object(foo)#3 (1) { - ["bar"]=> - string(10) "фубар" -} -object(foo)#3 (1) { - ["bar"]=> - &string(10) "фубар" -} -фубар - -Test 2: -object(foo)#3 (1) { - ["bar"]=> - string(10) "фубар" -} ---- -object(foo)#3 (1) { - ["bar"]=> - &string(10) "фубар" -} ---- -object(foo)#3 (1) { - ["bar"]=> - &string(10) "фубар" -} ---- -фубар - 0 - -Test 3: -object(foo)#3 (1) { - ["bar"]=> - string(10) "фубар" -} -object(foo)#3 (1) { - ["bar"]=> - &string(10) "фубар" -} -0 - фубар - -done! ---UEXPECTF-- -Test 1: -object(foo)#3 (1) { - [u"bar"]=> - unicode(5) "фубар" +Test 1: +object(foo)#%d (1) { + [%u|b%"bar"]=> + %unicode|string%(%d) "фубар" } -object(foo)#3 (1) { - [u"bar"]=> - &unicode(5) "фубар" +object(foo)#%d (1) { + [%u|b%"bar"]=> + &%unicode|string%(%d) "фубар" } фубар -Test 2: -object(foo)#3 (1) { - [u"bar"]=> - unicode(5) "фубар" +Test 2: +object(foo)#%d (1) { + [%u|b%"bar"]=> + %unicode|string%(%d) "фубар" } --- -object(foo)#3 (1) { - [u"bar"]=> - &unicode(5) "фубар" +object(foo)#%d (1) { + [%u|b%"bar"]=> + &%unicode|string%(%d) "фубар" } --- -object(foo)#3 (1) { - [u"bar"]=> - &unicode(5) "фубар" +object(foo)#%d (1) { + [%u|b%"bar"]=> + &%unicode|string%(%d) "фубар" } --- фубар - 0 -Test 3: -object(foo)#3 (1) { - [u"bar"]=> - unicode(5) "фубар" +Test 3: +object(foo)#%d (1) { + [%u|b%"bar"]=> + %unicode|string%(%d) "фубар" } -object(foo)#3 (1) { - [u"bar"]=> - &unicode(5) "фубар" +object(foo)#%d (1) { + [%u|b%"bar"]=> + &%unicode|string%(%d) "фубар" } 0 - фубар -done! +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param_references.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param_references.phpt index 8ca45691e..24d4314f1 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_param_references.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_param_references.phpt @@ -151,12 +151,13 @@ require_once('skipifconnectfailure.inc'); printf("[025] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); findRow(26, $link, $id_ref_ref, $label_ref_ref); + unset($id); + unset($label); $id = 102; $label = new stdClass(); $label->label = 'y'; $id_ref = &$GLOBALS['id']; $label_ref = &$label->label; - if (true !== ($tmp = mysqli_stmt_bind_param($stmt, "is", $id_ref, $label_ref))) printf("[027] Expecting boolean/false, got %s/%s\n", gettype($tmp), $tmp); if (true !== @mysqli_stmt_execute($stmt)) @@ -199,5 +200,9 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_param_type_juggling.phpt b/ext/mysqli/tests/mysqli_stmt_bind_param_type_juggling.phpt index 4e03c66f2..ab871ce95 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_param_type_juggling.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_param_type_juggling.phpt @@ -120,5 +120,9 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt index a1b0e2caa..f5756740e 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_result.phpt @@ -282,8 +282,12 @@ require_once('skipifconnectfailure.inc'); func_mysqli_stmt_bind_result($link, $engine, "b", "MEDIUMTEXT", "", 1640, $hint_str_or_unicode); /* Is this one related? http://bugs.php.net/bug.php?id=35759 */ - func_mysqli_stmt_bind_result($link, $engine, "b", "LONGBLOB", "", 1660); - func_mysqli_stmt_bind_result($link, $engine, "b", "LONGTEXT", "", 1680, $hint_str_or_unicode); + if (($IS_MYSQLND) || (!$IS_MYSQLND && (ini_get('memory_limit') > 4294967296))) { + /* NOTE: the MySQL Client Library - not mysqlnd - will allocate + a hugge max_length(type) = 4GB bind buffer */ + func_mysqli_stmt_bind_result($link, $engine, "b", "LONGBLOB", "", 1660); + func_mysqli_stmt_bind_result($link, $engine, "b", "LONGTEXT", "", 1680, $hint_str_or_unicode); + } func_mysqli_stmt_bind_result($link, $engine, "s", "ENUM('a', 'b')", "a", 1700, $hint_str_or_unicode); func_mysqli_stmt_bind_result($link, $engine, "s", "ENUM('a', 'b')", NULL, 1720, $hint_str_or_unicode); @@ -308,6 +312,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_bind_result(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result_bit.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result_bit.phpt index 34f783189..1eef76747 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_result_bit.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_result_bit.phpt @@ -25,11 +25,11 @@ require_once('skipifconnectfailure.inc'); return $bin; } - if (!$link_ins = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link_ins = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); - if (!$link_sel = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link_sel = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[002] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -151,5 +151,9 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link_sel); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result_format.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result_format.phpt index ba8868697..dee5a7e0f 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_result_format.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_result_format.phpt @@ -138,7 +138,7 @@ memory_limit=83886080 return true; } - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect - [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); @@ -329,5 +329,9 @@ memory_limit=83886080 mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result_references.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result_references.phpt index 3040d316a..511f7e3e1 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_result_references.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_result_references.phpt @@ -242,6 +242,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- plain vanilla... int(1) diff --git a/ext/mysqli/tests/mysqli_stmt_bind_result_zerofill.phpt b/ext/mysqli/tests/mysqli_stmt_bind_result_zerofill.phpt index e5bd30484..56508533b 100644 --- a/ext/mysqli/tests/mysqli_stmt_bind_result_zerofill.phpt +++ b/ext/mysqli/tests/mysqli_stmt_bind_result_zerofill.phpt @@ -89,5 +89,9 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_close.phpt b/ext/mysqli/tests/mysqli_stmt_close.phpt index dbe86805a..b38f0cd68 100644 --- a/ext/mysqli/tests/mysqli_stmt_close.phpt +++ b/ext/mysqli/tests/mysqli_stmt_close.phpt @@ -79,6 +79,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_close(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt index daabed8cd..246158e4c 100644 --- a/ext/mysqli/tests/mysqli_stmt_data_seek.phpt +++ b/ext/mysqli/tests/mysqli_stmt_data_seek.phpt @@ -81,6 +81,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_data_seek(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_datatype_change.phpt b/ext/mysqli/tests/mysqli_stmt_datatype_change.phpt index b5f8d5916..25c183a2a 100644 --- a/ext/mysqli/tests/mysqli_stmt_datatype_change.phpt +++ b/ext/mysqli/tests/mysqli_stmt_datatype_change.phpt @@ -9,14 +9,12 @@ require_once('skipifconnectfailure.inc'); --FILE-- query("use $db"); $c2->query("use $db"); $c1->query("drop table if exists type_change"); - $c1->query("create table type_change(a int, b char(10))"); + $c1->query("create table type_change(a int, b char(10)) ENGINE = " . $engine); $c1->query("insert into type_change values (1, 'one'), (2, 'two')"); $s1 = $c1->prepare("select a from type_change order by a"); var_dump($s1->execute(), $s1->bind_result($col1)); @@ -56,6 +54,18 @@ require_once('skipifconnectfailure.inc'); echo "done!"; ?> +--CLEAN-- + + --EXPECTF-- bool(true) bool(true) diff --git a/ext/mysqli/tests/mysqli_stmt_errno.phpt b/ext/mysqli/tests/mysqli_stmt_errno.phpt index 16f9baaa5..59fde718d 100644 --- a/ext/mysqli/tests/mysqli_stmt_errno.phpt +++ b/ext/mysqli/tests/mysqli_stmt_errno.phpt @@ -59,6 +59,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_errno(): Couldn't fetch mysqli_stmt in %s on line %d done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_error.phpt b/ext/mysqli/tests/mysqli_stmt_error.phpt index 2c46e142b..ffb77fe0a 100644 --- a/ext/mysqli/tests/mysqli_stmt_error.phpt +++ b/ext/mysqli/tests/mysqli_stmt_error.phpt @@ -59,6 +59,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_error(): Couldn't fetch mysqli_stmt in %s on line %d done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_execute.phpt b/ext/mysqli/tests/mysqli_stmt_execute.phpt index f3c34c517..d1d62c206 100644 --- a/ext/mysqli/tests/mysqli_stmt_execute.phpt +++ b/ext/mysqli/tests/mysqli_stmt_execute.phpt @@ -126,6 +126,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_execute(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt index e4e57138f..afedea42d 100644 --- a/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt +++ b/ext/mysqli/tests/mysqli_stmt_execute_stored_proc.phpt @@ -5,7 +5,7 @@ mysqli_stmt_execute() - Stored Procedures require_once('skipif.inc'); require_once('skipifconnectfailure.inc'); require_once('connect.inc'); -if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { +if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) { die(sprintf('skip Cannot connect to MySQL, [%d] %s.', mysqli_connect_errno(), mysqli_connect_error())); } if (mysqli_get_server_version($link) <= 50000) { @@ -181,5 +181,18 @@ if (mysqli_get_server_version($link) <= 50000) { mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_fetch.phpt b/ext/mysqli/tests/mysqli_stmt_fetch.phpt index ac0c07c94..6f7014831 100644 --- a/ext/mysqli/tests/mysqli_stmt_fetch.phpt +++ b/ext/mysqli/tests/mysqli_stmt_fetch.phpt @@ -85,6 +85,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_fetch(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_fetch_bit.phpt b/ext/mysqli/tests/mysqli_stmt_fetch_bit.phpt index 0846599b3..2a2914ad8 100644 --- a/ext/mysqli/tests/mysqli_stmt_fetch_bit.phpt +++ b/ext/mysqli/tests/mysqli_stmt_fetch_bit.phpt @@ -18,11 +18,12 @@ Fetching BIT column values using the PS API +--CLEAN-- + --EXPECTF-- -done! +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt b/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt index d858c94da..e63591a10 100644 --- a/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt +++ b/ext/mysqli/tests/mysqli_stmt_fetch_fields_win32_unicode.phpt @@ -46,6 +46,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- OK: 1 OK: 2 diff --git a/ext/mysqli/tests/mysqli_stmt_fetch_geom.phpt b/ext/mysqli/tests/mysqli_stmt_fetch_geom.phpt new file mode 100644 index 000000000..84998b942 --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_fetch_geom.phpt @@ -0,0 +1,141 @@ +--TEST-- +mysqli_stmt_fetch - geometry / spatial types +--SKIPIF-- + +--FILE-- +type != MYSQLI_TYPE_GEOMETRY) { + printf("[%04d] [%d] %s wrong type %d\n", $offset + 10, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $fields[1]->type); + } + + $num = 0; + $rows = array(); + while (true === @mysqli_stmt_fetch($stmt)) { + $rows[] = array('id' => $id, 'label' => $bind_res); + $num++; + } + + if ($num != 3) { + printf("[%04d] [%d] %s, expecting 3 results, got only %d results\n", + $offset + 17, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $num); + return false; + } + mysqli_stmt_close($stmt); + + foreach ($rows as $row) { + if (!$stmt = mysqli_stmt_init($link)) { + printf("[%04d] [%d] %s\n", $offset + 10, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_stmt_prepare($stmt, "INSERT INTO test(id, label) VALUES (?, ?)")) { + printf("[%04d] [%d] %s\n", $offset + 11, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + $new_id = $row['id'] + 10; + if (!mysqli_stmt_bind_param($stmt, "is", $new_id, $row['label'])) { + printf("[%04d] [%d] %s\n", $offset + 12, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + + if (!mysqli_stmt_execute($stmt)) { + printf("[%04d] [%d] %s\n", $offset + 13, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); + return false; + } + mysqli_stmt_close($stmt); + + if (!$res_normal = mysqli_query($link, sprintf("SELECT id, label FROM test WHERE id = %d", + $new_id))) { + printf("[%04d] [%d] %s\n", $offset + 14, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!$row_normal = mysqli_fetch_assoc($res_normal)) { + printf("[%04d] [%d] %s\n", $offset + 15, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if ($row_normal['label'] != $row['label']) { + printf("[%04d] PS and non-PS return different data.\n", $offset + 16); + return false; + } + mysqli_free_result($res_normal); + } + + return true; + } + + func_mysqli_stmt_fetch_geom($link, $engine, "GEOMETRY", "GeomFromText('POINT(2 2)')", 20); + func_mysqli_stmt_fetch_geom($link, $engine, "POINT", "GeomFromText('POINT(1 1)')", 40); + func_mysqli_stmt_fetch_geom($link, $engine, "LINESTRING", "GeomFromText('LINESTRING(0 0,1 1,2 2)')", 60); + func_mysqli_stmt_fetch_geom($link, $engine, "POLYGON", "GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))')", 80); + func_mysqli_stmt_fetch_geom($link, $engine, "MULTIPOINT", "GeomFromText('MULTIPOINT(1 1, 2 2)')", 100); + func_mysqli_stmt_fetch_geom($link, $engine, "MULTILINESTRING", "GeomFromText('MULTILINESTRING((0 0,1 1,2 2),(0 0,1 1,3 3))')", 120); + func_mysqli_stmt_fetch_geom($link, $engine, "MULTIPOLYGON", "GeomFromText('MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5)),((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5)))')", 140); + func_mysqli_stmt_fetch_geom($link, $engine, "GEOMETRYCOLLECTION", "GeomFromText('GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))')", 160); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- + +--EXPECTF-- +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_field_count.phpt b/ext/mysqli/tests/mysqli_stmt_field_count.phpt index 11c0e12e2..2dbf487ac 100644 --- a/ext/mysqli/tests/mysqli_stmt_field_count.phpt +++ b/ext/mysqli/tests/mysqli_stmt_field_count.phpt @@ -81,6 +81,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_field_count(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_free_result.phpt b/ext/mysqli/tests/mysqli_stmt_free_result.phpt index db9defc63..12c1a34bc 100644 --- a/ext/mysqli/tests/mysqli_stmt_free_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_free_result.phpt @@ -74,6 +74,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_free_result(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_get_result.phpt b/ext/mysqli/tests/mysqli_stmt_get_result.phpt index e58f6b000..58a7f0cde 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result.phpt @@ -155,6 +155,10 @@ if (!function_exists('mysqli_stmt_get_result')) print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_fetch(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_get_result2.phpt b/ext/mysqli/tests/mysqli_stmt_get_result2.phpt index c56200873..1f493d2f1 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result2.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result2.phpt @@ -151,6 +151,10 @@ if (!function_exists('mysqli_stmt_get_result')) print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(2) { [%u|b%"id"]=> diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt index 27ca38909..6c476f7e9 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_bit.phpt @@ -37,7 +37,7 @@ Fetching BIT column values using the PS API return $bin; } - if (!$link = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[001] Cannot connect to the server using host=%s, user=%s, passwd=***, dbname=%s, port=%s, socket=%s\n", $host, $user, $db, $port, $socket); @@ -125,5 +125,9 @@ Fetching BIT column values using the PS API mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_field_count.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_field_count.phpt index 6a7131b92..dab805c1b 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_field_count.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_field_count.phpt @@ -5,7 +5,7 @@ mysqli_stmt_get_result() - meta data, field_count() require_once('skipif.inc'); require_once('skipifemb.inc'); require_once('skipifconnectfailure.inc'); - + if (!function_exists('mysqli_stmt_get_result')) die('skip mysqli_stmt_get_result not available'); ?> @@ -42,6 +42,10 @@ mysqli_stmt_get_result() - meta data, field_count() mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- 2 2 done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_geom.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_geom.phpt new file mode 100644 index 000000000..c86a385be --- /dev/null +++ b/ext/mysqli/tests/mysqli_stmt_get_result_geom.phpt @@ -0,0 +1,143 @@ +--TEST-- +mysqli_stmt_get_result - geometry / spatial types +--SKIPIF-- + +--FILE-- +type != MYSQLI_TYPE_GEOMETRY) { + printf("[%04d] [%d] %s wrong type %d\n", $offset + 10, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $fields[1]->type); + } + + $num = 0; + while ($row = mysqli_fetch_assoc($res)) { + $bind_res = &$row['label']; + + if (!$stmt2 = mysqli_stmt_init($link)) { + printf("[%04d] [%d] %s\n", $offset + 11, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!mysqli_stmt_prepare($stmt2, "INSERT INTO test(id, label) VALUES (?, ?)")) { + printf("[%04d] [%d] %s\n", $offset + 12, mysqli_stmt_errno($stmt2), mysqli_stmt_error($stmt2)); + return false; + } + + $id = $row['id'] + 10; + if (!mysqli_stmt_bind_param($stmt2, "is", $id, $bind_res)) { + printf("[%04d] [%d] %s\n", $offset + 13, mysqli_stmt_errno($stmt2), mysqli_stmt_error($stmt2)); + return false; + } + + if (!mysqli_stmt_execute($stmt2)) { + printf("[%04d] [%d] %s\n", $offset + 14, mysqli_stmt_errno($stmt2), mysqli_stmt_error($stmt2)); + return false; + } + mysqli_stmt_close($stmt2); + + if (!$res_normal = mysqli_query($link, sprintf("SELECT id, label FROM test WHERE id = %d", + $row['id'] + 10))) { + printf("[%04d] [%d] %s\n", $offset + 15, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if (!$row_normal = mysqli_fetch_assoc($res_normal)) { + printf("[%04d] [%d] %s\n", $offset + 16, mysqli_errno($link), mysqli_error($link)); + return false; + } + + if ($row_normal['label'] != $bind_res) { + printf("[%04d] PS and non-PS return different data.\n", $offset + 17); + return false; + } + mysqli_free_result($res_normal); + $num++; + } + + if ($num != 3) { + printf("[%04d] [%d] %s, expecting 3 results, got only %d results\n", + $offset + 18, mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt), $num); + mysqli_free_result($res); + mysqli_stmt_close($stmt); + return false; + } + mysqli_free_result($res); + mysqli_stmt_close($stmt); + + return true; + } + + func_mysqli_stmt_get_result_geom($link, $engine, "GEOMETRY", "GeomFromText('POINT(2 2)')", 20); + func_mysqli_stmt_get_result_geom($link, $engine, "POINT", "GeomFromText('POINT(1 1)')", 40); + func_mysqli_stmt_get_result_geom($link, $engine, "LINESTRING", "GeomFromText('LINESTRING(0 0,1 1,2 2)')", 60); + func_mysqli_stmt_get_result_geom($link, $engine, "POLYGON", "GeomFromText('POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))')", 80); + func_mysqli_stmt_get_result_geom($link, $engine, "MULTIPOINT", "GeomFromText('MULTIPOINT(1 1, 2 2)')", 100); + func_mysqli_stmt_get_result_geom($link, $engine, "MULTILINESTRING", "GeomFromText('MULTILINESTRING((0 0,1 1,2 2),(0 0,1 1,3 3))')", 120); + func_mysqli_stmt_get_result_geom($link, $engine, "MULTIPOLYGON", "GeomFromText('MULTIPOLYGON(((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5)),((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5)))')", 140); + func_mysqli_stmt_get_result_geom($link, $engine, "GEOMETRYCOLLECTION", "GeomFromText('GEOMETRYCOLLECTION(POINT(1 1),LINESTRING(0 0,1 1,2 2,3 3,4 4))')", 160); + + mysqli_close($link); + print "done!"; +?> +--CLEAN-- + +--EXPECTF-- +done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt index bf13c1e2b..7fdabc001 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_metadata.phpt @@ -206,6 +206,10 @@ if (!function_exists('mysqli_stmt_get_result')) print "done!"; ?> +--CLEAN-- + --EXPECTF-- array(2) { [%u|b%"id"]=> diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt index 12489cef5..43ec10c4f 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_metadata_fetch_field.phpt @@ -39,199 +39,105 @@ if (!function_exists('mysqli_stmt_get_result')) mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- object(stdClass)#%d (11) { - ["name"]=> - string(2) "id" - ["orgname"]=> - string(2) "id" - ["table"]=> - string(4) "test" - ["orgtable"]=> - string(4) "test" - ["def"]=> - string(0) "" - ["max_length"]=> + [%u|b%"name"]=> + %unicode|string%(2) "id" + [%u|b%"orgname"]=> + %unicode|string%(2) "id" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"orgtable"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> int(0) - ["length"]=> + [%u|b%"length"]=> int(11) - ["charsetnr"]=> + [%u|b%"charsetnr"]=> int(63) - ["flags"]=> + [%u|b%"flags"]=> int(49155) - ["type"]=> + [%u|b%"type"]=> int(3) - ["decimals"]=> + [%u|b%"decimals"]=> int(0) } object(stdClass)#%d (11) { - ["name"]=> - string(5) "label" - ["orgname"]=> - string(5) "label" - ["table"]=> - string(4) "test" - ["orgtable"]=> - string(4) "test" - ["def"]=> - string(0) "" - ["max_length"]=> + [%u|b%"name"]=> + %unicode|string%(5) "label" + [%u|b%"orgname"]=> + %unicode|string%(5) "label" + [%u|b%"table"]=> + %unicode|string%(4) "test" + [%u|b%"orgtable"]=> + %unicode|string%(4) "test" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> int(1) - ["length"]=> + [%u|b%"length"]=> int(1) - ["charsetnr"]=> + [%u|b%"charsetnr"]=> int(8) - ["flags"]=> + [%u|b%"flags"]=> int(0) - ["type"]=> + [%u|b%"type"]=> int(254) - ["decimals"]=> + [%u|b%"decimals"]=> int(0) } object(stdClass)#%d (11) { - ["name"]=> - string(3) "_id" - ["orgname"]=> - string(0) "" - ["table"]=> - string(0) "" - ["orgtable"]=> - string(0) "" - ["def"]=> - string(0) "" - ["max_length"]=> + [%u|b%"name"]=> + %unicode|string%(3) "_id" + [%u|b%"orgname"]=> + %unicode|string%(0) "" + [%u|b%"table"]=> + %unicode|string%(0) "" + [%u|b%"orgtable"]=> + %unicode|string%(0) "" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> int(0) - ["length"]=> + [%u|b%"length"]=> int(%d) - ["charsetnr"]=> + [%u|b%"charsetnr"]=> int(63) - ["flags"]=> + [%u|b%"flags"]=> int(32897) - ["type"]=> + [%u|b%"type"]=> int(8) - ["decimals"]=> + [%u|b%"decimals"]=> int(0) } object(stdClass)#%d (11) { - ["name"]=> - string(8) "___label" - ["orgname"]=> - string(0) "" - ["table"]=> - string(0) "" - ["orgtable"]=> - string(0) "" - ["def"]=> - string(0) "" - ["max_length"]=> + [%u|b%"name"]=> + %unicode|string%(8) "___label" + [%u|b%"orgname"]=> + %unicode|string%(0) "" + [%u|b%"table"]=> + %unicode|string%(0) "" + [%u|b%"orgtable"]=> + %unicode|string%(0) "" + [%u|b%"def"]=> + %unicode|string%(0) "" + [%u|b%"max_length"]=> int(2) - ["length"]=> + [%u|b%"length"]=> int(2) - ["charsetnr"]=> + [%u|b%"charsetnr"]=> int(8) - ["flags"]=> - int(0) - ["type"]=> - int(253) - ["decimals"]=> - int(31) -} -done! ---UEXPECTF-- -object(stdClass)#%d (11) { - [u"name"]=> - unicode(2) "id" - [u"orgname"]=> - unicode(2) "id" - [u"table"]=> - unicode(4) "test" - [u"orgtable"]=> - unicode(4) "test" - [u"def"]=> - unicode(0) "" - [u"max_length"]=> - int(0) - [u"length"]=> - int(11) - [u"charsetnr"]=> - int(63) - [u"flags"]=> - int(49155) - [u"type"]=> - int(3) - [u"decimals"]=> - int(0) -} -object(stdClass)#%d (11) { - [u"name"]=> - unicode(5) "label" - [u"orgname"]=> - unicode(5) "label" - [u"table"]=> - unicode(4) "test" - [u"orgtable"]=> - unicode(4) "test" - [u"def"]=> - unicode(0) "" - [u"max_length"]=> - int(1) - [u"length"]=> - int(3) - [u"charsetnr"]=> - int(33) - [u"flags"]=> - int(0) - [u"type"]=> - int(254) - [u"decimals"]=> - int(0) -} -object(stdClass)#%d (11) { - [u"name"]=> - unicode(3) "_id" - [u"orgname"]=> - unicode(0) "" - [u"table"]=> - unicode(0) "" - [u"orgtable"]=> - unicode(0) "" - [u"def"]=> - unicode(0) "" - [u"max_length"]=> - int(0) - [u"length"]=> - int(%d) - [u"charsetnr"]=> - int(63) - [u"flags"]=> - int(32897) - [u"type"]=> - int(8) - [u"decimals"]=> - int(0) -} -object(stdClass)#%d (11) { - [u"name"]=> - unicode(8) "___label" - [u"orgname"]=> - unicode(0) "" - [u"table"]=> - unicode(0) "" - [u"orgtable"]=> - unicode(0) "" - [u"def"]=> - unicode(0) "" - [u"max_length"]=> - int(2) - [u"length"]=> - int(6) - [u"charsetnr"]=> - int(33) - [u"flags"]=> + [%u|b%"flags"]=> int(0) - [u"type"]=> + [%u|b%"type"]=> int(253) - [u"decimals"]=> + [%u|b%"decimals"]=> int(31) } done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_non_select.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_non_select.phpt index f08250292..717b39bd5 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_non_select.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_non_select.phpt @@ -88,5 +88,9 @@ if (!function_exists('mysqli_stmt_get_result')) print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt index 54e4aeb60..c4312c603 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_seek.phpt @@ -114,6 +114,10 @@ if (!function_exists('mysqli_stmt_get_result')) print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_data_seek(): Couldn't fetch mysqli_result in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_get_result_types.phpt b/ext/mysqli/tests/mysqli_stmt_get_result_types.phpt index 164326db4..724a32a78 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_result_types.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_result_types.phpt @@ -12,7 +12,7 @@ mysqli_stmt_get_result - data types --FILE-- ') == 1) ? 'unicode' : 'string'; @@ -251,5 +251,9 @@ mysqli_stmt_get_result - data types mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt b/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt index 9f8f824b9..b8ca14eaf 100644 --- a/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt +++ b/ext/mysqli/tests/mysqli_stmt_get_warnings.phpt @@ -79,6 +79,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_get_warnings(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_init.phpt b/ext/mysqli/tests/mysqli_stmt_init.phpt index db5a21cd0..7d0154d24 100644 --- a/ext/mysqli/tests/mysqli_stmt_init.phpt +++ b/ext/mysqli/tests/mysqli_stmt_init.phpt @@ -44,6 +44,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_close(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_insert_id.phpt b/ext/mysqli/tests/mysqli_stmt_insert_id.phpt index 1bfe19836..0347e66bd 100644 --- a/ext/mysqli/tests/mysqli_stmt_insert_id.phpt +++ b/ext/mysqli/tests/mysqli_stmt_insert_id.phpt @@ -67,6 +67,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_insert_id(): Couldn't fetch mysqli_stmt in %s on line %d NULL diff --git a/ext/mysqli/tests/mysqli_stmt_num_rows.phpt b/ext/mysqli/tests/mysqli_stmt_num_rows.phpt index 5cc83977d..4f3bc6142 100644 --- a/ext/mysqli/tests/mysqli_stmt_num_rows.phpt +++ b/ext/mysqli/tests/mysqli_stmt_num_rows.phpt @@ -97,6 +97,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- run_tests.php don't fool me with your 'ungreedy' expression '.+?'! diff --git a/ext/mysqli/tests/mysqli_stmt_param_count.phpt b/ext/mysqli/tests/mysqli_stmt_param_count.phpt index 92dfe6432..f55acfbbd 100644 --- a/ext/mysqli/tests/mysqli_stmt_param_count.phpt +++ b/ext/mysqli/tests/mysqli_stmt_param_count.phpt @@ -60,6 +60,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_param_count(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_prepare.phpt b/ext/mysqli/tests/mysqli_stmt_prepare.phpt index 35879591e..115e1a52e 100644 --- a/ext/mysqli/tests/mysqli_stmt_prepare.phpt +++ b/ext/mysqli/tests/mysqli_stmt_prepare.phpt @@ -47,6 +47,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_prepare(): Couldn't fetch mysqli_stmt in %s on line %d done! diff --git a/ext/mysqli/tests/mysqli_stmt_reset.phpt b/ext/mysqli/tests/mysqli_stmt_reset.phpt index 903ba23eb..9f8864d28 100644 --- a/ext/mysqli/tests/mysqli_stmt_reset.phpt +++ b/ext/mysqli/tests/mysqli_stmt_reset.phpt @@ -99,6 +99,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_reset(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt b/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt index 12235fc58..34d3bb201 100644 --- a/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt +++ b/ext/mysqli/tests/mysqli_stmt_result_metadata.phpt @@ -93,6 +93,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_result_metadata(): invalid object or resource mysqli_stmt diff --git a/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt b/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt index f6e509ae0..f0b775764 100644 --- a/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt +++ b/ext/mysqli/tests/mysqli_stmt_result_metadata_sqltests.phpt @@ -225,5 +225,9 @@ die("skip Check again when the Klingons visit earth - http://bugs.mysql.com/bug. mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt index d90248c71..4f173eff6 100644 --- a/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data.phpt @@ -126,6 +126,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_send_long_data(): Invalid parameter number in %s on line %d done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt index 6c6936cb6..5bd40d84f 100644 --- a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_libmysql.phpt @@ -91,5 +91,9 @@ if (stristr(mysqli_get_client_info(), 'mysqlnd')) print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt index f641819c9..be8e59544 100644 --- a/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt +++ b/ext/mysqli/tests/mysqli_stmt_send_long_data_packet_size_mysqlnd.phpt @@ -96,5 +96,9 @@ Warning: mysqli_stmt_send_long_data(): There was an error while sending long dat print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_sqlstate.phpt b/ext/mysqli/tests/mysqli_stmt_sqlstate.phpt index b946d31f2..b8a97cdef 100644 --- a/ext/mysqli/tests/mysqli_stmt_sqlstate.phpt +++ b/ext/mysqli/tests/mysqli_stmt_sqlstate.phpt @@ -51,6 +51,10 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_stmt_sqlstate(): invalid object or resource mysqli_stmt in %s on line %d diff --git a/ext/mysqli/tests/mysqli_stmt_store_result.phpt b/ext/mysqli/tests/mysqli_stmt_store_result.phpt index b74808bac..ee0bf83a8 100644 --- a/ext/mysqli/tests/mysqli_stmt_store_result.phpt +++ b/ext/mysqli/tests/mysqli_stmt_store_result.phpt @@ -42,7 +42,7 @@ require_once('skipifconnectfailure.inc'); !mysqli_stmt_execute($stmt)) printf("[008] [%d] %s\n", mysqli_stmt_errno($stmt), mysqli_stmt_error($stmt)); - if (!$link_buf = mysqli_connect($host, $user, $passwd, $db, $port, $socket)) + if (!$link_buf = my_mysqli_connect($host, $user, $passwd, $db, $port, $socket)) printf("[009] [%d] %s\n", mysqli_connect_errno(), mysqli_connect_error()); if (!$stmt_buf = mysqli_stmt_init($link_buf)) @@ -82,5 +82,9 @@ require_once('skipifconnectfailure.inc'); mysqli_close($link_buf); print "done!"; ?> +--CLEAN-- + --EXPECTF-- done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_stmt_unclonable.phpt b/ext/mysqli/tests/mysqli_stmt_unclonable.phpt index 5aa93b146..edddbea94 100644 --- a/ext/mysqli/tests/mysqli_stmt_unclonable.phpt +++ b/ext/mysqli/tests/mysqli_stmt_unclonable.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); +--CLEAN-- + --EXPECTF-- Warning: mysqli_store_result(): Couldn't fetch mysqli in %s on line %d done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_thread_id.phpt b/ext/mysqli/tests/mysqli_thread_id.phpt index 673548944..a67060a1c 100644 --- a/ext/mysqli/tests/mysqli_thread_id.phpt +++ b/ext/mysqli/tests/mysqli_thread_id.phpt @@ -35,6 +35,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_thread_id(): Couldn't fetch mysqli in %s on line %d done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_unclonable.phpt b/ext/mysqli/tests/mysqli_unclonable.phpt index 73894f4f2..d21eafa79 100644 --- a/ext/mysqli/tests/mysqli_unclonable.phpt +++ b/ext/mysqli/tests/mysqli_unclonable.phpt @@ -10,7 +10,7 @@ require_once('skipifconnectfailure.inc'); +--CLEAN-- + --EXPECTF-- Warning: mysqli_data_seek(): Function cannot be used with MYSQL_USE_RESULT in %s on line %d diff --git a/ext/mysqli/tests/mysqli_warning_count.phpt b/ext/mysqli/tests/mysqli_warning_count.phpt index c1663131b..0293fe869 100644 --- a/ext/mysqli/tests/mysqli_warning_count.phpt +++ b/ext/mysqli/tests/mysqli_warning_count.phpt @@ -43,6 +43,10 @@ require_once('skipifconnectfailure.inc'); print "done!"; ?> +--CLEAN-- + --EXPECTF-- Warning: mysqli_warning_count(): Couldn't fetch mysqli in %s on line %d done! \ No newline at end of file diff --git a/ext/mysqli/tests/mysqli_warning_unclonable.phpt b/ext/mysqli/tests/mysqli_warning_unclonable.phpt index bdbc0e2f7..57d5de764 100644 --- a/ext/mysqli/tests/mysqli_warning_unclonable.phpt +++ b/ext/mysqli/tests/mysqli_warning_unclonable.phpt @@ -13,7 +13,7 @@ if (!$TEST_EXPERIMENTAL) +--CLEAN-- + --EXPECTF-- Fatal error: Trying to clone an uncloneable object of class mysqli_warning in %s on line %d \ No newline at end of file diff --git a/ext/mysqli/tests/skipifconnectfailure.inc b/ext/mysqli/tests/skipifconnectfailure.inc index 68a62afe5..32a976357 100755 --- a/ext/mysqli/tests/skipifconnectfailure.inc +++ b/ext/mysqli/tests/skipifconnectfailure.inc @@ -2,7 +2,7 @@ require_once('connect.inc'); if ($skip_on_connect_failure) { include_once('connect.inc'); - $link = @mysqli_connect($host, $user, $passwd, $db, $port, $socket); + $link = @my_mysqli_connect($host, $user, $passwd, $db, $port, $socket); if (!is_object($link)) die(sprintf("skip Can't connect to MySQL Server - [%d] %s", mysqli_connect_errno(), mysqli_connect_error())); mysqli_close($link); diff --git a/ext/mysqli/tests/table.inc b/ext/mysqli/tests/table.inc index b36ba7b30..aa1207af4 100644 --- a/ext/mysqli/tests/table.inc +++ b/ext/mysqli/tests/table.inc @@ -1,7 +1,7 @@ diff --git a/ext/mysqlnd/mysqlnd.c b/ext/mysqlnd/mysqlnd.c index 4da134a45..42fa79d15 100644 --- a/ext/mysqlnd/mysqlnd.c +++ b/ext/mysqlnd/mysqlnd.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd.c,v 1.5.2.38 2009/03/30 16:52:33 felipe Exp $ */ +/* $Id: mysqlnd.c 289630 2009-10-14 13:51:25Z johannes $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_wireprotocol.h" @@ -82,6 +82,56 @@ void mysqlnd_library_end(TSRMLS_D) /* }}} */ +/* {{{ mysqlnd_conn::free_options */ +static void +MYSQLND_METHOD(mysqlnd_conn, free_options)(MYSQLND *conn TSRMLS_DC) +{ + zend_bool pers = conn->persistent; + + if (conn->options.charset_name) { + mnd_pefree(conn->options.charset_name, pers); + conn->options.charset_name = NULL; + } + if (conn->options.num_commands) { + unsigned int i; + for (i = 0; i < conn->options.num_commands; i++) { + /* allocated with pestrdup */ + mnd_pefree(conn->options.init_commands[i], pers); + } + mnd_pefree(conn->options.init_commands, pers); + conn->options.init_commands = NULL; + } + if (conn->options.cfg_file) { + mnd_pefree(conn->options.cfg_file, pers); + conn->options.cfg_file = NULL; + } + if (conn->options.cfg_section) { + mnd_pefree(conn->options.cfg_section, pers); + conn->options.cfg_section = NULL; + } + if (conn->options.ssl_key) { + mnd_pefree(conn->options.ssl_key, pers); + conn->options.ssl_key = NULL; + } + if (conn->options.ssl_cert) { + mnd_pefree(conn->options.ssl_cert, pers); + conn->options.ssl_cert = NULL; + } + if (conn->options.ssl_ca) { + mnd_pefree(conn->options.ssl_ca, pers); + conn->options.ssl_ca = NULL; + } + if (conn->options.ssl_capath) { + mnd_pefree(conn->options.ssl_capath, pers); + conn->options.ssl_capath = NULL; + } + if (conn->options.ssl_cipher) { + mnd_pefree(conn->options.ssl_cipher, pers); + conn->options.ssl_cipher = NULL; + } +} + + /* {{{ mysqlnd_conn::free_contents */ static void MYSQLND_METHOD(mysqlnd_conn, free_contents)(MYSQLND *conn TSRMLS_DC) @@ -153,46 +203,6 @@ MYSQLND_METHOD(mysqlnd_conn, free_contents)(MYSQLND *conn TSRMLS_DC) mnd_pefree(conn->last_message, pers); conn->last_message = NULL; } - if (conn->options.charset_name) { - mnd_pefree(conn->options.charset_name, pers); - conn->options.charset_name = NULL; - } - if (conn->options.num_commands) { - unsigned int i; - for (i = 0; i < conn->options.num_commands; i++) { - mnd_pefree(conn->options.init_commands[i], pers); - } - mnd_pefree(conn->options.init_commands, pers); - conn->options.init_commands = NULL; - } - if (conn->options.cfg_file) { - mnd_pefree(conn->options.cfg_file, pers); - conn->options.cfg_file = NULL; - } - if (conn->options.cfg_section) { - mnd_pefree(conn->options.cfg_section, pers); - conn->options.cfg_section = NULL; - } - if (conn->options.ssl_key) { - mnd_pefree(conn->options.ssl_key, pers); - conn->options.ssl_key = NULL; - } - if (conn->options.ssl_cert) { - mnd_pefree(conn->options.ssl_cert, pers); - conn->options.ssl_cert = NULL; - } - if (conn->options.ssl_ca) { - mnd_pefree(conn->options.ssl_ca, pers); - conn->options.ssl_ca = NULL; - } - if (conn->options.ssl_capath) { - mnd_pefree(conn->options.ssl_capath, pers); - conn->options.ssl_capath = NULL; - } - if (conn->options.ssl_cipher) { - mnd_pefree(conn->options.ssl_cipher, pers); - conn->options.ssl_cipher = NULL; - } if (conn->zval_cache) { DBG_INF("Freeing zval cache reference"); mysqlnd_palloc_free_thd_cache_reference(&conn->zval_cache); @@ -229,6 +239,7 @@ MYSQLND_METHOD_PRIVATE(mysqlnd_conn, dtor)(MYSQLND *conn TSRMLS_DC) DBG_INF_FMT("conn=%llu", conn->thread_id); conn->m->free_contents(conn TSRMLS_CC); + conn->m->free_options(conn TSRMLS_CC); #ifdef MYSQLND_THREADED if (conn->thread_is_running) { @@ -497,8 +508,8 @@ PHPAPI MYSQLND *mysqlnd_connect(MYSQLND *conn, host?host:"", user?user:"", db?db:"", port, mysql_flags, conn? conn->persistent:0, conn? CONN_GET_STATE(conn):-1); - DBG_INF_FMT("state=%d", CONN_GET_STATE(conn)); if (conn && CONN_GET_STATE(conn) > CONN_ALLOCED && CONN_GET_STATE(conn) ) { + DBG_INF_FMT("state=%d", CONN_GET_STATE(conn)); DBG_INF("Connecting on a connected handle."); if (CONN_GET_STATE(conn) < CONN_QUIT_SENT) { @@ -616,6 +627,10 @@ PHPAPI MYSQLND *mysqlnd_connect(MYSQLND *conn, mnd_efree(hashed_details); } + if (!conn->options.timeout_read) { + /* should always happen because read_timeout cannot be set via API */ + conn->options.timeout_read = (unsigned int) MYSQLND_G(net_read_timeout); + } if (conn->options.timeout_read) { tv.tv_sec = conn->options.timeout_read; @@ -654,7 +669,12 @@ PHPAPI MYSQLND *mysqlnd_connect(MYSQLND *conn, conn->greet_charset = mysqlnd_find_charset_nr(greet_packet.charset_no); /* we allow load data local infile by default */ - mysql_flags |= CLIENT_LOCAL_FILES; + mysql_flags |= CLIENT_LOCAL_FILES | CLIENT_PS_MULTI_RESULTS; +#ifndef MYSQLND_COMPRESSION_ENABLED + if (mysql_flags & CLIENT_COMPRESS) { + mysql_flags &= ~CLIENT_COMPRESS; + } +#endif auth_packet->user = user; auth_packet->password = passwd; @@ -736,13 +756,7 @@ PHPAPI MYSQLND *mysqlnd_connect(MYSQLND *conn, SET_EMPTY_ERROR(conn->error_info); - PACKET_FREE_ALLOCA(greet_packet); - PACKET_FREE(auth_packet); - PACKET_FREE_ALLOCA(ok_packet); - conn->zval_cache = mysqlnd_palloc_get_thd_cache_reference(zval_cache); - conn->net.cmd_buffer.length = 128L*1024L; - conn->net.cmd_buffer.buffer = mnd_pemalloc(conn->net.cmd_buffer.length, conn->persistent); mysqlnd_local_infile_default(conn); { @@ -756,13 +770,12 @@ PHPAPI MYSQLND *mysqlnd_connect(MYSQLND *conn, (char *)&buf_size TSRMLS_CC); } - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_CONNECT_SUCCESS); + MYSQLND_INC_CONN_STATISTIC_W_VALUE2(&conn->stats, STAT_CONNECT_SUCCESS, 1, STAT_OPENED_CONNECTIONS, 1); if (reconnect) { MYSQLND_INC_GLOBAL_STATISTIC(STAT_RECONNECT); } - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_OPENED_CONNECTIONS); if (conn->persistent) { - MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_OPENED_PERSISTENT_CONNECTIONS); + MYSQLND_INC_CONN_STATISTIC_W_VALUE2(&conn->stats, STAT_PCONNECT_SUCCESS, 1, STAT_OPENED_PERSISTENT_CONNECTIONS, 1); } DBG_INF_FMT("connection_id=%llu", conn->thread_id); @@ -791,6 +804,25 @@ PHPAPI MYSQLND *mysqlnd_connect(MYSQLND *conn, } #endif + if (conn->options.init_commands) { + int current_command = 0; + for (; current_command < conn->options.num_commands; ++current_command) { + const char * const command = conn->options.init_commands[current_command]; + MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_INIT_COMMAND_EXECUTED_COUNT); + if (PASS != conn->m->query(conn, command, strlen(command) TSRMLS_CC)) { + MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_INIT_COMMAND_FAILED_COUNT); + goto err; + } + if (conn->last_query_type == QUERY_SELECT) { + MYSQLND_RES * result = conn->m->use_result(conn TSRMLS_CC); + result->m.free_result(result, TRUE TSRMLS_CC); + } + } + } + + PACKET_FREE_ALLOCA(greet_packet); + PACKET_FREE(auth_packet); + PACKET_FREE_ALLOCA(ok_packet); DBG_RETURN(conn); } @@ -812,10 +844,6 @@ err: conn->scheme = NULL; } - - /* This will also close conn->net.stream if it has been opened */ - conn->m->free_contents(conn TSRMLS_CC); - if (self_alloced) { /* We have alloced, thus there are no references to this @@ -823,6 +851,8 @@ err: */ conn->m->dtor(conn TSRMLS_CC); } else { + /* This will also close conn->net.stream if it has been opened */ + conn->m->free_contents(conn TSRMLS_CC); MYSQLND_INC_CONN_STATISTIC(&conn->stats, STAT_CONNECT_FAILURE); } DBG_RETURN(NULL); @@ -1411,8 +1441,9 @@ mysqlnd_send_close(MYSQLND * conn TSRMLS_DC) switch (CONN_GET_STATE(conn)) { case CONN_READY: DBG_INF("Connection clean, sending COM_QUIT"); - ret = mysqlnd_simple_command(conn, COM_QUIT, NULL, 0, PROT_LAST, - TRUE, TRUE TSRMLS_CC); + if (conn->net.stream) { + ret = mysqlnd_simple_command(conn, COM_QUIT, NULL, 0, PROT_LAST, TRUE, TRUE TSRMLS_CC); + } /* Do nothing */ break; case CONN_SENDING_LOAD_DATA: @@ -1914,6 +1945,9 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn, break; #endif case MYSQLND_OPT_NET_CMD_BUFFER_SIZE: + if (*(unsigned int*) value < MYSQLND_NET_CMD_BUFFER_MIN_SIZE) { + DBG_RETURN(FAIL); + } conn->net.cmd_buffer.length = *(unsigned int*) value; if (!conn->net.cmd_buffer.buffer) { conn->net.cmd_buffer.buffer = mnd_pemalloc(conn->net.cmd_buffer.length, conn->persistent); @@ -1949,10 +1983,16 @@ MYSQLND_METHOD(mysqlnd_conn, set_client_option)(MYSQLND * const conn, conn->options.flags &= ~CLIENT_LOCAL_FILES; } break; + case MYSQL_INIT_COMMAND: + /* when num_commands is 0, then realloc will be effectively a malloc call, internally */ + conn->options.init_commands = mnd_perealloc(conn->options.init_commands, sizeof(char *) * (conn->options.num_commands + 1), + conn->persistent); + conn->options.init_commands[conn->options.num_commands] = pestrdup(value, conn->persistent); + ++conn->options.num_commands; + break; #ifdef WHEN_SUPPORTED_BY_MYSQLI case MYSQL_OPT_COMPRESS: #endif - case MYSQL_INIT_COMMAND: case MYSQL_READ_DEFAULT_FILE: case MYSQL_READ_DEFAULT_GROUP: #ifdef WHEN_SUPPORTED_BY_MYSQLI @@ -2161,6 +2201,7 @@ MYSQLND_CLASS_METHODS_START(mysqlnd_conn) MYSQLND_METHOD(mysqlnd_conn, set_server_option), MYSQLND_METHOD(mysqlnd_conn, set_client_option), MYSQLND_METHOD(mysqlnd_conn, free_contents), + MYSQLND_METHOD(mysqlnd_conn, free_options), MYSQLND_METHOD(mysqlnd_conn, close), MYSQLND_METHOD_PRIVATE(mysqlnd_conn, dtor), diff --git a/ext/mysqlnd/mysqlnd.h b/ext/mysqlnd/mysqlnd.h index bfd471bfb..3b3f637e0 100644 --- a/ext/mysqlnd/mysqlnd.h +++ b/ext/mysqlnd/mysqlnd.h @@ -17,18 +17,16 @@ | Ulf Wendel | +----------------------------------------------------------------------+ */ - -/* $Id: mysqlnd.h,v 1.3.2.27 2009/06/25 19:03:51 johannes Exp $ */ +/* $Id: mysqlnd.h 289630 2009-10-14 13:51:25Z johannes $ */ #ifndef MYSQLND_H #define MYSQLND_H -#define MYSQLND_VERSION "mysqlnd 5.0.5-dev - 081106 - $Revision: 1.3.2.27 $" +#define MYSQLND_VERSION "mysqlnd 5.0.5-dev - 081106 - $Revision: 289630 $" #define MYSQLND_VERSION_ID 50005 /* This forces inlining of some accessor functions */ -#define MYSQLND_USE_OPTIMISATIONS 1 - +#define MYSQLND_USE_OPTIMISATIONS 0 #define MYSQLND_STRING_TO_INT_CONVERSION /* @@ -230,8 +228,8 @@ PHPAPI unsigned int mysqlnd_get_client_version(); /*****************************************************************************************************/ -PHPAPI void mysqlnd_efree_param_bind_dtor(MYSQLND_PARAM_BIND * param_bind); -PHPAPI void mysqlnd_efree_result_bind_dtor(MYSQLND_RESULT_BIND * result_bind); +PHPAPI void mysqlnd_efree_param_bind_dtor(MYSQLND_PARAM_BIND * param_bind TSRMLS_DC); +PHPAPI void mysqlnd_efree_result_bind_dtor(MYSQLND_RESULT_BIND * result_bind TSRMLS_DC); PHPAPI const char * mysqlnd_field_type_name(enum mysqlnd_field_types field_type); @@ -252,7 +250,7 @@ PHPAPI void mysqlnd_set_local_infile_handler(MYSQLND * const conn, const char * #define mysqlnd_select_db(conn, db, db_len) (conn)->m->select_db((conn), (db), (db_len) TSRMLS_CC) #define mysqlnd_ping(conn) (conn)->m->ping((conn) TSRMLS_CC) #define mysqlnd_kill(conn, pid) (conn)->m->kill_connection((conn), (pid) TSRMLS_CC) -#define mysqlnd_refresh(conn, options) (conn)->m->refresh_server((conn), (options) TSRMLS_CC) +#define mysqlnd_refresh(conn, options) (conn)->m->refresh_server((conn), (options) TSRMLS_CC) #define mysqlnd_shutdown(conn, level) (conn)->m->shutdown_server((conn), (level) TSRMLS_CC) #define mysqlnd_get_server_version(conn) (conn)->m->get_server_version((conn)) #define mysqlnd_set_character_set(conn, cs) (conn)->m->set_charset((conn), (cs) TSRMLS_CC) @@ -376,6 +374,7 @@ ZEND_BEGIN_MODULE_GLOBALS(mysqlnd) #ifdef MYSQLND_THREADED THREAD_T thread_id; #endif + long net_read_timeout; ZEND_END_MODULE_GLOBALS(mysqlnd) ZEND_EXTERN_MODULE_GLOBALS(mysqlnd); diff --git a/ext/mysqlnd/mysqlnd_alloc.c b/ext/mysqlnd/mysqlnd_alloc.c index dd72919e3..e54f80c69 100644 --- a/ext/mysqlnd/mysqlnd_alloc.c +++ b/ext/mysqlnd/mysqlnd_alloc.c @@ -19,7 +19,7 @@ */ -/* $Id: mysqlnd_alloc.c,v 1.1.2.4 2008/12/31 11:15:39 sebastian Exp $ */ +/* $Id: mysqlnd_alloc.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_priv.h" diff --git a/ext/mysqlnd/mysqlnd_block_alloc.c b/ext/mysqlnd/mysqlnd_block_alloc.c index 1ba10310d..cf7be9fd0 100644 --- a/ext/mysqlnd/mysqlnd_block_alloc.c +++ b/ext/mysqlnd/mysqlnd_block_alloc.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_block_alloc.c,v 1.1.2.9 2009/06/25 19:03:51 johannes Exp $ */ +/* $Id: mysqlnd_block_alloc.c 282779 2009-06-25 19:03:52Z johannes $ */ #include "php.h" #include "mysqlnd.h" diff --git a/ext/mysqlnd/mysqlnd_block_alloc.h b/ext/mysqlnd/mysqlnd_block_alloc.h index aaf08800f..56576214e 100644 --- a/ext/mysqlnd/mysqlnd_block_alloc.h +++ b/ext/mysqlnd/mysqlnd_block_alloc.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_block_alloc.h,v 1.1.2.4 2009/06/25 19:03:51 johannes Exp $ */ +/* $Id: mysqlnd_block_alloc.h 282779 2009-06-25 19:03:52Z johannes $ */ #ifndef MYSQLND_BLOCK_ALLOC_H #define MYSQLND_BLOCK_ALLOC_H diff --git a/ext/mysqlnd/mysqlnd_debug.c b/ext/mysqlnd/mysqlnd_debug.c index f2bbd89fa..3537c1373 100644 --- a/ext/mysqlnd/mysqlnd_debug.c +++ b/ext/mysqlnd/mysqlnd_debug.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_debug.c,v 1.1.2.18 2009/06/25 19:03:51 johannes Exp $ */ +/* $Id: mysqlnd_debug.c 282779 2009-06-25 19:03:52Z johannes $ */ #include "php.h" #include "mysqlnd.h" diff --git a/ext/mysqlnd/mysqlnd_debug.h b/ext/mysqlnd/mysqlnd_debug.h index f30050901..13eeb24cd 100644 --- a/ext/mysqlnd/mysqlnd_debug.h +++ b/ext/mysqlnd/mysqlnd_debug.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_debug.h,v 1.1.2.12 2009/03/30 13:55:47 johannes Exp $ */ +/* $Id: mysqlnd_debug.h 278018 2009-03-30 13:55:47Z johannes $ */ #ifndef MYSQLND_DEBUG_H #define MYSQLND_DEBUG_H diff --git a/ext/mysqlnd/mysqlnd_enum_n_def.h b/ext/mysqlnd/mysqlnd_enum_n_def.h index 78f9202df..554dab8cc 100644 --- a/ext/mysqlnd/mysqlnd_enum_n_def.h +++ b/ext/mysqlnd/mysqlnd_enum_n_def.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_enum_n_def.h,v 1.2.2.15 2009/06/25 19:03:51 johannes Exp $ */ +/* $Id: mysqlnd_enum_n_def.h 289630 2009-10-14 13:51:25Z johannes $ */ #ifndef MYSQLND_ENUM_N_DEF_H #define MYSQLND_ENUM_N_DEF_H @@ -28,6 +28,10 @@ #define MYSQLND_SQLSTATE_LENGTH 5 #define MYSQLND_SQLSTATE_NULL "00000" + +#define MYSQLND_NET_CMD_BUFFER_MIN_SIZE 4096 +#define MYSQLND_NET_CMD_BUFFER_MIN_SIZE_STR "4096" + #define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */ #define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */ #define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */ @@ -73,6 +77,7 @@ #define CLIENT_SECURE_CONNECTION 32768 /* New 4.1 authentication */ #define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */ #define CLIENT_MULTI_RESULTS (1UL << 17) /* Enable/disable multi-results */ +#define CLIENT_PS_MULTI_RESULTS (1UL << 18) /* Multi-results in PS-protocol */ typedef enum mysqlnd_extension { @@ -425,6 +430,8 @@ typedef enum mysqlnd_collected_stats STAT_BINARY_TYPE_FETCHED_SET, STAT_BINARY_TYPE_FETCHED_GEOMETRY, STAT_BINARY_TYPE_FETCHED_OTHER, + STAT_INIT_COMMAND_EXECUTED_COUNT, + STAT_INIT_COMMAND_FAILED_COUNT, STAT_LAST /* Should be always the last */ } enum_mysqlnd_collected_stats; diff --git a/ext/mysqlnd/mysqlnd_palloc.c b/ext/mysqlnd/mysqlnd_palloc.c index 2bd0804b3..6146e6f00 100644 --- a/ext/mysqlnd/mysqlnd_palloc.c +++ b/ext/mysqlnd/mysqlnd_palloc.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_palloc.c,v 1.2.2.20 2009/06/25 19:03:51 johannes Exp $ */ +/* $Id: mysqlnd_palloc.c 289630 2009-10-14 13:51:25Z johannes $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_priv.h" @@ -42,7 +42,7 @@ char * mysqlnd_palloc_get_zval_name = "mysqlnd_palloc_get_zval"; /* {{{ _mysqlnd_palloc_init_cache */ PHPAPI MYSQLND_ZVAL_PCACHE* _mysqlnd_palloc_init_cache(unsigned int cache_size TSRMLS_DC) { - MYSQLND_ZVAL_PCACHE *ret = calloc(1, sizeof(MYSQLND_ZVAL_PCACHE)); + MYSQLND_ZVAL_PCACHE *ret = mnd_calloc(1, sizeof(MYSQLND_ZVAL_PCACHE)); unsigned int i; DBG_ENTER("_mysqlnd_palloc_init_cache"); @@ -58,13 +58,13 @@ PHPAPI MYSQLND_ZVAL_PCACHE* _mysqlnd_palloc_init_cache(unsigned int cache_size T /* 1. First initialize the free list part of the structure */ /* One more for empty position of last_added - always 0x0, bounds checking */ - ret->free_list.ptr_line = calloc(ret->max_items + 1, sizeof(mysqlnd_zval *)); + ret->free_list.ptr_line = mnd_calloc(ret->max_items + 1, sizeof(mysqlnd_zval *)); ret->free_list.last_added = ret->free_list.ptr_line + ret->max_items; ret->free_list.canary1 = (void*)0xBEEF; ret->free_list.canary2 = (void*)0xAFFE; /* 3. Allocate and initialize our zvals and initialize the free list */ - ret->block = calloc(ret->max_items, sizeof(mysqlnd_zval)); + ret->block = mnd_calloc(ret->max_items, sizeof(mysqlnd_zval)); ret->last_in_block = &(ret->block[ret->max_items]); for (i = 0; i < ret->max_items; i++) { /* 1. Initialize */ @@ -124,7 +124,7 @@ void _mysqlnd_palloc_free_cache(MYSQLND_ZVAL_PCACHE *cache TSRMLS_DC) /* {{{ _mysqlnd_palloc_init_thd_cache */ PHPAPI MYSQLND_THD_ZVAL_PCACHE* _mysqlnd_palloc_init_thd_cache(MYSQLND_ZVAL_PCACHE * const cache TSRMLS_DC) { - MYSQLND_THD_ZVAL_PCACHE *ret = calloc(1, sizeof(MYSQLND_THD_ZVAL_PCACHE)); + MYSQLND_THD_ZVAL_PCACHE *ret = mnd_calloc(1, sizeof(MYSQLND_THD_ZVAL_PCACHE)); DBG_ENTER("_mysqlnd_palloc_init_thd_cache"); DBG_INF_FMT("ret = %p", ret); @@ -146,7 +146,7 @@ PHPAPI MYSQLND_THD_ZVAL_PCACHE* _mysqlnd_palloc_init_thd_cache(MYSQLND_ZVAL_PCAC ret->references = 1; /* 1. Initialize the GC list */ - ret->gc_list.ptr_line = calloc(cache->max_items, sizeof(mysqlnd_zval *)); + ret->gc_list.ptr_line = mnd_calloc(cache->max_items, sizeof(mysqlnd_zval *)); /* Backward and forward looping is possible */ ret->gc_list.last_added = ret->gc_list.ptr_line; ret->gc_list.canary1 = (void*)0xCAFE; diff --git a/ext/mysqlnd/mysqlnd_palloc.h b/ext/mysqlnd/mysqlnd_palloc.h index d961154fa..b67c01d41 100644 --- a/ext/mysqlnd/mysqlnd_palloc.h +++ b/ext/mysqlnd/mysqlnd_palloc.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_palloc.h,v 1.2.2.7 2008/12/31 11:15:39 sebastian Exp $ */ +/* $Id: mysqlnd_palloc.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef MYSQLND_PALLOC_H #define MYSQLND_PALLOC_H diff --git a/ext/mysqlnd/mysqlnd_portability.h b/ext/mysqlnd/mysqlnd_portability.h index 9dba7fa51..43cb50586 100644 --- a/ext/mysqlnd/mysqlnd_portability.h +++ b/ext/mysqlnd/mysqlnd_portability.h @@ -9,6 +9,9 @@ This file is public domain and comes with NO WARRANTY of any kind */ were added to improve the header file, to get it more consistent. */ +#ifndef MYSQLND_PORTABILITY_H +#define MYSQLND_PORTABILITY_H + /* Comes from global.h as OFFSET, renamed to STRUCT_OFFSET */ #define STRUCT_OFFSET(t, f) ((size_t)(char *)&((t *)0)->f) @@ -30,9 +33,9 @@ This file is public domain and comes with NO WARRANTY of any kind */ #endif /* __CYGWIN__ */ #if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32) -# include +# include "ext/mysqlnd/config-win.h" #else -# include "ext/mysqlnd/php_mysqlnd_config.h" +# include #endif /* _WIN32... */ #ifdef HAVE_SYS_TYPES_H @@ -174,11 +177,16 @@ typedef unsigned long long uint64_t; #define MYSQLND_LLU_SPEC "%lu" #endif -#if __powerpc64__ +#if __powerpc64__ || __ppc64__ #define MYSQLND_LL_SPEC "%li" #define MYSQLND_LLU_SPEC "%lu" #endif +#if (__powerpc__ || __ppc__ ) && !(__powerpc64__ || __ppc64__) +#define MYSQLND_LL_SPEC "%lli" +#define MYSQLND_LLU_SPEC "%llu" +#endif + #if __x86_64__ #define MYSQLND_LL_SPEC "%li" #define MYSQLND_LLU_SPEC "%lu" @@ -189,11 +197,6 @@ typedef unsigned long long uint64_t; #define MYSQLND_LLU_SPEC "%lu" #endif -#if __powerpc__ && !__powerpc64__ -#define MYSQLND_LL_SPEC "%lli" -#define MYSQLND_LLU_SPEC "%llu" -#endif - #if __s390__ && !__s390x__ #define MYSQLND_LL_SPEC "%lli" #define MYSQLND_LLU_SPEC "%llu" @@ -204,6 +207,23 @@ typedef unsigned long long uint64_t; #define MYSQLND_LLU_SPEC "%llu" #endif +#ifndef MYSQLND_LL_SPEC + #if SIZEOF_LONG == 8 + #define MYSQLND_LL_SPEC "%li" + #elif SIZEOF_LONG == 4 + #define MYSQLND_LL_SPEC "%lli" + #endif +#endif + +#ifndef MYSQLND_LLU_SPEC + #if SIZEOF_LONG == 8 + #define MYSQLND_LLU_SPEC "%lu" + #elif SIZEOF_LONG == 4 + #define MYSQLND_LLU_SPEC "%llu" + #endif +#endif /* MYSQLND_LLU_SPEC*/ + + #define MYSQLND_SZ_T_SPEC "%zd" #ifndef L64 #define L64(x) x##LL @@ -480,6 +500,7 @@ typedef union { #endif /* WORDS_BIGENDIAN */ +#endif /* MYSQLND_PORTABILITY_H */ /* diff --git a/ext/mysqlnd/mysqlnd_priv.h b/ext/mysqlnd/mysqlnd_priv.h index 3ecd83c6a..b15e91579 100644 --- a/ext/mysqlnd/mysqlnd_priv.h +++ b/ext/mysqlnd/mysqlnd_priv.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_priv.h,v 1.4.2.17 2009/02/16 17:26:43 johannes Exp $ */ +/* $Id: mysqlnd_priv.h 289630 2009-10-14 13:51:25Z johannes $ */ #ifndef MYSQLND_PRIV_H #define MYSQLND_PRIV_H @@ -104,10 +104,12 @@ if ((buf)) { \ pefree((buf), (persistent)); \ } \ - (buf) = (message); \ + if ((message)) { \ + (buf) = pestrndup((message), (len), (persistent)); \ + } else { \ + buf = NULL; \ + } \ (buf_len) = (len); \ - /* Transfer ownership*/ \ - (message) = NULL; \ } #define SET_EMPTY_MESSAGE(buf, buf_len, persistent) \ diff --git a/ext/mysqlnd/mysqlnd_ps.c b/ext/mysqlnd/mysqlnd_ps.c index 0f1a77e12..68f0a828d 100644 --- a/ext/mysqlnd/mysqlnd_ps.c +++ b/ext/mysqlnd/mysqlnd_ps.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_ps.c,v 1.3.2.30 2009/06/25 19:03:51 johannes Exp $ */ +/* $Id: mysqlnd_ps.c 289630 2009-10-14 13:51:25Z johannes $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_wireprotocol.h" @@ -1329,7 +1329,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_parameters)(MYSQLND_STMT * const stmt, SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared); DBG_ERR("not prepared"); if (param_bind && stmt->param_bind_dtor) { - stmt->param_bind_dtor(param_bind); + stmt->param_bind_dtor(param_bind TSRMLS_CC); } DBG_RETURN(FAIL); } @@ -1362,7 +1362,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_parameters)(MYSQLND_STMT * const stmt, } } if (stmt->param_bind != param_bind && stmt->param_bind_dtor) { - stmt->param_bind_dtor(stmt->param_bind); + stmt->param_bind_dtor(stmt->param_bind TSRMLS_CC); } } @@ -1411,7 +1411,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_parameter)(MYSQLND_STMT * const stmt, unsi if (stmt->param_count) { if (!stmt->param_bind) { - stmt->param_bind = ecalloc(stmt->param_count, sizeof(MYSQLND_PARAM_BIND)); + stmt->param_bind = mnd_ecalloc(stmt->param_count, sizeof(MYSQLND_PARAM_BIND)); } /* Prevent from freeing */ @@ -1465,7 +1465,7 @@ MYSQLND_METHOD(mysqlnd_stmt, refresh_bind_param)(MYSQLND_STMT * const stmt TSRML /* {{{ mysqlnd_stmt::set_bind_param_dtor */ static void MYSQLND_METHOD(mysqlnd_stmt, set_param_bind_dtor)(MYSQLND_STMT * const stmt, - void (*param_bind_dtor)(MYSQLND_PARAM_BIND *dtor) TSRMLS_DC) + void (*param_bind_dtor)(MYSQLND_PARAM_BIND * dtor TSRMLS_DC) TSRMLS_DC) { DBG_ENTER("mysqlnd_stmt::set_bind_param_dtor"); DBG_INF_FMT("stmt=%p", param_bind_dtor); @@ -1487,7 +1487,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const stmt, if (stmt->state < MYSQLND_STMT_PREPARED) { SET_STMT_ERROR(stmt, CR_NO_PREPARE_STMT, UNKNOWN_SQLSTATE, mysqlnd_stmt_not_prepared); if (result_bind && stmt->result_bind_dtor) { - stmt->result_bind_dtor(result_bind); + stmt->result_bind_dtor(result_bind TSRMLS_CC); } DBG_ERR("not prepared"); DBG_RETURN(FAIL); @@ -1519,7 +1519,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_result)(MYSQLND_STMT * const stmt, stmt->result_bind[i].bound = TRUE; } } else if (result_bind && stmt->result_bind_dtor) { - stmt->result_bind_dtor(result_bind); + stmt->result_bind_dtor(result_bind TSRMLS_CC); } DBG_INF("PASS"); DBG_RETURN(PASS); @@ -1553,9 +1553,9 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_result)(MYSQLND_STMT * const stmt, unsigne mysqlnd_stmt_separate_one_result_bind(stmt, param_no TSRMLS_CC); /* Guaranteed is that stmt->result_bind is NULL */ if (!stmt->result_bind) { - stmt->result_bind = ecalloc(stmt->field_count, sizeof(MYSQLND_RESULT_BIND)); + stmt->result_bind = mnd_ecalloc(stmt->field_count, sizeof(MYSQLND_RESULT_BIND)); } else { - stmt->result_bind = erealloc(stmt->result_bind, stmt->field_count * sizeof(MYSQLND_RESULT_BIND)); + stmt->result_bind = mnd_erealloc(stmt->result_bind, stmt->field_count * sizeof(MYSQLND_RESULT_BIND)); } ALLOC_INIT_ZVAL(stmt->result_bind[param_no].zv); /* @@ -1574,7 +1574,7 @@ MYSQLND_METHOD(mysqlnd_stmt, bind_one_result)(MYSQLND_STMT * const stmt, unsigne /* {{{ mysqlnd_stmt::set_bind_result_dtor */ static void MYSQLND_METHOD(mysqlnd_stmt, set_result_bind_dtor)(MYSQLND_STMT * const stmt, - void (*result_bind_dtor)(MYSQLND_RESULT_BIND *dtor) TSRMLS_DC) + void (*result_bind_dtor)(MYSQLND_RESULT_BIND * dtor TSRMLS_DC) TSRMLS_DC) { DBG_ENTER("mysqlnd_stmt::set_bind_param_dtor"); DBG_INF_FMT("stmt=%p", result_bind_dtor); @@ -1898,7 +1898,7 @@ void mysqlnd_stmt_separate_result_bind(MYSQLND_STMT * const stmt TSRMLS_DC) } } if (stmt->result_bind_dtor) { - stmt->result_bind_dtor(stmt->result_bind); + stmt->result_bind_dtor(stmt->result_bind TSRMLS_CC); } stmt->result_bind = NULL; @@ -1979,7 +1979,7 @@ void mysqlnd_internal_free_stmt_content(MYSQLND_STMT * const stmt TSRMLS_DC) } } if (stmt->param_bind_dtor) { - stmt->param_bind_dtor(stmt->param_bind); + stmt->param_bind_dtor(stmt->param_bind TSRMLS_CC); } stmt->param_bind = NULL; } @@ -2177,18 +2177,18 @@ MYSQLND_STMT * _mysqlnd_stmt_init(MYSQLND * const conn TSRMLS_DC) /* {{{ mysqlnd_efree_param_bind_dtor */ PHPAPI void -mysqlnd_efree_param_bind_dtor(MYSQLND_PARAM_BIND * param_bind) +mysqlnd_efree_param_bind_dtor(MYSQLND_PARAM_BIND * param_bind TSRMLS_DC) { - efree(param_bind); + mnd_efree(param_bind); } /* }}} */ /* {{{ mysqlnd_efree_result_bind_dtor */ PHPAPI void -mysqlnd_efree_result_bind_dtor(MYSQLND_RESULT_BIND * result_bind) +mysqlnd_efree_result_bind_dtor(MYSQLND_RESULT_BIND * result_bind TSRMLS_DC) { - efree(result_bind); + mnd_efree(result_bind); } /* }}} */ diff --git a/ext/mysqlnd/mysqlnd_ps_codec.c b/ext/mysqlnd/mysqlnd_ps_codec.c index 3326f0577..65be19297 100644 --- a/ext/mysqlnd/mysqlnd_ps_codec.c +++ b/ext/mysqlnd/mysqlnd_ps_codec.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_ps_codec.c,v 1.3.2.16 2009/05/28 16:35:41 andrey Exp $ */ +/* $Id: mysqlnd_ps_codec.c 289630 2009-10-14 13:51:25Z johannes $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_wireprotocol.h" @@ -580,10 +580,10 @@ void _mysqlnd_init_ps_fetch_subsystem() /* {{{ mysqlnd_stmt_copy_it */ static void -mysqlnd_stmt_copy_it(zval *** copies, zval *original, unsigned int param_count, unsigned int current) +mysqlnd_stmt_copy_it(zval *** copies, zval *original, unsigned int param_count, unsigned int current TSRMLS_DC) { if (!*copies) { - *copies = ecalloc(param_count, sizeof(zval *)); + *copies = mnd_ecalloc(param_count, sizeof(zval *)); } MAKE_STD_ZVAL((*copies)[current]); *(*copies)[current] = *original; @@ -643,7 +643,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch for (j = i + 1; j < stmt->param_count; j++) { if (stmt->param_bind[j].zv == the_var) { /* Double binding of the same zval, make a copy */ - mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i); + mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC); break; } } @@ -653,7 +653,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch data_size += 8; if (Z_TYPE_P(the_var) != IS_DOUBLE) { if (!copies || !copies[i]) { - mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i); + mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC); } } break; @@ -668,7 +668,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch #endif if (Z_TYPE_P(the_var) != IS_LONG) { if (!copies || !copies[i]) { - mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i); + mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC); } } break; @@ -691,7 +691,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch #endif { if (!copies || !copies[i]) { - mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i); + mysqlnd_stmt_copy_it(&copies, the_var, stmt->param_count, i TSRMLS_CC); } the_var = copies[i]; #if PHP_MAJOR_VERSION >= 6 @@ -777,7 +777,7 @@ mysqlnd_stmt_execute_store_params(MYSQLND_STMT *stmt, zend_uchar **buf, zend_uch zval_ptr_dtor(&copies[i]); } } - efree(copies); + mnd_efree(copies); } } /* }}} */ diff --git a/ext/mysqlnd/mysqlnd_qcache.c b/ext/mysqlnd/mysqlnd_qcache.c index 98b8d2e8f..467ad0918 100644 --- a/ext/mysqlnd/mysqlnd_qcache.c +++ b/ext/mysqlnd/mysqlnd_qcache.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_qcache.c,v 1.2.2.5 2008/12/31 11:15:39 sebastian Exp $ */ +/* $Id: mysqlnd_qcache.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_priv.h" diff --git a/ext/mysqlnd/mysqlnd_result.c b/ext/mysqlnd/mysqlnd_result.c index 8b9574bc8..e724820a1 100644 --- a/ext/mysqlnd/mysqlnd_result.c +++ b/ext/mysqlnd/mysqlnd_result.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_result.c,v 1.4.2.34 2009/06/25 19:03:51 johannes Exp $ */ +/* $Id: mysqlnd_result.c 289630 2009-10-14 13:51:25Z johannes $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_wireprotocol.h" @@ -171,7 +171,7 @@ void mysqlnd_unbuffered_free_last_data(MYSQLND_RES *result TSRMLS_DC) STAT_COPY_ON_WRITE_PERFORMED, 0); /* Free last row's zvals */ - efree(unbuf->last_row_data); + mnd_efree(unbuf->last_row_data); unbuf->last_row_data = NULL; } if (unbuf->last_row_buffer) { @@ -223,11 +223,11 @@ void mysqlnd_free_buffered_data(MYSQLND_RES *result TSRMLS_DC) } DBG_INF("Freeing data & row_buffer"); if (set->data) { - pefree(set->data, set->persistent); + mnd_pefree(set->data, set->persistent); set->data = NULL; } if (set->row_buffers) { - pefree(set->row_buffers, set->persistent); + mnd_pefree(set->row_buffers, set->persistent); set->row_buffers = NULL; } set->data_cursor = NULL; @@ -237,7 +237,7 @@ void mysqlnd_free_buffered_data(MYSQLND_RES *result TSRMLS_DC) } DBG_INF("Freeing set"); - pefree(set, set->persistent); + mnd_pefree(set, set->persistent); DBG_INF_FMT("after: real_usage=%lu usage=%lu", zend_memory_usage(TRUE TSRMLS_CC), zend_memory_usage(FALSE TSRMLS_CC)); DBG_VOID_RETURN; @@ -295,13 +295,13 @@ void mysqlnd_free_background_buffered_data(MYSQLND_RES *result TSRMLS_DC) #if MYSQLND_DEBUG_MEMORY DBG_INF("Freeing current_row & current_buffer"); #endif - pefree(current_row, set->persistent); + mnd_pefree(current_row, set->persistent); } current_buffer->free_chunk(current_buffer, TRUE TSRMLS_CC); } DBG_INF("Freeing data & row_buffer"); - pefree(set->data, set->persistent); - pefree(set->row_buffers, set->persistent); + mnd_pefree(set->data, set->persistent); + mnd_pefree(set->row_buffers, set->persistent); set->data = NULL; set->row_buffers = NULL; set->data_cursor = NULL; @@ -315,7 +315,7 @@ void mysqlnd_free_background_buffered_data(MYSQLND_RES *result TSRMLS_DC) } DBG_INF("Freeing set"); - pefree(set, set->persistent); + mnd_pefree(set, set->persistent); DBG_INF_FMT("after: real_usage=%lu usage=%lu", zend_memory_usage(TRUE TSRMLS_CC), zend_memory_usage(FALSE TSRMLS_CC)); DBG_VOID_RETURN; @@ -333,7 +333,7 @@ MYSQLND_METHOD(mysqlnd_res, free_result_buffers)(MYSQLND_RES *result TSRMLS_DC) if (result->unbuf) { mysqlnd_unbuffered_free_last_data(result TSRMLS_CC); - efree(result->unbuf); + mnd_efree(result->unbuf); result->unbuf = NULL; } else if (result->stored_data) { mysqlnd_free_buffered_data(result TSRMLS_CC); @@ -347,7 +347,7 @@ MYSQLND_METHOD(mysqlnd_res, free_result_buffers)(MYSQLND_RES *result TSRMLS_DC) #endif if (result->lengths) { - efree(result->lengths); + mnd_efree(result->lengths); result->lengths = NULL; } @@ -398,7 +398,7 @@ void mysqlnd_internal_free_result(MYSQLND_RES *result TSRMLS_DC) result->conn = NULL; } - efree(result); + mnd_efree(result); DBG_VOID_RETURN; } @@ -431,6 +431,8 @@ MYSQLND_METHOD(mysqlnd_res, read_result_metadata)(MYSQLND_RES *result, MYSQLND * result->m.free_result_contents(result TSRMLS_CC); DBG_RETURN(FAIL); } + /* COM_FIELD_LIST is broken and has premature EOF, thus we need to hack here and in mysqlnd_res_meta.c */ + result->field_count = result->meta->field_count; /* 2. Follows an EOF packet, which the client of mysqlnd_read_result_metadata() @@ -573,7 +575,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC if (FAIL == (ret = result->m.read_result_metadata(result, conn TSRMLS_CC))) { /* For PS, we leave them in Prepared state */ if (!stmt) { - efree(conn->current_result); + mnd_efree(conn->current_result); conn->current_result = NULL; } DBG_ERR("Error ocurred while reading metadata"); @@ -585,7 +587,7 @@ mysqlnd_query_read_result_set_header(MYSQLND *conn, MYSQLND_STMT *stmt TSRMLS_DC if (FAIL == (ret = PACKET_READ_ALLOCA(fields_eof, conn))) { DBG_ERR("Error ocurred while reading the EOF packet"); result->m.free_result_contents(result TSRMLS_CC); - efree(result); + mnd_efree(result); if (!stmt) { conn->current_result = NULL; } else { @@ -899,13 +901,8 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int flag lengths[i] = len; } - /* Forbid ZE to free it, we will clean it */ - Z_ADDREF_P(data); - - if ((flags & MYSQLND_FETCH_BOTH) == MYSQLND_FETCH_BOTH) { - Z_ADDREF_P(data); - } if (flags & MYSQLND_FETCH_NUM) { + Z_ADDREF_P(data); zend_hash_next_index_insert(row_ht, &data, sizeof(zval *), NULL); } if (flags & MYSQLND_FETCH_ASSOC) { @@ -916,6 +913,7 @@ mysqlnd_fetch_row_unbuffered(MYSQLND_RES *result, void *param, unsigned int flag the index is a numeric and convert it to it. This however means constant hashing of the column name, which is not needed as it can be precomputed. */ + Z_ADDREF_P(data); if (zend_hash_key->is_numeric == FALSE) { #if PHP_MAJOR_VERSION >= 6 zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE, @@ -1126,16 +1124,8 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int flags, for (i = 0; i < result->field_count; i++, field++, zend_hash_key++) { zval *data = current_row[i]; - /* - Let us later know what to do with this zval. If ref_count > 1, we will just - decrease it, otherwise free it. zval_ptr_dtor() make this very easy job. - */ - Z_ADDREF_P(data); - - if ((flags & MYSQLND_FETCH_BOTH) == MYSQLND_FETCH_BOTH) { - Z_ADDREF_P(data); - } if (flags & MYSQLND_FETCH_NUM) { + Z_ADDREF_P(data); zend_hash_next_index_insert(Z_ARRVAL_P(row), &data, sizeof(zval *), NULL); } if (flags & MYSQLND_FETCH_ASSOC) { @@ -1146,6 +1136,7 @@ mysqlnd_fetch_row_buffered(MYSQLND_RES *result, void *param, unsigned int flags, the index is a numeric and convert it to it. This however means constant hashing of the column name, which is not needed as it can be precomputed. */ + Z_ADDREF_P(data); if (zend_hash_key->is_numeric == FALSE) { #if PHP_MAJOR_VERSION >= 6 zend_u_hash_quick_update(Z_ARRVAL_P(row), IS_UNICODE, @@ -1891,9 +1882,9 @@ MYSQLND_METHOD(mysqlnd_res, fetch_row_c)(MYSQLND_RES *result TSRMLS_DC) if (result->m.fetch_row) { if (result->m.fetch_row == result->m.fetch_row_normal_buffered) { - return mysqlnd_fetch_row_buffered_c(result TSRMLS_CC); + DBG_RETURN(mysqlnd_fetch_row_buffered_c(result TSRMLS_CC)); } else if (result->m.fetch_row == result->m.fetch_row_normal_unbuffered) { - return mysqlnd_fetch_row_unbuffered_c(result TSRMLS_CC); + DBG_RETURN(mysqlnd_fetch_row_unbuffered_c(result TSRMLS_CC)); } else { *((int*)NULL) = 1; } diff --git a/ext/mysqlnd/mysqlnd_result.h b/ext/mysqlnd/mysqlnd_result.h index e4d6968b1..1f7a249d2 100644 --- a/ext/mysqlnd/mysqlnd_result.h +++ b/ext/mysqlnd/mysqlnd_result.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_result.h,v 1.2.2.8 2008/12/31 11:15:39 sebastian Exp $ */ +/* $Id: mysqlnd_result.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef MYSQLND_RESULT_H #define MYSQLND_RESULT_H diff --git a/ext/mysqlnd/mysqlnd_result_meta.c b/ext/mysqlnd/mysqlnd_result_meta.c index 8738ef4b0..8a8787f88 100644 --- a/ext/mysqlnd/mysqlnd_result_meta.c +++ b/ext/mysqlnd/mysqlnd_result_meta.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_result_meta.c,v 1.3.2.9 2009/05/28 17:47:38 andrey Exp $ */ +/* $Id: mysqlnd_result_meta.c 289630 2009-10-14 13:51:25Z johannes $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_priv.h" @@ -165,7 +165,15 @@ MYSQLND_METHOD(mysqlnd_res_meta, read_metadata)(MYSQLND_RES_METADATA * const met PACKET_FREE_ALLOCA(field_packet); DBG_RETURN(FAIL); } + if (field_packet.error_info.error_no) { + conn->error_info = field_packet.error_info; + /* Return back from CONN_QUERY_SENT */ + PACKET_FREE_ALLOCA(field_packet); + DBG_RETURN(FAIL); + } + if (field_packet.stupid_list_fields_eof == TRUE) { + meta->field_count = i; break; } diff --git a/ext/mysqlnd/mysqlnd_result_meta.h b/ext/mysqlnd/mysqlnd_result_meta.h index 33c70f2f3..d4da9671e 100644 --- a/ext/mysqlnd/mysqlnd_result_meta.h +++ b/ext/mysqlnd/mysqlnd_result_meta.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_result_meta.h,v 1.2.2.6 2008/12/31 11:15:39 sebastian Exp $ */ +/* $Id: mysqlnd_result_meta.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef MYSQLND_RESULT_META_H #define MYSQLND_RESULT_META_H diff --git a/ext/mysqlnd/mysqlnd_statistics.c b/ext/mysqlnd/mysqlnd_statistics.c index cec5c0d2c..612614165 100644 --- a/ext/mysqlnd/mysqlnd_statistics.c +++ b/ext/mysqlnd/mysqlnd_statistics.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_statistics.c,v 1.2.2.12 2009/06/25 19:03:51 johannes Exp $ */ +/* $Id: mysqlnd_statistics.c 287807 2009-08-27 13:16:39Z andrey $ */ #include "php.h" #include "mysqlnd.h" #include "mysqlnd_priv.h" @@ -151,7 +151,9 @@ const MYSQLND_STRING mysqlnd_stats_values_names[STAT_LAST] = { STR_W_LEN("proto_binary_fetched_enum") }, { STR_W_LEN("proto_binary_fetched_set") }, { STR_W_LEN("proto_binary_fetched_geometry") }, - { STR_W_LEN("proto_binary_fetched_other") } + { STR_W_LEN("proto_binary_fetched_other") }, + { STR_W_LEN("init_command_executed_count") }, + { STR_W_LEN("init_command_failed_count") } }; /* }}} */ diff --git a/ext/mysqlnd/mysqlnd_statistics.h b/ext/mysqlnd/mysqlnd_statistics.h index 907878b78..184d0e389 100644 --- a/ext/mysqlnd/mysqlnd_statistics.h +++ b/ext/mysqlnd/mysqlnd_statistics.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_statistics.h,v 1.4.2.14 2009/06/12 13:24:57 andrey Exp $ */ +/* $Id: mysqlnd_statistics.h 282029 2009-06-12 13:24:57Z andrey $ */ #ifndef MYSQLND_STATISTICS_H #define MYSQLND_STATISTICS_H diff --git a/ext/mysqlnd/mysqlnd_structs.h b/ext/mysqlnd/mysqlnd_structs.h index e0fa450be..ad61d9c6e 100644 --- a/ext/mysqlnd/mysqlnd_structs.h +++ b/ext/mysqlnd/mysqlnd_structs.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_structs.h,v 1.2.2.21 2009/06/25 19:03:51 johannes Exp $ */ +/* $Id: mysqlnd_structs.h 289630 2009-10-14 13:51:25Z johannes $ */ #ifndef MYSQLND_STRUCTS_H #define MYSQLND_STRUCTS_H @@ -281,6 +281,7 @@ struct st_mysqlnd_conn_methods enum_func_status (*set_server_option)(MYSQLND * const conn, enum_mysqlnd_server_option option TSRMLS_DC); enum_func_status (*set_client_option)(MYSQLND * const conn, enum_mysqlnd_option option, const char * const value TSRMLS_DC); void (*free_contents)(MYSQLND *conn TSRMLS_DC); /* private */ + void (*free_options)(MYSQLND * conn TSRMLS_DC); /* private */ enum_func_status (*close)(MYSQLND *conn, enum_connection_close_type close_type TSRMLS_DC); void (*dtor)(MYSQLND *conn TSRMLS_DC); /* private */ @@ -359,10 +360,10 @@ struct st_mysqlnd_stmt_methods enum_func_status (*bind_parameters)(MYSQLND_STMT * const stmt, MYSQLND_PARAM_BIND * const param_bind TSRMLS_DC); enum_func_status (*bind_one_parameter)(MYSQLND_STMT * const stmt, unsigned int param_no, zval * const zv, zend_uchar type TSRMLS_DC); enum_func_status (*refresh_bind_param)(MYSQLND_STMT * const stmt TSRMLS_DC); - void (*set_param_bind_dtor)(MYSQLND_STMT * const stmt, void (*param_bind_dtor)(MYSQLND_PARAM_BIND *) TSRMLS_DC); + void (*set_param_bind_dtor)(MYSQLND_STMT * const stmt, void (*param_bind_dtor)(MYSQLND_PARAM_BIND * TSRMLS_DC) TSRMLS_DC); enum_func_status (*bind_result)(MYSQLND_STMT * const stmt, MYSQLND_RESULT_BIND * const result_bind TSRMLS_DC); enum_func_status (*bind_one_result)(MYSQLND_STMT * const stmt, unsigned int param_no TSRMLS_DC); - void (*set_result_bind_dtor)(MYSQLND_STMT * const stmt, void (*result_bind_dtor)(MYSQLND_RESULT_BIND *) TSRMLS_DC); + void (*set_result_bind_dtor)(MYSQLND_STMT * const stmt, void (*result_bind_dtor)(MYSQLND_RESULT_BIND * TSRMLS_DC) TSRMLS_DC); enum_func_status (*send_long_data)(MYSQLND_STMT * const stmt, unsigned int param_num, const char * const data, unsigned long length TSRMLS_DC); MYSQLND_RES * (*get_parameter_metadata)(MYSQLND_STMT * const stmt); @@ -624,8 +625,8 @@ struct st_mysqlnd_stmt MYSQLND_CMD_BUFFER execute_cmd_buffer; unsigned int execute_count;/* count how many times the stmt was executed */ - void (*param_bind_dtor)(MYSQLND_PARAM_BIND *); - void (*result_bind_dtor)(MYSQLND_RESULT_BIND *); + void (*param_bind_dtor)(MYSQLND_PARAM_BIND * TSRMLS_DC); + void (*result_bind_dtor)(MYSQLND_RESULT_BIND * TSRMLS_DC); struct st_mysqlnd_stmt_methods *m; }; diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.c b/ext/mysqlnd/mysqlnd_wireprotocol.c index 989cc87ed..cc0697cd0 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.c +++ b/ext/mysqlnd/mysqlnd_wireprotocol.c @@ -813,7 +813,7 @@ php_mysqlnd_ok_read(void *_packet, MYSQLND *conn TSRMLS_DC) /* There is a message */ if (packet->header.size > p - buf && (i = php_mysqlnd_net_field_length(&p))) { - packet->message = pestrndup((char *)p, MIN(i, sizeof(buf) - (p - buf)), conn->persistent); + packet->message = estrndup((char *)p, MIN(i, sizeof(buf) - (p - buf))); packet->message_len = i; } else { packet->message = NULL; @@ -1032,7 +1032,7 @@ php_mysqlnd_rset_header_read(void *_packet, MYSQLND *conn TSRMLS_DC) Thus, the name is size - 1. And we add 1 for a trailing \0. */ len = packet->header.size - 1; - packet->info_or_local_file = mnd_pemalloc(len + 1, conn->persistent); + packet->info_or_local_file = mnd_emalloc(len + 1); memcpy(packet->info_or_local_file, p, len); packet->info_or_local_file[len] = '\0'; packet->info_or_local_file_len = len; @@ -1047,7 +1047,7 @@ php_mysqlnd_rset_header_read(void *_packet, MYSQLND *conn TSRMLS_DC) p+=2; /* Check for additional textual data */ if (packet->header.size > (p - buf) && (len = php_mysqlnd_net_field_length(&p))) { - packet->info_or_local_file = mnd_pemalloc(len + 1, conn->persistent); + packet->info_or_local_file = mnd_emalloc(len + 1); memcpy(packet->info_or_local_file, p, len); packet->info_or_local_file[len] = '\0'; packet->info_or_local_file_len = len; @@ -1126,7 +1126,16 @@ php_mysqlnd_rset_field_read(void *_packet, MYSQLND *conn TSRMLS_DC) if (packet->skip_parsing) { DBG_RETURN(PASS); } - if (*p == 0xFE && packet->header.size < 8) { + if (*p == 0xFF) { + /* Error */ + p++; + php_mysqlnd_read_error_from_line(p, packet->header.size - 1, + packet->error_info.error, sizeof(packet->error_info.error), + &packet->error_info.error_no, packet->error_info.sqlstate + TSRMLS_CC); + DBG_ERR_FMT("Server error : (%d) %s", packet->error_info.error_no, packet->error_info.error); + DBG_RETURN(PASS); + } else if (*p == 0xFE && packet->header.size < 8) { /* Premature EOF. That should be COM_FIELD_LIST */ DBG_INF("Premature EOF. That should be COM_FIELD_LIST"); packet->stupid_list_fields_eof = TRUE; @@ -1364,8 +1373,10 @@ void php_mysqlnd_rowp_read_binary_protocol(MYSQLND_MEMORY_POOL_CHUNK * row_buffe zend_uchar *null_ptr, bit; zval **current_field, **end_field, **start_field; zend_bool as_unicode = conn->options.numeric_and_datetime_as_unicode; +#ifdef USE_ZVAL_CACHE zend_bool allocated; void *obj; +#endif DBG_ENTER("php_mysqlnd_rowp_read_binary_protocol"); @@ -1858,7 +1869,7 @@ php_mysqlnd_stats_read(void *_packet, MYSQLND *conn TSRMLS_DC) PACKET_READ_HEADER_AND_BODY(packet, conn, buf, sizeof(buf), "statistics", PROT_STATS_PACKET); - packet->message = mnd_pemalloc(packet->header.size + 1, conn->persistent); + packet->message = mnd_emalloc(packet->header.size + 1); memcpy(packet->message, buf, packet->header.size); packet->message[packet->header.size] = '\0'; packet->message_len = packet->header.size; diff --git a/ext/mysqlnd/mysqlnd_wireprotocol.h b/ext/mysqlnd/mysqlnd_wireprotocol.h index cbbbc8894..df813fd20 100644 --- a/ext/mysqlnd/mysqlnd_wireprotocol.h +++ b/ext/mysqlnd/mysqlnd_wireprotocol.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysqlnd_wireprotocol.h,v 1.4.2.12 2008/12/31 11:15:39 sebastian Exp $ */ +/* $Id: mysqlnd_wireprotocol.h 289630 2009-10-14 13:51:25Z johannes $ */ #ifndef MYSQLND_WIREPROTOCOL_H #define MYSQLND_WIREPROTOCOL_H @@ -242,6 +242,8 @@ typedef struct st_php_mysql_packet_res_field { /* For table definitions, empty for result sets */ zend_bool skip_parsing; zend_bool stupid_list_fields_eof; + + mysqlnd_error_info error_info; } php_mysql_packet_res_field; diff --git a/ext/mysqlnd/php_mysqlnd.c b/ext/mysqlnd/php_mysqlnd.c index ddec14267..1a5f929fc 100644 --- a/ext/mysqlnd/php_mysqlnd.c +++ b/ext/mysqlnd/php_mysqlnd.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_mysqlnd.c,v 1.1.2.11 2009/06/25 19:03:52 johannes Exp $ */ +/* $Id: php_mysqlnd.c 289630 2009-10-14 13:51:25Z johannes $ */ #include "php.h" #include "php_ini.h" #include "mysqlnd.h" @@ -26,7 +26,6 @@ #include "mysqlnd_debug.h" #include "ext/standard/info.h" - /* {{{ mysqlnd_functions[] * * Every user visible function must have an entry in mysqlnd_functions[]. @@ -107,6 +106,8 @@ PHP_MINFO_FUNCTION(mysqlnd) php_info_print_table_row(2, "Command buffer size", buf); snprintf(buf, sizeof(buf), "%ld", MYSQLND_G(net_read_buffer_size)); php_info_print_table_row(2, "Read buffer size", buf); + snprintf(buf, sizeof(buf), "%ld", MYSQLND_G(net_read_timeout)); + php_info_print_table_row(2, "Read timeout", buf); php_info_print_table_row(2, "Collecting statistics", MYSQLND_G(collect_statistics)? "Yes":"No"); php_info_print_table_row(2, "Collecting memory statistics", MYSQLND_G(collect_memory_statistics)? "Yes":"No"); php_info_print_table_end(); @@ -134,21 +135,34 @@ static PHP_GINIT_FUNCTION(mysqlnd) mysqlnd_globals->collect_memory_statistics = FALSE; mysqlnd_globals->debug = NULL; /* The actual string */ mysqlnd_globals->dbg = NULL; /* The DBG object*/ - mysqlnd_globals->net_cmd_buffer_size = 2048; + mysqlnd_globals->net_cmd_buffer_size = MYSQLND_NET_CMD_BUFFER_MIN_SIZE; mysqlnd_globals->net_read_buffer_size = 32768; + mysqlnd_globals->net_read_timeout = 31536000; mysqlnd_globals->log_mask = 0; } /* }}} */ +static PHP_INI_MH(OnUpdateNetCmdBufferSize) +{ + long long_value = atol(new_value); + if (long_value < MYSQLND_NET_CMD_BUFFER_MIN_SIZE) { + return FAILURE; + } + MYSQLND_G(net_cmd_buffer_size) = long_value; + + return SUCCESS; +} + /* {{{ PHP_INI_BEGIN */ PHP_INI_BEGIN() STD_PHP_INI_BOOLEAN("mysqlnd.collect_statistics", "1", PHP_INI_ALL, OnUpdateBool, collect_statistics, zend_mysqlnd_globals, mysqlnd_globals) STD_PHP_INI_BOOLEAN("mysqlnd.collect_memory_statistics", "0", PHP_INI_SYSTEM, OnUpdateBool, collect_memory_statistics, zend_mysqlnd_globals, mysqlnd_globals) STD_PHP_INI_ENTRY("mysqlnd.debug", NULL, PHP_INI_SYSTEM, OnUpdateString, debug, zend_mysqlnd_globals, mysqlnd_globals) - STD_PHP_INI_ENTRY("mysqlnd.net_cmd_buffer_size", "2048", PHP_INI_ALL, OnUpdateLong, net_cmd_buffer_size, zend_mysqlnd_globals, mysqlnd_globals) + STD_PHP_INI_ENTRY("mysqlnd.net_cmd_buffer_size", MYSQLND_NET_CMD_BUFFER_MIN_SIZE_STR, PHP_INI_ALL, OnUpdateNetCmdBufferSize, net_cmd_buffer_size, zend_mysqlnd_globals, mysqlnd_globals) STD_PHP_INI_ENTRY("mysqlnd.net_read_buffer_size", "32768",PHP_INI_ALL, OnUpdateLong, net_read_buffer_size, zend_mysqlnd_globals, mysqlnd_globals) + STD_PHP_INI_ENTRY("mysqlnd.net_read_timeout", "31536000", PHP_INI_SYSTEM, OnUpdateLong, net_read_timeout, zend_mysqlnd_globals, mysqlnd_globals) STD_PHP_INI_ENTRY("mysqlnd.log_mask", "0", PHP_INI_ALL, OnUpdateLong, log_mask, zend_mysqlnd_globals, mysqlnd_globals) PHP_INI_END() /* }}} */ diff --git a/ext/mysqlnd/php_mysqlnd.h b/ext/mysqlnd/php_mysqlnd.h index cb44fed39..44d0087bc 100644 --- a/ext/mysqlnd/php_mysqlnd.h +++ b/ext/mysqlnd/php_mysqlnd.h @@ -17,7 +17,7 @@ | Ulf Wendel | +----------------------------------------------------------------------+ - $Id: php_mysqlnd.h,v 1.2.2.5 2008/12/31 11:15:39 sebastian Exp $ + $Id: php_mysqlnd.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_MYSQLND_H diff --git a/ext/oci8/config.m4 b/ext/oci8/config.m4 index 740ed6333..c81ecd638 100644 --- a/ext/oci8/config.m4 +++ b/ext/oci8/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.55.2.3.2.11.2.7 2009/03/12 23:52:37 sixd Exp $ +dnl $Id: config.m4 277079 2009-03-12 23:52:37Z sixd $ dnl if test -z "$SED"; then diff --git a/ext/oci8/config.w32 b/ext/oci8/config.w32 index 0b5bc97cc..39a67fa57 100644 --- a/ext/oci8/config.w32 +++ b/ext/oci8/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.3.4.2.2.2.2.3 2008/08/01 15:07:59 pajoye Exp $ +// $Id: config.w32 264037 2008-08-01 15:07:59Z pajoye $ // vim:ft=javascript if (PHP_OCI8 != "no" && PHP_OCI8_11G != "no") { diff --git a/ext/oci8/oci8.c b/ext/oci8/oci8.c index 8f303d296..ec0ebdf70 100644 --- a/ext/oci8/oci8.c +++ b/ext/oci8/oci8.c @@ -26,7 +26,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: oci8.c,v 1.269.2.16.2.38.2.32 2009/03/16 05:34:02 sixd Exp $ */ +/* $Id: oci8.c 289423 2009-10-09 14:44:43Z pajoye $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -1248,7 +1248,7 @@ PHP_MINFO_FUNCTION(oci) php_info_print_table_start(); php_info_print_table_row(2, "OCI8 Support", "enabled"); php_info_print_table_row(2, "Version", PHP_OCI8_VERSION); - php_info_print_table_row(2, "Revision", "$Revision: 1.269.2.16.2.38.2.32 $"); + php_info_print_table_row(2, "Revision", "$Revision: 289423 $"); snprintf(buf, sizeof(buf), "%ld", OCI_G(num_persistent)); php_info_print_table_row(2, "Active Persistent Connections", buf); @@ -1529,6 +1529,12 @@ sb4 php_oci_error(OCIError *err_p, sword status TSRMLS_DC) break; case OCI_NO_DATA: php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_NO_DATA"); + errcode = php_oci_fetch_errmsg(err_p, &errbuf TSRMLS_CC); + if (errbuf) { + efree(errbuf); + } else { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "OCI_NO_DATA: failed to fetch error message"); + } break; case OCI_ERROR: errcode = php_oci_fetch_errmsg(err_p, &errbuf TSRMLS_CC); diff --git a/ext/oci8/oci8_collection.c b/ext/oci8/oci8_collection.c index cad31684a..7e514df73 100644 --- a/ext/oci8/oci8_collection.c +++ b/ext/oci8/oci8_collection.c @@ -25,7 +25,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: oci8_collection.c,v 1.5.2.3.2.7.2.7 2008/12/31 11:15:39 sebastian Exp $ */ +/* $Id: oci8_collection.c 272370 2008-12-31 11:15:49Z sebastian $ */ diff --git a/ext/oci8/oci8_interface.c b/ext/oci8/oci8_interface.c index 7e012da38..b5ed50187 100644 --- a/ext/oci8/oci8_interface.c +++ b/ext/oci8/oci8_interface.c @@ -25,7 +25,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: oci8_interface.c,v 1.8.2.7.2.13.2.11 2009/03/09 20:20:07 sixd Exp $ */ +/* $Id: oci8_interface.c 276933 2009-03-09 20:20:07Z sixd $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/oci8/oci8_lob.c b/ext/oci8/oci8_lob.c index a1f6a8640..521174029 100644 --- a/ext/oci8/oci8_lob.c +++ b/ext/oci8/oci8_lob.c @@ -25,7 +25,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: oci8_lob.c,v 1.7.2.6.2.14.2.9 2008/12/31 11:15:39 sebastian Exp $ */ +/* $Id: oci8_lob.c 272370 2008-12-31 11:15:49Z sebastian $ */ diff --git a/ext/oci8/oci8_statement.c b/ext/oci8/oci8_statement.c index b1bf8aab5..00c6079d9 100644 --- a/ext/oci8/oci8_statement.c +++ b/ext/oci8/oci8_statement.c @@ -25,7 +25,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: oci8_statement.c,v 1.7.2.14.2.28.2.13 2009/03/11 16:47:14 sixd Exp $ */ +/* $Id: oci8_statement.c 277003 2009-03-11 16:47:14Z sixd $ */ #ifdef HAVE_CONFIG_H diff --git a/ext/oci8/php_oci8.h b/ext/oci8/php_oci8.h index 11c59a8f4..bb4cfea1c 100644 --- a/ext/oci8/php_oci8.h +++ b/ext/oci8/php_oci8.h @@ -25,7 +25,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_oci8.h,v 1.36.2.2.2.1.2.13 2009/03/16 05:44:49 sixd Exp $ */ +/* $Id: php_oci8.h 277243 2009-03-16 05:44:49Z sixd $ */ #if HAVE_OCI8 # ifndef PHP_OCI8_H diff --git a/ext/oci8/php_oci8_int.h b/ext/oci8/php_oci8_int.h index 81fd72ca2..6e8d565b9 100644 --- a/ext/oci8/php_oci8_int.h +++ b/ext/oci8/php_oci8_int.h @@ -25,7 +25,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_oci8_int.h,v 1.11.2.6.2.21.2.14 2009/03/09 20:58:51 sixd Exp $ */ +/* $Id: php_oci8_int.h 276935 2009-03-09 20:58:51Z sixd $ */ #if HAVE_OCI8 # ifndef PHP_OCI8_INT_H diff --git a/ext/oci8/tests/connect.inc b/ext/oci8/tests/connect.inc index 8a116290e..5e340cf6f 100644 --- a/ext/oci8/tests/connect.inc +++ b/ext/oci8/tests/connect.inc @@ -1,18 +1,18 @@ diff --git a/ext/oci8/tests/details.inc b/ext/oci8/tests/details.inc index 0c53823ee..75a136ce3 100644 --- a/ext/oci8/tests/details.inc +++ b/ext/oci8/tests/details.inc @@ -14,36 +14,40 @@ * string like hostname:port/service_name:POOLED */ -if (false !== getenv('PHP_OCI8_TEST_DB')) { - $user = getenv('PHP_OCI8_TEST_USER'); // Database username for tests - $password = getenv('PHP_OCI8_TEST_PASS'); // Password for $user - $dbase = getenv('PHP_OCI8_TEST_DB'); // Database connection string - $test_drcp = getenv('PHP_OCI8_TEST_DRCP'); - if (false !== $test_drcp && 0 == strcasecmp($test_drcp,'TRUE')) { - $test_drcp = TRUE; - } else { - $test_drcp = FALSE; - } - $oracle_on_localhost = getenv('PHP_OCI8_TEST_DB_ON_LOCALHOST'); - if (false !== $oracle_on_localhost && 0 == strcasecmp($oracle_on_localhost,'TRUE')) { - $oracle_on_localhost = TRUE; - } else { - $oracle_on_localhost = FALSE; - } +if (file_exists(dirname(__FILE__)."/details_local.inc")) { + include(dirname(__FILE__)."/details_local.inc"); // this file is not part of the source distribution; make it your own local variant of details.inc } else { - $user = "system"; - $password = "oracle"; - $dbase = "localhost/XE"; - $oracle_on_localhost = TRUE; - $test_drcp = FALSE; + if (false !== getenv('PHP_OCI8_TEST_DB')) { + $user = getenv('PHP_OCI8_TEST_USER'); // Database username for tests + $password = getenv('PHP_OCI8_TEST_PASS'); // Password for $user + $dbase = getenv('PHP_OCI8_TEST_DB'); // Database connection string + $test_drcp = getenv('PHP_OCI8_TEST_DRCP'); + if (false !== $test_drcp && 0 == strcasecmp($test_drcp,'TRUE')) { + $test_drcp = TRUE; + } else { + $test_drcp = FALSE; + } + $oracle_on_localhost = getenv('PHP_OCI8_TEST_DB_ON_LOCALHOST'); + if (false !== $oracle_on_localhost && 0 == strcasecmp($oracle_on_localhost,'TRUE')) { + $oracle_on_localhost = TRUE; + } else { + $oracle_on_localhost = FALSE; + } + } else { + $user = "system"; + $password = "oracle"; + $dbase = "localhost/XE"; + $oracle_on_localhost = TRUE; + $test_drcp = FALSE; + } + + /* + * Common object names for scripts to use + */ + + $table_name = "tb".substr(str_replace(Array(".", "-"), "_", php_uname("n")), 0, 5); + $type_name = strtoupper("tp".substr(str_replace(Array(".", "-"), "_", php_uname("n")), 0, 5)); + $schema = ''; } -/* - * Common object names for scripts to use - */ - -$table_name = "tb".substr(str_replace(Array(".", "-"), "_", php_uname("n")), 0, 5); -$type_name = strtoupper("tp".substr(str_replace(Array(".", "-"), "_", php_uname("n")), 0, 5)); -$schema = ''; - ?> diff --git a/ext/oci8/tests/extauth_01.phpt b/ext/oci8/tests/extauth_01.phpt index 850b1385d..e054a2216 100644 --- a/ext/oci8/tests/extauth_01.phpt +++ b/ext/oci8/tests/extauth_01.phpt @@ -141,56 +141,56 @@ Test 7 Warning: oci_connect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d array(4) { - ["code"]=> + [%u|b%"code"]=> int(12154) - ["message"]=> - string(65) "ORA-12154: %s" - ["offset"]=> + [%u|b%"message"]=> + %unicode|string%(65) "ORA-12154: %s" + [%u|b%"offset"]=> int(0) - ["sqltext"]=> - string(0) "" + [%u|b%"sqltext"]=> + %unicode|string%(0) "" } bool(false) Test 8 Warning: oci_connect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d array(4) { - ["code"]=> + [%u|b%"code"]=> int(12154) - ["message"]=> - string(65) "ORA-12154: %s" - ["offset"]=> + [%u|b%"message"]=> + %unicode|string%(65) "ORA-12154: %s" + [%u|b%"offset"]=> int(0) - ["sqltext"]=> - string(0) "" + [%u|b%"sqltext"]=> + %unicode|string%(0) "" } bool(false) Test 9 -Warning: oci_connect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d +Warning: oci_connect(): ORA-%d: TNS:%s in %s on line %d array(4) { - ["code"]=> - int(12154) - ["message"]=> - string(65) "ORA-12154: %s" - ["offset"]=> + [%u|b%"code"]=> + int(%d) + [%u|b%"message"]=> + %unicode|string%(%d) "ORA-%d: %s" + [%u|b%"offset"]=> int(0) - ["sqltext"]=> - string(0) "" + [%u|b%"sqltext"]=> + %unicode|string%(0) "" } bool(false) Test 10 -Warning: oci_connect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d +Warning: oci_connect(): ORA-%d: TNS:%s in %s on line %d array(4) { - ["code"]=> - int(12154) - ["message"]=> - string(65) "ORA-12154: %s" - ["offset"]=> + [%u|b%"code"]=> + int(%d) + [%u|b%"message"]=> + %unicode|string%(%d) "ORA-%d: %s" + [%u|b%"offset"]=> int(0) - ["sqltext"]=> - string(0) "" + [%u|b%"sqltext"]=> + %unicode|string%(0) "" } bool(false) ===DONE=== diff --git a/ext/oci8/tests/extauth_02.phpt b/ext/oci8/tests/extauth_02.phpt index df9cb5eb0..b27522961 100644 --- a/ext/oci8/tests/extauth_02.phpt +++ b/ext/oci8/tests/extauth_02.phpt @@ -141,56 +141,56 @@ Test 7 Warning: oci_new_connect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d array(4) { - ["code"]=> + [%u|b%"code"]=> int(12154) - ["message"]=> - string(65) "ORA-12154: %s" - ["offset"]=> + [%u|b%"message"]=> + %unicode|string%(65) "ORA-12154: %s" + [%u|b%"offset"]=> int(0) - ["sqltext"]=> - string(0) "" + [%u|b%"sqltext"]=> + %unicode|string%(0) "" } bool(false) Test 8 Warning: oci_new_connect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d array(4) { - ["code"]=> + [%u|b%"code"]=> int(12154) - ["message"]=> - string(65) "ORA-12154: %s" - ["offset"]=> + [%u|b%"message"]=> + %unicode|string%(65) "ORA-12154: %s" + [%u|b%"offset"]=> int(0) - ["sqltext"]=> - string(0) "" + [%u|b%"sqltext"]=> + %unicode|string%(0) "" } bool(false) Test 9 -Warning: oci_new_connect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d +Warning: oci_new_connect(): ORA-%d: TNS:%s %s on line %d array(4) { - ["code"]=> - int(12154) - ["message"]=> - string(65) "ORA-12154: %s" - ["offset"]=> + [%u|b%"code"]=> + int(%d) + [%u|b%"message"]=> + %unicode|string%(%d) "ORA-%d: %s" + [%u|b%"offset"]=> int(0) - ["sqltext"]=> - string(0) "" + [%u|b%"sqltext"]=> + %unicode|string%(0) "" } bool(false) Test 10 -Warning: oci_new_connect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d +Warning: oci_new_connect(): ORA-%d: TNS:%s %s on line %d array(4) { - ["code"]=> - int(12154) - ["message"]=> - string(65) "ORA-12154: %s" - ["offset"]=> + [%u|b%"code"]=> + int(%d) + [%u|b%"message"]=> + %unicode|string%(%d) "ORA-%d: %s" + [%u|b%"offset"]=> int(0) - ["sqltext"]=> - string(0) "" + [%u|b%"sqltext"]=> + %unicode|string%(0) "" } bool(false) ===DONE=== diff --git a/ext/oci8/tests/extauth_03.phpt b/ext/oci8/tests/extauth_03.phpt index 501274232..50be0e724 100644 --- a/ext/oci8/tests/extauth_03.phpt +++ b/ext/oci8/tests/extauth_03.phpt @@ -141,56 +141,56 @@ Test 7 Warning: oci_pconnect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d array(4) { - ["code"]=> + [%u|b%"code"]=> int(12154) - ["message"]=> - string(65) "ORA-12154: %s" - ["offset"]=> + [%u|b%"message"]=> + %unicode|string%(65) "ORA-12154: %s" + [%u|b%"offset"]=> int(0) - ["sqltext"]=> - string(0) "" + [%u|b%"sqltext"]=> + %unicode|string%(0) "" } bool(false) Test 8 Warning: oci_pconnect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d array(4) { - ["code"]=> + [%u|b%"code"]=> int(12154) - ["message"]=> - string(65) "ORA-12154: %s" - ["offset"]=> + [%u|b%"message"]=> + %unicode|string%(65) "ORA-12154: %s" + [%u|b%"offset"]=> int(0) - ["sqltext"]=> - string(0) "" + [%u|b%"sqltext"]=> + %unicode|string%(0) "" } bool(false) Test 9 -Warning: oci_pconnect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d +Warning: oci_pconnect(): ORA-%d: TNS:%s in %s on line %d array(4) { - ["code"]=> - int(12154) - ["message"]=> - string(65) "ORA-12154: %s" - ["offset"]=> + [%u|b%"code"]=> + int(%d) + [%u|b%"message"]=> + %unicode|string%(%d) "ORA-%d: %s" + [%u|b%"offset"]=> int(0) - ["sqltext"]=> - string(0) "" + [%u|b%"sqltext"]=> + %unicode|string%(0) "" } bool(false) Test 10 -Warning: oci_pconnect(): ORA-12154: TNS:could not resolve the connect identifier specified in %s on line %d +Warning: oci_pconnect(): ORA-%d: TNS:%s in %s on line %d array(4) { - ["code"]=> - int(12154) - ["message"]=> - string(65) "ORA-12154: %s" - ["offset"]=> + [%u|b%"code"]=> + int(%d) + [%u|b%"message"]=> + %unicode|string%(%d) "ORA-%d: %s" + [%u|b%"offset"]=> int(0) - ["sqltext"]=> - string(0) "" + [%u|b%"sqltext"]=> + %unicode|string%(0) "" } bool(false) ===DONE=== diff --git a/ext/oci8/tests/oci8safemode.phpt b/ext/oci8/tests/oci8safemode.phpt index 4662b4448..112e544c8 100644 --- a/ext/oci8/tests/oci8safemode.phpt +++ b/ext/oci8/tests/oci8safemode.phpt @@ -15,6 +15,8 @@ $r = oci_password_change($c, "hr", "hrpwd", "hrpwd"); echo "Done\n"; ?> --EXPECTF-- +PHP Warning: Directive 'safe_mode' is deprecated in PHP 5.3 and greater in Unknown on line 0 + Warning: oci_connect(): Privileged connect is disabled in Safe Mode in %s on line %d Warning: oci_password_change(): is disabled in Safe Mode in %s on line %d diff --git a/ext/oci8/tests/pecl_bug16842.phpt b/ext/oci8/tests/pecl_bug16842.phpt new file mode 100644 index 000000000..d796d2506 --- /dev/null +++ b/ext/oci8/tests/pecl_bug16842.phpt @@ -0,0 +1,69 @@ +--TEST-- +PECL Bug #16842 (NO_DATA_FOUND exception is a warning) +--SKIPIF-- + +--INI-- +error_reporting = E_WARNING +--FILE-- + +===DONE=== + +--EXPECTF-- +Test 1 +Raises NO_DATA_FOUND + +Warning: oci_execute(): OCI_NO_DATA in %s on line 11 +bool(false) +array(4) { + [%u|b%"code"]=> + int(1403) + [%u|b%"message"]=> + %unicode|string%(45) "ORA-01403: %s +ORA-06512: at line 1" + [%u|b%"offset"]=> + int(0) + [%u|b%"sqltext"]=> + %unicode|string%(31) "begin raise NO_DATA_FOUND; end;" +} +Test 2 +Raises ZERO_DIVIDE + +Warning: oci_execute(): ORA-01476: %s +ORA-06512: at line 1 in %s on line 19 +bool(false) +array(4) { + [%u|b%"code"]=> + int(1476) + [%u|b%"message"]=> + %unicode|string%(56) "ORA-01476: %s +ORA-06512: at line 1" + [%u|b%"offset"]=> + int(0) + [%u|b%"sqltext"]=> + %unicode|string%(29) "begin raise ZERO_DIVIDE; end;" +} +===DONE=== diff --git a/ext/oci8/tests/xmltype_01.phpt b/ext/oci8/tests/xmltype_01.phpt index 49420259f..a9458c83d 100644 --- a/ext/oci8/tests/xmltype_01.phpt +++ b/ext/oci8/tests/xmltype_01.phpt @@ -2,7 +2,7 @@ Basic XMLType test --SKIPIF-- - + --FILE-- = 0x10000002L + LHASH_OF(CONF_VALUE) * global_config; /* Global SSL config */ + LHASH_OF(CONF_VALUE) * req_config; /* SSL config for this request */ +#else + LHASH * global_config; /* Global SSL config */ + LHASH * req_config; /* SSL config for this request */ +#endif const EVP_MD * md_alg; const EVP_MD * digest; char * section_name, @@ -680,7 +685,11 @@ static time_t asn1_time_to_time_t(ASN1_UTCTIME * timestr TSRMLS_DC) /* {{{ */ } /* }}} */ -static inline int php_openssl_config_check_syntax(const char * section_label, const char * config_filename, const char * section, LHASH * config TSRMLS_DC) /* {{{ */ +#if OPENSSL_VERSION_NUMBER >= 0x10000002L +static inline int php_openssl_config_check_syntax(const char * section_label, const char * config_filename, const char * section, LHASH_OF(CONF_VALUE) * config TSRMLS_DC) /* {{{ */ +#else +static inline int php_openssl_config_check_syntax(const char * section_label, const char * config_filename, const char * section, LHASH * config TSRMLS_DC) /* {{{ */ +#endif { X509V3_CTX ctx; @@ -1158,7 +1167,11 @@ static X509 * php_openssl_x509_from_zval(zval ** val, int makeresource, long * r if (in == NULL) { return NULL; } +#ifdef TYPEDEF_D2I_OF + cert = (X509 *) PEM_ASN1_read_bio((d2i_of_void *)d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); +#else cert = (X509 *) PEM_ASN1_read_bio((char *(*)())d2i_X509, PEM_STRING_X509, in, NULL, NULL, NULL); +#endif BIO_free(in); } @@ -2787,8 +2800,7 @@ static int php_openssl_is_private_key(EVP_PKEY* pkey TSRMLS_DC) case EVP_PKEY_RSA: case EVP_PKEY_RSA2: assert(pkey->pkey.rsa != NULL); - - if (NULL == pkey->pkey.rsa->p || NULL == pkey->pkey.rsa->q) { + if (pkey->pkey.rsa != NULL && (NULL == pkey->pkey.rsa->p || NULL == pkey->pkey.rsa->q)) { return 0; } break; @@ -4311,8 +4323,15 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre GET_VER_OPT_STRING("CN_match", cnmatch); if (cnmatch) { int match = 0; + int name_len = X509_NAME_get_text_by_NID(name, NID_commonName, buf, sizeof(buf)); - X509_NAME_get_text_by_NID(name, NID_commonName, buf, sizeof(buf)); + if (name_len == -1) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to locate peer certificate CN"); + return FAILURE; + } else if (name_len != strlen(buf)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' is malformed", name_len, buf); + return FAILURE; + } match = strcmp(cnmatch, buf) == 0; if (!match && strlen(buf) > 3 && buf[0] == '*' && buf[1] == '.') { @@ -4327,10 +4346,7 @@ int php_openssl_apply_verification_policy(SSL *ssl, X509 *peer, php_stream *stre if (!match) { /* didn't match */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, - "Peer certificate CN=`%s' did not match expected CN=`%s'", - buf, cnmatch); - + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Peer certificate CN=`%.*s' did not match expected CN=`%s'", name_len, buf, cnmatch); return FAILURE; } } diff --git a/ext/openssl/openssl.mak b/ext/openssl/openssl.mak index 4c907b8d7..a0c6fa483 100644 --- a/ext/openssl/openssl.mak +++ b/ext/openssl/openssl.mak @@ -1,185 +1,185 @@ -# Temporarily here -- later may go into some batch file -# which will set this as an environment variable -PROJECT_ROOT = ..\.. - -# Module details -MODULE_NAME = php_ossl -MODULE_DESC = "PHP 5 - OpenSSL Extension" -VMAJ = 1 -VMIN = 0 -VREV = 0 - -#include the common settings -include $(PROJECT_ROOT)/netware/common.mif - -# OpenSSL directory -OSSL_DIR = P:/APPS/script/sw/OpenSSL - -# Build type defaults to 'release' -ifndef BUILD -BUILD = release -endif - -# Extensions of all input and output files -.SUFFIXES: -.SUFFIXES: .nlm .lib .obj .cpp .c .msg .mlc .mdb .xdc .d - -# Source files -C_SRC = openssl.c \ - xp_ssl.c \ - start.c \ - -CPP_SRC_NODIR = $(notdir $(CPP_SRC)) -C_SRC_NODIR = $(notdir $(C_SRC)) -SRC_DIR = $(dir $(CPP_SRC) $(C_SRC)) - -# Library files -LIBRARY = $(OSSL_DIR)/lib/RSAglue.lib \ - $(OSSL_DIR)/lib/crypto.lib \ - $(OSSL_DIR)/lib/ssl.lib - -# Destination directories and files -OBJ_DIR = $(BUILD) -FINAL_DIR = $(BUILD) -MAP_FILE = $(FINAL_DIR)\$(MODULE_NAME).map -OBJECTS = $(addprefix $(OBJ_DIR)/,$(CPP_SRC_NODIR:.c=.obj) $(C_SRC_NODIR:.c=.obj)) -DEPDS = $(addprefix $(OBJ_DIR)/,$(CPP_SRC_NODIR:.c=.d) $(C_SRC_NODIR:.c=.d)) - -# Binary file -ifndef BINARY - BINARY=$(FINAL_DIR)\$(MODULE_NAME).nlm -endif - -# Compile flags -C_FLAGS += -c -maxerrors 25 -msgstyle gcc -C_FLAGS += -wchar_t on -bool on -processor Pentium -C_FLAGS += -nostdinc -nosyspath -C_FLAGS += -relax_pointers # To remove type-casting errors -C_FLAGS += -DNETWARE -DZTS -C_FLAGS += -DUSE_OLD_FUNCTIONS -DCOMPILE_DL_OPENSSL=1 - -C_FLAGS += -I. -I$(PROJECT_ROOT) -I$(PROJECT_ROOT)/main -C_FLAGS += -I$(PROJECT_ROOT)/ext/standard -I$(PROJECT_ROOT)/netware -C_FLAGS += -I$(PROJECT_ROOT)/zend -I$(PROJECT_ROOT)/tsrm -C_FLAGS += -I- -I$(SDK_DIR)/include -I$(MWCIncludes) -C_FLAGS += -I$(OSSL_DIR)/include - -ifndef STACK_SIZE -STACK_SIZE=8192 -endif - -# Extra stuff based on debug / release builds -ifeq '$(BUILD)' 'debug' - SYM_FILE = $(FINAL_DIR)\$(MODULE_NAME).sym - C_FLAGS += -inline smart -sym on -sym codeview4 -opt off -opt intrinsics -sym internal -DDEBUGGING -DDKFBPON - C_FLAGS += -exc cw -DZEND_DEBUG=1 - LD_FLAGS += -sym on -sym codeview4 -osym $(SYM_FILE) - export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtld.lib -else - C_FLAGS += -opt all -inline on -inline smart -inline auto -sym off - C_FLAGS += -opt intrinsics -opt level=4 -DZEND_DEBUG=0 - LD_FLAGS += -sym off - export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtl.lib -endif - - -# Dependencies -MODULE = LibC \ - phplib -IMPORT = @$(SDK_DIR)/imports/libc.imp \ - @$(SDK_DIR)/imports/ws2nlm.imp \ - @$(SDK_DIR)/imports/netware.imp \ - @$(MPK_DIR)/import/mpkOrg.imp \ - @$(PROJECT_ROOT)/netware/phplib.imp -EXPORT = ($(MODULE_NAME)) get_module -API = OutputToScreen - -# Virtual paths -vpath %.cpp . -vpath %.c . ..\..\netware -vpath %.obj $(OBJ_DIR) - - -all: prebuild project - -.PHONY: all - -prebuild: - @if not exist $(OBJ_DIR) md $(OBJ_DIR) - -project: $(BINARY) - @echo Build complete. - -$(OBJ_DIR)/%.d: %.cpp - @echo Building Dependencies for $( $(basename $@).def -ifdef API - @echo Import $(API) >> $(basename $@).def -endif - @echo Module $(MODULE) >> $(basename $@).def -ifdef EXPORT - @echo Export $(EXPORT) >> $(basename $@).def -endif - @echo AutoUnload >> $(basename $@).def -ifeq '$(BUILD)' 'debug' - @echo Debug >> $(basename $@).def -endif - @echo Flag_On 0x00000008 >> $(basename $@).def - @echo Start _LibCPrelude >> $(basename $@).def - @echo Exit _LibCPostlude >> $(basename $@).def - -# Two functions imported to build the openssl extension - @echo Import GetProcessSwitchCount >> $(basename $@).def - @echo Import RunningProcess >> $(basename $@).def - - $(MPKTOOL) $(XDCFLAGS) $(basename $@).xdc - @echo xdcdata $(basename $@).xdc >> $(basename $@).def - - @echo Linking $@... - @echo $(LD_FLAGS) -commandfile $(basename $@).def > $(basename $@).link - - @echo $(LIBRARY) $(OBJECTS) >> $(basename $@).link - - @$(LINK) @$(basename $@).link - - -.PHONY: clean -clean: cleanobj cleanbin - -.PHONY: cleand -cleand: - @echo Deleting all dependency files... - -@del "$(OBJ_DIR)\*.d" - -.PHONY: cleanobj -cleanobj: - @echo Deleting all object files... - -@del "$(OBJ_DIR)\*.obj" - -.PHONY: cleanbin -cleanbin: - @echo Deleting binary files... - -@del "$(FINAL_DIR)\$(MODULE_NAME).nlm" - @echo Deleting MAP, DEF files, etc.... - -@del "$(FINAL_DIR)\$(MODULE_NAME).map" - -@del "$(FINAL_DIR)\$(MODULE_NAME).def" - -@del "$(FINAL_DIR)\$(MODULE_NAME).link" -ifeq '$(BUILD)' 'debug' - -@del $(FINAL_DIR)\$(MODULE_NAME).sym -endif +# Temporarily here -- later may go into some batch file +# which will set this as an environment variable +PROJECT_ROOT = ..\.. + +# Module details +MODULE_NAME = php_ossl +MODULE_DESC = "PHP 5 - OpenSSL Extension" +VMAJ = 1 +VMIN = 0 +VREV = 0 + +#include the common settings +include $(PROJECT_ROOT)/netware/common.mif + +# OpenSSL directory +OSSL_DIR = P:/APPS/script/sw/OpenSSL + +# Build type defaults to 'release' +ifndef BUILD +BUILD = release +endif + +# Extensions of all input and output files +.SUFFIXES: +.SUFFIXES: .nlm .lib .obj .cpp .c .msg .mlc .mdb .xdc .d + +# Source files +C_SRC = openssl.c \ + xp_ssl.c \ + start.c \ + +CPP_SRC_NODIR = $(notdir $(CPP_SRC)) +C_SRC_NODIR = $(notdir $(C_SRC)) +SRC_DIR = $(dir $(CPP_SRC) $(C_SRC)) + +# Library files +LIBRARY = $(OSSL_DIR)/lib/RSAglue.lib \ + $(OSSL_DIR)/lib/crypto.lib \ + $(OSSL_DIR)/lib/ssl.lib + +# Destination directories and files +OBJ_DIR = $(BUILD) +FINAL_DIR = $(BUILD) +MAP_FILE = $(FINAL_DIR)\$(MODULE_NAME).map +OBJECTS = $(addprefix $(OBJ_DIR)/,$(CPP_SRC_NODIR:.c=.obj) $(C_SRC_NODIR:.c=.obj)) +DEPDS = $(addprefix $(OBJ_DIR)/,$(CPP_SRC_NODIR:.c=.d) $(C_SRC_NODIR:.c=.d)) + +# Binary file +ifndef BINARY + BINARY=$(FINAL_DIR)\$(MODULE_NAME).nlm +endif + +# Compile flags +C_FLAGS += -c -maxerrors 25 -msgstyle gcc +C_FLAGS += -wchar_t on -bool on -processor Pentium +C_FLAGS += -nostdinc -nosyspath +C_FLAGS += -relax_pointers # To remove type-casting errors +C_FLAGS += -DNETWARE -DZTS +C_FLAGS += -DUSE_OLD_FUNCTIONS -DCOMPILE_DL_OPENSSL=1 + +C_FLAGS += -I. -I$(PROJECT_ROOT) -I$(PROJECT_ROOT)/main +C_FLAGS += -I$(PROJECT_ROOT)/ext/standard -I$(PROJECT_ROOT)/netware +C_FLAGS += -I$(PROJECT_ROOT)/zend -I$(PROJECT_ROOT)/tsrm +C_FLAGS += -I- -I$(SDK_DIR)/include -I$(MWCIncludes) +C_FLAGS += -I$(OSSL_DIR)/include + +ifndef STACK_SIZE +STACK_SIZE=8192 +endif + +# Extra stuff based on debug / release builds +ifeq '$(BUILD)' 'debug' + SYM_FILE = $(FINAL_DIR)\$(MODULE_NAME).sym + C_FLAGS += -inline smart -sym on -sym codeview4 -opt off -opt intrinsics -sym internal -DDEBUGGING -DDKFBPON + C_FLAGS += -exc cw -DZEND_DEBUG=1 + LD_FLAGS += -sym on -sym codeview4 -osym $(SYM_FILE) + export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtld.lib +else + C_FLAGS += -opt all -inline on -inline smart -inline auto -sym off + C_FLAGS += -opt intrinsics -opt level=4 -DZEND_DEBUG=0 + LD_FLAGS += -sym off + export MWLibraryFiles=$(SDK_DIR)/imports/libcpre.o;mwcrtl.lib +endif + + +# Dependencies +MODULE = LibC \ + phplib +IMPORT = @$(SDK_DIR)/imports/libc.imp \ + @$(SDK_DIR)/imports/ws2nlm.imp \ + @$(SDK_DIR)/imports/netware.imp \ + @$(MPK_DIR)/import/mpkOrg.imp \ + @$(PROJECT_ROOT)/netware/phplib.imp +EXPORT = ($(MODULE_NAME)) get_module +API = OutputToScreen + +# Virtual paths +vpath %.cpp . +vpath %.c . ..\..\netware +vpath %.obj $(OBJ_DIR) + + +all: prebuild project + +.PHONY: all + +prebuild: + @if not exist $(OBJ_DIR) md $(OBJ_DIR) + +project: $(BINARY) + @echo Build complete. + +$(OBJ_DIR)/%.d: %.cpp + @echo Building Dependencies for $( $(basename $@).def +ifdef API + @echo Import $(API) >> $(basename $@).def +endif + @echo Module $(MODULE) >> $(basename $@).def +ifdef EXPORT + @echo Export $(EXPORT) >> $(basename $@).def +endif + @echo AutoUnload >> $(basename $@).def +ifeq '$(BUILD)' 'debug' + @echo Debug >> $(basename $@).def +endif + @echo Flag_On 0x00000008 >> $(basename $@).def + @echo Start _LibCPrelude >> $(basename $@).def + @echo Exit _LibCPostlude >> $(basename $@).def + +# Two functions imported to build the openssl extension + @echo Import GetProcessSwitchCount >> $(basename $@).def + @echo Import RunningProcess >> $(basename $@).def + + $(MPKTOOL) $(XDCFLAGS) $(basename $@).xdc + @echo xdcdata $(basename $@).xdc >> $(basename $@).def + + @echo Linking $@... + @echo $(LD_FLAGS) -commandfile $(basename $@).def > $(basename $@).link + + @echo $(LIBRARY) $(OBJECTS) >> $(basename $@).link + + @$(LINK) @$(basename $@).link + + +.PHONY: clean +clean: cleanobj cleanbin + +.PHONY: cleand +cleand: + @echo Deleting all dependency files... + -@del "$(OBJ_DIR)\*.d" + +.PHONY: cleanobj +cleanobj: + @echo Deleting all object files... + -@del "$(OBJ_DIR)\*.obj" + +.PHONY: cleanbin +cleanbin: + @echo Deleting binary files... + -@del "$(FINAL_DIR)\$(MODULE_NAME).nlm" + @echo Deleting MAP, DEF files, etc.... + -@del "$(FINAL_DIR)\$(MODULE_NAME).map" + -@del "$(FINAL_DIR)\$(MODULE_NAME).def" + -@del "$(FINAL_DIR)\$(MODULE_NAME).link" +ifeq '$(BUILD)' 'debug' + -@del $(FINAL_DIR)\$(MODULE_NAME).sym +endif diff --git a/ext/openssl/php_openssl.h b/ext/openssl/php_openssl.h index 83fc716e6..1aa8adf8d 100644 --- a/ext/openssl/php_openssl.h +++ b/ext/openssl/php_openssl.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_openssl.h,v 1.16.2.1.2.4.2.2 2008/12/31 11:15:40 sebastian Exp $ */ +/* $Id: php_openssl.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_OPENSSL_H #define PHP_OPENSSL_H diff --git a/ext/openssl/tests/bug48182.phpt b/ext/openssl/tests/bug48182.phpt new file mode 100644 index 000000000..0af04e1a9 --- /dev/null +++ b/ext/openssl/tests/bug48182.phpt @@ -0,0 +1,92 @@ +--TEST-- +#48182,ssl handshake fails during asynchronous socket connection +--SKIPIF-- + +--FILE-- + false, 'allow_self_signed' => true, 'local_cert' => $pem); + $ssl = array('ssl' => $ssl_params); + + $context = stream_context_create($ssl); + $sock = stream_socket_server($host, $errno, $errstr, $flags, $context); + if (!$sock) return false; + + $link = stream_socket_accept($sock); + if (!$link) return false; // bad link? + + $r = array($link); + $w = array(); + $e = array(); + if (stream_select($r, $w, $e, 0, 1000) != 0) + $data .= fread($link, 8192); + + $r = array(); + $w = array($link); + if (stream_select($r, $w, $e, 0, 1000) != 0) + $wrote = fwrite($link, $data, strlen($data)); + + // close stuff + fclose($link); + fclose($sock); + + exit; +} + +function ssl_async_client($port) { + $host = 'ssl://127.0.0.1'.':'.$port; + $flags = STREAM_CLIENT_CONNECT | STREAM_CLIENT_ASYNC_CONNECT; + $data = "Sending data over to SSL server in async mode with contents like Hello World\n"; + + $socket = stream_socket_client($host, $errno, $errstr, 10, $flags); + stream_set_blocking($socket, 0); + + while ($data) { + $wrote = fwrite($socket, $data, strlen($data)); + $data = substr($data, $wrote); + } + + $r = array($socket); + $w = array(); + $e = array(); + if (stream_select($r, $w, $e, 0, 10) != 0) + { + $data .= fread($socket, 1024); + } + + echo "$data"; + + fclose($socket); +} + +echo "Running bug48182\n"; + +$port = rand(15000, 32000); + +$pid = pcntl_fork(); +if ($pid == 0) { // child + ssl_server($port); + exit; +} + +// client or failed +sleep(1); +ssl_async_client($port); + +pcntl_waitpid($pid, $status); + +?> +--EXPECTF-- +Running bug48182 +Sending bug48182 +Sending data over to SSL server in async mode with contents like Hello World diff --git a/ext/openssl/xp_ssl.c b/ext/openssl/xp_ssl.c index 7c08ab147..9462e0f91 100644 --- a/ext/openssl/xp_ssl.c +++ b/ext/openssl/xp_ssl.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xp_ssl.c,v 1.22.2.3.2.9.2.10 2008/12/31 11:15:40 sebastian Exp $ */ +/* $Id: xp_ssl.c 289416 2009-10-09 14:20:17Z pajoye $ */ #include "php.h" #include "ext/standard/file.h" @@ -48,6 +48,7 @@ int php_openssl_get_x509_list_id(void); typedef struct _php_openssl_netstream_data_t { php_netstream_data_t s; SSL *ssl_handle; + SSL_CTX *ctx; struct timeval connect_timeout; int enable_on_connect; int is_client; @@ -254,6 +255,14 @@ static int php_openssl_sockop_close(php_stream *stream, int close_handle TSRMLS_ SSL_free(sslsock->ssl_handle); sslsock->ssl_handle = NULL; } + if (sslsock->ctx) { + SSL_CTX_free(sslsock->ctx); + sslsock->ctx = NULL; + } +#ifdef PHP_WIN32 + if (sslsock->s.socket == -1) + sslsock->s.socket = SOCK_ERR; +#endif if (sslsock->s.socket != SOCK_ERR) { #ifdef PHP_WIN32 /* prevent more data from coming in */ @@ -295,7 +304,6 @@ static inline int php_openssl_setup_crypto(php_stream *stream, php_stream_xport_crypto_param *cparam TSRMLS_DC) { - SSL_CTX *ctx; SSL_METHOD *method; if (sslsock->ssl_handle) { @@ -344,18 +352,19 @@ static inline int php_openssl_setup_crypto(php_stream *stream, } - ctx = SSL_CTX_new(method); - if (ctx == NULL) { + sslsock->ctx = SSL_CTX_new(method); + if (sslsock->ctx == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to create an SSL context"); return -1; } - SSL_CTX_set_options(ctx, SSL_OP_ALL); + SSL_CTX_set_options(sslsock->ctx, SSL_OP_ALL); - sslsock->ssl_handle = php_SSL_new_from_context(ctx, stream TSRMLS_CC); + sslsock->ssl_handle = php_SSL_new_from_context(sslsock->ctx, stream TSRMLS_CC); if (sslsock->ssl_handle == NULL) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "failed to create an SSL handle"); - SSL_CTX_free(ctx); + SSL_CTX_free(sslsock->ctx); + sslsock->ctx = NULL; return -1; } @@ -672,7 +681,11 @@ static int php_openssl_sockop_set_option(php_stream *stream, int option, int val * we notice that the connect has actually been established */ php_stream_socket_ops.set_option(stream, option, value, ptrparam TSRMLS_CC); - if (xparam->outputs.returncode == 0 && sslsock->enable_on_connect) { + if ((sslsock->enable_on_connect) && + ((xparam->outputs.returncode == 0) || + (xparam->op == STREAM_XPORT_OP_CONNECT_ASYNC && + xparam->outputs.returncode == 1 && xparam->outputs.error_code == EINPROGRESS))) + { if (php_stream_xport_crypto_setup(stream, sslsock->method, NULL TSRMLS_CC) < 0 || php_stream_xport_crypto_enable(stream, 1 TSRMLS_CC) < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to enable crypto"); @@ -772,6 +785,9 @@ php_stream *php_openssl_ssl_socket_factory(const char *proto, long protolen, * connecting */ sslsock->s.socket = -1; + /* Initialize context as NULL */ + sslsock->ctx = NULL; + stream = php_stream_alloc_rel(&php_openssl_socket_ops, sslsock, persistent_id, "r+"); if (stream == NULL) { diff --git a/ext/pcntl/config.m4 b/ext/pcntl/config.m4 index d0fef8ade..ea26eb149 100644 --- a/ext/pcntl/config.m4 +++ b/ext/pcntl/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.10.8.3 2008/08/07 13:11:05 tony2001 Exp $ +dnl $Id: config.m4 264390 2008-08-07 13:11:05Z tony2001 $ dnl PHP_ARG_ENABLE(pcntl, whether to enable pcntl support, diff --git a/ext/pcntl/pcntl.c b/ext/pcntl/pcntl.c index 85f08e24a..eec6aaa33 100755 --- a/ext/pcntl/pcntl.c +++ b/ext/pcntl/pcntl.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pcntl.c,v 1.48.2.2.2.4.2.21 2009/05/26 14:01:39 lbarnaud Exp $ */ +/* $Id: pcntl.c 281177 2009-05-26 14:01:39Z lbarnaud $ */ #define PCNTL_DEBUG 0 diff --git a/ext/pcntl/php_pcntl.h b/ext/pcntl/php_pcntl.h index 03e3d33cb..6bd45b212 100644 --- a/ext/pcntl/php_pcntl.h +++ b/ext/pcntl/php_pcntl.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pcntl.h,v 1.20.2.1.2.1.2.6 2008/12/31 11:15:40 sebastian Exp $ */ +/* $Id: php_pcntl.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PCNTL_H #define PHP_PCNTL_H diff --git a/ext/pcntl/php_signal.c b/ext/pcntl/php_signal.c index 22c8fb32f..4396c0531 100644 --- a/ext/pcntl/php_signal.c +++ b/ext/pcntl/php_signal.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_signal.c,v 1.9.2.1.2.1.2.3 2008/12/31 11:15:40 sebastian Exp $ */ +/* $Id: php_signal.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_signal.h" diff --git a/ext/pcntl/php_signal.h b/ext/pcntl/php_signal.h index 06d8219ce..73a395c44 100644 --- a/ext/pcntl/php_signal.h +++ b/ext/pcntl/php_signal.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_signal.h,v 1.9.2.1.2.1.2.3 2008/12/31 11:15:40 sebastian Exp $ */ +/* $Id: php_signal.h 272370 2008-12-31 11:15:49Z sebastian $ */ #include #ifndef PHP_SIGNAL_H diff --git a/ext/pcntl/tests/bug47566.phpt b/ext/pcntl/tests/bug47566.phpt index 8a69e6bc7..6eb3dbc13 100644 --- a/ext/pcntl/tests/bug47566.phpt +++ b/ext/pcntl/tests/bug47566.phpt @@ -3,7 +3,7 @@ Bug #47566 (return value of pcntl_wexitstatus()) --SKIPIF-- --FILE-- - +--FILE-- + 0) { + pcntl_wait($status); + var_dump($pid); +} else { + var_dump($pid); +} +?> +--EXPECTF-- +*** Test by calling method or function with its expected arguments, first print the child PID and the the father *** +int(0) +int(%d) diff --git a/ext/pcntl/tests/pcntl_fork_variation.phpt b/ext/pcntl/tests/pcntl_fork_variation.phpt new file mode 100644 index 000000000..4eea07181 --- /dev/null +++ b/ext/pcntl/tests/pcntl_fork_variation.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test function pcntl_fork() by testing the process isolation in the forking hierarchy father -> son -> grandson where father can not knows his grandson +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- + +--FILE-- + 0) { + pcntl_wait($status); + echo "father is $pid\n"; + + if (!isset($pid2)) + { + echo "father ($pid) doesn't know its grandsons\n"; + } +} +else +{ + echo "son ($pid)\n"; + $pid2 = pcntl_fork(); + if ($pid2 > 0) + { + pcntl_wait($status2); + echo "son is father of $pid2\n"; + } + else + { + echo "grandson ($pid2)\n"; + } +} +?> +--EXPECTF-- +*** Testing the process isolations between a process and its forks *** +son (0) +grandson (0) +son is father of %d +father is %d +father (%d) doesn't know its grandsons diff --git a/ext/pcre/config.w32 b/ext/pcre/config.w32 index 0115c8a29..4e3917f85 100644 --- a/ext/pcre/config.w32 +++ b/ext/pcre/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.4.2.5.2.7.2.4 2009/01/02 04:59:41 andi Exp $ +// $Id: config.w32 272550 2009-01-02 04:59:41Z andi $ // vim:ft=javascript EXTENSION("pcre", "php_pcre.c", false /* never shared */, diff --git a/ext/pcre/config0.m4 b/ext/pcre/config0.m4 index 570573142..3e8a8c20c 100644 --- a/ext/pcre/config0.m4 +++ b/ext/pcre/config0.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config0.m4,v 1.38.2.3.2.10.2.4 2008/09/09 07:55:07 nlopess Exp $ +dnl $Id: config0.m4 287118 2009-08-11 21:40:15Z scottmac $ dnl dnl By default we'll compile and link against the bundled PCRE library @@ -11,7 +11,7 @@ PHP_ARG_WITH(pcre-regex,, if test "$PHP_PCRE_REGEX" != "yes" && test "$PHP_PCRE_REGEX" != "no"; then AC_MSG_CHECKING([for PCRE headers location]) - for i in $PHP_PCRE_REGEX $PHP_PCRE_REGEX/include $PHP_PCRE_REGEX/include/pcre; do + for i in $PHP_PCRE_REGEX $PHP_PCRE_REGEX/include $PHP_PCRE_REGEX/include/pcre $PHP_PCRE_REGEX/local/include; do test -f $i/pcre.h && PCRE_INCDIR=$i done diff --git a/ext/pcre/pcrelib/testdata/grepinput8 b/ext/pcre/pcrelib/testdata/grepinput8 index c4b8c440f..e8ddc2733 100644 --- a/ext/pcre/pcrelib/testdata/grepinput8 +++ b/ext/pcre/pcrelib/testdata/grepinput8 @@ -1,10 +1,11 @@ X one -X two X three X four X five +X two X three X four +X five X six X seven…X eight
X nine
X ten Before 111 -Before 222
Before 333…Match +Before 222
Before 333…Match After 111 After 222
After 333 And so on and so on diff --git a/ext/pcre/pcrelib/testdata/grepoutput8 b/ext/pcre/pcrelib/testdata/grepoutput8 index 0a8b7ec7b..6317355cc 100644 --- a/ext/pcre/pcrelib/testdata/grepoutput8 +++ b/ext/pcre/pcrelib/testdata/grepoutput8 @@ -1,10 +1,11 @@ ---------------------------- Test U1 ------------------------------ 1:X one -2:X two 3:X three 4:X four 5:X five +2:X two 3:X three 4:X four +5:X five 6:X six 7:X seven…8:X eight
9:X nine
10:X ten ---------------------------- Test U2 ------------------------------ 12-Before 111 -13-Before 222
14-Before 333…15:Match +13-Before 222
14-Before 333…15:Match 16-After 111 17-After 222
18-After 333 diff --git a/ext/pcre/pcrelib/testdata/grepoutputN b/ext/pcre/pcrelib/testdata/grepoutputN index 1f9f8801e..170a4321e 100644 --- a/ext/pcre/pcrelib/testdata/grepoutputN +++ b/ext/pcre/pcrelib/testdata/grepoutputN @@ -1,16 +1,22 @@ ----------------------------- Test N1 ------------------------------ -1:abc 2:def ---------------------------- Test N2 ------------------------------ -1:abc def +---------------------------- Test N1 ------------------------------ +1:abc +2:def +---------------------------- Test N2 ------------------------------ +1:abc +def 2:ghi -jkl---------------------------- Test N3 ------------------------------ -2:def 3: +jkl---------------------------- Test N3 ------------------------------ +2:def +3: ghi -jkl---------------------------- Test N4 ------------------------------ +jkl---------------------------- Test N4 ------------------------------ 2:ghi -jkl---------------------------- Test N5 ------------------------------ -1:abc 2:def +jkl---------------------------- Test N5 ------------------------------ +1:abc +2:def 3:ghi -4:jkl---------------------------- Test N6 ------------------------------ -1:abc 2:def +4:jkl---------------------------- Test N6 ------------------------------ +1:abc +2:def 3:ghi 4:jkl \ No newline at end of file diff --git a/ext/pcre/php_pcre.c b/ext/pcre/php_pcre.c index 13db594f9..d89e3537b 100644 --- a/ext/pcre/php_pcre.c +++ b/ext/pcre/php_pcre.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pcre.c,v 1.168.2.9.2.21.2.32 2009/06/05 18:50:32 mattwil Exp $ */ +/* $Id: php_pcre.c 289418 2009-10-09 14:25:51Z pajoye $ */ #include "php.h" #include "php_ini.h" @@ -1836,7 +1836,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_match_all, 0, 0, 3) ZEND_ARG_INFO(0, offset) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_replace, 0, 0, 2) +ZEND_BEGIN_ARG_INFO_EX(arginfo_preg_replace, 0, 0, 3) ZEND_ARG_INFO(0, regex) ZEND_ARG_INFO(0, replace) ZEND_ARG_INFO(0, subject) diff --git a/ext/pcre/php_pcre.h b/ext/pcre/php_pcre.h index 0a82cb4d7..841773bb8 100644 --- a/ext/pcre/php_pcre.h +++ b/ext/pcre/php_pcre.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pcre.h,v 1.41.2.1.2.5.2.3 2008/12/31 11:15:40 sebastian Exp $ */ +/* $Id: php_pcre.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PCRE_H #define PHP_PCRE_H diff --git a/ext/pcre/tests/preg_split_basic.phpt b/ext/pcre/tests/preg_split_basic.phpt index 324270ac3..e94a94f62 100644 --- a/ext/pcre/tests/preg_split_basic.phpt +++ b/ext/pcre/tests/preg_split_basic.phpt @@ -1,6 +1,5 @@ --TEST-- Test preg_split() function : basic functionality ---INI-- --FILE-- string(1) ")" -} \ No newline at end of file +} diff --git a/ext/pdo/README b/ext/pdo/README index 9431b6147..16a82fc15 100755 --- a/ext/pdo/README +++ b/ext/pdo/README @@ -1,4 +1,4 @@ -$Id: README,v 1.3 2005/02/09 23:34:53 wez Exp $ +$Id: README 242949 2007-09-26 15:44:16Z cvs2svn $ PHP Data Objects ================ diff --git a/ext/pdo/TODO b/ext/pdo/TODO index 133b2c8fb..762d726f5 100755 --- a/ext/pdo/TODO +++ b/ext/pdo/TODO @@ -1,4 +1,4 @@ -$Id: TODO,v 1.6.2.2.2.1 2007/07/25 22:26:14 iliaa Exp $ +$Id: TODO 240335 2007-07-25 22:26:14Z iliaa $ Roadmap for PDO diff --git a/ext/pdo/config.m4 b/ext/pdo/config.m4 index 262697d08..ef9b1654f 100755 --- a/ext/pdo/config.m4 +++ b/ext/pdo/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.15.2.3.2.1.2.1 2008/07/25 13:46:23 jani Exp $ +dnl $Id: config.m4 263549 2008-07-25 13:46:24Z jani $ dnl config.m4 for extension pdo dnl vim:se ts=2 sw=2 et: diff --git a/ext/pdo/config.w32 b/ext/pdo/config.w32 index d34b8c3e3..e8f864bca 100755 --- a/ext/pdo/config.w32 +++ b/ext/pdo/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.5.2.2.4.1 2008/07/24 16:05:34 pajoye Exp $ +// $Id: config.w32 263427 2008-07-24 16:05:34Z pajoye $ // vim:ft=javascript ARG_ENABLE("pdo", "Enable PHP Data Objects support", "no"); diff --git a/ext/pdo/pdo.c b/ext/pdo/pdo.c index c111d21aa..8b3734099 100755 --- a/ext/pdo/pdo.c +++ b/ext/pdo/pdo.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo.c,v 1.57.2.17.2.9.2.8 2008/12/31 11:15:40 sebastian Exp $ */ +/* $Id: pdo.c 284394 2009-07-19 22:46:03Z felipe $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo/pdo_dbh.c b/ext/pdo/pdo_dbh.c index ed6ddcf1c..c85a59308 100755 --- a/ext/pdo/pdo_dbh.c +++ b/ext/pdo/pdo_dbh.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_dbh.c,v 1.82.2.31.2.17.2.25 2009/05/02 01:37:33 kalle Exp $ */ +/* $Id: pdo_dbh.c 289775 2009-10-19 21:43:34Z johannes $ */ /* The PDO Database Handle Class */ @@ -110,7 +110,7 @@ void pdo_handle_error(pdo_dbh_t *dbh, pdo_stmt_t *stmt TSRMLS_DC) /* {{{ */ char *message = NULL; zval *info = NULL; - if (dbh->error_mode == PDO_ERRMODE_SILENT) { + if (dbh == NULL || dbh->error_mode == PDO_ERRMODE_SILENT) { return; } diff --git a/ext/pdo/pdo_sql_parser.c b/ext/pdo/pdo_sql_parser.c index 358bc3983..072d9e69b 100644 --- a/ext/pdo/pdo_sql_parser.c +++ b/ext/pdo/pdo_sql_parser.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_sql_parser.c,v 1.35.2.6.2.12.2.8 2008/12/31 11:15:40 sebastian Exp $ */ +/* $Id: pdo_sql_parser.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "php_pdo_driver.h" diff --git a/ext/pdo/pdo_sql_parser.c.orig b/ext/pdo/pdo_sql_parser.c.orig index 3e6883b33..1d3eaa6fc 100644 --- a/ext/pdo/pdo_sql_parser.c.orig +++ b/ext/pdo/pdo_sql_parser.c.orig @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_sql_parser.c,v 1.35.2.6.2.12.2.8 2008/12/31 11:15:40 sebastian Exp $ */ +/* $Id: pdo_sql_parser.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "php_pdo_driver.h" diff --git a/ext/pdo/pdo_sql_parser.re b/ext/pdo/pdo_sql_parser.re index a7459033b..4b92183c1 100644 --- a/ext/pdo/pdo_sql_parser.re +++ b/ext/pdo/pdo_sql_parser.re @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_sql_parser.re,v 1.28.2.4.2.9.2.8 2008/12/31 11:13:54 sebastian Exp $ */ +/* $Id: pdo_sql_parser.re 272369 2008-12-31 11:13:54Z sebastian $ */ #include "php.h" #include "php_pdo_driver.h" diff --git a/ext/pdo/pdo_sqlstate.c b/ext/pdo/pdo_sqlstate.c index 2fe789986..de44331d1 100644 --- a/ext/pdo/pdo_sqlstate.c +++ b/ext/pdo/pdo_sqlstate.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_sqlstate.c,v 1.7.2.1.2.1.2.3 2008/12/31 11:15:40 sebastian Exp $ */ +/* $Id: pdo_sqlstate.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo/pdo_stmt.c b/ext/pdo/pdo_stmt.c index 9291c02dc..18a3bd84b 100755 --- a/ext/pdo/pdo_stmt.c +++ b/ext/pdo/pdo_stmt.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_stmt.c,v 1.118.2.38.2.24.2.46 2009/04/23 13:26:09 mbeccati Exp $ */ +/* $Id: pdo_stmt.c 289775 2009-10-19 21:43:34Z johannes $ */ /* The PDO Statement Handle Class */ @@ -317,7 +317,7 @@ static int really_register_bound_param(struct pdo_bound_param_data *param, pdo_s if (PDO_PARAM_TYPE(param->param_type) == PDO_PARAM_STR && param->max_value_len <= 0 && ! ZVAL_IS_NULL(param->parameter)) { if (Z_TYPE_P(param->parameter) == IS_DOUBLE) { char *p; - int len = spprintf(&p, 0, "%F", Z_DVAL_P(param->parameter)); + int len = spprintf(&p, 0, "%.*H", (int) EG(precision), Z_DVAL_P(param->parameter)); ZVAL_STRINGL(param->parameter, p, len, 0); } else { convert_to_string(param->parameter); @@ -2663,26 +2663,28 @@ static zval *row_prop_or_dim_read(zval *object, zval *member, int type TSRMLS_DC MAKE_STD_ZVAL(return_value); RETVAL_NULL(); - - if (Z_TYPE_P(member) == IS_LONG) { - if (Z_LVAL_P(member) >= 0 && Z_LVAL_P(member) < stmt->column_count) { - fetch_value(stmt, return_value, Z_LVAL_P(member), NULL TSRMLS_CC); - } - } else { - convert_to_string(member); - /* TODO: replace this with a hash of available column names to column - * numbers */ - for (colno = 0; colno < stmt->column_count; colno++) { - if (strcmp(stmt->columns[colno].name, Z_STRVAL_P(member)) == 0) { - fetch_value(stmt, return_value, colno, NULL TSRMLS_CC); - Z_SET_REFCOUNT_P(return_value, 0); - Z_UNSET_ISREF_P(return_value); - return return_value; + + if (stmt) { + if (Z_TYPE_P(member) == IS_LONG) { + if (Z_LVAL_P(member) >= 0 && Z_LVAL_P(member) < stmt->column_count) { + fetch_value(stmt, return_value, Z_LVAL_P(member), NULL TSRMLS_CC); + } + } else { + convert_to_string(member); + /* TODO: replace this with a hash of available column names to column + * numbers */ + for (colno = 0; colno < stmt->column_count; colno++) { + if (strcmp(stmt->columns[colno].name, Z_STRVAL_P(member)) == 0) { + fetch_value(stmt, return_value, colno, NULL TSRMLS_CC); + Z_SET_REFCOUNT_P(return_value, 0); + Z_UNSET_ISREF_P(return_value); + return return_value; + } + } + if (strcmp(Z_STRVAL_P(member), "queryString") == 0) { + zval_ptr_dtor(&return_value); + return std_object_handlers.read_property(object, member, IS_STRING TSRMLS_CC); } - } - if (strcmp(Z_STRVAL_P(member), "queryString") == 0) { - zval_ptr_dtor(&return_value); - return std_object_handlers.read_property(object, member, IS_STRING TSRMLS_CC); } } @@ -2702,16 +2704,18 @@ static int row_prop_or_dim_exists(zval *object, zval *member, int check_empty TS pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC); int colno = -1; - if (Z_TYPE_P(member) == IS_LONG) { - return Z_LVAL_P(member) >= 0 && Z_LVAL_P(member) < stmt->column_count; - } else { - convert_to_string(member); + if (stmt) { + if (Z_TYPE_P(member) == IS_LONG) { + return Z_LVAL_P(member) >= 0 && Z_LVAL_P(member) < stmt->column_count; + } else { + convert_to_string(member); - /* TODO: replace this with a hash of available column names to column - * numbers */ - for (colno = 0; colno < stmt->column_count; colno++) { - if (strcmp(stmt->columns[colno].name, Z_STRVAL_P(member)) == 0) { - return 1; + /* TODO: replace this with a hash of available column names to column + * numbers */ + for (colno = 0; colno < stmt->column_count; colno++) { + if (strcmp(stmt->columns[colno].name, Z_STRVAL_P(member)) == 0) { + return 1; + } } } } @@ -2729,6 +2733,10 @@ static HashTable *row_get_properties(zval *object TSRMLS_DC) pdo_stmt_t * stmt = (pdo_stmt_t *) zend_object_store_get_object(object TSRMLS_CC); int i; + if (stmt == NULL) { + return NULL; + } + for (i = 0; i < stmt->column_count; i++) { zval *val; MAKE_STD_ZVAL(val); diff --git a/ext/pdo/php_pdo.h b/ext/pdo/php_pdo.h index 5b3d57e37..6d6658196 100755 --- a/ext/pdo/php_pdo.h +++ b/ext/pdo/php_pdo.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo.h,v 1.7.2.5.2.3.2.3 2008/12/31 11:15:40 sebastian Exp $ */ +/* $Id: php_pdo.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PDO_H #define PHP_PDO_H diff --git a/ext/pdo/php_pdo_driver.h b/ext/pdo/php_pdo_driver.h index 9a8b721e9..e8aa505f9 100755 --- a/ext/pdo/php_pdo_driver.h +++ b/ext/pdo/php_pdo_driver.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_driver.h,v 1.66.2.11.2.6.2.5 2008/12/31 11:15:40 sebastian Exp $ */ +/* $Id: php_pdo_driver.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PDO_DRIVER_H #define PHP_PDO_DRIVER_H diff --git a/ext/pdo/php_pdo_int.h b/ext/pdo/php_pdo_int.h index f25c409ce..3e301b522 100755 --- a/ext/pdo/php_pdo_int.h +++ b/ext/pdo/php_pdo_int.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_int.h,v 1.17.2.6.2.2.2.3 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_int.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* Stuff private to the PDO extension and not for consumption by PDO drivers * */ diff --git a/ext/pdo/tests/pdo.inc b/ext/pdo/tests/pdo.inc index 9bf6d5974..8089236bb 100755 --- a/ext/pdo/tests/pdo.inc +++ b/ext/pdo/tests/pdo.inc @@ -1,10 +1,10 @@ - + diff --git a/ext/pdo/tests/pdo_036.phpt b/ext/pdo/tests/pdo_036.phpt new file mode 100644 index 000000000..6bd38cb06 --- /dev/null +++ b/ext/pdo/tests/pdo_036.phpt @@ -0,0 +1,21 @@ +--TEST-- +Testing PDORow and PDOStatement instances with Reflection +--FILE-- +newInstance(); +var_dump($x); + +$instance = new reflectionclass('pdostatement'); +$x = $instance->newInstance(); +var_dump($x); + +?> +--EXPECTF-- +object(PDORow)#%d (0) { +} +object(PDOStatement)#%d (1) { + [%u|b%"queryString"]=> + NULL +} diff --git a/ext/pdo_dblib/config.m4 b/ext/pdo_dblib/config.m4 index 0e6e0777c..657da6263 100644 --- a/ext/pdo_dblib/config.m4 +++ b/ext/pdo_dblib/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.2.2.2.2.1.2.2 2008/10/04 12:52:58 felipe Exp $ +dnl $Id: config.m4 266959 2008-10-04 12:52:58Z felipe $ dnl PHP_ARG_WITH(pdo-dblib, for PDO_DBLIB support via FreeTDS, diff --git a/ext/pdo_dblib/config.w32 b/ext/pdo_dblib/config.w32 index 48302c837..0245bd5fd 100755 --- a/ext/pdo_dblib/config.w32 +++ b/ext/pdo_dblib/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.7.4.1.2.1 2009/05/19 10:22:25 kalle Exp $ +// $Id: config.w32 280765 2009-05-19 10:22:25Z kalle $ // vim:ft=javascript ARG_WITH("pdo-dblib", "freetds dblib (Sybase, MS-SQL) support for PDO", "no"); diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index 025486471..7234c2bc1 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dblib_driver.c,v 1.9.2.2.2.2.2.4 2009/06/29 09:36:03 johannes Exp $ */ +/* $Id: dblib_driver.c 289440 2009-10-09 18:56:19Z pajoye $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -230,11 +230,11 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ goto cleanup; } -#if PHP_DBLIB_IS_MSSQL - if (DBSETOPT(H->link, DBTEXTLIMIT, "2147483647") == FAIL) { - goto cleanup; - } -#endif + /* dblib do not return more than this length from text/image */ + DBSETOPT(H->link, DBTEXTLIMIT, "2147483647"); + + /* limit text/image from network */ + DBSETOPT(H->link, DBTEXTSIZE, "2147483647"); if (vars[3].optval && FAIL == dbuse(H->link, vars[3].optval)) { goto cleanup; diff --git a/ext/pdo_dblib/dblib_stmt.c b/ext/pdo_dblib/dblib_stmt.c index ec1222a77..0080b30aa 100644 --- a/ext/pdo_dblib/dblib_stmt.c +++ b/ext/pdo_dblib/dblib_stmt.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dblib_stmt.c,v 1.6.2.2.2.4.2.3 2009/03/19 22:16:29 sfox Exp $ */ +/* $Id: dblib_stmt.c 277492 2009-03-19 22:16:29Z sfox $ */ #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/ext/pdo_dblib/pdo_dblib.c b/ext/pdo_dblib/pdo_dblib.c index dab0588bb..73cf49b6b 100644 --- a/ext/pdo_dblib/pdo_dblib.c +++ b/ext/pdo_dblib/pdo_dblib.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_dblib.c,v 1.9.2.6.2.3.2.5 2009/05/20 10:18:51 kalle Exp $ */ +/* $Id: pdo_dblib.c 280855 2009-05-20 10:18:51Z kalle $ */ #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/ext/pdo_dblib/php_pdo_dblib.h b/ext/pdo_dblib/php_pdo_dblib.h index 20219c64b..f2096c764 100644 --- a/ext/pdo_dblib/php_pdo_dblib.h +++ b/ext/pdo_dblib/php_pdo_dblib.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_dblib.h,v 1.2.2.1.2.1.2.4 2009/05/19 10:22:25 kalle Exp $ */ +/* $Id: php_pdo_dblib.h 280765 2009-05-19 10:22:25Z kalle $ */ #ifndef PHP_PDO_DBLIB_H #define PHP_PDO_DBLIB_H diff --git a/ext/pdo_dblib/php_pdo_dblib_int.h b/ext/pdo_dblib/php_pdo_dblib_int.h index e47c4a8d5..518787b7c 100644 --- a/ext/pdo_dblib/php_pdo_dblib_int.h +++ b/ext/pdo_dblib/php_pdo_dblib_int.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_dblib_int.h,v 1.4.2.1.2.1.2.2 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_dblib_int.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PDO_DBLIB_INT_H #define PHP_PDO_DBLIB_INT_H diff --git a/ext/pdo_firebird/config.m4 b/ext/pdo_firebird/config.m4 index 5ac1084c3..e30b4b452 100644 --- a/ext/pdo_firebird/config.m4 +++ b/ext/pdo_firebird/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.8.4.2.2.2 2009/05/23 13:52:00 nlopess Exp $ +dnl $Id: config.m4 280986 2009-05-23 13:52:00Z nlopess $ dnl PHP_ARG_WITH(pdo-firebird,for Firebird support for PDO, diff --git a/ext/pdo_firebird/config.w32 b/ext/pdo_firebird/config.w32 index 833b7b95f..82ddf062f 100644 --- a/ext/pdo_firebird/config.w32 +++ b/ext/pdo_firebird/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.6.4.1 2006/05/11 21:43:59 edink Exp $ +// $Id: config.w32 212867 2006-05-11 21:43:59Z edink $ // vim:ft=javascript ARG_WITH("pdo-firebird", "Firebird support for PDO", "no"); diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c index 232ae740a..b099d317c 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: firebird_driver.c,v 1.17.2.2.2.4.2.8 2009/04/18 18:56:11 felipe Exp $ */ +/* $Id: firebird_driver.c 278929 2009-04-18 18:56:11Z felipe $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo_firebird/firebird_statement.c b/ext/pdo_firebird/firebird_statement.c index 16ff7ca30..b58b756b5 100644 --- a/ext/pdo_firebird/firebird_statement.c +++ b/ext/pdo_firebird/firebird_statement.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: firebird_statement.c,v 1.18.2.1.2.5.2.11 2009/02/09 12:07:23 felipe Exp $ */ +/* $Id: firebird_statement.c 284404 2009-07-20 00:17:24Z felipe $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -363,7 +363,8 @@ static int firebird_stmt_get_col(pdo_stmt_t *stmt, int colno, char **ptr, /* {{ fmt = S->H->timestamp_format ? S->H->timestamp_format : PDO_FB_DEF_TIMESTAMP_FMT; } /* convert the timestamp into a string */ - *ptr = FETCH_BUF(S->fetch_buf[colno], char, *len = 80, NULL); + *len = 80; + *ptr = FETCH_BUF(S->fetch_buf[colno], char, *len, NULL); *len = strftime(*ptr, *len, fmt, &t); break; case SQL_BLOB: diff --git a/ext/pdo_firebird/pdo_firebird.c b/ext/pdo_firebird/pdo_firebird.c index 75aa707a1..7f6364990 100644 --- a/ext/pdo_firebird/pdo_firebird.c +++ b/ext/pdo_firebird/pdo_firebird.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_firebird.c,v 1.4.2.3.2.1.2.4 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: pdo_firebird.c 284399 2009-07-19 23:33:50Z felipe $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -35,8 +35,23 @@ const zend_function_entry pdo_firebird_functions[] = { /* {{{ */ }; /* }}} */ +/* {{{ pdo_firebird_deps + */ +#if ZEND_MODULE_API_NO >= 20050922 +static const zend_module_dep pdo_firebird_deps[] = { + ZEND_MOD_REQUIRED("pdo") + {NULL, NULL, NULL} +}; +#endif +/* }}} */ + zend_module_entry pdo_firebird_module_entry = { /* {{{ */ +#if ZEND_MODULE_API_NO >= 20050922 + STANDARD_MODULE_HEADER_EX, NULL, + pdo_firebird_deps, +#else STANDARD_MODULE_HEADER, +#endif "PDO_Firebird", pdo_firebird_functions, PHP_MINIT(pdo_firebird), diff --git a/ext/pdo_firebird/php_pdo_firebird.h b/ext/pdo_firebird/php_pdo_firebird.h index c068f81a5..4797cc624 100644 --- a/ext/pdo_firebird/php_pdo_firebird.h +++ b/ext/pdo_firebird/php_pdo_firebird.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_firebird.h,v 1.3.2.1.2.1.2.3 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_firebird.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PDO_FIREBIRD_H #define PHP_PDO_FIREBIRD_H diff --git a/ext/pdo_firebird/php_pdo_firebird_int.h b/ext/pdo_firebird/php_pdo_firebird_int.h index bd9fa2d64..485a86250 100644 --- a/ext/pdo_firebird/php_pdo_firebird_int.h +++ b/ext/pdo_firebird/php_pdo_firebird_int.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_firebird_int.h,v 1.10.2.1.2.1.2.5 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_firebird_int.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PDO_FIREBIRD_INT_H #define PHP_PDO_FIREBIRD_INT_H diff --git a/ext/pdo_firebird/tests/connect.phpt b/ext/pdo_firebird/tests/connect.phpt index c33cb1f66..ef78a1988 100644 --- a/ext/pdo_firebird/tests/connect.phpt +++ b/ext/pdo_firebird/tests/connect.phpt @@ -3,7 +3,7 @@ PDO_Firebird: connect/disconnect --SKIPIF-- --FILE-- - --FILE-- -buffered = pdo_attr_lval(driver_options, PDO_MYSQL_ATTR_USE_BUFFERED_QUERY, 1 TSRMLS_CC); @@ -671,7 +671,6 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ mysql_options(H->server, MYSQL_OPT_RECONNECT, (const char*)&reconnect); } #endif -#ifndef PDO_USE_MYSQLND init_cmd = pdo_attr_strval(driver_options, PDO_MYSQL_ATTR_INIT_COMMAND, NULL TSRMLS_CC); if (init_cmd) { if (mysql_options(H->server, MYSQL_INIT_COMMAND, (const char *)init_cmd)) { @@ -681,7 +680,7 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options TSRMLS_ } efree(init_cmd); } - +#ifndef PDO_USE_MYSQLND default_file = pdo_attr_strval(driver_options, PDO_MYSQL_ATTR_READ_DEFAULT_FILE, NULL TSRMLS_CC); if (default_file) { if (mysql_options(H->server, MYSQL_READ_DEFAULT_FILE, (const char *)default_file)) { diff --git a/ext/pdo_mysql/mysql_statement.c b/ext/pdo_mysql/mysql_statement.c index 9ef009c5d..6899dd77a 100755 --- a/ext/pdo_mysql/mysql_statement.c +++ b/ext/pdo_mysql/mysql_statement.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mysql_statement.c,v 1.48.2.14.2.6.2.5 2009/05/20 08:30:12 kalle Exp $ */ +/* $Id: mysql_statement.c 280838 2009-05-20 08:30:12Z kalle $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo_mysql/pdo_mysql.c b/ext/pdo_mysql/pdo_mysql.c index b5875e0a5..44719fd79 100755 --- a/ext/pdo_mysql/pdo_mysql.c +++ b/ext/pdo_mysql/pdo_mysql.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_mysql.c,v 1.8.2.13.2.1.2.8 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: pdo_mysql.c 289630 2009-10-14 13:51:25Z johannes $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -75,9 +75,9 @@ static PHP_MINIT_FUNCTION(pdo_mysql) REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_USE_BUFFERED_QUERY", (long)PDO_MYSQL_ATTR_USE_BUFFERED_QUERY); REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_LOCAL_INFILE", (long)PDO_MYSQL_ATTR_LOCAL_INFILE); + REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_INIT_COMMAND", (long)PDO_MYSQL_ATTR_INIT_COMMAND); #ifndef PDO_USE_MYSQLND REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_MAX_BUFFER_SIZE", (long)PDO_MYSQL_ATTR_MAX_BUFFER_SIZE); - REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_INIT_COMMAND", (long)PDO_MYSQL_ATTR_INIT_COMMAND); REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_READ_DEFAULT_FILE", (long)PDO_MYSQL_ATTR_READ_DEFAULT_FILE); REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_READ_DEFAULT_GROUP", (long)PDO_MYSQL_ATTR_READ_DEFAULT_GROUP); REGISTER_PDO_CLASS_CONST_LONG("MYSQL_ATTR_COMPRESS", (long)PDO_MYSQL_ATTR_COMPRESS); diff --git a/ext/pdo_mysql/php_pdo_mysql.h b/ext/pdo_mysql/php_pdo_mysql.h index 19a5b3843..6adfbf095 100755 --- a/ext/pdo_mysql/php_pdo_mysql.h +++ b/ext/pdo_mysql/php_pdo_mysql.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_mysql.h,v 1.3.2.1.2.1.2.4 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_mysql.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PDO_MYSQL_H #define PHP_PDO_MYSQL_H diff --git a/ext/pdo_mysql/php_pdo_mysql_int.h b/ext/pdo_mysql/php_pdo_mysql_int.h index 32a292ca3..ac0a97394 100755 --- a/ext/pdo_mysql/php_pdo_mysql_int.h +++ b/ext/pdo_mysql/php_pdo_mysql_int.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_mysql_int.h,v 1.16.2.4.2.1.2.6 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_mysql_int.h 289630 2009-10-14 13:51:25Z johannes $ */ #ifndef PHP_PDO_MYSQL_INT_H #define PHP_PDO_MYSQL_INT_H @@ -153,8 +153,8 @@ extern struct pdo_stmt_methods mysql_stmt_methods; enum { PDO_MYSQL_ATTR_USE_BUFFERED_QUERY = PDO_ATTR_DRIVER_SPECIFIC, PDO_MYSQL_ATTR_LOCAL_INFILE, -#ifndef PDO_USE_MYSQLND PDO_MYSQL_ATTR_INIT_COMMAND, +#ifndef PDO_USE_MYSQLND PDO_MYSQL_ATTR_READ_DEFAULT_FILE, PDO_MYSQL_ATTR_READ_DEFAULT_GROUP, PDO_MYSQL_ATTR_MAX_BUFFER_SIZE, diff --git a/ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt b/ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt index fb955ac2a..8d086b7cc 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_attr_init_command.phpt @@ -6,8 +6,6 @@ require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'skipif.inc'); require_once(dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mysql_pdo_test.inc'); MySQLPDOTest::skip(); $db = MySQLPDOTest::factory(); -if (MySQLPDOTest::isPDOMySQLnd()) - die("skip PDO::MYSQL_ATTR_MAX_INIT_COMMAND not supported with mysqlnd"); ?> --INI-- error_reporting=E_ALL @@ -27,7 +25,8 @@ error_reporting=E_ALL var_dump($create); $db = new PDO($dsn, $user, $pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => $create)); - var_dump($db->errorInfo()); + $info = $db->errorInfo(); + var_dump($info[0]); $db->exec(sprintf('INSERT INTO %s(id) VALUES (1)', $table)); $stmt = $db->query(sprintf('SELECT id FROM %s', $table)); @@ -35,22 +34,14 @@ error_reporting=E_ALL $db->exec(sprintf('DROP TABLE IF EXISTS %s', $table)); print "done!\n"; -?> --EXPECTF-- -string(58) "CREATE TABLE test_%s(id INT)" -array(3) { - [0]=> - string(5) "00000" - [1]=> - NULL - [2]=> - NULL -} +%unicode|string%(58) "CREATE TABLE test_%s(id INT)" +%unicode|string%(5) "00000" array(1) { [0]=> array(1) { - ["id"]=> - string(1) "1" + [%u|b%"id"]=> + %unicode|string%(1) "1" } } done! diff --git a/ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt b/ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt index eac6bf331..a8cbde6ea 100644 --- a/ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt +++ b/ext/pdo_mysql/tests/pdo_mysql_fetch_both.phpt @@ -49,7 +49,7 @@ $db = MySQLPDOTest::factory(); try { - fetch(2, &$db, 'SELECT 1', array(0 => '1', '1' => '1')); + fetch(2, $db, 'SELECT 1', array(0 => '1', '1' => '1')); } catch (PDOException $e) { printf("[001] %s [%s] %s\n", diff --git a/ext/pdo_oci/config.m4 b/ext/pdo_oci/config.m4 index 1067f7d69..ebe68a85a 100755 --- a/ext/pdo_oci/config.m4 +++ b/ext/pdo_oci/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.14.2.5.2.6.2.5 2008/10/22 19:29:24 stas Exp $ +dnl $Id: config.m4 267636 2008-10-22 19:29:24Z stas $ dnl config.m4 for extension pdo_oci dnl vim:et:sw=2:ts=2: diff --git a/ext/pdo_oci/config.w32 b/ext/pdo_oci/config.w32 index fe5e826c9..10bbbf8f8 100755 --- a/ext/pdo_oci/config.w32 +++ b/ext/pdo_oci/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.6.4.1.2.2 2008/08/01 19:09:47 pajoye Exp $ +// $Id: config.w32 264051 2008-08-01 19:09:47Z pajoye $ // vim:ft=javascript ARG_WITH("pdo-oci", "Oracle OCI support for PDO", "no"); diff --git a/ext/pdo_oci/oci_driver.c b/ext/pdo_oci/oci_driver.c index a3812c101..a862857d1 100755 --- a/ext/pdo_oci/oci_driver.c +++ b/ext/pdo_oci/oci_driver.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: oci_driver.c,v 1.24.2.4.2.7.2.5 2009/05/12 21:53:18 mbeccati Exp $ */ +/* $Id: oci_driver.c 280403 2009-05-12 21:53:18Z mbeccati $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo_oci/oci_statement.c b/ext/pdo_oci/oci_statement.c index 1ced8afd7..62d4f9a70 100755 --- a/ext/pdo_oci/oci_statement.c +++ b/ext/pdo_oci/oci_statement.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: oci_statement.c,v 1.16.2.10.2.7.2.4 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: oci_statement.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo_oci/pdo_oci.c b/ext/pdo_oci/pdo_oci.c index b8f99c69c..39efda4b2 100755 --- a/ext/pdo_oci/pdo_oci.c +++ b/ext/pdo_oci/pdo_oci.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_oci.c,v 1.5.2.6.2.1.2.3 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: pdo_oci.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo_oci/php_pdo_oci.h b/ext/pdo_oci/php_pdo_oci.h index 3dcfc4454..e638ca602 100755 --- a/ext/pdo_oci/php_pdo_oci.h +++ b/ext/pdo_oci/php_pdo_oci.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_oci.h,v 1.2.2.1.2.1.2.3 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_oci.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PDO_OCI_H #define PHP_PDO_OCI_H diff --git a/ext/pdo_oci/php_pdo_oci_int.h b/ext/pdo_oci/php_pdo_oci_int.h index 48847ec87..671c135d1 100755 --- a/ext/pdo_oci/php_pdo_oci_int.h +++ b/ext/pdo_oci/php_pdo_oci_int.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_oci_int.h,v 1.4.2.2.2.4.2.2 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_oci_int.h 272370 2008-12-31 11:15:49Z sebastian $ */ #include diff --git a/ext/pdo_oci/tests/bug41996.phpt b/ext/pdo_oci/tests/bug41996.phpt index ee015a6da..d1a4cfc6e 100644 --- a/ext/pdo_oci/tests/bug41996.phpt +++ b/ext/pdo_oci/tests/bug41996.phpt @@ -2,7 +2,7 @@ PDO OCI Bug #41996 (Problem accessing Oracle ROWID) --SKIPIF-- einfo.last_err_msg, "Unknown Attribute"); H->einfo.what = "setAttribute"; - strcpy(H->einfo.last_state, "IM0001"); + strcpy(H->einfo.last_state, "IM001"); return -1; } } diff --git a/ext/pdo_odbc/odbc_stmt.c b/ext/pdo_odbc/odbc_stmt.c index 89fa5c67a..d650b6fdd 100755 --- a/ext/pdo_odbc/odbc_stmt.c +++ b/ext/pdo_odbc/odbc_stmt.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: odbc_stmt.c,v 1.26.2.2.2.3.2.5 2009/05/19 10:25:53 kalle Exp $ */ +/* $Id: odbc_stmt.c 284097 2009-07-15 02:32:43Z felipe $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -763,7 +763,7 @@ static int odbc_stmt_set_param(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC) default: strcpy(S->einfo.last_err_msg, "Unknown Attribute"); S->einfo.what = "setAttribute"; - strcpy(S->einfo.last_state, "IM0001"); + strcpy(S->einfo.last_state, "IM001"); return -1; } } @@ -795,7 +795,7 @@ static int odbc_stmt_get_attr(pdo_stmt_t *stmt, long attr, zval *val TSRMLS_DC) default: strcpy(S->einfo.last_err_msg, "Unknown Attribute"); S->einfo.what = "getAttribute"; - strcpy(S->einfo.last_state, "IM0001"); + strcpy(S->einfo.last_state, "IM001"); return -1; } } diff --git a/ext/pdo_odbc/pdo_odbc.c b/ext/pdo_odbc/pdo_odbc.c index 29f290993..698fced89 100755 --- a/ext/pdo_odbc/pdo_odbc.c +++ b/ext/pdo_odbc/pdo_odbc.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_odbc.c,v 1.14.2.7.2.2.2.4 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: pdo_odbc.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo_odbc/php_pdo_odbc.h b/ext/pdo_odbc/php_pdo_odbc.h index 358f4872d..75247567f 100644 --- a/ext/pdo_odbc/php_pdo_odbc.h +++ b/ext/pdo_odbc/php_pdo_odbc.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_odbc.h,v 1.2.4.3.2.3 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_odbc.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PDO_ODBC_H #define PHP_PDO_ODBC_H diff --git a/ext/pdo_odbc/php_pdo_odbc_int.h b/ext/pdo_odbc/php_pdo_odbc_int.h index b2e4dcc3a..550c4ff73 100755 --- a/ext/pdo_odbc/php_pdo_odbc_int.h +++ b/ext/pdo_odbc/php_pdo_odbc_int.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_odbc_int.h,v 1.9.2.1.2.2.2.3 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_odbc_int.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef PHP_WIN32 # define PDO_ODBC_TYPE "Win32" diff --git a/ext/pdo_pgsql/config.m4 b/ext/pdo_pgsql/config.m4 index 4e59b77f5..8e55524f5 100644 --- a/ext/pdo_pgsql/config.m4 +++ b/ext/pdo_pgsql/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.13.4.6.2.2 2009/04/30 12:38:43 mbeccati Exp $ +dnl $Id: config.m4 279602 2009-04-30 12:38:43Z mbeccati $ dnl config.m4 for extension pdo_pgsql dnl vim:et:sw=2:ts=2: diff --git a/ext/pdo_pgsql/config.w32 b/ext/pdo_pgsql/config.w32 index f14107b68..db6b15ae5 100644 --- a/ext/pdo_pgsql/config.w32 +++ b/ext/pdo_pgsql/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.4.2.1.2.3.2.5 2009/04/30 12:56:00 mbeccati Exp $ +// $Id: config.w32 279604 2009-04-30 12:56:00Z mbeccati $ // vim:ft=javascript ARG_WITH("pdo-pgsql", "PostgreSQL support for PDO", "no"); diff --git a/ext/pdo_pgsql/pdo_pgsql.c b/ext/pdo_pgsql/pdo_pgsql.c index 2e4e820d0..40856557c 100644 --- a/ext/pdo_pgsql/pdo_pgsql.c +++ b/ext/pdo_pgsql/pdo_pgsql.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_pgsql.c,v 1.7.2.11.2.1.2.4 2009/03/28 01:58:49 mbeccati Exp $ */ +/* $Id: pdo_pgsql.c 277898 2009-03-28 01:58:49Z mbeccati $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -128,7 +128,7 @@ PHP_MINFO_FUNCTION(pdo_pgsql) php_info_print_table_row(2, "PostgreSQL(libpq) Version", PG_VERSION); #endif php_info_print_table_row(2, "Module version", pdo_pgsql_module_entry.version); - php_info_print_table_row(2, "Revision", " $Id: pdo_pgsql.c,v 1.7.2.11.2.1.2.4 2009/03/28 01:58:49 mbeccati Exp $ "); + php_info_print_table_row(2, "Revision", " $Id: pdo_pgsql.c 277898 2009-03-28 01:58:49Z mbeccati $ "); php_info_print_table_end(); } diff --git a/ext/pdo_pgsql/pgsql_driver.c b/ext/pdo_pgsql/pgsql_driver.c index 91f8d7754..ef720cdac 100644 --- a/ext/pdo_pgsql/pgsql_driver.c +++ b/ext/pdo_pgsql/pgsql_driver.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pgsql_driver.c,v 1.53.2.14.2.9.2.8 2009/04/30 12:56:00 mbeccati Exp $ */ +/* $Id: pgsql_driver.c 279604 2009-04-30 12:56:00Z mbeccati $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo_pgsql/pgsql_statement.c b/ext/pdo_pgsql/pgsql_statement.c index d35af9aa0..85ae91367 100644 --- a/ext/pdo_pgsql/pgsql_statement.c +++ b/ext/pdo_pgsql/pgsql_statement.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pgsql_statement.c,v 1.31.2.12.2.7.2.13 2009/05/25 19:41:13 kalle Exp $ */ +/* $Id: pgsql_statement.c 281107 2009-05-25 19:41:13Z kalle $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo_pgsql/php_pdo_pgsql.h b/ext/pdo_pgsql/php_pdo_pgsql.h index 2adc12995..1760d61b4 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql.h +++ b/ext/pdo_pgsql/php_pdo_pgsql.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_pgsql.h,v 1.3.2.1.2.1.2.3 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_pgsql.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PDO_PGSQL_H #define PHP_PDO_PGSQL_H diff --git a/ext/pdo_pgsql/php_pdo_pgsql_int.h b/ext/pdo_pgsql/php_pdo_pgsql_int.h index 2c080c112..fb0a95ec3 100644 --- a/ext/pdo_pgsql/php_pdo_pgsql_int.h +++ b/ext/pdo_pgsql/php_pdo_pgsql_int.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_pgsql_int.h,v 1.13.2.4.2.1.2.4 2009/05/12 22:18:14 mbeccati Exp $ */ +/* $Id: php_pdo_pgsql_int.h 280407 2009-05-12 22:18:15Z mbeccati $ */ #ifndef PHP_PDO_PGSQL_INT_H #define PHP_PDO_PGSQL_INT_H diff --git a/ext/pdo_sqlite/config.m4 b/ext/pdo_sqlite/config.m4 index 9158d2cb5..1735f0f47 100644 --- a/ext/pdo_sqlite/config.m4 +++ b/ext/pdo_sqlite/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.26.2.9.2.7.2.8 2009/01/13 02:50:54 scottmac Exp $ +dnl $Id: config.m4 273413 2009-01-13 02:50:54Z scottmac $ dnl config.m4 for extension pdo_sqlite dnl vim:et:sw=2:ts=2: diff --git a/ext/pdo_sqlite/config.w32 b/ext/pdo_sqlite/config.w32 index b21a1ed0c..d1f159d4e 100644 --- a/ext/pdo_sqlite/config.w32 +++ b/ext/pdo_sqlite/config.w32 @@ -1,10 +1,10 @@ -// $Id: config.w32,v 1.6.2.1.2.3.2.8 2008/08/06 16:56:35 auroraeosrose Exp $ +// $Id: config.w32 287047 2009-08-10 16:58:53Z kalle $ // vim:ft=javascript ARG_WITH("pdo-sqlite", "for pdo_sqlite support", "no"); if (PHP_PDO_SQLITE != "no") { - EXTENSION("pdo_sqlite", "pdo_sqlite.c sqlite_driver.c sqlite_statement.c", null, "/DSQLITE_THREADSAFE=1 /I" + configure_module_dirname + "/../sqlite3/libsqlite /I" + configure_module_dirname); + EXTENSION("pdo_sqlite", "pdo_sqlite.c sqlite_driver.c sqlite_statement.c", null, "/DSQLITE_THREADSAFE=" + (PHP_ZTS == "yes" ? "1" : "0") + " /I" + configure_module_dirname + "/../sqlite3/libsqlite /I" + configure_module_dirname); ADD_EXTENSION_DEP('pdo_sqlite', 'pdo'); // If pdo_sqlite is static, and sqlite3 is also static, then we don't add a second copy of the sqlite3 libs diff --git a/ext/pdo_sqlite/pdo_sqlite.c b/ext/pdo_sqlite/pdo_sqlite.c index 6ec30089c..ba2b697f8 100644 --- a/ext/pdo_sqlite/pdo_sqlite.c +++ b/ext/pdo_sqlite/pdo_sqlite.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_sqlite.c,v 1.10.2.6.2.2.2.4 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: pdo_sqlite.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo_sqlite/php_pdo_sqlite.h b/ext/pdo_sqlite/php_pdo_sqlite.h index b3aeaad20..36bbb93a9 100644 --- a/ext/pdo_sqlite/php_pdo_sqlite.h +++ b/ext/pdo_sqlite/php_pdo_sqlite.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_sqlite.h,v 1.2.2.1.2.1.2.3 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_sqlite.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PDO_SQLITE_H diff --git a/ext/pdo_sqlite/php_pdo_sqlite_int.h b/ext/pdo_sqlite/php_pdo_sqlite_int.h index eaabe75a3..4deb99652 100644 --- a/ext/pdo_sqlite/php_pdo_sqlite_int.h +++ b/ext/pdo_sqlite/php_pdo_sqlite_int.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pdo_sqlite_int.h,v 1.3.2.1.2.1.2.2 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pdo_sqlite_int.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PDO_SQLITE_INT_H #define PHP_PDO_SQLITE_INT_H diff --git a/ext/pdo_sqlite/sqlite_driver.c b/ext/pdo_sqlite/sqlite_driver.c index c18ecb7cf..f16e17e06 100644 --- a/ext/pdo_sqlite/sqlite_driver.c +++ b/ext/pdo_sqlite/sqlite_driver.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sqlite_driver.c,v 1.20.2.5.2.2.2.6 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: sqlite_driver.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo_sqlite/sqlite_statement.c b/ext/pdo_sqlite/sqlite_statement.c index 54579e827..d8e5049df 100644 --- a/ext/pdo_sqlite/sqlite_statement.c +++ b/ext/pdo_sqlite/sqlite_statement.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sqlite_statement.c,v 1.18.2.4.2.3.2.10 2009/05/20 15:05:36 iliaa Exp $ */ +/* $Id: sqlite_statement.c 280873 2009-05-20 15:05:36Z iliaa $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/pdo_sqlite/tests/bug48773.phpt b/ext/pdo_sqlite/tests/bug48773.phpt new file mode 100644 index 000000000..b8bdea918 --- /dev/null +++ b/ext/pdo_sqlite/tests/bug48773.phpt @@ -0,0 +1,34 @@ +--TEST-- +Bug #48773 (Incorrect error when setting PDO::ATTR_STATEMENT_CLASS with ctor_args) +--SKIPIF-- + +--FILE-- +setAttribute(PDO::ATTR_STATEMENT_CLASS, array($this->statementClass, array($this))); + } +} + +$db = new foo('sqlite::memory:', '', ''); +$stmt = $db->query('SELECT 1'); +var_dump($stmt); + +?> +--EXPECTF-- +object(bar)#%d (1) { + [%u|b%"queryString"]=> + %unicode|string%(8) "SELECT 1" +} diff --git a/ext/pgsql/config.m4 b/ext/pgsql/config.m4 index 4584567ae..f78aa0d66 100644 --- a/ext/pgsql/config.m4 +++ b/ext/pgsql/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.46.2.1.2.5.2.2 2008/07/23 21:44:25 hholzgra Exp $ +dnl $Id: config.m4 263340 2008-07-23 21:44:25Z hholzgra $ dnl PHP_ARG_WITH(pgsql,for PostgreSQL support, diff --git a/ext/pgsql/config.w32 b/ext/pgsql/config.w32 index e877684d6..6cf41f7da 100644 --- a/ext/pgsql/config.w32 +++ b/ext/pgsql/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.7.4.5.2.2 2009/05/11 10:44:12 pajoye Exp $ +// $Id: config.w32 280344 2009-05-11 10:44:12Z pajoye $ // vim:ft=javascript ARG_WITH("pgsql", "PostgreSQL support", "no"); diff --git a/ext/pgsql/pgsql.c b/ext/pgsql/pgsql.c index 32bcbb911..c8cf494e3 100644 --- a/ext/pgsql/pgsql.c +++ b/ext/pgsql/pgsql.c @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pgsql.c,v 1.331.2.13.2.24.2.28 2009/05/19 16:03:36 kalle Exp $ */ +/* $Id: pgsql.c 280789 2009-05-19 16:03:36Z kalle $ */ #include diff --git a/ext/pgsql/php_pgsql.h b/ext/pgsql/php_pgsql.h index f016c51ea..efc804098 100644 --- a/ext/pgsql/php_pgsql.h +++ b/ext/pgsql/php_pgsql.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pgsql.h,v 1.73.2.1.2.2.2.3 2008/12/31 11:15:41 sebastian Exp $ */ +/* $Id: php_pgsql.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PGSQL_H #define PHP_PGSQL_H diff --git a/ext/phar/Makefile.frag b/ext/phar/Makefile.frag index 554bc0cdf..076ce8a93 100755 --- a/ext/phar/Makefile.frag +++ b/ext/phar/Makefile.frag @@ -37,10 +37,11 @@ $(builddir)/phar.phar: $(builddir)/phar.php $(builddir)/phar/phar.inc $(srcdir)/ -@echo "Generating phar.phar" -@rm -f $(builddir)/phar.phar -@rm -f $(srcdir)/phar.phar - @$(PHP_PHARCMD_EXECUTABLE) $(PHP_PHARCMD_SETTINGS) $(builddir)/phar.php pack -f $(builddir)/phar.phar -a pharcommand -c auto -x CVS -p 0 -s $(srcdir)/phar/phar.php -h sha1 -b "$(PHP_PHARCMD_BANG)" $(srcdir)/phar/ + @$(PHP_PHARCMD_EXECUTABLE) $(PHP_PHARCMD_SETTINGS) $(builddir)/phar.php pack -f $(builddir)/phar.phar -a pharcommand -c auto -x \\.svn -p 0 -s $(srcdir)/phar/phar.php -h sha1 -b "$(PHP_PHARCMD_BANG)" $(srcdir)/phar/ -@chmod +x $(builddir)/phar.phar install-pharcmd: pharcmd -@$(mkinstalldirs) $(INSTALL_ROOT)$(bindir) $(INSTALL) $(builddir)/phar.phar $(INSTALL_ROOT)$(bindir) - $(LN_S) -f $(INSTALL_ROOT)$(bindir)/phar.phar $(INSTALL_ROOT)$(bindir)/phar + -@rm -f $(INSTALL_ROOT)$(bindir)/phar + $(LN_S) -f $(bindir)/phar.phar $(INSTALL_ROOT)$(bindir)/phar diff --git a/ext/phar/config.m4 b/ext/phar/config.m4 index 42b55bb1b..70b03a2c9 100644 --- a/ext/phar/config.m4 +++ b/ext/phar/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.27.2.13 2009/02/16 16:41:40 cellog Exp $ +dnl $Id: config.m4 275933 2009-02-16 16:41:40Z cellog $ dnl config.m4 for extension phar PHP_ARG_ENABLE(phar, for phar archive support, diff --git a/ext/phar/config.w32 b/ext/phar/config.w32 index c61ed6cfa..c117cc147 100644 --- a/ext/phar/config.w32 +++ b/ext/phar/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.27.2.10 2009/05/11 06:43:05 kalle Exp $ +// $Id: config.w32 280331 2009-05-11 06:43:05Z kalle $ // vim:ft=javascript ARG_ENABLE("phar", "disable phar support", "yes"); diff --git a/ext/phar/dirstream.c b/ext/phar/dirstream.c index f466b4a13..c1758d420 100644 --- a/ext/phar/dirstream.c +++ b/ext/phar/dirstream.c @@ -112,11 +112,13 @@ static size_t phar_dir_read(php_stream *stream, char *buf, size_t count TSRMLS_D to_read = MIN(keylen, count); if (to_read == 0 || count < keylen) { + PHAR_STR_FREE(str_key); return 0; } memset(buf, 0, sizeof(php_stream_dirent)); memcpy(((php_stream_dirent *) buf)->d_name, str_key, to_read); + PHAR_STR_FREE(str_key); ((php_stream_dirent *) buf)->d_name[to_read + 1] = '\0'; return sizeof(php_stream_dirent); @@ -217,6 +219,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) if (keylen <= (uint)dirlen) { if (keylen < (uint)dirlen || !strncmp(str_key, dir, dirlen)) { + PHAR_STR_FREE(str_key); if (SUCCESS != zend_hash_move_forward(manifest)) { break; } @@ -227,6 +230,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) if (*dir == '/') { /* root directory */ if (keylen >= sizeof(".phar")-1 && !memcmp(str_key, ".phar", sizeof(".phar")-1)) { + PHAR_STR_FREE(str_key); /* do not add any magic entries to this directory */ if (SUCCESS != zend_hash_move_forward(manifest)) { break; @@ -246,16 +250,19 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) entry[keylen] = '\0'; } + PHAR_STR_FREE(str_key); goto PHAR_ADD_ENTRY; } else { if (0 != memcmp(str_key, dir, dirlen)) { /* entry in directory not found */ + PHAR_STR_FREE(str_key); if (SUCCESS != zend_hash_move_forward(manifest)) { break; } continue; } else { if (str_key[dirlen] != '/') { + PHAR_STR_FREE(str_key); if (SUCCESS != zend_hash_move_forward(manifest)) { break; } @@ -282,6 +289,7 @@ static php_stream *phar_make_dirstream(char *dir, HashTable *manifest TSRMLS_DC) entry[keylen - dirlen - 1] = '\0'; keylen = keylen - dirlen - 1; } + PHAR_STR_FREE(str_key); PHAR_ADD_ENTRY: if (keylen) { phar_add_empty(data, entry, keylen); @@ -400,12 +408,14 @@ php_stream *phar_wrapper_open_dir(php_stream_wrapper *wrapper, char *path, char &phar->manifest, &key, &keylen, &unused, 0, NULL)) { PHAR_STR(key, str_key); if (keylen > (uint)i_len && 0 == memcmp(str_key, internal_file, i_len)) { + PHAR_STR_FREE(str_key); /* directory found */ internal_file = estrndup(internal_file, i_len); php_url_free(resource); return phar_make_dirstream(internal_file, &phar->manifest TSRMLS_CC); } + PHAR_STR_FREE(str_key); } if (SUCCESS != zend_hash_move_forward(&phar->manifest)) { @@ -635,6 +645,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_ if (key_len > path_len && memcmp(str_key, resource->path+1, path_len) == 0 && IS_SLASH(str_key[path_len])) { + PHAR_STR_FREE(str_key); php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty"); if (entry->is_temp_dir) { efree(entry->filename); @@ -643,6 +654,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_ php_url_free(resource); return 0; } + PHAR_STR_FREE(str_key); } for (zend_hash_internal_pointer_reset(&phar->virtual_dirs); @@ -654,6 +666,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_ if (key_len > path_len && memcmp(str_key, resource->path+1, path_len) == 0 && IS_SLASH(str_key[path_len])) { + PHAR_STR_FREE(str_key); php_stream_wrapper_log_error(wrapper, options TSRMLS_CC, "phar error: Directory not empty"); if (entry->is_temp_dir) { efree(entry->filename); @@ -662,6 +675,7 @@ int phar_wrapper_rmdir(php_stream_wrapper *wrapper, char *url, int options, php_ php_url_free(resource); return 0; } + PHAR_STR_FREE(str_key); } } diff --git a/ext/phar/dirstream.h b/ext/phar/dirstream.h index f7d73bfb8..e7bb4ae68 100644 --- a/ext/phar/dirstream.h +++ b/ext/phar/dirstream.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dirstream.h,v 1.5.2.3 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: dirstream.h 272370 2008-12-31 11:15:49Z sebastian $ */ BEGIN_EXTERN_C() int phar_wrapper_mkdir(php_stream_wrapper *wrapper, char *url_from, int mode, int options, php_stream_context *context TSRMLS_DC); diff --git a/ext/phar/func_interceptors.c b/ext/phar/func_interceptors.c index 224b0a2ba..199509b5e 100644 --- a/ext/phar/func_interceptors.c +++ b/ext/phar/func_interceptors.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: func_interceptors.c,v 1.20.2.22 2009/05/13 15:55:12 kalle Exp $ */ +/* $Id: func_interceptors.c 280454 2009-05-13 15:55:12Z kalle $ */ #include "phar_internal.h" diff --git a/ext/phar/func_interceptors.h b/ext/phar/func_interceptors.h index 0fc82b4eb..1b4c623b5 100644 --- a/ext/phar/func_interceptors.h +++ b/ext/phar/func_interceptors.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: func_interceptors.h,v 1.1.2.4 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: func_interceptors.h 272370 2008-12-31 11:15:49Z sebastian $ */ BEGIN_EXTERN_C() void phar_intercept_functions(TSRMLS_D); diff --git a/ext/phar/makestub.php b/ext/phar/makestub.php index eb089af77..43298c99a 100644 --- a/ext/phar/makestub.php +++ b/ext/phar/makestub.php @@ -48,7 +48,7 @@ $stub = '/* +----------------------------------------------------------------------+ */ -/* $Id: makestub.php,v 1.7.2.2 2008/08/01 13:48:44 sfox Exp $ */ +/* $Id: makestub.php 264018 2008-08-01 13:48:45Z sfox $ */ static inline void phar_get_stub(const char *index_php, const char *web, size_t *len, char **stub, const int name_len, const int web_len TSRMLS_DC) { diff --git a/ext/phar/package.php b/ext/phar/package.php index 53b693905..181c7c45f 100644 --- a/ext/phar/package.php +++ b/ext/phar/package.php @@ -43,6 +43,29 @@ Security addition * aliases are validated so that they contain no directory separators as intended * on conversion to other formats, user-supplied aliases are validated +Changes since 2.0.0RC2: + fixed PHP Bug #49021: phar tar signature algorithm reports as Unknown (0) in + getSignature() call + fixed PHP Bug #49020: phar misinterprets ustar long filename standard + fixed PHP Bug #49018: phar tar stores long filenames with prefix/name reversed + fixed PHP Bug #48791: open office files always reported as corrupted + fixed PHP Bug #48783: make install will fail saying phar file exists + fixed PHP Bug #48740: PHAR install fails when INSTALL_ROOT is not the final install location + fixed PHP Bug #48681: openssl signature verification for tar archives broken + fixed PHP Bug #48377: error message unclear on converting phar with existing file + fixed isset() on sub-directories (isset("blah") if file "blah/foo.php" exists) + + make phar work in PHP 6 +Changes since 2.0.0RC1: + security vulnerability in handling of long tar filenames fixed + fixed PECL Bug #14646: phar error message unclear with php stream wrappers + fixed PECL Bug #16338: php_stream_copy_to_stream{,_ex}() + fixed PHP Bug #48257: PharData throws an exception with non-phar tar + fixed PHP Bug #47085: rename() returns true even if the file in PHAR does not exist + fixed PHP Bug #46032: PharData::__construct() - wrong memory read + fixed PHP Bug #46060: Phar::addEmptyDir() breaks + fixed PHP Bug #45907: undefined reference to \'PHP_SHA512Init\' + fixed PHP Bug #45726: PHP_Archive / Archive.php missing Changes since 2.0.0a2: many bugfixes, removal of phar.extract_list, compression API refactored, conversion API refactored Changes since 2.0.0b1: addition of phar.cache_list, many performance improvements and bugfixes @@ -61,7 +84,7 @@ require_once 'PEAR/PackageFileManager2.php'; PEAR::setErrorHandling(PEAR_ERROR_DIE); $options = array( - 'filelistgenerator' => 'CVS', + 'filelistgenerator' => 'svn', 'changelogoldtonew' => false, 'simpleoutput' => true, 'baseinstalldir' => '/', @@ -101,8 +124,8 @@ $package->setPackageType('extsrc'); $package->addRelease(); $package->setReleaseVersion(phpversion('phar')); $package->setAPIVersion(Phar::apiVersion()); -$package->setReleaseStability('beta'); -$package->setAPIStability('beta'); +$package->setReleaseStability('stable'); +$package->setAPIStability('stable'); $package->setNotes("\n$notes\n"); //$package->addGlobalReplacement('package-info', '@package_version@', 'version'); $package->generateContents(); diff --git a/ext/phar/package.xml b/ext/phar/package.xml index e4c2fe4f3..45bdb9edc 100644 --- a/ext/phar/package.xml +++ b/ext/phar/package.xml @@ -1,5 +1,5 @@ - + phar pecl.php.net allows running of complete applications out of .phar files (like Java .jar files) @@ -42,19 +42,18 @@ a 6x speedup measured running phpMyAdmin as a phar archive. sfox@php.net yes - 2008-08-31 - + 2009-07-26 + - 2.0.0RC1 + 2.0.0 1.1.1 - beta - beta + stable + stable PHP License - BC BREAKING RELEASE BC breaks: * Phar object Compression API is rewritten. Use Phar::compress() and decompress(), @@ -97,13 +96,35 @@ Security addition * aliases are validated so that they contain no directory separators as intended * on conversion to other formats, user-supplied aliases are validated +Changes since 2.0.0RC2: + fixed PHP Bug #49021: phar tar signature algorithm reports as Unknown (0) in + getSignature() call + fixed PHP Bug #49020: phar misinterprets ustar long filename standard + fixed PHP Bug #49018: phar tar stores long filenames with prefix/name reversed + fixed PHP Bug #48791: open office files always reported as corrupted + fixed PHP Bug #48783: make install will fail saying phar file exists + fixed PHP Bug #48740: PHAR install fails when INSTALL_ROOT is not the final install location + fixed PHP Bug #48681: openssl signature verification for tar archives broken + fixed PHP Bug #48377: error message unclear on converting phar with existing file + fixed isset() on sub-directories (isset("blah") if file "blah/foo.php" exists) + + make phar work in PHP 6 +Changes since 2.0.0RC1: + security vulnerability in handling of long tar filenames fixed + fixed PECL Bug #14646: phar error message unclear with php stream wrappers + fixed PECL Bug #16338: php_stream_copy_to_stream{,_ex}() + fixed PHP Bug #48257: PharData throws an exception with non-phar tar + fixed PHP Bug #47085: rename() returns true even if the file in PHAR does not exist + fixed PHP Bug #46032: PharData::__construct() - wrong memory read + fixed PHP Bug #46060: Phar::addEmptyDir() breaks + fixed PHP Bug #45907: undefined reference to 'PHP_SHA512Init' + fixed PHP Bug #45726: PHP_Archive / Archive.php missing Changes since 2.0.0a2: many bugfixes, removal of phar.extract_list, compression API refactored, conversion API refactored Changes since 2.0.0b1: addition of phar.cache_list, many performance improvements and bugfixes implement OpenSSL asynchronous true package signing add support for package signing to tar-based archives require PHP 5.2.1+ - @@ -119,6 +140,10 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + + + + @@ -155,7 +180,95 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -232,6 +345,9 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + + + @@ -279,8 +395,13 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + + + + + @@ -294,6 +415,7 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + @@ -328,6 +450,7 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + @@ -350,6 +473,7 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + @@ -375,7 +499,9 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + + @@ -385,6 +511,7 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + @@ -442,9 +569,11 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + + @@ -452,6 +581,7 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + @@ -526,6 +656,7 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + @@ -534,6 +665,7 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + @@ -586,6 +718,12 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + + + + + + @@ -604,6 +742,7 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + @@ -640,8 +779,8 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + - @@ -693,10 +832,9 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement - - + @@ -783,6 +921,7 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement + @@ -815,7 +954,6 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement - @@ -866,17 +1004,101 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement - 2.0.0RC1 + 2.0.0 1.1.1 beta beta - 2008-08-31 + 2009-07-26 PHP License +BC BREAKING RELEASE + BC breaks: + * Phar object Compression API is rewritten. Use Phar::compress() and decompress(), + Phar::compressFiles()/decompressFiles() and PharFileInfo->compress()/decompress(). + * phar.extract_list and Phar::getExtractList() are removed + +Major feature functionality release + * phar.cache_list allows web-based phar applications to run at equal or faster than + their on-disk equivalent [Greg] + * new default stub allows running of phar-based phars without phar extension [Greg/Steph] + * add support for tar-based and zip-based phar archives [Greg] + * add support for OpenSSL-based true signatures [Greg] + * add support for signatures to tar-based phar archives [Greg] + * add Phar::isFileFormat() [Greg] + * add Phar::convertToExecutable(), Phar::convertToData() [Greg] + * add Phar::compress() [Greg] + * rename Phar::compressAllFiles() to compressFiles(), uncompressAllFiles() to + decompressFiles() [Greg] + * conversion to compressed or to other file formats automatically copies the archive + to a new extension (i.e. ".phar" to ".phar.tar" or ".tar" to ".tar.gz") [Steph] + * add Phar::webPhar() for running a web-based application unmodified + directly from a phar archive [Greg] + * file functions (fopen-based and stat-based) can be instructed to only look for + relative paths within a phar via Phar::interceptFileFuncs() + * add PharData class to allow manipulation/creation of non-executable tar and zip archives. [Steph] + non-executable tar/zip manipulation is allowed even when phar.readonly=1 [Greg] + * paths with . and .. work (phar://blah.phar/a/../b.php => phar://blah.phar/b.php) [Greg] + * add support for mkdir()/rmdir() and support for empty directories to phar file format [Greg] + * add option to compress the entire phar file for phar/tar file format [Greg] + * implement Phar::isCompressed() returning 0, Phar::GZ or Phar::BZ2 [Greg] + * implement Phar::copy(string $from, string $to) [Greg] + * implement Phar::running(), returns path or URL to currently executed phar + * implement Phar::buildFromIterator(Iterator $it[, string $base_directory]) [Greg] + * implement Phar::buildFromDirectory(string $base_directory[, string $regex]) [Steph] + * implement Phar::mount() for mounting external paths or files to locations inside a phar [Greg] + * add Phar::delete() [Greg] + * implement Phar::unlinkArchive() [Greg] + +Security addition + * aliases are validated so that they contain no directory separators as intended + * on conversion to other formats, user-supplied aliases are validated +Changes since 2.0.0RC2: + fixed PHP Bug #49021: phar tar signature algorithm reports as Unknown (0) in + getSignature() call + fixed PHP Bug #49020: phar misinterprets ustar long filename standard + fixed PHP Bug #49018: phar tar stores long filenames with prefix/name reversed + fixed PHP Bug #48791: open office files always reported as corrupted + fixed PHP Bug #48783: make install will fail saying phar file exists + fixed PHP Bug #48740: PHAR install fails when INSTALL_ROOT is not the final install location + fixed PHP Bug #48681: openssl signature verification for tar archives broken + fixed PHP Bug #48377: error message unclear on converting phar with existing file + fixed isset() on sub-directories (isset("blah") if file "blah/foo.php" exists) + + make phar work in PHP 6 +Changes since 2.0.0RC1: + security vulnerability in handling of long tar filenames fixed + fixed PECL Bug #14646: phar error message unclear with php stream wrappers + fixed PECL Bug #16338: php_stream_copy_to_stream{,_ex}() + fixed PHP Bug #48257: PharData throws an exception with non-phar tar + fixed PHP Bug #47085: rename() returns true even if the file in PHAR does not exist + fixed PHP Bug #46032: PharData::__construct() - wrong memory read + fixed PHP Bug #46060: Phar::addEmptyDir() breaks + fixed PHP Bug #45907: undefined reference to 'PHP_SHA512Init' + fixed PHP Bug #45726: PHP_Archive / Archive.php missing +Changes since 2.0.0a2: many bugfixes, removal of phar.extract_list, compression API refactored, + conversion API refactored +Changes since 2.0.0b1: addition of phar.cache_list, many performance improvements and bugfixes + implement OpenSSL asynchronous true package signing + add support for package signing to tar-based archives + require PHP 5.2.1+ + + + + + 2.0.0RC2 + 1.1.1 + + + beta + beta + + 2009-06-04 + PHP License + BC BREAKING RELEASE BC breaks: * Phar object Compression API is rewritten. Use Phar::compress() and decompress(), @@ -919,13 +1141,84 @@ Security addition * aliases are validated so that they contain no directory separators as intended * on conversion to other formats, user-supplied aliases are validated +Changes since 2.0.0RC1: + security vulnerability in handling of long tar filenames fixed + fixed PECL Bug #14646: phar error message unclear with php stream wrappers + fixed PECL Bug #16338: php_stream_copy_to_stream{,_ex}() + fixed PHP Bug #48257: PharData throws an exception with non-phar tar + fixed PHP Bug #47085: rename() returns true even if the file in PHAR does not exist + fixed PHP Bug #46032: PharData::__construct() - wrong memory read + fixed PHP Bug #46060: Phar::addEmptyDir() breaks + fixed PHP Bug #45907: undefined reference to 'PHP_SHA512Init' + fixed PHP Bug #45726: PHP_Archive / Archive.php missing Changes since 2.0.0a2: many bugfixes, removal of phar.extract_list, compression API refactored, conversion API refactored Changes since 2.0.0b1: addition of phar.cache_list, many performance improvements and bugfixes implement OpenSSL asynchronous true package signing add support for package signing to tar-based archives require PHP 5.2.1+ + + + + + 2.0.0RC1 + 1.1.1 + + + beta + beta + + 2008-08-31 + PHP License + +BC BREAKING RELEASE + BC breaks: + * Phar object Compression API is rewritten. Use Phar::compress() and decompress(), + Phar::compressFiles()/decompressFiles() and PharFileInfo->compress()/decompress(). + * phar.extract_list and Phar::getExtractList() are removed + +Major feature functionality release + * phar.cache_list allows web-based phar applications to run at equal or faster than + their on-disk equivalent [Greg] + * new default stub allows running of phar-based phars without phar extension [Greg/Steph] + * add support for tar-based and zip-based phar archives [Greg] + * add support for OpenSSL-based true signatures [Greg] + * add support for signatures to tar-based phar archives [Greg] + * add Phar::isFileFormat() [Greg] + * add Phar::convertToExecutable(), Phar::convertToData() [Greg] + * add Phar::compress() [Greg] + * rename Phar::compressAllFiles() to compressFiles(), uncompressAllFiles() to + decompressFiles() [Greg] + * conversion to compressed or to other file formats automatically copies the archive + to a new extension (i.e. ".phar" to ".phar.tar" or ".tar" to ".tar.gz") [Steph] + * add Phar::webPhar() for running a web-based application unmodified + directly from a phar archive [Greg] + * file functions (fopen-based and stat-based) can be instructed to only look for + relative paths within a phar via Phar::interceptFileFuncs() + * add PharData class to allow manipulation/creation of non-executable tar and zip archives. [Steph] + non-executable tar/zip manipulation is allowed even when phar.readonly=1 [Greg] + * paths with . and .. work (phar://blah.phar/a/../b.php => phar://blah.phar/b.php) [Greg] + * add support for mkdir()/rmdir() and support for empty directories to phar file format [Greg] + * add option to compress the entire phar file for phar/tar file format [Greg] + * implement Phar::isCompressed() returning 0, Phar::GZ or Phar::BZ2 [Greg] + * implement Phar::copy(string $from, string $to) [Greg] + * implement Phar::running(), returns path or URL to currently executed phar + * implement Phar::buildFromIterator(Iterator $it[, string $base_directory]) [Greg] + * implement Phar::buildFromDirectory(string $base_directory[, string $regex]) [Steph] + * implement Phar::mount() for mounting external paths or files to locations inside a phar [Greg] + * add Phar::delete() [Greg] + * implement Phar::unlinkArchive() [Greg] + +Security addition + * aliases are validated so that they contain no directory separators as intended + * on conversion to other formats, user-supplied aliases are validated +Changes since 2.0.0a2: many bugfixes, removal of phar.extract_list, compression API refactored, + conversion API refactored +Changes since 2.0.0b1: addition of phar.cache_list, many performance improvements and bugfixes + implement OpenSSL asynchronous true package signing + add support for package signing to tar-based archives + require PHP 5.2.1+ @@ -939,7 +1232,8 @@ Changes since 2.0.0b1: addition of phar.cache_list, many performance improvement 2008-05-12 PHP License - BC BREAKING RELEASE + +BC BREAKING RELEASE BC breaks: * Phar object Compression API is rewritten. Use Phar::compress() and decompress(), Phar::compressFiles()/decompressFiles() and PharFileInfo->compress()/decompress(). @@ -978,7 +1272,8 @@ Security addition * on conversion to other formats, user-supplied aliases are validated Changes since 2.0.0a2: many bugfixes, removal of phar.extract_list, compression API refactored, - conversion API refactored + conversion API refactored + @@ -991,7 +1286,8 @@ Changes since 2.0.0a2: many bugfixes, removal of phar.extract_list, compression 2008-03-27 PHP License - Major feature functionality release + +Major feature functionality release * new default stub allows running of phar-based phars without phar extension [Greg/Steph] * add support for tar-based and zip-based phar archives [Greg] * add Phar::isTar(), Phar::isZip(), and Phar::isPhar() [Greg] @@ -1014,7 +1310,8 @@ Changes since 2.0.0a2: many bugfixes, removal of phar.extract_list, compression * implement Phar::mount() for mounting external paths or files to locations inside a phar [Greg] * add Phar::delete() [Greg] -Changes since 2.0.0a1: fix build in PHP 5.2 +Changes since 2.0.0a1: fix build in PHP 5.2 + @@ -1027,7 +1324,8 @@ Changes since 2.0.0a1: fix build in PHP 5.2 2008-03-26 PHP License - Major feature functionality release + +Major feature functionality release * new default stub allows running of phar-based phars without phar extension [Greg/Steph] * add support for tar-based and zip-based phar archives [Greg] * add Phar::isTar(), Phar::isZip(), and Phar::isPhar() [Greg] @@ -1048,7 +1346,8 @@ Changes since 2.0.0a1: fix build in PHP 5.2 * implement Phar::copy(string $from, string $to) [Greg] * implement Phar::buildFromIterator(Iterator $it[, string $base_directory]) [Greg] * implement Phar::mount() for mounting external paths or files to locations inside a phar [Greg] - * add Phar::delete() [Greg] + * add Phar::delete() [Greg] + @@ -1061,7 +1360,8 @@ Changes since 2.0.0a1: fix build in PHP 5.2 2007-08-24 PHP License - * add Phar::setAlias() [Greg] + +* add Phar::setAlias() [Greg] * fix too many open file handles issue [Greg] * fix rename [Greg] * add Phar::getAlias() [Marcus] @@ -1072,7 +1372,8 @@ Changes since 2.0.0a1: fix build in PHP 5.2 * Made Phar::loadPhar() and Phar::mapPhar() ignore extracted archives [Marcus] * Fix issue with compressed entries and uncompressing entries [Marcus] * Verify stubs before writing [Marcus] -* Always use longest stub end to avoid issues with length field [Marcus] +* Always use longest stub end to avoid issues with length field [Marcus] + @@ -1085,13 +1386,15 @@ Changes since 2.0.0a1: fix build in PHP 5.2 2007-05-18 PHP License - * add PharFileInfo::hasMetadata(), PharFileInfo::delMetadata() [Marcus] + +* add PharFileInfo::hasMetadata(), PharFileInfo::delMetadata() [Marcus] * add Phar::hasMetadata(), Phar::delMetadata() [Marcus] * fix Phar::CanWrite() [Marcus] * add preliminary phar command (phar.php) [Marcus] * add phar command (phar.phar) [Marcus] * list all available compression methods using Phar::getSupportedCompression() [Marcus] -* remove RINIT [Marcus] +* remove RINIT [Marcus] + @@ -1104,13 +1407,15 @@ Changes since 2.0.0a1: fix build in PHP 5.2 2007-04-12 PHP License - * implement ability connect a phar file 'phar://whatever' to a directory. That way all + +* implement ability connect a phar file 'phar://whatever' to a directory. That way all access to that phar archive are directed to the extracted directory. This allows to have the installed files and the archive keep the same includes. [Marcus] * implement SHA-2 (256, 512) support [Marcus] * implement setSignatureAlgorithm() and Phar::MD5 Phar::SHA1 Phar::SHA256 Phar::SHA512 Phar::PGP to - choose the kind of signature to use (PGP falls back to SHA1) [Greg] + choose the kind of signature to use (PGP falls back to SHA1) [Greg] + @@ -1123,7 +1428,9 @@ Changes since 2.0.0a1: fix build in PHP 5.2 2007-03-28 PHP License - * Fix return value of unlink() and rename() when used for phar archievs. [Marcus] + +* Fix return value of unlink() and rename() when used for phar archievs. [Marcus] + @@ -1136,9 +1443,11 @@ Changes since 2.0.0a1: fix build in PHP 5.2 2007-03-26 PHP License - *BACKWARDS COMPATIBILITY BREAK* + +*BACKWARDS COMPATIBILITY BREAK* Rename Phar->begin/isFlushingToPhar/commit to startBuffering/isBuffering/stopBuffering -Note that isBuffering() returns the opposite value to isFlushingToPhar() +Note that isBuffering() returns the opposite value to isFlushingToPhar() + diff --git a/ext/phar/phar.c b/ext/phar/phar.c index e41233596..571ae4577 100644 --- a/ext/phar/phar.c +++ b/ext/phar/phar.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar.c,v 1.370.2.62 2009/05/13 20:25:43 cellog Exp $ */ +/* $Id: phar.c 286338 2009-07-26 01:03:47Z cellog $ */ #define PHAR_MAIN 1 #include "phar_internal.h" @@ -1972,11 +1972,13 @@ woohoo: if (keylen > (uint) filename_len) { zend_hash_move_forward(&(PHAR_GLOBALS->phar_fname_map)); + PHAR_STR_FREE(str_key); continue; } if (!memcmp(filename, str_key, keylen) && ((uint)filename_len == keylen || filename[keylen] == '/' || filename[keylen] == '\0')) { + PHAR_STR_FREE(str_key); if (FAILURE == zend_hash_get_current_data(&(PHAR_GLOBALS->phar_fname_map), (void **) &pphar)) { break; } @@ -1984,6 +1986,7 @@ woohoo: goto woohoo; } + PHAR_STR_FREE(str_key); zend_hash_move_forward(&(PHAR_GLOBALS->phar_fname_map)); } @@ -1999,17 +2002,20 @@ woohoo: if (keylen > (uint) filename_len) { zend_hash_move_forward(&cached_phars); + PHAR_STR_FREE(str_key); continue; } if (!memcmp(filename, str_key, keylen) && ((uint)filename_len == keylen || filename[keylen] == '/' || filename[keylen] == '\0')) { + PHAR_STR_FREE(str_key); if (FAILURE == zend_hash_get_current_data(&cached_phars, (void **) &pphar)) { break; } *ext_str = filename + (keylen - (*pphar)->ext_len); goto woohoo; } + PHAR_STR_FREE(str_key); zend_hash_move_forward(&cached_phars); } } @@ -2407,6 +2413,7 @@ int phar_postprocess_file(phar_entry_data *idata, php_uint32 crc32, char **error if (entry->is_zip && process_zip > 0) { /* verify local file header */ phar_zip_file_header local; + phar_zip_data_desc desc; if (SUCCESS != phar_open_archive_fp(idata->phar TSRMLS_CC)) { spprintf(error, 0, "phar error: unable to open zip-based phar archive \"%s\" to verify local file header for file \"%s\"", idata->phar->fname, entry->filename); @@ -2420,6 +2427,25 @@ int phar_postprocess_file(phar_entry_data *idata, php_uint32 crc32, char **error return FAILURE; } + /* check for data descriptor */ + if (((PHAR_ZIP_16(local.flags)) & 0x8) == 0x8) { + php_stream_seek(phar_get_entrypfp(idata->internal_file TSRMLS_CC), + entry->header_offset + sizeof(local) + + PHAR_ZIP_16(local.filename_len) + + PHAR_ZIP_16(local.extra_len) + + entry->compressed_filesize, SEEK_SET); + if (sizeof(desc) != php_stream_read(phar_get_entrypfp(idata->internal_file TSRMLS_CC), + (char *) &desc, sizeof(desc))) { + spprintf(error, 0, "phar error: internal corruption of zip-based phar \"%s\" (cannot read local data descriptor for file \"%s\")", idata->phar->fname, entry->filename); + return FAILURE; + } + if (desc.signature[0] == 'P' && desc.signature[1] == 'K') { + memcpy(&(local.crc32), &(desc.crc32), 12); + } else { + /* old data descriptors have no signature */ + memcpy(&(local.crc32), &desc, 12); + } + } /* verify local header */ if (entry->filename_len != PHAR_ZIP_16(local.filename_len) || entry->crc32 != PHAR_ZIP_32(local.crc32) || entry->uncompressed_filesize != PHAR_ZIP_32(local.uncompsize) || entry->compressed_filesize != PHAR_ZIP_32(local.compsize)) { spprintf(error, 0, "phar error: internal corruption of zip-based phar \"%s\" (local header of file \"%s\" does not match central directory)", idata->phar->fname, entry->filename); @@ -2621,7 +2647,11 @@ int phar_flush(phar_archive_data *phar, char *user_stub, long len, int convert, len = -len; } user_stub = 0; +#if PHP_MAJOR_VERSION >= 6 + if (!(len = php_stream_copy_to_mem(stubfile, (void **) &user_stub, len, 0)) || !user_stub) { +#else if (!(len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)) || !user_stub) { +#endif if (closeoldfile) { php_stream_close(oldfile); } @@ -3635,7 +3665,7 @@ PHP_MINFO_FUNCTION(phar) /* {{{ */ php_info_print_table_header(2, "Phar: PHP Archive support", "enabled"); php_info_print_table_row(2, "Phar EXT version", PHP_PHAR_VERSION); php_info_print_table_row(2, "Phar API version", PHP_PHAR_API_VERSION); - php_info_print_table_row(2, "CVS revision", "$Revision: 1.370.2.62 $"); + php_info_print_table_row(2, "CVS revision", "$Revision: 286338 $"); php_info_print_table_row(2, "Phar-based phar archives", "enabled"); php_info_print_table_row(2, "Tar-based phar archives", "enabled"); php_info_print_table_row(2, "ZIP-based phar archives", "enabled"); diff --git a/ext/phar/phar/directorygraphiterator.inc b/ext/phar/phar/directorygraphiterator.inc index 846680053..5a658ddab 100755 --- a/ext/phar/phar/directorygraphiterator.inc +++ b/ext/phar/phar/directorygraphiterator.inc @@ -1,34 +1,34 @@ - \ No newline at end of file diff --git a/ext/phar/phar/directorytreeiterator.inc b/ext/phar/phar/directorytreeiterator.inc index 2c71c93dc..9ed2e1a1b 100755 --- a/ext/phar/phar/directorytreeiterator.inc +++ b/ext/phar/phar/directorytreeiterator.inc @@ -1,54 +1,54 @@ -getDepth(); $l++) { - $tree .= $this->getSubIterator($l)->hasNext() ? '| ' : ' '; - } - return $tree . ($this->getSubIterator($l)->hasNext() ? '|-' : '\-') - . $this->getSubIterator($l)->__toString(); - } - - /** Aggregates the inner iterator - */ - function __call($func, $params) - { - return call_user_func_array(array($this->getSubIterator(), $func), $params); - } -} - +getDepth(); $l++) { + $tree .= $this->getSubIterator($l)->hasNext() ? '| ' : ' '; + } + return $tree . ($this->getSubIterator($l)->hasNext() ? '|-' : '\-') + . $this->getSubIterator($l)->__toString(); + } + + /** Aggregates the inner iterator + */ + function __call($func, $params) + { + return call_user_func_array(array($this->getSubIterator(), $func), $params); + } +} + ?> \ No newline at end of file diff --git a/ext/phar/phar/invertedregexiterator.inc b/ext/phar/phar/invertedregexiterator.inc index de21b01e0..aec87e6ab 100755 --- a/ext/phar/phar/invertedregexiterator.inc +++ b/ext/phar/phar/invertedregexiterator.inc @@ -1,27 +1,27 @@ - \ No newline at end of file diff --git a/ext/phar/phar/pharcommand.inc b/ext/phar/phar/pharcommand.inc index 6b70cef1b..9886676cc 100755 --- a/ext/phar/phar/pharcommand.inc +++ b/ext/phar/phar/pharcommand.inc @@ -1566,7 +1566,7 @@ class PharCommand extends CLICommand $use_ext = extension_loaded('phar'); $version = array( 'PHP Version' => phpversion(), - 'phar.phar version' => '$Revision: 1.49.2.16 $', + 'phar.phar version' => '$Revision: 282735 $', 'Phar EXT version' => $use_ext ? phpversion('phar') : 'Not available', 'Phar API version' => Phar::apiVersion(), 'Phar-based phar archives' => true, diff --git a/ext/phar/phar_internal.h b/ext/phar/phar_internal.h index 445784fea..da9cf22ad 100755 --- a/ext/phar/phar_internal.h +++ b/ext/phar/phar_internal.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar_internal.h,v 1.109.2.31 2009/05/13 20:25:43 cellog Exp $ */ +/* $Id: phar_internal.h 286338 2009-07-26 01:03:47Z cellog $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -544,12 +544,47 @@ typedef zstr phar_zstr; spprintf(&b, 0, "%s", a.s); #define PHAR_ZSTR(a, b) \ b = ZSTR(a); +#define PHAR_STR_FREE(a) \ + efree(a); +static inline int phar_make_unicode(zstr *c_var, char *arKey, uint nKeyLength TSRMLS_DC) +{ + int c_var_len; + UConverter *conv = ZEND_U_CONVERTER(UG(runtime_encoding_conv)); + + c_var->u = NULL; + if (zend_string_to_unicode(conv, &c_var->u, &c_var_len, arKey, nKeyLength TSRMLS_CC) == FAILURE) { + + if (c_var->u) { + efree(c_var->u); + } + return 0; + + } + return c_var_len; +} +static inline int phar_find_key(HashTable *_SERVER, char *key, int len, void **stuff TSRMLS_DC) +{ + if (SUCCESS == zend_hash_find(_SERVER, key, len, stuff)) { + return 1; + } else { + int s = len; + zstr var; + s = phar_make_unicode(&var, key, len TSRMLS_CC); + if (SUCCESS == zend_u_hash_find(_SERVER, IS_UNICODE, var, s, stuff)) { + efree(var.u); + return 1; + } + efree(var.u); + return 0; + } +} #else typedef char *phar_zstr; #define PHAR_STR(a, b) \ b = a; #define PHAR_ZSTR(a, b) \ b = a; +#define PHAR_STR_FREE(a) #endif BEGIN_EXTERN_C() diff --git a/ext/phar/phar_object.c b/ext/phar/phar_object.c index 76016e706..69e8e382b 100755 --- a/ext/phar/phar_object.c +++ b/ext/phar/phar_object.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar_object.c,v 1.266.2.63 2009/06/05 04:46:49 cellog Exp $ */ +/* $Id: phar_object.c 286518 2009-07-29 16:17:57Z felipe $ */ #include "phar_internal.h" #include "func_interceptors.h" @@ -30,6 +30,12 @@ static zend_class_entry *phar_ce_PharException; static zend_class_entry *phar_ce_entry; #endif +#if PHP_MAJOR_VERSION > 5 || ((PHP_MAJOR_VERSION == 5) && (PHP_MINOR_VERSION >= 3)) +# define PHAR_ARG_INFO +#else +# define PHAR_ARG_INFO static +#endif + static int phar_file_type(HashTable *mimes, char *file, char **mime_type TSRMLS_DC) /* {{{ */ { char *ext; @@ -52,10 +58,15 @@ static int phar_file_type(HashTable *mimes, char *file, char **mime_type TSRMLS_ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char *basename, int request_uri_len TSRMLS_DC) /* {{{ */ { +#if PHP_MAJOR_VERSION >= 6 + int is_unicode = 0; +#endif HashTable *_SERVER; zval **stuff; char *path_info; int basename_len = strlen(basename); + int code; + zval *temp; /* "tweak" $_SERVER variables requested in earlier call to Phar::mungServer() */ if (!PG(http_globals)[TRACK_VARS_SERVER]) { @@ -65,9 +76,17 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char _SERVER = Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER]); /* PATH_INFO and PATH_TRANSLATED should always be munged */ +#if PHP_MAJOR_VERSION >= 6 + if (phar_find_key(_SERVER, "PATH_INFO", sizeof("PATH_INFO"), (void **) &stuff TSRMLS_CC)) { + if (Z_TYPE_PP(stuff) == IS_UNICODE) { + is_unicode = 1; + zval_unicode_to_string(*stuff TSRMLS_CC); + } else { + is_unicode = 0; + } +#else if (SUCCESS == zend_hash_find(_SERVER, "PATH_INFO", sizeof("PATH_INFO"), (void **) &stuff)) { - int code; - zval *temp; +#endif path_info = Z_STRVAL_PP(stuff); code = Z_STRLEN_PP(stuff); @@ -77,13 +96,26 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char MAKE_STD_ZVAL(temp); ZVAL_STRINGL(temp, path_info, code, 0); - zend_hash_update(_SERVER, "PHAR_PATH_INFO", sizeof("PHAR_PATH_INFO"), (void *) &temp, sizeof(zval **), NULL); +#if PHP_MAJOR_VERSION >= 6 + if (is_unicode) { + zval_string_to_unicode(*stuff TSRMLS_CC); + } +#endif + zend_hash_update(_SERVER, "PHAR_PATH_INFO", sizeof("PHAR_PATH_INFO"), &temp, sizeof(zval **), NULL); } } +#if PHP_MAJOR_VERSION >= 6 + if (phar_find_key(_SERVER, "PATH_TRANSLATED", sizeof("PATH_TRANSLATED"), (void **) &stuff TSRMLS_CC)) { + if (Z_TYPE_PP(stuff) == IS_UNICODE) { + is_unicode = 1; + zval_unicode_to_string(*stuff TSRMLS_CC); + } else { + is_unicode = 0; + } +#else if (SUCCESS == zend_hash_find(_SERVER, "PATH_TRANSLATED", sizeof("PATH_TRANSLATED"), (void **) &stuff)) { - int code; - zval *temp; +#endif path_info = Z_STRVAL_PP(stuff); code = Z_STRLEN_PP(stuff); @@ -91,6 +123,11 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char MAKE_STD_ZVAL(temp); ZVAL_STRINGL(temp, path_info, code, 0); +#if PHP_MAJOR_VERSION >= 6 + if (is_unicode) { + zval_string_to_unicode(*stuff TSRMLS_CC); + } +#endif zend_hash_update(_SERVER, "PHAR_PATH_TRANSLATED", sizeof("PHAR_PATH_TRANSLATED"), (void *) &temp, sizeof(zval **), NULL); } @@ -99,9 +136,17 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char } if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_REQUEST_URI) { +#if PHP_MAJOR_VERSION >= 6 + if (phar_find_key(_SERVER, "REQUEST_URI", sizeof("REQUEST_URI"), (void **) &stuff TSRMLS_CC)) { + if (Z_TYPE_PP(stuff) == IS_UNICODE) { + is_unicode = 1; + zval_unicode_to_string(*stuff TSRMLS_CC); + } else { + is_unicode = 0; + } +#else if (SUCCESS == zend_hash_find(_SERVER, "REQUEST_URI", sizeof("REQUEST_URI"), (void **) &stuff)) { - int code; - zval *temp; +#endif path_info = Z_STRVAL_PP(stuff); code = Z_STRLEN_PP(stuff); @@ -111,15 +156,28 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char MAKE_STD_ZVAL(temp); ZVAL_STRINGL(temp, path_info, code, 0); +#if PHP_MAJOR_VERSION >= 6 + if (is_unicode) { + zval_string_to_unicode(*stuff TSRMLS_CC); + } +#endif zend_hash_update(_SERVER, "PHAR_REQUEST_URI", sizeof("PHAR_REQUEST_URI"), (void *) &temp, sizeof(zval **), NULL); } } } if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_PHP_SELF) { +#if PHP_MAJOR_VERSION >= 6 + if (phar_find_key(_SERVER, "PHP_SELF", sizeof("PHP_SELF"), (void **) &stuff TSRMLS_CC)) { + if (Z_TYPE_PP(stuff) == IS_UNICODE) { + is_unicode = 1; + zval_unicode_to_string(*stuff TSRMLS_CC); + } else { + is_unicode = 0; + } +#else if (SUCCESS == zend_hash_find(_SERVER, "PHP_SELF", sizeof("PHP_SELF"), (void **) &stuff)) { - int code; - zval *temp; +#endif path_info = Z_STRVAL_PP(stuff); code = Z_STRLEN_PP(stuff); @@ -129,15 +187,28 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char MAKE_STD_ZVAL(temp); ZVAL_STRINGL(temp, path_info, code, 0); +#if PHP_MAJOR_VERSION >= 6 + if (is_unicode) { + zval_string_to_unicode(*stuff TSRMLS_CC); + } +#endif zend_hash_update(_SERVER, "PHAR_PHP_SELF", sizeof("PHAR_PHP_SELF"), (void *) &temp, sizeof(zval **), NULL); } } } if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_SCRIPT_NAME) { +#if PHP_MAJOR_VERSION >= 6 + if (phar_find_key(_SERVER, "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void **) &stuff TSRMLS_CC)) { + if (Z_TYPE_PP(stuff) == IS_UNICODE) { + is_unicode = 1; + zval_unicode_to_string(*stuff TSRMLS_CC); + } else { + is_unicode = 0; + } +#else if (SUCCESS == zend_hash_find(_SERVER, "SCRIPT_NAME", sizeof("SCRIPT_NAME"), (void **) &stuff)) { - int code; - zval *temp; +#endif path_info = Z_STRVAL_PP(stuff); code = Z_STRLEN_PP(stuff); @@ -145,14 +216,27 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char MAKE_STD_ZVAL(temp); ZVAL_STRINGL(temp, path_info, code, 0); +#if PHP_MAJOR_VERSION >= 6 + if (is_unicode) { + zval_string_to_unicode(*stuff TSRMLS_CC); + } +#endif zend_hash_update(_SERVER, "PHAR_SCRIPT_NAME", sizeof("PHAR_SCRIPT_NAME"), (void *) &temp, sizeof(zval **), NULL); } } if (PHAR_GLOBALS->phar_SERVER_mung_list & PHAR_MUNG_SCRIPT_FILENAME) { +#if PHP_MAJOR_VERSION >= 6 + if (phar_find_key(_SERVER, "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &stuff TSRMLS_CC)) { + if (Z_TYPE_PP(stuff) == IS_UNICODE) { + is_unicode = 1; + zval_unicode_to_string(*stuff TSRMLS_CC); + } else { + is_unicode = 0; + } +#else if (SUCCESS == zend_hash_find(_SERVER, "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &stuff)) { - int code; - zval *temp; +#endif path_info = Z_STRVAL_PP(stuff); code = Z_STRLEN_PP(stuff); @@ -160,6 +244,11 @@ static void phar_mung_server_vars(char *fname, char *entry, int entry_len, char MAKE_STD_ZVAL(temp); ZVAL_STRINGL(temp, path_info, code, 0); +#if PHP_MAJOR_VERSION >= 6 + if (is_unicode) { + zval_string_to_unicode(*stuff TSRMLS_CC); + } +#endif zend_hash_update(_SERVER, "PHAR_SCRIPT_FILENAME", sizeof("PHAR_SCRIPT_FILENAME"), (void *) &temp, sizeof(zval **), NULL); } } @@ -851,7 +940,11 @@ PHP_METHOD(Phar, webPhar) if (ext) { ++ext; +#if PHP_MAJOR_VERSION >= 6 + if (phar_find_key(Z_ARRVAL_P(mimeoverride), ext, strlen(ext)+1, (void **) &val TSRMLS_CC)) { +#else if (SUCCESS == zend_hash_find(Z_ARRVAL_P(mimeoverride), ext, strlen(ext)+1, (void **) &val)) { +#endif switch (Z_TYPE_PP(val)) { case IS_LONG: if (Z_LVAL_PP(val) == PHAR_MIME_PHP || Z_LVAL_PP(val) == PHAR_MIME_PHPS) { @@ -865,6 +958,11 @@ PHP_METHOD(Phar, webPhar) RETURN_FALSE; } break; +#if PHP_MAJOR_VERSION >= 6 + case IS_UNICODE: + zval_unicode_to_string(*(val) TSRMLS_CC); + /* break intentionally omitted */ +#endif case IS_STRING: mime_type = Z_STRVAL_PP(val); code = PHAR_MIME_OTHER; @@ -915,12 +1013,26 @@ PHP_METHOD(Phar, mungServer) for (zend_hash_internal_pointer_reset(Z_ARRVAL_P(mungvalues)); SUCCESS == zend_hash_has_more_elements(Z_ARRVAL_P(mungvalues)); zend_hash_move_forward(Z_ARRVAL_P(mungvalues))) { zval **data = NULL; +#if PHP_MAJOR_VERSION >= 6 + zval *unicopy = NULL; +#endif if (SUCCESS != zend_hash_get_current_data(Z_ARRVAL_P(mungvalues), (void **) &data)) { zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "unable to retrieve array value in Phar::mungServer()"); return; } +#if PHP_MAJOR_VERSION >= 6 + if (Z_TYPE_PP(data) == IS_UNICODE) { + MAKE_STD_ZVAL(unicopy); + *unicopy = **data; + zval_copy_ctor(unicopy); + INIT_PZVAL(unicopy); + zval_unicode_to_string(unicopy TSRMLS_CC); + data = &unicopy; + } +#endif + if (Z_TYPE_PP(data) != IS_STRING) { zend_throw_exception_ex(phar_ce_PharException, 0 TSRMLS_CC, "Non-string value passed to Phar::mungServer(), expecting an array of any of these strings: PHP_SELF, REQUEST_URI, SCRIPT_FILENAME, SCRIPT_NAME"); return; @@ -942,6 +1054,11 @@ PHP_METHOD(Phar, mungServer) if (Z_STRLEN_PP(data) == sizeof("SCRIPT_FILENAME")-1 && !strncmp(Z_STRVAL_PP(data), "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME")-1)) { PHAR_GLOBALS->phar_SERVER_mung_list |= PHAR_MUNG_SCRIPT_FILENAME; } +#if PHP_MAJOR_VERSION >= 6 + if (unicopy) { + zval_ptr_dtor(&unicopy); + } +#endif } } /* }}} */ @@ -1476,6 +1593,7 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ spprintf(&str_key, 0, "%s", key); #else spprintf(&str_key, 0, "%v", key); + ezfree(key); #endif } else { PHAR_STR(key, str_key); @@ -1537,7 +1655,21 @@ static int phar_build(zend_object_iterator *iter, void *puser TSRMLS_DC) /* {{{ case SPL_FS_INFO: case SPL_FS_FILE: #if PHP_VERSION_ID >= 60000 - fname = expand_filepath(intern->file_name.s, NULL TSRMLS_CC); + if (intern->file_name_type == IS_UNICODE) { + zval zv; + + INIT_ZVAL(zv); + Z_UNIVAL(zv) = intern->file_name; + Z_UNILEN(zv) = intern->file_name_len; + Z_TYPE(zv) = IS_UNICODE; + + zval_copy_ctor(&zv); + zval_unicode_to_string(&zv TSRMLS_CC); + fname = expand_filepath(Z_STRVAL(zv), NULL TSRMLS_CC); + ezfree(Z_UNIVAL(zv)); + } else { + fname = expand_filepath(intern->file_name.s, NULL TSRMLS_CC); + } #else fname = expand_filepath(intern->file_name, NULL TSRMLS_CC); #endif @@ -1608,6 +1740,7 @@ phar_spl_fileinfo: spprintf(&str_key, 0, "%s", key); #else spprintf(&str_key, 0, "%v", key); + ezfree(key); #endif } else { PHAR_STR(key, str_key); @@ -2037,6 +2170,7 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c int ext_len = ext ? strlen(ext) : 0; int oldname_len; phar_archive_data **pphar = NULL; + php_stream_statbuf ssb; if (!ext) { if (phar->is_zip) { @@ -2107,6 +2241,8 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c spprintf(&newname, 0, "%s.%s", strtok(basename, "."), ext); efree(basename); + + basepath = estrndup(oldpath, (strlen(oldpath) - oldname_len)); phar->fname_len = spprintf(&newpath, 0, "%s%s", basepath, newname); phar->fname = newpath; @@ -2142,6 +2278,11 @@ static zval *phar_rename_archive(phar_archive_data *phar, char *ext, zend_bool c return NULL; } its_ok: + if (SUCCESS == php_stream_stat_path(newpath, &ssb)) { + efree(oldpath); + zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, "phar \"%s\" exists and must be unlinked prior to conversion", newpath); + return NULL; + } if (!phar->is_data) { if (SUCCESS != phar_detect_phar_fname_ext(newpath, phar->fname_len, (const char **) &(phar->ext), &(phar->ext_len), 1, 1, 1 TSRMLS_CC)) { efree(oldpath); @@ -3004,12 +3145,6 @@ PHP_METHOD(Phar, setSignatureAlgorithm) return; } - if (phar_obj->arc.archive->is_zip) { - zend_throw_exception_ex(spl_ce_BadMethodCallException, 0 TSRMLS_CC, - "Cannot set signature algorithm, not possible with zip-based phar archives"); - return; - } - if (zend_parse_parameters_ex(ZEND_PARSE_PARAMS_QUIET, ZEND_NUM_ARGS() TSRMLS_CC, "l|s", &algo, &key, &key_len) != SUCCESS) { return; } @@ -4766,7 +4901,11 @@ PHP_METHOD(PharFileInfo, getContent) phar_seek_efp(link, 0, SEEK_SET, 0, 0 TSRMLS_CC); Z_TYPE_P(return_value) = IS_STRING; +#if PHP_MAJOR_VERSION >= 6 + Z_STRLEN_P(return_value) = php_stream_copy_to_mem(fp, (void **) &(Z_STRVAL_P(return_value)), link->uncompressed_filesize, 0); +#else Z_STRLEN_P(return_value) = php_stream_copy_to_mem(fp, &(Z_STRVAL_P(return_value)), link->uncompressed_filesize, 0); +#endif if (!Z_STRVAL_P(return_value)) { Z_STRVAL_P(return_value) = estrndup("", 0); @@ -4978,7 +5117,7 @@ PHP_METHOD(PharFileInfo, decompress) #endif /* HAVE_SPL */ /* {{{ phar methods */ - +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar___construct, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_ARG_INFO(0, flags) @@ -4986,30 +5125,36 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_phar___construct, 0, 0, 1) ZEND_ARG_INFO(0, fileformat) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_createDS, 0, 0, 0) ZEND_ARG_INFO(0, index) ZEND_ARG_INFO(0, webindex) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_loadPhar, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_ARG_INFO(0, alias) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_mapPhar, 0, 0, 0) ZEND_ARG_INFO(0, alias) ZEND_ARG_INFO(0, offset) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_mount, 0, 0, 2) ZEND_ARG_INFO(0, inphar) ZEND_ARG_INFO(0, externalfile) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_mungServer, 0, 0, 1) ZEND_ARG_INFO(0, munglist) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_webPhar, 0, 0, 0) ZEND_ARG_INFO(0, alias) ZEND_ARG_INFO(0, index) @@ -5018,105 +5163,126 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_webPhar, 0, 0, 0) ZEND_ARG_INFO(0, rewrites) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_running, 0, 0, 1) ZEND_ARG_INFO(0, retphar) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_ua, 0, 0, 1) ZEND_ARG_INFO(0, archive) ZEND_END_ARG_INFO() #if HAVE_SPL - +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_build, 0, 0, 1) ZEND_ARG_INFO(0, iterator) ZEND_ARG_INFO(0, base_directory) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_conv, 0, 0, 0) ZEND_ARG_INFO(0, format) ZEND_ARG_INFO(0, compression_type) ZEND_ARG_INFO(0, file_ext) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_comps, 0, 0, 1) ZEND_ARG_INFO(0, compression_type) ZEND_ARG_INFO(0, file_ext) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_decomp, 0, 0, 0) ZEND_ARG_INFO(0, file_ext) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_comp, 0, 0, 1) ZEND_ARG_INFO(0, compression_type) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_compo, 0, 0, 0) ZEND_ARG_INFO(0, compression_type) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_copy, 0, 0, 2) ZEND_ARG_INFO(0, newfile) ZEND_ARG_INFO(0, oldfile) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_delete, 0, 0, 1) ZEND_ARG_INFO(0, entry) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_fromdir, 0, 0, 1) ZEND_ARG_INFO(0, base_dir) ZEND_ARG_INFO(0, regex) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_offsetExists, 0, 0, 1) ZEND_ARG_INFO(0, entry) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_offsetSet, 0, 0, 2) ZEND_ARG_INFO(0, entry) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_setAlias, 0, 0, 1) ZEND_ARG_INFO(0, alias) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_setMetadata, 0, 0, 1) ZEND_ARG_INFO(0, metadata) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_setSigAlgo, 0, 0, 1) ZEND_ARG_INFO(0, algorithm) ZEND_ARG_INFO(0, privatekey) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_setStub, 0, 0, 1) ZEND_ARG_INFO(0, newstub) ZEND_ARG_INFO(0, maxlen) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_emptydir, 0, 0, 0) ZEND_ARG_INFO(0, dirname) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_extract, 0, 0, 1) ZEND_ARG_INFO(0, pathto) ZEND_ARG_INFO(0, files) ZEND_ARG_INFO(0, overwrite) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_addfile, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_ARG_INFO(0, localname) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_fromstring, 0, 0, 1) ZEND_ARG_INFO(0, localname) ZEND_ARG_INFO(0, contents) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_phar_isff, 0, 0, 1) ZEND_ARG_INFO(0, fileformat) ZEND_END_ARG_INFO() @@ -5189,10 +5355,12 @@ zend_function_entry php_archive_methods[] = { }; #if HAVE_SPL +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_entry___construct, 0, 0, 1) ZEND_ARG_INFO(0, filename) ZEND_END_ARG_INFO() +PHAR_ARG_INFO ZEND_BEGIN_ARG_INFO_EX(arginfo_entry_chmod, 0, 0, 1) ZEND_ARG_INFO(0, perms) ZEND_END_ARG_INFO() diff --git a/ext/phar/phar_path_check.c b/ext/phar/phar_path_check.c index d812b7133..f41d5897c 100755 --- a/ext/phar/phar_path_check.c +++ b/ext/phar/phar_path_check.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar_path_check.c,v 1.9.2.2 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: phar_path_check.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "phar_internal.h" diff --git a/ext/phar/phar_path_check.re b/ext/phar/phar_path_check.re index 6e402d202..db92987c7 100755 --- a/ext/phar/phar_path_check.re +++ b/ext/phar/phar_path_check.re @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: phar_path_check.re,v 1.8.2.2 2008/12/31 11:13:54 sebastian Exp $ */ +/* $Id: phar_path_check.re 272369 2008-12-31 11:13:54Z sebastian $ */ #include "phar_internal.h" diff --git a/ext/phar/pharzip.h b/ext/phar/pharzip.h index 8c8afe9f1..b97b42851 100644 --- a/ext/phar/pharzip.h +++ b/ext/phar/pharzip.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pharzip.h,v 1.2.2.3 2009/02/20 05:06:37 cellog Exp $ */ +/* $Id: pharzip.h 284658 2009-07-23 16:30:27Z cellog $ */ typedef struct _phar_zip_file_header { char signature[4]; /* local file header signature 4 bytes (0x04034b50) */ @@ -37,6 +37,7 @@ typedef struct _phar_zip_file_header { /* unused in this release */ typedef struct _phar_zip_file_datadesc { + char signature[4]; /* signature (optional) 4 bytes */ char crc32[4]; /* crc-32 4 bytes */ char compsize[4]; /* compressed size 4 bytes */ char uncompsize[4]; /* uncompressed size 4 bytes */ diff --git a/ext/phar/php_phar.h b/ext/phar/php_phar.h index 1d2448759..494ef6717 100644 --- a/ext/phar/php_phar.h +++ b/ext/phar/php_phar.h @@ -17,12 +17,12 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_phar.h,v 1.16.2.3 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: php_phar.h 290601 2009-11-12 17:43:23Z johannes $ */ #ifndef PHP_PHAR_H #define PHP_PHAR_H -#define PHP_PHAR_VERSION "2.0.0-dev" +#define PHP_PHAR_VERSION "2.0.1" #include "ext/standard/basic_functions.h" extern zend_module_entry phar_module_entry; diff --git a/ext/phar/stream.c b/ext/phar/stream.c index bc38f5e75..a357ba0da 100644 --- a/ext/phar/stream.c +++ b/ext/phar/stream.c @@ -207,18 +207,30 @@ static php_stream * phar_wrapper_open_url(php_stream_wrapper *wrapper, char *pat fpf = php_stream_alloc(&phar_ops, idata, NULL, mode); php_url_free(resource); efree(internal_file); +#if PHP_MAJOR_VERSION >= 6 + if (context && context->options && phar_find_key(HASH_OF(context->options), "phar", sizeof("phar"), (void**)&pzoption TSRMLS_CC)) { +#else if (context && context->options && zend_hash_find(HASH_OF(context->options), "phar", sizeof("phar"), (void**)&pzoption) == SUCCESS) { +#endif pharcontext = HASH_OF(*pzoption); if (idata->internal_file->uncompressed_filesize == 0 && idata->internal_file->compressed_filesize == 0 +#if PHP_MAJOR_VERSION >= 6 + && phar_find_key(pharcontext, "compress", sizeof("compress"), (void**)&pzoption TSRMLS_CC) +#else && zend_hash_find(pharcontext, "compress", sizeof("compress"), (void**)&pzoption) == SUCCESS +#endif && Z_TYPE_PP(pzoption) == IS_LONG && (Z_LVAL_PP(pzoption) & ~PHAR_ENT_COMPRESSION_MASK) == 0 ) { idata->internal_file->flags &= ~PHAR_ENT_COMPRESSION_MASK; idata->internal_file->flags |= Z_LVAL_PP(pzoption); } +#if PHP_MAJOR_VERSION >= 6 + if (phar_find_key(pharcontext, "metadata", sizeof("metadata"), (void**)&pzoption TSRMLS_CC)) { +#else if (zend_hash_find(pharcontext, "metadata", sizeof("metadata"), (void**)&pzoption) == SUCCESS) { +#endif if (idata->internal_file->metadata) { zval_ptr_dtor(&idata->internal_file->metadata); idata->internal_file->metadata = NULL; @@ -635,6 +647,7 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, PHAR_STR(key, str_key); if ((int)keylen >= internal_file_len || strncmp(str_key, internal_file, keylen)) { zend_hash_move_forward_ex(&phar->mounted_dirs, &pos); + PHAR_STR_FREE(str_key); continue; } else { char *test; @@ -642,8 +655,10 @@ static int phar_wrapper_stat(php_stream_wrapper *wrapper, char *url, int flags, php_stream_statbuf ssbi; if (SUCCESS != zend_hash_find(&phar->manifest, str_key, keylen, (void **) &entry)) { + PHAR_STR_FREE(str_key); goto free_resource; } + PHAR_STR_FREE(str_key); if (!entry->tmp || !entry->is_mounted) { goto free_resource; } @@ -939,6 +954,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char zend_hash_update_current_key_ex(&phar->manifest, key_type, new_key, new_key_len, 0, HASH_UPDATE_KEY_ANYWAY, NULL); #endif } + PHAR_STR_FREE(str_key); } for (zend_hash_internal_pointer_reset(&phar->virtual_dirs); @@ -965,6 +981,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char #endif efree(new_str_key); } + PHAR_STR_FREE(str_key); } for (zend_hash_internal_pointer_reset(&phar->mounted_dirs); @@ -992,6 +1009,7 @@ static int phar_wrapper_rename(php_stream_wrapper *wrapper, char *url_from, char #endif efree(new_str_key); } + PHAR_STR_FREE(str_key); } } diff --git a/ext/phar/stream.h b/ext/phar/stream.h index 566e7eb62..4609ca686 100644 --- a/ext/phar/stream.h +++ b/ext/phar/stream.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: stream.h,v 1.3.2.4 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: stream.h 272370 2008-12-31 11:15:49Z sebastian $ */ BEGIN_EXTERN_C() diff --git a/ext/phar/stub.h b/ext/phar/stub.h index 53ab000dd..843c82074 100644 --- a/ext/phar/stub.h +++ b/ext/phar/stub.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: stub.h,v 1.13.2.3 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: stub.h 272370 2008-12-31 11:15:49Z sebastian $ */ static inline void phar_get_stub(const char *index_php, const char *web, size_t *len, char **stub, const int name_len, const int web_len TSRMLS_DC) { diff --git a/ext/phar/tar.c b/ext/phar/tar.c index 85c064990..53255b1d2 100644 --- a/ext/phar/tar.c +++ b/ext/phar/tar.c @@ -200,6 +200,7 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, tar_header *hdr; php_uint32 sum1, sum2, size, old; phar_archive_data *myphar, **actual; + int last_was_longlink = 0; if (error) { *error = NULL; @@ -255,6 +256,8 @@ int phar_parse_tarfile(php_stream* fp, char *fname, int fname_len, char *alias, phar_tar_number(hdr->size, sizeof(hdr->size)); if (((!old && hdr->prefix[0] == 0) || old) && strlen(hdr->name) == sizeof(".phar/signature.bin")-1 && !strncmp(hdr->name, ".phar/signature.bin", sizeof(".phar/signature.bin")-1)) { + off_t curloc; + if (size > 511) { if (error) { spprintf(error, 4096, "phar error: tar-based phar \"%s\" has signature that is larger than 511 bytes, cannot process", fname); @@ -264,6 +267,7 @@ bail: phar_destroy_phar_data(myphar TSRMLS_CC); return FAILURE; } + curloc = php_stream_tell(fp); read = php_stream_read(fp, buf, size); if (read != size) { if (error) { @@ -280,7 +284,8 @@ bail: #else # define PHAR_GET_32(buffer) (php_uint32) *(buffer) #endif - if (FAILURE == phar_verify_signature(fp, php_stream_tell(fp) - size - 512, PHAR_GET_32(buf), buf + 8, PHAR_GET_32(buf + 4), fname, &myphar->signature, &myphar->sig_len, error TSRMLS_CC)) { + myphar->sig_flags = PHAR_GET_32(buf); + if (FAILURE == phar_verify_signature(fp, php_stream_tell(fp) - size - 512, myphar->sig_flags, buf + 8, size - 8, fname, &myphar->signature, &myphar->sig_len, error TSRMLS_CC)) { if (error) { char *save = *error; spprintf(error, 4096, "phar error: tar-based phar \"%s\" signature cannot be verified: %s", fname, save); @@ -288,11 +293,11 @@ bail: } goto bail; } + php_stream_seek(fp, curloc + 512, SEEK_SET); /* signature checked out, let's ensure this is the last file in the phar */ - size = ((size+511)&~511) + 512; if (((hdr->typeflag == '\0') || (hdr->typeflag == TAR_FILE)) && size > 0) { /* this is not good enough - seek succeeds even on truncated tars */ - php_stream_seek(fp, size, SEEK_CUR); + php_stream_seek(fp, 512, SEEK_CUR); if ((uint)php_stream_tell(fp) > totalsize) { if (error) { spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname); @@ -328,7 +333,52 @@ bail: goto bail; } - if (!old && hdr->prefix[0] != 0) { + if (!last_was_longlink && hdr->typeflag == 'L') { + last_was_longlink = 1; + /* support the ././@LongLink system for storing long filenames */ + entry.filename_len = entry.uncompressed_filesize; + entry.filename = pemalloc(entry.filename_len+1, myphar->is_persistent); + + read = php_stream_read(fp, entry.filename, entry.filename_len); + if (read != entry.filename_len) { + efree(entry.filename); + if (error) { + spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname); + } + php_stream_close(fp); + phar_destroy_phar_data(myphar TSRMLS_CC); + return FAILURE; + } + entry.filename[entry.filename_len] = '\0'; + + /* skip blank stuff */ + size = ((size+511)&~511) - size; + + /* this is not good enough - seek succeeds even on truncated tars */ + php_stream_seek(fp, size, SEEK_CUR); + if ((uint)php_stream_tell(fp) > totalsize) { + efree(entry.filename); + if (error) { + spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname); + } + php_stream_close(fp); + phar_destroy_phar_data(myphar TSRMLS_CC); + return FAILURE; + } + + read = php_stream_read(fp, buf, sizeof(buf)); + + if (read != sizeof(buf)) { + efree(entry.filename); + if (error) { + spprintf(error, 4096, "phar error: \"%s\" is a corrupted tar file (truncated)", fname); + } + php_stream_close(fp); + phar_destroy_phar_data(myphar TSRMLS_CC); + return FAILURE; + } + continue; + } else if (!last_was_longlink && !old && hdr->prefix[0] != 0) { char name[256]; int i, j; @@ -338,8 +388,12 @@ bail: break; } } + name[i++] = '/'; for (j = 0; j < 100; j++) { name[i+j] = hdr->name[j]; + if (name[i+j] == '\0') { + break; + } } entry.filename_len = i+j; @@ -349,7 +403,7 @@ bail: entry.filename_len--; } entry.filename = pestrndup(name, entry.filename_len, myphar->is_persistent); - } else { + } else if (!last_was_longlink) { int i; /* calculate strlen, which can be no longer than 100 */ @@ -367,6 +421,7 @@ bail: entry.filename_len--; } } + last_was_longlink = 0; phar_add_virtual_dirs(myphar, entry.filename, entry.filename_len TSRMLS_CC); @@ -635,14 +690,25 @@ static int phar_tar_writeheaders(void *pDest, void *argument TSRMLS_DC) /* {{{ * memset((char *) &header, 0, sizeof(header)); if (entry->filename_len > 100) { - if (entry->filename_len > 255) { + char *boundary; + if (entry->filename_len > 256) { if (fp->error) { spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", entry->phar->fname, entry->filename); } return ZEND_HASH_APPLY_STOP; } - memcpy(header.prefix, entry->filename+100, entry->filename_len - 100); - memcpy(header.name, entry->filename, 100); + boundary = entry->filename + entry->filename_len - 101; + while (*boundary && *boundary != '/') { + ++boundary; + } + if (!*boundary || ((boundary - entry->filename) > 155)) { + if (fp->error) { + spprintf(fp->error, 4096, "tar-based phar \"%s\" cannot be created, filename \"%s\" is too long for tar file format", entry->phar->fname, entry->filename); + } + return ZEND_HASH_APPLY_STOP; + } + memcpy(header.prefix, entry->filename, boundary - entry->filename); + memcpy(header.name, boundary + 1, entry->filename_len - (boundary + 1 - entry->filename)); } else { memcpy(header.name, entry->filename, entry->filename_len); } @@ -909,7 +975,11 @@ int phar_tar_flush(phar_archive_data *phar, char *user_stub, long len, int defau len = -len; } user_stub = 0; +#if PHP_MAJOR_VERSION >= 6 + if (!(len = php_stream_copy_to_mem(stubfile, (void **) &user_stub, len, 0)) || !user_stub) { +#else if (!(len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)) || !user_stub) { +#endif if (error) { spprintf(error, 0, "unable to read resource to copy stub to new tar-based phar \"%s\"", phar->fname); } diff --git a/ext/phar/tests/009.phpt b/ext/phar/tests/009.phpt index 8b1db2f09..61933b381 100644 --- a/ext/phar/tests/009.phpt +++ b/ext/phar/tests/009.phpt @@ -9,7 +9,7 @@ phar.require_hash=0 $file = b""; -$file .= pack('VVnVVV', 500, 500, 0x1000, 0x00000000, 0, 0) . str_repeat('A', 500); +$file .= (binary) pack(b'VVnVVV', 500, 500, 0x1000, 0x00000000, 0, 0) . (binary) str_repeat((binary)'A', 500); file_put_contents(dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php', $file); try { include dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '.phar.php'; diff --git a/ext/phar/tests/016.phpt b/ext/phar/tests/016.phpt index 302d06d3c..3288e8eca 100644 --- a/ext/phar/tests/016.phpt +++ b/ext/phar/tests/016.phpt @@ -9,14 +9,14 @@ phar.require_hash=0 "; +$file = b""; // file length is too short $files = array(); // "hi" gzdeflated -$files['a'] = array('cont'=>'a','comp'=> pack('H*', 'cbc80400'),'flags'=>0x00001000, 'ulen' => 1, 'clen' => 4); +$files['a'] = array('cont'=>b'a','comp'=> (binary)pack('H*', 'cbc80400'),'flags'=>0x00001000, 'ulen' => 1, 'clen' => 4); $files['b'] = $files['a']; -$files['c'] = array('cont'=>'*'); +$files['c'] = array('cont'=>b'*'); $files['d'] = $files['a']; include 'files/phar_test.inc'; diff --git a/ext/phar/tests/badparameters.phpt b/ext/phar/tests/badparameters.phpt index 2f0e34ecf..d4291e622 100644 --- a/ext/phar/tests/badparameters.phpt +++ b/ext/phar/tests/badparameters.phpt @@ -76,11 +76,6 @@ $a->setSignatureAlgorithm(Phar::MD5); } catch (Exception $e) { echo $e->getMessage() . "\n"; } -try { -$c->setSignatureAlgorithm(Phar::MD5); -} catch (Exception $e) { -echo $e->getMessage() . "\n"; -} $a->compress(array()); try { $a->compress(1); @@ -160,7 +155,6 @@ A Phar stub cannot be set in a plain tar archive Warning: Phar::setDefaultStub() expects parameter 1 to be %string, array given in %sbadparameters.php on line %d Cannot change stub: phar.readonly=1 Cannot set signature algorithm, phar is read-only -Cannot set signature algorithm, not possible with zip-based phar archives Warning: Phar::compress() expects parameter 1 to be long, array given in %sbadparameters.php on line %d Cannot compress phar archive, phar is read-only diff --git a/ext/phar/tests/bug46032.phpt b/ext/phar/tests/bug46032.phpt index 4ff1026b5..5a88d5b42 100644 --- a/ext/phar/tests/bug46032.phpt +++ b/ext/phar/tests/bug46032.phpt @@ -6,7 +6,7 @@ Phar: bug #46032: PharData::__construct wrong memory read --FILE-- ===DONE=== --EXPECTF-- -string(%d) "%smytest" -string(%d) "%smytest" +%string|unicode%(%d) "%smytest" +%string|unicode%(%d) "%smytest" Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Cannot create phar '0000000000000000000', file extension (or combination) not recognised' in %sbug46032.php:%d Stack trace: -#0 %s(%d): PharData->__construct('000000000000000...') +#0 %sbug46032.php(%d): PharData->__construct('000000000000000...') #1 {main} thrown in %sbug46032.php on line %d diff --git a/ext/phar/tests/bug48377.2.phpt b/ext/phar/tests/bug48377.2.phpt new file mode 100644 index 000000000..be2a0e103 --- /dev/null +++ b/ext/phar/tests/bug48377.2.phpt @@ -0,0 +1,25 @@ +--TEST-- +Phar: PHP bug #48377 "error message unclear on converting phar with existing file" test #2 +--SKIPIF-- + +--INI-- +phar.require_hash=0 +phar.readonly=0 +--FILE-- +convertToData(Phar::ZIP, Phar::NONE, '.2.phar.zip'); +} catch (BadMethodCallException $e) { + echo $e->getMessage(),"\n"; +} +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +data phar "%sbug48377.2.phar.zip" has invalid extension 2.phar.zip +===DONE=== \ No newline at end of file diff --git a/ext/phar/tests/bug48377.phpt b/ext/phar/tests/bug48377.phpt new file mode 100644 index 000000000..6282a1565 --- /dev/null +++ b/ext/phar/tests/bug48377.phpt @@ -0,0 +1,29 @@ +--TEST-- +Phar: PHP bug #48377 "error message unclear on converting phar with existing file" +--SKIPIF-- + +--INI-- +phar.require_hash=0 +phar.readonly=0 +--FILE-- +convertToData(Phar::ZIP, Phar::NONE, 'zip'); +} catch (BadMethodCallException $e) { + echo $e->getMessage(),"\n"; +} +?> +===DONE=== +--CLEAN-- + + +--EXPECTF-- +phar "%sbug48377.zip" exists and must be unlinked prior to conversion +===DONE=== \ No newline at end of file diff --git a/ext/phar/tests/cache_list/copyonwrite17.phar.phpt b/ext/phar/tests/cache_list/copyonwrite17.phar.phpt index 6e1308851..158c049b1 100644 --- a/ext/phar/tests/cache_list/copyonwrite17.phar.phpt +++ b/ext/phar/tests/cache_list/copyonwrite17.phar.phpt @@ -10,5 +10,5 @@ phar.readonly=0 files/write17.phar --EXPECTF-- NULL -string(2) "hi" +%string|unicode%(2) "hi" ok \ No newline at end of file diff --git a/ext/phar/tests/cache_list/copyonwrite19.phar.phpt b/ext/phar/tests/cache_list/copyonwrite19.phar.phpt index 4870550c4..6e03554d9 100644 --- a/ext/phar/tests/cache_list/copyonwrite19.phar.phpt +++ b/ext/phar/tests/cache_list/copyonwrite19.phar.phpt @@ -10,5 +10,5 @@ phar.readonly=0 files/write19.phar --EXPECTF-- string(2) "hi" -string(3) "hi2" +%string|unicode%(3) "hi2" ok \ No newline at end of file diff --git a/ext/phar/tests/cache_list/copyonwrite6.phar.phpt b/ext/phar/tests/cache_list/copyonwrite6.phar.phpt index 6d6d56187..661fef42c 100644 --- a/ext/phar/tests/cache_list/copyonwrite6.phar.phpt +++ b/ext/phar/tests/cache_list/copyonwrite6.phar.phpt @@ -7,6 +7,7 @@ phar.readonly=0 open_basedir= --SKIPIF-- + --FILE_EXTERNAL-- files/write6.phar --CLEAN-- diff --git a/ext/phar/tests/cache_list/files/frontcontroller12.phar b/ext/phar/tests/cache_list/files/frontcontroller12.phar index 9e4558761..1cf362928 100644 Binary files a/ext/phar/tests/cache_list/files/frontcontroller12.phar and b/ext/phar/tests/cache_list/files/frontcontroller12.phar differ diff --git a/ext/phar/tests/cache_list/files/frontcontroller12.phar.inc b/ext/phar/tests/cache_list/files/frontcontroller12.phar.inc index ba17df37e..f1e4645e2 100644 --- a/ext/phar/tests/cache_list/files/frontcontroller12.phar.inc +++ b/ext/phar/tests/cache_list/files/frontcontroller12.phar.inc @@ -3,13 +3,13 @@ $a = new Phar(dirname(__FILE__) . '/frontcontroller12.phar'); $a['index.php'] = 'setStub('setStub('setStub(' "a.phps"); + static $b = array(b"/hi" => "a.phps"); if (isset($b[$a])) return $b[$a]; return $a; } diff --git a/ext/phar/tests/cache_list/files/frontcontroller4.phar b/ext/phar/tests/cache_list/files/frontcontroller4.phar index 4c9a92a19..835946181 100644 Binary files a/ext/phar/tests/cache_list/files/frontcontroller4.phar and b/ext/phar/tests/cache_list/files/frontcontroller4.phar differ diff --git a/ext/phar/tests/cache_list/files/frontcontroller4.phar.inc b/ext/phar/tests/cache_list/files/frontcontroller4.phar.inc index 5c6a43f95..daf807e41 100644 --- a/ext/phar/tests/cache_list/files/frontcontroller4.phar.inc +++ b/ext/phar/tests/cache_list/files/frontcontroller4.phar.inc @@ -7,7 +7,7 @@ $a['a.phps'] = 'setStub(' false); + static $b = array(b"/hi" => false); if (isset($b[$a])) return $b[$a]; return $a; } diff --git a/ext/phar/tests/cache_list/files/frontcontroller8.phar b/ext/phar/tests/cache_list/files/frontcontroller8.phar index ec05ceafb..c9c0e409e 100644 Binary files a/ext/phar/tests/cache_list/files/frontcontroller8.phar and b/ext/phar/tests/cache_list/files/frontcontroller8.phar differ diff --git a/ext/phar/tests/cache_list/files/frontcontroller8.phar.inc b/ext/phar/tests/cache_list/files/frontcontroller8.phar.inc index 1dfb654a0..8629f0890 100644 --- a/ext/phar/tests/cache_list/files/frontcontroller8.phar.inc +++ b/ext/phar/tests/cache_list/files/frontcontroller8.phar.inc @@ -2,7 +2,7 @@ @unlink(dirname(__FILE__) . '/frontcontroller8.phar'); $a = new Phar(dirname(__FILE__) . '/frontcontroller8.phar'); $a['a.phps'] = 'hio1'; -$a['a1.phps'] = 'setStub('getSignature(); -var_dump($sig1['hash']); -var_dump($sig2['hash']); -var_dump($sig1['hash'] != $sig2['hash']); +var_dump($sig1[b'hash']); +var_dump($sig2[b'hash']); +var_dump($sig1[b'hash'] != $sig2[b'hash']); include $pname . '/a.php'; include $pname . '/b.php'; diff --git a/ext/phar/tests/files/frontcontroller12.phar b/ext/phar/tests/files/frontcontroller12.phar index 9e4558761..315c2901e 100644 Binary files a/ext/phar/tests/files/frontcontroller12.phar and b/ext/phar/tests/files/frontcontroller12.phar differ diff --git a/ext/phar/tests/files/frontcontroller12.phar.inc b/ext/phar/tests/files/frontcontroller12.phar.inc index ba17df37e..f1e4645e2 100644 --- a/ext/phar/tests/files/frontcontroller12.phar.inc +++ b/ext/phar/tests/files/frontcontroller12.phar.inc @@ -3,13 +3,13 @@ $a = new Phar(dirname(__FILE__) . '/frontcontroller12.phar'); $a['index.php'] = 'setStub('setStub('setStub(' "a.phps"); + static $b = array(b"/hi" => b"a.phps"); if (isset($b[$a])) return $b[$a]; return $a; } diff --git a/ext/phar/tests/files/frontcontroller4.phar b/ext/phar/tests/files/frontcontroller4.phar index 4c9a92a19..004d1ffd1 100644 Binary files a/ext/phar/tests/files/frontcontroller4.phar and b/ext/phar/tests/files/frontcontroller4.phar differ diff --git a/ext/phar/tests/files/frontcontroller4.phar.inc b/ext/phar/tests/files/frontcontroller4.phar.inc index 5c6a43f95..daf807e41 100644 --- a/ext/phar/tests/files/frontcontroller4.phar.inc +++ b/ext/phar/tests/files/frontcontroller4.phar.inc @@ -7,7 +7,7 @@ $a['a.phps'] = 'setStub(' false); + static $b = array(b"/hi" => false); if (isset($b[$a])) return $b[$a]; return $a; } diff --git a/ext/phar/tests/files/frontcontroller8.phar b/ext/phar/tests/files/frontcontroller8.phar index ec05ceafb..27280a327 100644 Binary files a/ext/phar/tests/files/frontcontroller8.phar and b/ext/phar/tests/files/frontcontroller8.phar differ diff --git a/ext/phar/tests/files/frontcontroller8.phar.inc b/ext/phar/tests/files/frontcontroller8.phar.inc index 1dfb654a0..8629f0890 100644 --- a/ext/phar/tests/files/frontcontroller8.phar.inc +++ b/ext/phar/tests/files/frontcontroller8.phar.inc @@ -2,7 +2,7 @@ @unlink(dirname(__FILE__) . '/frontcontroller8.phar'); $a = new Phar(dirname(__FILE__) . '/frontcontroller8.phar'); $a['a.phps'] = 'hio1'; -$a['a1.phps'] = ' +=')) die('skip parameter parsing changed in 6.0'); ?> --INI-- phar.readonly=0 --FILE-- @@ -12,14 +13,14 @@ $pname = 'phar://' . $fname; fopen(array(), 'r'); chdir(dirname(__FILE__)); -file_put_contents($fname, "blah\n"); -file_put_contents("foob", "test\n"); +file_put_contents($fname, b"blah\n"); +file_put_contents("foob", b"test\n"); $a = fopen($fname, 'rb'); echo fread($a, 1000); fclose($a); unlink($fname); mkdir($pname . '/oops'); -file_put_contents($pname . '/foo/hi', ' + +--INI-- +phar.readonly=0 +--FILE-- + +'); +include $pname . '/foo/hi'; +?> +===DONE=== +--CLEAN-- + + + +--EXPECTF-- +Notice: Array to string conversion in %sfopen_edgecases2U.php on line 6 + +Warning: fopen(Array): failed to open stream: No such file or directory in %sfopen_edgecases2U.php on line 6 +blah +test + +Warning: fopen(phar://%sfopen_edgecases2U.phar.php/oops): failed to open stream: phar error: path "oops" is a directory in phar://%sfopen_edgecases2U.phar.php/foo/hi on line 6 +===DONE=== \ No newline at end of file diff --git a/ext/phar/tests/frontcontroller21.phpt b/ext/phar/tests/frontcontroller21.phpt index dcdbf575f..bf50c6e80 100644 --- a/ext/phar/tests/frontcontroller21.phpt +++ b/ext/phar/tests/frontcontroller21.phpt @@ -14,7 +14,7 @@ files/frontcontroller12.phar --EXPECTHEADERS-- Content-type: text/html; charset=UTF-8 --EXPECTF-- -string(10) "/index.php" +%unicode|string%(10) "/index.php" string(10) "/index.php" string(%d) "phar://%sfrontcontroller21.php/index.php" string(18) "/index.php?test=hi" diff --git a/ext/phar/tests/frontcontroller22.phpt b/ext/phar/tests/frontcontroller22.phpt index 827c5688c..b85c1eb49 100644 --- a/ext/phar/tests/frontcontroller22.phpt +++ b/ext/phar/tests/frontcontroller22.phpt @@ -13,8 +13,8 @@ files/frontcontroller13.phar --EXPECTHEADERS-- Content-type: text/html; charset=UTF-8 --EXPECTF-- -string(4) "test" -string(12) "oof/test.php" +%unicode|string%(4) "test" +%unicode|string%(12) "oof/test.php" Warning: include(./hi.php): failed to open stream: No such file or directory in phar://%s/oof/test.php on line %d diff --git a/ext/phar/tests/ini_set.phpt b/ext/phar/tests/ini_set.phpt index 01dc99589..7ccd6ea12 100644 --- a/ext/phar/tests/ini_set.phpt +++ b/ext/phar/tests/ini_set.phpt @@ -3,7 +3,6 @@ Phar: test ini_set with readonly and require_hash enabled --SKIPIF-- ")) die("skip pre-unicode version of PHP required"); ?> --INI-- phar.require_hash=1 @@ -14,18 +13,22 @@ var_dump(ini_set('phar.require_hash', 1)); var_dump(ini_set('phar.readonly', 1)); var_dump(ini_get('phar.require_hash')); var_dump(ini_get('phar.readonly')); +if (version_compare(PHP_VERSION, "5.3", "<")) { +var_dump(false, false); +} else { var_dump(ini_set('phar.require_hash', 0)); var_dump(ini_set('phar.readonly', 0)); +} var_dump(ini_get('phar.require_hash')); var_dump(ini_get('phar.readonly')); __HALT_COMPILER(); ?> ---EXPECT-- -string(1) "1" -string(1) "1" -string(1) "1" -string(1) "1" +--EXPECTF-- +%unicode|string%(1) "1" +%unicode|string%(1) "1" +%unicode|string%(1) "1" +%unicode|string%(1) "1" bool(false) bool(false) -string(1) "1" -string(1) "1" +%unicode|string%(1) "1" +%unicode|string%(1) "1" diff --git a/ext/phar/tests/ini_setU.phpt b/ext/phar/tests/ini_setU.phpt deleted file mode 100644 index 470040f7b..000000000 --- a/ext/phar/tests/ini_setU.phpt +++ /dev/null @@ -1,31 +0,0 @@ ---TEST-- -Phar: test ini_set with readonly and require_hash enabled ---SKIPIF-- - ---INI-- -phar.require_hash=1 -phar.readonly=1 ---FILE-- - ---EXPECT-- -unicode(1) "1" -unicode(1) "1" -unicode(1) "1" -unicode(1) "1" -unicode(1) "1" -unicode(1) "1" -unicode(1) "1" -unicode(1) "1" diff --git a/ext/phar/tests/phar_buildfromiterator10.phpt b/ext/phar/tests/phar_buildfromiterator10.phpt index 4dc3af7cc..024277ed0 100644 --- a/ext/phar/tests/phar_buildfromiterator10.phpt +++ b/ext/phar/tests/phar_buildfromiterator10.phpt @@ -3,7 +3,6 @@ Phar::buildFromIterator() RegexIterator(RecursiveIteratorIterator), SplFileInfo --SKIPIF-- ")) die("skip pre-unicode version of PHP required"); ?> --INI-- phar.require_hash=0 diff --git a/ext/phar/tests/phar_buildfromiterator10U.phpt b/ext/phar/tests/phar_buildfromiterator10U.phpt deleted file mode 100644 index 74f41597a..000000000 --- a/ext/phar/tests/phar_buildfromiterator10U.phpt +++ /dev/null @@ -1,101 +0,0 @@ ---TEST-- -Phar::buildFromIterator() RegexIterator(RecursiveIteratorIterator), SplFileInfo as current ---SKIPIF-- - ---INI-- -phar.require_hash=0 -phar.readonly=0 ---FILE-- -buildFromIterator(new RegexIterator($iter, '/_\d{3}\.phpt$/'), dirname(__FILE__) . DIRECTORY_SEPARATOR); - asort($a); - var_dump($a); -} catch (Exception $e) { - var_dump(get_class($e)); - echo $e->getMessage() . "\n"; -} -?> -===DONE=== ---CLEAN-- - ---EXPECTF-- -array(33) { - ["phar_ctx_001.phpt"]=> - unicode(%d) "%sphar_ctx_001.phpt" - ["phar_get_supported_signatures_001.phpt"]=> - unicode(%d) "%sphar_get_supported_signatures_001.phpt" - ["phar_get_supported_signatures_002.phpt"]=> - unicode(%d) "%sphar_get_supported_signatures_002.phpt" - ["phar_oo_001.phpt"]=> - unicode(%d) "%sphar_oo_001.phpt" - ["phar_oo_002.phpt"]=> - unicode(%d) "%sphar_oo_002.phpt" - ["phar_oo_003.phpt"]=> - unicode(%d) "%sphar_oo_003.phpt" - ["phar_oo_004.phpt"]=> - unicode(%d) "%sphar_oo_004.phpt" - ["phar_oo_005.phpt"]=> - unicode(%d) "%sphar_oo_005.phpt" - ["phar_oo_006.phpt"]=> - unicode(%d) "%sphar_oo_006.phpt" - ["phar_oo_007.phpt"]=> - unicode(%d) "%sphar_oo_007.phpt" - ["phar_oo_008.phpt"]=> - unicode(%d) "%sphar_oo_008.phpt" - ["phar_oo_009.phpt"]=> - unicode(%d) "%sphar_oo_009.phpt" - ["phar_oo_010.phpt"]=> - unicode(%d) "%sphar_oo_010.phpt" - ["phar_oo_011.phpt"]=> - unicode(%d) "%sphar_oo_011.phpt" - ["phar_oo_012.phpt"]=> - unicode(%d) "%sphar_oo_012.phpt" - ["phar_oo_compressed_001.phpt"]=> - unicode(%d) "%sphar_oo_compressed_001.phpt" - ["phar_oo_compressed_002.phpt"]=> - unicode(%d) "%sphar_oo_compressed_002.phpt" - ["phpinfo_001.phpt"]=> - unicode(%d) "%sphpinfo_001.phpt" - ["phpinfo_002.phpt"]=> - unicode(%d) "%sphpinfo_002.phpt" - ["phpinfo_003.phpt"]=> - unicode(%d) "%sphpinfo_003.phpt" - ["phpinfo_004.phpt"]=> - unicode(%d) "%sphpinfo_004.phpt" - ["tar/tar_001.phpt"]=> - unicode(%d) "%star%ctar_001.phpt" - ["tar/tar_002.phpt"]=> - unicode(%d) "%star%ctar_002.phpt" - ["tar/tar_003.phpt"]=> - unicode(%d) "%star%ctar_003.phpt" - ["tar/tar_004.phpt"]=> - unicode(%d) "%star%ctar_004.phpt" - ["zip/corrupt_001.phpt"]=> - unicode(%d) "%szip%ccorrupt_001.phpt" - ["zip/corrupt_002.phpt"]=> - unicode(%d) "%szip%ccorrupt_002.phpt" - ["zip/corrupt_003.phpt"]=> - unicode(%d) "%szip%ccorrupt_003.phpt" - ["zip/corrupt_004.phpt"]=> - unicode(%d) "%szip%ccorrupt_004.phpt" - ["zip/corrupt_005.phpt"]=> - unicode(%d) "%szip%ccorrupt_005.phpt" - ["zip/corrupt_006.phpt"]=> - unicode(%d) "%szip%ccorrupt_006.phpt" - ["zip/corrupt_007.phpt"]=> - unicode(%d) "%szip%ccorrupt_007.phpt" - ["zip/corrupt_008.phpt"]=> - unicode(%d) "%szip%ccorrupt_008.phpt" -} -===DONE=== diff --git a/ext/phar/tests/phar_bz2.phpt b/ext/phar/tests/phar_bz2.phpt index 6e05663d5..0e6e3ecb5 100644 --- a/ext/phar/tests/phar_bz2.phpt +++ b/ext/phar/tests/phar_bz2.phpt @@ -3,7 +3,6 @@ Phar: bzipped phar --SKIPIF-- ")) die("skip pre-unicode version of PHP required"); if (!extension_loaded("spl")) die("skip SPL not available"); if (!extension_loaded("bz2")) die("skip bz2 not available"); ?> @@ -56,8 +55,8 @@ echo $e->getMessage(),"\n"; @unlink(dirname(__FILE__) . '/phar_bz2.2.phar'); ?> --EXPECTF-- -string(9) "it worked" -string(%d) "phar://%sphar_bz2.phar/tar_004.php" +%unicode|string%(9) "it worked" +%unicode|string%(%d) "phar://%sphar_bz2.phar/tar_004.php" bool(true) bool(true) diff --git a/ext/phar/tests/phar_bz2U.phpt b/ext/phar/tests/phar_bz2U.phpt deleted file mode 100644 index 62f5c5812..000000000 --- a/ext/phar/tests/phar_bz2U.phpt +++ /dev/null @@ -1,66 +0,0 @@ ---TEST-- -Phar: bzipped phar ---SKIPIF-- - ---INI-- -phar.readonly=0 -phar.require_hash=0 ---FILE-- -setAlias('another'); -$b = new Phar($fname2); -var_dump($b->isFileFormat(Phar::PHAR)); -var_dump($b->isCompressed() == Phar::BZ2); -// additional code coverage -$b->isFileFormat(array()); -try { -$b->isFileFormat(25); -} catch (Exception $e) { -echo $e->getMessage(),"\n"; -} -?> -===DONE=== ---CLEAN-- - ---EXPECTF-- -unicode(9) "it worked" -unicode(%d) "phar://%sphar_bz2U.phar/tar_004.php" -bool(true) -bool(true) - -Warning: Phar::isFileFormat() expects parameter 1 to be long, array given in %sphar_bz2U.php on line %d -Unknown file format specified -===DONE=== diff --git a/ext/phar/tests/phar_convert_again.phpt b/ext/phar/tests/phar_convert_again.phpt index 9485f1e6a..bbf2c6633 100644 --- a/ext/phar/tests/phar_convert_again.phpt +++ b/ext/phar/tests/phar_convert_again.phpt @@ -62,11 +62,6 @@ $data->setAlias('hi'); } catch (Exception $e) { echo $e->getMessage() . "\n"; } -try { -$data->setSignatureAlgorithm(Phar::MD5); -} catch (Exception $e) { -echo $e->getMessage() . "\n"; -} $tar = $phar->convertToExecutable(Phar::TAR); echo $tar->getPath() . "\n"; $data = $tar->convertToData(); @@ -188,7 +183,6 @@ hi A Phar stub cannot be set in a plain zip archive A Phar stub cannot be set in a plain zip archive A Phar alias cannot be set in a plain zip archive -Cannot set signature algorithm, not possible with zip-based phar archives %sphar_convert_again2.phar.tar %sphar_convert_again2.tar %sphar_convert_again2.phar.tar.gz diff --git a/ext/phar/tests/phar_ctx_001.phpt b/ext/phar/tests/phar_ctx_001.phpt index 14b7afc71..72edc5a99 100644 --- a/ext/phar/tests/phar_ctx_001.phpt +++ b/ext/phar/tests/phar_ctx_001.phpt @@ -28,7 +28,7 @@ var_dump($phar['b']->isCompressed()); var_dump(file_get_contents($pname . '/c')); var_dump($phar['c']->isCompressed()); -$context = stream_context_create(array('phar'=> array('compress'=>Phar::GZ, 'metadata' => array(2, 'hi' => 3)))); +$context = stream_context_create(array('phar'=> array('compress'=>Phar::GZ, 'metadata' => array(2, b'hi' => 3)))); $context2 = stream_context_create(array('phar' => array('metadata' => array(4)))); file_put_contents($pname . '/a', b'new a', 0); // no compression diff --git a/ext/phar/tests/phar_magic.phpt b/ext/phar/tests/phar_magic.phpt index f6a0a675e..7c60589f9 100644 --- a/ext/phar/tests/phar_magic.phpt +++ b/ext/phar/tests/phar_magic.phpt @@ -14,6 +14,9 @@ $p['b/c.php'] = 'setStub(' +=")) die("skip requires php older than 6.0"); ?> --INI-- phar.readonly=0 --FILE-- diff --git a/ext/phar/tests/readfile_edgecasesU.phpt b/ext/phar/tests/readfile_edgecasesU.phpt new file mode 100644 index 000000000..c26b45fc5 --- /dev/null +++ b/ext/phar/tests/readfile_edgecasesU.phpt @@ -0,0 +1,61 @@ +--TEST-- +Phar: test edge cases of readfile() function interception +--SKIPIF-- + + +--INI-- +phar.readonly=0 +--FILE-- + +'); +include $pname . '/foo/hi'; +?> +===DONE=== +--CLEAN-- + + + +--EXPECTF-- +blah + +test +test + + +Warning: readfile(phar://%sreadfile_edgecasesU.phar.php/oops): failed to open stream: phar error: path "oops" is a directory in phar://%sreadfile_edgecasesU.phar.php/foo/hi on line %d +===DONE=== \ No newline at end of file diff --git a/ext/phar/tests/tar/bignames.phpt b/ext/phar/tests/tar/bignames.phpt index 4b51e2a92..c10b1cea2 100644 --- a/ext/phar/tests/tar/bignames.phpt +++ b/ext/phar/tests/tar/bignames.phpt @@ -8,30 +8,50 @@ phar.require_hash=0 getContent() . "\n"; -echo $p2[str_repeat('a', 255)]->getContent() . "\n"; +echo $p2[str_repeat('a', 100) . '/b']->getContent() . "\n"; +echo $p2[str_repeat('a', 155) . '/' . str_repeat('b', 100)]->getContent() . "\n"; try { $p2[str_repeat('a', 400)] = 'yuck'; } catch (Exception $e) { echo $e->getMessage() . "\n"; } + +try { + $p2 = new PharData($fname3); + $p2[str_repeat('a', 101)] = 'yuck'; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} + +try { + $p2 = new PharData($fname4); + $p2[str_repeat('b', 160) . '/' . str_repeat('a', 90)] = 'yuck'; +} catch (Exception $e) { + echo $e->getMessage() . "\n"; +} ?> ===DONE=== --CLEAN-- --EXPECTF-- hi hi2 tar-based phar "%sbignames.2.tar" cannot be created, filename "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" is too long for tar file format +tar-based phar "%sbignames.3.tar" cannot be created, filename "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" is too long for tar file format +tar-based phar "%sbignames.4.tar" cannot be created, filename "bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" is too long for tar file format ===DONE=== diff --git a/ext/phar/tests/tar/bignames_overflow.phpt b/ext/phar/tests/tar/bignames_overflow.phpt index 80873119f..359e9c634 100644 --- a/ext/phar/tests/tar/bignames_overflow.phpt +++ b/ext/phar/tests/tar/bignames_overflow.phpt @@ -22,8 +22,8 @@ $p1 = new PharData($fname); foreach ($p1 as $file) { echo $file->getFileName(), "\n"; } -echo $p1[str_repeat('a', 101)]->getContent() . "\n"; -echo $p1[str_repeat('a', 255)]->getContent() . "\n"; +echo $p1['a/' . str_repeat('a', 100)]->getContent() . "\n"; +echo $p1[str_repeat('a', 155) . '/' . str_repeat('a', 100)]->getContent() . "\n"; ?> ===DONE=== @@ -33,8 +33,8 @@ unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.tar'); unlink(dirname(__FILE__) . '/' . basename(__FILE__, '.clean.php') . '.2.tar'); ?> --EXPECT-- -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa -aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +a +aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa hi hi2 ===DONE=== diff --git a/ext/phar/tests/tar/bug49910.phpt b/ext/phar/tests/tar/bug49910.phpt new file mode 100644 index 000000000..6fb66a50a --- /dev/null +++ b/ext/phar/tests/tar/bug49910.phpt @@ -0,0 +1,50 @@ +--TEST-- +Bug #49910: no support for ././@LongLink for long filenames in phar tar support +--SKIPIF-- + + +--FILE-- +getPathName()); +} +print_r($files); +?> +===DONE=== +--EXPECT-- +Array +( + [0] => phar://*/Structures_Graph-1.0.3/LICENSE + [1] => phar://*/Structures_Graph-1.0.3/Structures/Graph/Manipulator/AcyclicTest.php + [2] => phar://*/Structures_Graph-1.0.3/Structures/Graph/Manipulator/TopologicalSorter.php + [3] => phar://*/Structures_Graph-1.0.3/Structures/Graph/Node.php + [4] => phar://*/Structures_Graph-1.0.3/Structures/Graph.php + [5] => phar://*/Structures_Graph-1.0.3/docs/generate.sh + [6] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/Structures_Graph.html + [7] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/Structures_Graph_Manipulator_AcyclicTest.html + [8] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/Structures_Graph_Manipulator_TopologicalSorter.html + [9] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/Structures_Graph_Node.html + [10] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/_Structures_Graph_Manipulator_AcyclicTest_php.html + [11] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/_Structures_Graph_Manipulator_TopologicalSorter_php.html + [12] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/_Structures_Graph_Node_php.html + [13] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/_Structures_Graph_php.html + [14] => phar://*/Structures_Graph-1.0.3/docs/html/Structures_Graph/tutorial_Structures_Graph.pkg.html + [15] => phar://*/Structures_Graph-1.0.3/docs/html/classtrees_Structures_Graph.html + [16] => phar://*/Structures_Graph-1.0.3/docs/html/elementindex.html + [17] => phar://*/Structures_Graph-1.0.3/docs/html/elementindex_Structures_Graph.html + [18] => phar://*/Structures_Graph-1.0.3/docs/html/errors.html + [19] => phar://*/Structures_Graph-1.0.3/docs/html/index.html + [20] => phar://*/Structures_Graph-1.0.3/docs/html/li_Structures_Graph.html + [21] => phar://*/Structures_Graph-1.0.3/docs/html/media/banner.css + [22] => phar://*/Structures_Graph-1.0.3/docs/html/media/stylesheet.css + [23] => phar://*/Structures_Graph-1.0.3/docs/html/packages.html + [24] => phar://*/Structures_Graph-1.0.3/docs/html/todolist.html + [25] => phar://*/Structures_Graph-1.0.3/docs/tutorials/Structures_Graph/Structures_Graph.pkg + [26] => phar://*/Structures_Graph-1.0.3/tests/AllTests.php + [27] => phar://*/Structures_Graph-1.0.3/tests/testCase/BasicGraph.php + [28] => phar://*/package.xml +) +===DONE=== diff --git a/ext/phar/tests/tar/files/P1-1.0.0.tgz b/ext/phar/tests/tar/files/P1-1.0.0.tgz new file mode 100644 index 000000000..1d9cae439 Binary files /dev/null and b/ext/phar/tests/tar/files/P1-1.0.0.tgz differ diff --git a/ext/phar/tests/tar/files/P1-1.0.0.tgz.pubkey b/ext/phar/tests/tar/files/P1-1.0.0.tgz.pubkey new file mode 100644 index 000000000..eb59bdd26 --- /dev/null +++ b/ext/phar/tests/tar/files/P1-1.0.0.tgz.pubkey @@ -0,0 +1,9 @@ +-----BEGIN PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4drcwddPs6LmIbdT1ifT +Ev8HXh1Fk1yNusCDoCX6mYkgqvCmx02F/9k5q7n6CPblTcF5mdDI8kcRrUHmyXtD +9X0d7RN7BakZMPH5KPaNkXiXsI9YGSb39AnZgYw01n6u0W6Ohha+KwOsrxkKCF4u +LjPLQAlM+3uD8y9Tz2fF+pAE901kHrd3ue7a5i5EtW0bzl5QfxnwFZXAO0StQ9dF +slzibRH+1pFjMRxDnlgYmLQF6jMWm9Ty6x9UH9HZ3E3F9QZEQVXWT9y/pe30HcAX +YxAGZjPIx19UNPF5C+Nps6MjxNRht0pGXTL9sptYoiNjRiXAS0y4FM+8K6xvBIOF +ZQIDAQAB +-----END PUBLIC KEY----- diff --git a/ext/phar/tests/tar/files/Structures_Graph-1.0.3.tgz b/ext/phar/tests/tar/files/Structures_Graph-1.0.3.tgz new file mode 100644 index 000000000..fa14f0c6a Binary files /dev/null and b/ext/phar/tests/tar/files/Structures_Graph-1.0.3.tgz differ diff --git a/ext/phar/tests/tar/files/frontcontroller12.phar.inc b/ext/phar/tests/tar/files/frontcontroller12.phar.inc index 693ef0aa0..0a9422a29 100644 --- a/ext/phar/tests/tar/files/frontcontroller12.phar.inc +++ b/ext/phar/tests/tar/files/frontcontroller12.phar.inc @@ -3,13 +3,13 @@ $a = new Phar(dirname(__FILE__) . '/frontcontroller12.phar.tar'); $a['index.php'] = 'setStub('setStub(' "a.phps"); + static $b = array(b"/hi" => b"a.phps"); if (isset($b[$a])) return $b[$a]; return $a; } diff --git a/ext/phar/tests/tar/files/frontcontroller3.phar.tar b/ext/phar/tests/tar/files/frontcontroller3.phar.tar index 2df61c95a..16853bd10 100644 Binary files a/ext/phar/tests/tar/files/frontcontroller3.phar.tar and b/ext/phar/tests/tar/files/frontcontroller3.phar.tar differ diff --git a/ext/phar/tests/tar/files/frontcontroller4.phar.inc b/ext/phar/tests/tar/files/frontcontroller4.phar.inc index eb1d56f0d..bfb9b4104 100644 --- a/ext/phar/tests/tar/files/frontcontroller4.phar.inc +++ b/ext/phar/tests/tar/files/frontcontroller4.phar.inc @@ -7,7 +7,7 @@ $a['a.phps'] = 'setStub(' false); + static $b = array(b"/hi" => false); if (isset($b[$a])) return $b[$a]; return $a; } diff --git a/ext/phar/tests/tar/files/frontcontroller4.phar.tar b/ext/phar/tests/tar/files/frontcontroller4.phar.tar index 4cd684d25..5a1d4ee10 100644 Binary files a/ext/phar/tests/tar/files/frontcontroller4.phar.tar and b/ext/phar/tests/tar/files/frontcontroller4.phar.tar differ diff --git a/ext/phar/tests/tar/frontcontroller21.phar.phpt b/ext/phar/tests/tar/frontcontroller21.phar.phpt index c1a299cc9..bb93996d6 100644 --- a/ext/phar/tests/tar/frontcontroller21.phar.phpt +++ b/ext/phar/tests/tar/frontcontroller21.phar.phpt @@ -14,7 +14,7 @@ files/frontcontroller12.phar.tar --EXPECTHEADERS-- Content-type: text/html; charset=UTF-8 --EXPECTF-- -string(10) "/index.php" +%unicode|string%(10) "/index.php" string(10) "/index.php" string(%d) "phar://%sfrontcontroller21.phar.php/index.php" string(18) "/index.php?test=hi" diff --git a/ext/phar/tests/tar/phar_convert_phar4.phpt b/ext/phar/tests/tar/phar_convert_phar4.phpt index f23780e1a..9b095f11c 100644 --- a/ext/phar/tests/tar/phar_convert_phar4.phpt +++ b/ext/phar/tests/tar/phar_convert_phar4.phpt @@ -14,7 +14,7 @@ $fname2 = dirname(__FILE__) . '/' . basename(__FILE__, '.php') . '2.phar'; $phar = new Phar($fname); $phar['a.txt'] = 'some text'; -$phar->setMetadata('hi'); +$phar->setMetadata(b'hi'); $phar->stopBuffering(); var_dump($phar->isFileFormat(Phar::TAR)); var_dump(strlen($phar->getStub())); diff --git a/ext/phar/tests/tar/phar_magic.phpt b/ext/phar/tests/tar/phar_magic.phpt index 1bb336f96..ed0a46297 100644 --- a/ext/phar/tests/tar/phar_magic.phpt +++ b/ext/phar/tests/tar/phar_magic.phpt @@ -15,6 +15,9 @@ $p['b/c.php'] = 'setStub(' + + + +--INI-- +phar.readonly=1 +phar.require_hash=1 +--FILE-- +getMessage()."\n"; +} + +?> +===DONE=== +--EXPECT-- +===DONE=== diff --git a/ext/phar/tests/zip/all.phpt b/ext/phar/tests/zip/all.phpt index 7fcb5f368..49d79a44c 100644 --- a/ext/phar/tests/zip/all.phpt +++ b/ext/phar/tests/zip/all.phpt @@ -46,6 +46,7 @@ var_dump($phar['a']->getMetadata()); ?> ===DONE=== --CLEAN-- + --EXPECT-- bool(false) diff --git a/ext/phar/tests/zip/bug48791.phpt b/ext/phar/tests/zip/bug48791.phpt new file mode 100644 index 000000000..45c527188 --- /dev/null +++ b/ext/phar/tests/zip/bug48791.phpt @@ -0,0 +1,15 @@ +--TEST-- +Phar: Bug #48791: open office documents always reported as corrupted by phar extension +--SKIPIF-- + + + +--FILE-- + +===DONE=== +--EXPECT-- + +ÜberschriftName:$$n_fn$$Firma:$$org_name$$Menge:$$#menge$$ +===DONE=== diff --git a/ext/phar/tests/zip/files/corrupt_zipmaker.php.inc b/ext/phar/tests/zip/files/corrupt_zipmaker.php.inc index 7c3b356c2..b993ff553 100644 --- a/ext/phar/tests/zip/files/corrupt_zipmaker.php.inc +++ b/ext/phar/tests/zip/files/corrupt_zipmaker.php.inc @@ -26,7 +26,7 @@ * @author Vincent Lascaux * @copyright 1997-2005 The PHP Group * @license http://www.gnu.org/copyleft/lesser.html LGPL - * @version CVS: $Id: corrupt_zipmaker.php.inc,v 1.5.2.2 2008/08/11 22:43:02 cellog Exp $ + * @version CVS: $Id: corrupt_zipmaker.php.inc 264655 2008-08-11 22:43:02Z cellog $ * @link http://pear.php.net/package/File_Archive */ diff --git a/ext/phar/tests/zip/files/frontcontroller12.phar.inc b/ext/phar/tests/zip/files/frontcontroller12.phar.inc index 77c4a1dd0..c5f38ffd1 100644 --- a/ext/phar/tests/zip/files/frontcontroller12.phar.inc +++ b/ext/phar/tests/zip/files/frontcontroller12.phar.inc @@ -3,13 +3,13 @@ $a = new Phar(dirname(__FILE__) . '/frontcontroller12.phar.zip'); $a['index.php'] = 'setStub('setStub(' "a.phps"); + static $b = array(b"/hi" => b"a.phps"); if (isset($b[$a])) return $b[$a]; return $a; } diff --git a/ext/phar/tests/zip/files/frontcontroller3.phar.zip b/ext/phar/tests/zip/files/frontcontroller3.phar.zip index f167f2f6e..6f35a8042 100644 Binary files a/ext/phar/tests/zip/files/frontcontroller3.phar.zip and b/ext/phar/tests/zip/files/frontcontroller3.phar.zip differ diff --git a/ext/phar/tests/zip/files/frontcontroller4.phar.inc b/ext/phar/tests/zip/files/frontcontroller4.phar.inc index d78399142..9f664cf2c 100644 --- a/ext/phar/tests/zip/files/frontcontroller4.phar.inc +++ b/ext/phar/tests/zip/files/frontcontroller4.phar.inc @@ -7,7 +7,7 @@ $a['a.phps'] = 'setStub(' false); + static $b = array(b"/hi" => false); if (isset($b[$a])) return $b[$a]; return $a; } diff --git a/ext/phar/tests/zip/files/frontcontroller4.phar.zip b/ext/phar/tests/zip/files/frontcontroller4.phar.zip index 1ad83f8a6..fb27ccb0b 100644 Binary files a/ext/phar/tests/zip/files/frontcontroller4.phar.zip and b/ext/phar/tests/zip/files/frontcontroller4.phar.zip differ diff --git a/ext/phar/tests/zip/files/test.odt b/ext/phar/tests/zip/files/test.odt new file mode 100644 index 000000000..c5cefe58e Binary files /dev/null and b/ext/phar/tests/zip/files/test.odt differ diff --git a/ext/phar/tests/zip/frontcontroller21.phar.phpt b/ext/phar/tests/zip/frontcontroller21.phar.phpt index d0a16c5d9..74caa2c81 100644 --- a/ext/phar/tests/zip/frontcontroller21.phar.phpt +++ b/ext/phar/tests/zip/frontcontroller21.phar.phpt @@ -15,7 +15,7 @@ files/frontcontroller12.phar.zip --EXPECTHEADERS-- Content-type: text/html; charset=UTF-8 --EXPECTF-- -string(10) "/index.php" +%unicode|string%(10) "/index.php" string(10) "/index.php" string(%d) "phar://%sfrontcontroller21.phar.php/index.php" string(18) "/index.php?test=hi" diff --git a/ext/phar/tests/zip/phar_magic.phpt b/ext/phar/tests/zip/phar_magic.phpt index a56639d7e..694f92777 100644 --- a/ext/phar/tests/zip/phar_magic.phpt +++ b/ext/phar/tests/zip/phar_magic.phpt @@ -21,6 +21,9 @@ $p->setStub(' + +--INI-- +phar.require_hash=0 +phar.readonly=0 +--FILE-- +getSignature()); +$p->setSignatureAlgorithm(Phar::MD5); + +copy($fname, $fname2); +$p = new Phar($fname2); +var_dump($p->getSignature()); + +$p->setSignatureAlgorithm(Phar::SHA1); + +copy($fname2, $fname3); +$p = new Phar($fname3); +var_dump($p->getSignature()); + +try { +$p->setSignatureAlgorithm(Phar::SHA256); +copy($fname3, $fname4); +$p = new Phar($fname4); +var_dump($p->getSignature()); +} catch (Exception $e) { +echo $e->getMessage(); +} +try { +$p->setSignatureAlgorithm(Phar::SHA512); +copy($fname4, $fname5); +$p = new Phar($fname5); +var_dump($p->getSignature()); +} catch (Exception $e) { +echo $e->getMessage(); +} +try { +$keys=openssl_pkey_new(); +openssl_pkey_export($keys, $privkey); +$pubkey=openssl_pkey_get_details($keys); +$p->setSignatureAlgorithm(Phar::OPENSSL, $privkey); + +copy($fname5, $fname6); +file_put_contents($fname6 . '.pubkey', $pubkey['key']); +$p = new Phar($fname6); +var_dump($p->getSignature()); +} catch (Exception $e) { +echo $e->getMessage(); +} +?> +===DONE=== +--CLEAN-- + +--EXPECTF-- +array(2) { + ["hash"]=> + string(%d) "%s" + ["hash_type"]=> + string(5) "SHA-1" +} +array(2) { + ["hash"]=> + string(%d) "%s" + ["hash_type"]=> + string(3) "MD5" +} +array(2) { + ["hash"]=> + string(%d) "%s" + ["hash_type"]=> + string(5) "SHA-1" +} +array(2) { + ["hash"]=> + string(%d) "%s" + ["hash_type"]=> + string(7) "SHA-256" +} +array(2) { + ["hash"]=> + string(%d) "%s" + ["hash_type"]=> + string(7) "SHA-512" +} +array(2) { + ["hash"]=> + string(%d) "%s" + ["hash_type"]=> + string(7) "OpenSSL" +} +===DONE=== diff --git a/ext/phar/util.c b/ext/phar/util.c index cb00cbc69..e65f76061 100644 --- a/ext/phar/util.c +++ b/ext/phar/util.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: util.c,v 1.55.2.42 2009/04/29 03:24:27 cellog Exp $ */ +/* $Id: util.c 284729 2009-07-24 23:53:24Z cellog $ */ #include "phar_internal.h" #ifdef PHAR_HASH_OK @@ -1551,6 +1551,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in PHAR_STR(key, str_key); if ((int)keylen >= path_len || strncmp(str_key, path, keylen)) { + PHAR_STR_FREE(str_key); continue; } else { char *test; @@ -1561,6 +1562,7 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in if (error) { spprintf(error, 4096, "phar internal error: mounted path \"%s\" could not be retrieved from manifest", str_key); } + PHAR_STR_FREE(str_key); return NULL; } @@ -1568,8 +1570,10 @@ phar_entry_info *phar_get_entry_info_dir(phar_archive_data *phar, char *path, in if (error) { spprintf(error, 4096, "phar internal error: mounted path \"%s\" is not properly initialized as a mounted path", str_key); } + PHAR_STR_FREE(str_key); return NULL; } + PHAR_STR_FREE(str_key); test_len = spprintf(&test, MAXPATHLEN, "%s%s", entry->tmp, path + keylen); @@ -1661,10 +1665,19 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end, Z_TYPE_P(zdata) = IS_STRING; Z_STRLEN_P(zdata) = end; +#if PHP_MAJOR_VERSION > 5 + if (end != (off_t) php_stream_copy_to_mem(fp, (void **) &(Z_STRVAL_P(zdata)), (size_t) end, 0)) { +#else if (end != (off_t) php_stream_copy_to_mem(fp, &(Z_STRVAL_P(zdata)), (size_t) end, 0)) { +#endif zval_dtor(zdata); zval_dtor(zsig); zval_dtor(zkey); + zval_dtor(openssl); + efree(openssl); + efree(zdata); + efree(zkey); + efree(zsig); return FAILURE; } @@ -1678,6 +1691,9 @@ static int phar_call_openssl_signverify(int is_sign, php_stream *fp, off_t end, zval_dtor(zkey); zval_dtor(openssl); efree(openssl); + efree(zdata); + efree(zkey); + efree(zsig); return FAILURE; } @@ -1796,7 +1812,14 @@ int phar_verify_signature(php_stream *fp, size_t end_of_phar, php_uint32 sig_typ pfp = php_stream_open_wrapper(pfile, "rb", 0, NULL); efree(pfile); +#if PHP_MAJOR_VERSION > 5 + if (!pfp || !(pubkey_len = php_stream_copy_to_mem(pfp, (void **) &pubkey, PHP_STREAM_COPY_ALL, 0)) || !pubkey) { +#else if (!pfp || !(pubkey_len = php_stream_copy_to_mem(pfp, &pubkey, PHP_STREAM_COPY_ALL, 0)) || !pubkey) { +#endif + if (pfp) { + php_stream_close(pfp); + } if (error) { spprintf(error, 0, "openssl public key could not be read"); } diff --git a/ext/phar/zip.c b/ext/phar/zip.c index ee365d0d1..383561ab8 100644 --- a/ext/phar/zip.c +++ b/ext/phar/zip.c @@ -172,6 +172,7 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, phar_archive_data *mydata = NULL; phar_entry_info entry = {0}; char *p = buf, *ext, *actual_alias = NULL; + char *metadata = NULL; size = php_stream_tell(fp); @@ -222,7 +223,6 @@ int phar_parse_zipfile(php_stream *fp, char *fname, int fname_len, char *alias, /* read in archive comment, if any */ if (PHAR_GET_16(locator.comment_len)) { - char *metadata; metadata = p + sizeof(locator); @@ -299,6 +299,30 @@ foundit: entry.is_zip = 1; entry.fp_type = PHAR_FP; entry.is_persistent = mydata->is_persistent; +#define PHAR_ZIP_FAIL_FREE(errmsg, save) \ + zend_hash_destroy(&mydata->manifest); \ + mydata->manifest.arBuckets = 0; \ + zend_hash_destroy(&mydata->mounted_dirs); \ + mydata->mounted_dirs.arBuckets = 0; \ + zend_hash_destroy(&mydata->virtual_dirs); \ + mydata->virtual_dirs.arBuckets = 0; \ + php_stream_close(fp); \ + if (mydata->metadata) { \ + zval_dtor(mydata->metadata); \ + } \ + if (mydata->signature) { \ + efree(mydata->signature); \ + } \ + if (error) { \ + spprintf(error, 4096, "phar error: %s in zip-based phar \"%s\"", errmsg, mydata->fname); \ + } \ + pefree(mydata->fname, mydata->is_persistent); \ + if (mydata->alias) { \ + pefree(mydata->alias, mydata->is_persistent); \ + } \ + pefree(mydata, mydata->is_persistent); \ + efree(save); \ + return FAILURE; #define PHAR_ZIP_FAIL(errmsg) \ zend_hash_destroy(&mydata->manifest); \ mydata->manifest.arBuckets = 0; \ @@ -310,6 +334,9 @@ foundit: if (mydata->metadata) { \ zval_dtor(mydata->metadata); \ } \ + if (mydata->signature) { \ + efree(mydata->signature); \ + } \ if (error) { \ spprintf(error, 4096, "phar error: %s in zip-based phar \"%s\"", errmsg, mydata->fname); \ } \ @@ -323,6 +350,7 @@ foundit: /* add each central directory item to the manifest */ for (i = 0; i < PHAR_GET_16(locator.count); ++i) { phar_zip_central_dir_file zipentry; + off_t beforeus = php_stream_tell(fp); if (sizeof(zipentry) != php_stream_read(fp, (char *) &zipentry, sizeof(zipentry))) { PHAR_ZIP_FAIL("unable to read central directory entry, truncated"); @@ -374,6 +402,58 @@ foundit: entry.is_dir = 0; } + if (entry.filename_len == sizeof(".phar/signature.bin")-1 && !strncmp(entry.filename, ".phar/signature.bin", sizeof(".phar/signature.bin")-1)) { + size_t read; + php_stream *sigfile; + off_t now; + char *sig; + + now = php_stream_tell(fp); + pefree(entry.filename, entry.is_persistent); + sigfile = php_stream_fopen_tmpfile(); + + php_stream_seek(fp, 0, SEEK_SET); + /* copy file contents + local headers and zip comment, if any, to be hashed for signature */ + phar_stream_copy_to_stream(fp, sigfile, entry.header_offset, NULL); + /* seek to central directory */ + php_stream_seek(fp, PHAR_GET_32(locator.cdir_offset), SEEK_SET); + /* copy central directory header */ + phar_stream_copy_to_stream(fp, sigfile, beforeus - PHAR_GET_32(locator.cdir_offset), NULL); + if (metadata) { + php_stream_write(sigfile, metadata, PHAR_GET_16(locator.comment_len)); + } + php_stream_seek(fp, sizeof(phar_zip_file_header) + entry.header_offset + entry.filename_len + PHAR_GET_16(zipentry.extra_len), SEEK_SET); + sig = (char *) emalloc(entry.uncompressed_filesize); + read = php_stream_read(fp, sig, entry.uncompressed_filesize); + if (read != entry.uncompressed_filesize) { + php_stream_close(sigfile); + efree(sig); + PHAR_ZIP_FAIL("signature cannot be read"); + } + mydata->sig_flags = PHAR_GET_32(sig); + if (FAILURE == phar_verify_signature(sigfile, php_stream_tell(sigfile), mydata->sig_flags, sig + 8, entry.uncompressed_filesize - 8, fname, &mydata->signature, &mydata->sig_len, error TSRMLS_CC)) { + efree(sig); + if (error) { + char *save; + php_stream_close(sigfile); + spprintf(&save, 4096, "signature cannot be verified: %s", *error); + efree(*error); + PHAR_ZIP_FAIL_FREE(save, save); + } else { + php_stream_close(sigfile); + PHAR_ZIP_FAIL("signature cannot be verified"); + } + } + php_stream_close(sigfile); + efree(sig); + /* signature checked out, let's ensure this is the last file in the phar */ + if (i != PHAR_GET_16(locator.count) - 1) { + PHAR_ZIP_FAIL("entries exist after signature, invalid phar"); + } + + continue; + } + phar_add_virtual_dirs(mydata, entry.filename, entry.filename_len TSRMLS_CC); if (PHAR_GET_16(zipentry.extra_len)) { @@ -520,7 +600,11 @@ foundit: php_stream_filter_append(&fp->readfilters, filter); +#if PHP_MAJOR_VERSION >= 6 + if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, (void **) &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) { +#else if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) { +#endif pefree(entry.filename, entry.is_persistent); #if PHP_VERSION_ID < 50207 PHAR_ZIP_FAIL("unable to read in alias, truncated (PHP 5.2.7 and newer has a potential fix for this problem)"); @@ -541,7 +625,11 @@ foundit: php_stream_filter_append(&fp->readfilters, filter); +#if PHP_MAJOR_VERSION >= 6 + if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, (void **) &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) { +#else if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) { +#endif pefree(entry.filename, entry.is_persistent); #if PHP_VERSION_ID < 50207 PHAR_ZIP_FAIL("unable to read in alias, truncated (PHP 5.2.7 and newer has a potential fix for this problem)"); @@ -552,7 +640,11 @@ foundit: php_stream_filter_flush(filter, 1); php_stream_filter_remove(filter, 1 TSRMLS_CC); } else { +#if PHP_MAJOR_VERSION >= 6 + if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, (void **) &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) { +#else if (!(entry.uncompressed_filesize = php_stream_copy_to_mem(fp, &actual_alias, entry.uncompressed_filesize, 0)) || !actual_alias) { +#endif pefree(entry.filename, entry.is_persistent); PHAR_ZIP_FAIL("unable to read in alias, truncated"); } @@ -1000,6 +1092,76 @@ continue_dir: } /* }}} */ +static int phar_zip_applysignature(phar_archive_data *phar, struct _phar_zip_pass *pass, + smart_str *metadata TSRMLS_DC) /* {{{ */ +{ + /* add signature for executable tars or tars explicitly set with setSignatureAlgorithm */ + if (!phar->is_data || phar->sig_flags) { + int signature_length; + char *signature, sigbuf[8]; + phar_entry_info entry = {0}; + php_stream *newfile; + off_t tell, st; + + newfile = php_stream_fopen_tmpfile(); + st = tell = php_stream_tell(pass->filefp); + /* copy the local files, central directory, and the zip comment to generate the hash */ + php_stream_seek(pass->filefp, 0, SEEK_SET); + phar_stream_copy_to_stream(pass->filefp, newfile, tell, NULL); + tell = php_stream_tell(pass->centralfp); + php_stream_seek(pass->centralfp, 0, SEEK_SET); + phar_stream_copy_to_stream(pass->centralfp, newfile, tell, NULL); + if (metadata->c) { + php_stream_write(newfile, metadata->c, metadata->len); + } + + if (FAILURE == phar_create_signature(phar, newfile, &signature, &signature_length, pass->error TSRMLS_CC)) { + if (pass->error) { + char *save = *(pass->error); + spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar: %s", save); + efree(save); + } + + php_stream_close(newfile); + return FAILURE; + } + + entry.filename = ".phar/signature.bin"; + entry.filename_len = sizeof(".phar/signature.bin")-1; + entry.fp = php_stream_fopen_tmpfile(); + entry.fp_type = PHAR_MOD; + entry.is_modified = 1; + + PHAR_SET_32(sigbuf, phar->sig_flags); + PHAR_SET_32(sigbuf + 4, signature_length); + + if (8 != (int)php_stream_write(entry.fp, sigbuf, 8) || signature_length != (int)php_stream_write(entry.fp, signature, signature_length)) { + efree(signature); + if (pass->error) { + spprintf(pass->error, 0, "phar error: unable to write signature to zip-based phar %s", phar->fname); + } + + php_stream_close(newfile); + return FAILURE; + } + + efree(signature); + entry.uncompressed_filesize = entry.compressed_filesize = signature_length + 8; + entry.phar = phar; + /* throw out return value and write the signature */ + phar_zip_changed_apply((void *)&entry, (void *)pass TSRMLS_CC); + php_stream_close(newfile); + + if (pass->error && *(pass->error)) { + /* error is set by writeheaders */ + php_stream_close(newfile); + return FAILURE; + } + } /* signature */ + return SUCCESS; +} +/* }}} */ + int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defaultstub, char **error TSRMLS_DC) /* {{{ */ { char *pos; @@ -1084,7 +1246,11 @@ int phar_zip_flush(phar_archive_data *phar, char *user_stub, long len, int defau user_stub = 0; +#if PHP_MAJOR_VERSION >= 6 + if (!(len = php_stream_copy_to_mem(stubfile, (void **) &user_stub, len, 0)) || !user_stub) { +#else if (!(len = php_stream_copy_to_mem(stubfile, &user_stub, len, 0)) || !user_stub) { +#endif if (error) { spprintf(error, 0, "unable to read resource to copy stub to new zip-based phar \"%s\"", phar->fname); } @@ -1214,10 +1380,24 @@ fperror: memset(&eocd, 0, sizeof(eocd)); strncpy(eocd.signature, "PK\5\6", 4); - PHAR_SET_16(eocd.counthere, zend_hash_num_elements(&phar->manifest)); - PHAR_SET_16(eocd.count, zend_hash_num_elements(&phar->manifest)); + if (!phar->is_data && !phar->sig_flags) { + phar->sig_flags = PHAR_SIG_SHA1; + } + if (phar->sig_flags) { + PHAR_SET_16(eocd.counthere, zend_hash_num_elements(&phar->manifest) + 1); + PHAR_SET_16(eocd.count, zend_hash_num_elements(&phar->manifest) + 1); + } else { + PHAR_SET_16(eocd.counthere, zend_hash_num_elements(&phar->manifest)); + PHAR_SET_16(eocd.count, zend_hash_num_elements(&phar->manifest)); + } zend_hash_apply_with_argument(&phar->manifest, phar_zip_changed_apply, (void *) &pass TSRMLS_CC); + if (phar->metadata) { + /* set phar metadata */ + PHP_VAR_SERIALIZE_INIT(metadata_hash); + php_var_serialize(&main_metadata_str, &phar->metadata, &metadata_hash TSRMLS_CC); + PHP_VAR_SERIALIZE_DESTROY(metadata_hash); + } if (temperr) { if (error) { spprintf(error, 4096, "phar zip flush of \"%s\" failed: %s", phar->fname, temperr); @@ -1226,6 +1406,9 @@ fperror: temperror: php_stream_close(pass.centralfp); nocentralerror: + if (phar->metadata) { + smart_str_free(&main_metadata_str); + } php_stream_close(pass.filefp); if (closeoldfile) { php_stream_close(oldfile); @@ -1233,6 +1416,10 @@ nocentralerror: return EOF; } + if (FAILURE == phar_zip_applysignature(phar, &pass, &main_metadata_str TSRMLS_CC)) { + goto temperror; + } + /* save zip */ cdir_size = php_stream_tell(pass.centralfp); cdir_offset = php_stream_tell(pass.filefp); @@ -1255,9 +1442,6 @@ nocentralerror: if (phar->metadata) { /* set phar metadata */ - PHP_VAR_SERIALIZE_INIT(metadata_hash); - php_var_serialize(&main_metadata_str, &phar->metadata, &metadata_hash TSRMLS_CC); - PHP_VAR_SERIALIZE_DESTROY(metadata_hash); PHAR_SET_16(eocd.comment_len, main_metadata_str.len); if (sizeof(eocd) != php_stream_write(pass.filefp, (char *)&eocd, sizeof(eocd))) { diff --git a/ext/posix/config.m4 b/ext/posix/config.m4 index 9f648536d..eb02958af 100644 --- a/ext/posix/config.m4 +++ b/ext/posix/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.12.4.5.2.2 2009/01/21 19:22:39 jani Exp $ +dnl $Id: config.m4 274134 2009-01-21 19:22:39Z jani $ dnl PHP_ARG_ENABLE(posix,whether to enable POSIX-like functions, diff --git a/ext/posix/php_posix.h b/ext/posix/php_posix.h index eff709190..fdc69b79e 100644 --- a/ext/posix/php_posix.h +++ b/ext/posix/php_posix.h @@ -17,7 +17,7 @@ */ -/* $Id: php_posix.h,v 1.18.2.1.2.2.2.2 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: php_posix.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_POSIX_H #define PHP_POSIX_H diff --git a/ext/posix/posix.c b/ext/posix/posix.c index beedd3894..1e6c5eccc 100644 --- a/ext/posix/posix.c +++ b/ext/posix/posix.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: posix.c,v 1.70.2.3.2.16.2.15 2009/06/06 02:40:48 mattwil Exp $ */ +/* $Id: posix.c 289424 2009-10-09 14:46:48Z pajoye $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -310,7 +310,7 @@ const zend_function_entry posix_functions[] = { static PHP_MINFO_FUNCTION(posix) { php_info_print_table_start(); - php_info_print_table_row(2, "Revision", "$Revision: 1.70.2.3.2.16.2.15 $"); + php_info_print_table_row(2, "Revision", "$Revision: 289424 $"); php_info_print_table_end(); } /* }}} */ @@ -651,7 +651,7 @@ PHP_FUNCTION(posix_times) PHP_POSIX_NO_ARGS; - if((ticks = times(&t)) < 0) { + if ((ticks = times(&t)) == -1) { POSIX_G(last_error) = errno; RETURN_FALSE; } @@ -840,7 +840,8 @@ PHP_FUNCTION(posix_mkfifo) RETURN_FALSE; } - if (PG(safe_mode) && (!php_checkuid(path, NULL, CHECKUID_ALLOW_ONLY_DIR))) { + if (php_check_open_basedir_ex(path, 0 TSRMLS_CC) || + (PG(safe_mode) && (!php_checkuid(path, NULL, CHECKUID_ALLOW_ONLY_DIR)))) { RETURN_FALSE; } @@ -1361,6 +1362,10 @@ PHP_FUNCTION(posix_initgroups) RETURN_FALSE; } + if (name_len == 0) { + RETURN_FALSE; + } + RETURN_BOOL(!initgroups((const char *)name, basegid)); } /* }}} */ diff --git a/ext/posix/tests/posix_ctermid_basic.phpt b/ext/posix/tests/posix_ctermid_basic.phpt new file mode 100644 index 000000000..d1d46943b --- /dev/null +++ b/ext/posix/tests/posix_ctermid_basic.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test function posix_ctermid() by calling it with its expected arguments +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +string(%d) %s diff --git a/ext/posix/tests/posix_ctermid_error.phpt b/ext/posix/tests/posix_ctermid_error.phpt new file mode 100644 index 000000000..a177f5457 --- /dev/null +++ b/ext/posix/tests/posix_ctermid_error.phpt @@ -0,0 +1,19 @@ +--TEST-- +Test function posix_ctermid() by calling it more than or less than its expected arguments +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +--EXPECTF-- +Warning: posix_ctermid() expects exactly 0 parameters, 1 given in %s on line %d +NULL diff --git a/ext/posix/tests/posix_errno_basic.phpt b/ext/posix/tests/posix_errno_basic.phpt new file mode 100644 index 000000000..cd94a9751 --- /dev/null +++ b/ext/posix/tests/posix_errno_basic.phpt @@ -0,0 +1,22 @@ +--TEST-- +Test function posix_errno() by calling it with its expected arguments +--CREDITS-- +Morten Amundsen mor10am@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Test by calling method or function with its expected arguments *** +int(0) diff --git a/ext/posix/tests/posix_errno_error.phpt b/ext/posix/tests/posix_errno_error.phpt new file mode 100644 index 000000000..0a77fb000 --- /dev/null +++ b/ext/posix/tests/posix_errno_error.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test function posix_errno() by calling it with its expected arguments +--SKIPIF-- + +--CREDITS-- +Morten Amundsen mor10am@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +--EXPECTF-- +*** Test by calling method or function with more than expected arguments *** + +Warning: posix_errno() expects exactly 0 parameters, 1 given in %s on line %d +NULL diff --git a/ext/posix/tests/posix_errno_variation1.phpt b/ext/posix/tests/posix_errno_variation1.phpt new file mode 100644 index 000000000..aa9889f7f --- /dev/null +++ b/ext/posix/tests/posix_errno_variation1.phpt @@ -0,0 +1,22 @@ +--TEST-- +Test function posix_errno() by calling it with with permission error +--CREDITS-- +Morten Amundsen mor10am@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Test by calling function with permission error *** +int(1) diff --git a/ext/posix/tests/posix_errno_variation2.phpt b/ext/posix/tests/posix_errno_variation2.phpt new file mode 100644 index 000000000..f463d7875 --- /dev/null +++ b/ext/posix/tests/posix_errno_variation2.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test function posix_errno() by calling it with its expected arguments +--CREDITS-- +Morten Amundsen mor10am@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +*** Test by calling function with pid error *** +int(3) diff --git a/ext/posix/tests/posix_getcwd.phpt b/ext/posix/tests/posix_getcwd.phpt index fc5a6d43e..75c8d575b 100644 --- a/ext/posix/tests/posix_getcwd.phpt +++ b/ext/posix/tests/posix_getcwd.phpt @@ -1,6 +1,6 @@ --TEST-- posix_getcwd(): Basic tests ---SKIP-- +--SKIPIF-- +--FILE-- + +--EXPECTF-- +int(%d) diff --git a/ext/posix/tests/posix_geteuid_error1.phpt b/ext/posix/tests/posix_geteuid_error1.phpt new file mode 100644 index 000000000..ac4e0d5dd --- /dev/null +++ b/ext/posix/tests/posix_geteuid_error1.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test function posix_geteuid() by calling it more than or less than its expected arguments +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + '1234', 'string' => 'string' ); + +var_dump( posix_geteuid( $extra_args )); +foreach ( $extra_args as $arg ) +{ + var_dump(posix_geteuid( $arg )); +} + +?> +--EXPECTF-- +*** Test by calling method or function with incorrect numbers of arguments *** + +Warning: posix_geteuid() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: posix_geteuid() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: posix_geteuid() expects exactly 0 parameters, 1 given in %s on line %d +NULL + +Warning: posix_geteuid() expects exactly 0 parameters, 1 given in %s on line %d +NULL diff --git a/ext/posix/tests/posix_getgrnam.phpt b/ext/posix/tests/posix_getgrnam.phpt index 9d24f085e..854db4ac1 100644 --- a/ext/posix/tests/posix_getgrnam.phpt +++ b/ext/posix/tests/posix_getgrnam.phpt @@ -1,6 +1,6 @@ --TEST-- posix_getgrnam(): Basic tests ---SKIP-- +--SKIPIF-- +--FILE-- + +--EXPECTF-- +bool(true) diff --git a/ext/posix/tests/posix_seteuid_error.phpt b/ext/posix/tests/posix_seteuid_error.phpt new file mode 100644 index 000000000..b10e41075 --- /dev/null +++ b/ext/posix/tests/posix_seteuid_error.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test function posix_seteuid() by calling it more than or less than its expected arguments +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +--EXPECTF-- +*** Test by calling method or function with incorrect numbers of arguments *** + +Warning: posix_seteuid() expects exactly 1 parameter, 2 given in %s on line 9 +bool(false) + +Warning: posix_seteuid() expects exactly 1 parameter, 0 given in %s on line 10 +bool(false) diff --git a/ext/posix/tests/posix_seteuid_error2.phpt b/ext/posix/tests/posix_seteuid_error2.phpt new file mode 100644 index 000000000..808f2d32d --- /dev/null +++ b/ext/posix/tests/posix_seteuid_error2.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test function posix_seteuid() by substituting argument 1 with object values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_seteuid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with object values *** +Error: 2 - posix_seteuid() expects parameter 1 to be long, object given, %s +bool(false) +Error: 2 - posix_seteuid() expects parameter 1 to be long, object given, %s +bool(false) diff --git a/ext/posix/tests/posix_seteuid_variation1.phpt b/ext/posix/tests/posix_seteuid_variation1.phpt new file mode 100644 index 000000000..841bfe0db --- /dev/null +++ b/ext/posix/tests/posix_seteuid_variation1.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test function posix_seteuid() by substituting argument 1 with array values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 'one', 2 => 'two'); + +$variation_array = array( + 'empty array' => array(), + 'int indexed array' => $index_array, + 'associative array' => $assoc_array, + 'nested arrays' => array('foo', $index_array, $assoc_array), + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_seteuid( $var ) ); +} + +?> +--EXPECTF-- +Warning: posix_seteuid() expects parameter 1 to be long, array given in %s on line 15 +bool(false) + +Warning: posix_seteuid() expects parameter 1 to be long, array given in %s on line 15 +bool(false) + +Warning: posix_seteuid() expects parameter 1 to be long, array given in %s on line 15 +bool(false) + +Warning: posix_seteuid() expects parameter 1 to be long, array given in %s on line 15 +bool(false) diff --git a/ext/posix/tests/posix_seteuid_variation2.phpt b/ext/posix/tests/posix_seteuid_variation2.phpt new file mode 100644 index 000000000..2ab7302ce --- /dev/null +++ b/ext/posix/tests/posix_seteuid_variation2.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test function posix_seteuid() by substituting argument 1 with boolean values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + true, + 'lowercase false' =>false, + 'uppercase TRUE' =>TRUE, + 'uppercase FALSE' =>FALSE, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_seteuid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with boolean values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_seteuid_variation3.phpt b/ext/posix/tests/posix_seteuid_variation3.phpt new file mode 100644 index 000000000..70c05c86e --- /dev/null +++ b/ext/posix/tests/posix_seteuid_variation3.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test function posix_seteuid() by substituting argument 1 with emptyUnsetUndefNull values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + @$unset_var, + 'undefined var' => @$undefined_var, + 'empty string DQ' => "", + 'empty string SQ' => '', + 'uppercase NULL' => NULL, + 'lowercase null' => null, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_seteuid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with emptyUnsetUndefNull values *** +bool(false) +bool(false) + +Warning: posix_seteuid() expects parameter 1 to be long, string given in %s on line 22 +bool(false) + +Warning: posix_seteuid() expects parameter 1 to be long, string given in %s on line 22 +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_seteuid_variation4.phpt b/ext/posix/tests/posix_seteuid_variation4.phpt new file mode 100644 index 000000000..65291417e --- /dev/null +++ b/ext/posix/tests/posix_seteuid_variation4.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test function posix_seteuid() by substituting argument 1 with float values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + $myUid, + 'float -'.$myUid => -$myUid, + 'float 12.3456789000e10' => 12.3456789000e10, + 'float -12.3456789000e10' => -12.3456789000e10, + 'float .5' => .5, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_seteuid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with float values *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_seteuid_variation5.phpt b/ext/posix/tests/posix_seteuid_variation5.phpt new file mode 100644 index 000000000..91d3a72e9 --- /dev/null +++ b/ext/posix/tests/posix_seteuid_variation5.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test function posix_seteuid() by substituting argument 1 with int values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 0, + 'int 1' => 1, + 'int -12345' => -12345, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_seteuid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with int values *** +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_seteuid_variation6.phpt b/ext/posix/tests/posix_seteuid_variation6.phpt new file mode 100644 index 000000000..65ff56be0 --- /dev/null +++ b/ext/posix/tests/posix_seteuid_variation6.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test function posix_seteuid() by substituting argument 1 with string values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_seteuid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with string values *** + +Warning: posix_seteuid() expects parameter 1 to be long, string given in %s on line 21 +bool(false) + +Warning: posix_seteuid() expects parameter 1 to be long, string given in %s on line 21 +bool(false) + +Warning: posix_seteuid() expects parameter 1 to be long, string given in %s on line 21 +bool(false) + +Warning: posix_seteuid() expects parameter 1 to be long, string given in %s on line 21 +bool(false) diff --git a/ext/posix/tests/posix_setgid_basic.phpt b/ext/posix/tests/posix_setgid_basic.phpt new file mode 100644 index 000000000..da3751fea --- /dev/null +++ b/ext/posix/tests/posix_setgid_basic.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test function posix_setgid() by calling it with its expected arguments +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +===DONE=== +--EXPECTF-- +*** Test by calling method or function with its expected arguments *** +bool(true) +===DONE=== + \ No newline at end of file diff --git a/ext/posix/tests/posix_setgid_error.phpt b/ext/posix/tests/posix_setgid_error.phpt new file mode 100644 index 000000000..247435d94 --- /dev/null +++ b/ext/posix/tests/posix_setgid_error.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test function posix_setgid() by calling it more than or less than its expected arguments. +--CREDITS-- +--SKIPIF-- + +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +===DONE=== +--EXPECTF-- +*** Test by calling method or function with incorrect numbers of arguments *** + +Warning: posix_setgid() expects exactly 1 parameter, 2 given in %s on line %d +bool(false) + +Warning: posix_setgid() expects exactly 1 parameter, 0 given in %s on line %d +bool(false) +===DONE=== diff --git a/ext/posix/tests/posix_setgid_variation1.phpt b/ext/posix/tests/posix_setgid_variation1.phpt new file mode 100644 index 000000000..3690a7718 --- /dev/null +++ b/ext/posix/tests/posix_setgid_variation1.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test function posix_setgid() by substituting argument 1 with array values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 'one', 2 => 'two'); + +$variation_array = array( + 'empty array' => array(), + 'int indexed array' => $index_array, + 'associative array' => $assoc_array, + 'nested arrays' => array('foo', $index_array, $assoc_array), + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setgid( $var ) ); +} +?> +===DONE=== +--EXPECTF-- +*** Test substituting argument 1 with array values *** + +Warning: posix_setgid() expects parameter 1 to be long, array given in %s on line %d +bool(false) + +Warning: posix_setgid() expects parameter 1 to be long, array given in %s on line %d +bool(false) + +Warning: posix_setgid() expects parameter 1 to be long, array given in %s on line %d +bool(false) + +Warning: posix_setgid() expects parameter 1 to be long, array given in %s on line %d +bool(false) +===DONE=== diff --git a/ext/posix/tests/posix_setgid_variation2.phpt b/ext/posix/tests/posix_setgid_variation2.phpt new file mode 100644 index 000000000..6d53b0837 --- /dev/null +++ b/ext/posix/tests/posix_setgid_variation2.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test function posix_setgid() by substituting argument 1 with boolean values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + true, + 'lowercase false' =>false, + 'uppercase TRUE' =>TRUE, + 'uppercase FALSE' =>FALSE, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setgid( $var ) ); +} +?> +===DONE=== +--EXPECTF-- +*** Test substituting argument 1 with boolean values *** +bool(false) +bool(false) +bool(false) +bool(false) +===DONE=== + \ No newline at end of file diff --git a/ext/posix/tests/posix_setgid_variation3.phpt b/ext/posix/tests/posix_setgid_variation3.phpt new file mode 100644 index 000000000..5855746f0 --- /dev/null +++ b/ext/posix/tests/posix_setgid_variation3.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test function posix_setgid() by substituting argument 1 with emptyUnsetUndefNull values. +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- + +--FILE-- + @$unset_var, + 'undefined var' => @$undefined_var, + 'empty string DQ' => "", + 'empty string SQ' => '', + 'uppercase NULL' => NULL, + 'lowercase null' => null, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setgid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with emptyUnsetUndefNull values *** +bool(false) +bool(false) + +Warning: posix_setgid() expects parameter 1 to be long, string given in %s on line %d +bool(false) + +Warning: posix_setgid() expects parameter 1 to be long, string given in %s on line %d +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_setgid_variation4.phpt b/ext/posix/tests/posix_setgid_variation4.phpt new file mode 100644 index 000000000..2bd209bd3 --- /dev/null +++ b/ext/posix/tests/posix_setgid_variation4.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test function posix_setgid() by substituting argument 1 with float values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 12.3456789000e10, + 'float -12.3456789000e10' => -12.3456789000e10, + 'float .5' => .5, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setgid( $var ) ); +} +?> +===DONE=== +--EXPECTF-- +*** Test substituting argument 1 with float values *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +===DONE=== + \ No newline at end of file diff --git a/ext/posix/tests/posix_setgid_variation5.phpt b/ext/posix/tests/posix_setgid_variation5.phpt new file mode 100644 index 000000000..91f2bb593 --- /dev/null +++ b/ext/posix/tests/posix_setgid_variation5.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test function posix_setgid() by substituting argument 1 with int values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 0, + 'long 1' => 1, + 'int -12345' => -2345, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setgid( $var ) ); +} +?> +===DONE=== +--EXPECTF-- +*** Test substituting argument 1 with int values *** +bool(false) +bool(false) +bool(false) +===DONE=== + \ No newline at end of file diff --git a/ext/posix/tests/posix_setgid_variation6.phpt b/ext/posix/tests/posix_setgid_variation6.phpt new file mode 100644 index 000000000..8557fd2e8 --- /dev/null +++ b/ext/posix/tests/posix_setgid_variation6.phpt @@ -0,0 +1,58 @@ +--TEST-- +Test function posix_setgid() by substituting argument 1 with object values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setgid( $var ) ); +} +?> +===DONE=== +--EXPECTF-- +*** Test substituting argument 1 with object values *** +Error: 2 - posix_setgid() expects parameter 1 to be long, object given, %s +bool(false) +Error: 2 - posix_setgid() expects parameter 1 to be long, object given, %s +bool(false) +===DONE=== + \ No newline at end of file diff --git a/ext/posix/tests/posix_setgid_variation7.phpt b/ext/posix/tests/posix_setgid_variation7.phpt new file mode 100644 index 000000000..f8083c38f --- /dev/null +++ b/ext/posix/tests/posix_setgid_variation7.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test function posix_setgid() by substituting argument 1 with string values. +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- + +--FILE-- + "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setgid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with string values *** + +Warning: posix_setgid() expects parameter 1 to be long, string given in %s on line %d +bool(false) + +Warning: posix_setgid() expects parameter 1 to be long, string given in %s on line %d +bool(false) + +Warning: posix_setgid() expects parameter 1 to be long, string given in %s on line %d +bool(false) + +Warning: posix_setgid() expects parameter 1 to be long, string given in %s on line %d +bool(false) diff --git a/ext/posix/tests/posix_setuid_basic.phpt b/ext/posix/tests/posix_setuid_basic.phpt new file mode 100644 index 000000000..986b0be62 --- /dev/null +++ b/ext/posix/tests/posix_setuid_basic.phpt @@ -0,0 +1,19 @@ +--TEST-- +Test function posix_setuid() by calling it with its expected arguments +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(true) diff --git a/ext/posix/tests/posix_setuid_error.phpt b/ext/posix/tests/posix_setuid_error.phpt new file mode 100644 index 000000000..8aa51586a --- /dev/null +++ b/ext/posix/tests/posix_setuid_error.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test function posix_setuid() by calling it more than or less than its expected arguments +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +--EXPECTF-- +*** Test by calling method or function with incorrect numbers of arguments *** + +Warning: posix_setuid() expects exactly 1 parameter, 2 given in %s on line 11 +bool(false) + +Warning: posix_setuid() expects exactly 1 parameter, 0 given in %s on line 13 +bool(false) diff --git a/ext/posix/tests/posix_setuid_error2.phpt b/ext/posix/tests/posix_setuid_error2.phpt new file mode 100644 index 000000000..6ec0aa9af --- /dev/null +++ b/ext/posix/tests/posix_setuid_error2.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test function posix_setuid() by substituting argument 1 with object values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setuid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with object values *** +Error: 2 - posix_setuid() expects parameter 1 to be long, object given, %s +bool(false) +Error: 2 - posix_setuid() expects parameter 1 to be long, object given, %s +bool(false) diff --git a/ext/posix/tests/posix_setuid_variation1.phpt b/ext/posix/tests/posix_setuid_variation1.phpt new file mode 100644 index 000000000..bf6d4376c --- /dev/null +++ b/ext/posix/tests/posix_setuid_variation1.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test function posix_setuid() by substituting argument 1 with array values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 'one', 2 => 'two'); + +$variation_array = array( + 'empty array' => array(), + 'int indexed array' => $index_array, + 'associative array' => $assoc_array, + 'nested arrays' => array('foo', $index_array, $assoc_array), + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setuid( $var ) ); +} + +?> +--EXPECTF-- +Warning: posix_setuid() expects parameter 1 to be long, array given in %s on line 15 +bool(false) + +Warning: posix_setuid() expects parameter 1 to be long, array given in %s on line 15 +bool(false) + +Warning: posix_setuid() expects parameter 1 to be long, array given in %s on line 15 +bool(false) + +Warning: posix_setuid() expects parameter 1 to be long, array given in %s on line 15 +bool(false) diff --git a/ext/posix/tests/posix_setuid_variation2.phpt b/ext/posix/tests/posix_setuid_variation2.phpt new file mode 100644 index 000000000..c8ef92827 --- /dev/null +++ b/ext/posix/tests/posix_setuid_variation2.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test function posix_setuid() by substituting argument 1 with boolean values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + true, + 'lowercase false' =>false, + 'uppercase TRUE' =>TRUE, + 'uppercase FALSE' =>FALSE, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setuid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with boolean values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_setuid_variation3.phpt b/ext/posix/tests/posix_setuid_variation3.phpt new file mode 100644 index 000000000..1630cd1d0 --- /dev/null +++ b/ext/posix/tests/posix_setuid_variation3.phpt @@ -0,0 +1,47 @@ +--TEST-- +Test function posix_setuid() by substituting argument 1 with emptyUnsetUndefNull values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + @$unset_var, + 'undefined var' => @$undefined_var, + 'empty string DQ' => "", + 'empty string SQ' => '', + 'uppercase NULL' => NULL, + 'lowercase null' => null, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setuid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with emptyUnsetUndefNull values *** +bool(false) +bool(false) + +Warning: posix_setuid() expects parameter 1 to be long, string given in %s on line 22 +bool(false) + +Warning: posix_setuid() expects parameter 1 to be long, string given in %s on line 22 +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_setuid_variation4.phpt b/ext/posix/tests/posix_setuid_variation4.phpt new file mode 100644 index 000000000..167596492 --- /dev/null +++ b/ext/posix/tests/posix_setuid_variation4.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test function posix_setuid() by substituting argument 1 with float values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + $myUid, + 'float -'.$myUid => -$myUid, + 'float 12.3456789000e10' => 12.3456789000e10, + 'float -12.3456789000e10' => -12.3456789000e10, + 'float .5' => .5, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setuid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with float values *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_setuid_variation5.phpt b/ext/posix/tests/posix_setuid_variation5.phpt new file mode 100644 index 000000000..e1b7c05e0 --- /dev/null +++ b/ext/posix/tests/posix_setuid_variation5.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test function posix_setuid() by substituting argument 1 with int values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 0, + 'int 1' => 1, + 'int -12345' => -12345, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setuid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with int values *** +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_setuid_variation6.phpt b/ext/posix/tests/posix_setuid_variation6.phpt new file mode 100644 index 000000000..79e614fec --- /dev/null +++ b/ext/posix/tests/posix_setuid_variation6.phpt @@ -0,0 +1,48 @@ +--TEST-- +Test function posix_setuid() by substituting argument 1 with string values. +--SKIPIF-- + +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_setuid( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with string values *** + +Warning: posix_setuid() expects parameter 1 to be long, string given in %s on line 21 +bool(false) + +Warning: posix_setuid() expects parameter 1 to be long, string given in %s on line 21 +bool(false) + +Warning: posix_setuid() expects parameter 1 to be long, string given in %s on line 21 +bool(false) + +Warning: posix_setuid() expects parameter 1 to be long, string given in %s on line 21 +bool(false) diff --git a/ext/posix/tests/posix_ttyname_error.phpt b/ext/posix/tests/posix_ttyname_error.phpt new file mode 100644 index 000000000..e3ec695e5 --- /dev/null +++ b/ext/posix/tests/posix_ttyname_error.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test function posix_ttyname() by calling it more than or less than its expected arguments +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +--EXPECTF-- +*** Test by calling method or function with incorrect numbers of arguments *** + +Warning: posix_ttyname() expects exactly 1 parameter, 2 given in %s on line %d +bool(false) + +Warning: posix_ttyname() expects exactly 1 parameter, 0 given in %s on line %d +bool(false) diff --git a/ext/posix/tests/posix_ttyname_variation1.phpt b/ext/posix/tests/posix_ttyname_variation1.phpt new file mode 100644 index 000000000..072b9fa67 --- /dev/null +++ b/ext/posix/tests/posix_ttyname_variation1.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test function posix_ttyname() by substituting argument 1 with array values. +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 'one', 2 => 'two'); + +$variation_array = array( + 'empty array' => array(), + 'int indexed array' => $index_array, + 'associative array' => $assoc_array, + 'nested arrays' => array('foo', $index_array, $assoc_array), + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_ttyname( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with array values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_ttyname_variation2.phpt b/ext/posix/tests/posix_ttyname_variation2.phpt new file mode 100644 index 000000000..f46821b0c --- /dev/null +++ b/ext/posix/tests/posix_ttyname_variation2.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test function posix_ttyname() by substituting argument 1 with boolean values. +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + true, + 'lowercase false' =>false, + 'uppercase TRUE' =>TRUE, + 'uppercase FALSE' =>FALSE, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_ttyname( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with boolean values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_ttyname_variation3.phpt b/ext/posix/tests/posix_ttyname_variation3.phpt new file mode 100644 index 000000000..30054265a --- /dev/null +++ b/ext/posix/tests/posix_ttyname_variation3.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test function posix_ttyname() by substituting argument 1 with emptyUnsetUndefNull values. +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + @$unset_var, + 'undefined var' => @$undefined_var, + 'empty string DQ' => "", + 'empty string SQ' => '', + 'uppercase NULL' => NULL, + 'lowercase null' => null, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_ttyname( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with emptyUnsetUndefNull values *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_ttyname_variation4.phpt b/ext/posix/tests/posix_ttyname_variation4.phpt new file mode 100644 index 000000000..321549279 --- /dev/null +++ b/ext/posix/tests/posix_ttyname_variation4.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test function posix_ttyname() by substituting argument 1 with float values. +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 12.3456789000e10, + 'float -12.3456789000e10' => -12.3456789000e10, + 'float .5' => .5, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_ttyname( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with float values *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_ttyname_variation5.phpt b/ext/posix/tests/posix_ttyname_variation5.phpt new file mode 100644 index 000000000..661dd606f --- /dev/null +++ b/ext/posix/tests/posix_ttyname_variation5.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test function posix_ttyname() by substituting argument 1 with int values. +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 12345, + 'int -12345' => -2345, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_ttyname( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with int values *** +bool(false) +bool(false) diff --git a/ext/posix/tests/posix_ttyname_variation6.phpt b/ext/posix/tests/posix_ttyname_variation6.phpt new file mode 100644 index 000000000..020aef115 --- /dev/null +++ b/ext/posix/tests/posix_ttyname_variation6.phpt @@ -0,0 +1,51 @@ +--TEST-- +Test function posix_ttyname() by substituting argument 1 with object values. +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_ttyname( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with object values *** +Error: 8 - Object of class classWithToString could not be converted to int, %s(%d) +bool(false) +Error: 8 - Object of class classWithoutToString could not be converted to int, %s(%d) +bool(false) diff --git a/ext/posix/tests/posix_ttyname_variation7.phpt b/ext/posix/tests/posix_ttyname_variation7.phpt new file mode 100644 index 000000000..b39916c5b --- /dev/null +++ b/ext/posix/tests/posix_ttyname_variation7.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test function posix_ttyname() by substituting argument 1 with string values. +--CREDITS-- +Marco Fabbri mrfabbri@gmail.com +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + ); + + +foreach ( $variation_array as $var ) { + var_dump(posix_ttyname( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with string values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/pspell/config.m4 b/ext/pspell/config.m4 index 85d0d3b0d..99030b2ac 100644 --- a/ext/pspell/config.m4 +++ b/ext/pspell/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.12 2005/05/29 23:16:43 sniper Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(pspell,for PSPELL support, diff --git a/ext/pspell/config.w32 b/ext/pspell/config.w32 index 2be33e7de..aebe1d25c 100644 --- a/ext/pspell/config.w32 +++ b/ext/pspell/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.2 2004/01/07 20:06:30 wez Exp $ +// $Id: config.w32 242949 2007-09-26 15:44:16Z cvs2svn $ // vim:ft=javascript ARG_WITH("pspell", "pspell/aspell (whatever it's called this month) support", "no"); diff --git a/ext/pspell/php_pspell.h b/ext/pspell/php_pspell.h index c938356fe..525a2c9d3 100644 --- a/ext/pspell/php_pspell.h +++ b/ext/pspell/php_pspell.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_pspell.h,v 1.15.2.1.2.3.2.2 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: php_pspell.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef _PSPELL_H #define _PSPELL_H diff --git a/ext/pspell/pspell.c b/ext/pspell/pspell.c index 9aa3297e6..692d597d9 100644 --- a/ext/pspell/pspell.c +++ b/ext/pspell/pspell.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pspell.c,v 1.45.2.4.2.7.2.10 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: pspell.c 272370 2008-12-31 11:15:49Z sebastian $ */ #define IS_EXT_MODULE diff --git a/ext/pspell/tests/001.phpt b/ext/pspell/tests/001.phpt index 7c6b4d516..5d73a43a0 100644 --- a/ext/pspell/tests/001.phpt +++ b/ext/pspell/tests/001.phpt @@ -8,7 +8,7 @@ if (!@pspell_new ("en", "", "", "", (PSPELL_FAST|PSPELL_RUN_TOGETHER))) { } ?> --FILE-- -properties_info, prop_name, prop_name_size, zend_get_hash_value(prop_name, prop_name_size))) { - count++; - _property_string(&dyn, NULL, prop_name, sub_indent.string TSRMLS_CC); + if (zend_hash_get_current_key_ex(properties, &prop_name, &prop_name_size, &index, 1, &pos) == HASH_KEY_IS_STRING) { + if (prop_name_size && prop_name[0]) { /* skip all private and protected properties */ + if (!zend_hash_quick_exists(&ce->properties_info, prop_name, prop_name_size, zend_get_hash_value(prop_name, prop_name_size))) { + count++; + _property_string(&dyn, NULL, prop_name, sub_indent.string TSRMLS_CC); + } } + efree(prop_name); } - efree(prop_name); + zend_hash_move_forward_ex(properties, &pos); } - zend_hash_move_forward_ex(properties, &pos); } string_printf(str, "\n%s - Dynamic properties [%d] {\n", indent, count); @@ -1514,8 +1516,18 @@ ZEND_METHOD(reflection_function, __construct) fptr = (zend_function*)zend_get_closure_method_def(closure TSRMLS_CC); Z_ADDREF_P(closure); } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &name_str, &name_len) == SUCCESS) { + char *nsname; + lcname = zend_str_tolower_dup(name_str, name_len); - if (zend_hash_find(EG(function_table), lcname, name_len + 1, (void **)&fptr) == FAILURE) { + + /* Ignore leading "\" */ + nsname = lcname; + if (lcname[0] == '\\') { + nsname = &lcname[1]; + name_len--; + } + + if (zend_hash_find(EG(function_table), nsname, name_len + 1, (void **)&fptr) == FAILURE) { efree(lcname); zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, "Function %s() does not exist", name_str); @@ -1717,7 +1729,7 @@ ZEND_METHOD(reflection_function, getStaticVariables) } /* }}} */ -/* {{{ proto public mixed ReflectionFunction::invoke(mixed* args) +/* {{{ proto public mixed ReflectionFunction::invoke([mixed* args]) Invokes the function */ ZEND_METHOD(reflection_function, invoke) { @@ -1732,7 +1744,7 @@ ZEND_METHOD(reflection_function, invoke) METHOD_NOTSTATIC(reflection_function_ptr); GET_REFLECTION_OBJECT_PTR(fptr); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "+", ¶ms, &num_args) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "*", ¶ms, &num_args) == FAILURE) { return; } @@ -1754,7 +1766,9 @@ ZEND_METHOD(reflection_function, invoke) result = zend_call_function(&fci, &fcc TSRMLS_CC); - efree(params); + if (num_args) { + efree(params); + } if (result == FAILURE) { zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, @@ -2660,11 +2674,11 @@ ZEND_METHOD(reflection_method, invokeArgs) { if (mptr->common.fn_flags & ZEND_ACC_ABSTRACT) { zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, - "Trying to invoke abstract method %s::%s", + "Trying to invoke abstract method %s::%s()", mptr->common.scope->name, mptr->common.function_name); } else { zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, - "Trying to invoke %s method %s::%s from scope %s", + "Trying to invoke %s method %s::%s() from scope %s", mptr->common.fn_flags & ZEND_ACC_PROTECTED ? "protected" : "private", mptr->common.scope->name, mptr->common.function_name, Z_OBJCE_P(getThis())->name); @@ -2691,7 +2705,7 @@ ZEND_METHOD(reflection_method, invokeArgs) if (!object) { efree(params); zend_throw_exception_ex(reflection_exception_ptr, 0 TSRMLS_CC, - "Trying to invoke non static method %s::%s without an object", + "Trying to invoke non static method %s::%s() without an object", mptr->common.scope->name, mptr->common.function_name); return; } @@ -3026,6 +3040,7 @@ ZEND_METHOD(reflection_class, getStaticProperties) if (zend_parse_parameters_none() == FAILURE) { return; } + GET_REFLECTION_OBJECT_PTR(ce); zend_update_class_constants(ce TSRMLS_CC); @@ -3041,12 +3056,20 @@ ZEND_METHOD(reflection_class, getStaticProperties) if (zend_hash_get_current_key_ex(CE_STATIC_MEMBERS(ce), &key, &key_len, &num_index, 0, &pos) != FAILURE && key) { char *prop_name, *class_name; + zval *prop_copy; zend_unmangle_property_name(key, key_len-1, &class_name, &prop_name); - zval_add_ref(value); + /* filter privates from base classes */ + if (!(class_name && class_name[0] != '*' && strcmp(class_name, ce->name))) { + /* copy: enforce read only access */ + ALLOC_ZVAL(prop_copy); + *prop_copy = **value; + zval_copy_ctor(prop_copy); + INIT_PZVAL(prop_copy); - zend_hash_update(Z_ARRVAL_P(return_value), prop_name, strlen(prop_name)+1, value, sizeof(zval *), NULL); + add_assoc_zval(return_value, prop_name, prop_copy); + } } zend_hash_move_forward_ex(CE_STATIC_MEMBERS(ce), &pos); } @@ -5008,7 +5031,7 @@ ZEND_BEGIN_ARG_INFO(arginfo_reflection_function___construct, 0) ZEND_ARG_INFO(0, name) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_reflection_function_invoke, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_reflection_function_invoke, 0, 0, 0) ZEND_ARG_INFO(0, args) ZEND_END_ARG_INFO() @@ -5442,7 +5465,7 @@ PHP_MINFO_FUNCTION(reflection) /* {{{ */ php_info_print_table_start(); php_info_print_table_header(2, "Reflection", "enabled"); - php_info_print_table_row(2, "Version", "$Revision: 1.164.2.33.2.45.2.58 $"); + php_info_print_table_row(2, "Version", "$Revision: 287991 $"); php_info_print_table_end(); } /* }}} */ @@ -5456,7 +5479,7 @@ zend_module_entry reflection_module_entry = { /* {{{ */ NULL, NULL, PHP_MINFO(reflection), - "$Revision: 1.164.2.33.2.45.2.58 $", + "$Revision: 287991 $", STANDARD_MODULE_PROPERTIES }; /* }}} */ diff --git a/ext/reflection/php_reflection.h b/ext/reflection/php_reflection.h index e38ee3663..d280a9f4e 100644 --- a/ext/reflection/php_reflection.h +++ b/ext/reflection/php_reflection.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_reflection.h,v 1.4.2.3.2.2.2.2 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: php_reflection.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_REFLECTION_H #define PHP_REFLECTION_H diff --git a/ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt b/ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt new file mode 100644 index 000000000..6b440cfe0 --- /dev/null +++ b/ext/reflection/tests/ReflectionClass_CannotClone_basic.phpt @@ -0,0 +1,15 @@ +--TEST-- +Reflection class can not be cloned +--CREDITS-- +Stefan Koopmanschap +TestFest PHP|Tek +--SKIPIF-- + +--FILE-- + stat pubC in B [statProtC] => stat protC in B - [statPrivC] => stat privC in A + [statPrivC] => stat privC in B [statPubB] => stat pubB in B [statProtB] => stat protB in B [statPrivB] => stat privB in B [statPubA] => stat pubA in A [statProtA] => stat protA in A - [statPrivA] => stat privA in A ) @@ -146,13 +145,11 @@ Array ( [statPubC] => stat pubC in C [statProtC] => stat protC in C - [statPrivC] => stat privC in A + [statPrivC] => stat privC in C [statPubB] => stat pubB in B [statProtB] => stat protB in B - [statPrivB] => stat privB in B [statPubA] => stat pubA in A [statProtA] => stat protA in A - [statPrivA] => stat privA in A ) @@ -195,4 +192,3 @@ Array [protC] => protC in X [privC] => privC in X ) - diff --git a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt index 70a3bab9c..082ef676c 100644 --- a/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt +++ b/ext/reflection/tests/ReflectionClass_setStaticPropertyValue_001.phpt @@ -67,11 +67,11 @@ Array ) Array ( - [privateOverridden] => new value 4 + [privateOverridden] => new value 5 [protectedOverridden] => new value 6 [publicOverridden] => new value 7 ) Set non-existent values from A with no default value: Class A does not have a property named protectedOverridden -Class A does not have a property named privateOverridden \ No newline at end of file +Class A does not have a property named privateOverridden diff --git a/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt b/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt new file mode 100644 index 000000000..eeaf8d382 --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_isClosure_basic.phpt @@ -0,0 +1,18 @@ +--TEST-- +Reflection::isClosure +--CREDITS-- +Stefan Koopmanschap +TestFest PHP|Tek +--SKIPIF-- + +--FILE-- +isClosure()); +--EXPECTF-- +bool(true) diff --git a/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt b/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt new file mode 100644 index 000000000..31d37a85f --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_isDeprecated_basic.phpt @@ -0,0 +1,15 @@ +--TEST-- +ReflectionFunction::isDeprecated +--CREDITS-- +Stefan Koopmanschap +TestFest PHP|Tek +--SKIPIF-- + +--FILE-- +isDeprecated()); +--EXPECTF-- +bool(true) diff --git a/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt b/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt new file mode 100644 index 000000000..c71b96b8e --- /dev/null +++ b/ext/reflection/tests/ReflectionFunction_isDisabled_basic.phpt @@ -0,0 +1,17 @@ +--TEST-- +ReflectionFunction::isDisabled +--CREDITS-- +Stefan Koopmanschap +TestFest PHP|Tek +--SKIPIF-- + +--INI-- +disable_functions=is_file +--FILE-- +isDisabled()); +--EXPECTF-- +bool(true) diff --git a/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt b/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt index a0a336a9a..513cc1845 100644 --- a/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt +++ b/ext/reflection/tests/ReflectionMethod_invokeArgs_error3.phpt @@ -109,9 +109,9 @@ NULL NULL Private method: -string(84) "Trying to invoke private method TestClass::privateMethod from scope ReflectionMethod" +string(86) "Trying to invoke private method TestClass::privateMethod() from scope ReflectionMethod" Abstract method: -string(51) "Trying to invoke abstract method AbstractClass::foo" +string(53) "Trying to invoke abstract method AbstractClass::foo()" Warning: ReflectionMethod::invokeArgs() expects exactly 2 parameters, 1 given in %s on line %d diff --git a/ext/reflection/tests/bug46064.phpt b/ext/reflection/tests/bug46064.phpt index 89c5af37d..510e71b00 100644 --- a/ext/reflection/tests/bug46064.phpt +++ b/ext/reflection/tests/bug46064.phpt @@ -37,10 +37,6 @@ class bar extends test { $this->foobar = 2; $this->a = 200; - $p = new reflectionproperty($this, 'a'); - $p->setAccessible(true); - var_dump($p->getValue($this), $p->isDefault(), $p->isPublic()); - $p = new reflectionproperty($this, 'foobar'); var_dump($p->getValue($this), $p->isDefault(), $p->isPublic()); } @@ -49,8 +45,9 @@ class bar extends test { new bar; ?> +===DONE=== --EXPECTF-- -object(ReflectionProperty)#2 (2) { +object(ReflectionProperty)#%d (2) { ["name"]=> string(1) "z" ["class"]=> @@ -67,15 +64,13 @@ array(1) { int(1000) --------------------------- string(30) "Property x::$zz does not exist" -object(ReflectionProperty)#3 (2) { +object(ReflectionProperty)#%d (2) { ["name"]=> string(3) "zzz" ["class"]=> string(1) "x" } -int(200) -bool(true) -bool(false) int(2) bool(false) bool(true) +===DONE=== diff --git a/ext/reflection/tests/bug46064_2.phpt b/ext/reflection/tests/bug46064_2.phpt index 832d13c41..da14148a7 100644 --- a/ext/reflection/tests/bug46064_2.phpt +++ b/ext/reflection/tests/bug46064_2.phpt @@ -36,14 +36,15 @@ class test extends bar { new test; ?> ---EXPECT-- -object(ReflectionProperty)#3 (2) { +===DONE=== +--EXPECTF-- +object(ReflectionProperty)#%d (2) { ["name"]=> string(4) "test" ["class"]=> string(3) "foo" } -object(ReflectionProperty)#5 (2) { +object(ReflectionProperty)#%d (2) { ["name"]=> string(1) "a" ["class"]=> @@ -56,17 +57,18 @@ bool(true) bool(false) array(2) { [0]=> - &object(ReflectionProperty)#6 (2) { + &object(ReflectionProperty)#%d (2) { ["name"]=> string(1) "b" ["class"]=> string(4) "test" } [1]=> - &object(ReflectionProperty)#7 (2) { + &object(ReflectionProperty)#%d (2) { ["name"]=> string(1) "a" ["class"]=> string(4) "test" } } +===DONE=== \ No newline at end of file diff --git a/ext/reflection/tests/bug47254.phpt b/ext/reflection/tests/bug47254.phpt new file mode 100644 index 000000000..4bcce1bb7 --- /dev/null +++ b/ext/reflection/tests/bug47254.phpt @@ -0,0 +1,42 @@ +--TEST-- +Bug #47254 +--CREDITS-- +Sebastian Schürmann +sebs@php.net +Testfest 2009 Munich +--FILE-- +getMethods(); +print_r($m); + +?> +--CLEAN-- +--EXPECT-- +Array +( + [0] => ReflectionMethod Object + ( + [name] => b + [class] => B + ) + + [1] => ReflectionMethod Object + ( + [name] => a + [class] => A + ) + +) diff --git a/ext/reflection/tests/bug48757.phpt b/ext/reflection/tests/bug48757.phpt new file mode 100644 index 000000000..a5ced91d3 --- /dev/null +++ b/ext/reflection/tests/bug48757.phpt @@ -0,0 +1,21 @@ +--TEST-- +Bug #48757 (ReflectionFunction::invoke() parameter issues) +--FILE-- +invoke(); + +$func = new ReflectionFunction('another_test'); +$func->invoke('testing'); +?> +--EXPECT-- +Hello World +string(7) "testing" diff --git a/ext/reflection/tests/bug49074.phpt b/ext/reflection/tests/bug49074.phpt new file mode 100644 index 000000000..7ce23b41e --- /dev/null +++ b/ext/reflection/tests/bug49074.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #49074 (private class static fields can be modified by using reflection) +--FILE-- +getStaticProperties(); + +$m['data1'] = 100; +$m['data2'] = 200; +$m['data3'] = 300; +$m['data4'] = 400; + +var_dump($r->getStaticProperties()); +?> +--EXPECT-- +array(2) { + ["data2"]=> + int(2) + ["data3"]=> + int(3) +} diff --git a/ext/reflection/tests/bug49092.phpt b/ext/reflection/tests/bug49092.phpt new file mode 100644 index 000000000..460a13127 --- /dev/null +++ b/ext/reflection/tests/bug49092.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #49092 (ReflectionFunction fails to work with functions in fully qualified namespaces) +--FILE-- + +--EXPECT-- +Ok diff --git a/ext/session/config.m4 b/ext/session/config.m4 index 7286a6b77..8a0d4c0f8 100644 --- a/ext/session/config.m4 +++ b/ext/session/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.28 2005/05/29 23:16:44 sniper Exp $ +dnl $Id: config.m4 286445 2009-07-28 08:59:08Z tony2001 $ dnl PHP_ARG_ENABLE(session, whether to enable PHP sessions, @@ -12,6 +12,7 @@ if test "$PHP_SESSION" != "no"; then PHP_PWRITE_TEST PHP_PREAD_TEST PHP_NEW_EXTENSION(session, session.c mod_files.c mod_mm.c mod_user.c, $ext_shared) + PHP_ADD_EXTENSION_DEP(session, hash, true) PHP_SUBST(SESSION_SHARED_LIBADD) PHP_INSTALL_HEADERS(ext/session, [php_session.h mod_files.h mod_user.h]) AC_DEFINE(HAVE_PHP_SESSION,1,[ ]) diff --git a/ext/session/config.w32 b/ext/session/config.w32 index 4d5dcd31d..353ff73f8 100644 --- a/ext/session/config.w32 +++ b/ext/session/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.1 2003/12/02 23:16:56 wez Exp $ +// $Id: config.w32 145409 2003-12-02 23:17:04Z wez $ // vim:ft=javascript ARG_ENABLE("session", "session support", "yes"); diff --git a/ext/session/mod_files.c b/ext/session/mod_files.c index 105f6d597..045acdfab 100644 --- a/ext/session/mod_files.c +++ b/ext/session/mod_files.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mod_files.c,v 1.100.2.3.2.10.2.5 2009/05/18 16:10:09 jani Exp $ */ +/* $Id: mod_files.c 280729 2009-05-18 16:10:09Z jani $ */ #include "php.h" diff --git a/ext/session/mod_files.h b/ext/session/mod_files.h index bbfe69801..2522f6f28 100644 --- a/ext/session/mod_files.h +++ b/ext/session/mod_files.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mod_files.h,v 1.11.2.1.2.1.2.2 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: mod_files.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef MOD_FILES_H #define MOD_FILES_H diff --git a/ext/session/mod_mm.c b/ext/session/mod_mm.c index e5ba2fbe5..37623da39 100644 --- a/ext/session/mod_mm.c +++ b/ext/session/mod_mm.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mod_mm.c,v 1.46.2.1.2.5.2.3 2009/05/18 16:10:09 jani Exp $ */ +/* $Id: mod_mm.c 280729 2009-05-18 16:10:09Z jani $ */ #include "php.h" diff --git a/ext/session/mod_mm.h b/ext/session/mod_mm.h index 085090f6e..983424f9f 100644 --- a/ext/session/mod_mm.h +++ b/ext/session/mod_mm.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mod_mm.h,v 1.12.2.1.2.1.2.2 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: mod_mm.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef MOD_MM_H #define MOD_MM_H diff --git a/ext/session/mod_user.c b/ext/session/mod_user.c index 1449a848c..f1e922fd1 100644 --- a/ext/session/mod_user.c +++ b/ext/session/mod_user.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mod_user.c,v 1.29.2.1.2.1.2.4 2009/05/18 16:10:09 jani Exp $ */ +/* $Id: mod_user.c 280729 2009-05-18 16:10:09Z jani $ */ #include "php.h" #include "php_session.h" diff --git a/ext/session/mod_user.h b/ext/session/mod_user.h index 88958df49..3ee546e4d 100644 --- a/ext/session/mod_user.h +++ b/ext/session/mod_user.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mod_user.h,v 1.14.2.1.2.1.2.3 2008/12/31 11:15:42 sebastian Exp $ */ +/* $Id: mod_user.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef MOD_USER_H #define MOD_USER_H diff --git a/ext/session/php_session.h b/ext/session/php_session.h index 8dafb5303..4dcab6c21 100644 --- a/ext/session/php_session.h +++ b/ext/session/php_session.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_session.h,v 1.101.2.2.2.5.2.6 2009/05/18 16:10:09 jani Exp $ */ +/* $Id: php_session.h 280729 2009-05-18 16:10:09Z jani $ */ #ifndef PHP_SESSION_H #define PHP_SESSION_H diff --git a/ext/session/session.c b/ext/session/session.c index a4469b218..05a66f231 100644 --- a/ext/session/session.c +++ b/ext/session/session.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: session.c,v 1.417.2.8.2.40.2.22 2009/05/18 16:10:09 jani Exp $ */ +/* $Id: session.c 286443 2009-07-28 08:54:23Z tony2001 $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -347,7 +347,6 @@ static char *bin_to_readable(char *in, size_t inlen, char *out, char nbits) /* { } /* }}} */ -#define PS_ID_INITIAL_SIZE 100 PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS) /* {{{ */ { PHP_MD5_CTX md5_context; @@ -358,7 +357,7 @@ PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS) /* {{{ */ unsigned char *digest; int digest_len; int j; - char *buf; + char *buf, *outid; struct timeval tv; zval **array; zval **token; @@ -406,6 +405,7 @@ PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS) /* {{{ */ efree(buf); return NULL; } + efree(buf); if (PS(entropy_length) > 0) { int fd; @@ -461,20 +461,16 @@ PHPAPI char *php_session_create_id(PS_CREATE_SID_ARGS) /* {{{ */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "The ini setting hash_bits_per_character is out of range (should be 4, 5, or 6) - using 4 for now"); } - - if (PS_ID_INITIAL_SIZE < ((digest_len + 2) * (8 / PS(hash_bits_per_character))) ) { - /* 100 bytes is enough for most, but not all hash algos */ - buf = erealloc(buf, (digest_len + 2) * (8 / PS(hash_bits_per_character)) ); - } - - j = (int) (bin_to_readable((char *)digest, digest_len, buf, PS(hash_bits_per_character)) - buf); + + outid = emalloc((digest_len + 2) * ((8.0f / PS(hash_bits_per_character)) + 0.5)); + j = (int) (bin_to_readable((char *)digest, digest_len, outid, PS(hash_bits_per_character)) - outid); efree(digest); if (newlen) { *newlen = j; } - return buf; + return outid; } /* }}} */ @@ -2252,8 +2248,16 @@ static PHP_MINFO_FUNCTION(session) /* {{{ */ } /* }}} */ +static const zend_module_dep session_deps[] = { /* {{{ */ + ZEND_MOD_OPTIONAL("hash") + {NULL, NULL, NULL} +}; +/* }}} */ + zend_module_entry session_module_entry = { - STANDARD_MODULE_HEADER, + STANDARD_MODULE_HEADER_EX, + NULL, + session_deps, "session", session_functions, PHP_MINIT(session), PHP_MSHUTDOWN(session), diff --git a/ext/session/tests/031.phpt b/ext/session/tests/031.phpt new file mode 100644 index 000000000..e8deb3dac --- /dev/null +++ b/ext/session/tests/031.phpt @@ -0,0 +1,22 @@ +--TEST-- +setting hash_function to sha512 and hash_bits_per_character > 4 should not crash +--SKIPIF-- + +--INI-- +session.use_cookies=0 +session.cache_limiter= +session.serialize_handler=php +session.save_handler=files +session.hash_function=sha512 +session.hash_bits_per_character=5 +--FILE-- + +--EXPECT-- +I live diff --git a/ext/shmop/config.m4 b/ext/shmop/config.m4 index ae80c3d8a..f948e6aa2 100644 --- a/ext/shmop/config.m4 +++ b/ext/shmop/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.5 2002/03/12 16:35:09 sas Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ PHP_ARG_ENABLE(shmop, whether to enable shmop support, [ --enable-shmop Enable shmop support]) diff --git a/ext/shmop/config.w32 b/ext/shmop/config.w32 index 589e9a618..c42426d28 100644 --- a/ext/shmop/config.w32 +++ b/ext/shmop/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.1 2003/12/03 00:32:19 iliaa Exp $ +// $Id: config.w32 242949 2007-09-26 15:44:16Z cvs2svn $ // vim:ft=javascript ARG_ENABLE("shmop", "shmop support", "no"); diff --git a/ext/shmop/shmop.c b/ext/shmop/shmop.c index 72d18dc05..aed85d645 100644 --- a/ext/shmop/shmop.c +++ b/ext/shmop/shmop.c @@ -16,7 +16,7 @@ | Ilia Alshanetsky | +----------------------------------------------------------------------+ */ -/* $Id: shmop.c,v 1.31.2.2.2.5.2.9 2009/06/06 02:40:48 mattwil Exp $ */ +/* $Id: shmop.c 281742 2009-06-06 02:40:49Z mattwil $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/simplexml/config.m4 b/ext/simplexml/config.m4 index b1f5de673..4d7fa22d9 100644 --- a/ext/simplexml/config.m4 +++ b/ext/simplexml/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.9.2.1.4.1 2008/11/06 00:37:13 colder Exp $ +dnl $Id: config.m4 268395 2008-11-06 00:37:13Z colder $ dnl config.m4 for extension simplexml PHP_ARG_ENABLE(simplexml, whether to enable SimpleXML support, diff --git a/ext/simplexml/config.w32 b/ext/simplexml/config.w32 index 2fa34f2c0..5e9a95d9a 100644 --- a/ext/simplexml/config.w32 +++ b/ext/simplexml/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.4.8.7 2008/12/27 12:22:38 rrichards Exp $ +// $Id: config.w32 272005 2008-12-27 12:22:38Z rrichards $ // vim:ft=javascript ARG_WITH("simplexml", "Simple XML support", "yes"); diff --git a/ext/simplexml/php_simplexml.h b/ext/simplexml/php_simplexml.h index 2bdc5ced0..37b583569 100644 --- a/ext/simplexml/php_simplexml.h +++ b/ext/simplexml/php_simplexml.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_simplexml.h,v 1.20.2.2.2.3.2.7 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_simplexml.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SIMPLEXML_H #define PHP_SIMPLEXML_H diff --git a/ext/simplexml/php_simplexml_exports.h b/ext/simplexml/php_simplexml_exports.h index 37f870654..23e70e94b 100755 --- a/ext/simplexml/php_simplexml_exports.h +++ b/ext/simplexml/php_simplexml_exports.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_simplexml_exports.h,v 1.3.2.3.2.1.2.3 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_simplexml_exports.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SIMPLEXML_EXPORTS_H #define PHP_SIMPLEXML_EXPORTS_H diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 6308c59f0..21fb5d863 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: simplexml.c,v 1.151.2.22.2.35.2.32 2009/06/11 09:41:15 bjori Exp $ */ +/* $Id: simplexml.c 281953 2009-06-11 09:41:15Z bjori $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -2556,7 +2556,7 @@ PHP_MINFO_FUNCTION(simplexml) { php_info_print_table_start(); php_info_print_table_header(2, "Simplexml support", "enabled"); - php_info_print_table_row(2, "Revision", "$Revision: 1.151.2.22.2.35.2.32 $"); + php_info_print_table_row(2, "Revision", "$Revision: 281953 $"); php_info_print_table_row(2, "Schema support", #ifdef LIBXML_SCHEMAS_ENABLED "enabled"); diff --git a/ext/simplexml/sxe.c b/ext/simplexml/sxe.c index 1ebde2ad5..406f89f61 100755 --- a/ext/simplexml/sxe.c +++ b/ext/simplexml/sxe.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sxe.c,v 1.1.2.3 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: sxe.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/ext/simplexml/sxe.h b/ext/simplexml/sxe.h index d0990dbc0..d0bf59f69 100755 --- a/ext/simplexml/sxe.h +++ b/ext/simplexml/sxe.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sxe.h,v 1.1.2.3 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: sxe.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SXE_H #define SXE_H diff --git a/ext/simplexml/tests/034.phpt b/ext/simplexml/tests/034.phpt index 5d99faa72..1f3a854fd 100755 --- a/ext/simplexml/tests/034.phpt +++ b/ext/simplexml/tests/034.phpt @@ -1,6 +1,7 @@ --TEST-- SimpleXML: array casting bug --XFAIL-- +Does anyone know why? --SKIPIF-- --FILE-- diff --git a/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt b/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt new file mode 100644 index 000000000..22ea4488e --- /dev/null +++ b/ext/simplexml/tests/SimpleXMLElement_addAttribute_required_attribute_name.phpt @@ -0,0 +1,18 @@ +--TEST-- +SimpleXMLElement: Test to ensure that the required attribute name correctly is giving a warning +--CREDITS-- +Havard Eide +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- +testfest"); +$a->addAttribute( "", "" ); +echo $a->asXML(); +?> +--EXPECTF-- +Warning: SimpleXMLElement::addAttribute(): Attribute name is required in %s on line %d + +testfest + diff --git a/ext/simplexml/tests/bug36611.phpt b/ext/simplexml/tests/bug36611.phpt index 835e926fe..fdcfd4743 100644 --- a/ext/simplexml/tests/bug36611.phpt +++ b/ext/simplexml/tests/bug36611.phpt @@ -19,12 +19,12 @@ $xml = simplexml_load_string ($xml_str) ; $val = 1; var_dump($val); -$obj->pos["act_idx"] = $val; +$zml->pos["act_idx"] = $val; var_dump($val) ; -echo "Done\n"; ?> +===DONE=== --EXPECT-- int(1) int(1) -Done +===DONE=== diff --git a/ext/simplexml/tests/bug40451.phpt b/ext/simplexml/tests/bug40451.phpt index 1a499a731..afd78c769 100644 --- a/ext/simplexml/tests/bug40451.phpt +++ b/ext/simplexml/tests/bug40451.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #40451 (addAttribute() may crash when used with non-existent child node) +--SKIPIF-- + --FILE-- addChild('Host'); $add->Host->addAttribute('enable', 'true'); -echo "Done\n"; ?> +===DONE=== --EXPECTF-- Warning: SimpleXMLElement::addAttribute(): Unable to locate parent Element in %s on line %d -Done +===DONE=== diff --git a/ext/simplexml/tests/bug41175.phpt b/ext/simplexml/tests/bug41175.phpt index 51181d29c..db03da977 100644 --- a/ext/simplexml/tests/bug41175.phpt +++ b/ext/simplexml/tests/bug41175.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #41175 (addAttribute() fails to add an attribute with an empty value) +--SKIPIF-- + --FILE-- addAttribute("src", "foo"); $xml->addAttribute("alt", ""); echo $xml->asXML(); -echo "Done\n"; ?> +===DONE=== --EXPECT-- -Done \ No newline at end of file +===DONE=== \ No newline at end of file diff --git a/ext/simplexml/tests/bug41582.phpt b/ext/simplexml/tests/bug41582.phpt index b689607d0..8733810d7 100644 --- a/ext/simplexml/tests/bug41582.phpt +++ b/ext/simplexml/tests/bug41582.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #41582 (SimpleXML crashes when accessing newly created element) +--SKIPIF-- + --FILE-- movie[]->characters->character[0]->name = 'Miss Coder'; echo($xml->asXml()); -echo "Done\n"; ?> +===DONE=== --EXPECT-- Miss Coder -Done +===DONE=== diff --git a/ext/simplexml/tests/bug41861.phpt b/ext/simplexml/tests/bug41861.phpt index 07622ebbd..607d301f7 100644 --- a/ext/simplexml/tests/bug41861.phpt +++ b/ext/simplexml/tests/bug41861.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #41861 (getNamespaces() returns the namespaces of a node's siblings) +--SKIPIF-- + --FILE-- +===DONE=== --EXPECT-- root(recursive): 'root' -- namespaces: #ns1, #ns2, #ns3 root(non-recursive): 'root' -- namespaces: @@ -36,3 +39,4 @@ children(): 'last_node_no_ns' -- namespaces: children(#ns1): 'node1' -- namespaces: #ns1 children(#ns2): 'node2' -- namespaces: #ns2 children(#ns3): 'node3' -- namespaces: #ns3 +===DONE=== diff --git a/ext/simplexml/tests/bug41867.phpt b/ext/simplexml/tests/bug41867.phpt index f530f95dc..33e2de9e2 100644 --- a/ext/simplexml/tests/bug41867.phpt +++ b/ext/simplexml/tests/bug41867.phpt @@ -1,14 +1,18 @@ --TEST-- Bug #41867 (getName is broken) +--SKIPIF-- + --FILE-- "); echo $a->getName()."\n"; echo $a->b->getName()."\n"; -echo $a->b->c->getName(); +echo $a->b->c->getName()."\n"; ?> +===DONE=== --EXPECT-- a b c +===DONE=== diff --git a/ext/simplexml/tests/bug41947.phpt b/ext/simplexml/tests/bug41947.phpt index 7af9ff8e7..0b974ce4f 100644 --- a/ext/simplexml/tests/bug41947.phpt +++ b/ext/simplexml/tests/bug41947.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #41947 (addChild incorrectly registers empty strings as namespaces) +--SKIPIF-- + --FILE-- '); @@ -7,8 +9,10 @@ $grandchild = $xml->addChild('child', null, 'http://myns')->addChild('grandchild $gchild = $xml->xpath("//grandchild"); if (count($gchild) > 0) { - echo $gchild[0]; + echo $gchild[0]."\n"; } ?> +===DONE=== --EXPECT-- hello +===DONE=== diff --git a/ext/simplexml/tests/bug42369.phpt b/ext/simplexml/tests/bug42369.phpt index e5df81460..e18677003 100644 --- a/ext/simplexml/tests/bug42369.phpt +++ b/ext/simplexml/tests/bug42369.phpt @@ -1,7 +1,7 @@ --TEST-- Bug #42369 (Implicit conversion to string leaks memory) --SKIPIF-- - + --FILE-- '; @@ -17,9 +17,9 @@ Bug #42369 (Implicit conversion to string leaks memory) md5($x->x); } - echo 'done' . PHP_EOL; ?> +===DONE=== --EXPECT-- explicit conversion no conversion -done \ No newline at end of file +===DONE=== \ No newline at end of file diff --git a/ext/simplexml/tests/bug43221.phpt b/ext/simplexml/tests/bug43221.phpt index 6973d091c..53b6efdcc 100644 --- a/ext/simplexml/tests/bug43221.phpt +++ b/ext/simplexml/tests/bug43221.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #43221 (SimpleXML adding default namespace in addAttribute) +--SKIPIF-- + --FILE-- '); @@ -9,7 +11,10 @@ $n->addAttribute("c", "d", "http://bar.com"); $n->addAttribute("foo:e", "f", "http://bar.com"); print_r($xml->asXml()); ?> +===DONE=== --EXPECTF-- Warning: SimpleXMLElement::addAttribute(): Attribute requires prefix for namespace in %sbug43221.php on line %d -value \ No newline at end of file +value +===DONE=== + \ No newline at end of file diff --git a/ext/simplexml/tests/bug44478.phpt b/ext/simplexml/tests/bug44478.phpt index 5c21d75c8..17a26f949 100644 --- a/ext/simplexml/tests/bug44478.phpt +++ b/ext/simplexml/tests/bug44478.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #44478 (Inconsistent behaviour when assigning new nodes) +--SKIPIF-- + --FILE-- '); @@ -15,6 +17,7 @@ print $xml_element->node2."\n"; print $xml_element->asXML(); ?> +===DONE=== --EXPECTF-- a & b a & b @@ -22,3 +25,5 @@ a & b a & b a &#38; ba & b +===DONE=== + \ No newline at end of file diff --git a/ext/simplexml/tests/bug45553.phpt b/ext/simplexml/tests/bug45553.phpt index 37a46f427..b355c4869 100644 --- a/ext/simplexml/tests/bug45553.phpt +++ b/ext/simplexml/tests/bug45553.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #45553 (Using XPath to return values for attributes with a namespace does not work) +--SKIPIF-- + --FILE-- xpath("/xml/data/@label"); echo $atts[0] . "\n"; ?> +===DONE=== --EXPECTF-- I am A I am a:Nothing I am a:A I am a:Nothing -I am Nothing \ No newline at end of file +I am Nothing +===DONE=== + \ No newline at end of file diff --git a/ext/simplexml/tests/bug46003.phpt b/ext/simplexml/tests/bug46003.phpt index a10b01872..712675c09 100644 --- a/ext/simplexml/tests/bug46003.phpt +++ b/ext/simplexml/tests/bug46003.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #46003 (isset on nonexisting nodes return unexpected results) +--SKIPIF-- + --FILE-- o->zz)); var_dump(isset($x->o->text)); var_dump(isset($x->o->xx)); ?> +===DONE=== --EXPECTF-- bool(true) bool(false) bool(true) bool(false) bool(false) -bool(true) \ No newline at end of file +bool(true) +===DONE=== + \ No newline at end of file diff --git a/ext/simplexml/tests/bug46047.phpt b/ext/simplexml/tests/bug46047.phpt index 37f31cdeb..043815482 100644 --- a/ext/simplexml/tests/bug46047.phpt +++ b/ext/simplexml/tests/bug46047.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #46047 (SimpleXML converts empty nodes into object with nested array) +--SKIPIF-- + --FILE-- ', @@ -12,6 +14,7 @@ print_r($xml); $xml = new SimpleXMLElement(''); print_r($xml); ?> +===DONE=== --EXPECTF-- SimpleXMLElement Object ( @@ -45,4 +48,6 @@ SimpleXMLElement Object ( ) -) \ No newline at end of file +) +===DONE=== + \ No newline at end of file diff --git a/ext/simplexml/tests/bug46048.phpt b/ext/simplexml/tests/bug46048.phpt index e3eb4f546..97fc9ed08 100644 --- a/ext/simplexml/tests/bug46048.phpt +++ b/ext/simplexml/tests/bug46048.phpt @@ -1,5 +1,7 @@ --TEST-- Bug #46048 (SimpleXML top-level @attributes not part of iterator) +--SKIPIF-- + --FILE-- +===DONE=== --EXPECT-- Array ( @@ -21,4 +23,4 @@ Array [key] => value ) -Done +===DONE=== diff --git a/ext/skeleton/create_stubs b/ext/skeleton/create_stubs index c33e8d890..95dba84c9 100755 --- a/ext/skeleton/create_stubs +++ b/ext/skeleton/create_stubs @@ -67,7 +67,7 @@ BEGIN { xmlhead = "\n" \ - "\n" \ + "\n" \ " \n" \ " functions\n" \ " \n\n" \ diff --git a/ext/snmp/config.m4 b/ext/snmp/config.m4 index bc51ce218..5043b225f 100644 --- a/ext/snmp/config.m4 +++ b/ext/snmp/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.32.2.1.2.3 2007/07/31 13:02:00 jani Exp $ +dnl $Id: config.m4 240511 2007-07-31 13:02:00Z jani $ dnl PHP_ARG_WITH(snmp,for SNMP support, diff --git a/ext/snmp/config.w32 b/ext/snmp/config.w32 index c0e797249..49d0d007c 100644 --- a/ext/snmp/config.w32 +++ b/ext/snmp/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.1 2003/12/19 17:00:10 wez Exp $ +// $Id: config.w32 242949 2007-09-26 15:44:16Z cvs2svn $ // vim:ft=javascript ARG_WITH("snmp", "SNMP support", "no"); diff --git a/ext/snmp/php_snmp.h b/ext/snmp/php_snmp.h index 5b551ba6c..f1239a736 100644 --- a/ext/snmp/php_snmp.h +++ b/ext/snmp/php_snmp.h @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_snmp.h,v 1.25.2.1.2.2.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_snmp.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SNMP_H #define PHP_SNMP_H diff --git a/ext/snmp/snmp.c b/ext/snmp/snmp.c index 92b277437..7819fed06 100644 --- a/ext/snmp/snmp.c +++ b/ext/snmp/snmp.c @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: snmp.c,v 1.106.2.2.2.5.2.13 2009/06/01 13:10:18 iliaa Exp $ */ +/* $Id: snmp.c 287430 2009-08-17 22:15:18Z stas $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -775,22 +775,21 @@ retry: */ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) { - char *a1, **a2, **a3; + char *a1, *a2, *a3; int a1_len, a2_len, a3_len; - zval **a4 = NULL, **a5 = NULL; - long a6 = 0, a7 = 0; struct snmp_session session; long timeout = SNMP_DEFAULT_TIMEOUT; long retries = SNMP_DEFAULT_RETRIES; char type = (char) 0; - char *value = (char *) 0; + char *value = (char *) 0, *stype = ""; + int value_len, stype_len; char hostname[MAX_NAME_LEN]; int remote_port = 161; char *pptr; int argc = ZEND_NUM_ARGS(); if (st == SNMP_CMD_SET) { - if (zend_parse_parameters(argc TSRMLS_CC, "sssZZ|ll", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len, &a4, &a5, &a6, &a7) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "sssss|ll", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len, &stype, &stype_len, &value, &value_len, &timeout, &retries) == FAILURE) { return; } } else { @@ -799,36 +798,14 @@ static void php_snmp(INTERNAL_FUNCTION_PARAMETERS, int st, int version) * SNMP_CMD_WALK * SNMP_CMD_REALWALK */ - if (zend_parse_parameters(argc TSRMLS_CC, "sss|ZZ", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len, &a4, &a5) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "sss|ll", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len, &timeout, &retries) == FAILURE) { return; } } if (st == SNMP_CMD_SET) { - convert_to_string_ex(a4); - convert_to_string_ex(a5); - - if (argc > 5) { - timeout = a6; - } - - if (argc > 6) { - retries = a7; - } - - type = Z_STRVAL_PP(a4)[0]; - value = Z_STRVAL_PP(a5); - } else { - if (argc > 3) { - convert_to_long_ex(a4); - timeout = Z_LVAL_PP(a4); - } - - if (argc > 4) { - convert_to_long_ex(a5); - retries = Z_LVAL_PP(a5); - } - } + type = stype[0]; + } snmp_sess_init(&session); strlcpy(hostname, a1, sizeof(hostname)); @@ -1201,23 +1178,22 @@ PHP_FUNCTION(snmp2_set) */ static void php_snmpv3(INTERNAL_FUNCTION_PARAMETERS, int st) { - zval **a9 = NULL, **a10 = NULL; char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; int a1_len, a2_len, a3_len, a4_len, a5_len, a6_len, a7_len, a8_len; - long a11 = 0, a12 = 0; struct snmp_session session; long timeout = SNMP_DEFAULT_TIMEOUT; long retries = SNMP_DEFAULT_RETRIES; char type = (char) 0; - char *value = (char *) 0; + char *value = (char *) 0, *stype = ""; + int stype_len, value_len; char hostname[MAX_NAME_LEN]; int remote_port = 161; char *pptr; int argc = ZEND_NUM_ARGS(); if (st == SNMP_CMD_SET) { - if (zend_parse_parameters(argc TSRMLS_CC, "ssssssssZZ|ll", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len, - &a4, &a4_len, &a5, &a5_len, &a6, &a6_len, &a7, &a7_len, &a8, &a8_len, &a9, &a10, &a11, &a12) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "ssssssssss|ll", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len, + &a4, &a4_len, &a5, &a5_len, &a6, &a6_len, &a7, &a7_len, &a8, &a8_len, &stype, &stype_len, &value, &value_len, &timeout, &retries) == FAILURE) { return; } } else { @@ -1226,8 +1202,8 @@ static void php_snmpv3(INTERNAL_FUNCTION_PARAMETERS, int st) * SNMP_CMD_WALK * SNMP_CMD_REALWALK */ - if (zend_parse_parameters(argc TSRMLS_CC, "ssssssss|ZZ", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len, - &a4, &a4_len, &a5, &a5_len, &a6, &a6_len, &a7, &a7_len, &a8, &a8_len, &a9, &a10) == FAILURE) { + if (zend_parse_parameters(argc TSRMLS_CC, "ssssssss|ll", &a1, &a1_len, &a2, &a2_len, &a3, &a3_len, + &a4, &a4_len, &a5, &a5_len, &a6, &a6_len, &a7, &a7_len, &a8, &a8_len, &timeout, &retries) == FAILURE) { return; } } @@ -1281,25 +1257,7 @@ static void php_snmpv3(INTERNAL_FUNCTION_PARAMETERS, int st) } if (st == SNMP_CMD_SET) { - if (argc > 10) { - timeout = a11; - } - if (argc > 11) { - retries = a12; - } - convert_to_string_ex(a9); - convert_to_string_ex(a10); - type = Z_STRVAL_PP(a9)[0]; - value = Z_STRVAL_PP(a10); - } else { - if (argc > 8) { - convert_to_long_ex(a9); - timeout = Z_LVAL_PP(a9); - } - if (argc > 9) { - convert_to_long_ex(a10); - retries = Z_LVAL_PP(a10); - } + type = stype[0]; } session.retries = retries; diff --git a/ext/soap/TODO b/ext/soap/TODO index 800176cf0..ad0b11c94 100644 --- a/ext/soap/TODO +++ b/ext/soap/TODO @@ -1,98 +1,98 @@ -General -------- -- make sure soapserver.map(), soap_encode_to_xml() and soap_encode_to_zval() are really need -- reimplement SoapObject::__getfunctions() and SoapObject::__gettypes() - to return structures instead of strings -- error handling??? - -SOAP ----- -- SOAP routing -- root attribute (it is defined by SOAP 1.1, but not SOAP 1.2) -- make sure soap 1.1 and 1.2 are supported fully - -Encoding --------- -? full support for standard simple types ( - ? language, (pattern: "[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*") - ? NMTOKEN, (pattern: "\c+") (\c: [a-zA-Z0-9.\-_:]) - ? NMTOKENS, (list: NMTOKEN, minLength: 1) - ? Name, (pattern: "\i\c*") (\i: [a-zA-Z_:] - ? NCName, (pattern: "[\i-[:]][\c-[:]]*") - ? ID, (base: NCName) - ? IDREF, (base: NCName) - ? IDREFS, (list: IDREF; minLength: 1) - ? ENTITY, (base: NCName) - ? ENTITIES, (list: ENTITY; minLength: 1) - ? duration) -? full support for standard date/time types ( - ? dateTime, - ? time, - ? date, - ? gYearMonth, - ? gYear, - ? gMonthDay, - ? gDay, - ? gMonth) -? full support for arrays - - SOAP 1.1 encoding of arrays with holes (partially transmitted and sparse arrays) - SOAP 1.2 doesn't support partially transmitted and sparse arrays -- references to external resources -? support for "nillable" and "nil" -? default values of -? provide schema 1999/2001 support??? -? make internal refrences for soap encoding (use seralization logic)??? -? provide user space overriding of serialization certin objects and types??? - -WSDL ----- -? server part support for "document" style encoding -? support for , -? -- parts attribute (with MIME/DIME binding) -- MIME binding -- DIME binding -- support for portType/operation parameterOrder attribute -- support for binding operation input/output name attribute (part of overloading) -- function/method overloading/redeclaration (test(int); test(string)) -- wsdl auto generation -- HTTP GET/POST binding -- SOAP security extension - -Schema ------- -- -? support for user defined simple types - ? restiction - ? enumeration - ? length (for string, anyURI, hexBinary, base64Binary and derived) list??? - ? minLength (for string, hexBinary, base64Binary and derived) list??? - ? maxLength (for string, hexBinary, base64Binary and derived) list??? - + whiteSpace (preserve, replace [#x9,#xA,#xD=>#x20], collapse [replace+?]) - - pattern - - minExclusive (for numeric, date types) - - minInclusive (for numeric, date types) - - maxExclusive (for numeric, date types) - - maxInclusive (for numeric, date types) - - totalDigits (for decimal) - - fractionDigits (for decimal) - ? union -? support for user defined complex types - ? full support for content model encoding/decoding - - - - - -Transport ---------- -? HTTP status codes -? HTTP chunked Transfer-Encoding -? support for HTTP compression (gzip,x-gzip,defalte) -- transport abstraction layer??? - -Interop Testing ---------------- -- more interop rounds/groups - -UDDI ----- -- ??? +General +------- +- make sure soapserver.map(), soap_encode_to_xml() and soap_encode_to_zval() are really need +- reimplement SoapObject::__getfunctions() and SoapObject::__gettypes() + to return structures instead of strings +- error handling??? + +SOAP +---- +- SOAP routing +- root attribute (it is defined by SOAP 1.1, but not SOAP 1.2) +- make sure soap 1.1 and 1.2 are supported fully + +Encoding +-------- +? full support for standard simple types ( + ? language, (pattern: "[a-zA-Z]{1,8}(-[a-zA-Z0-9]{1,8})*") + ? NMTOKEN, (pattern: "\c+") (\c: [a-zA-Z0-9.\-_:]) + ? NMTOKENS, (list: NMTOKEN, minLength: 1) + ? Name, (pattern: "\i\c*") (\i: [a-zA-Z_:] + ? NCName, (pattern: "[\i-[:]][\c-[:]]*") + ? ID, (base: NCName) + ? IDREF, (base: NCName) + ? IDREFS, (list: IDREF; minLength: 1) + ? ENTITY, (base: NCName) + ? ENTITIES, (list: ENTITY; minLength: 1) + ? duration) +? full support for standard date/time types ( + ? dateTime, + ? time, + ? date, + ? gYearMonth, + ? gYear, + ? gMonthDay, + ? gDay, + ? gMonth) +? full support for arrays + - SOAP 1.1 encoding of arrays with holes (partially transmitted and sparse arrays) + SOAP 1.2 doesn't support partially transmitted and sparse arrays +- references to external resources +? support for "nillable" and "nil" +? default values of +? provide schema 1999/2001 support??? +? make internal refrences for soap encoding (use seralization logic)??? +? provide user space overriding of serialization certin objects and types??? + +WSDL +---- +? server part support for "document" style encoding +? support for , +? +- parts attribute (with MIME/DIME binding) +- MIME binding +- DIME binding +- support for portType/operation parameterOrder attribute +- support for binding operation input/output name attribute (part of overloading) +- function/method overloading/redeclaration (test(int); test(string)) +- wsdl auto generation +- HTTP GET/POST binding +- SOAP security extension + +Schema +------ +- +? support for user defined simple types + ? restiction + ? enumeration + ? length (for string, anyURI, hexBinary, base64Binary and derived) list??? + ? minLength (for string, hexBinary, base64Binary and derived) list??? + ? maxLength (for string, hexBinary, base64Binary and derived) list??? + + whiteSpace (preserve, replace [#x9,#xA,#xD=>#x20], collapse [replace+?]) + - pattern + - minExclusive (for numeric, date types) + - minInclusive (for numeric, date types) + - maxExclusive (for numeric, date types) + - maxInclusive (for numeric, date types) + - totalDigits (for decimal) + - fractionDigits (for decimal) + ? union +? support for user defined complex types + ? full support for content model encoding/decoding + - + - + +Transport +--------- +? HTTP status codes +? HTTP chunked Transfer-Encoding +? support for HTTP compression (gzip,x-gzip,defalte) +- transport abstraction layer??? + +Interop Testing +--------------- +- more interop rounds/groups + +UDDI +---- +- ??? diff --git a/ext/soap/TODO.old b/ext/soap/TODO.old index cb55a35ff..a1cc15c39 100644 --- a/ext/soap/TODO.old +++ b/ext/soap/TODO.old @@ -1,39 +1,39 @@ -TODO: -make sure soap 1.1 and 1.2 is supported fully -Better WSDL support Client and server (how much validation is needed here?) -UDDI?? -make internal refrences for soap encoding (use seralization logic) -add ini option for always soap_error_handler -provide user space overriding of serialization certin objects and types -serialization in general needs to be polished/finished... all xsd types -make perstistant objects and work with or without register_globals on -look to see if php-soap will work with out always_populate_raw_post_data on -see if client will work with ssl.. should be eaiser with php_streams -work on soap seralizer (php serialization) --work on a soap-service 'regiestry' and 'proxy' (apache soap style) --convert all string mainpulation to use smart_str -make the 'soap' packet abstract.. maybe incorperate xml-rpc -make the transport layer abstract.. what other transport layers are needed?... who uses smtp? what about jabber? -make $soap_object->data = 'text'; maybe invoke a set_*() and/or get_*() method -when using wsdls and function names are similar find the best match - void test(int); - void test(string); - maybe use the same alogrithim as ext/java. -investigate further http keep_alive... inital testing proved slower.. maybe php_streams will speed things up.. -provide schema 1999/2001 support.... -through memory leak testing -possible using shared memory for sdl caching... -api for clearing/checking sdl caching... -make php-soap work as a standalone server using php_streams and the new socket extension -http authication -proxy support -wsdl generation static and auto (.net style (http://server.com/soapserver.php?WSDL)) using phpdoc parsing engine -interpo testing... -BENCHMARKING...... lets prove how fast it is. -do some more work on website - -does this list stop... what exactly have i done? -im sure im forgetting 20 thousand more things.... - - - - brad +TODO: +make sure soap 1.1 and 1.2 is supported fully +Better WSDL support Client and server (how much validation is needed here?) +UDDI?? +make internal refrences for soap encoding (use seralization logic) +add ini option for always soap_error_handler +provide user space overriding of serialization certin objects and types +serialization in general needs to be polished/finished... all xsd types +make perstistant objects and work with or without register_globals on +look to see if php-soap will work with out always_populate_raw_post_data on +see if client will work with ssl.. should be eaiser with php_streams +work on soap seralizer (php serialization) +-work on a soap-service 'regiestry' and 'proxy' (apache soap style) +-convert all string mainpulation to use smart_str +make the 'soap' packet abstract.. maybe incorperate xml-rpc +make the transport layer abstract.. what other transport layers are needed?... who uses smtp? what about jabber? +make $soap_object->data = 'text'; maybe invoke a set_*() and/or get_*() method +when using wsdls and function names are similar find the best match + void test(int); + void test(string); + maybe use the same alogrithim as ext/java. +investigate further http keep_alive... inital testing proved slower.. maybe php_streams will speed things up.. +provide schema 1999/2001 support.... +through memory leak testing +possible using shared memory for sdl caching... +api for clearing/checking sdl caching... +make php-soap work as a standalone server using php_streams and the new socket extension +http authication +proxy support +wsdl generation static and auto (.net style (http://server.com/soapserver.php?WSDL)) using phpdoc parsing engine +interpo testing... +BENCHMARKING...... lets prove how fast it is. +do some more work on website + +does this list stop... what exactly have i done? +im sure im forgetting 20 thousand more things.... + + + - brad diff --git a/ext/soap/config.m4 b/ext/soap/config.m4 index 7a1b4a680..719e13c9c 100644 --- a/ext/soap/config.m4 +++ b/ext/soap/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.10 2005/05/29 23:16:44 sniper Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl config.m4 for extension soap PHP_ARG_ENABLE(soap, whether to enable SOAP support, diff --git a/ext/soap/config.w32 b/ext/soap/config.w32 index 809dcea9a..b4ea7d999 100644 --- a/ext/soap/config.w32 +++ b/ext/soap/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.5.8.2 2009/04/22 19:06:47 pajoye Exp $ +// $Id: config.w32 279159 2009-04-22 19:06:47Z pajoye $ // vim:ft=javascript ARG_ENABLE("soap", "SOAP support", "no"); diff --git a/ext/soap/interop/client_round2_interop.php b/ext/soap/interop/client_round2_interop.php index 3caee080d..49439eaa3 100644 --- a/ext/soap/interop/client_round2_interop.php +++ b/ext/soap/interop/client_round2_interop.php @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo | // +----------------------------------------------------------------------+ // -// $Id: client_round2_interop.php,v 1.17.2.2 2006/01/01 13:27:13 sniper Exp $ +// $Id: client_round2_interop.php 242949 2007-09-26 15:44:16Z cvs2svn $ // require_once 'DB.php'; // PEAR/DB require_once 'client_round2_params.php'; diff --git a/ext/soap/interop/client_round2_params.php b/ext/soap/interop/client_round2_params.php index 25d299136..c83d92438 100644 --- a/ext/soap/interop/client_round2_params.php +++ b/ext/soap/interop/client_round2_params.php @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo | // +----------------------------------------------------------------------+ // -// $Id: client_round2_params.php,v 1.11.4.2 2006/01/01 13:27:13 sniper Exp $ +// $Id: client_round2_params.php 242949 2007-09-26 15:44:16Z cvs2svn $ // define('SOAP_TEST_ACTOR_OTHER','http://some/other/actor'); diff --git a/ext/soap/interop/client_round2_results.php b/ext/soap/interop/client_round2_results.php index 5b5f1350b..52e3b5cd1 100644 --- a/ext/soap/interop/client_round2_results.php +++ b/ext/soap/interop/client_round2_results.php @@ -19,7 +19,7 @@ // | Authors: Shane Caraveo | // +----------------------------------------------------------------------+ // -// $Id: client_round2_results.php,v 1.4.4.2 2006/01/01 13:27:13 sniper Exp $ +// $Id: client_round2_results.php 242949 2007-09-26 15:44:16Z cvs2svn $ // require_once 'client_round2_interop.php'; ?> diff --git a/ext/soap/interop/client_round2_run.php b/ext/soap/interop/client_round2_run.php index 16699c25b..0c54ab0ad 100644 --- a/ext/soap/interop/client_round2_run.php +++ b/ext/soap/interop/client_round2_run.php @@ -15,7 +15,7 @@ // | Authors: Shane Caraveo | // +----------------------------------------------------------------------+ // -// $Id: client_round2_run.php,v 1.4.4.2 2006/01/01 13:27:13 sniper Exp $ +// $Id: client_round2_run.php 242949 2007-09-26 15:44:16Z cvs2svn $ // set_time_limit(0); diff --git a/ext/soap/interop/server_round2_base.php b/ext/soap/interop/server_round2_base.php index c1f244266..1b4576405 100644 --- a/ext/soap/interop/server_round2_base.php +++ b/ext/soap/interop/server_round2_base.php @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala Original Author | // +----------------------------------------------------------------------+ // -// $Id: server_round2_base.php,v 1.7.4.2 2006/01/01 13:27:13 sniper Exp $ +// $Id: server_round2_base.php 242949 2007-09-26 15:44:16Z cvs2svn $ // class SOAP_Interop_Base { diff --git a/ext/soap/interop/server_round2_groupB.php b/ext/soap/interop/server_round2_groupB.php index 89ae819cb..788df6cb2 100644 --- a/ext/soap/interop/server_round2_groupB.php +++ b/ext/soap/interop/server_round2_groupB.php @@ -17,7 +17,7 @@ // | Authors: Dietrich Ayala Original Author | // +----------------------------------------------------------------------+ // -// $Id: server_round2_groupB.php,v 1.7.4.2 2006/01/01 13:27:13 sniper Exp $ +// $Id: server_round2_groupB.php 242949 2007-09-26 15:44:16Z cvs2svn $ // class SOAP_Interop_GroupB { diff --git a/ext/soap/interop/server_round2_groupC.php b/ext/soap/interop/server_round2_groupC.php index 065b6f33d..96e2f80da 100644 --- a/ext/soap/interop/server_round2_groupC.php +++ b/ext/soap/interop/server_round2_groupC.php @@ -16,7 +16,7 @@ // | Authors: Shane Caraveo | // +----------------------------------------------------------------------+ // -// $Id: server_round2_groupC.php,v 1.7.4.2 2006/01/01 13:27:13 sniper Exp $ +// $Id: server_round2_groupC.php 242949 2007-09-26 15:44:16Z cvs2svn $ // class SOAP_Interop_GroupC { diff --git a/ext/soap/php_encoding.c b/ext/soap/php_encoding.c index 3634ecaa1..9bf3356fd 100644 --- a/ext/soap/php_encoding.c +++ b/ext/soap/php_encoding.c @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_encoding.c,v 1.103.2.21.2.37.2.14 2009/06/15 17:31:02 felipe Exp $ */ +/* $Id: php_encoding.c 282177 2009-06-15 17:31:02Z felipe $ */ #include diff --git a/ext/soap/php_encoding.h b/ext/soap/php_encoding.h index 2e12b2024..e144901f0 100644 --- a/ext/soap/php_encoding.h +++ b/ext/soap/php_encoding.h @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_encoding.h,v 1.38.2.3.2.4.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_encoding.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_ENCODING_H #define PHP_ENCODING_H diff --git a/ext/soap/php_http.c b/ext/soap/php_http.c index a142f7cbb..f1efbed44 100644 --- a/ext/soap/php_http.c +++ b/ext/soap/php_http.c @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_http.c,v 1.77.2.11.2.12.2.11 2009/06/03 12:39:50 iliaa Exp $ */ +/* $Id: php_http.c 281589 2009-06-03 12:39:50Z iliaa $ */ #include "php_soap.h" #include "ext/standard/base64.h" diff --git a/ext/soap/php_http.h b/ext/soap/php_http.h index b5fa33f48..e3470a1ce 100644 --- a/ext/soap/php_http.h +++ b/ext/soap/php_http.h @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_http.h,v 1.16.2.1.2.1.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_http.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HTTP_H #define PHP_HTTP_H diff --git a/ext/soap/php_packet_soap.c b/ext/soap/php_packet_soap.c index f96efca39..f93e76849 100644 --- a/ext/soap/php_packet_soap.c +++ b/ext/soap/php_packet_soap.c @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_packet_soap.c,v 1.42.2.1.2.4.2.3 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_packet_soap.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_soap.h" diff --git a/ext/soap/php_packet_soap.h b/ext/soap/php_packet_soap.h index 1c56a8097..d9c00edb2 100644 --- a/ext/soap/php_packet_soap.h +++ b/ext/soap/php_packet_soap.h @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_packet_soap.h,v 1.10.2.1.2.1.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_packet_soap.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_PACKET_SOAP_H #define PHP_PACKET_SOAP_H diff --git a/ext/soap/php_schema.c b/ext/soap/php_schema.c index 8a76418c0..c51bea4ee 100644 --- a/ext/soap/php_schema.c +++ b/ext/soap/php_schema.c @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_schema.c,v 1.58.2.6.2.6.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_schema.c 287425 2009-08-17 18:23:48Z dmitry $ */ #include "php_soap.h" #include "libxml/uri.h" @@ -102,7 +102,10 @@ static void schema_load_file(sdlCtx *ctx, xmlAttrPtr ns, xmlChar *location, xmlA xmlNodePtr schema; xmlAttrPtr new_tns; + sdl_set_uri_credentials(ctx, (char*)location TSRMLS_CC); doc = soap_xmlParseFile((char*)location TSRMLS_CC); + sdl_restore_uri_credentials(ctx TSRMLS_CC); + if (doc == NULL) { soap_error1(E_ERROR, "Parsing Schema: can't import schema from '%s'", location); } diff --git a/ext/soap/php_schema.h b/ext/soap/php_schema.h index 002c07efe..d7cc00aa2 100644 --- a/ext/soap/php_schema.h +++ b/ext/soap/php_schema.h @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_schema.h,v 1.13.2.2.2.1.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_schema.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SCHEMA_H #define PHP_SCHEMA_H diff --git a/ext/soap/php_sdl.c b/ext/soap/php_sdl.c index a4b38e6c9..62161f9fe 100644 --- a/ext/soap/php_sdl.c +++ b/ext/soap/php_sdl.c @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_sdl.c,v 1.88.2.12.2.9.2.6 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_sdl.c 287425 2009-08-17 18:23:48Z dmitry $ */ #include "php_soap.h" #include "ext/libxml/php_libxml.h" @@ -226,6 +226,64 @@ static int is_wsdl_element(xmlNodePtr node) return 1; } +void sdl_set_uri_credentials(sdlCtx *ctx, char *uri TSRMLS_DC) +{ + char *s; + int l1, l2; + zval *context = NULL; + zval **header = NULL; + + /* check if we load xsd from the same server */ + s = strstr(ctx->sdl->source, "://"); + if (!s) return; + s = strchr(s+3, '/'); + l1 = s - ctx->sdl->source; + s = strstr((char*)uri, "://"); + if (!s) return; + s = strchr(s+3, '/'); + l2 = s - (char*)uri; + if (l1 != l2 || memcmp(ctx->sdl->source, uri, l1) != 0) { + /* another server. clear authentication credentals */ + context = php_libxml_switch_context(NULL TSRMLS_CC); + php_libxml_switch_context(context TSRMLS_CC); + if (context) { + ctx->context = php_stream_context_from_zval(context, 1); + + if (ctx->context && + php_stream_context_get_option(ctx->context, "http", "header", &header) == SUCCESS) { + s = strstr(Z_STRVAL_PP(header), "Authorization: Basic"); + if (s && (s == Z_STRVAL_PP(header) || *(s-1) == '\n' || *(s-1) == '\r')) { + char *rest = strstr(s, "\r\n"); + if (rest) { + zval new_header; + + rest += 2; + Z_TYPE(new_header) = IS_STRING; + Z_STRLEN(new_header) = Z_STRLEN_PP(header) - (rest - s); + Z_STRVAL(new_header) = emalloc(Z_STRLEN_PP(header) + 1); + memcpy(Z_STRVAL(new_header), Z_STRVAL_PP(header), s - Z_STRVAL_PP(header)); + memcpy(Z_STRVAL(new_header) + (s - Z_STRVAL_PP(header)), rest, Z_STRLEN_PP(header) - (rest - Z_STRVAL_PP(header)) + 1); + ctx->old_header = *header; + Z_ADDREF_P(ctx->old_header); + php_stream_context_set_option(ctx->context, "http", "header", &new_header); + zval_dtor(&new_header); + } + } + } + } + } +} + +void sdl_restore_uri_credentials(sdlCtx *ctx TSRMLS_DC) +{ + if (ctx->old_header) { + php_stream_context_set_option(ctx->context, "http", "header", ctx->old_header); + zval_ptr_dtor(&ctx->old_header); + ctx->old_header = NULL; + } + ctx->context = NULL; +} + static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include TSRMLS_DC) { sdlPtr tmpsdl = ctx->sdl; @@ -237,7 +295,9 @@ static void load_wsdl_ex(zval *this_ptr, char *struri, sdlCtx *ctx, int include return; } + sdl_set_uri_credentials(ctx, struri TSRMLS_CC); wsdl = soap_xmlParseFile(struri TSRMLS_CC); + sdl_restore_uri_credentials(ctx TSRMLS_CC); if (!wsdl) { xmlErrorPtr xmlErrorPtr = xmlGetLastError(); diff --git a/ext/soap/php_sdl.h b/ext/soap/php_sdl.h index 67f45159b..97612bf7c 100644 --- a/ext/soap/php_sdl.h +++ b/ext/soap/php_sdl.h @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_sdl.h,v 1.37.2.3.2.2.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_sdl.h 287425 2009-08-17 18:23:48Z dmitry $ */ #ifndef PHP_SDL_H #define PHP_SDL_H @@ -76,6 +76,8 @@ typedef struct sdlCtx { HashTable *attributes; /* array of sdlAttributePtr */ HashTable *attributeGroups; /* array of sdlTypesPtr */ + php_stream_context *context; + zval *old_header; } sdlCtx; struct _sdlBinding { @@ -264,4 +266,7 @@ sdlBindingPtr get_binding_from_name(sdlPtr sdl, char *name, char *ns); void delete_sdl(void *handle); void delete_sdl_impl(void *handle); +void sdl_set_uri_credentials(sdlCtx *ctx, char *uri TSRMLS_DC); +void sdl_restore_uri_credentials(sdlCtx *ctx TSRMLS_DC); + #endif diff --git a/ext/soap/php_soap.h b/ext/soap/php_soap.h index 23d0fefed..11ff51029 100644 --- a/ext/soap/php_soap.h +++ b/ext/soap/php_soap.h @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_soap.h,v 1.38.2.6.2.6.2.4 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_soap.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SOAP_H #define PHP_SOAP_H diff --git a/ext/soap/php_xml.c b/ext/soap/php_xml.c index 86fb9d3dc..92fa6cfef 100644 --- a/ext/soap/php_xml.c +++ b/ext/soap/php_xml.c @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_xml.c,v 1.25.2.1.2.2.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_xml.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_soap.h" #include "libxml/parser.h" diff --git a/ext/soap/php_xml.h b/ext/soap/php_xml.h index 05ef2bda7..7d22ce715 100644 --- a/ext/soap/php_xml.h +++ b/ext/soap/php_xml.h @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: php_xml.h,v 1.17.2.1.2.2.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: php_xml.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SOAP_XML_H #define PHP_SOAP_XML_H diff --git a/ext/soap/readme.html b/ext/soap/readme.html index 366a0b2f5..98efff3c5 100644 --- a/ext/soap/readme.html +++ b/ext/soap/readme.html @@ -1,646 +1,646 @@ - - -PHP SOAP Manual - - - - -

PHP SOAP

-

Introduction

- - - -
Warning
This extension is EXPERIMENTAL. The behaviour of this extension -- including the names of its functions and anything else documented about this extension -- may change without notice in a future release of PHP. Use this extension at your own risk. -
-

-SOAP extension can be used to write SOAP Servers and Clients. It supports -subsets of SOAP 1.1, -SOAP 1.2 and -WSDL 1.1 specifications. -

-
-

Requirements

-This extension makes use of the GNOME XML library. Download and install this library. You will need at least libxml-2.5.4. -
-

Installation

-This extension is only available if PHP was configured with --enable-soap. -
-

Runtime Configuration

-

The behaviour of these functions is affected by settings in php.ini.

- - - - - -
NameDefaultChangeable
soap.wsdl_cache_enabled"1"PHP_INI_ALL
soap.wsdl_cache_dir"/tmp"PHP_INI_ALL
soap.wsdl_cache_ttl86400PHP_INI_ALL
-

Here is a short explanation of the configuration directives.

-
-
soap.wsdl_cache_enabled (boolean)
-
enables or disables WSDL caching feature.
-
soap.wsdl_cache_dir (string)
-
sets the directory name where SOAP extension will put cache files
-
soap.wsdl_cache_ttl (integer)
-
(time to live) sets the number of second while cached file will be used instead of original one.
-
- - -
-

Predefined Constants

-The constants below are defined by this extension, and will only be available when the extension has either been compiled into PHP or dynamically loaded at runtime. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
ConstantValueDescription
SOAP_1_1 (integer)1SOAP version - SOAP 1.1. Can be used as an option in SoapClient and SoapServer constructors.
SOAP_1_2 (integer)2SOAP version - SOAP 1.2. Can be used as an option in SoapClient and SoapServer constructors.
SOAP_FUNCTIONS_ALL (integer)999Allows to export all defined functions with SoapClient::addFunction
SOAP_PERSISTENCE_SESSION (integer)1Allows making class passed to SoapServer::setClass persistent for a PHP session.
SOAP_PERSISTENCE_REQUEST (integer)2Allows making class passed to SoapServer::setClass non-persistent for a PHP session.
SOAP_ENCODED (integer)1Can be passed as style option to SoapClient constructor in nonWSDL mode.
SOAP_LITERAL (integer)2Can be passed as style option to SoapClient constructor in nonWSDL mode.
SOAP_RPC (integer)1Can be passed as use option to SoapClient constructor in nonWSDL mode.
SOAP_DOCUMENT (integer)2Can be passed as use option to SoapClient constructor in nonWSDL mode.
SOAP_ACTOR_NEXT (integer)1Can be passed as actor to SoapHeader constructor.
SOAP_ACTOR_NONE (integer)2Can be passed as actor to SoapHeader constructor
SOAP_ACTOR_UNLIMATERECEIVER (integer)3Can be passed as actor to SoapHeader constructor
UNKNOWN_TYPE (integer)999998Encoding for unknown type. Can be passed to SoapVar constructor.
XSD_STRING (integer)101Encoding for standard XMLSchema string type. Can be passed to SoapVar constructor.
XSD_BOOLEAN (integer)102Encoding for standard XMLSchema boolen type. Can be passed to SoapVar constructor.
XSD_DECIMAL (integer)103Encoding for standard XMLSchema decimal type. Can be passed to SoapVar constructor.
XSD_FLOAT (integer)104Encoding for standard XMLSchema float type. Can be passed to SoapVar constructor.
XSD_DOUBLE (integer)105Encoding for standard XMLSchema double type. Can be passed to SoapVar constructor.
XSD_DURATION (integer)106Encoding for standard XMLSchema duration type. Can be passed to SoapVar constructor.
XSD_DATETIME (integer)107Encoding for standard XMLSchema dateTime type. Can be passed to SoapVar constructor.
XSD_TIME (integer)108Encoding for standard XMLSchema time type. Can be passed to SoapVar constructor.
XSD_DATE (integer)109Encoding for standard XMLSchema data type. Can be passed to SoapVar constructor.
XSD_GYEARMONTH (integer)110Encoding for standard XMLSchema gYearMonth type. Can be passed to SoapVar constructor.
XSD_GYEAR (integer)111Encoding for standard XMLSchema gYear type. Can be passed to SoapVar constructor.
XSD_GMONTHDAY (integer)112Encoding for standard XMLSchema gMonthDay type. Can be passed to SoapVar constructor.
XSD_GDAY (integer)113Encoding for standard XMLSchema gDay type. Can be passed to SoapVar constructor.
XSD_GMONTH (integer)114Encoding for standard XMLSchema gMonth type. Can be passed to SoapVar constructor.
XSD_HEXBINARY (integer)115Encoding for standard XMLSchema hexBinary type. Can be passed to SoapVar constructor.
XSD_BASE64BINARY (integer)116Encoding for standard XMLSchema base64Binary type. Can be passed to SoapVar constructor.
XSD_ANYURI (integer)117Encoding for standard XMLSchema anyURI type. Can be passed to SoapVar constructor.
XSD_QNAME (integer)118Encoding for standard XMLSchema QName type. Can be passed to SoapVar constructor.
XSD_NOTATION (integer)119Encoding for standard XMLSchema NOTATION type. Can be passed to SoapVar constructor.
XSD_NORMALIZEDSTRING (integer)120Encoding for standard XMLSchema normalizedString type. Can be passed to SoapVar constructor.
XSD_TOKEN (integer)121Encoding for standard XMLSchema token type. Can be passed to SoapVar constructor.
XSD_LANGUAGE (integer)122Encoding for standard XMLSchema language type. Can be passed to SoapVar constructor.
XSD_NMTOKEN (integer)123Encoding for standard XMLSchema NMTOKEN type. Can be passed to SoapVar constructor.
XSD_NAME (integer)124Encoding for standard XMLSchema Name type. Can be passed to SoapVar constructor.
XSD_NCNAME (integer)125Encoding for standard XMLSchema NCName type. Can be passed to SoapVar constructor.
XSD_ID (integer)126Encoding for standard XMLSchema ID type. Can be passed to SoapVar constructor.
XSD_IDREF (integer)127Encoding for standard XMLSchema IDREF type. Can be passed to SoapVar constructor.
XSD_IDREFS (integer)128Encoding for standard XMLSchema IDREFS type. Can be passed to SoapVar constructor.
XSD_ENTITY (integer)129Encoding for standard XMLSchema ENTITY type. Can be passed to SoapVar constructor.
XSD_ENTITIES (integer)130Encoding for standard XMLSchema ENTITIES type. Can be passed to SoapVar constructor.
XSD_INTEGER (integer)131Encoding for standard XMLSchema integer type. Can be passed to SoapVar constructor.
XSD_NONPOSITIVEINTEGER (integer)132Encoding for standard XMLSchema nonPositiveInteger type. Can be passed to SoapVar constructor.
XSD_NEGATIVEINTEGER (integer)133Encoding for standard XMLSchema negativeInteger type. Can be passed to SoapVar constructor.
XSD_LONG (integer)134Encoding for standard XMLSchema long type. Can be passed to SoapVar constructor.
XSD_INT (integer)135Encoding for standard XMLSchema int type. Can be passed to SoapVar constructor.
XSD_SHORT (integer)136Encoding for standard XMLSchema short type. Can be passed to SoapVar constructor.
XSD_BYTE (integer)137Encoding for standard XMLSchema byte type. Can be passed to SoapVar constructor.
XSD_NONNEGATIVEINTEGER (integer)138Encoding for standard XMLSchema nonNegativeInteger type. Can be passed to SoapVar constructor.
XSD_UNSIGNEDLONG (integer)139Encoding for standard XMLSchema unsignedLong type. Can be passed to SoapVar constructor.
XSD_UNSIGNEDINT (integer)140Encoding for standard XMLSchema unsignedInt type. Can be passed to SoapVar constructor.
XSD_UNSIGNEDSHORT (integer)141Encoding for standard XMLSchema unsignedShort type. Can be passed to SoapVar constructor.
XSD_UNSIGNEDBYTE (integer)142Encoding for standard XMLSchema unsignedByte type. Can be passed to SoapVar constructor.
XSD_POSITIVEINTEGER (integer)143Encoding for standard XMLSchema positiveInteger type. Can be passed to SoapVar constructor.
XSD_NMTOKENS (integer)144Encoding for standard XMLSchema NMTOKENS type. Can be passed to SoapVar constructor.
XSD_ANYTYPE (integer)145Encoding for standard XMLSchema anyType type. Can be passed to SoapVar constructor.
SOAP_ENC_ARRAY (integer)300Encoding for SOAP Array type. Can be passed to SoapVar constructor.
SOAP_ENC_OBJECT (integer)301Encoding for SOAP Struct type. Can be passed to SoapVar constructor.
XSD_1999_TIMEINSTANT (integer)401Encoding for old XMLSchema timeInstant type. Can be passed to SoapVar constructor.
XSD_NAMESPACE (string) The XML Schema namespace.
XSD_1999_NAMESPACE (string) The old XML Schema namespace.
-
-

Classes

-

List of classes

- - - - - - - -
SoapClient
SoapServer
SoapParam
SoapVar
SoapHeader
SoapFault
- -

SoapClient class

-A SOAP client, that allows calling remote methods on SOAP WebService over HTTP -or HTTPS. - - - - - - - -
SoapClient -- SoapClient constructor
__call -- calls a SOAP function
__getLastRequest -- returns last SOAP request
__getLastResponse -- returns last SOAP response
__getFunctions -- returns list of SOAP functions
__getTypes -- returns list of SOAP types
-
-

SoapServer class

-This class can be used to build SOAP WebServices, which can be accessed from -remote SOAP clients over HTTP or HTTPS. - - - - - - - -
SoapServer -- SoapServer constructor
addFunction -- adds one or several functions those will handle SOAP requests
setClass -- sets class which will handle SOAP requests
getFunctions -- returns list of defined functions
setPersistence -- sets persistence mode of SoapServer
handle -- handles a SOAP request
-
-

SoapParam class

-

-SoapParam is a special low-level class for naming parameters and return values -in nonWSDL mode. It is just a data holder and it has not any special method -except constructor. -

- - -
SoapParam -- SoapParam constructor
-
-

SoapVar classes

-

-SoapVar is a special low-level class for encoding parameters and return values -in nonWSDL mode. It is just a data holder and it has not any special method -except constructor. It is useful when you like to set type property in SOAP -request or response. -

- - -
SoapVar -- SoapVar constructor
-
-

SoapHeader class

-

-SoapHeader is a special low-level class for passing or returning SOAP headers. -It is just a data holder and it has not any special method except constructor. -

- - -
SoapHeader -- SoapHeader constructor
-
-

SoapFault class

-

-SoapFault is a special class that can be used for error reporting during -handling of SOAP request. It is derived form standard PHP Exception class, -so it can be used to throw exceptions in server side and to catch tham on -client side. -

- - -
SoapFault -- SoapFault constructor
-
- -

Table of Contents

- - - - - - - - - - - - - - - - - - -
is_soap_fault -- checks if SOAP call was failed
SoapClient::SoapClient -- SoapClient constructor
SoapClient::__call -- calls a SOAP function
SoapClient::__getLastRequest -- returns last SOAP request
SoapClient::__getLastResponse -- returns last SOAP response
SoapClient::__getFunctions -- returns list of SOAP functions
SoapClient::__getTypes -- returns list of SOAP types
SoapServer::SoapServer -- SoapServer constructor
SoapServer::addFunction -- adds one or several functions those will handle SOAP requests
SoapServer::setClass -- sets class which will handle SOAP requests
SoapServer::getFunctions -- returns list of defined functions
SoapServer::setPersistence -- sets persistence mode of SoapServer
SoapServer::handle -- handles a SOAP request
SoapParam::SoapParam -- SoapParam constructor
SoapVar::SoapVar -- SoapVar constructor
SoapHeader::SoapHeader -- SoapHeader constructor
SoapFault::SoapFault -- SoapFault constructor
- -
-

is_soap_fault

-

(PHP 5)

-

checks if SOAP call was failed

-

Description

-

bool is_soap_fault(mixed obj)

-

-This function is useful when you like to check if the SOAP call was failed, -but don't like to use exceptions. To use it you must create SoapClient object -with exceptions option set to zero or false. In this case SOAP method -will return a special SoapFault object which encapsulate the fault details -(faultcode, faultstring, faultactor and faultdetails). If exceptions is -not set then SOAP call will throw an exception on error.
-is_soap_fault() functions checks if the given parameter is a SoapFault object.
-

-

Example

-
-<?php
-    $client = SoapClient("some.wsdl",array("exceptions"=>0));
-    $result = $client->SomeFunction(...);
-    if (is_soap_fault($result)) {
-        trigger_error("SOAP Fault: (faultcode: {$result->faultcode}, faultstring: {$result->faulstring})", E_ERROR);
-    }
-?>
-

Standard method that used by SOAP extension for error reporting is excptions.

-
-<?php
-    try {
-        $client = SoapClient("some.wsdl");
-        $result = $client->SomeFunction(...);
-    } catch (SoapFault $fault) {
-        trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faulstring})", E_ERROR);
-    }
-?>
- - -

SoapClient::SoapClient

-

(PHP 5)

-

SoapClient constructor

-

Description

-

SoapClient(mixed wsdl [, array options])

-

-The constructor allows creating SoapClient objects in WSDL or nonWSDL mode. -The first case requires URI of WSDL file as first parameter and optional -options array. The second case requires NULL as first parameter and options -array with location and uri options set. Where location is -a URL to request and uri is a target namespace of the SOAP service. -style and use options has effect only on nonWSDL (in WSDL mode -they comes from WSDL file). soap_version option allows to work as SOAP 1.1 or -SOAP 1.2 client. -Some additional optional options allow using HTTP authentication (login -and password) and HTTP connection through proxy server (proxy_host, -proxy_port, proxy_login and proxy_password). -

-

Examples

-
-    $client = new SoapClient("some.wsdl");
-
-    $client = new SoapClient("some.wsdl",array('soap_version'   => SOAP_1_2));
-
-    $client = new SoapClient("some.wsdl",array('login'          => "some_name",
-                                               'password'       => "some_password"));
-
-    $client = new SoapClient("some.wsdl",array('proxy_host'     => "localhost",
-                                               'proxy_port'     => 8080));
-
-    $client = new SoapClient("some.wsdl",array('proxy_host'     => "localhost",
-                                               'proxy_port'     => 8080,
-                                               'proxy_login'    => "some_name",
-                                               'proxy_password' => "some_password"));
-
-    $client = new SoapClient(null,array('location' => "http://localhost/soap.php",
-                                        'uri'      => "http://test-uri/"));
-
-    $client = new SoapClient(null,array('location' => "http://localhost/soap.php",
-                                        'uri'      => "http://test-uri/",
-                                        'style'    => SOAP_DOCUMENT,
-                                        'use'      => SOAP_LITERAL));
-
- - -

SoapClient::__call

-

(PHP 5)

-

calls a SOAP function

-

Description

-

mixed __call(string function_name, array arguments, [array options [, mixed input_headers [, mixed &output_headers]]])

-

-This is a low level API function to make a SOAP call. Usually in WSDL mode -you can simple call SOAP functions as SoapClient methods. It is useful for -nonWSDL mode when 'soapaction' is unknown, 'uri' is differ form default or -when ypu like to send and/or receive SOAP Headers. To check if function call -is failed check the result with is_soap_fault() function.
-SOAP function may return one or several values. In the first case __call will -return just the value of output parameter, in the second it will return -array with named output parameters. -

-

Examples

-
-    $client = new SoapClient("some.wsdl");
-    $client->SomeFunction($a,$b,$c);
-    $client->__call("SomeFunction",array($a,$b,$c));
-    $client->__call("SomeFunction",array($a,$b,$c), NULL,
-                    new SoapHeader(...), $output_headers);
-
-
-    $client = new SoapClient(null,array('location' => "http://localhost/soap.php",
-                                        'uri'      => "http://test-uri/"));
-    $client->SomeFunction($a,$b,$c);
-    $client->__call("SomeFunction",array($a,$b,$c));
-    $client->__call("SomeFunction",array($a,$b,$c),
-                    array('soapaction' => 'some_action',
-                          'uri'        => 'some_uri'));
-
- - -

SoapClient::__getLastRequest

-

(PHP 5)

-

returns last SOAP request

-

Description

-

string __getLastRequest()

-

-This function works only with SoapClient which was created with trace option. -

-

Example

-
-<?php
-    $client = SoapClient("some.wsdl", array('trace'=>1));
-    $result = $client->SomeFunction(...);
-    echo "REQUEST:\n".$client->__getLastRequest()."\n";
-?>
-
- - -

SoapClient::__getLastResponse

-

(PHP 5)

-

returns last SOAP response

-

Description

-

string __getLastResponse()

-

-This function works only with SoapClient which was created with trace option. -

-

Example

-
-<?php
-    $client = SoapClient("some.wsdl", array('trace'=>1));
-    $result = $client->SomeFunction(...);
-    echo "RESPONSE:\n".$client->__getLastResponse()."\n";
-?>
-
- - -

SoapClient::__getFunctions

-

(PHP 5)

-

returns list of SOAP functions

-

Description

-

array __getFunctions()

-

-This function works only in WSDL mode. -

-

Example

-
-<?php
-    $client = SoapClient("some.wsdl");
-    var_dump($client->__getFunctions());
-?>
-
- - -

SoapClient::__getTypes

-

(PHP 5)

-

returns list of SOAP types

-

Description

-

array __getTypes()

-

-This function works only in WSDL mode. -

-

Example

-
-<?php
-    $client = SoapClient("some.wsdl");
-    var_dump($client->__getTypes());
-?>
-
- - -

SoapServer::SoapServer

-

(PHP 5)

-

SoapServer constructor

-

Description

-

SoapServer(mixed wsdl [, array options])

-It allows creating SoapServer objects in WSDL or nonWSDL mode. In the first -case wsdl must be set to URI of WSDL file. In the second wsdl -must be set to null and uti option must be set. Additional options -allow setting a default SOAP version (soap_version) and actor URI -(actor). - -

Examples

-
-    $server = new SoapServer("some.wsdl");
-
-    $server = new SoapServer("some.wsdl",array('soap_version'=>SOAP_1_2));
-
-    $server = new SoapServer("some.wsdl",array('actor'=>"http://example.org/ts-tests/C"));
-
-    $server = new SoapServer(null,array('uri'=>"http://test-uri/"));
-
- - -

SoapServer::addFunction

-

(PHP 5)

-

adds one or several functions those will handle SOAP requests

-

Description

-

void addFunction(mixed functions)

-Exports one or more functions for remote clients. To export one function pass -function name into functions parameter as string. To export several -functions pass an array of function names and to export all functions pass -a special constant SOAP_FUNCTIONS_ALL.
-Functions must receive all input arguments in the same order as defined -in WSDL file (They should not receive any output parameters as arguments) and -return one or more values. To return several values they must return array with -named output parameters. -

Examples

-
-    function func($inputString) {
-        return $inputString;
-    }
-    $server->addFunction("echoString");
-
-    function echoTwoStrings($inputString1, $inputString2) {
-        return array("outputString1"=>$inputString1,"outputString2"=>$inputString2);
-    }
-    $server->addFunction(array("echoString","echoTwoStrings"));
-
-    $server->addFunction(SOAP_FUNCTIONS_ALL);
-
- -
-

SoapServer::setClass

-

(PHP 5)

-

sets class which will handle SOAP requests

-

Description

-

void setClass(string class_name [, ...])

-Exports all methods from specified class. Additional parameters will be passed -to default class constructor during object creation. The object can be maiden -persistent across request for a given PHP session with -SoapServer::setPersistence method. -

Examples

-
-    $server->setClass("foo");
-
-    $server->setClass("foo", $arg1, $arg2);
-
- - -

SoapServer::getFunctions

-

(PHP 5)

-

returns list of defined functions

-

Description

-

array getFunctions()

- -
-

SoapServer::setPersistence

-

(PHP 5)

-

sets persistence mode of SoapServer

-

Description

-

void setPersistence(int mode)

-This function allows saving data between requests in PHP session. It works only -with server that exports functions form class (see -SoapServer:setCalss). -

Examples

-
-    $server->setpersistence(SOAP_PERSISTENCE_SESSION);
-
-    $server->setpersistence(SOAP_PERSISTENCE_REQUEST);
-
- - -

SoapServer::handle

-

(PHP 5)

-

handles a SOAP request

-

Description

-

void handle([string soap_envelope])

-It processes a SOAP request, call necessary functions, and send response back. -It assumes request in input parameter or in global $HTTP_RAW_POST_DATA PHP variable -if the argument is omitted. -

Example

-
-<?php
-    function test($x) {
-        return $x;
-    }
-
-    $server = new SoapServer(null,array('uri'=>"http://test-uri/"));
-    $server->addFunction("test");
-    $server->handle();
-?>
-
- - -

SoapParam::SoapParam

-

(PHP 5)

-

SoapParam constructor

-

Description

-

SoapParam(mixed data, string name)

-

-SoapParam is a special low-level class for naming parameters and return values -in nonWSDL mode. It is just a data holder and it has not any special method -except constructor. The constructor takes data to pass or return and -name. It is possible to pass parameter directly as PHP value, but in -this case it will be named as paramN and SOAP Service may not -understand it. -

-

Example

-
-<?php
-    $client = new SoapClient(null,array('location' => "http://localhost/soap.php",
-                                        'uri'      => "http://test-uri/"));
-    $client->SomeFunction(new SoapParam($a,"a"),
-                          new SoapParam($b,"b"),
-                          new SoapParam($c,"c"));
-?>
-
- - -

SoapVar::SoapVar

-

(PHP 5)

-

SoapVar constructor

-

Description

-

SoapVar(mixed data, int encoding [, string type [, string type_ns [, string name [, string name_ns]]]])

-

-SoapVar is a special low-level class for encoding parameters and return values -in nonWSDL mode. It is just a data holder and it has not any special method -except constructor. It is useful when you like to set type property in SOAP -request or response. The constructor takes data to pass or return, -encoding ID to encode it (see XSD_... constants) and as -option type name and namespace and value name and namespace. -

-

Example

-
-<?php
-    class SOAPStruct {
-    	function SOAPStruct($s, $i, $f) {
-    		$this->varString = $s;
-    		$this->varInt = $i;
-    		$this->varFloat = $f;
-    	}
-    }
-    $client = new SoapClient(null,array('location' => "http://localhost/soap.php",
-                                        'uri'      => "http://test-uri/"));
-    $struct = new SOAPStruct('arg',34,325.325);
-    $soapstruct = new SoapVar($struct,SOAP_ENC_OBJECT,"SOAPStruct","http://soapinterop.org/xsd");
-    $client->echoStruct(new SoapParam($soapstruct, "inputStruct"));
-?>
-
- - -

SoapHeader::SoapHeader

-

(PHP 5)

-

SoapHeader constructor

-

Description

-

SoapHeader(string name_ns, string name [, mixed data [, bool must_understand [, mixed actor]]])

-

-SoapHeader is a special low-level class for passing or returning SOAP headers. -It is just a data holder and it has not any special method except constructor. -It can be used in SoapClient::__call -method to pass SOAP header or in SOAP header handler to return header in SOAP -response. name_ns and name are namespace and name of the SOAP -header element. data is a SOAP header's content. It can be a PHP value -or SoapVar object. must_understand and actor are values for -mustUnderstand and actor attributes of this SOAP -Header element. -

-

Example

-
-<?php
-    $client = new SoapClient(null,array('location' => "http://localhost/soap.php",
-                                        'uri'      => "http://test-uri/"));
-    $client->__call("echoVoid",NULL,NULL,
-                    new SoapHeader('http://soapinterop.org/echoheader/',
-                                   'echoMeStringRequest',
-                                   'hello world'));
-?>
-
- - -

SoapFault::SoapFault

-

(PHP 5)

-

SoapFault constructor

-

Description

-

SoapFault(string faultcode, string faultstring [, string faultactor [, mixed details [, string faultname [, mixed headerfault]]]])

-This class is useful when you like to send SOAP fault response from PHP handler.
-faultcode, faultstring, faultactor and details are standard elements of SOAP Fault;
-faultname is an optional parameter that can be used to select proper fault encoding from WSDL.
-headerfault is an optional parameter that can be used during SOAP header handling to report error in response header. -

Example

-
-<?php
-    function test($x) {
-        return new SoapFault("Server","Some error message");
-    }
-
-    $server = new SoapServer(null,array('uri'=>"http://test-uri/"));
-    $server->addFunction("test");
-    $server->handle();
-?>
-
-

It is possible to use PHP exception mechanism to throw SOAP Fault.

-
-<?php
-    function test($x) {
-        throw new SoapFault("Server","Some error message");
-    }
-
-    $server = new SoapServer(null,array('uri'=>"http://test-uri/"));
-    $server->addFunction("test");
-    $server->handle();
-?>
-
- + + +PHP SOAP Manual + + + + +

PHP SOAP

+

Introduction

+ + + +
Warning
This extension is EXPERIMENTAL. The behaviour of this extension -- including the names of its functions and anything else documented about this extension -- may change without notice in a future release of PHP. Use this extension at your own risk. +
+

+SOAP extension can be used to write SOAP Servers and Clients. It supports +subsets of SOAP 1.1, +SOAP 1.2 and +WSDL 1.1 specifications. +

+
+

Requirements

+This extension makes use of the GNOME XML library. Download and install this library. You will need at least libxml-2.5.4. +
+

Installation

+This extension is only available if PHP was configured with --enable-soap. +
+

Runtime Configuration

+

The behaviour of these functions is affected by settings in php.ini.

+ + + + + +
NameDefaultChangeable
soap.wsdl_cache_enabled"1"PHP_INI_ALL
soap.wsdl_cache_dir"/tmp"PHP_INI_ALL
soap.wsdl_cache_ttl86400PHP_INI_ALL
+

Here is a short explanation of the configuration directives.

+
+
soap.wsdl_cache_enabled (boolean)
+
enables or disables WSDL caching feature.
+
soap.wsdl_cache_dir (string)
+
sets the directory name where SOAP extension will put cache files
+
soap.wsdl_cache_ttl (integer)
+
(time to live) sets the number of second while cached file will be used instead of original one.
+
+ + +
+

Predefined Constants

+The constants below are defined by this extension, and will only be available when the extension has either been compiled into PHP or dynamically loaded at runtime. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ConstantValueDescription
SOAP_1_1 (integer)1SOAP version - SOAP 1.1. Can be used as an option in SoapClient and SoapServer constructors.
SOAP_1_2 (integer)2SOAP version - SOAP 1.2. Can be used as an option in SoapClient and SoapServer constructors.
SOAP_FUNCTIONS_ALL (integer)999Allows to export all defined functions with SoapClient::addFunction
SOAP_PERSISTENCE_SESSION (integer)1Allows making class passed to SoapServer::setClass persistent for a PHP session.
SOAP_PERSISTENCE_REQUEST (integer)2Allows making class passed to SoapServer::setClass non-persistent for a PHP session.
SOAP_ENCODED (integer)1Can be passed as style option to SoapClient constructor in nonWSDL mode.
SOAP_LITERAL (integer)2Can be passed as style option to SoapClient constructor in nonWSDL mode.
SOAP_RPC (integer)1Can be passed as use option to SoapClient constructor in nonWSDL mode.
SOAP_DOCUMENT (integer)2Can be passed as use option to SoapClient constructor in nonWSDL mode.
SOAP_ACTOR_NEXT (integer)1Can be passed as actor to SoapHeader constructor.
SOAP_ACTOR_NONE (integer)2Can be passed as actor to SoapHeader constructor
SOAP_ACTOR_UNLIMATERECEIVER (integer)3Can be passed as actor to SoapHeader constructor
UNKNOWN_TYPE (integer)999998Encoding for unknown type. Can be passed to SoapVar constructor.
XSD_STRING (integer)101Encoding for standard XMLSchema string type. Can be passed to SoapVar constructor.
XSD_BOOLEAN (integer)102Encoding for standard XMLSchema boolen type. Can be passed to SoapVar constructor.
XSD_DECIMAL (integer)103Encoding for standard XMLSchema decimal type. Can be passed to SoapVar constructor.
XSD_FLOAT (integer)104Encoding for standard XMLSchema float type. Can be passed to SoapVar constructor.
XSD_DOUBLE (integer)105Encoding for standard XMLSchema double type. Can be passed to SoapVar constructor.
XSD_DURATION (integer)106Encoding for standard XMLSchema duration type. Can be passed to SoapVar constructor.
XSD_DATETIME (integer)107Encoding for standard XMLSchema dateTime type. Can be passed to SoapVar constructor.
XSD_TIME (integer)108Encoding for standard XMLSchema time type. Can be passed to SoapVar constructor.
XSD_DATE (integer)109Encoding for standard XMLSchema data type. Can be passed to SoapVar constructor.
XSD_GYEARMONTH (integer)110Encoding for standard XMLSchema gYearMonth type. Can be passed to SoapVar constructor.
XSD_GYEAR (integer)111Encoding for standard XMLSchema gYear type. Can be passed to SoapVar constructor.
XSD_GMONTHDAY (integer)112Encoding for standard XMLSchema gMonthDay type. Can be passed to SoapVar constructor.
XSD_GDAY (integer)113Encoding for standard XMLSchema gDay type. Can be passed to SoapVar constructor.
XSD_GMONTH (integer)114Encoding for standard XMLSchema gMonth type. Can be passed to SoapVar constructor.
XSD_HEXBINARY (integer)115Encoding for standard XMLSchema hexBinary type. Can be passed to SoapVar constructor.
XSD_BASE64BINARY (integer)116Encoding for standard XMLSchema base64Binary type. Can be passed to SoapVar constructor.
XSD_ANYURI (integer)117Encoding for standard XMLSchema anyURI type. Can be passed to SoapVar constructor.
XSD_QNAME (integer)118Encoding for standard XMLSchema QName type. Can be passed to SoapVar constructor.
XSD_NOTATION (integer)119Encoding for standard XMLSchema NOTATION type. Can be passed to SoapVar constructor.
XSD_NORMALIZEDSTRING (integer)120Encoding for standard XMLSchema normalizedString type. Can be passed to SoapVar constructor.
XSD_TOKEN (integer)121Encoding for standard XMLSchema token type. Can be passed to SoapVar constructor.
XSD_LANGUAGE (integer)122Encoding for standard XMLSchema language type. Can be passed to SoapVar constructor.
XSD_NMTOKEN (integer)123Encoding for standard XMLSchema NMTOKEN type. Can be passed to SoapVar constructor.
XSD_NAME (integer)124Encoding for standard XMLSchema Name type. Can be passed to SoapVar constructor.
XSD_NCNAME (integer)125Encoding for standard XMLSchema NCName type. Can be passed to SoapVar constructor.
XSD_ID (integer)126Encoding for standard XMLSchema ID type. Can be passed to SoapVar constructor.
XSD_IDREF (integer)127Encoding for standard XMLSchema IDREF type. Can be passed to SoapVar constructor.
XSD_IDREFS (integer)128Encoding for standard XMLSchema IDREFS type. Can be passed to SoapVar constructor.
XSD_ENTITY (integer)129Encoding for standard XMLSchema ENTITY type. Can be passed to SoapVar constructor.
XSD_ENTITIES (integer)130Encoding for standard XMLSchema ENTITIES type. Can be passed to SoapVar constructor.
XSD_INTEGER (integer)131Encoding for standard XMLSchema integer type. Can be passed to SoapVar constructor.
XSD_NONPOSITIVEINTEGER (integer)132Encoding for standard XMLSchema nonPositiveInteger type. Can be passed to SoapVar constructor.
XSD_NEGATIVEINTEGER (integer)133Encoding for standard XMLSchema negativeInteger type. Can be passed to SoapVar constructor.
XSD_LONG (integer)134Encoding for standard XMLSchema long type. Can be passed to SoapVar constructor.
XSD_INT (integer)135Encoding for standard XMLSchema int type. Can be passed to SoapVar constructor.
XSD_SHORT (integer)136Encoding for standard XMLSchema short type. Can be passed to SoapVar constructor.
XSD_BYTE (integer)137Encoding for standard XMLSchema byte type. Can be passed to SoapVar constructor.
XSD_NONNEGATIVEINTEGER (integer)138Encoding for standard XMLSchema nonNegativeInteger type. Can be passed to SoapVar constructor.
XSD_UNSIGNEDLONG (integer)139Encoding for standard XMLSchema unsignedLong type. Can be passed to SoapVar constructor.
XSD_UNSIGNEDINT (integer)140Encoding for standard XMLSchema unsignedInt type. Can be passed to SoapVar constructor.
XSD_UNSIGNEDSHORT (integer)141Encoding for standard XMLSchema unsignedShort type. Can be passed to SoapVar constructor.
XSD_UNSIGNEDBYTE (integer)142Encoding for standard XMLSchema unsignedByte type. Can be passed to SoapVar constructor.
XSD_POSITIVEINTEGER (integer)143Encoding for standard XMLSchema positiveInteger type. Can be passed to SoapVar constructor.
XSD_NMTOKENS (integer)144Encoding for standard XMLSchema NMTOKENS type. Can be passed to SoapVar constructor.
XSD_ANYTYPE (integer)145Encoding for standard XMLSchema anyType type. Can be passed to SoapVar constructor.
SOAP_ENC_ARRAY (integer)300Encoding for SOAP Array type. Can be passed to SoapVar constructor.
SOAP_ENC_OBJECT (integer)301Encoding for SOAP Struct type. Can be passed to SoapVar constructor.
XSD_1999_TIMEINSTANT (integer)401Encoding for old XMLSchema timeInstant type. Can be passed to SoapVar constructor.
XSD_NAMESPACE (string) The XML Schema namespace.
XSD_1999_NAMESPACE (string) The old XML Schema namespace.
+
+

Classes

+

List of classes

+ + + + + + + +
SoapClient
SoapServer
SoapParam
SoapVar
SoapHeader
SoapFault
+ +

SoapClient class

+A SOAP client, that allows calling remote methods on SOAP WebService over HTTP +or HTTPS. + + + + + + + +
SoapClient -- SoapClient constructor
__call -- calls a SOAP function
__getLastRequest -- returns last SOAP request
__getLastResponse -- returns last SOAP response
__getFunctions -- returns list of SOAP functions
__getTypes -- returns list of SOAP types
+
+

SoapServer class

+This class can be used to build SOAP WebServices, which can be accessed from +remote SOAP clients over HTTP or HTTPS. + + + + + + + +
SoapServer -- SoapServer constructor
addFunction -- adds one or several functions those will handle SOAP requests
setClass -- sets class which will handle SOAP requests
getFunctions -- returns list of defined functions
setPersistence -- sets persistence mode of SoapServer
handle -- handles a SOAP request
+
+

SoapParam class

+

+SoapParam is a special low-level class for naming parameters and return values +in nonWSDL mode. It is just a data holder and it has not any special method +except constructor. +

+ + +
SoapParam -- SoapParam constructor
+
+

SoapVar classes

+

+SoapVar is a special low-level class for encoding parameters and return values +in nonWSDL mode. It is just a data holder and it has not any special method +except constructor. It is useful when you like to set type property in SOAP +request or response. +

+ + +
SoapVar -- SoapVar constructor
+
+

SoapHeader class

+

+SoapHeader is a special low-level class for passing or returning SOAP headers. +It is just a data holder and it has not any special method except constructor. +

+ + +
SoapHeader -- SoapHeader constructor
+
+

SoapFault class

+

+SoapFault is a special class that can be used for error reporting during +handling of SOAP request. It is derived form standard PHP Exception class, +so it can be used to throw exceptions in server side and to catch tham on +client side. +

+ + +
SoapFault -- SoapFault constructor
+
+ +

Table of Contents

+ + + + + + + + + + + + + + + + + + +
is_soap_fault -- checks if SOAP call was failed
SoapClient::SoapClient -- SoapClient constructor
SoapClient::__call -- calls a SOAP function
SoapClient::__getLastRequest -- returns last SOAP request
SoapClient::__getLastResponse -- returns last SOAP response
SoapClient::__getFunctions -- returns list of SOAP functions
SoapClient::__getTypes -- returns list of SOAP types
SoapServer::SoapServer -- SoapServer constructor
SoapServer::addFunction -- adds one or several functions those will handle SOAP requests
SoapServer::setClass -- sets class which will handle SOAP requests
SoapServer::getFunctions -- returns list of defined functions
SoapServer::setPersistence -- sets persistence mode of SoapServer
SoapServer::handle -- handles a SOAP request
SoapParam::SoapParam -- SoapParam constructor
SoapVar::SoapVar -- SoapVar constructor
SoapHeader::SoapHeader -- SoapHeader constructor
SoapFault::SoapFault -- SoapFault constructor
+ +
+

is_soap_fault

+

(PHP 5)

+

checks if SOAP call was failed

+

Description

+

bool is_soap_fault(mixed obj)

+

+This function is useful when you like to check if the SOAP call was failed, +but don't like to use exceptions. To use it you must create SoapClient object +with exceptions option set to zero or false. In this case SOAP method +will return a special SoapFault object which encapsulate the fault details +(faultcode, faultstring, faultactor and faultdetails). If exceptions is +not set then SOAP call will throw an exception on error.
+is_soap_fault() functions checks if the given parameter is a SoapFault object.
+

+

Example

+
+<?php
+    $client = SoapClient("some.wsdl",array("exceptions"=>0));
+    $result = $client->SomeFunction(...);
+    if (is_soap_fault($result)) {
+        trigger_error("SOAP Fault: (faultcode: {$result->faultcode}, faultstring: {$result->faulstring})", E_ERROR);
+    }
+?>
+

Standard method that used by SOAP extension for error reporting is excptions.

+
+<?php
+    try {
+        $client = SoapClient("some.wsdl");
+        $result = $client->SomeFunction(...);
+    } catch (SoapFault $fault) {
+        trigger_error("SOAP Fault: (faultcode: {$fault->faultcode}, faultstring: {$fault->faulstring})", E_ERROR);
+    }
+?>
+ + +

SoapClient::SoapClient

+

(PHP 5)

+

SoapClient constructor

+

Description

+

SoapClient(mixed wsdl [, array options])

+

+The constructor allows creating SoapClient objects in WSDL or nonWSDL mode. +The first case requires URI of WSDL file as first parameter and optional +options array. The second case requires NULL as first parameter and options +array with location and uri options set. Where location is +a URL to request and uri is a target namespace of the SOAP service. +style and use options has effect only on nonWSDL (in WSDL mode +they comes from WSDL file). soap_version option allows to work as SOAP 1.1 or +SOAP 1.2 client. +Some additional optional options allow using HTTP authentication (login +and password) and HTTP connection through proxy server (proxy_host, +proxy_port, proxy_login and proxy_password). +

+

Examples

+
+    $client = new SoapClient("some.wsdl");
+
+    $client = new SoapClient("some.wsdl",array('soap_version'   => SOAP_1_2));
+
+    $client = new SoapClient("some.wsdl",array('login'          => "some_name",
+                                               'password'       => "some_password"));
+
+    $client = new SoapClient("some.wsdl",array('proxy_host'     => "localhost",
+                                               'proxy_port'     => 8080));
+
+    $client = new SoapClient("some.wsdl",array('proxy_host'     => "localhost",
+                                               'proxy_port'     => 8080,
+                                               'proxy_login'    => "some_name",
+                                               'proxy_password' => "some_password"));
+
+    $client = new SoapClient(null,array('location' => "http://localhost/soap.php",
+                                        'uri'      => "http://test-uri/"));
+
+    $client = new SoapClient(null,array('location' => "http://localhost/soap.php",
+                                        'uri'      => "http://test-uri/",
+                                        'style'    => SOAP_DOCUMENT,
+                                        'use'      => SOAP_LITERAL));
+
+ + +

SoapClient::__call

+

(PHP 5)

+

calls a SOAP function

+

Description

+

mixed __call(string function_name, array arguments, [array options [, mixed input_headers [, mixed &output_headers]]])

+

+This is a low level API function to make a SOAP call. Usually in WSDL mode +you can simple call SOAP functions as SoapClient methods. It is useful for +nonWSDL mode when 'soapaction' is unknown, 'uri' is differ form default or +when ypu like to send and/or receive SOAP Headers. To check if function call +is failed check the result with is_soap_fault() function.
+SOAP function may return one or several values. In the first case __call will +return just the value of output parameter, in the second it will return +array with named output parameters. +

+

Examples

+
+    $client = new SoapClient("some.wsdl");
+    $client->SomeFunction($a,$b,$c);
+    $client->__call("SomeFunction",array($a,$b,$c));
+    $client->__call("SomeFunction",array($a,$b,$c), NULL,
+                    new SoapHeader(...), $output_headers);
+
+
+    $client = new SoapClient(null,array('location' => "http://localhost/soap.php",
+                                        'uri'      => "http://test-uri/"));
+    $client->SomeFunction($a,$b,$c);
+    $client->__call("SomeFunction",array($a,$b,$c));
+    $client->__call("SomeFunction",array($a,$b,$c),
+                    array('soapaction' => 'some_action',
+                          'uri'        => 'some_uri'));
+
+ + +

SoapClient::__getLastRequest

+

(PHP 5)

+

returns last SOAP request

+

Description

+

string __getLastRequest()

+

+This function works only with SoapClient which was created with trace option. +

+

Example

+
+<?php
+    $client = SoapClient("some.wsdl", array('trace'=>1));
+    $result = $client->SomeFunction(...);
+    echo "REQUEST:\n".$client->__getLastRequest()."\n";
+?>
+
+ + +

SoapClient::__getLastResponse

+

(PHP 5)

+

returns last SOAP response

+

Description

+

string __getLastResponse()

+

+This function works only with SoapClient which was created with trace option. +

+

Example

+
+<?php
+    $client = SoapClient("some.wsdl", array('trace'=>1));
+    $result = $client->SomeFunction(...);
+    echo "RESPONSE:\n".$client->__getLastResponse()."\n";
+?>
+
+ + +

SoapClient::__getFunctions

+

(PHP 5)

+

returns list of SOAP functions

+

Description

+

array __getFunctions()

+

+This function works only in WSDL mode. +

+

Example

+
+<?php
+    $client = SoapClient("some.wsdl");
+    var_dump($client->__getFunctions());
+?>
+
+ + +

SoapClient::__getTypes

+

(PHP 5)

+

returns list of SOAP types

+

Description

+

array __getTypes()

+

+This function works only in WSDL mode. +

+

Example

+
+<?php
+    $client = SoapClient("some.wsdl");
+    var_dump($client->__getTypes());
+?>
+
+ + +

SoapServer::SoapServer

+

(PHP 5)

+

SoapServer constructor

+

Description

+

SoapServer(mixed wsdl [, array options])

+It allows creating SoapServer objects in WSDL or nonWSDL mode. In the first +case wsdl must be set to URI of WSDL file. In the second wsdl +must be set to null and uti option must be set. Additional options +allow setting a default SOAP version (soap_version) and actor URI +(actor). + +

Examples

+
+    $server = new SoapServer("some.wsdl");
+
+    $server = new SoapServer("some.wsdl",array('soap_version'=>SOAP_1_2));
+
+    $server = new SoapServer("some.wsdl",array('actor'=>"http://example.org/ts-tests/C"));
+
+    $server = new SoapServer(null,array('uri'=>"http://test-uri/"));
+
+ + +

SoapServer::addFunction

+

(PHP 5)

+

adds one or several functions those will handle SOAP requests

+

Description

+

void addFunction(mixed functions)

+Exports one or more functions for remote clients. To export one function pass +function name into functions parameter as string. To export several +functions pass an array of function names and to export all functions pass +a special constant SOAP_FUNCTIONS_ALL.
+Functions must receive all input arguments in the same order as defined +in WSDL file (They should not receive any output parameters as arguments) and +return one or more values. To return several values they must return array with +named output parameters. +

Examples

+
+    function func($inputString) {
+        return $inputString;
+    }
+    $server->addFunction("echoString");
+
+    function echoTwoStrings($inputString1, $inputString2) {
+        return array("outputString1"=>$inputString1,"outputString2"=>$inputString2);
+    }
+    $server->addFunction(array("echoString","echoTwoStrings"));
+
+    $server->addFunction(SOAP_FUNCTIONS_ALL);
+
+ +
+

SoapServer::setClass

+

(PHP 5)

+

sets class which will handle SOAP requests

+

Description

+

void setClass(string class_name [, ...])

+Exports all methods from specified class. Additional parameters will be passed +to default class constructor during object creation. The object can be maiden +persistent across request for a given PHP session with +SoapServer::setPersistence method. +

Examples

+
+    $server->setClass("foo");
+
+    $server->setClass("foo", $arg1, $arg2);
+
+ + +

SoapServer::getFunctions

+

(PHP 5)

+

returns list of defined functions

+

Description

+

array getFunctions()

+ +
+

SoapServer::setPersistence

+

(PHP 5)

+

sets persistence mode of SoapServer

+

Description

+

void setPersistence(int mode)

+This function allows saving data between requests in PHP session. It works only +with server that exports functions form class (see +SoapServer:setCalss). +

Examples

+
+    $server->setpersistence(SOAP_PERSISTENCE_SESSION);
+
+    $server->setpersistence(SOAP_PERSISTENCE_REQUEST);
+
+ + +

SoapServer::handle

+

(PHP 5)

+

handles a SOAP request

+

Description

+

void handle([string soap_envelope])

+It processes a SOAP request, call necessary functions, and send response back. +It assumes request in input parameter or in global $HTTP_RAW_POST_DATA PHP variable +if the argument is omitted. +

Example

+
+<?php
+    function test($x) {
+        return $x;
+    }
+
+    $server = new SoapServer(null,array('uri'=>"http://test-uri/"));
+    $server->addFunction("test");
+    $server->handle();
+?>
+
+ + +

SoapParam::SoapParam

+

(PHP 5)

+

SoapParam constructor

+

Description

+

SoapParam(mixed data, string name)

+

+SoapParam is a special low-level class for naming parameters and return values +in nonWSDL mode. It is just a data holder and it has not any special method +except constructor. The constructor takes data to pass or return and +name. It is possible to pass parameter directly as PHP value, but in +this case it will be named as paramN and SOAP Service may not +understand it. +

+

Example

+
+<?php
+    $client = new SoapClient(null,array('location' => "http://localhost/soap.php",
+                                        'uri'      => "http://test-uri/"));
+    $client->SomeFunction(new SoapParam($a,"a"),
+                          new SoapParam($b,"b"),
+                          new SoapParam($c,"c"));
+?>
+
+ + +

SoapVar::SoapVar

+

(PHP 5)

+

SoapVar constructor

+

Description

+

SoapVar(mixed data, int encoding [, string type [, string type_ns [, string name [, string name_ns]]]])

+

+SoapVar is a special low-level class for encoding parameters and return values +in nonWSDL mode. It is just a data holder and it has not any special method +except constructor. It is useful when you like to set type property in SOAP +request or response. The constructor takes data to pass or return, +encoding ID to encode it (see XSD_... constants) and as +option type name and namespace and value name and namespace. +

+

Example

+
+<?php
+    class SOAPStruct {
+    	function SOAPStruct($s, $i, $f) {
+    		$this->varString = $s;
+    		$this->varInt = $i;
+    		$this->varFloat = $f;
+    	}
+    }
+    $client = new SoapClient(null,array('location' => "http://localhost/soap.php",
+                                        'uri'      => "http://test-uri/"));
+    $struct = new SOAPStruct('arg',34,325.325);
+    $soapstruct = new SoapVar($struct,SOAP_ENC_OBJECT,"SOAPStruct","http://soapinterop.org/xsd");
+    $client->echoStruct(new SoapParam($soapstruct, "inputStruct"));
+?>
+
+ + +

SoapHeader::SoapHeader

+

(PHP 5)

+

SoapHeader constructor

+

Description

+

SoapHeader(string name_ns, string name [, mixed data [, bool must_understand [, mixed actor]]])

+

+SoapHeader is a special low-level class for passing or returning SOAP headers. +It is just a data holder and it has not any special method except constructor. +It can be used in SoapClient::__call +method to pass SOAP header or in SOAP header handler to return header in SOAP +response. name_ns and name are namespace and name of the SOAP +header element. data is a SOAP header's content. It can be a PHP value +or SoapVar object. must_understand and actor are values for +mustUnderstand and actor attributes of this SOAP +Header element. +

+

Example

+
+<?php
+    $client = new SoapClient(null,array('location' => "http://localhost/soap.php",
+                                        'uri'      => "http://test-uri/"));
+    $client->__call("echoVoid",NULL,NULL,
+                    new SoapHeader('http://soapinterop.org/echoheader/',
+                                   'echoMeStringRequest',
+                                   'hello world'));
+?>
+
+ + +

SoapFault::SoapFault

+

(PHP 5)

+

SoapFault constructor

+

Description

+

SoapFault(string faultcode, string faultstring [, string faultactor [, mixed details [, string faultname [, mixed headerfault]]]])

+This class is useful when you like to send SOAP fault response from PHP handler.
+faultcode, faultstring, faultactor and details are standard elements of SOAP Fault;
+faultname is an optional parameter that can be used to select proper fault encoding from WSDL.
+headerfault is an optional parameter that can be used during SOAP header handling to report error in response header. +

Example

+
+<?php
+    function test($x) {
+        return new SoapFault("Server","Some error message");
+    }
+
+    $server = new SoapServer(null,array('uri'=>"http://test-uri/"));
+    $server->addFunction("test");
+    $server->handle();
+?>
+
+

It is possible to use PHP exception mechanism to throw SOAP Fault.

+
+<?php
+    function test($x) {
+        throw new SoapFault("Server","Some error message");
+    }
+
+    $server = new SoapServer(null,array('uri'=>"http://test-uri/"));
+    $server->addFunction("test");
+    $server->handle();
+?>
+
+ \ No newline at end of file diff --git a/ext/soap/soap.c b/ext/soap/soap.c index ef16a9bb2..62abbe5fd 100644 --- a/ext/soap/soap.c +++ b/ext/soap/soap.c @@ -17,7 +17,7 @@ | Dmitry Stogov | +----------------------------------------------------------------------+ */ -/* $Id: soap.c,v 1.156.2.28.2.30.2.32 2009/02/18 13:25:48 dmitry Exp $ */ +/* $Id: soap.c 287746 2009-08-26 14:05:48Z dmitry $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -2128,8 +2128,13 @@ PHP_METHOD(SoapServer, fault) char *code, *string, *actor=NULL, *name=NULL; int code_len, string_len, actor_len = 0, name_len = 0; zval* details = NULL; + soapServicePtr service; + xmlCharEncodingHandlerPtr old_encoding; SOAP_SERVER_BEGIN_CODE(); + FETCH_THIS_SERVICE(service); + old_encoding = SOAP_GLOBAL(encoding); + SOAP_GLOBAL(encoding) = service->encoding; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|szs", &code, &code_len, &string, &string_len, &actor, &actor_len, &details, @@ -2138,6 +2143,8 @@ PHP_METHOD(SoapServer, fault) } soap_server_fault(code, string, actor, details, name TSRMLS_CC); + + SOAP_GLOBAL(encoding) = old_encoding; SOAP_SERVER_END_CODE(); } /* }}} */ diff --git a/ext/soap/tests/bugs/bug47273.phpt b/ext/soap/tests/bugs/bug47273.phpt new file mode 100644 index 000000000..174948f59 --- /dev/null +++ b/ext/soap/tests/bugs/bug47273.phpt @@ -0,0 +1,53 @@ +--TEST-- +Bug #47273 (Encoding bug in SoapServer->fault) +--SKIPIF-- + +--INI-- +unicode.script_encoding=ISO-8859-1 +unicode.output_encoding=ISO-8859-1 +--FILE-- + + +EOF; +$request2 = << + +EOF; + +class SoapFaultTest +{ + public function test1() { + // Test #1 + return 'Test #1 exception with some special chars: Äßö'; + } + public function test2() { + // Test #2 + //throw new SoapFault('Server', 'Test #2 exception with some special chars: Äßö'); + throw new Exception('Test #2 exception with some special chars: Äßö'); + } +} + +$server = new SoapServer(null, array( +'uri' => "http://127.0.0.1:8080/test/", +'encoding' => 'ISO-8859-1')); +$server->setClass('SoapFaultTest'); + +try { + $server->handle($request1); +} catch (Exception $e) { + $server->fault("Sender", $e->getMessage()); +} +try { + $server->handle($request2); +} catch (Exception $e) { + $server->fault("Sender", $e->getMessage()); +} +?> +--EXPECT-- + +Test #1 exception with some special chars: Äßö + +SenderTest #2 exception with some special chars: Äßö + diff --git a/ext/soap/tests/bugs/xml.xsd b/ext/soap/tests/bugs/xml.xsd index 7d599db74..abb844ac1 100644 --- a/ext/soap/tests/bugs/xml.xsd +++ b/ext/soap/tests/bugs/xml.xsd @@ -1,34 +1,34 @@ - - - - - - - In due course, we should install the relevant ISO 2- and 3-letter - codes as the enumerated possible values . . . - - - - - - - - - - - - - - - See http://www.w3.org/TR/xmlbase/ for - information about this attribute. - - - - - - - - - - + + + + + + + In due course, we should install the relevant ISO 2- and 3-letter + codes as the enumerated possible values . . . + + + + + + + + + + + + + + + See http://www.w3.org/TR/xmlbase/ for + information about this attribute. + + + + + + + + + + diff --git a/ext/soap/tests/schema/test_schema.inc b/ext/soap/tests/schema/test_schema.inc index 8c7d9d034..bfc4ce0db 100644 --- a/ext/soap/tests/schema/test_schema.inc +++ b/ext/soap/tests/schema/test_schema.inc @@ -1,77 +1,77 @@ - - - - - - $schema - - - - - - - - - - - - - - - - - - - - - - - - - -EOF; - - $fname = tempnam ("./", "wsdl"); - $f = fopen($fname,"w"); - fwrite($f,$wsdl); - fclose($f); - ini_set("soap.wsdl_cache_enabled",0); - $x = new SoapClient($fname, array("trace"=>1,"exceptions"=>0,"features"=>$features)); - $y = new SoapServer($fname, array("features"=>$features)); - $y->addfunction("test"); - unlink($fname); - - $x->test($param); - $xml = xml_parser_create(); - $req = $x->__getlastrequest(); - if ($style == "rpc") { - $HTTP_RAW_POST_DATA = $req; - ob_start(); - $y->handle($HTTP_RAW_POST_DATA); - ob_end_clean(); - echo $req; - var_dump($val); - } else { - echo $req; - } -} -?> + + + + + + $schema + + + + + + + + + + + + + + + + + + + + + + + + + +EOF; + + $fname = tempnam ("./", "wsdl"); + $f = fopen($fname,"w"); + fwrite($f,$wsdl); + fclose($f); + ini_set("soap.wsdl_cache_enabled",0); + $x = new SoapClient($fname, array("trace"=>1,"exceptions"=>0,"features"=>$features)); + $y = new SoapServer($fname, array("features"=>$features)); + $y->addfunction("test"); + unlink($fname); + + $x->test($param); + $xml = xml_parser_create(); + $req = $x->__getlastrequest(); + if ($style == "rpc") { + $HTTP_RAW_POST_DATA = $req; + ob_start(); + $y->handle($HTTP_RAW_POST_DATA); + ob_end_clean(); + echo $req; + var_dump($val); + } else { + echo $req; + } +} +?> diff --git a/ext/soap/tests/soap12/soap12-test.inc b/ext/soap/tests/soap12/soap12-test.inc index 7b2e2efea..fbdc855a7 100644 --- a/ext/soap/tests/soap12/soap12-test.inc +++ b/ext/soap/tests/soap12/soap12-test.inc @@ -1,131 +1,131 @@ - $struct->varString, - 'outputInteger' => $struct->varInt, - 'outputFloat' => $struct->varFloat); - } - - function echoSimpleTypesAsStruct($string, $int, $float) { - return (object)array("varString" => $string, - "varInt" => $int, - "varFloat" => $float); - } - - function echoNestedStruct($struct) { - return $struct; - } - - function echo2DStringArray($ary) { - return $ary; - } - - function echoNestedArray($ary) { - return $ary; - } - - function countItems($input) { - return count($input); - } - - function isNil($input) { - return is_null($input); - } - - function returnVoid() { - } - - function emptyBody() { - } - - function requiredHeader($x) { - $this->header = $x; - } - - function echoHeader() { - return $this->header; - } - - function echoResolvedRef($ref) { - return $ref->RelativeReference->base.$ref->RelativeReference->href; - } - - function validateCountryCode($code) { - if (strlen($code) != 2) { - return new SoapFault("Client", "Not a valid country code", NULL, NULL, NULL, new SoapHeader("http://example.org/ts-tests", "validateCountryCodeFault", "Country code must be 2 letters.")); - } else { - return "OK"; - } - } - -} - -ini_set("soap.wsdl_cache_enabled",0); -$server = new soapserver(dirname(__FILE__)."/soap12-test.wsdl", array('soap_version'=>SOAP_1_2,'actor'=>"http://example.org/ts-tests/C")); -$server->setClass("Soap12test"); - -$server->handle($HTTP_RAW_POST_DATA); -echo "ok\n"; -?> + $struct->varString, + 'outputInteger' => $struct->varInt, + 'outputFloat' => $struct->varFloat); + } + + function echoSimpleTypesAsStruct($string, $int, $float) { + return (object)array("varString" => $string, + "varInt" => $int, + "varFloat" => $float); + } + + function echoNestedStruct($struct) { + return $struct; + } + + function echo2DStringArray($ary) { + return $ary; + } + + function echoNestedArray($ary) { + return $ary; + } + + function countItems($input) { + return count($input); + } + + function isNil($input) { + return is_null($input); + } + + function returnVoid() { + } + + function emptyBody() { + } + + function requiredHeader($x) { + $this->header = $x; + } + + function echoHeader() { + return $this->header; + } + + function echoResolvedRef($ref) { + return $ref->RelativeReference->base.$ref->RelativeReference->href; + } + + function validateCountryCode($code) { + if (strlen($code) != 2) { + return new SoapFault("Client", "Not a valid country code", NULL, NULL, NULL, new SoapHeader("http://example.org/ts-tests", "validateCountryCodeFault", "Country code must be 2 letters.")); + } else { + return "OK"; + } + } + +} + +ini_set("soap.wsdl_cache_enabled",0); +$server = new soapserver(dirname(__FILE__)."/soap12-test.wsdl", array('soap_version'=>SOAP_1_2,'actor'=>"http://example.org/ts-tests/C")); +$server->setClass("Soap12test"); + +$server->handle($HTTP_RAW_POST_DATA); +echo "ok\n"; +?> diff --git a/ext/sockets/config.m4 b/ext/sockets/config.m4 index 8ebd25b92..ce18979ce 100644 --- a/ext/sockets/config.m4 +++ b/ext/sockets/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.15.4.1.2.1 2007/07/22 22:18:41 jani Exp $ +dnl $Id: config.m4 240160 2007-07-22 22:18:41Z jani $ dnl PHP_ARG_ENABLE(sockets, whether to enable sockets support, diff --git a/ext/sockets/config.w32 b/ext/sockets/config.w32 index 7b7a3ca50..320a19b1b 100644 --- a/ext/sockets/config.w32 +++ b/ext/sockets/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.1.8.2 2009/01/23 15:49:48 kalle Exp $ +// $Id: config.w32 274392 2009-01-23 15:49:49Z kalle $ // vim:ft=javascript ARG_ENABLE("sockets", "SOCKETS support", "no"); diff --git a/ext/sockets/php_sockets.h b/ext/sockets/php_sockets.h index fdf258d04..4f5c21e60 100644 --- a/ext/sockets/php_sockets.h +++ b/ext/sockets/php_sockets.h @@ -22,7 +22,7 @@ #ifndef PHP_SOCKETS_H #define PHP_SOCKETS_H -/* $Id: php_sockets.h,v 1.36.2.1.2.4.2.6 2009/01/24 12:42:19 bjori Exp $ */ +/* $Id: php_sockets.h 289417 2009-10-09 14:22:29Z pajoye $ */ #if HAVE_SOCKETS @@ -73,7 +73,9 @@ PHP_FUNCTION(socket_clear_error); #ifndef PHP_WIN32 typedef int PHP_SOCKET; +# define PHP_SOCKETS_API PHPAPI #else +# define PHP_SOCKETS_API __declspec(dllexport) typedef SOCKET PHP_SOCKET; #endif @@ -91,6 +93,8 @@ struct sockaddr_un { }; #endif +PHP_SOCKETS_API int php_sockets_le_socket(void); + /* Prototypes */ #ifdef ilia_0 /* not needed, only causes a compiler warning */ static int php_open_listen_sock(php_socket **php_sock, int port, int backlog TSRMLS_DC); diff --git a/ext/sockets/sockets.c b/ext/sockets/sockets.c index 03d5c847d..6e74490a5 100644 --- a/ext/sockets/sockets.c +++ b/ext/sockets/sockets.c @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sockets.c,v 1.171.2.9.2.14.2.20 2009/06/04 18:17:43 andrei Exp $ */ +/* $Id: sockets.c 289417 2009-10-09 14:22:29Z pajoye $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -323,6 +323,12 @@ ZEND_GET_MODULE(sockets) /* inet_ntop should be used instead of inet_ntoa */ int inet_ntoa_lock = 0; +PHP_SOCKETS_API int php_sockets_le_socket(void) /* {{{ */ +{ + return le_socket; +} +/* }}} */ + static void php_destroy_socket(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ { php_socket *php_sock = (php_socket *) rsrc->ptr; @@ -364,14 +370,14 @@ static int php_open_listen_sock(php_socket **php_sock, int port, int backlog TSR sock->type = PF_INET; - if (bind(sock->bsd_socket, (struct sockaddr *)&la, sizeof(la)) < 0) { + if (bind(sock->bsd_socket, (struct sockaddr *)&la, sizeof(la)) != 0) { PHP_SOCKET_ERROR(sock, "unable to bind to given address", errno); close(sock->bsd_socket); efree(sock); return 0; } - if (listen(sock->bsd_socket, backlog) < 0) { + if (listen(sock->bsd_socket, backlog) != 0) { PHP_SOCKET_ERROR(sock, "unable to listen on socket", errno); close(sock->bsd_socket); efree(sock); diff --git a/ext/sockets/tests/bug46360.phpt b/ext/sockets/tests/bug46360.phpt new file mode 100644 index 000000000..c725a82f9 --- /dev/null +++ b/ext/sockets/tests/bug46360.phpt @@ -0,0 +1,17 @@ +--TEST-- +Bug 46360 - TCP_NODELAY constant (sock_get_option, sock_set_option) +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(11) "TCP_NODELAY" diff --git a/ext/sockets/tests/socket_bind.phpt b/ext/sockets/tests/socket_bind.phpt new file mode 100644 index 000000000..15181e68a --- /dev/null +++ b/ext/sockets/tests/socket_bind.phpt @@ -0,0 +1,38 @@ +--TEST-- +ext/sockets - socket_bind - basic test +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + + +--EXPECTF-- +bool(true) +bool(true) +int(16) +NULL + diff --git a/ext/sockets/tests/socket_bind_params.phpt b/ext/sockets/tests/socket_bind_params.phpt new file mode 100644 index 000000000..d68a62a47 --- /dev/null +++ b/ext/sockets/tests/socket_bind_params.phpt @@ -0,0 +1,29 @@ +--TEST-- +ext/sockets - socket_bind - test with empty parameters +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + +--EXPECTF-- + +Warning: socket_bind() expects at least 2 parameters, 0 given in %s on line %i +NULL + +Warning: socket_bind() expects at least 2 parameters, 1 given in %s on line %i +NULL diff --git a/ext/sockets/tests/socket_close_params.phpt b/ext/sockets/tests/socket_close_params.phpt new file mode 100644 index 000000000..a00330f5e --- /dev/null +++ b/ext/sockets/tests/socket_close_params.phpt @@ -0,0 +1,21 @@ +--TEST-- +ext/sockets - socket_close - test with empty parameters +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + +--EXPECTF-- + +Warning: socket_close() expects exactly 1 parameter, 0 given in %s on line %i +NULL diff --git a/ext/sockets/tests/socket_connect_error.phpt b/ext/sockets/tests/socket_connect_error.phpt new file mode 100644 index 000000000..33e60f3d5 --- /dev/null +++ b/ext/sockets/tests/socket_connect_error.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test error cases when creating a socket +--CREDITS-- +Russell Flynn +#PHPTestFest2009 Norway 2009-06-09 \o/ +--INI-- +error_reporting=E_ALL +display_errors=1 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: socket_create() expects exactly 3 parameters, 0 given in %s on line %d + +Warning: socket_create() expects exactly 3 parameters, 2 given in %s on line %d + +Warning: socket_create() expects parameter 1 to be long, array given in %s on line %d + diff --git a/ext/sockets/tests/socket_connect_params.phpt b/ext/sockets/tests/socket_connect_params.phpt new file mode 100644 index 000000000..c8dff06e8 --- /dev/null +++ b/ext/sockets/tests/socket_connect_params.phpt @@ -0,0 +1,33 @@ +--TEST-- +ext/sockets - socket_connect - test with empty parameters +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + +--EXPECTF-- + +Warning: socket_connect() expects at least 2 parameters, 0 given in %s on line %i + +Warning: socket_connect() expects at least 2 parameters, 1 given in %s on line %i + +Warning: socket_connect(): Socket of type AF_INET requires 3 arguments in %s on line %i + +Warning: socket_connect(): unable to connect [%i]: Transport endpoint is already connected in %s on line %i diff --git a/ext/sockets/tests/socket_create_listen.phpt b/ext/sockets/tests/socket_create_listen.phpt index 6d607cab6..440fade61 100644 --- a/ext/sockets/tests/socket_create_listen.phpt +++ b/ext/sockets/tests/socket_create_listen.phpt @@ -1,5 +1,5 @@ --TEST-- -Test if socket binds on 31337 +Test if socket binds on 31338 --SKIPIF-- +--FILE-- + +--EXPECTF-- +Warning: socket_create_listen() expects at least 1 parameter, 0 given in %s on line %i +NULL diff --git a/ext/sockets/tests/socket_create_listen_used.phpt b/ext/sockets/tests/socket_create_listen_used.phpt new file mode 100644 index 000000000..d89f1b70e --- /dev/null +++ b/ext/sockets/tests/socket_create_listen_used.phpt @@ -0,0 +1,30 @@ +--TEST-- +ext/sockets - socket_create_listen - test for used socket +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +resource(%i) of type (Socket) + +Warning: socket_create_listen(): unable to bind to given address [%i]: Address already in use in %s on line %i +bool(false) + +Warning: socket_close() expects parameter 1 to be resource, boolean given in %s on line %i diff --git a/ext/sockets/tests/socket_create_pair-wrongparams.phpt b/ext/sockets/tests/socket_create_pair-wrongparams.phpt index 64c5048ed..99512bcc3 100644 --- a/ext/sockets/tests/socket_create_pair-wrongparams.phpt +++ b/ext/sockets/tests/socket_create_pair-wrongparams.phpt @@ -24,17 +24,17 @@ NULL Warning: socket_create_pair() expects parameter 1 to be long, %unicode_string_optional% given in %s on line %d NULL -Warning: socket_create_pair(): unable to create socket pair [94]: Socket type not supported in %s on line %d +Warning: socket_create_pair(): unable to create socket pair [%d]: %s not supported in %s on line %d bool(false) Warning: socket_create_pair(): invalid socket domain [31337] specified for argument 1, assuming AF_INET in %s on line %d -Warning: socket_create_pair(): unable to create socket pair [94]: Socket type not supported in %s on line %d +Warning: socket_create_pair(): unable to create socket pair [%d]: %s not supported in %s on line %d bool(false) Warning: socket_create_pair(): invalid socket type [31337] specified for argument 2, assuming SOCK_STREAM in %s on line %d -Warning: socket_create_pair(): unable to create socket pair [95]: Operation not supported in %s on line %d +Warning: socket_create_pair(): unable to create socket pair [%d]: %s not supported %s on line %d bool(false) --CREDITS-- Till Klampaeckel, till@php.net diff --git a/ext/sockets/tests/socket_create_params.phpt b/ext/sockets/tests/socket_create_params.phpt new file mode 100644 index 000000000..13a1c73ee --- /dev/null +++ b/ext/sockets/tests/socket_create_params.phpt @@ -0,0 +1,24 @@ +--TEST-- +ext/sockets - socket_create - test with empty parameters +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + +--EXPECTF-- + +Warning: socket_create() expects exactly 3 parameters, 0 given in %s on line %i + +Warning: socket_create() expects exactly 3 parameters, 1 given in %s on line %i + +Warning: socket_create() expects exactly 3 parameters, 2 given in %s on line %i diff --git a/ext/sockets/tests/socket_getpeername.phpt b/ext/sockets/tests/socket_getpeername.phpt new file mode 100644 index 000000000..2252992c0 --- /dev/null +++ b/ext/sockets/tests/socket_getpeername.phpt @@ -0,0 +1,33 @@ +--TEST-- +ext/sockets - socket_getsockname - basic test +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + + +--EXPECTF-- +bool(true) + +Warning: socket_getpeername(): unable to retrieve peer name [%i]: Transport endpoint is not connected in %s on line %i +bool(false) +NULL +NULL diff --git a/ext/sockets/tests/socket_getpeername_ipv4loop.phpt b/ext/sockets/tests/socket_getpeername_ipv4loop.phpt new file mode 100644 index 000000000..aa59abb8d --- /dev/null +++ b/ext/sockets/tests/socket_getpeername_ipv4loop.phpt @@ -0,0 +1,59 @@ +--TEST-- +ext/sockets - socket_getpeername_ipv4loop - basic test +--CREDITS-- +# TestFest 2009 - NorwayUG +# $Id: socket_getpeername_ipv4loop.phpt 494 2009-06-09 20:38:05Z tatjana.andersen@redpill-linpro.com $ +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(9) "127.0.0.1" +int(31337) diff --git a/ext/sockets/tests/socket_getpeername_ipv6loop.phpt b/ext/sockets/tests/socket_getpeername_ipv6loop.phpt new file mode 100644 index 000000000..ba3c1347d --- /dev/null +++ b/ext/sockets/tests/socket_getpeername_ipv6loop.phpt @@ -0,0 +1,59 @@ +--TEST-- +ext/sockets - socket_getpeername_ipv6loop - basic test +--CREDITS-- +# TestFest 2009 - NorwayUG +# $Id: socket_getpeername_ipv6loop.phpt 494 2009-06-09 20:38:05Z tatjana.andersen@redpill-linpro.com $ +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(3) "::1" +int(31337) diff --git a/ext/sockets/tests/socket_getsockname.phpt b/ext/sockets/tests/socket_getsockname.phpt new file mode 100644 index 000000000..877bef501 --- /dev/null +++ b/ext/sockets/tests/socket_getsockname.phpt @@ -0,0 +1,32 @@ +--TEST-- +ext/sockets - socket_getsockname - basic test +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + + +--EXPECTF-- +bool(true) +bool(true) +string(7) "0.0.0.0" +int(%i) + diff --git a/ext/sockets/tests/socket_listen_params.phpt b/ext/sockets/tests/socket_listen_params.phpt new file mode 100644 index 000000000..65c11170f --- /dev/null +++ b/ext/sockets/tests/socket_listen_params.phpt @@ -0,0 +1,21 @@ +--TEST-- +ext/sockets - socket_listen - test with empty parameters +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + +--EXPECTF-- + +Warning: socket_listen() expects at least 1 parameter, 0 given in %s on line %i +NULL diff --git a/ext/sockets/tests/socket_read_params.phpt b/ext/sockets/tests/socket_read_params.phpt new file mode 100644 index 000000000..69af710ca --- /dev/null +++ b/ext/sockets/tests/socket_read_params.phpt @@ -0,0 +1,28 @@ +--TEST-- +ext/sockets - socket_read- test with empty parameters +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + +--EXPECTF-- + +Warning: socket_read() expects at least 2 parameters, 0 given in %s on line %i + +Warning: socket_read() expects at least 2 parameters, 1 given in %s on line %i + +Warning: socket_read(): unable to read from socket [%i]: Transport endpoint is not connected in %s on line %i diff --git a/ext/sockets/tests/socket_sentto_recvfrom_ipv4_udp.phpt b/ext/sockets/tests/socket_sentto_recvfrom_ipv4_udp.phpt index 64b657a48..8b7ed0bd3 100644 --- a/ext/sockets/tests/socket_sentto_recvfrom_ipv4_udp.phpt +++ b/ext/sockets/tests/socket_sentto_recvfrom_ipv4_udp.phpt @@ -44,7 +44,7 @@ if (!extension_loaded('sockets')) { socket_close($socket); --EXPECTF-- -Warning: socket_recvfrom(): unable to recvfrom [11]: Resource temporarily unavailable in %s on line %d +Warning: socket_recvfrom(): unable to recvfrom [%d]: Resource temporarily unavailable in %s on line %d Warning: Wrong parameter count for socket_sendto() in %s on line %d diff --git a/ext/sockets/tests/socket_sentto_recvfrom_unix.phpt b/ext/sockets/tests/socket_sentto_recvfrom_unix.phpt index 94eac3bdf..ab111898b 100644 --- a/ext/sockets/tests/socket_sentto_recvfrom_unix.phpt +++ b/ext/sockets/tests/socket_sentto_recvfrom_unix.phpt @@ -26,8 +26,10 @@ if (!extension_loaded('sockets')) { $bytes_sent = socket_sendto($socket, $msg, $len, 0); // cause warning $bytes_sent = socket_sendto($socket, $msg, $len, 0, $address); if ($bytes_sent == -1) { + @unlink($address); die('An error occured while sending to the socket'); } else if ($bytes_sent != $len) { + @unlink($address); die($bytes_sent . ' bytes have been sent instead of the ' . $len . ' bytes expected'); } @@ -35,17 +37,21 @@ if (!extension_loaded('sockets')) { var_dump(socket_recvfrom($socket, $buf, 0, 0, $from)); // expect false $bytes_received = socket_recvfrom($socket, $buf, 12, 0, $from); if ($bytes_received == -1) { + @unlink($address); die('An error occured while receiving from the socket'); } else if ($bytes_received != $len) { + @unlink($address); die($bytes_received . ' bytes have been received instead of the ' . $len . ' bytes expected'); } echo "Received $buf"; socket_close($socket); + @unlink($address); +?> --EXPECTF-- -Warning: socket_create(): Unable to create socket [93]: Protocol not supported in %s on line %d +Warning: socket_create(): Unable to create socket [%d]: Protocol not supported in %s on line %d -Warning: socket_recvfrom(): unable to recvfrom [11]: Resource temporarily unavailable in %s on line %d +Warning: socket_recvfrom(): unable to recvfrom [%d]: Resource temporarily unavailable in %s on line %d Warning: socket_sendto() expects at least 5 parameters, 4 given in %s on line %d bool(false) diff --git a/ext/sockets/tests/socket_set_block-retval.phpt b/ext/sockets/tests/socket_set_block-retval.phpt index fe09d5a5b..2aa4b0e5c 100644 --- a/ext/sockets/tests/socket_set_block-retval.phpt +++ b/ext/sockets/tests/socket_set_block-retval.phpt @@ -9,11 +9,11 @@ if (!extension_loaded('sockets')) { --FILE-- +--FILE-- + + +--EXPECTF-- +resource(%i) of type (Socket) + diff --git a/ext/sockets/tests/socket_strerror.phpt b/ext/sockets/tests/socket_strerror.phpt new file mode 100644 index 000000000..074d2ff7f --- /dev/null +++ b/ext/sockets/tests/socket_strerror.phpt @@ -0,0 +1,154 @@ +--TEST-- +ext/sockets - socket_strerror - basic test +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + +--EXPECTF-- + +Warning: socket_strerror() expects exactly 1 parameter, 0 given in %s on line %i +string(7) "Success" +string(23) "Operation not permitted" +string(25) "No such file or directory" +string(15) "No such process" +string(23) "Interrupted system call" +string(18) "Input/output error" +string(25) "No such device or address" +string(22) "Argument list too long" +string(17) "Exec format error" +string(19) "Bad file descriptor" +string(18) "No child processes" +string(32) "Resource temporarily unavailable" +string(22) "Cannot allocate memory" +string(17) "Permission denied" +string(11) "Bad address" +string(21) "Block device required" +string(23) "Device or resource busy" +string(11) "File exists" +string(25) "Invalid cross-device link" +string(14) "No such device" +string(15) "Not a directory" +string(14) "Is a directory" +string(16) "Invalid argument" +string(29) "Too many open files in system" +string(19) "Too many open files" +string(30) "Inappropriate ioctl for device" +string(14) "Text file busy" +string(14) "File too large" +string(23) "No space left on device" +string(12) "Illegal seek" +string(21) "Read-only file system" +string(14) "Too many links" +string(11) "Broken pipe" +string(32) "Numerical argument out of domain" +string(29) "Numerical result out of range" +string(25) "Resource deadlock avoided" +string(18) "File name too long" +string(18) "No locks available" +string(24) "Function not implemented" +string(19) "Directory not empty" +string(33) "Too many levels of symbolic links" +string(16) "Unknown error 41" +string(26) "No message of desired type" +string(18) "Identifier removed" +string(27) "Channel number out of range" +string(24) "Level 2 not synchronized" +string(14) "Level 3 halted" +string(13) "Level 3 reset" +string(24) "Link number out of range" +string(28) "Protocol driver not attached" +string(26) "No CSI structure available" +string(14) "Level 2 halted" +string(16) "Invalid exchange" +string(26) "Invalid request descriptor" +string(13) "Exchange full" +string(8) "No anode" +string(20) "Invalid request code" +string(12) "Invalid slot" +string(16) "Unknown error 58" +string(20) "Bad font file format" +string(19) "Device not a stream" +string(17) "No data available" +string(13) "Timer expired" +string(24) "Out of streams resources" +string(29) "Machine is not on the network" +string(21) "Package not installed" +string(16) "Object is remote" +string(21) "Link has been severed" +string(15) "Advertise error" +string(13) "Srmount error" +string(27) "Communication error on send" +string(14) "Protocol error" +string(18) "Multihop attempted" +string(18) "RFS specific error" +string(11) "Bad message" +string(37) "Value too large for defined data type" +string(26) "Name not unique on network" +string(28) "File descriptor in bad state" +string(22) "Remote address changed" +string(38) "Can not access a needed shared library" +string(36) "Accessing a corrupted shared library" +string(31) ".lib section in a.out corrupted" +string(47) "Attempting to link in too many shared libraries" +string(37) "Cannot exec a shared library directly" +string(49) "Invalid or incomplete multibyte or wide character" +string(43) "Interrupted system call should be restarted" +string(18) "Streams pipe error" +string(14) "Too many users" +string(30) "Socket operation on non-socket" +string(28) "Destination address required" +string(16) "Message too long" +string(30) "Protocol wrong type for socket" +string(22) "Protocol not available" +string(22) "Protocol not supported" +string(25) "Socket type not supported" +string(23) "Operation not supported" +string(29) "Protocol family not supported" +string(40) "Address family not supported by protocol" +string(22) "Address already in use" +string(31) "Cannot assign requested address" +string(15) "Network is down" +string(22) "Network is unreachable" +string(35) "Network dropped connection on reset" +string(32) "Software caused connection abort" +string(24) "Connection reset by peer" +string(25) "No buffer space available" +string(39) "Transport endpoint is already connected" +string(35) "Transport endpoint is not connected" +string(45) "Cannot send after transport endpoint shutdown" +string(34) "Too many references: cannot splice" +string(20) "Connection timed out" +string(18) "Connection refused" +string(12) "Host is down" +string(16) "No route to host" +string(29) "Operation already in progress" +string(25) "Operation now in progress" +string(21) "Stale NFS file handle" +string(24) "Structure needs cleaning" +string(27) "Not a XENIX named type file" +string(29) "No XENIX semaphores available" +string(20) "Is a named type file" +string(16) "Remote I/O error" +string(19) "Disk quota exceeded" +string(15) "No medium found" +string(17) "Wrong medium type" +string(18) "Operation canceled" +string(26) "Required key not available" +string(15) "Key has expired" +string(20) "Key has been revoked" +string(27) "Key was rejected by service" +string(10) "Owner died" +string(21) "State not recoverable" +string(17) "Unknown error 132" diff --git a/ext/sockets/tests/socket_write_params.phpt b/ext/sockets/tests/socket_write_params.phpt new file mode 100644 index 000000000..e23766ea6 --- /dev/null +++ b/ext/sockets/tests/socket_write_params.phpt @@ -0,0 +1,28 @@ +--TEST-- +ext/sockets - socket_write - test with empty parameters +--CREDITS-- +Florian Anderiasch +fa@php.net +--SKIPIF-- + +--FILE-- + +--EXPECTF-- + +Warning: socket_write() expects at least 2 parameters, 0 given in %s on line %i + +Warning: socket_write() expects at least 2 parameters, 1 given in %s on line %i + +Warning: socket_write(): unable to write to socket [%i]: Broken pipe in %s on line %i diff --git a/ext/sockets/unix_socket_constants.h b/ext/sockets/unix_socket_constants.h index 96dd7fbea..8403425c9 100644 --- a/ext/sockets/unix_socket_constants.h +++ b/ext/sockets/unix_socket_constants.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: unix_socket_constants.h,v 1.5.2.1.2.1.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: unix_socket_constants.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* This file is to be included by sockets.c */ diff --git a/ext/sockets/win32_socket_constants.h b/ext/sockets/win32_socket_constants.h index e2738ca37..f593ec674 100644 --- a/ext/sockets/win32_socket_constants.h +++ b/ext/sockets/win32_socket_constants.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: win32_socket_constants.h,v 1.5.2.1.2.1.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: win32_socket_constants.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* This file is to be included by sockets.c */ diff --git a/ext/spl/TODO b/ext/spl/TODO index 294c95ecd..68b00da6a 100755 --- a/ext/spl/TODO +++ b/ext/spl/TODO @@ -1,4 +1,4 @@ -This is the ToDo of ext/spl: - -Implement the classes/interfaces from the .inc files in +This is the ToDo of ext/spl: + +Implement the classes/interfaces from the .inc files in directory examples. \ No newline at end of file diff --git a/ext/spl/config.m4 b/ext/spl/config.m4 index 879936644..c3736291b 100755 --- a/ext/spl/config.m4 +++ b/ext/spl/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.13.2.4.2.3.2.6 2008/11/06 00:37:12 colder Exp $ +dnl $Id: config.m4 268395 2008-11-06 00:37:13Z colder $ dnl config.m4 for extension SPL AC_MSG_CHECKING(whether zend_object_value is packed) diff --git a/ext/spl/config.w32 b/ext/spl/config.w32 index 61744f180..a91c273b4 100644 --- a/ext/spl/config.w32 +++ b/ext/spl/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.7.6.7 2008/11/06 00:37:12 colder Exp $ +// $Id: config.w32 268395 2008-11-06 00:37:13Z colder $ // vim:ft=javascript EXTENSION("spl", "php_spl.c spl_functions.c spl_engine.c spl_iterators.c spl_array.c spl_directory.c spl_exceptions.c spl_observer.c spl_dllist.c spl_heap.c spl_fixedarray.c", false /*never shared */); diff --git a/ext/spl/examples/autoload.inc b/ext/spl/examples/autoload.inc index acb2e11e0..5871e7d63 100755 --- a/ext/spl/examples/autoload.inc +++ b/ext/spl/examples/autoload.inc @@ -1,50 +1,50 @@ - \ No newline at end of file diff --git a/ext/spl/examples/cachingrecursiveiterator.inc b/ext/spl/examples/cachingrecursiveiterator.inc index 352e42120..4fa6b235c 100644 --- a/ext/spl/examples/cachingrecursiveiterator.inc +++ b/ext/spl/examples/cachingrecursiveiterator.inc @@ -1,28 +1,28 @@ - \ No newline at end of file diff --git a/ext/spl/examples/class_tree.php b/ext/spl/examples/class_tree.php index 4dc5888d3..fc021d5c0 100755 --- a/ext/spl/examples/class_tree.php +++ b/ext/spl/examples/class_tree.php @@ -1,113 +1,113 @@ - - * - * Simply specify the root class or interface to tree with parameter \. - */ - -if ($argc < 2) { - echo << - -Displays a graphical tree for the given . - - The class or interface for which to generate the tree graph. - - -EOF; - exit(1); -} - -if (!class_exists("RecursiveTreeIterator", false)) require_once("recursivetreeiterator.inc"); - -/** \brief Collects sub classes for given class or interface - */ -class SubClasses extends RecursiveArrayIterator -{ - /** @param base base class to collect sub classes for - * @param check_interfaces whether we deal with interfaces - */ - function __construct($base, $check_interfaces = false) - { - foreach(get_declared_classes() as $cname) - { - $parent = get_parent_class($cname); - if (strcasecmp($parent, $base) == 0) - { - $this->offsetSet($cname, new SubClasses($cname)); - } - if ($check_interfaces) - { - if ($parent) - { - $parent_imp = class_implements($parent); - } - foreach(class_implements($cname) as $iname) - { - if (strcasecmp($iname, $base) == 0) - { - if (!$parent || !in_array($iname, $parent_imp)) - { - $this->offsetSet($cname, new SubClasses($cname)); - } - } - } - } - } - if ($check_interfaces) - { - foreach(get_declared_interfaces() as $cname) - { - foreach(class_implements($cname) as $iname) - { - if (strcasecmp($iname, $base) == 0) - { - $this->offsetSet($cname, new SubClasses($cname, true)); - } - } - } - } - $this->uksort('strnatcasecmp'); - } - - /** @return key() since that is the name we need - */ - function current() - { - $result = parent::key(); - $parent = get_parent_class($result); - if ($parent) - { - $interfaces = array_diff(class_implements($result), class_implements($parent)); - if ($interfaces) - { - $implements = array(); - foreach($interfaces as $interface) - { - $implements = array_merge($implements, class_implements($interface)); - } - $interfaces = array_diff($interfaces, $implements); - natcasesort($interfaces); - $result .= ' (' . join(', ', $interfaces) . ')'; - } - } - return $result; - } -} - -$it = new RecursiveTreeIterator(new SubClasses($argv[1], true)); - -echo $argv[1]."\n"; -foreach($it as $c=>$v) -{ - echo "$v\n"; -} - + + * + * Simply specify the root class or interface to tree with parameter \. + */ + +if ($argc < 2) { + echo << + +Displays a graphical tree for the given . + + The class or interface for which to generate the tree graph. + + +EOF; + exit(1); +} + +if (!class_exists("RecursiveTreeIterator", false)) require_once("recursivetreeiterator.inc"); + +/** \brief Collects sub classes for given class or interface + */ +class SubClasses extends RecursiveArrayIterator +{ + /** @param base base class to collect sub classes for + * @param check_interfaces whether we deal with interfaces + */ + function __construct($base, $check_interfaces = false) + { + foreach(get_declared_classes() as $cname) + { + $parent = get_parent_class($cname); + if (strcasecmp($parent, $base) == 0) + { + $this->offsetSet($cname, new SubClasses($cname)); + } + if ($check_interfaces) + { + if ($parent) + { + $parent_imp = class_implements($parent); + } + foreach(class_implements($cname) as $iname) + { + if (strcasecmp($iname, $base) == 0) + { + if (!$parent || !in_array($iname, $parent_imp)) + { + $this->offsetSet($cname, new SubClasses($cname)); + } + } + } + } + } + if ($check_interfaces) + { + foreach(get_declared_interfaces() as $cname) + { + foreach(class_implements($cname) as $iname) + { + if (strcasecmp($iname, $base) == 0) + { + $this->offsetSet($cname, new SubClasses($cname, true)); + } + } + } + } + $this->uksort('strnatcasecmp'); + } + + /** @return key() since that is the name we need + */ + function current() + { + $result = parent::key(); + $parent = get_parent_class($result); + if ($parent) + { + $interfaces = array_diff(class_implements($result), class_implements($parent)); + if ($interfaces) + { + $implements = array(); + foreach($interfaces as $interface) + { + $implements = array_merge($implements, class_implements($interface)); + } + $interfaces = array_diff($interfaces, $implements); + natcasesort($interfaces); + $result .= ' (' . join(', ', $interfaces) . ')'; + } + } + return $result; + } +} + +$it = new RecursiveTreeIterator(new SubClasses($argv[1], true)); + +echo $argv[1]."\n"; +foreach($it as $c=>$v) +{ + echo "$v\n"; +} + ?> \ No newline at end of file diff --git a/ext/spl/examples/dba_array.php b/ext/spl/examples/dba_array.php index 3375bd44f..346ac1f2f 100755 --- a/ext/spl/examples/dba_array.php +++ b/ext/spl/examples/dba_array.php @@ -1,52 +1,52 @@ - \ \ [\] - * - * If \ is specified then \ is set to \ in \. - * Else the value of \ is printed only. - * - * Note: configure with --enable-dba - */ - -if ($argc < 4) { - echo << [] - -If is specified then is set to in . -Else the value of is printed only. - - -EOF; - exit(1); -} - -if (!class_exists("DbaReader", false)) require_once("dbareader.inc"); - -try { - if ($argc > 2) { - $dba = new DbaArray($argv[1], $argv[2]); - if ($dba && $argc > 3) { - if ($argc > 4) { - $dba[$argv[3]] = $argv[4]; - } - var_dump(array('Index' => $argv[3], 'Value' => $dba[$argv[3]])); - } - unset($dba); - } - else - { - echo "Not enough parameters\n"; - exit(1); - } -} -catch (exception $err) { - var_dump($err); - exit(1); -} + \ \ [\] + * + * If \ is specified then \ is set to \ in \. + * Else the value of \ is printed only. + * + * Note: configure with --enable-dba + */ + +if ($argc < 4) { + echo << [] + +If is specified then is set to in . +Else the value of is printed only. + + +EOF; + exit(1); +} + +if (!class_exists("DbaReader", false)) require_once("dbareader.inc"); + +try { + if ($argc > 2) { + $dba = new DbaArray($argv[1], $argv[2]); + if ($dba && $argc > 3) { + if ($argc > 4) { + $dba[$argv[3]] = $argv[4]; + } + var_dump(array('Index' => $argv[3], 'Value' => $dba[$argv[3]])); + } + unset($dba); + } + else + { + echo "Not enough parameters\n"; + exit(1); + } +} +catch (exception $err) { + var_dump($err); + exit(1); +} ?> \ No newline at end of file diff --git a/ext/spl/examples/dba_dump.php b/ext/spl/examples/dba_dump.php index 33720932d..2c698d427 100755 --- a/ext/spl/examples/dba_dump.php +++ b/ext/spl/examples/dba_dump.php @@ -1,42 +1,42 @@ - \ [\] - * - * Show all groups in the ini file specified by \. - * The regular expression \ is used to filter the by setting name. - * - * Note: configure with --enable-dba - */ - -if ($argc < 3) { - echo << [] - -Show all groups in the ini file specified by . -The regular expression is used to filter the by setting name. - - -EOF; - exit(1); -} - -if (!class_exists("DbaReader", false)) require_once("dbareader.inc"); -if (!class_exists("KeyFilter", false)) require_once("keyfilter.inc"); - -$db = new DbaReader($argv[1], $argv[2]); - -if ($argc>3) { - $db = new KeyFilter($db, $argv[3]); -} - -foreach($db as $key => $val) { - echo "'$key' => '$val'\n"; -} - + \ [\] + * + * Show all groups in the ini file specified by \. + * The regular expression \ is used to filter the by setting name. + * + * Note: configure with --enable-dba + */ + +if ($argc < 3) { + echo << [] + +Show all groups in the ini file specified by . +The regular expression is used to filter the by setting name. + + +EOF; + exit(1); +} + +if (!class_exists("DbaReader", false)) require_once("dbareader.inc"); +if (!class_exists("KeyFilter", false)) require_once("keyfilter.inc"); + +$db = new DbaReader($argv[1], $argv[2]); + +if ($argc>3) { + $db = new KeyFilter($db, $argv[3]); +} + +foreach($db as $key => $val) { + echo "'$key' => '$val'\n"; +} + ?> \ No newline at end of file diff --git a/ext/spl/examples/dbaarray.inc b/ext/spl/examples/dbaarray.inc index 01d2d38cd..fcd6bb378 100755 --- a/ext/spl/examples/dbaarray.inc +++ b/ext/spl/examples/dbaarray.inc @@ -1,98 +1,98 @@ -db = dba_popen($file, "c", $handler); - if (!$this->db) { - throw new exception("Databse could not be opened"); - } - } - - /** - * Close database. - */ - function __destruct() - { - parent::__destruct(); - } - - /** - * Read an entry. - * - * @param $name key to read from - * @return value associated with $name - */ - function offsetGet($name) - { - $data = dba_fetch($name, $this->db); - if($data) { - if (ini_get('magic_quotes_runtime')) { - $data = stripslashes($data); - } - //return unserialize($data); - return $data; - } - else - { - return NULL; - } - } - - /** - * Set an entry. - * - * @param $name key to write to - * @param $value value to write - */ - function offsetSet($name, $value) - { - //dba_replace($name, serialize($value), $this->db); - dba_replace($name, $value, $this->db); - return $value; - } - - /** - * @return whether key $name exists. - */ - function offsetExists($name) - { - return dba_exists($name, $this->db); - } - - /** - * Delete a key/value pair. - * - * @param $name key to delete. - */ - function offsetUnset($name) - { - return dba_delete($name, $this->db); - } -} - +db = dba_popen($file, "c", $handler); + if (!$this->db) { + throw new exception("Databse could not be opened"); + } + } + + /** + * Close database. + */ + function __destruct() + { + parent::__destruct(); + } + + /** + * Read an entry. + * + * @param $name key to read from + * @return value associated with $name + */ + function offsetGet($name) + { + $data = dba_fetch($name, $this->db); + if($data) { + if (ini_get('magic_quotes_runtime')) { + $data = stripslashes($data); + } + //return unserialize($data); + return $data; + } + else + { + return NULL; + } + } + + /** + * Set an entry. + * + * @param $name key to write to + * @param $value value to write + */ + function offsetSet($name, $value) + { + //dba_replace($name, serialize($value), $this->db); + dba_replace($name, $value, $this->db); + return $value; + } + + /** + * @return whether key $name exists. + */ + function offsetExists($name) + { + return dba_exists($name, $this->db); + } + + /** + * Delete a key/value pair. + * + * @param $name key to delete. + */ + function offsetUnset($name) + { + return dba_delete($name, $this->db); + } +} + ?> \ No newline at end of file diff --git a/ext/spl/examples/dbareader.inc b/ext/spl/examples/dbareader.inc index 858000cca..b09791239 100755 --- a/ext/spl/examples/dbareader.inc +++ b/ext/spl/examples/dbareader.inc @@ -1,96 +1,96 @@ -db = dba_open($file, 'r', $handler)) { - throw new exception('Could not open file ' . $file); - } - } - - /** - * Close database. - */ - function __destruct() { - dba_close($this->db); - } - - /** - * Rewind to first element. - */ - function rewind() { - $this->key = dba_firstkey($this->db); - $this->fetch_data(); - } - - /** - * Move to next element. - * - * @return void - */ - function next() { - $this->key = dba_nextkey($this->db); - $this->fetch_data(); - } - - /** - * Fetches the current data if $key is valid - */ - private function fetch_data() { - if ($this->key !== false) { - $this->val = dba_fetch($this->key, $this->db); - } - } - - /** - * @return Current data. - */ - function current() { - return $this->val; - } - - /** - * @return Whether more elements are available. - */ - function valid() { - if ($this->db && $this->key !== false) { - return true; - } else { - return false; - } - } - - /** - * @return Current key. - */ - function key() { - return $this->key; - } -} - +db = dba_open($file, 'r', $handler)) { + throw new exception('Could not open file ' . $file); + } + } + + /** + * Close database. + */ + function __destruct() { + dba_close($this->db); + } + + /** + * Rewind to first element. + */ + function rewind() { + $this->key = dba_firstkey($this->db); + $this->fetch_data(); + } + + /** + * Move to next element. + * + * @return void + */ + function next() { + $this->key = dba_nextkey($this->db); + $this->fetch_data(); + } + + /** + * Fetches the current data if $key is valid + */ + private function fetch_data() { + if ($this->key !== false) { + $this->val = dba_fetch($this->key, $this->db); + } + } + + /** + * @return Current data. + */ + function current() { + return $this->val; + } + + /** + * @return Whether more elements are available. + */ + function valid() { + if ($this->db && $this->key !== false) { + return true; + } else { + return false; + } + } + + /** + * @return Current key. + */ + function key() { + return $this->key; + } +} + ?> \ No newline at end of file diff --git a/ext/spl/examples/directoryfilterdots.inc b/ext/spl/examples/directoryfilterdots.inc index aa4b6ddd6..37f14b710 100755 --- a/ext/spl/examples/directoryfilterdots.inc +++ b/ext/spl/examples/directoryfilterdots.inc @@ -1,45 +1,45 @@ -getInnerIterator()->isDot(); - } - - /** @return the current entries path name - */ - function key() - { - return $this->getInnerIterator()->getPathname(); - } -} - -?> +getInnerIterator()->isDot(); + } + + /** @return the current entries path name + */ + function key() + { + return $this->getInnerIterator()->getPathname(); + } +} + +?> diff --git a/ext/spl/examples/directorygraphiterator.inc b/ext/spl/examples/directorygraphiterator.inc index 61d6709e1..5808e3b89 100644 --- a/ext/spl/examples/directorygraphiterator.inc +++ b/ext/spl/examples/directorygraphiterator.inc @@ -1,34 +1,34 @@ - \ No newline at end of file diff --git a/ext/spl/examples/directorytree.inc b/ext/spl/examples/directorytree.inc index 4c999eb94..7bd9c2c59 100755 --- a/ext/spl/examples/directorytree.inc +++ b/ext/spl/examples/directorytree.inc @@ -1,27 +1,27 @@ - \ No newline at end of file diff --git a/ext/spl/examples/directorytree.php b/ext/spl/examples/directorytree.php index 687f8437b..dc26d6cc2 100755 --- a/ext/spl/examples/directorytree.php +++ b/ext/spl/examples/directorytree.php @@ -1,37 +1,37 @@ - [\ [\]] - * - * Simply specify the path to tree with parameter \. - */ - -if ($argc < 2) { - echo << - -Displays a graphical directory tree for the given . - - The directory for which to generate the directory tree graph. - - -EOF; - exit(1); -} - -if (!class_exists("DirectoryTreeIterator", false)) require_once("directorytreeiterator.inc"); - -$length = $argc > 3 ? $argv[3] : -1; - -echo $argv[1]."\n"; -foreach(new LimitIterator(new DirectoryTreeIterator($argv[1]), @$argv[2], $length) as $key=>$file) { -//foreach(new DirectoryTreeIterator($argv[1]) as $file) { - echo $file . "\n"; -} - + [\ [\]] + * + * Simply specify the path to tree with parameter \. + */ + +if ($argc < 2) { + echo << + +Displays a graphical directory tree for the given . + + The directory for which to generate the directory tree graph. + + +EOF; + exit(1); +} + +if (!class_exists("DirectoryTreeIterator", false)) require_once("directorytreeiterator.inc"); + +$length = $argc > 3 ? $argv[3] : -1; + +echo $argv[1]."\n"; +foreach(new LimitIterator(new DirectoryTreeIterator($argv[1]), @$argv[2], $length) as $key=>$file) { +//foreach(new DirectoryTreeIterator($argv[1]) as $file) { + echo $file . "\n"; +} + ?> \ No newline at end of file diff --git a/ext/spl/examples/directorytreeiterator.inc b/ext/spl/examples/directorytreeiterator.inc index 4a741c318..8e65d0db1 100644 --- a/ext/spl/examples/directorytreeiterator.inc +++ b/ext/spl/examples/directorytreeiterator.inc @@ -1,54 +1,54 @@ -getDepth(); $l++) { - $tree .= $this->getSubIterator($l)->hasNext() ? '| ' : ' '; - } - return $tree . ($this->getSubIterator($l)->hasNext() ? '|-' : '\-') - . $this->getSubIterator($l)->__toString(); - } - - /** Aggregates the inner iterator - */ - function __call($func, $params) - { - return call_user_func_array(array($this->getSubIterator(), $func), $params); - } -} - +getDepth(); $l++) { + $tree .= $this->getSubIterator($l)->hasNext() ? '| ' : ' '; + } + return $tree . ($this->getSubIterator($l)->hasNext() ? '|-' : '\-') + . $this->getSubIterator($l)->__toString(); + } + + /** Aggregates the inner iterator + */ + function __call($func, $params) + { + return call_user_func_array(array($this->getSubIterator(), $func), $params); + } +} + ?> \ No newline at end of file diff --git a/ext/spl/examples/ini_groups.php b/ext/spl/examples/ini_groups.php index 91ddb49f2..513691109 100755 --- a/ext/spl/examples/ini_groups.php +++ b/ext/spl/examples/ini_groups.php @@ -1,41 +1,41 @@ - [\] - * - * Show all groups in the ini file specified by \. - * The regular expression \ is used to filter the result. - * - * Note: configure with --enable-dba - */ - -if ($argc < 2) { - echo << [] - -Show all groups in the ini file specified by . -The regular expression is used to filter the result. - - -EOF; - exit(1); -} - -if (!class_exists("KeyFilter", false)) require_once("keyfilter.inc"); -if (!class_exists("IniGroups", false)) require_once("inigroups.inc"); - -$it = new IniGroups($argv[1]); -if ($argc>2) { - $it = new KeyFilter($it, $argv[2]); -} - -foreach($it as $group) { - echo "$group\n"; -} - + [\] + * + * Show all groups in the ini file specified by \. + * The regular expression \ is used to filter the result. + * + * Note: configure with --enable-dba + */ + +if ($argc < 2) { + echo << [] + +Show all groups in the ini file specified by . +The regular expression is used to filter the result. + + +EOF; + exit(1); +} + +if (!class_exists("KeyFilter", false)) require_once("keyfilter.inc"); +if (!class_exists("IniGroups", false)) require_once("inigroups.inc"); + +$it = new IniGroups($argv[1]); +if ($argc>2) { + $it = new KeyFilter($it, $argv[2]); +} + +foreach($it as $group) { + echo "$group\n"; +} + ?> \ No newline at end of file diff --git a/ext/spl/examples/keyfilter.inc b/ext/spl/examples/keyfilter.inc index a309f098e..eaf6b7736 100755 --- a/ext/spl/examples/keyfilter.inc +++ b/ext/spl/examples/keyfilter.inc @@ -1,64 +1,64 @@ -regex = $regex; - } - - /** \return whether the current key mathes the regular expression - */ - function accept() - { - return ereg($this->regex, $this->getInnerIterator()->key()); - } - - /** @return regular expression used as filter - */ - function getRegex() - { - return $this->regex; - } - - /** - * hidden __clone - */ - protected function __clone() - { - // disallow clone - } -} - +regex = $regex; + } + + /** \return whether the current key mathes the regular expression + */ + function accept() + { + return ereg($this->regex, $this->getInnerIterator()->key()); + } + + /** @return regular expression used as filter + */ + function getRegex() + { + return $this->regex; + } + + /** + * hidden __clone + */ + protected function __clone() + { + // disallow clone + } +} + ?> \ No newline at end of file diff --git a/ext/spl/examples/nocvsdir.php b/ext/spl/examples/nocvsdir.php index e14ad74f4..699326894 100755 --- a/ext/spl/examples/nocvsdir.php +++ b/ext/spl/examples/nocvsdir.php @@ -1,55 +1,55 @@ - - * - * Simply specify the path to tree with parameter \. - */ - -if ($argc < 2) { - echo << - -Show the directory and all it's contents without any CVS directory in . - - The directory for which to generate the directory. - - -EOF; - exit(1); -} - -if (!class_exists("RecursiveFilterIterator")) require_once("recursivefilteriterator.inc"); - -class NoCvsDirectory extends RecursiveFilterIterator -{ - function __construct($path) - { - parent::__construct(new RecursiveDirectoryIterator($path)); - } - - function accept() - { - return $this->getInnerIterator()->getFilename() != 'CVS'; - } - - function getChildren() - { - return new NoCvsDirectory($this->key()); - } -} - -$it = new RecursiveIteratorIterator(new NoCvsDirectory($argv[1])); - -foreach($it as $pathname => $file) -{ - echo $pathname."\n"; -} - + + * + * Simply specify the path to tree with parameter \. + */ + +if ($argc < 2) { + echo << + +Show the directory and all it's contents without any CVS directory in . + + The directory for which to generate the directory. + + +EOF; + exit(1); +} + +if (!class_exists("RecursiveFilterIterator")) require_once("recursivefilteriterator.inc"); + +class NoCvsDirectory extends RecursiveFilterIterator +{ + function __construct($path) + { + parent::__construct(new RecursiveDirectoryIterator($path)); + } + + function accept() + { + return $this->getInnerIterator()->getFilename() != 'CVS'; + } + + function getChildren() + { + return new NoCvsDirectory($this->key()); + } +} + +$it = new RecursiveIteratorIterator(new NoCvsDirectory($argv[1])); + +foreach($it as $pathname => $file) +{ + echo $pathname."\n"; +} + ?> \ No newline at end of file diff --git a/ext/spl/examples/searchiterator.inc b/ext/spl/examples/searchiterator.inc index 0e6a7bcc4..944a4ac5a 100755 --- a/ext/spl/examples/searchiterator.inc +++ b/ext/spl/examples/searchiterator.inc @@ -1,58 +1,58 @@ -done = false; - } - - /** @return whether the current element is valid - * which can only happen once per iteration. - */ - function valid() - { - return !$this->done && parent::valid(); - } - - /** Do not move forward but instead mark as finished. - * @return void - */ - function next() - { - $this->done = true; - } - - /** Aggregates the inner iterator - */ - function __call($func, $params) - { - return call_user_func_array(array($this->getInnerIterator(), $func), $params); - } -} - +done = false; + } + + /** @return whether the current element is valid + * which can only happen once per iteration. + */ + function valid() + { + return !$this->done && parent::valid(); + } + + /** Do not move forward but instead mark as finished. + * @return void + */ + function next() + { + $this->done = true; + } + + /** Aggregates the inner iterator + */ + function __call($func, $params) + { + return call_user_func_array(array($this->getInnerIterator(), $func), $params); + } +} + ?> \ No newline at end of file diff --git a/ext/spl/examples/tree.php b/ext/spl/examples/tree.php index 7c630e823..9c2cc5586 100755 --- a/ext/spl/examples/tree.php +++ b/ext/spl/examples/tree.php @@ -1,40 +1,40 @@ - - * - * Simply specify the path to tree with parameter \. - */ - -// The following line only operates on classes which are converted to c already. -// But does not generate a graphical output. -//foreach(new RecursiveIteratorIterator(new ParentIterator(new RecursiveDirectoryIterator($argv[1])), 1) as $file) { - -if ($argc < 2) { - echo << - -Displays a graphical tree for the given . - - The directory for which to generate the tree graph. - - -EOF; - exit(1); -} - -if (!class_exists("DirectoryTreeIterator", false)) require_once("directorytreeiterator.inc"); -if (!class_exists("DirectoryGraphIterator", false)) require_once("directorygraphiterator.inc"); - -echo $argv[1]."\n"; -foreach(new DirectoryGraphIterator($argv[1]) as $file) -{ - echo $file . "\n"; -} - -?> + + * + * Simply specify the path to tree with parameter \. + */ + +// The following line only operates on classes which are converted to c already. +// But does not generate a graphical output. +//foreach(new RecursiveIteratorIterator(new ParentIterator(new RecursiveDirectoryIterator($argv[1])), 1) as $file) { + +if ($argc < 2) { + echo << + +Displays a graphical tree for the given . + + The directory for which to generate the tree graph. + + +EOF; + exit(1); +} + +if (!class_exists("DirectoryTreeIterator", false)) require_once("directorytreeiterator.inc"); +if (!class_exists("DirectoryGraphIterator", false)) require_once("directorygraphiterator.inc"); + +echo $argv[1]."\n"; +foreach(new DirectoryGraphIterator($argv[1]) as $file) +{ + echo $file . "\n"; +} + +?> diff --git a/ext/spl/php_spl.c b/ext/spl/php_spl.c index 49d3f5519..1945f982e 100755 --- a/ext/spl/php_spl.c +++ b/ext/spl/php_spl.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_spl.c,v 1.52.2.28.2.17.2.38 2009/06/13 17:30:50 cellog Exp $ */ +/* $Id: php_spl.c 283179 2009-06-30 17:14:37Z cseiler $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -509,10 +509,10 @@ PHP_FUNCTION(spl_autoload_register) alfi.closure = zcallable; Z_ADDREF_P(zcallable); - lc_name = erealloc(lc_name, func_name_len + 2 + sizeof(zcallable->value.obj.handle)); - memcpy(lc_name + func_name_len, &(zcallable->value.obj.handle), - sizeof(zcallable->value.obj.handle)); - func_name_len += sizeof(zcallable->value.obj.handle); + lc_name = erealloc(lc_name, func_name_len + 2 + sizeof(zend_object_handle)); + memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_P(zcallable), + sizeof(zend_object_handle)); + func_name_len += sizeof(zend_object_handle); lc_name[func_name_len] = '\0'; } @@ -579,6 +579,7 @@ PHP_FUNCTION(spl_autoload_unregister) { char *func_name, *error = NULL; int func_name_len; + char *lc_name = NULL; zval *zcallable; int success = FAILURE; zend_function *spl_func_ptr; @@ -604,10 +605,20 @@ PHP_FUNCTION(spl_autoload_unregister) efree(error); } - zend_str_tolower(func_name, func_name_len); + lc_name = safe_emalloc(func_name_len, 1, sizeof(long) + 1); + zend_str_tolower_copy(lc_name, func_name, func_name_len); + efree(func_name); + + if (Z_TYPE_P(zcallable) == IS_OBJECT) { + lc_name = erealloc(lc_name, func_name_len + 2 + sizeof(zend_object_handle)); + memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_P(zcallable), + sizeof(zend_object_handle)); + func_name_len += sizeof(zend_object_handle); + lc_name[func_name_len] = '\0'; + } if (SPL_G(autoload_functions)) { - if (func_name_len == sizeof("spl_autoload_call")-1 && !strcmp(func_name, "spl_autoload_call")) { + if (func_name_len == sizeof("spl_autoload_call")-1 && !strcmp(lc_name, "spl_autoload_call")) { /* remove all */ zend_hash_destroy(SPL_G(autoload_functions)); FREE_HASHTABLE(SPL_G(autoload_functions)); @@ -616,16 +627,16 @@ PHP_FUNCTION(spl_autoload_unregister) success = SUCCESS; } else { /* remove specific */ - success = zend_hash_del(SPL_G(autoload_functions), func_name, func_name_len+1); + success = zend_hash_del(SPL_G(autoload_functions), lc_name, func_name_len+1); if (success != SUCCESS && obj_ptr) { - func_name = erealloc(func_name, func_name_len + 1 + sizeof(zend_object_handle)); - memcpy(func_name + func_name_len, &Z_OBJ_HANDLE_P(obj_ptr), sizeof(zend_object_handle)); + lc_name = erealloc(lc_name, func_name_len + 2 + sizeof(zend_object_handle)); + memcpy(lc_name + func_name_len, &Z_OBJ_HANDLE_P(obj_ptr), sizeof(zend_object_handle)); func_name_len += sizeof(zend_object_handle); - func_name[func_name_len] = '\0'; - success = zend_hash_del(SPL_G(autoload_functions), func_name, func_name_len+1); + lc_name[func_name_len] = '\0'; + success = zend_hash_del(SPL_G(autoload_functions), lc_name, func_name_len+1); } } - } else if (func_name_len == sizeof("spl_autoload")-1 && !strcmp(func_name, "spl_autoload")) { + } else if (func_name_len == sizeof("spl_autoload")-1 && !strcmp(lc_name, "spl_autoload")) { /* register single spl_autoload() */ zend_hash_find(EG(function_table), "spl_autoload", sizeof("spl_autoload"), (void **) &spl_func_ptr); @@ -635,7 +646,7 @@ PHP_FUNCTION(spl_autoload_unregister) } } - efree(func_name); + efree(lc_name); RETURN_BOOL(success == SUCCESS); } /* }}} */ @@ -663,7 +674,10 @@ PHP_FUNCTION(spl_autoload_functions) zend_hash_internal_pointer_reset_ex(SPL_G(autoload_functions), &function_pos); while(zend_hash_has_more_elements_ex(SPL_G(autoload_functions), &function_pos) == SUCCESS) { zend_hash_get_current_data_ex(SPL_G(autoload_functions), (void **) &alfi, &function_pos); - if (alfi->func_ptr->common.scope) { + if (alfi->closure) { + Z_ADDREF_P(alfi->closure); + add_next_index_zval(return_value, alfi->closure); + } else if (alfi->func_ptr->common.scope) { zval *tmp; MAKE_STD_ZVAL(tmp); array_init(tmp); diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c index 16d213129..2a2e2f355 100755 --- a/ext/spl/spl_array.c +++ b/ext/spl/spl_array.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_array.c,v 1.71.2.17.2.13.2.40 2009/05/21 13:26:14 lbarnaud Exp $ */ +/* $Id: spl_array.c 287266 2009-08-13 22:07:05Z colder $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -76,6 +76,7 @@ typedef struct _spl_array_object { zend_class_entry *ce_get_iterator; php_serialize_data_t *serialize_data; php_unserialize_data_t *unserialize_data; + HashTable *debug_info; } spl_array_object; static inline HashTable *spl_array_get_hash_table(spl_array_object* intern, int check_std_props TSRMLS_DC) { /* {{{ */ @@ -144,6 +145,11 @@ static void spl_array_object_free_storage(void *object TSRMLS_DC) zval_ptr_dtor(&intern->array); zval_ptr_dtor(&intern->retval); + if (intern->debug_info != NULL) { + zend_hash_destroy(intern->debug_info); + efree(intern->debug_info); + } + efree(object); } /* }}} */ @@ -172,6 +178,7 @@ static zend_object_value spl_array_object_new_ex(zend_class_entry *class_type, s intern->ar_flags = 0; intern->serialize_data = NULL; intern->unserialize_data = NULL; + intern->debug_info = NULL; intern->ce_get_iterator = spl_ce_ArrayIterator; if (orig) { spl_array_object *other = (spl_array_object*)zend_object_store_get_object(orig TSRMLS_CC); @@ -677,32 +684,34 @@ static HashTable *spl_array_get_properties(zval *object TSRMLS_DC) /* {{{ */ static HashTable* spl_array_get_debug_info(zval *obj, int *is_temp TSRMLS_DC) /* {{{ */ { spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(obj TSRMLS_CC); - HashTable *rv; zval *tmp, *storage; int name_len; char *zname; zend_class_entry *base; + *is_temp = 0; + if (HASH_OF(intern->array) == intern->std.properties) { - *is_temp = 0; return intern->std.properties; } else { - *is_temp = 1; - - ALLOC_HASHTABLE(rv); - ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 1, 0); + if (intern->debug_info == NULL) { + ALLOC_HASHTABLE(intern->debug_info); + ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0); + } - zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + if (intern->debug_info->nApplyCount == 0) { + zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - storage = intern->array; - zval_add_ref(&storage); + storage = intern->array; + zval_add_ref(&storage); - base = (Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator) ? spl_ce_ArrayIterator : spl_ce_ArrayObject; - zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); - zend_symtable_update(rv, zname, name_len+1, &storage, sizeof(zval *), NULL); - efree(zname); + base = (Z_OBJ_HT_P(obj) == &spl_handler_ArrayIterator) ? spl_ce_ArrayIterator : spl_ce_ArrayObject; + zname = spl_gen_private_prop_name(base, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); + zend_symtable_update(intern->debug_info, zname, name_len+1, &storage, sizeof(zval *), NULL); + efree(zname); + } - return rv; + return intern->debug_info; } } /* }}} */ @@ -1789,6 +1798,9 @@ ZEND_BEGIN_ARG_INFO(arginfo_array_unserialize, 0) ZEND_ARG_INFO(0, serialized) ZEND_END_ARG_INFO(); +ZEND_BEGIN_ARG_INFO(arginfo_array_void, 0) +ZEND_END_ARG_INFO() + static const zend_function_entry spl_funcs_ArrayObject[] = { SPL_ME(Array, __construct, arginfo_array___construct, ZEND_ACC_PUBLIC) SPL_ME(Array, offsetExists, arginfo_array_offsetGet, ZEND_ACC_PUBLIC) @@ -1796,23 +1808,23 @@ static const zend_function_entry spl_funcs_ArrayObject[] = { SPL_ME(Array, offsetSet, arginfo_array_offsetSet, ZEND_ACC_PUBLIC) SPL_ME(Array, offsetUnset, arginfo_array_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(Array, append, arginfo_array_append, ZEND_ACC_PUBLIC) - SPL_ME(Array, getArrayCopy, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, count, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, getFlags, NULL, ZEND_ACC_PUBLIC) + SPL_ME(Array, getArrayCopy, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, count, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, getFlags, arginfo_array_void, ZEND_ACC_PUBLIC) SPL_ME(Array, setFlags, arginfo_array_setFlags, ZEND_ACC_PUBLIC) - SPL_ME(Array, asort, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, ksort, NULL, ZEND_ACC_PUBLIC) + SPL_ME(Array, asort, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, ksort, arginfo_array_void, ZEND_ACC_PUBLIC) SPL_ME(Array, uasort, arginfo_array_uXsort, ZEND_ACC_PUBLIC) SPL_ME(Array, uksort, arginfo_array_uXsort, ZEND_ACC_PUBLIC) - SPL_ME(Array, natsort, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, natcasesort, NULL, ZEND_ACC_PUBLIC) + SPL_ME(Array, natsort, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, natcasesort, arginfo_array_void, ZEND_ACC_PUBLIC) SPL_ME(Array, unserialize, arginfo_array_unserialize, ZEND_ACC_PUBLIC) - SPL_ME(Array, serialize, NULL, ZEND_ACC_PUBLIC) + SPL_ME(Array, serialize, arginfo_array_void, ZEND_ACC_PUBLIC) /* ArrayObject specific */ - SPL_ME(Array, getIterator, NULL, ZEND_ACC_PUBLIC) + SPL_ME(Array, getIterator, arginfo_array_void, ZEND_ACC_PUBLIC) SPL_ME(Array, exchangeArray, arginfo_array_exchangeArray, ZEND_ACC_PUBLIC) SPL_ME(Array, setIteratorClass, arginfo_array_setIteratorClass, ZEND_ACC_PUBLIC) - SPL_ME(Array, getIteratorClass, NULL, ZEND_ACC_PUBLIC) + SPL_ME(Array, getIteratorClass, arginfo_array_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -1823,31 +1835,31 @@ static const zend_function_entry spl_funcs_ArrayIterator[] = { SPL_ME(Array, offsetSet, arginfo_array_offsetSet, ZEND_ACC_PUBLIC) SPL_ME(Array, offsetUnset, arginfo_array_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(Array, append, arginfo_array_append, ZEND_ACC_PUBLIC) - SPL_ME(Array, getArrayCopy, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, count, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, getFlags, NULL, ZEND_ACC_PUBLIC) + SPL_ME(Array, getArrayCopy, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, count, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, getFlags, arginfo_array_void, ZEND_ACC_PUBLIC) SPL_ME(Array, setFlags, arginfo_array_setFlags, ZEND_ACC_PUBLIC) - SPL_ME(Array, asort, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, ksort, NULL, ZEND_ACC_PUBLIC) + SPL_ME(Array, asort, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, ksort, arginfo_array_void, ZEND_ACC_PUBLIC) SPL_ME(Array, uasort, arginfo_array_uXsort, ZEND_ACC_PUBLIC) SPL_ME(Array, uksort, arginfo_array_uXsort, ZEND_ACC_PUBLIC) - SPL_ME(Array, natsort, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, natcasesort, NULL, ZEND_ACC_PUBLIC) + SPL_ME(Array, natsort, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, natcasesort, arginfo_array_void, ZEND_ACC_PUBLIC) SPL_ME(Array, unserialize, arginfo_array_unserialize, ZEND_ACC_PUBLIC) - SPL_ME(Array, serialize, NULL, ZEND_ACC_PUBLIC) + SPL_ME(Array, serialize, arginfo_array_void, ZEND_ACC_PUBLIC) /* ArrayIterator specific */ - SPL_ME(Array, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, valid, NULL, ZEND_ACC_PUBLIC) + SPL_ME(Array, rewind, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, current, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, key, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, next, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, valid, arginfo_array_void, ZEND_ACC_PUBLIC) SPL_ME(Array, seek, arginfo_array_seek, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; static const zend_function_entry spl_funcs_RecursiveArrayIterator[] = { - SPL_ME(Array, hasChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(Array, getChildren, NULL, ZEND_ACC_PUBLIC) + SPL_ME(Array, hasChildren, arginfo_array_void, ZEND_ACC_PUBLIC) + SPL_ME(Array, getChildren, arginfo_array_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; /* }}} */ diff --git a/ext/spl/spl_array.h b/ext/spl/spl_array.h index a98dc803c..9590ca6ed 100755 --- a/ext/spl/spl_array.h +++ b/ext/spl/spl_array.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_array.h,v 1.13.2.2.2.4.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: spl_array.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SPL_ARRAY_H #define SPL_ARRAY_H diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index a1728fb0c..860c6728b 100755 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_directory.c,v 1.45.2.27.2.23.2.44 2009/06/24 08:53:18 dmitry Exp $ */ +/* $Id: spl_directory.c 284648 2009-07-23 14:42:46Z jani $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -1246,7 +1246,7 @@ SPL_METHOD(RecursiveDirectoryIterator, hasChildren) return; } spl_filesystem_object_get_file_name(intern TSRMLS_CC); - if (!allow_links) { + if (!allow_links && !(intern->flags & SPL_FILE_DIR_FOLLOW_SYMLINKS)) { php_stat(intern->file_name, intern->file_name_len, FS_IS_LINK, return_value TSRMLS_CC); if (zend_is_true(return_value)) { RETURN_FALSE; @@ -1657,39 +1657,42 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_optinalSuffix, 0, 0, 0) ZEND_ARG_INFO(0, suffix) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_splfileinfo_void, 0) +ZEND_END_ARG_INFO() + /* the method table */ /* each method can have its own parameters and visibility */ static const zend_function_entry spl_SplFileInfo_functions[] = { SPL_ME(SplFileInfo, __construct, arginfo_info___construct, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getPath, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getFilename, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getPath, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getFilename, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, getBasename, arginfo_optinalSuffix, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getPathname, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getPerms, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getInode, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getSize, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getOwner, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getGroup, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getATime, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getMTime, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getCTime, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getType, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, isWritable, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, isReadable, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, isExecutable, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, isFile, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, isDir, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, isLink, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileInfo, getLinkTarget, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getPathname, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getPerms, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getInode, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getSize, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getOwner, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getGroup, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getATime, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getMTime, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getCTime, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getType, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, isWritable, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, isReadable, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, isExecutable, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, isFile, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, isDir, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, isLink, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getLinkTarget, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) #if (!defined(__BEOS__) && !defined(NETWARE) && HAVE_REALPATH) || defined(ZTS) - SPL_ME(SplFileInfo, getRealPath, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, getRealPath, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) #endif SPL_ME(SplFileInfo, getFileInfo, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, getPathInfo, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, openFile, arginfo_info_openFile, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, setFileClass, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, setInfoClass, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC) - SPL_MA(SplFileInfo, __toString, SplFileInfo, getPathname, NULL, ZEND_ACC_PUBLIC) + SPL_MA(SplFileInfo, __toString, SplFileInfo, getPathname, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -1705,16 +1708,16 @@ ZEND_END_ARG_INFO(); /* each method can have its own parameters and visibility */ static const zend_function_entry spl_DirectoryIterator_functions[] = { SPL_ME(DirectoryIterator, __construct, arginfo_dir___construct, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, getFilename, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, getFilename, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) SPL_ME(DirectoryIterator, getBasename, arginfo_optinalSuffix, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, isDot, NULL, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, next, NULL, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, isDot, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, rewind, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, valid, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, key, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, current, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, next, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) SPL_ME(DirectoryIterator, seek, arginfo_dir_it_seek, ZEND_ACC_PUBLIC) - SPL_MA(DirectoryIterator, __toString, DirectoryIterator, getFilename, NULL, ZEND_ACC_PUBLIC) + SPL_MA(DirectoryIterator, __toString, DirectoryIterator, getFilename, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -1733,11 +1736,11 @@ ZEND_END_ARG_INFO() static const zend_function_entry spl_FilesystemIterator_functions[] = { SPL_ME(FilesystemIterator, __construct, arginfo_r_dir___construct, ZEND_ACC_PUBLIC) - SPL_ME(FilesystemIterator, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(DirectoryIterator, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(FilesystemIterator, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(FilesystemIterator, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(FilesystemIterator, getFlags, NULL, ZEND_ACC_PUBLIC) + SPL_ME(FilesystemIterator, rewind, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(DirectoryIterator, next, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(FilesystemIterator, key, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(FilesystemIterator, current, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(FilesystemIterator, getFlags, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) SPL_ME(FilesystemIterator, setFlags, arginfo_r_dir_setFlags, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -1745,15 +1748,15 @@ static const zend_function_entry spl_FilesystemIterator_functions[] = { static const zend_function_entry spl_RecursiveDirectoryIterator_functions[] = { SPL_ME(RecursiveDirectoryIterator, __construct, arginfo_r_dir___construct, ZEND_ACC_PUBLIC) SPL_ME(RecursiveDirectoryIterator, hasChildren, arginfo_r_dir_hasChildren, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveDirectoryIterator, getChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveDirectoryIterator, getSubPath, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveDirectoryIterator, getSubPathname,NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveDirectoryIterator, getChildren, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveDirectoryIterator, getSubPath, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveDirectoryIterator, getSubPathname,arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; static const zend_function_entry spl_GlobIterator_functions[] = { SPL_ME(GlobIterator, __construct, arginfo_r_dir___construct, ZEND_ACC_PUBLIC) - SPL_ME(GlobIterator, count, NULL, ZEND_ACC_PUBLIC) + SPL_ME(GlobIterator, count, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; /* }}} */ @@ -2564,8 +2567,9 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fgetss, 0, 0, 0) ZEND_ARG_INFO(0, allowable_tags) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fscanf, 0, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fscanf, 1, 0, 1) ZEND_ARG_INFO(0, format) + ZEND_ARG_INFO(1, ...) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_file_object_fwrite, 0, 0, 1) @@ -2583,37 +2587,37 @@ ZEND_END_ARG_INFO() static const zend_function_entry spl_SplFileObject_functions[] = { SPL_ME(SplFileObject, __construct, arginfo_file_object___construct, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, eof, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, fgets, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, rewind, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, eof, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, valid, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, fgets, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, fgetcsv, arginfo_file_object_fgetcsv, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, setCsvControl, arginfo_file_object_fgetcsv, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, getCsvControl, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, getCsvControl, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, flock, arginfo_file_object_flock, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, fflush, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, ftell, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, fflush, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, ftell, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, fseek, arginfo_file_object_fseek, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, fgetc, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, fpassthru, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, fgetc, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, fpassthru, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, fgetss, arginfo_file_object_fgetss, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, fscanf, arginfo_file_object_fscanf, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, fwrite, arginfo_file_object_fwrite, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, fstat, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, fstat, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, ftruncate, arginfo_file_object_ftruncate, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, next, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, current, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, key, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, next, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, setFlags, arginfo_file_object_setFlags, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, getFlags, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, getFlags, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, setMaxLineLen, arginfo_file_object_setMaxLineLen, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, getMaxLineLen, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, hasChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFileObject, getChildren, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, getMaxLineLen, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, hasChildren, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileObject, getChildren, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) SPL_ME(SplFileObject, seek, arginfo_file_object_seek, ZEND_ACC_PUBLIC) /* mappings */ - SPL_MA(SplFileObject, getCurrentLine, SplFileObject, fgets, NULL, ZEND_ACC_PUBLIC) - SPL_MA(SplFileObject, __toString, SplFileObject, current, NULL, ZEND_ACC_PUBLIC) + SPL_MA(SplFileObject, getCurrentLine, SplFileObject, fgets, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_MA(SplFileObject, __toString, SplFileObject, current, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2653,6 +2657,7 @@ PHP_MINIT_FUNCTION(spl_directory) REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "CURRENT_AS_SELF", SPL_FILE_DIR_CURRENT_AS_SELF); REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "KEY_MODE_MASK", SPL_FILE_DIR_KEY_MODE_MASK); REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "KEY_AS_PATHNAME", SPL_FILE_DIR_KEY_AS_PATHNAME); + REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "FOLLOW_SYMLINKS", SPL_FILE_DIR_FOLLOW_SYMLINKS); REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "KEY_AS_FILENAME", SPL_FILE_DIR_KEY_AS_FILENAME); REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "NEW_CURRENT_AND_KEY", SPL_FILE_DIR_KEY_AS_FILENAME|SPL_FILE_DIR_CURRENT_AS_FILEINFO); REGISTER_SPL_CLASS_CONST_LONG(FilesystemIterator, "SKIP_DOTS", SPL_FILE_DIR_SKIPDOTS); diff --git a/ext/spl/spl_directory.h b/ext/spl/spl_directory.h index 9659fb545..549cff657 100755 --- a/ext/spl/spl_directory.h +++ b/ext/spl/spl_directory.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_directory.h,v 1.12.2.5.2.4.2.14 2009/06/04 14:46:26 colder Exp $ */ +/* $Id: spl_directory.h 283689 2009-07-08 03:06:59Z iliaa $ */ #ifndef SPL_DIRECTORY_H #define SPL_DIRECTORY_H @@ -129,6 +129,7 @@ static inline spl_filesystem_object* spl_filesystem_iterator_to_object(spl_files #define SPL_FILE_DIR_KEY_AS_PATHNAME 0x00000000 /* make RecursiveDirectoryTree::key() return getPathname() */ #define SPL_FILE_DIR_KEY_AS_FILENAME 0x00000100 /* make RecursiveDirectoryTree::key() return getFilename() */ +#define SPL_FILE_DIR_FOLLOW_SYMLINKS 0x00000200 /* make RecursiveDirectoryTree::hasChildren() follow symlinks */ #define SPL_FILE_DIR_KEY_MODE_MASK 0x00000F00 /* mask RecursiveDirectoryTree::key() */ #define SPL_FILE_DIR_KEY(intern,mode) ((intern->flags&SPL_FILE_DIR_KEY_MODE_MASK)==mode) diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c index 9d6a9a8ff..2caf9cce4 100644 --- a/ext/spl/spl_dllist.c +++ b/ext/spl/spl_dllist.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_dllist.c,v 1.1.2.19 2009/06/17 13:27:09 scottmac Exp $ */ +/* $Id: spl_dllist.c 287266 2009-08-13 22:07:05Z colder $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -94,6 +94,7 @@ struct _spl_dllist_object { zend_function *fptr_offset_del; zend_function *fptr_count; zend_class_entry *ce_get_iterator; + HashTable *debug_info; }; /* define an overloaded iterator structure */ @@ -351,6 +352,11 @@ static void spl_dllist_object_free_storage(void *object TSRMLS_DC) /* {{{ */ SPL_LLIST_CHECK_DELREF(intern->traverse_pointer); zval_ptr_dtor(&intern->retval); + if (intern->debug_info != NULL) { + zend_hash_destroy(intern->debug_info); + efree(intern->debug_info); + } + efree(object); } /* }}} */ @@ -374,6 +380,7 @@ static zend_object_value spl_dllist_object_new_ex(zend_class_entry *class_type, intern->flags = 0; intern->traverse_position = 0; + intern->debug_info = NULL; if (orig) { spl_dllist_object *other = (spl_dllist_object*)zend_object_store_get_object(orig TSRMLS_CC); @@ -383,6 +390,7 @@ static zend_object_value spl_dllist_object_new_ex(zend_class_entry *class_type, intern->llist = (spl_ptr_llist *)spl_ptr_llist_init(other->llist->ctor, other->llist->dtor); spl_ptr_llist_copy(other->llist, intern->llist TSRMLS_CC); intern->traverse_pointer = intern->llist->head; + SPL_LLIST_CHECK_ADDREF(intern->traverse_pointer); } else { intern->llist = other->llist; intern->traverse_pointer = intern->llist->head; @@ -499,44 +507,47 @@ static HashTable* spl_dllist_object_get_debug_info(zval *obj, int *is_temp TSRML { spl_dllist_object *intern = (spl_dllist_object*)zend_object_store_get_object(obj TSRMLS_CC); spl_ptr_llist_element *current = intern->llist->head, *next; - HashTable *rv; zval *tmp, zrv, *dllist_array; char *pnstr; int pnlen; - int i = 0;; + int i = 0; - *is_temp = 1; + *is_temp = 0; - ALLOC_HASHTABLE(rv); - ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 1, 0); + if (intern->debug_info == NULL) { + ALLOC_HASHTABLE(intern->debug_info); + zend_hash_init(intern->debug_info, 1, NULL, ZVAL_PTR_DTOR, 0); + } - INIT_PZVAL(&zrv); - Z_ARRVAL(zrv) = rv; + if (intern->debug_info->nApplyCount == 0) { + INIT_PZVAL(&zrv); + Z_ARRVAL(zrv) = intern->debug_info; - zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); - add_assoc_long_ex(&zrv, pnstr, pnlen+1, intern->flags); - efree(pnstr); + pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); + add_assoc_long_ex(&zrv, pnstr, pnlen+1, intern->flags); + efree(pnstr); - ALLOC_INIT_ZVAL(dllist_array); - array_init(dllist_array); + ALLOC_INIT_ZVAL(dllist_array); + array_init(dllist_array); - while (current) { - next = current->next; + while (current) { + next = current->next; - add_index_zval(dllist_array, i, (zval *)current->data); - Z_ADDREF_P(current->data); - i++; + add_index_zval(dllist_array, i, (zval *)current->data); + Z_ADDREF_P(current->data); + i++; - current = next; - } + current = next; + } - pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "dllist", sizeof("dllist")-1, &pnlen TSRMLS_CC); - add_assoc_zval_ex(&zrv, pnstr, pnlen+1, dllist_array); - efree(pnstr); + pnstr = spl_gen_private_prop_name(spl_ce_SplDoublyLinkedList, "dllist", sizeof("dllist")-1, &pnlen TSRMLS_CC); + add_assoc_zval_ex(&zrv, pnstr, pnlen+1, dllist_array); + efree(pnstr); + } - return rv; + return intern->debug_info; } /* }}}} */ @@ -1150,33 +1161,36 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dllist_offsetSet, 0, 0, 2) ZEND_ARG_INFO(0, newval) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_dllist_void, 0) +ZEND_END_ARG_INFO() + static const zend_function_entry spl_funcs_SplQueue[] = { SPL_MA(SplQueue, enqueue, SplDoublyLinkedList, push, arginfo_dllist_push, ZEND_ACC_PUBLIC) - SPL_MA(SplQueue, dequeue, SplDoublyLinkedList, shift, NULL, ZEND_ACC_PUBLIC) + SPL_MA(SplQueue, dequeue, SplDoublyLinkedList, shift, arginfo_dllist_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; static const zend_function_entry spl_funcs_SplDoublyLinkedList[] = { - SPL_ME(SplDoublyLinkedList, pop, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, shift, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, pop, arginfo_dllist_void, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, shift, arginfo_dllist_void, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, push, arginfo_dllist_push, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, unshift, arginfo_dllist_push, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, top, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, bottom, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, count, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, isEmpty, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, top, arginfo_dllist_void, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, bottom, arginfo_dllist_void, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, count, arginfo_dllist_void, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, isEmpty, arginfo_dllist_void, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, setIteratorMode, arginfo_dllist_setiteratormode, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, getIteratorMode, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, getIteratorMode, arginfo_dllist_void, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, offsetExists, arginfo_dllist_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, offsetGet, arginfo_dllist_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, offsetSet, arginfo_dllist_offsetSet, ZEND_ACC_PUBLIC) SPL_ME(SplDoublyLinkedList, offsetUnset, arginfo_dllist_offsetGet, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, prev, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplDoublyLinkedList, valid, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, rewind, arginfo_dllist_void, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, current, arginfo_dllist_void, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, key, arginfo_dllist_void, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, next, arginfo_dllist_void, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, prev, arginfo_dllist_void, ZEND_ACC_PUBLIC) + SPL_ME(SplDoublyLinkedList, valid, arginfo_dllist_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; /* }}} */ diff --git a/ext/spl/spl_dllist.h b/ext/spl/spl_dllist.h index 5b0998b69..e5b6cb798 100644 --- a/ext/spl/spl_dllist.h +++ b/ext/spl/spl_dllist.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_dllist.h,v 1.1.2.4 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: spl_dllist.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SPL_DLLIST_H #define SPL_DLLIST_H diff --git a/ext/spl/spl_engine.h b/ext/spl/spl_engine.h index 139a8a2df..bb62cb363 100755 --- a/ext/spl/spl_engine.h +++ b/ext/spl/spl_engine.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_engine.h,v 1.19.2.3.2.1.2.4 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: spl_engine.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SPL_ENGINE_H #define SPL_ENGINE_H diff --git a/ext/spl/spl_exceptions.c b/ext/spl/spl_exceptions.c index 9a224e78e..3a0904dff 100755 --- a/ext/spl/spl_exceptions.c +++ b/ext/spl/spl_exceptions.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_exceptions.c,v 1.6.2.1.2.2.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: spl_exceptions.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H # include "config.h" diff --git a/ext/spl/spl_exceptions.h b/ext/spl/spl_exceptions.h index 33d96290d..1eabcdf46 100755 --- a/ext/spl/spl_exceptions.h +++ b/ext/spl/spl_exceptions.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_exceptions.h,v 1.5.2.1.2.1.2.2 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: spl_exceptions.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SPL_EXCEPTIONS_H #define SPL_EXCEPTIONS_H diff --git a/ext/spl/spl_fixedarray.c b/ext/spl/spl_fixedarray.c index 5576fd397..5c192c811 100644 --- a/ext/spl/spl_fixedarray.c +++ b/ext/spl/spl_fixedarray.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_fixedarray.c,v 1.1.2.11 2009/05/23 15:14:15 felipe Exp $ */ +/* $Id: spl_fixedarray.c 283486 2009-07-04 20:31:27Z felipe $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -1021,6 +1021,10 @@ zend_object_iterator *spl_fixedarray_get_iterator(zend_class_entry *ce, zval *ob } /* }}} */ +ZEND_BEGIN_ARG_INFO_EX(arginfo_splfixedarray_construct, 0, 0, 0) + ZEND_ARG_INFO(0, size) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_fixedarray_offsetGet, 0, 0, 1) ZEND_ARG_INFO(0, index) ZEND_END_ARG_INFO() @@ -1039,22 +1043,25 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_fixedarray_fromArray, 0, 0, 1) ZEND_ARG_INFO(0, save_indexes) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_splfixedarray_void, 0) +ZEND_END_ARG_INFO() + static zend_function_entry spl_funcs_SplFixedArray[] = { /* {{{ */ - SPL_ME(SplFixedArray, __construct, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFixedArray, count, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFixedArray, toArray, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFixedArray, __construct, arginfo_splfixedarray_construct,ZEND_ACC_PUBLIC) + SPL_ME(SplFixedArray, count, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFixedArray, toArray, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) SPL_ME(SplFixedArray, fromArray, arginfo_fixedarray_fromArray, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) - SPL_ME(SplFixedArray, getSize, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFixedArray, getSize, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) SPL_ME(SplFixedArray, setSize, arginfo_fixedarray_setSize, ZEND_ACC_PUBLIC) SPL_ME(SplFixedArray, offsetExists, arginfo_fixedarray_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(SplFixedArray, offsetGet, arginfo_fixedarray_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(SplFixedArray, offsetSet, arginfo_fixedarray_offsetSet, ZEND_ACC_PUBLIC) SPL_ME(SplFixedArray, offsetUnset, arginfo_fixedarray_offsetGet, ZEND_ACC_PUBLIC) - SPL_ME(SplFixedArray, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFixedArray, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFixedArray, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFixedArray, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplFixedArray, valid, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplFixedArray, rewind, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFixedArray, current, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFixedArray, key, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFixedArray, next, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFixedArray, valid, arginfo_splfixedarray_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; /* }}} */ diff --git a/ext/spl/spl_fixedarray.h b/ext/spl/spl_fixedarray.h index dd556bef4..0dfd9eb5c 100644 --- a/ext/spl/spl_fixedarray.h +++ b/ext/spl/spl_fixedarray.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_fixedarray.h,v 1.1.2.3 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: spl_fixedarray.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SPL_FIXEDARRAY_H #define SPL_FIXEDARRAY_H diff --git a/ext/spl/spl_functions.c b/ext/spl/spl_functions.c index 4af4e7265..8279aeeec 100755 --- a/ext/spl/spl_functions.c +++ b/ext/spl/spl_functions.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_functions.c,v 1.28.2.3.2.3.2.5 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: spl_functions.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/spl/spl_functions.h b/ext/spl/spl_functions.h index 31c6870f7..c992f48c4 100755 --- a/ext/spl/spl_functions.h +++ b/ext/spl/spl_functions.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_functions.h,v 1.19.2.3.2.2.2.5 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: spl_functions.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_FUNCTIONS_H #define PHP_FUNCTIONS_H diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c index ad6d0c933..550b9efce 100644 --- a/ext/spl/spl_heap.c +++ b/ext/spl/spl_heap.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_heap.c,v 1.1.2.13 2008/12/31 11:15:43 sebastian Exp $ */ +/* $Id: spl_heap.c 287266 2009-08-13 22:07:05Z colder $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -76,6 +76,7 @@ struct _spl_heap_object { zend_class_entry *ce_get_iterator; zend_function *fptr_cmp; zend_function *fptr_count; + HashTable *debug_info; }; /* define an overloaded iterator structure */ @@ -370,6 +371,12 @@ static void spl_heap_object_free_storage(void *object TSRMLS_DC) /* {{{ */ spl_ptr_heap_destroy(intern->heap TSRMLS_CC); zval_ptr_dtor(&intern->retval); + + if (intern->debug_info != NULL) { + zend_hash_destroy(intern->debug_info); + efree(intern->debug_info); + } + efree(object); } /* }}} */ @@ -389,8 +396,9 @@ static zend_object_value spl_heap_object_new_ex(zend_class_entry *class_type, sp zend_object_std_init(&intern->std, class_type TSRMLS_CC); zend_hash_copy(intern->std.properties, &class_type->default_properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - intern->flags = 0; - intern->fptr_cmp = NULL; + intern->flags = 0; + intern->fptr_cmp = NULL; + intern->debug_info = NULL; if (orig) { spl_heap_object *other = (spl_heap_object*)zend_object_store_get_object(orig TSRMLS_CC); @@ -514,43 +522,46 @@ static int spl_heap_object_count_elements(zval *object, long *count TSRMLS_DC) / static HashTable* spl_heap_object_get_debug_info_helper(zend_class_entry *ce, zval *obj, int *is_temp TSRMLS_DC) { /* {{{ */ spl_heap_object *intern = (spl_heap_object*)zend_object_store_get_object(obj TSRMLS_CC); - HashTable *rv; zval *tmp, zrv, *heap_array; char *pnstr; int pnlen; int i; - *is_temp = 1; + *is_temp = 0; - ALLOC_HASHTABLE(rv); - ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(intern->std.properties) + 1, 0); + if (intern->debug_info == NULL) { + ALLOC_HASHTABLE(intern->debug_info); + ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(intern->std.properties) + 1, 0); + } - INIT_PZVAL(&zrv); - Z_ARRVAL(zrv) = rv; + if (intern->debug_info->nApplyCount == 0) { + INIT_PZVAL(&zrv); + Z_ARRVAL(zrv) = intern->debug_info; - zend_hash_copy(rv, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + zend_hash_copy(intern->debug_info, intern->std.properties, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); - pnstr = spl_gen_private_prop_name(ce, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); - add_assoc_long_ex(&zrv, pnstr, pnlen+1, intern->flags); - efree(pnstr); + pnstr = spl_gen_private_prop_name(ce, "flags", sizeof("flags")-1, &pnlen TSRMLS_CC); + add_assoc_long_ex(&zrv, pnstr, pnlen+1, intern->flags); + efree(pnstr); - pnstr = spl_gen_private_prop_name(ce, "isCorrupted", sizeof("isCorrupted")-1, &pnlen TSRMLS_CC); - add_assoc_bool_ex(&zrv, pnstr, pnlen+1, intern->heap->flags&SPL_HEAP_CORRUPTED); - efree(pnstr); + pnstr = spl_gen_private_prop_name(ce, "isCorrupted", sizeof("isCorrupted")-1, &pnlen TSRMLS_CC); + add_assoc_bool_ex(&zrv, pnstr, pnlen+1, intern->heap->flags&SPL_HEAP_CORRUPTED); + efree(pnstr); - ALLOC_INIT_ZVAL(heap_array); - array_init(heap_array); + ALLOC_INIT_ZVAL(heap_array); + array_init(heap_array); - for (i = 0; i < intern->heap->count; ++i) { - add_index_zval(heap_array, i, (zval *)intern->heap->elements[i]); - Z_ADDREF_P(intern->heap->elements[i]); - } + for (i = 0; i < intern->heap->count; ++i) { + add_index_zval(heap_array, i, (zval *)intern->heap->elements[i]); + Z_ADDREF_P(intern->heap->elements[i]); + } - pnstr = spl_gen_private_prop_name(ce, "heap", sizeof("heap")-1, &pnlen TSRMLS_CC); - add_assoc_zval_ex(&zrv, pnstr, pnlen+1, heap_array); - efree(pnstr); + pnstr = spl_gen_private_prop_name(ce, "heap", sizeof("heap")-1, &pnlen TSRMLS_CC); + add_assoc_zval_ex(&zrv, pnstr, pnlen+1, heap_array); + efree(pnstr); + } - return rv; + return intern->debug_info; } /* }}} */ @@ -1128,6 +1139,9 @@ ZEND_BEGIN_ARG_INFO(arginfo_pqueue_setflags, 0) ZEND_ARG_INFO(0, flags) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_splheap_void, 0) +ZEND_END_ARG_INFO() + static const zend_function_entry spl_funcs_SplMinHeap[] = { SPL_ME(SplMinHeap, compare, arginfo_heap_compare, ZEND_ACC_PROTECTED) {NULL, NULL, NULL} @@ -1141,31 +1155,31 @@ static const zend_function_entry spl_funcs_SplPriorityQueue[] = { SPL_ME(SplPriorityQueue, compare, arginfo_heap_compare, ZEND_ACC_PUBLIC) SPL_ME(SplPriorityQueue, insert, arginfo_pqueue_insert, ZEND_ACC_PUBLIC) SPL_ME(SplPriorityQueue, setExtractFlags, arginfo_pqueue_setflags, ZEND_ACC_PUBLIC) - SPL_ME(SplPriorityQueue, top, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplPriorityQueue, extract, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, count, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, isEmpty, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplPriorityQueue, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, recoverFromCorruption, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplPriorityQueue, top, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplPriorityQueue, extract, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, count, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, isEmpty, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, rewind, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplPriorityQueue, current, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, key, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, next, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, valid, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, recoverFromCorruption, arginfo_splheap_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; static const zend_function_entry spl_funcs_SplHeap[] = { - SPL_ME(SplHeap, extract, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, extract, arginfo_splheap_void, ZEND_ACC_PUBLIC) SPL_ME(SplHeap, insert, arginfo_heap_insert, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, top, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, count, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, isEmpty, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(SplHeap, recoverFromCorruption, NULL, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, top, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, count, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, isEmpty, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, rewind, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, current, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, key, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, next, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, valid, arginfo_splheap_void, ZEND_ACC_PUBLIC) + SPL_ME(SplHeap, recoverFromCorruption, arginfo_splheap_void, ZEND_ACC_PUBLIC) ZEND_FENTRY(compare, NULL, NULL, ZEND_ACC_PROTECTED|ZEND_ACC_ABSTRACT) {NULL, NULL, NULL} }; diff --git a/ext/spl/spl_heap.h b/ext/spl/spl_heap.h index 56c82b594..cd9d36ab4 100644 --- a/ext/spl/spl_heap.h +++ b/ext/spl/spl_heap.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_heap.h,v 1.1.2.3 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: spl_heap.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SPL_HEAP_H #define SPL_HEAP_H diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 11aa01911..d498890bc 100755 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_iterators.c,v 1.73.2.30.2.28.2.24 2009/05/09 19:45:26 scottmac Exp $ */ +/* $Id: spl_iterators.c 283486 2009-07-04 20:31:27Z felipe $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -61,9 +61,12 @@ PHPAPI zend_class_entry *spl_ce_RecursiveRegexIterator; PHPAPI zend_class_entry *spl_ce_Countable; PHPAPI zend_class_entry *spl_ce_RecursiveTreeIterator; +ZEND_BEGIN_ARG_INFO(arginfo_recursive_it_void, 0) +ZEND_END_ARG_INFO() + const zend_function_entry spl_funcs_RecursiveIterator[] = { - SPL_ABSTRACT_ME(RecursiveIterator, hasChildren, NULL) - SPL_ABSTRACT_ME(RecursiveIterator, getChildren, NULL) + SPL_ABSTRACT_ME(RecursiveIterator, hasChildren, arginfo_recursive_it_void) + SPL_ABSTRACT_ME(RecursiveIterator, getChildren, arginfo_recursive_it_void) {NULL, NULL, NULL} }; @@ -860,23 +863,23 @@ ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_RecursiveIteratorIterator[] = { SPL_ME(RecursiveIteratorIterator, __construct, arginfo_recursive_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, getDepth, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, rewind, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, valid, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, key, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, current, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, next, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, getDepth, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(RecursiveIteratorIterator, getSubIterator, arginfo_recursive_it_getSubIterator, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, getInnerIterator, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, beginIteration, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, endIteration, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, callHasChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, callGetChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, beginChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, endChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, nextElement, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, getInnerIterator, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, beginIteration, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, endIteration, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, callHasChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, callGetChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, beginChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, endChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, nextElement, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(RecursiveIteratorIterator, setMaxDepth, arginfo_recursive_it_setMaxDepth, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, getMaxDepth, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, getMaxDepth, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -1120,22 +1123,22 @@ ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_RecursiveTreeIterator[] = { SPL_ME(RecursiveTreeIterator, __construct, arginfo_recursive_tree_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveTreeIterator, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveTreeIterator, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, beginIteration, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, endIteration, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, callHasChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, callGetChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, beginChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, endChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveIteratorIterator, nextElement, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveTreeIterator, getPrefix, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, rewind, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, valid, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveTreeIterator, key, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveTreeIterator, current, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, next, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, beginIteration, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, endIteration, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, callHasChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, callGetChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, beginChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, endChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveIteratorIterator, nextElement, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveTreeIterator, getPrefix, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(RecursiveTreeIterator, setPrefixPart, arginfo_recursive_tree_it_setPrefixPart, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveTreeIterator, getEntry, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveTreeIterator, getPostfix, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveTreeIterator, getEntry, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveTreeIterator, getPostfix, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -1978,13 +1981,13 @@ ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_FilterIterator[] = { SPL_ME(FilterIterator, __construct, arginfo_filter_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(FilterIterator, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(FilterIterator, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, getInnerIterator, NULL, ZEND_ACC_PUBLIC) - SPL_ABSTRACT_ME(FilterIterator, accept, NULL) + SPL_ME(FilterIterator, rewind, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, valid, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, key, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, current, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(FilterIterator, next, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, getInnerIterator, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ABSTRACT_ME(FilterIterator, accept, arginfo_recursive_it_void) {NULL, NULL, NULL} }; @@ -1994,14 +1997,14 @@ ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_RecursiveFilterIterator[] = { SPL_ME(RecursiveFilterIterator, __construct, arginfo_parent_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveFilterIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveFilterIterator, getChildren, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveFilterIterator, hasChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveFilterIterator, getChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; static const zend_function_entry spl_funcs_ParentIterator[] = { SPL_ME(ParentIterator, __construct, arginfo_parent_it___construct, ZEND_ACC_PUBLIC) - SPL_MA(ParentIterator, accept, RecursiveFilterIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) + SPL_MA(ParentIterator, accept, RecursiveFilterIterator, hasChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2028,12 +2031,12 @@ ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_RegexIterator[] = { SPL_ME(RegexIterator, __construct, arginfo_regex_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(RegexIterator, accept, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RegexIterator, getMode, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RegexIterator, accept, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RegexIterator, getMode, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(RegexIterator, setMode, arginfo_regex_it_set_mode, ZEND_ACC_PUBLIC) - SPL_ME(RegexIterator, getFlags, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RegexIterator, getFlags, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(RegexIterator, setFlags, arginfo_regex_it_set_flags, ZEND_ACC_PUBLIC) - SPL_ME(RegexIterator, getPregFlags, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RegexIterator, getPregFlags, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(RegexIterator, setPregFlags, arginfo_regex_it_set_preg_flags, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2048,8 +2051,8 @@ ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_RecursiveRegexIterator[] = { SPL_ME(RecursiveRegexIterator, __construct, arginfo_rec_regex_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveFilterIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveRegexIterator, getChildren, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveFilterIterator, hasChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveRegexIterator, getChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; #endif @@ -2194,14 +2197,14 @@ ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_LimitIterator[] = { SPL_ME(LimitIterator, __construct, arginfo_limit_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(LimitIterator, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(LimitIterator, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(LimitIterator, next, NULL, ZEND_ACC_PUBLIC) + SPL_ME(LimitIterator, rewind, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(LimitIterator, valid, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, key, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, current, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(LimitIterator, next, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(LimitIterator, seek, arginfo_limit_it_seek, ZEND_ACC_PUBLIC) - SPL_ME(LimitIterator, getPosition, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, getInnerIterator, NULL, ZEND_ACC_PUBLIC) + SPL_ME(LimitIterator, getPosition, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, getInnerIterator, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2591,22 +2594,22 @@ ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_CachingIterator[] = { SPL_ME(CachingIterator, __construct, arginfo_caching_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(CachingIterator, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(CachingIterator, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(CachingIterator, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(CachingIterator, hasNext, NULL, ZEND_ACC_PUBLIC) - SPL_ME(CachingIterator, __toString, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, getInnerIterator, NULL, ZEND_ACC_PUBLIC) - SPL_ME(CachingIterator, getFlags, NULL, ZEND_ACC_PUBLIC) + SPL_ME(CachingIterator, rewind, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(CachingIterator, valid, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, key, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, current, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(CachingIterator, next, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(CachingIterator, hasNext, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(CachingIterator, __toString, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, getInnerIterator, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(CachingIterator, getFlags, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, setFlags, arginfo_caching_it_setFlags, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, offsetGet, arginfo_caching_it_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, offsetSet, arginfo_caching_it_offsetSet, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, offsetUnset, arginfo_caching_it_offsetGet, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, offsetExists, arginfo_caching_it_offsetGet, ZEND_ACC_PUBLIC) - SPL_ME(CachingIterator, getCache, NULL, ZEND_ACC_PUBLIC) - SPL_ME(CachingIterator, count, NULL, ZEND_ACC_PUBLIC) + SPL_ME(CachingIterator, getCache, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(CachingIterator, count, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2650,8 +2653,8 @@ ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_RecursiveCachingIterator[] = { SPL_ME(RecursiveCachingIterator, __construct, arginfo_caching_rec_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveCachingIterator, hasChildren, NULL, ZEND_ACC_PUBLIC) - SPL_ME(RecursiveCachingIterator, getChildren, NULL, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveCachingIterator, hasChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(RecursiveCachingIterator, getChildren, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2668,12 +2671,12 @@ ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_IteratorIterator[] = { SPL_ME(IteratorIterator, __construct, arginfo_iterator_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, getInnerIterator, NULL, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, rewind, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, valid, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, key, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, current, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, next, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, getInnerIterator, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2758,12 +2761,12 @@ ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_NoRewindIterator[] = { SPL_ME(NoRewindIterator, __construct, arginfo_norewind_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(NoRewindIterator, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(NoRewindIterator, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(NoRewindIterator, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(NoRewindIterator, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(NoRewindIterator, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, getInnerIterator, NULL, ZEND_ACC_PUBLIC) + SPL_ME(NoRewindIterator, rewind, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(NoRewindIterator, valid, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(NoRewindIterator, key, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(NoRewindIterator, current, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(NoRewindIterator, next, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, getInnerIterator, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2795,7 +2798,7 @@ SPL_METHOD(InfiniteIterator, next) static const zend_function_entry spl_funcs_InfiniteIterator[] = { SPL_ME(InfiniteIterator, __construct, arginfo_norewind_it___construct, ZEND_ACC_PUBLIC) - SPL_ME(InfiniteIterator, next, NULL, ZEND_ACC_PUBLIC) + SPL_ME(InfiniteIterator, next, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2833,11 +2836,11 @@ SPL_METHOD(EmptyIterator, next) } /* }}} */ static const zend_function_entry spl_funcs_EmptyIterator[] = { - SPL_ME(EmptyIterator, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(EmptyIterator, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(EmptyIterator, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(EmptyIterator, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(EmptyIterator, next, NULL, ZEND_ACC_PUBLIC) + SPL_ME(EmptyIterator, rewind, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(EmptyIterator, valid, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(EmptyIterator, key, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(EmptyIterator, current, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(EmptyIterator, next, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -2989,16 +2992,16 @@ ZEND_BEGIN_ARG_INFO(arginfo_append_it_append, 0) ZEND_END_ARG_INFO(); static const zend_function_entry spl_funcs_AppendIterator[] = { - SPL_ME(AppendIterator, __construct, NULL, ZEND_ACC_PUBLIC) + SPL_ME(AppendIterator, __construct, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(AppendIterator, append, arginfo_append_it_append, ZEND_ACC_PUBLIC) - SPL_ME(AppendIterator, rewind, NULL, ZEND_ACC_PUBLIC) - SPL_ME(AppendIterator, valid, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, key, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, current, NULL, ZEND_ACC_PUBLIC) - SPL_ME(AppendIterator, next, NULL, ZEND_ACC_PUBLIC) - SPL_ME(dual_it, getInnerIterator, NULL, ZEND_ACC_PUBLIC) - SPL_ME(AppendIterator, getIteratorIndex, NULL, ZEND_ACC_PUBLIC) - SPL_ME(AppendIterator, getArrayIterator, NULL, ZEND_ACC_PUBLIC) + SPL_ME(AppendIterator, rewind, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(AppendIterator, valid, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, key, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, current, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(AppendIterator, next, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(dual_it, getInnerIterator, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(AppendIterator, getIteratorIndex, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(AppendIterator, getArrayIterator, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) {NULL, NULL, NULL} }; @@ -3186,12 +3189,12 @@ PHP_FUNCTION(iterator_apply) /* }}} */ static const zend_function_entry spl_funcs_OuterIterator[] = { - SPL_ABSTRACT_ME(OuterIterator, getInnerIterator, NULL) + SPL_ABSTRACT_ME(OuterIterator, getInnerIterator, arginfo_recursive_it_void) {NULL, NULL, NULL} }; static const zend_function_entry spl_funcs_Countable[] = { - SPL_ABSTRACT_ME(Countable, count, NULL) + SPL_ABSTRACT_ME(Countable, count, arginfo_recursive_it_void) {NULL, NULL, NULL} }; diff --git a/ext/spl/spl_iterators.h b/ext/spl/spl_iterators.h index 4fa823292..d252d71b5 100755 --- a/ext/spl/spl_iterators.h +++ b/ext/spl/spl_iterators.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_iterators.h,v 1.18.2.7.2.12.2.5 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: spl_iterators.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SPL_ITERATORS_H #define SPL_ITERATORS_H diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c index 12e212ea1..3100ead59 100755 --- a/ext/spl/spl_observer.c +++ b/ext/spl/spl_observer.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_observer.c,v 1.2.2.6.2.3.2.17 2009/03/19 02:45:17 colder Exp $ */ +/* $Id: spl_observer.c 287266 2009-08-13 22:07:05Z colder $ */ #ifdef HAVE_CONFIG_H # include "config.h" @@ -57,6 +57,9 @@ ZEND_BEGIN_ARG_INFO(arginfo_SplSubject_attach, 0) ZEND_ARG_OBJ_INFO(0, SplObserver, SplObserver, 0) ZEND_END_ARG_INFO(); +ZEND_BEGIN_ARG_INFO(arginfo_SplSubject_void, 0) +ZEND_END_ARG_INFO(); + /*ZEND_BEGIN_ARG_INFO_EX(arginfo_SplSubject_notify, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, ignore, SplObserver, 1) ZEND_END_ARG_INFO();*/ @@ -64,7 +67,7 @@ ZEND_END_ARG_INFO();*/ static const zend_function_entry spl_funcs_SplSubject[] = { SPL_ABSTRACT_ME(SplSubject, attach, arginfo_SplSubject_attach) SPL_ABSTRACT_ME(SplSubject, detach, arginfo_SplSubject_attach) - SPL_ABSTRACT_ME(SplSubject, notify, NULL) + SPL_ABSTRACT_ME(SplSubject, notify, arginfo_SplSubject_void) {NULL, NULL, NULL} }; @@ -81,6 +84,7 @@ typedef struct _spl_SplObjectStorage { /* {{{ */ long index; HashPosition pos; long flags; + HashTable *debug_info; } spl_SplObjectStorage; /* }}} */ /* {{{ storage is an assoc aray of [zend_object_value]=>[zval *obj, zval *inf] */ @@ -96,6 +100,11 @@ void spl_SplOjectStorage_free_storage(void *object TSRMLS_DC) /* {{{ */ zend_object_std_dtor(&intern->std TSRMLS_CC); zend_hash_destroy(&intern->storage); + + if (intern->debug_info != NULL) { + zend_hash_destroy(intern->debug_info); + efree(intern->debug_info); + } efree(object); } /* }}} */ @@ -235,42 +244,46 @@ static HashTable* spl_object_storage_debug_info(zval *obj, int *is_temp TSRMLS_D { spl_SplObjectStorage *intern = (spl_SplObjectStorage*)zend_object_store_get_object(obj TSRMLS_CC); spl_SplObjectStorageElement *element; - HashTable *rv, *props; + HashTable *props; HashPosition pos; zval *tmp, *storage; char md5str[33]; int name_len; char *zname; - *is_temp = 1; + *is_temp = 0; props = Z_OBJPROP_P(obj); - ALLOC_HASHTABLE(rv); - ZEND_INIT_SYMTABLE_EX(rv, zend_hash_num_elements(props) + 1, 0); - - zend_hash_copy(rv, props, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + if (intern->debug_info == NULL) { + ALLOC_HASHTABLE(intern->debug_info); + ZEND_INIT_SYMTABLE_EX(intern->debug_info, zend_hash_num_elements(props) + 1, 0); + } - MAKE_STD_ZVAL(storage); - array_init(storage); + if (intern->debug_info->nApplyCount == 0) { + zend_hash_copy(intern->debug_info, props, (copy_ctor_func_t) zval_add_ref, (void *) &tmp, sizeof(zval *)); + + MAKE_STD_ZVAL(storage); + array_init(storage); + + zend_hash_internal_pointer_reset_ex(&intern->storage, &pos); + while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) { + php_spl_object_hash(element->obj, md5str TSRMLS_CC); + Z_ADDREF_P(element->obj); + Z_ADDREF_P(element->inf); + MAKE_STD_ZVAL(tmp); + array_init(tmp); + add_assoc_zval_ex(tmp, "obj", sizeof("obj"), element->obj); + add_assoc_zval_ex(tmp, "inf", sizeof("inf"), element->inf); + add_assoc_zval_ex(storage, md5str, 33, tmp); + zend_hash_move_forward_ex(&intern->storage, &pos); + } - zend_hash_internal_pointer_reset_ex(&intern->storage, &pos); - while (zend_hash_get_current_data_ex(&intern->storage, (void **)&element, &pos) == SUCCESS) { - php_spl_object_hash(element->obj, md5str TSRMLS_CC); - Z_ADDREF_P(element->obj); - Z_ADDREF_P(element->inf); - MAKE_STD_ZVAL(tmp); - array_init(tmp); - add_assoc_zval_ex(tmp, "obj", sizeof("obj"), element->obj); - add_assoc_zval_ex(tmp, "inf", sizeof("inf"), element->inf); - add_assoc_zval_ex(storage, md5str, 33, tmp); - zend_hash_move_forward_ex(&intern->storage, &pos); + zname = spl_gen_private_prop_name(spl_ce_SplObjectStorage, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); + zend_symtable_update(intern->debug_info, zname, name_len+1, &storage, sizeof(zval *), NULL); + efree(zname); } - zname = spl_gen_private_prop_name(spl_ce_SplObjectStorage, "storage", sizeof("storage")-1, &name_len TSRMLS_CC); - zend_symtable_update(rv, zname, name_len+1, &storage, sizeof(zval *), NULL); - efree(zname); - - return rv; + return intern->debug_info; } /* }}} */ @@ -700,25 +713,28 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_offsetSet, 0, 0, 2) ZEND_ARG_INFO(0, info) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_splobject_void, 0) +ZEND_END_ARG_INFO() + static const zend_function_entry spl_funcs_SplObjectStorage[] = { SPL_ME(SplObjectStorage, attach, arginfo_attach, 0) SPL_ME(SplObjectStorage, detach, arginfo_Object, 0) SPL_ME(SplObjectStorage, contains, arginfo_Object, 0) SPL_ME(SplObjectStorage, addAll, arginfo_Object, 0) SPL_ME(SplObjectStorage, removeAll, arginfo_Object, 0) - SPL_ME(SplObjectStorage, getInfo, NULL, 0) + SPL_ME(SplObjectStorage, getInfo, arginfo_splobject_void,0) SPL_ME(SplObjectStorage, setInfo, arginfo_setInfo, 0) /* Countable */ - SPL_ME(SplObjectStorage, count, NULL, 0) + SPL_ME(SplObjectStorage, count, arginfo_splobject_void,0) /* Iterator */ - SPL_ME(SplObjectStorage, rewind, NULL, 0) - SPL_ME(SplObjectStorage, valid, NULL, 0) - SPL_ME(SplObjectStorage, key, NULL, 0) - SPL_ME(SplObjectStorage, current, NULL, 0) - SPL_ME(SplObjectStorage, next, NULL, 0) + SPL_ME(SplObjectStorage, rewind, arginfo_splobject_void,0) + SPL_ME(SplObjectStorage, valid, arginfo_splobject_void,0) + SPL_ME(SplObjectStorage, key, arginfo_splobject_void,0) + SPL_ME(SplObjectStorage, current, arginfo_splobject_void,0) + SPL_ME(SplObjectStorage, next, arginfo_splobject_void,0) /* Serializable */ SPL_ME(SplObjectStorage, unserialize, arginfo_Serialized, 0) - SPL_ME(SplObjectStorage, serialize, NULL, 0) + SPL_ME(SplObjectStorage, serialize, arginfo_splobject_void,0) /* ArrayAccess */ SPL_MA(SplObjectStorage, offsetExists, SplObjectStorage, contains, arginfo_offsetGet, 0) SPL_MA(SplObjectStorage, offsetSet, SplObjectStorage, attach, arginfo_offsetSet, 0) @@ -998,20 +1014,24 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_MultipleIterator_containsIterator, 0, 0, 1) ZEND_ARG_OBJ_INFO(0, iterator, Iterator, 0) ZEND_END_ARG_INFO(); +ZEND_BEGIN_ARG_INFO_EX(arginfo_MultipleIterator_setflags, 0, 0, 1) + ZEND_ARG_INFO(0, flags) +ZEND_END_ARG_INFO(); + static const zend_function_entry spl_funcs_MultipleIterator[] = { - SPL_ME(MultipleIterator, __construct, NULL, 0) - SPL_ME(MultipleIterator, getFlags, NULL, 0) - SPL_ME(MultipleIterator, setFlags, NULL, 0) + SPL_ME(MultipleIterator, __construct, arginfo_MultipleIterator_setflags, 0) + SPL_ME(MultipleIterator, getFlags, arginfo_splobject_void, 0) + SPL_ME(MultipleIterator, setFlags, arginfo_MultipleIterator_setflags, 0) SPL_ME(MultipleIterator, attachIterator, arginfo_MultipleIterator_attachIterator, 0) SPL_MA(MultipleIterator, detachIterator, SplObjectStorage, detach, arginfo_MultipleIterator_detachIterator, 0) SPL_MA(MultipleIterator, containsIterator, SplObjectStorage, contains, arginfo_MultipleIterator_containsIterator, 0) - SPL_MA(MultipleIterator, countIterators, SplObjectStorage, count, NULL, 0) + SPL_MA(MultipleIterator, countIterators, SplObjectStorage, count, arginfo_splobject_void, 0) /* Iterator */ - SPL_ME(MultipleIterator, rewind, NULL, 0) - SPL_ME(MultipleIterator, valid, NULL, 0) - SPL_ME(MultipleIterator, key, NULL, 0) - SPL_ME(MultipleIterator, current, NULL, 0) - SPL_ME(MultipleIterator, next, NULL, 0) + SPL_ME(MultipleIterator, rewind, arginfo_splobject_void, 0) + SPL_ME(MultipleIterator, valid, arginfo_splobject_void, 0) + SPL_ME(MultipleIterator, key, arginfo_splobject_void, 0) + SPL_ME(MultipleIterator, current, arginfo_splobject_void, 0) + SPL_ME(MultipleIterator, next, arginfo_splobject_void, 0) {NULL, NULL, NULL} }; diff --git a/ext/spl/spl_observer.h b/ext/spl/spl_observer.h index 1a0a1c362..0edb338c5 100755 --- a/ext/spl/spl_observer.h +++ b/ext/spl/spl_observer.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spl_observer.h,v 1.2.2.2.2.1.2.3 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: spl_observer.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SPL_OBSERVER_H #define SPL_OBSERVER_H diff --git a/ext/spl/tests/ArrayObject_unserialize_empty_string.phpt b/ext/spl/tests/ArrayObject_unserialize_empty_string.phpt new file mode 100644 index 000000000..75d8a4132 --- /dev/null +++ b/ext/spl/tests/ArrayObject_unserialize_empty_string.phpt @@ -0,0 +1,16 @@ +--TEST-- +ArrayObject: test that you cannot unserialize a empty string +--CREDITS-- +Havard Eide +#PHPTestFest2009 Norway 2009-06-09 \o/ +--FILE-- +unserialize(""); +?> +--EXPECTF-- +Fatal error: Uncaught exception 'UnexpectedValueException' with message 'Empty serialized string cannot be empty' in %s.php:%d +Stack trace: +#0 %s(%d): ArrayObject->unserialize('') +#1 {main} + thrown in %s.php on line %d diff --git a/ext/spl/tests/DirectoryIterator_by_reference.phpt b/ext/spl/tests/DirectoryIterator_by_reference.phpt new file mode 100644 index 000000000..5352a5df1 --- /dev/null +++ b/ext/spl/tests/DirectoryIterator_by_reference.phpt @@ -0,0 +1,14 @@ +--TEST-- +DirectoryIterator: test that you cannot use iterator with reference +--CREDITS-- +Havard Eide +#PHPTestFest2009 Norway 2009-06-09 \o/ +--FILE-- + +--EXPECTF-- +Fatal error: An iterator cannot be used with foreach by reference in %s on line %d \ No newline at end of file diff --git a/ext/spl/tests/DirectoryIterator_empty_constructor.phpt b/ext/spl/tests/DirectoryIterator_empty_constructor.phpt new file mode 100644 index 000000000..da5276ccd --- /dev/null +++ b/ext/spl/tests/DirectoryIterator_empty_constructor.phpt @@ -0,0 +1,15 @@ +--TEST-- +DirectoryIterator: Test empty value to DirectoryIterator constructor +--CREDITS-- +Havard Eide +#PHPTestFest2009 Norway 2009-06-09 \o/ +--FILE-- + +--EXPECTF-- +Fatal error: Uncaught exception 'RuntimeException' with message 'Directory name must not be empty.' in %s:%d +Stack trace: +#0 %s(%d): DirectoryIterator->__construct('') +#1 {main} + thrown in %s on line %d \ No newline at end of file diff --git a/ext/spl/tests/DirectoryIterator_getBasename_basic_test.phpt b/ext/spl/tests/DirectoryIterator_getBasename_basic_test.phpt index f748bb1c9..ed1f473be 100644 --- a/ext/spl/tests/DirectoryIterator_getBasename_basic_test.phpt +++ b/ext/spl/tests/DirectoryIterator_getBasename_basic_test.phpt @@ -1,23 +1,23 @@ ---TEST-- -DirectoryIterator::getBasename() - Basic Test ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -isFile()) { - $dir->next(); - } - echo $dir->getBasename('.txt'); -?> ---CLEAN-- - ---EXPECTF-- -getBasename_test +--TEST-- +DirectoryIterator::getBasename() - Basic Test +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +isFile()) { + $dir->next(); + } + echo $dir->getBasename('.txt'); +?> +--CLEAN-- + +--EXPECTF-- +getBasename_test diff --git a/ext/spl/tests/DirectoryIterator_getBasename_pass_array.phpt b/ext/spl/tests/DirectoryIterator_getBasename_pass_array.phpt index cad30c686..b2df8a55c 100644 --- a/ext/spl/tests/DirectoryIterator_getBasename_pass_array.phpt +++ b/ext/spl/tests/DirectoryIterator_getBasename_pass_array.phpt @@ -1,23 +1,23 @@ ---TEST-- -DirectoryIterator::getBasename() - Pass unexpected array ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -isFile()) { - $dir->next(); - } - echo $dir->getBasename(array()); -?> ---CLEAN-- - ---EXPECTF-- -Warning: DirectoryIterator::getBasename() expects parameter 1 to be %binary_string_optional%, array given in %s on line %d +--TEST-- +DirectoryIterator::getBasename() - Pass unexpected array +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +isFile()) { + $dir->next(); + } + echo $dir->getBasename(array()); +?> +--CLEAN-- + +--EXPECTF-- +Warning: DirectoryIterator::getBasename() expects parameter 1 to be %binary_string_optional%, array given in %s on line %d diff --git a/ext/spl/tests/DirectoryIterator_getGroup_basic.phpt b/ext/spl/tests/DirectoryIterator_getGroup_basic.phpt new file mode 100644 index 000000000..58387ccce --- /dev/null +++ b/ext/spl/tests/DirectoryIterator_getGroup_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +SPL: DirectoryIterator test getGroup +--CREDITS-- +Cesare D'Amico +Andrea Giorgini +Filippo De Santis +Daniel Londero +Francesco Trucchia +Jacopo Romei +#Test Fest Cesena (Italy) on 2009-06-20 +--SKIPIF-- + +--FILE-- +getGroup() == $result); + +?> +--CLEAN-- + +--EXPECTF-- +bool(true) diff --git a/ext/spl/tests/DirectoryIterator_getInode_basic.phpt b/ext/spl/tests/DirectoryIterator_getInode_basic.phpt new file mode 100644 index 000000000..4fd7e8da3 --- /dev/null +++ b/ext/spl/tests/DirectoryIterator_getInode_basic.phpt @@ -0,0 +1,29 @@ +--TEST-- +SPL: Spl Directory Iterator test getInode +--CREDITS-- +Cesare D'Amico +Andrea Giorgini +Filippo De Santis +Daniel Londero +Francesco Trucchia +Jacopo Romei +#Test Fest Cesena (Italy) on 2009-06-20 +--SKIPIF-- + +--FILE-- +getInode())); + +?> +--CLEAN-- + +--EXPECTF-- +string(%d) "%d" diff --git a/ext/spl/tests/DirectoryIterator_getInode_error.phpt b/ext/spl/tests/DirectoryIterator_getInode_error.phpt new file mode 100644 index 000000000..c3641f9d8 --- /dev/null +++ b/ext/spl/tests/DirectoryIterator_getInode_error.phpt @@ -0,0 +1,28 @@ +--TEST-- +SPL: Spl File Info test getInode +--CREDITS-- +Cesare D'Amico +Andrea Giorgini +Filippo De Santis +Daniel Londero +Francesco Trucchia +Jacopo Romei +#Test Fest Cesena (Italy) on 2009-06-20 +--SKIPIF-- + +--FILE-- +getInode()); +?> + +--EXPECTF-- +Fatal error: Uncaught exception 'RuntimeException' with message 'SplFileInfo::getInode(): stat failed for %s' in %s +Stack trace: +#0 %s: SplFileInfo->getInode() +#1 {main} + thrown in %s diff --git a/ext/spl/tests/DirectoryIterator_getOwner_basic.phpt b/ext/spl/tests/DirectoryIterator_getOwner_basic.phpt new file mode 100644 index 000000000..e342dcdb6 --- /dev/null +++ b/ext/spl/tests/DirectoryIterator_getOwner_basic.phpt @@ -0,0 +1,29 @@ +--TEST-- +SPL: Spl Directory Iterator test getOwner +--CREDITS-- +Cesare D'Amico +Andrea Giorgini +Filippo De Santis +Daniel Londero +Francesco Trucchia +Jacopo Romei +#Test Fest Cesena (Italy) on 2009-06-20 +--SKIPIF-- + +--FILE-- +getOwner() == $result); + +?> +--CLEAN-- + +--EXPECTF-- +bool(true) diff --git a/ext/spl/tests/SplDoublyLinkedList_bottom_pass_array.phpt b/ext/spl/tests/SplDoublyLinkedList_bottom_pass_array.phpt index 4891fbedd..36b186d6b 100644 --- a/ext/spl/tests/SplDoublyLinkedList_bottom_pass_array.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_bottom_pass_array.phpt @@ -1,14 +1,14 @@ ---TEST-- -SplDoublyLinkedList::bottom() - pass in an unexpected array parameter ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -push("top"); -$list->bottom(array()); - -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::bottom() expects exactly 0 parameters, 1 given in %s on line %d +--TEST-- +SplDoublyLinkedList::bottom() - pass in an unexpected array parameter +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +push("top"); +$list->bottom(array()); + +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::bottom() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplDoublyLinkedList_bottom_pass_float.phpt b/ext/spl/tests/SplDoublyLinkedList_bottom_pass_float.phpt index cff9d6a5e..94312a0f6 100644 --- a/ext/spl/tests/SplDoublyLinkedList_bottom_pass_float.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_bottom_pass_float.phpt @@ -1,14 +1,14 @@ ---TEST-- -SplDoublyLinkedList::bottom() - pass in an unexpected float parameter ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -push("top"); -$list->bottom(3.14159); - -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::bottom() expects exactly 0 parameters, 1 given in %s on line %d +--TEST-- +SplDoublyLinkedList::bottom() - pass in an unexpected float parameter +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +push("top"); +$list->bottom(3.14159); + +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::bottom() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplDoublyLinkedList_bottom_pass_integer.phpt b/ext/spl/tests/SplDoublyLinkedList_bottom_pass_integer.phpt index e966199d7..651f1e438 100644 --- a/ext/spl/tests/SplDoublyLinkedList_bottom_pass_integer.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_bottom_pass_integer.phpt @@ -1,14 +1,14 @@ ---TEST-- -SplDoublyLinkedList::bottom() - pass in an unexpected integer parameter ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -push("top"); -$list->bottom(45); - -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::bottom() expects exactly 0 parameters, 1 given in %s on line %d +--TEST-- +SplDoublyLinkedList::bottom() - pass in an unexpected integer parameter +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +push("top"); +$list->bottom(45); + +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::bottom() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplDoublyLinkedList_bottom_pass_null.phpt b/ext/spl/tests/SplDoublyLinkedList_bottom_pass_null.phpt index 05b6be932..efc6b8ae5 100644 --- a/ext/spl/tests/SplDoublyLinkedList_bottom_pass_null.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_bottom_pass_null.phpt @@ -1,14 +1,14 @@ ---TEST-- -SplDoublyLinkedList::bottom() - pass in an unexpected null parameter ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -push("top"); -$list->bottom(null); - -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::bottom() expects exactly 0 parameters, 1 given in %s on line %d +--TEST-- +SplDoublyLinkedList::bottom() - pass in an unexpected null parameter +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +push("top"); +$list->bottom(null); + +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::bottom() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplDoublyLinkedList_count_param_SplDoublyLinkedList.phpt b/ext/spl/tests/SplDoublyLinkedList_count_param_SplDoublyLinkedList.phpt index 77bd11ee5..36c72de19 100644 --- a/ext/spl/tests/SplDoublyLinkedList_count_param_SplDoublyLinkedList.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_count_param_SplDoublyLinkedList.phpt @@ -1,11 +1,11 @@ ---TEST-- -Create a SplDoublyLinkedList, call count() and pass a SplDoublyLinkedList object as the parameter. ---CREDITS-- -Philip Norton philipnorton42@gmail.com ---FILE-- -count(new SplDoublyLinkedList(2)); -?> ---EXPECTF-- +--TEST-- +Create a SplDoublyLinkedList, call count() and pass a SplDoublyLinkedList object as the parameter. +--CREDITS-- +Philip Norton philipnorton42@gmail.com +--FILE-- +count(new SplDoublyLinkedList(2)); +?> +--EXPECTF-- Warning: SplDoublyLinkedList::count() expects exactly 0 parameters, 1 given in %s on line %d \ No newline at end of file diff --git a/ext/spl/tests/SplDoublyLinkedList_current_empty.phpt b/ext/spl/tests/SplDoublyLinkedList_current_empty.phpt index 99aaf2691..558504b38 100644 --- a/ext/spl/tests/SplDoublyLinkedList_current_empty.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_current_empty.phpt @@ -1,13 +1,13 @@ ---TEST-- -Run current() function on an empty SplDoublyLinkedList. ---CREDITS-- -Philip Norton philipnorton42@gmail.com ---FILE-- -current()); - -?> ---EXPECT-- +--TEST-- +Run current() function on an empty SplDoublyLinkedList. +--CREDITS-- +Philip Norton philipnorton42@gmail.com +--FILE-- +current()); + +?> +--EXPECT-- NULL \ No newline at end of file diff --git a/ext/spl/tests/SplDoublyLinkedList_offsetGet_empty.phpt b/ext/spl/tests/SplDoublyLinkedList_offsetGet_empty.phpt index 639e35fe0..36c47fef2 100644 --- a/ext/spl/tests/SplDoublyLinkedList_offsetGet_empty.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_offsetGet_empty.phpt @@ -1,14 +1,14 @@ ---TEST-- -SplDoublyLinkedList::offsetGet() with no parameter passed. ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- -offsetGet(); - -?> ---EXPECTF-- +--TEST-- +SplDoublyLinkedList::offsetGet() with no parameter passed. +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- +offsetGet(); + +?> +--EXPECTF-- Warning: SplDoublyLinkedList::offsetGet() expects exactly 1 parameter, 0 given in %s on line %d \ No newline at end of file diff --git a/ext/spl/tests/SplDoublyLinkedList_offsetGet_param_array.phpt b/ext/spl/tests/SplDoublyLinkedList_offsetGet_param_array.phpt index 6e3a69aaf..5df4ab59a 100644 --- a/ext/spl/tests/SplDoublyLinkedList_offsetGet_param_array.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_offsetGet_param_array.phpt @@ -1,18 +1,18 @@ ---TEST-- -SplDoublyLinkedList::offsetGet() with 1st parameter passed as array. ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- -offsetGet( array( 'fail' ) ); - -?> ---EXPECTF-- -Fatal error: Uncaught exception 'OutOfRangeException' with message 'Offset invalid or out of range' in %s -Stack trace: -#0 %s -#1 {main} +--TEST-- +SplDoublyLinkedList::offsetGet() with 1st parameter passed as array. +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- +offsetGet( array( 'fail' ) ); + +?> +--EXPECTF-- +Fatal error: Uncaught exception 'OutOfRangeException' with message 'Offset invalid or out of range' in %s +Stack trace: +#0 %s +#1 {main} thrown in %s on line %d \ No newline at end of file diff --git a/ext/spl/tests/SplDoublyLinkedList_offsetGet_param_string.phpt b/ext/spl/tests/SplDoublyLinkedList_offsetGet_param_string.phpt index d35aaf16f..fcff762e6 100644 --- a/ext/spl/tests/SplDoublyLinkedList_offsetGet_param_string.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_offsetGet_param_string.phpt @@ -1,18 +1,18 @@ ---TEST-- -SplDoublyLinkedList::offsetGet() with 1st parameter passed as string. ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- -offsetGet( 'fail' ); - -?> ---EXPECTF-- -Fatal error: Uncaught exception 'OutOfRangeException' with message 'Offset invalid or out of range' in %s -Stack trace: -#0 %s -#1 {main} +--TEST-- +SplDoublyLinkedList::offsetGet() with 1st parameter passed as string. +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- +offsetGet( 'fail' ); + +?> +--EXPECTF-- +Fatal error: Uncaught exception 'OutOfRangeException' with message 'Offset invalid or out of range' in %s +Stack trace: +#0 %s +#1 {main} thrown in %s on line %d \ No newline at end of file diff --git a/ext/spl/tests/SplDoublyLinkedList_pop_params.phpt b/ext/spl/tests/SplDoublyLinkedList_pop_params.phpt index 0b80babe1..11ab343db 100644 --- a/ext/spl/tests/SplDoublyLinkedList_pop_params.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_pop_params.phpt @@ -1,14 +1,14 @@ ---TEST-- -SplDoublyLinkedList::offsetGet() with no parameter passed. ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- -pop( 'param' ); - -?> ---EXPECTF-- +--TEST-- +SplDoublyLinkedList::offsetGet() with no parameter passed. +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- +pop( 'param' ); + +?> +--EXPECTF-- Warning: SplDoublyLinkedList::pop() expects exactly 0 parameters, 1 given in %s on line %d \ No newline at end of file diff --git a/ext/spl/tests/SplDoublyLinkedList_setIteratorMode_param_SplDoublyLinkedList.phpt b/ext/spl/tests/SplDoublyLinkedList_setIteratorMode_param_SplDoublyLinkedList.phpt index e92121568..9bf7a3200 100644 --- a/ext/spl/tests/SplDoublyLinkedList_setIteratorMode_param_SplDoublyLinkedList.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_setIteratorMode_param_SplDoublyLinkedList.phpt @@ -1,11 +1,11 @@ ---TEST-- -Create a SplDoublyLinkedList, call setIteratorMode() and pass a SplDoublyLinkedList object as the parameter. ---CREDITS-- -Philip Norton philipnorton42@gmail.com ---FILE-- -setIteratorMode(new SplDoublyLinkedList(2)); -?> ---EXPECTF-- +--TEST-- +Create a SplDoublyLinkedList, call setIteratorMode() and pass a SplDoublyLinkedList object as the parameter. +--CREDITS-- +Philip Norton philipnorton42@gmail.com +--FILE-- +setIteratorMode(new SplDoublyLinkedList(2)); +?> +--EXPECTF-- Warning: SplDoublyLinkedList::setIteratorMode() expects parameter 1 to be long, object given in %s on line %d \ No newline at end of file diff --git a/ext/spl/tests/SplDoublyLinkedList_shift_noParams.phpt b/ext/spl/tests/SplDoublyLinkedList_shift_noParams.phpt deleted file mode 100644 index cd4ea5b03..000000000 --- a/ext/spl/tests/SplDoublyLinkedList_shift_noParams.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -Checks that the shift() method of DoublyLinkedList does not accept args. ---CREDITS-- -PHPNW Test Fest 2009 - Rick Ogden ---FILE-- -push(1); -$ll->push(2); - -var_dump($ll->shift(1)); -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::shift() expects exactly 0 parameters, 1 given in %s on line %d -NULL diff --git a/ext/spl/tests/SplDoublyLinkedList_top_pass_array.phpt b/ext/spl/tests/SplDoublyLinkedList_top_pass_array.phpt index 33d22d755..2e2632d39 100644 --- a/ext/spl/tests/SplDoublyLinkedList_top_pass_array.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_top_pass_array.phpt @@ -1,14 +1,14 @@ ---TEST-- -SplDoublyLinkedList::top() - pass in an unexpected array ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -push("top"); -$list->top(array()); - -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::top() expects exactly 0 parameters, 1 given in %s on line %d +--TEST-- +SplDoublyLinkedList::top() - pass in an unexpected array +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +push("top"); +$list->top(array()); + +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::top() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplDoublyLinkedList_top_pass_float.phpt b/ext/spl/tests/SplDoublyLinkedList_top_pass_float.phpt index 08394f386..0a481b85a 100644 --- a/ext/spl/tests/SplDoublyLinkedList_top_pass_float.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_top_pass_float.phpt @@ -1,14 +1,14 @@ ---TEST-- -SplDoublyLinkedList::top() - pass in an unexpected float parameter ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -push("top"); -$list->top(3.14159); - -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::top() expects exactly 0 parameters, 1 given in %s on line %d +--TEST-- +SplDoublyLinkedList::top() - pass in an unexpected float parameter +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +push("top"); +$list->top(3.14159); + +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::top() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplDoublyLinkedList_top_pass_integer.phpt b/ext/spl/tests/SplDoublyLinkedList_top_pass_integer.phpt index e44097204..72bdbabc3 100644 --- a/ext/spl/tests/SplDoublyLinkedList_top_pass_integer.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_top_pass_integer.phpt @@ -1,14 +1,14 @@ ---TEST-- -SplDoublyLinkedList::top() - pass in an unexpected integer parameter ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -push("top"); -$list->top(45); - -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::top() expects exactly 0 parameters, 1 given in %s on line %d +--TEST-- +SplDoublyLinkedList::top() - pass in an unexpected integer parameter +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +push("top"); +$list->top(45); + +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::top() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplDoublyLinkedList_top_pass_null.phpt b/ext/spl/tests/SplDoublyLinkedList_top_pass_null.phpt index 297506e4b..6a9239973 100644 --- a/ext/spl/tests/SplDoublyLinkedList_top_pass_null.phpt +++ b/ext/spl/tests/SplDoublyLinkedList_top_pass_null.phpt @@ -1,14 +1,14 @@ ---TEST-- -SplDoublyLinkedList::top() - pass in an unexpected null parameter ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -push("top"); -$list->top(null); - -?> ---EXPECTF-- -Warning: SplDoublyLinkedList::top() expects exactly 0 parameters, 1 given in %s on line %d +--TEST-- +SplDoublyLinkedList::top() - pass in an unexpected null parameter +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +push("top"); +$list->top(null); + +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::top() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplFileInfo_getGroup_basic.phpt b/ext/spl/tests/SplFileInfo_getGroup_basic.phpt new file mode 100644 index 000000000..7b0528d7d --- /dev/null +++ b/ext/spl/tests/SplFileInfo_getGroup_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +SPL: Spl File Info test getGroup +--CREDITS-- +Cesare D'Amico +Andrea Giorgini +Filippo De Santis +Daniel Londero +Francesco Trucchia +Jacopo Romei +#Test Fest Cesena (Italy) on 2009-06-20 +--SKIPIF-- + +--FILE-- +getGroup() == $result); + +?> +--CLEAN-- + +--EXPECTF-- +bool(true) diff --git a/ext/spl/tests/SplFileInfo_getGroup_error.phpt b/ext/spl/tests/SplFileInfo_getGroup_error.phpt new file mode 100644 index 000000000..f0db00d9e --- /dev/null +++ b/ext/spl/tests/SplFileInfo_getGroup_error.phpt @@ -0,0 +1,28 @@ +--TEST-- +SPL: Spl File Info test getGroup +--CREDITS-- +Cesare D'Amico +Andrea Giorgini +Filippo De Santis +Daniel Londero +Francesco Trucchia +Jacopo Romei +#Test Fest Cesena (Italy) on 2009-06-20 +--SKIPIF-- + +--FILE-- +getGroup()); +?> + +--EXPECTF-- +Fatal error: Uncaught exception 'RuntimeException' with message 'SplFileInfo::getGroup(): stat failed for not_existing' in %s +Stack trace: +#0 %s: SplFileInfo->getGroup() +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/SplFileInfo_getInode_basic.phpt b/ext/spl/tests/SplFileInfo_getInode_basic.phpt new file mode 100644 index 000000000..902cbb31c --- /dev/null +++ b/ext/spl/tests/SplFileInfo_getInode_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +SPL: Spl File Info test getInode +--CREDITS-- +Cesare D'Amico +Andrea Giorgini +Filippo De Santis +Daniel Londero +Francesco Trucchia +Jacopo Romei +#Test Fest Cesena (Italy) on 2009-06-20 +--SKIPIF-- + +--FILE-- +getInode() == $result); + +?> +--CLEAN-- + +--EXPECTF-- +bool(true) diff --git a/ext/spl/tests/SplFileInfo_getInode_error.phpt b/ext/spl/tests/SplFileInfo_getInode_error.phpt new file mode 100644 index 000000000..bf8efae4c --- /dev/null +++ b/ext/spl/tests/SplFileInfo_getInode_error.phpt @@ -0,0 +1,28 @@ +--TEST-- +SPL: Spl File Info test getPerms +--CREDITS-- +Cesare D'Amico +Andrea Giorgini +Filippo De Santis +Daniel Londero +Francesco Trucchia +Jacopo Romei +#Test Fest Cesena (Italy) on 2009-06-20 +--SKIPIF-- + +--FILE-- +getInode()); +?> + +--EXPECTF-- +Fatal error: Uncaught exception 'RuntimeException' with message 'SplFileInfo::getInode(): stat failed for not_existing' in %s +Stack trace: +#0 %s: SplFileInfo->getInode() +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/SplFileInfo_getOwner_basic.phpt b/ext/spl/tests/SplFileInfo_getOwner_basic.phpt new file mode 100644 index 000000000..50f79430c --- /dev/null +++ b/ext/spl/tests/SplFileInfo_getOwner_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +SPL: Spl File Info test getOwner +--CREDITS-- +Cesare D'Amico +Andrea Giorgini +Filippo De Santis +Daniel Londero +Francesco Trucchia +Jacopo Romei +#Test Fest Cesena (Italy) on 2009-06-20 +--SKIPIF-- + +--FILE-- +getOwner() == $result); + +?> +--CLEAN-- + +--EXPECTF-- +bool(true) diff --git a/ext/spl/tests/SplFileInfo_getOwner_error.phpt b/ext/spl/tests/SplFileInfo_getOwner_error.phpt new file mode 100644 index 000000000..d5d46781c --- /dev/null +++ b/ext/spl/tests/SplFileInfo_getOwner_error.phpt @@ -0,0 +1,28 @@ +--TEST-- +SPL: Spl File Info test getOwner +--CREDITS-- +Cesare D'Amico +Andrea Giorgini +Filippo De Santis +Daniel Londero +Francesco Trucchia +Jacopo Romei +#Test Fest Cesena (Italy) on 2009-06-20 +--SKIPIF-- + +--FILE-- +getOwner()); +?> + +--EXPECTF-- +Fatal error: Uncaught exception 'RuntimeException' with message 'SplFileInfo::getOwner(): stat failed for not_existing' in %s +Stack trace: +#0 %s: SplFileInfo->getOwner() +#1 {main} + thrown in %s on line %d diff --git a/ext/spl/tests/SplFileInfo_getPerms_basic.phpt b/ext/spl/tests/SplFileInfo_getPerms_basic.phpt new file mode 100644 index 000000000..e9b7beaa9 --- /dev/null +++ b/ext/spl/tests/SplFileInfo_getPerms_basic.phpt @@ -0,0 +1,30 @@ +--TEST-- +SPL: Spl File Info test getPerms +--CREDITS-- +Cesare D'Amico +Andrea Giorgini +Filippo De Santis +Daniel Londero +Francesco Trucchia +Jacopo Romei +#Test Fest Cesena (Italy) on 2009-06-20 +--SKIPIF-- + +--FILE-- +getPerms() == 0100557); + +?> +--CLEAN-- + +--EXPECTF-- +bool(true) diff --git a/ext/spl/tests/SplFileInfo_getPerms_error.phpt b/ext/spl/tests/SplFileInfo_getPerms_error.phpt new file mode 100644 index 000000000..8e05cdf8d --- /dev/null +++ b/ext/spl/tests/SplFileInfo_getPerms_error.phpt @@ -0,0 +1,28 @@ +--TEST-- +SPL: Spl File Info test getPerms +--CREDITS-- +Cesare D'Amico +Andrea Giorgini +Filippo De Santis +Daniel Londero +Francesco Trucchia +Jacopo Romei +#Test Fest Cesena (Italy) on 2009-06-20 +--SKIPIF-- + +--FILE-- +getPerms() == 0100557); +?> + +--EXPECTF-- +Fatal error: Uncaught exception 'RuntimeException' with message 'SplFileInfo::getPerms(): stat failed for %s' in %s +Stack trace: +#0 %s: SplFileInfo->getPerms() +#1 {main} + thrown in %s diff --git a/ext/spl/tests/SplFixedArray__construct_param_array.phpt b/ext/spl/tests/SplFixedArray__construct_param_array.phpt index ca0cc197d..d63d7cca5 100644 --- a/ext/spl/tests/SplFixedArray__construct_param_array.phpt +++ b/ext/spl/tests/SplFixedArray__construct_param_array.phpt @@ -1,12 +1,12 @@ ---TEST-- -SplFixedArray::__construct() with array passed as integer. ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- - ---EXPECTF-- +--TEST-- +SplFixedArray::__construct() with array passed as integer. +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- + +--EXPECTF-- Warning: SplFixedArray::__construct() expects parameter 1 to be long, array given in %s on line %d \ No newline at end of file diff --git a/ext/spl/tests/SplFixedArray__construct_param_float.phpt b/ext/spl/tests/SplFixedArray__construct_param_float.phpt index 833738699..670a1095e 100644 --- a/ext/spl/tests/SplFixedArray__construct_param_float.phpt +++ b/ext/spl/tests/SplFixedArray__construct_param_float.phpt @@ -1,14 +1,14 @@ ---TEST-- -SplFixedArray::__construct() with float passed as parameter. ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- -getSize(); - -?> ---EXPECT-- +--TEST-- +SplFixedArray::__construct() with float passed as parameter. +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- +getSize(); + +?> +--EXPECT-- 3 \ No newline at end of file diff --git a/ext/spl/tests/SplFixedArray__construct_param_null.phpt b/ext/spl/tests/SplFixedArray__construct_param_null.phpt index 2b631c537..3b1543d4d 100644 --- a/ext/spl/tests/SplFixedArray__construct_param_null.phpt +++ b/ext/spl/tests/SplFixedArray__construct_param_null.phpt @@ -1,16 +1,16 @@ ---TEST-- -SplFixedArray::__construct() with null passed as parameter. ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- - ---EXPECTF-- -SplFixedArray Object -( +--TEST-- +SplFixedArray::__construct() with null passed as parameter. +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- + +--EXPECTF-- +SplFixedArray Object +( ) \ No newline at end of file diff --git a/ext/spl/tests/SplFixedArray__construct_param_string.phpt b/ext/spl/tests/SplFixedArray__construct_param_string.phpt index 56a2dd809..3a7e734b0 100644 --- a/ext/spl/tests/SplFixedArray__construct_param_string.phpt +++ b/ext/spl/tests/SplFixedArray__construct_param_string.phpt @@ -1,12 +1,12 @@ ---TEST-- -SplFixedArray::__construct() with string passed as parameter. ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- - ---EXPECTF-- -Warning: SplFixedArray::__construct() expects parameter 1 to be long, %unicode_string_optional% given in %s on line %d +--TEST-- +SplFixedArray::__construct() with string passed as parameter. +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- + +--EXPECTF-- +Warning: SplFixedArray::__construct() expects parameter 1 to be long, %unicode_string_optional% given in %s on line %d diff --git a/ext/spl/tests/SplFixedArray_construct_param_SplFixedArray.phpt b/ext/spl/tests/SplFixedArray_construct_param_SplFixedArray.phpt index ae0f9e998..6582f847b 100644 --- a/ext/spl/tests/SplFixedArray_construct_param_SplFixedArray.phpt +++ b/ext/spl/tests/SplFixedArray_construct_param_SplFixedArray.phpt @@ -1,13 +1,13 @@ ---TEST-- -Create an SplFixedArray using an SplFixedArray object. ---CREDITS-- -Philip Norton philipnorton42@gmail.com ---FILE-- - ---EXPECTF-- -Warning: SplFixedArray::__construct() expects parameter 1 to be long, object given in %s on line %d -object(SplFixedArray)#1 (0) { +--TEST-- +Create an SplFixedArray using an SplFixedArray object. +--CREDITS-- +Philip Norton philipnorton42@gmail.com +--FILE-- + +--EXPECTF-- +Warning: SplFixedArray::__construct() expects parameter 1 to be long, object given in %s on line %d +object(SplFixedArray)#1 (0) { } \ No newline at end of file diff --git a/ext/spl/tests/SplFixedArray_count_param_int.phpt b/ext/spl/tests/SplFixedArray_count_param_int.phpt index db379906a..108bb2db6 100644 --- a/ext/spl/tests/SplFixedArray_count_param_int.phpt +++ b/ext/spl/tests/SplFixedArray_count_param_int.phpt @@ -1,11 +1,11 @@ ---TEST-- -Creates array, uses the count function to get the size of the array, but passes a parameter. ---CREDITS-- -Philip Norton philipnorton42@gmail.com ---FILE-- -count(3); -?> ---EXPECTF-- +--TEST-- +Creates array, uses the count function to get the size of the array, but passes a parameter. +--CREDITS-- +Philip Norton philipnorton42@gmail.com +--FILE-- +count(3); +?> +--EXPECTF-- Warning: SplFixedArray::count() expects exactly 0 parameters, 1 given in %s on line %d \ No newline at end of file diff --git a/ext/spl/tests/SplFixedArray_current_param.phpt b/ext/spl/tests/SplFixedArray_current_param.phpt index 46df10d73..71f5d3a52 100644 --- a/ext/spl/tests/SplFixedArray_current_param.phpt +++ b/ext/spl/tests/SplFixedArray_current_param.phpt @@ -1,24 +1,24 @@ ---TEST-- -SplFixedArray::current() with a parameter. *BUG* ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- -current( array("this","should","not","execute") ); -} - -?> ---EXPECTF-- -Warning: SplFixedArray::current() expects exactly 0 parameters, 1 given in %s on line %d - -Warning: SplFixedArray::current() expects exactly 0 parameters, 1 given in %s on line %d - -Warning: SplFixedArray::current() expects exactly 0 parameters, 1 given in %s on line %d +--TEST-- +SplFixedArray::current() with a parameter. *BUG* +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- +current( array("this","should","not","execute") ); +} + +?> +--EXPECTF-- +Warning: SplFixedArray::current() expects exactly 0 parameters, 1 given in %s on line %d + +Warning: SplFixedArray::current() expects exactly 0 parameters, 1 given in %s on line %d + +Warning: SplFixedArray::current() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplFixedArray_fromarray_indexes.phpt b/ext/spl/tests/SplFixedArray_fromarray_indexes.phpt index faac20f03..034d45731 100644 --- a/ext/spl/tests/SplFixedArray_fromarray_indexes.phpt +++ b/ext/spl/tests/SplFixedArray_fromarray_indexes.phpt @@ -1,22 +1,22 @@ ---TEST-- -Create a SplFixedArray from an array using the fromArray() function use the default behaviour of preserve the indexes. ---CREDITS-- -Philip Norton philipnorton42@gmail.com ---FILE-- - 1, - 2 => '2', - 3 => false)); -var_dump($array); -?> ---EXPECTF-- -object(SplFixedArray)#1 (4) { - [0]=> - NULL - [1]=> - int(1) - [2]=> - %string|unicode%(1) "2" - [3]=> - bool(false) -} +--TEST-- +Create a SplFixedArray from an array using the fromArray() function use the default behaviour of preserve the indexes. +--CREDITS-- +Philip Norton philipnorton42@gmail.com +--FILE-- + 1, + 2 => '2', + 3 => false)); +var_dump($array); +?> +--EXPECTF-- +object(SplFixedArray)#1 (4) { + [0]=> + NULL + [1]=> + int(1) + [2]=> + %string|unicode%(1) "2" + [3]=> + bool(false) +} diff --git a/ext/spl/tests/SplFixedArray_fromarray_non_indexes.phpt b/ext/spl/tests/SplFixedArray_fromarray_non_indexes.phpt index a78293bc5..ecae2ab76 100644 --- a/ext/spl/tests/SplFixedArray_fromarray_non_indexes.phpt +++ b/ext/spl/tests/SplFixedArray_fromarray_non_indexes.phpt @@ -1,21 +1,21 @@ ---TEST-- -Create a SplFixedArray from an array using the fromArray() function don't try to preserve the indexes. ---CREDITS-- -Philip Norton philipnorton42@gmail.com ---FILE-- - 1, - 2 => '2', - 3 => false), - false); -var_dump($array); -?> ---EXPECTF-- -object(SplFixedArray)#1 (3) { - [0]=> - int(1) - [1]=> - %string|unicode%(1) "2" - [2]=> - bool(false) -} +--TEST-- +Create a SplFixedArray from an array using the fromArray() function don't try to preserve the indexes. +--CREDITS-- +Philip Norton philipnorton42@gmail.com +--FILE-- + 1, + 2 => '2', + 3 => false), + false); +var_dump($array); +?> +--EXPECTF-- +object(SplFixedArray)#1 (3) { + [0]=> + int(1) + [1]=> + %string|unicode%(1) "2" + [2]=> + bool(false) +} diff --git a/ext/spl/tests/SplFixedArray_fromarray_param_boolean.phpt b/ext/spl/tests/SplFixedArray_fromarray_param_boolean.phpt index 36a4ab1eb..80d966997 100644 --- a/ext/spl/tests/SplFixedArray_fromarray_param_boolean.phpt +++ b/ext/spl/tests/SplFixedArray_fromarray_param_boolean.phpt @@ -1,10 +1,10 @@ ---TEST-- -Tries to create a SplFixedArray using a boolean value. ---CREDITS-- -Philip Norton philipnorton42@gmail.com ---FILE-- - ---EXPECTF-- +--TEST-- +Tries to create a SplFixedArray using a boolean value. +--CREDITS-- +Philip Norton philipnorton42@gmail.com +--FILE-- + +--EXPECTF-- Warning: SplFixedArray::fromArray() expects parameter 1 to be array, boolean given in %s on line %d \ No newline at end of file diff --git a/ext/spl/tests/SplFixedArray_fromarray_param_multiarray.phpt b/ext/spl/tests/SplFixedArray_fromarray_param_multiarray.phpt index 226b38bda..f57fe78fb 100644 --- a/ext/spl/tests/SplFixedArray_fromarray_param_multiarray.phpt +++ b/ext/spl/tests/SplFixedArray_fromarray_param_multiarray.phpt @@ -1,17 +1,17 @@ ---TEST-- -Tries to create a SplFixedArray using the fromArray() function and a multi dimentional array. ---CREDITS-- -Philip Norton philipnorton42@gmail.com ---FILE-- - ---EXPECTF-- -object(SplFixedArray)#1 (1) { - [0]=> - array(1) { - [0]=> - %string|unicode%(1) "1" - } -} +--TEST-- +Tries to create a SplFixedArray using the fromArray() function and a multi dimentional array. +--CREDITS-- +Philip Norton philipnorton42@gmail.com +--FILE-- + +--EXPECTF-- +object(SplFixedArray)#1 (1) { + [0]=> + array(1) { + [0]=> + %string|unicode%(1) "1" + } +} diff --git a/ext/spl/tests/SplFixedArray_getSize_pass_param.phpt b/ext/spl/tests/SplFixedArray_getSize_pass_param.phpt index d60c4bd8f..ef4f40c32 100644 --- a/ext/spl/tests/SplFixedArray_getSize_pass_param.phpt +++ b/ext/spl/tests/SplFixedArray_getSize_pass_param.phpt @@ -1,12 +1,12 @@ ---TEST-- -SplFixedArray::getSize() pass a parameter when none are expected ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -getSize(3); -?> ---EXPECTF-- -Warning: SplFixedArray::getSize() expects exactly 0 parameters, 1 given in %s on line %d -*test* +--TEST-- +SplFixedArray::getSize() pass a parameter when none are expected +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +getSize(3); +?> +--EXPECTF-- +Warning: SplFixedArray::getSize() expects exactly 0 parameters, 1 given in %s on line %d +*test* diff --git a/ext/spl/tests/SplFixedArray_key_param.phpt b/ext/spl/tests/SplFixedArray_key_param.phpt index a0b24058f..300e6df79 100644 --- a/ext/spl/tests/SplFixedArray_key_param.phpt +++ b/ext/spl/tests/SplFixedArray_key_param.phpt @@ -1,24 +1,24 @@ ---TEST-- -SplFixedArray::key() with a parameter passed. This is a bug and an error should be called. ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- -key( array("this","should","not","execute") ); -} - -?> ---EXPECTF-- -Warning: SplFixedArray::key() expects exactly 0 parameters, 1 given in %s on line %d - -Warning: SplFixedArray::key() expects exactly 0 parameters, 1 given in %s on line %d - -Warning: SplFixedArray::key() expects exactly 0 parameters, 1 given in %s on line %d +--TEST-- +SplFixedArray::key() with a parameter passed. This is a bug and an error should be called. +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- +key( array("this","should","not","execute") ); +} + +?> +--EXPECTF-- +Warning: SplFixedArray::key() expects exactly 0 parameters, 1 given in %s on line %d + +Warning: SplFixedArray::key() expects exactly 0 parameters, 1 given in %s on line %d + +Warning: SplFixedArray::key() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplFixedArray_key_setsize.phpt b/ext/spl/tests/SplFixedArray_key_setsize.phpt index 9562a6025..97e48115f 100644 --- a/ext/spl/tests/SplFixedArray_key_setsize.phpt +++ b/ext/spl/tests/SplFixedArray_key_setsize.phpt @@ -1,20 +1,20 @@ ---TEST-- -SplFixedArray::key() when the array has a size higher than the amount of values specified. ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- -key( ); -} - -?> ---EXPECT-- +--TEST-- +SplFixedArray::key() when the array has a size higher than the amount of values specified. +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- +key( ); +} + +?> +--EXPECT-- 0123 \ No newline at end of file diff --git a/ext/spl/tests/SplFixedArray_next_param.phpt b/ext/spl/tests/SplFixedArray_next_param.phpt index f7a40c107..5e8cb633b 100644 --- a/ext/spl/tests/SplFixedArray_next_param.phpt +++ b/ext/spl/tests/SplFixedArray_next_param.phpt @@ -1,18 +1,18 @@ ---TEST-- -SplFixedArray::next() with a parameter. *BUG* ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- -next( "invalid" ); - -?> ---EXPECTF-- -Warning: SplFixedArray::next() expects exactly 0 parameters, 1 given in %s on line %d +--TEST-- +SplFixedArray::next() with a parameter. *BUG* +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- +next( "invalid" ); + +?> +--EXPECTF-- +Warning: SplFixedArray::next() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplFixedArray_rewind_param.phpt b/ext/spl/tests/SplFixedArray_rewind_param.phpt index 5d1721946..7002efb31 100644 --- a/ext/spl/tests/SplFixedArray_rewind_param.phpt +++ b/ext/spl/tests/SplFixedArray_rewind_param.phpt @@ -1,18 +1,18 @@ ---TEST-- -SplFixedArray::rewind() with a parameter. *BUG* ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- -rewind( "invalid" ); - -?> ---EXPECTF-- -Warning: SplFixedArray::rewind() expects exactly 0 parameters, 1 given in %s on line %d +--TEST-- +SplFixedArray::rewind() with a parameter. *BUG* +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- +rewind( "invalid" ); + +?> +--EXPECTF-- +Warning: SplFixedArray::rewind() expects exactly 0 parameters, 1 given in %s on line %d diff --git a/ext/spl/tests/SplFixedArray_setSize_filled_to_smaller.phpt b/ext/spl/tests/SplFixedArray_setSize_filled_to_smaller.phpt index 46922b838..a46074760 100644 --- a/ext/spl/tests/SplFixedArray_setSize_filled_to_smaller.phpt +++ b/ext/spl/tests/SplFixedArray_setSize_filled_to_smaller.phpt @@ -1,22 +1,22 @@ ---TEST-- -Create array, fills it with and resizes it to lower value. ---CREDITS-- -Philip Norton philipnorton42@gmail.com ---FILE-- -setSize(2); -var_dump($array); -?> ---EXPECT-- -object(SplFixedArray)#1 (2) { - [0]=> - int(1) - [1]=> - int(1) +--TEST-- +Create array, fills it with and resizes it to lower value. +--CREDITS-- +Philip Norton philipnorton42@gmail.com +--FILE-- +setSize(2); +var_dump($array); +?> +--EXPECT-- +object(SplFixedArray)#1 (2) { + [0]=> + int(1) + [1]=> + int(1) } \ No newline at end of file diff --git a/ext/spl/tests/SplFixedArray_setSize_param_array.phpt b/ext/spl/tests/SplFixedArray_setSize_param_array.phpt index 6967e47bd..269a45de1 100644 --- a/ext/spl/tests/SplFixedArray_setSize_param_array.phpt +++ b/ext/spl/tests/SplFixedArray_setSize_param_array.phpt @@ -1,18 +1,18 @@ ---TEST-- -SplFixedArray::setSize() with an array parameter ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -setSize(array()); -var_dump($fixed_array); -?> ---EXPECTF-- -Warning: SplFixedArray::setSize() expects parameter 1 to be long, array given in %s on line %d -object(SplFixedArray)#1 (2) { - [0]=> - NULL - [1]=> - NULL -} +--TEST-- +SplFixedArray::setSize() with an array parameter +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +setSize(array()); +var_dump($fixed_array); +?> +--EXPECTF-- +Warning: SplFixedArray::setSize() expects parameter 1 to be long, array given in %s on line %d +object(SplFixedArray)#1 (2) { + [0]=> + NULL + [1]=> + NULL +} diff --git a/ext/spl/tests/SplFixedArray_setSize_param_float.phpt b/ext/spl/tests/SplFixedArray_setSize_param_float.phpt index 2cafa8467..c65686c61 100644 --- a/ext/spl/tests/SplFixedArray_setSize_param_float.phpt +++ b/ext/spl/tests/SplFixedArray_setSize_param_float.phpt @@ -1,19 +1,19 @@ ---TEST-- -SplFixedArray::setSize() with a float param ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -setSize(3.14159); -var_dump($fixed_array); -?> ---EXPECTF-- -object(SplFixedArray)#1 (3) { - [0]=> - NULL - [1]=> - NULL - [2]=> - NULL -} +--TEST-- +SplFixedArray::setSize() with a float param +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +setSize(3.14159); +var_dump($fixed_array); +?> +--EXPECTF-- +object(SplFixedArray)#1 (3) { + [0]=> + NULL + [1]=> + NULL + [2]=> + NULL +} diff --git a/ext/spl/tests/SplFixedArray_setSize_param_null.phpt b/ext/spl/tests/SplFixedArray_setSize_param_null.phpt index d2dec401d..ddb37be9f 100644 --- a/ext/spl/tests/SplFixedArray_setSize_param_null.phpt +++ b/ext/spl/tests/SplFixedArray_setSize_param_null.phpt @@ -1,13 +1,13 @@ ---TEST-- -SplFixedArray::setSize() with a null parameter ---CREDITS-- -PHPNW Testfest 2009 - Adrian Hardy ---FILE-- -setSize(null); -var_dump($fixed_array); -?> ---EXPECT-- -object(SplFixedArray)#1 (0) { -} +--TEST-- +SplFixedArray::setSize() with a null parameter +--CREDITS-- +PHPNW Testfest 2009 - Adrian Hardy +--FILE-- +setSize(null); +var_dump($fixed_array); +?> +--EXPECT-- +object(SplFixedArray)#1 (0) { +} diff --git a/ext/spl/tests/SplFixedArray_setsize_grow.phpt b/ext/spl/tests/SplFixedArray_setsize_grow.phpt index 0c9f6d83e..418d1ac37 100644 --- a/ext/spl/tests/SplFixedArray_setsize_grow.phpt +++ b/ext/spl/tests/SplFixedArray_setsize_grow.phpt @@ -1,30 +1,30 @@ ---TEST-- -SplFixedArray::setSize() grow ---CREDITS-- -PHPNW Test Fest 2009 - Jordan Hatch ---FILE-- -setSize(4); - -$array[2] = "Value 3"; -$array[3] = "Value 4"; - -print_r($array); - -?> ---EXPECT-- -SplFixedArray Object -( - [0] => Value 1 - [1] => Value 2 - [2] => Value 3 - [3] => Value 4 +--TEST-- +SplFixedArray::setSize() grow +--CREDITS-- +PHPNW Test Fest 2009 - Jordan Hatch +--FILE-- +setSize(4); + +$array[2] = "Value 3"; +$array[3] = "Value 4"; + +print_r($array); + +?> +--EXPECT-- +SplFixedArray Object +( + [0] => Value 1 + [1] => Value 2 + [2] => Value 3 + [3] => Value 4 ) \ No newline at end of file diff --git a/ext/spl/tests/SplFixedarray_offsetExists_larger.phpt b/ext/spl/tests/SplFixedarray_offsetExists_larger.phpt deleted file mode 100644 index 9449d64d8..000000000 --- a/ext/spl/tests/SplFixedarray_offsetExists_larger.phpt +++ /dev/null @@ -1,15 +0,0 @@ ---TEST-- -Checks that offsetExists() does not accept a value larger than the array. ---CREDITS-- - PHPNW Test Fest 2009 - Rick Ogden ---FILE-- -offsetExists(4)); -?> ---EXPECT-- -bool(false) diff --git a/ext/spl/tests/SplObjectStorage_var_dump.phpt b/ext/spl/tests/SplObjectStorage_var_dump.phpt new file mode 100644 index 000000000..c1c7158ec --- /dev/null +++ b/ext/spl/tests/SplObjectStorage_var_dump.phpt @@ -0,0 +1,35 @@ +--TEST-- +SPL: SplObjectStorage: recursive var_dump +--FILE-- + + array(1) { + ["%s"]=> + array(2) { + ["obj"]=> + object(stdClass)#2 (0) { + } + ["inf"]=> + object(SplObjectStorage)#1 (1) { + ["storage":"SplObjectStorage":private]=> + array(1) { + ["%s"]=> + array(2) { + ["obj"]=> + object(stdClass)#2 (0) { + } + ["inf"]=> + *RECURSION* + } + } + } + } + } +} diff --git a/ext/spl/tests/arrayObject___construct_basic1.phpt b/ext/spl/tests/arrayObject___construct_basic1.phpt index 2134caaab..f192ccab4 100644 --- a/ext/spl/tests/arrayObject___construct_basic1.phpt +++ b/ext/spl/tests/arrayObject___construct_basic1.phpt @@ -1,22 +1,22 @@ ---TEST-- -SPL: ArrayObject::__construct basic usage. ---FILE-- - No arguments:\n"; -var_dump(new ArrayObject()); - -echo "--> Object argument:\n"; -$a = new stdClass; -$a->p = 'hello'; -var_dump(new ArrayObject($a)); - -echo "--> Array argument:\n"; -var_dump(new ArrayObject(array('key1' => 'val1'))); - -echo "--> Nested ArrayObject argument:\n"; -var_dump(new ArrayObject(new ArrayObject($a))); -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject::__construct basic usage. +--FILE-- + No arguments:\n"; +var_dump(new ArrayObject()); + +echo "--> Object argument:\n"; +$a = new stdClass; +$a->p = 'hello'; +var_dump(new ArrayObject($a)); + +echo "--> Array argument:\n"; +var_dump(new ArrayObject(array('key1' => 'val1'))); + +echo "--> Nested ArrayObject argument:\n"; +var_dump(new ArrayObject(new ArrayObject($a))); +?> +--EXPECTF-- --> No arguments: object(ArrayObject)#1 (1) { ["storage":"ArrayObject":private]=> diff --git a/ext/spl/tests/arrayObject___construct_basic2.phpt b/ext/spl/tests/arrayObject___construct_basic2.phpt index e5200b32f..9ff0e4257 100644 --- a/ext/spl/tests/arrayObject___construct_basic2.phpt +++ b/ext/spl/tests/arrayObject___construct_basic2.phpt @@ -1,52 +1,52 @@ ---TEST-- -SPL: ArrayObject::__construct basic usage. ---FILE-- - Access prop on instance of ArrayObject:\n"; -$c = new C; -$ao = new ArrayObject($c); -testAccess($c, $ao); - -echo "\n--> Access prop on instance of MyArrayObject:\n"; -$c = new C; -$ao = new MyArrayObject($c); -testAccess($c, $ao); - -function testAccess($c, $ao) { - echo " - Iteration:\n"; - foreach ($ao as $key=>$value) { - echo " $key=>$value\n"; - } - - echo " - Read:\n"; - @var_dump($ao->prop, $ao['prop']); - - echo " - Write:\n"; - $ao->prop = 'changed1'; - $ao['prop'] = 'changed2'; - var_dump($ao->prop, $ao['prop']); - - echo " - Isset:\n"; - var_dump(isset($ao->prop), isset($ao['prop'])); - - echo " - Unset:\n"; - unset($ao->prop); - unset($ao['prop']); - var_dump($ao->prop, $ao['prop']); - - echo " - After:\n"; - var_dump($ao, $c); -} -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject::__construct basic usage. +--FILE-- + Access prop on instance of ArrayObject:\n"; +$c = new C; +$ao = new ArrayObject($c); +testAccess($c, $ao); + +echo "\n--> Access prop on instance of MyArrayObject:\n"; +$c = new C; +$ao = new MyArrayObject($c); +testAccess($c, $ao); + +function testAccess($c, $ao) { + echo " - Iteration:\n"; + foreach ($ao as $key=>$value) { + echo " $key=>$value\n"; + } + + echo " - Read:\n"; + @var_dump($ao->prop, $ao['prop']); + + echo " - Write:\n"; + $ao->prop = 'changed1'; + $ao['prop'] = 'changed2'; + var_dump($ao->prop, $ao['prop']); + + echo " - Isset:\n"; + var_dump(isset($ao->prop), isset($ao['prop'])); + + echo " - Unset:\n"; + unset($ao->prop); + unset($ao['prop']); + var_dump($ao->prop, $ao['prop']); + + echo " - After:\n"; + var_dump($ao, $c); +} +?> +--EXPECTF-- --> Access prop on instance of ArrayObject: - Iteration: prop=>C::prop.orig diff --git a/ext/spl/tests/arrayObject___construct_basic3.phpt b/ext/spl/tests/arrayObject___construct_basic3.phpt index 791681756..1abd1a1ab 100644 --- a/ext/spl/tests/arrayObject___construct_basic3.phpt +++ b/ext/spl/tests/arrayObject___construct_basic3.phpt @@ -1,52 +1,52 @@ ---TEST-- -SPL: ArrayObject::__construct basic usage with ArrayObject::STD_PROP_LIST. ---FILE-- - Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST:\n"; -$c = new C; -$ao = new ArrayObject($c, ArrayObject::STD_PROP_LIST); -testAccess($c, $ao); - -echo "\n--> Access prop on instance of MyArrayObject with ArrayObject::STD_PROP_LIST:\n"; -$c = new C; -$ao = new MyArrayObject($c, ArrayObject::STD_PROP_LIST); -testAccess($c, $ao); - -function testAccess($c, $ao) { - echo " - Iteration:\n"; - foreach ($ao as $key=>$value) { - echo " $key=>$value\n"; - } - - echo " - Read:\n"; - @var_dump($ao->prop, $ao['prop']); - - echo " - Write:\n"; - $ao->prop = 'changed1'; - $ao['prop'] = 'changed2'; - var_dump($ao->prop, $ao['prop']); - - echo " - Isset:\n"; - var_dump(isset($ao->prop), isset($ao['prop'])); - - echo " - Unset:\n"; - unset($ao->prop); - unset($ao['prop']); - var_dump($ao->prop, $ao['prop']); - - echo " - After:\n"; - var_dump($ao, $c); -} -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject::__construct basic usage with ArrayObject::STD_PROP_LIST. +--FILE-- + Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST:\n"; +$c = new C; +$ao = new ArrayObject($c, ArrayObject::STD_PROP_LIST); +testAccess($c, $ao); + +echo "\n--> Access prop on instance of MyArrayObject with ArrayObject::STD_PROP_LIST:\n"; +$c = new C; +$ao = new MyArrayObject($c, ArrayObject::STD_PROP_LIST); +testAccess($c, $ao); + +function testAccess($c, $ao) { + echo " - Iteration:\n"; + foreach ($ao as $key=>$value) { + echo " $key=>$value\n"; + } + + echo " - Read:\n"; + @var_dump($ao->prop, $ao['prop']); + + echo " - Write:\n"; + $ao->prop = 'changed1'; + $ao['prop'] = 'changed2'; + var_dump($ao->prop, $ao['prop']); + + echo " - Isset:\n"; + var_dump(isset($ao->prop), isset($ao['prop'])); + + echo " - Unset:\n"; + unset($ao->prop); + unset($ao['prop']); + var_dump($ao->prop, $ao['prop']); + + echo " - After:\n"; + var_dump($ao, $c); +} +?> +--EXPECTF-- --> Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST: - Iteration: prop=>C::prop.orig diff --git a/ext/spl/tests/arrayObject___construct_basic4.phpt b/ext/spl/tests/arrayObject___construct_basic4.phpt index ec524712a..80f5e0861 100644 --- a/ext/spl/tests/arrayObject___construct_basic4.phpt +++ b/ext/spl/tests/arrayObject___construct_basic4.phpt @@ -1,52 +1,52 @@ ---TEST-- -SPL: ArrayObject::__construct basic usage with ArrayObject::ARRAY_AS_PROPS. Currently fails on php.net due to bug 45622. ---FILE-- - Access prop on instance of ArrayObject with ArrayObject::ARRAY_AS_PROPS:\n"; -$c = new C; -$ao = new ArrayObject($c, ArrayObject::ARRAY_AS_PROPS); -testAccess($c, $ao); - -echo "\n--> Access prop on instance of MyArrayObject with ArrayObject::ARRAY_AS_PROPS:\n"; -$c = new C; -$ao = new MyArrayObject($c, ArrayObject::ARRAY_AS_PROPS); -testAccess($c, $ao); - -function testAccess($c, $ao) { - echo " - Iteration:\n"; - foreach ($ao as $key=>$value) { - echo " $key=>$value\n"; - } - - echo " - Read:\n"; - @var_dump($ao->prop, $ao['prop']); - - echo " - Write:\n"; - $ao->prop = 'changed1'; - $ao['prop'] = 'changed2'; - var_dump($ao->prop, $ao['prop']); - - echo " - Isset:\n"; - var_dump(isset($ao->prop), isset($ao['prop'])); - - echo " - Unset:\n"; - unset($ao->prop); - unset($ao['prop']); - var_dump($ao->prop, $ao['prop']); - - echo " - After:\n"; - var_dump($ao, $c); -} -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject::__construct basic usage with ArrayObject::ARRAY_AS_PROPS. Currently fails on php.net due to bug 45622. +--FILE-- + Access prop on instance of ArrayObject with ArrayObject::ARRAY_AS_PROPS:\n"; +$c = new C; +$ao = new ArrayObject($c, ArrayObject::ARRAY_AS_PROPS); +testAccess($c, $ao); + +echo "\n--> Access prop on instance of MyArrayObject with ArrayObject::ARRAY_AS_PROPS:\n"; +$c = new C; +$ao = new MyArrayObject($c, ArrayObject::ARRAY_AS_PROPS); +testAccess($c, $ao); + +function testAccess($c, $ao) { + echo " - Iteration:\n"; + foreach ($ao as $key=>$value) { + echo " $key=>$value\n"; + } + + echo " - Read:\n"; + @var_dump($ao->prop, $ao['prop']); + + echo " - Write:\n"; + $ao->prop = 'changed1'; + $ao['prop'] = 'changed2'; + var_dump($ao->prop, $ao['prop']); + + echo " - Isset:\n"; + var_dump(isset($ao->prop), isset($ao['prop'])); + + echo " - Unset:\n"; + unset($ao->prop); + unset($ao['prop']); + var_dump($ao->prop, $ao['prop']); + + echo " - After:\n"; + var_dump($ao, $c); +} +?> +--EXPECTF-- --> Access prop on instance of ArrayObject with ArrayObject::ARRAY_AS_PROPS: - Iteration: prop=>C::prop.orig diff --git a/ext/spl/tests/arrayObject___construct_basic5.phpt b/ext/spl/tests/arrayObject___construct_basic5.phpt index db4d6abd9..5368d250a 100644 --- a/ext/spl/tests/arrayObject___construct_basic5.phpt +++ b/ext/spl/tests/arrayObject___construct_basic5.phpt @@ -1,52 +1,52 @@ ---TEST-- -SPL: ArrayObject::__construct basic usage with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS. Currently fails on php.net due to bug 45622. ---FILE-- - Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS:\n"; -$c = new C; -$ao = new ArrayObject($c, ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS); -testAccess($c, $ao); - -echo "\n--> Access prop on instance of MyArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS:\n"; -$c = new C; -$ao = new MyArrayObject($c, ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS); -testAccess($c, $ao); - -function testAccess($c, $ao) { - echo " - Iteration:\n"; - foreach ($ao as $key=>$value) { - echo " $key=>$value\n"; - } - - echo " - Read:\n"; - @var_dump($ao->prop, $ao['prop']); - - echo " - Write:\n"; - $ao->prop = 'changed1'; - $ao['prop'] = 'changed2'; - var_dump($ao->prop, $ao['prop']); - - echo " - Isset:\n"; - var_dump(isset($ao->prop), isset($ao['prop'])); - - echo " - Unset:\n"; - unset($ao->prop); - unset($ao['prop']); - var_dump($ao->prop, $ao['prop']); - - echo " - After:\n"; - var_dump($ao, $c); -} -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject::__construct basic usage with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS. Currently fails on php.net due to bug 45622. +--FILE-- + Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS:\n"; +$c = new C; +$ao = new ArrayObject($c, ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS); +testAccess($c, $ao); + +echo "\n--> Access prop on instance of MyArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS:\n"; +$c = new C; +$ao = new MyArrayObject($c, ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS); +testAccess($c, $ao); + +function testAccess($c, $ao) { + echo " - Iteration:\n"; + foreach ($ao as $key=>$value) { + echo " $key=>$value\n"; + } + + echo " - Read:\n"; + @var_dump($ao->prop, $ao['prop']); + + echo " - Write:\n"; + $ao->prop = 'changed1'; + $ao['prop'] = 'changed2'; + var_dump($ao->prop, $ao['prop']); + + echo " - Isset:\n"; + var_dump(isset($ao->prop), isset($ao['prop'])); + + echo " - Unset:\n"; + unset($ao->prop); + unset($ao['prop']); + var_dump($ao->prop, $ao['prop']); + + echo " - After:\n"; + var_dump($ao, $c); +} +?> +--EXPECTF-- --> Access prop on instance of ArrayObject with ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS: - Iteration: prop=>C::prop.orig diff --git a/ext/spl/tests/arrayObject___construct_basic6.phpt b/ext/spl/tests/arrayObject___construct_basic6.phpt index c57a9fc3f..1c7ec3636 100644 --- a/ext/spl/tests/arrayObject___construct_basic6.phpt +++ b/ext/spl/tests/arrayObject___construct_basic6.phpt @@ -1,27 +1,27 @@ ---TEST-- -SPL: ArrayObject::__construct: check impact of ArrayObject::STD_PROP_LIST on var_dump. ---FILE-- -p = 1; -var_dump($ao); - -$ao = new ArrayObject(array(1,2,3), ArrayObject::STD_PROP_LIST); -$ao->p = 1; -var_dump($ao); - -$ao = new MyArrayObject(array(1,2,3)); -var_dump($ao); - -$ao = new MyArrayObject(array(1,2,3), ArrayObject::STD_PROP_LIST); -var_dump($ao); -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject::__construct: check impact of ArrayObject::STD_PROP_LIST on var_dump. +--FILE-- +p = 1; +var_dump($ao); + +$ao = new ArrayObject(array(1,2,3), ArrayObject::STD_PROP_LIST); +$ao->p = 1; +var_dump($ao); + +$ao = new MyArrayObject(array(1,2,3)); +var_dump($ao); + +$ao = new MyArrayObject(array(1,2,3), ArrayObject::STD_PROP_LIST); +var_dump($ao); +?> +--EXPECTF-- object(ArrayObject)#1 (2) { ["p"]=> int(1) diff --git a/ext/spl/tests/arrayObject___construct_error1.phpt b/ext/spl/tests/arrayObject___construct_error1.phpt index 07e08ccc7..21c312d2d 100644 --- a/ext/spl/tests/arrayObject___construct_error1.phpt +++ b/ext/spl/tests/arrayObject___construct_error1.phpt @@ -1,25 +1,25 @@ ---TEST-- -SPL: ArrayObject::__construct with bad iterator. ---FILE-- -p = 1; -try { - var_dump(new ArrayObject($a, 0, "Exception")); -} catch (InvalidArgumentException $e) { - echo $e->getMessage() . "(" . $e->getLine() . ")\n"; -} - -echo "Non-existent class:\n"; -try { - var_dump(new ArrayObject(new stdClass, 0, "nonExistentClassName")); -} catch (InvalidArgumentException $e) { - echo $e->getMessage() . "(" . $e->getLine() . ")\n"; -} -?> ---EXPECTF-- -Bad iterator type: -ArrayObject::__construct() expects parameter 3 to be a class name derived from Iterator, 'Exception' given(6) -Non-existent class: +--TEST-- +SPL: ArrayObject::__construct with bad iterator. +--FILE-- +p = 1; +try { + var_dump(new ArrayObject($a, 0, "Exception")); +} catch (InvalidArgumentException $e) { + echo $e->getMessage() . "(" . $e->getLine() . ")\n"; +} + +echo "Non-existent class:\n"; +try { + var_dump(new ArrayObject(new stdClass, 0, "nonExistentClassName")); +} catch (InvalidArgumentException $e) { + echo $e->getMessage() . "(" . $e->getLine() . ")\n"; +} +?> +--EXPECTF-- +Bad iterator type: +ArrayObject::__construct() expects parameter 3 to be a class name derived from Iterator, 'Exception' given(6) +Non-existent class: ArrayObject::__construct() expects parameter 3 to be a class name derived from Iterator, 'nonExistentClassName' given(13) diff --git a/ext/spl/tests/arrayObject___construct_error2.phpt b/ext/spl/tests/arrayObject___construct_error2.phpt index 80b68d6b8..850a2cb3f 100644 --- a/ext/spl/tests/arrayObject___construct_error2.phpt +++ b/ext/spl/tests/arrayObject___construct_error2.phpt @@ -1,22 +1,22 @@ ---TEST-- -SPL: ArrayObject::__construct with too many arguments. ---FILE-- -getMessage() . "(" . $e->getLine() . ")\n"; -} -?> ---EXPECTF-- -Too many arguments: +--TEST-- +SPL: ArrayObject::__construct with too many arguments. +--FILE-- +getMessage() . "(" . $e->getLine() . ")\n"; +} +?> +--EXPECTF-- +Too many arguments: ArrayObject::__construct() expects at most 3 parameters, 4 given(12) \ No newline at end of file diff --git a/ext/spl/tests/arrayObject_asort_basic1.phpt b/ext/spl/tests/arrayObject_asort_basic1.phpt index d85202f02..ec69049a3 100644 --- a/ext/spl/tests/arrayObject_asort_basic1.phpt +++ b/ext/spl/tests/arrayObject_asort_basic1.phpt @@ -1,26 +1,26 @@ ---TEST-- -SPL: Test ArrayObject::asort() function : basic functionality with array based store ---FILE-- -4,'b'=>2,'c'=>3)); -var_dump($ao1->asort()); -var_dump($ao1); -var_dump($ao2->asort('blah')); -var_dump($ao2); -?> -===DONE=== ---EXPECTF-- -*** Testing ArrayObject::asort() : basic functionality *** +--TEST-- +SPL: Test ArrayObject::asort() function : basic functionality with array based store +--FILE-- +4,'b'=>2,'c'=>3)); +var_dump($ao1->asort()); +var_dump($ao1); +var_dump($ao2->asort('blah')); +var_dump($ao2); +?> +===DONE=== +--EXPECTF-- +*** Testing ArrayObject::asort() : basic functionality *** bool(true) object(ArrayObject)#1 (1) { ["storage":"ArrayObject":private]=> diff --git a/ext/spl/tests/arrayObject_asort_basic2.phpt b/ext/spl/tests/arrayObject_asort_basic2.phpt index 5f25fa7dd..d481d0c4e 100644 --- a/ext/spl/tests/arrayObject_asort_basic2.phpt +++ b/ext/spl/tests/arrayObject_asort_basic2.phpt @@ -1,30 +1,30 @@ ---TEST-- -SPL: Test ArrayObject::asort() function : basic functionality with object based store ---FILE-- -asort()); -var_dump($ao1, $c); -?> -===DONE=== ---EXPECTF-- -*** Testing ArrayObject::asort() : basic functionality *** +--TEST-- +SPL: Test ArrayObject::asort() function : basic functionality with object based store +--FILE-- +asort()); +var_dump($ao1, $c); +?> +===DONE=== +--EXPECTF-- +*** Testing ArrayObject::asort() : basic functionality *** bool(true) object(ArrayObject)#2 (1) { ["storage":"ArrayObject":private]=> diff --git a/ext/spl/tests/arrayObject_clone_basic1.phpt b/ext/spl/tests/arrayObject_clone_basic1.phpt index edffecca2..dd4abf3ff 100644 --- a/ext/spl/tests/arrayObject_clone_basic1.phpt +++ b/ext/spl/tests/arrayObject_clone_basic1.phpt @@ -1,19 +1,19 @@ ---TEST-- -SPL: Cloning an instance of ArrayObject which wraps an array. ---FILE-- - ---EXPECTF-- +--TEST-- +SPL: Cloning an instance of ArrayObject which wraps an array. +--FILE-- + +--EXPECTF-- array(4) { [0]=> int(1) diff --git a/ext/spl/tests/arrayObject_clone_basic2.phpt b/ext/spl/tests/arrayObject_clone_basic2.phpt index 250b49ccb..932eaed71 100644 --- a/ext/spl/tests/arrayObject_clone_basic2.phpt +++ b/ext/spl/tests/arrayObject_clone_basic2.phpt @@ -1,21 +1,21 @@ ---TEST-- -SPL: Cloning an instance of ArrayObject which wraps an object. ---FILE-- -p1 = 'new prop added to c before clone'; - -$ao2 = clone $ao1; - -$c->p2 = 'new prop added to c after clone'; -$ao1['new.ao1'] = 'new element added to ao1'; -$ao2['new.ao2'] = 'new element added to ao2'; -var_dump($c, $ao1, $ao2); -?> ---EXPECTF-- +--TEST-- +SPL: Cloning an instance of ArrayObject which wraps an object. +--FILE-- +p1 = 'new prop added to c before clone'; + +$ao2 = clone $ao1; + +$c->p2 = 'new prop added to c after clone'; +$ao1['new.ao1'] = 'new element added to ao1'; +$ao2['new.ao2'] = 'new element added to ao2'; +var_dump($c, $ao1, $ao2); +?> +--EXPECTF-- object(C)#1 (3) { ["p1"]=> string(32) "new prop added to c before clone" diff --git a/ext/spl/tests/arrayObject_clone_basic3.phpt b/ext/spl/tests/arrayObject_clone_basic3.phpt index d433f70f1..f7ac89442 100644 --- a/ext/spl/tests/arrayObject_clone_basic3.phpt +++ b/ext/spl/tests/arrayObject_clone_basic3.phpt @@ -1,27 +1,27 @@ ---TEST-- -SPL: Cloning nested ArrayObjects. ---FILE-- -dynamic1 = 'new prop added to $wrappedObject before clone'; -$clonedOuterArrayObject = clone $outerArrayObject; -$wrappedObject->dynamic2 = 'new prop added to $wrappedObject after clone'; - -$innerArrayObject['new.iAO'] = 'new element added $innerArrayObject'; -$outerArrayObject['new.oAO'] = 'new element added to $outerArrayObject'; -$clonedOuterArrayObject['new.coAO'] = 'new element added to $clonedOuterArrayObject'; - -var_dump($wrappedObject, $innerArrayObject, $outerArrayObject, $clonedOuterArrayObject); -?> ---EXPECTF-- +--TEST-- +SPL: Cloning nested ArrayObjects. +--FILE-- +dynamic1 = 'new prop added to $wrappedObject before clone'; +$clonedOuterArrayObject = clone $outerArrayObject; +$wrappedObject->dynamic2 = 'new prop added to $wrappedObject after clone'; + +$innerArrayObject['new.iAO'] = 'new element added $innerArrayObject'; +$outerArrayObject['new.oAO'] = 'new element added to $outerArrayObject'; +$clonedOuterArrayObject['new.coAO'] = 'new element added to $clonedOuterArrayObject'; + +var_dump($wrappedObject, $innerArrayObject, $outerArrayObject, $clonedOuterArrayObject); +?> +--EXPECTF-- object(C)#1 (5) { ["p"]=> string(9) "C::p.orig" diff --git a/ext/spl/tests/arrayObject_count_basic1.phpt b/ext/spl/tests/arrayObject_count_basic1.phpt index 63686b063..1a3b84d50 100644 --- a/ext/spl/tests/arrayObject_count_basic1.phpt +++ b/ext/spl/tests/arrayObject_count_basic1.phpt @@ -1,80 +1,80 @@ ---TEST-- -SPL: ArrayObject::count() and ArrayIterator::count() basic functionality. ---FILE-- -==ArrayObject== -count(), $ao->count()); - -//Extra args are ignored. -var_dump($ao->count('blah')); -?> -==ArrayIterator== -count(), $ao->count()); - -//Extra args are ignored. -var_dump($ao->count('blah')); -?> ---EXPECTF-- -==ArrayObject== -int(99) -int(0) -int(99) -int(1) -int(99) -int(2) -int(99) -int(1) -int(1) -==ArrayIterator== -int(99) -int(0) -int(99) -int(1) -int(99) -int(2) -int(99) -int(1) +--TEST-- +SPL: ArrayObject::count() and ArrayIterator::count() basic functionality. +--FILE-- +==ArrayObject== +count(), $ao->count()); + +//Extra args are ignored. +var_dump($ao->count('blah')); +?> +==ArrayIterator== +count(), $ao->count()); + +//Extra args are ignored. +var_dump($ao->count('blah')); +?> +--EXPECTF-- +==ArrayObject== +int(99) +int(0) +int(99) +int(1) +int(99) +int(2) +int(99) +int(1) +int(1) +==ArrayIterator== +int(99) +int(0) +int(99) +int(1) +int(99) +int(2) +int(99) +int(1) int(1) \ No newline at end of file diff --git a/ext/spl/tests/arrayObject_exchangeArray_basic3.phpt b/ext/spl/tests/arrayObject_exchangeArray_basic3.phpt index 91a2d45eb..4045b7a94 100644 --- a/ext/spl/tests/arrayObject_exchangeArray_basic3.phpt +++ b/ext/spl/tests/arrayObject_exchangeArray_basic3.phpt @@ -1,55 +1,55 @@ ---TEST-- -SPL: ArrayObject::exchangeArray() basic usage with object as underlying data store. ---FILE-- - exchangeArray() with objects:\n"; -$original = new C; -$ao = new ArrayObject($original); -$swapIn = new C; -try { - $copy = $ao->exchangeArray($swapIn); - $copy['addedToCopy'] = 'added To Copy'; -} catch (Exception $e) { - echo "Exception:" . $e->getMessage() . "\n"; -} -$swapIn->addedToSwapIn = 'added To Swap-In'; -$original->addedToOriginal = 'added To Original'; -var_dump($ao, $original, $swapIn, $copy); - - -echo "\n\n--> exchangeArray() with no arg:\n"; -unset($original, $ao, $swapIn, $copy); -$original = new C; -$ao = new ArrayObject($original); -try { - $copy = $ao->exchangeArray(); - $copy['addedToCopy'] = 'added To Copy'; -} catch (Exception $e) { - echo "Exception:" . $e->getMessage() . "\n"; -} -$original->addedToOriginal = 'added To Original'; -var_dump($ao, $original, $copy); - -echo "\n\n--> exchangeArray() with bad arg type:\n"; -unset($original, $ao, $swapIn, $copy); -$original = new C; -$ao = new ArrayObject($original); -try { - $copy = $ao->exchangeArray(null); - $copy['addedToCopy'] = 'added To Copy'; -} catch (Exception $e) { - echo "Exception:" . $e->getMessage() . "\n"; -} -$original->addedToOriginal = 'added To Original'; -var_dump($ao, $original, $copy); - -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject::exchangeArray() basic usage with object as underlying data store. +--FILE-- + exchangeArray() with objects:\n"; +$original = new C; +$ao = new ArrayObject($original); +$swapIn = new C; +try { + $copy = $ao->exchangeArray($swapIn); + $copy['addedToCopy'] = 'added To Copy'; +} catch (Exception $e) { + echo "Exception:" . $e->getMessage() . "\n"; +} +$swapIn->addedToSwapIn = 'added To Swap-In'; +$original->addedToOriginal = 'added To Original'; +var_dump($ao, $original, $swapIn, $copy); + + +echo "\n\n--> exchangeArray() with no arg:\n"; +unset($original, $ao, $swapIn, $copy); +$original = new C; +$ao = new ArrayObject($original); +try { + $copy = $ao->exchangeArray(); + $copy['addedToCopy'] = 'added To Copy'; +} catch (Exception $e) { + echo "Exception:" . $e->getMessage() . "\n"; +} +$original->addedToOriginal = 'added To Original'; +var_dump($ao, $original, $copy); + +echo "\n\n--> exchangeArray() with bad arg type:\n"; +unset($original, $ao, $swapIn, $copy); +$original = new C; +$ao = new ArrayObject($original); +try { + $copy = $ao->exchangeArray(null); + $copy['addedToCopy'] = 'added To Copy'; +} catch (Exception $e) { + echo "Exception:" . $e->getMessage() . "\n"; +} +$original->addedToOriginal = 'added To Original'; +var_dump($ao, $original, $copy); + +?> +--EXPECTF-- --> exchangeArray() with objects: object(ArrayObject)#2 (1) { ["storage":"ArrayObject":private]=> diff --git a/ext/spl/tests/arrayObject_getFlags_basic1.phpt b/ext/spl/tests/arrayObject_getFlags_basic1.phpt index b55e99310..b078c51ab 100644 --- a/ext/spl/tests/arrayObject_getFlags_basic1.phpt +++ b/ext/spl/tests/arrayObject_getFlags_basic1.phpt @@ -1,25 +1,25 @@ ---TEST-- -SPL: ArrayObject::getFlags() basic usage ---FILE-- -getFlags()); - -$ao = new ArrayObject(new ArrayObject(array(1,2,3)), ArrayObject::STD_PROP_LIST); -var_dump($ao->getFlags()); - -$ao = new ArrayObject(new ArrayIterator(new ArrayObject()), ArrayObject::ARRAY_AS_PROPS); -var_dump($ao->getFlags()); - -$ao = new ArrayObject(new ArrayObject(), ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS); -var_dump($ao->getFlags()); - -$cao = clone $ao; -var_dump($cao->getFlags()); -?> ---EXPECTF-- -int(0) -int(1) -int(2) -int(3) +--TEST-- +SPL: ArrayObject::getFlags() basic usage +--FILE-- +getFlags()); + +$ao = new ArrayObject(new ArrayObject(array(1,2,3)), ArrayObject::STD_PROP_LIST); +var_dump($ao->getFlags()); + +$ao = new ArrayObject(new ArrayIterator(new ArrayObject()), ArrayObject::ARRAY_AS_PROPS); +var_dump($ao->getFlags()); + +$ao = new ArrayObject(new ArrayObject(), ArrayObject::STD_PROP_LIST|ArrayObject::ARRAY_AS_PROPS); +var_dump($ao->getFlags()); + +$cao = clone $ao; +var_dump($cao->getFlags()); +?> +--EXPECTF-- +int(0) +int(1) +int(2) +int(3) int(3) \ No newline at end of file diff --git a/ext/spl/tests/arrayObject_getFlags_basic2.phpt b/ext/spl/tests/arrayObject_getFlags_basic2.phpt index e171d79a0..f7d56eaf8 100644 --- a/ext/spl/tests/arrayObject_getFlags_basic2.phpt +++ b/ext/spl/tests/arrayObject_getFlags_basic2.phpt @@ -1,24 +1,24 @@ ---TEST-- -SPL: ArrayObject::getFlags() - ensure flags are passed on to nested array objects and iterators. ---FILE-- -getFlags()); - -$ao2 = new ArrayObject($ao); -var_dump($ao2->getFlags()); -var_dump($ao2->getIterator()->getFlags()); - -$ai = new ArrayIterator($ao); -var_dump($ai->getFlags()); - -$ao2 = new ArrayObject($ao, 0); -var_dump($ao2->getFlags()); - -?> ---EXPECTF-- -int(3) -int(3) -int(3) -int(3) +--TEST-- +SPL: ArrayObject::getFlags() - ensure flags are passed on to nested array objects and iterators. +--FILE-- +getFlags()); + +$ao2 = new ArrayObject($ao); +var_dump($ao2->getFlags()); +var_dump($ao2->getIterator()->getFlags()); + +$ai = new ArrayIterator($ao); +var_dump($ai->getFlags()); + +$ao2 = new ArrayObject($ao, 0); +var_dump($ao2->getFlags()); + +?> +--EXPECTF-- +int(3) +int(3) +int(3) +int(3) int(0) \ No newline at end of file diff --git a/ext/spl/tests/arrayObject_getIteratorClass_basic1.phpt b/ext/spl/tests/arrayObject_getIteratorClass_basic1.phpt index c65dc867d..b23c19622 100644 --- a/ext/spl/tests/arrayObject_getIteratorClass_basic1.phpt +++ b/ext/spl/tests/arrayObject_getIteratorClass_basic1.phpt @@ -1,64 +1,64 @@ ---TEST-- -SPL: ArrayObject::getIteratorClass and ArrayObject::setIteratorClass basic functionality ---FILE-- -1,'b'=>2,'c'=>3), 0, "MyIterator"); - -echo "--> Access using MyIterator:\n"; -var_dump($ao->getIteratorClass()); -var_dump($ao->getIterator()); -foreach($ao as $key=>$value) { - echo " $key=>$value\n"; -} - -echo "\n\n--> Access using ArrayIterator:\n"; -var_dump($ao->setIteratorClass("ArrayIterator")); -var_dump($ao->getIteratorClass()); -var_dump($ao->getIterator()); -foreach($ao as $key=>$value) { - echo "$key=>$value\n"; -} - -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject::getIteratorClass and ArrayObject::setIteratorClass basic functionality +--FILE-- +1,'b'=>2,'c'=>3), 0, "MyIterator"); + +echo "--> Access using MyIterator:\n"; +var_dump($ao->getIteratorClass()); +var_dump($ao->getIterator()); +foreach($ao as $key=>$value) { + echo " $key=>$value\n"; +} + +echo "\n\n--> Access using ArrayIterator:\n"; +var_dump($ao->setIteratorClass("ArrayIterator")); +var_dump($ao->getIteratorClass()); +var_dump($ao->getIterator()); +foreach($ao as $key=>$value) { + echo "$key=>$value\n"; +} + +?> +--EXPECTF-- --> Access using MyIterator: string(10) "MyIterator" object(MyIterator)#2 (1) { diff --git a/ext/spl/tests/arrayObject_ksort_basic1.phpt b/ext/spl/tests/arrayObject_ksort_basic1.phpt index 8dda4c098..9c8d1e734 100644 --- a/ext/spl/tests/arrayObject_ksort_basic1.phpt +++ b/ext/spl/tests/arrayObject_ksort_basic1.phpt @@ -3,7 +3,7 @@ SPL: Test ArrayObject::ksort() function : basic functionality with array based s --FILE-- Write existent, non-existent and dynamic:\n"; -$ao['a'] = 'changed'; -$ao['dynamic'] = 'new'; -$ao['dynamic'] = 'new.changed'; -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> Read existent, non-existent and dynamic:\n"; -var_dump($ao['a']); -var_dump($ao['nonexistent']); -var_dump($ao['dynamic']); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> isset existent, non-existent and dynamic:\n"; -var_dump(isset($ao['a'])); -var_dump(isset($ao['nonexistent'])); -var_dump(isset($ao['dynamic'])); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> Unset existent, non-existent and dynamic:\n"; -unset($ao['a']); -unset($ao['nonexistent']); -unset($ao['dynamic']); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject: ensure a wrapped object's magic methods for property access are not invoked when manipulating the ArrayObject's elements using []. +--FILE-- + Write existent, non-existent and dynamic:\n"; +$ao['a'] = 'changed'; +$ao['dynamic'] = 'new'; +$ao['dynamic'] = 'new.changed'; +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> Read existent, non-existent and dynamic:\n"; +var_dump($ao['a']); +var_dump($ao['nonexistent']); +var_dump($ao['dynamic']); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> isset existent, non-existent and dynamic:\n"; +var_dump(isset($ao['a'])); +var_dump(isset($ao['nonexistent'])); +var_dump(isset($ao['dynamic'])); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> Unset existent, non-existent and dynamic:\n"; +unset($ao['a']); +unset($ao['nonexistent']); +unset($ao['dynamic']); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); +?> +--EXPECTF-- --> Write existent, non-existent and dynamic: Original wrapped object: object(UsesMagic)#1 (5) { diff --git a/ext/spl/tests/arrayObject_magicMethods2.phpt b/ext/spl/tests/arrayObject_magicMethods2.phpt index 79d972929..691a9a1e6 100644 --- a/ext/spl/tests/arrayObject_magicMethods2.phpt +++ b/ext/spl/tests/arrayObject_magicMethods2.phpt @@ -1,73 +1,73 @@ ---TEST-- -SPL: ArrayObject: ensure a wrapped object's magic methods for property access are not invoked when manipulating the ArrayObject's elements using ->. ---FILE-- - Write existent, non-existent and dynamic:\n"; -$ao->a = 'changed'; -$ao->dynamic = 'new'; -$ao->dynamic = 'new.changed'; -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> Read existent, non-existent and dynamic:\n"; -var_dump($ao->a); -var_dump($ao->nonexistent); -var_dump($ao->dynamic); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> isset existent, non-existent and dynamic:\n"; -var_dump(isset($ao->a)); -var_dump(isset($ao->nonexistent)); -var_dump(isset($ao->dynamic)); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> Unset existent, non-existent and dynamic:\n"; -unset($ao->a); -unset($ao->nonexistent); -unset($ao->dynamic); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject: ensure a wrapped object's magic methods for property access are not invoked when manipulating the ArrayObject's elements using ->. +--FILE-- + Write existent, non-existent and dynamic:\n"; +$ao->a = 'changed'; +$ao->dynamic = 'new'; +$ao->dynamic = 'new.changed'; +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> Read existent, non-existent and dynamic:\n"; +var_dump($ao->a); +var_dump($ao->nonexistent); +var_dump($ao->dynamic); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> isset existent, non-existent and dynamic:\n"; +var_dump(isset($ao->a)); +var_dump(isset($ao->nonexistent)); +var_dump(isset($ao->dynamic)); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> Unset existent, non-existent and dynamic:\n"; +unset($ao->a); +unset($ao->nonexistent); +unset($ao->dynamic); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); +?> +--EXPECTF-- --> Write existent, non-existent and dynamic: Original wrapped object: object(UsesMagic)#1 (4) { diff --git a/ext/spl/tests/arrayObject_magicMethods3.phpt b/ext/spl/tests/arrayObject_magicMethods3.phpt index 749e9cf28..16a6a3b80 100644 --- a/ext/spl/tests/arrayObject_magicMethods3.phpt +++ b/ext/spl/tests/arrayObject_magicMethods3.phpt @@ -1,72 +1,72 @@ ---TEST-- -SPL: ArrayObject: ensure a wrapped object's magic methods for property access are not invoked when manipulating the ArrayObject's elements using -> and ArrayObject::ARRAY_AS_PROPS. ---FILE-- - Write existent, non-existent and dynamic:\n"; -$ao->a = 'changed'; -$ao->dynamic = 'new'; -$ao->dynamic = 'new.changed'; -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> Read existent, non-existent and dynamic:\n"; -var_dump($ao->a); -var_dump($ao->nonexistent); -var_dump($ao->dynamic); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> isset existent, non-existent and dynamic:\n"; -var_dump(isset($ao->a)); -var_dump(isset($ao->nonexistent)); -var_dump(isset($ao->dynamic)); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> Unset existent, non-existent and dynamic:\n"; -unset($ao->a); -unset($ao->nonexistent); -unset($ao->dynamic); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); -?> +--TEST-- +SPL: ArrayObject: ensure a wrapped object's magic methods for property access are not invoked when manipulating the ArrayObject's elements using -> and ArrayObject::ARRAY_AS_PROPS. +--FILE-- + Write existent, non-existent and dynamic:\n"; +$ao->a = 'changed'; +$ao->dynamic = 'new'; +$ao->dynamic = 'new.changed'; +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> Read existent, non-existent and dynamic:\n"; +var_dump($ao->a); +var_dump($ao->nonexistent); +var_dump($ao->dynamic); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> isset existent, non-existent and dynamic:\n"; +var_dump(isset($ao->a)); +var_dump(isset($ao->nonexistent)); +var_dump(isset($ao->dynamic)); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> Unset existent, non-existent and dynamic:\n"; +unset($ao->a); +unset($ao->nonexistent); +unset($ao->dynamic); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); +?> --EXPECTF-- --> Write existent, non-existent and dynamic: Original wrapped object: diff --git a/ext/spl/tests/arrayObject_magicMethods4.phpt b/ext/spl/tests/arrayObject_magicMethods4.phpt index 39c30aa5f..3c9f78781 100644 --- a/ext/spl/tests/arrayObject_magicMethods4.phpt +++ b/ext/spl/tests/arrayObject_magicMethods4.phpt @@ -1,76 +1,76 @@ ---TEST-- -SPL: ArrayObject: ensure the magic methods for property access of a subclass of ArrayObject are not invoked when manipulating its elements using []. ---FILE-- - Write existent, non-existent and dynamic:\n"; -$ao['a'] = 'changed'; -$ao['dynamic'] = 'new'; -$ao['dynamic'] = 'new.changed'; -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> Read existent, non-existent and dynamic:\n"; -var_dump($ao['a']); -var_dump($ao['nonexistent']); -var_dump($ao['dynamic']); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> isset existent, non-existent and dynamic:\n"; -var_dump(isset($ao['a'])); -var_dump(isset($ao['nonexistent'])); -var_dump(isset($ao['dynamic'])); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> Unset existent, non-existent and dynamic:\n"; -unset($ao['a']); -unset($ao['nonexistent']); -unset($ao['dynamic']); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject: ensure the magic methods for property access of a subclass of ArrayObject are not invoked when manipulating its elements using []. +--FILE-- + Write existent, non-existent and dynamic:\n"; +$ao['a'] = 'changed'; +$ao['dynamic'] = 'new'; +$ao['dynamic'] = 'new.changed'; +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> Read existent, non-existent and dynamic:\n"; +var_dump($ao['a']); +var_dump($ao['nonexistent']); +var_dump($ao['dynamic']); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> isset existent, non-existent and dynamic:\n"; +var_dump(isset($ao['a'])); +var_dump(isset($ao['nonexistent'])); +var_dump(isset($ao['dynamic'])); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> Unset existent, non-existent and dynamic:\n"; +unset($ao['a']); +unset($ao['nonexistent']); +unset($ao['dynamic']); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); +?> +--EXPECTF-- --> Write existent, non-existent and dynamic: Original wrapped object: object(C)#1 (5) { diff --git a/ext/spl/tests/arrayObject_magicMethods5.phpt b/ext/spl/tests/arrayObject_magicMethods5.phpt index b59bf7137..023086d83 100644 --- a/ext/spl/tests/arrayObject_magicMethods5.phpt +++ b/ext/spl/tests/arrayObject_magicMethods5.phpt @@ -1,76 +1,76 @@ ---TEST-- -SPL: ArrayObject: ensure the magic methods for property access of a subclass of ArrayObject ARE invoked when manipulating its elements using ->. ---FILE-- - Write existent, non-existent and dynamic:\n"; -$ao->a = 'changed'; -$ao->dynamic = 'new'; -$ao->dynamic = 'new.changed'; -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> Read existent, non-existent and dynamic:\n"; -var_dump($ao->a); -var_dump($ao->nonexistent); -var_dump($ao->dynamic); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> isset existent, non-existent and dynamic:\n"; -var_dump(isset($ao->a)); -var_dump(isset($ao->nonexistent)); -var_dump(isset($ao->dynamic)); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> Unset existent, non-existent and dynamic:\n"; -unset($ao->a); -unset($ao->nonexistent); -unset($ao->dynamic); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject: ensure the magic methods for property access of a subclass of ArrayObject ARE invoked when manipulating its elements using ->. +--FILE-- + Write existent, non-existent and dynamic:\n"; +$ao->a = 'changed'; +$ao->dynamic = 'new'; +$ao->dynamic = 'new.changed'; +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> Read existent, non-existent and dynamic:\n"; +var_dump($ao->a); +var_dump($ao->nonexistent); +var_dump($ao->dynamic); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> isset existent, non-existent and dynamic:\n"; +var_dump(isset($ao->a)); +var_dump(isset($ao->nonexistent)); +var_dump(isset($ao->dynamic)); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> Unset existent, non-existent and dynamic:\n"; +unset($ao->a); +unset($ao->nonexistent); +unset($ao->dynamic); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); +?> +--EXPECTF-- --> Write existent, non-existent and dynamic: In UsesMagic::__set(a,changed) In UsesMagic::__set(dynamic,new) diff --git a/ext/spl/tests/arrayObject_magicMethods6.phpt b/ext/spl/tests/arrayObject_magicMethods6.phpt index 90781fa1d..45a0e4a76 100644 --- a/ext/spl/tests/arrayObject_magicMethods6.phpt +++ b/ext/spl/tests/arrayObject_magicMethods6.phpt @@ -1,76 +1,76 @@ ---TEST-- -SPL: ArrayObject: ensure the magic methods for property access of a subclass of ArrayObject are not invoked when manipulating its elements using -> ArrayObject::ARRAY_AS_PROPS. ---FILE-- - Write existent, non-existent and dynamic:\n"; -$ao->a = 'changed'; -$ao->dynamic = 'new'; -$ao->dynamic = 'new.changed'; -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> Read existent, non-existent and dynamic:\n"; -var_dump($ao->a); -var_dump($ao->nonexistent); -var_dump($ao->dynamic); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> isset existent, non-existent and dynamic:\n"; -var_dump(isset($ao->a)); -var_dump(isset($ao->nonexistent)); -var_dump(isset($ao->dynamic)); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); - -echo "\n--> Unset existent, non-existent and dynamic:\n"; -unset($ao->a); -unset($ao->nonexistent); -unset($ao->dynamic); -echo " Original wrapped object:\n"; -var_dump($obj); -echo " Wrapping ArrayObject:\n"; -var_dump($ao); -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject: ensure the magic methods for property access of a subclass of ArrayObject are not invoked when manipulating its elements using -> ArrayObject::ARRAY_AS_PROPS. +--FILE-- + Write existent, non-existent and dynamic:\n"; +$ao->a = 'changed'; +$ao->dynamic = 'new'; +$ao->dynamic = 'new.changed'; +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> Read existent, non-existent and dynamic:\n"; +var_dump($ao->a); +var_dump($ao->nonexistent); +var_dump($ao->dynamic); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> isset existent, non-existent and dynamic:\n"; +var_dump(isset($ao->a)); +var_dump(isset($ao->nonexistent)); +var_dump(isset($ao->dynamic)); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); + +echo "\n--> Unset existent, non-existent and dynamic:\n"; +unset($ao->a); +unset($ao->nonexistent); +unset($ao->dynamic); +echo " Original wrapped object:\n"; +var_dump($obj); +echo " Wrapping ArrayObject:\n"; +var_dump($ao); +?> +--EXPECTF-- --> Write existent, non-existent and dynamic: Original wrapped object: object(C)#1 (5) { diff --git a/ext/spl/tests/arrayObject_natcasesort_basic1.phpt b/ext/spl/tests/arrayObject_natcasesort_basic1.phpt index fed9f316b..62ad2ed48 100644 --- a/ext/spl/tests/arrayObject_natcasesort_basic1.phpt +++ b/ext/spl/tests/arrayObject_natcasesort_basic1.phpt @@ -3,7 +3,7 @@ SPL: Test ArrayObject::natcasesort() function : basic functionality --FILE-- p)); - // read - var_dump($ao->p); - // write - $ao->p = $ao->p . '.changed'; - var_dump($ao->p); -} - -$ao = new C(array('p'=>'array element')); -$ao->setFlags(ArrayObject::ARRAY_AS_PROPS); - -echo "\n--> Access the real property:\n"; -access_p($ao); - -echo "\n--> Remove the real property and access the array element:\n"; -unset($ao->p); -access_p($ao); - -echo "\n--> Remove the array element and try access again:\n"; -unset($ao->p); -access_p($ao); -?> ---EXPECTF-- ---> Access the real property: -bool(true) -string(15) "object property" -string(23) "object property.changed" - ---> Remove the real property and access the array element: -bool(true) -string(13) "array element" -string(21) "array element.changed" - ---> Remove the array element and try access again: -bool(false) - -Notice: Undefined index: p in %s on line 10 -NULL - -Notice: Undefined index: p in %s on line 12 -string(8) ".changed" +--TEST-- +SPL: ArrayObject::setFlags basic usage with ArrayObject::ARRAY_AS_PROPS. Currently fails on php.net due to bug 45622. +--FILE-- +p)); + // read + var_dump($ao->p); + // write + $ao->p = $ao->p . '.changed'; + var_dump($ao->p); +} + +$ao = new C(array('p'=>'array element')); +$ao->setFlags(ArrayObject::ARRAY_AS_PROPS); + +echo "\n--> Access the real property:\n"; +access_p($ao); + +echo "\n--> Remove the real property and access the array element:\n"; +unset($ao->p); +access_p($ao); + +echo "\n--> Remove the array element and try access again:\n"; +unset($ao->p); +access_p($ao); +?> +--EXPECTF-- +--> Access the real property: +bool(true) +string(15) "object property" +string(23) "object property.changed" + +--> Remove the real property and access the array element: +bool(true) +string(13) "array element" +string(21) "array element.changed" + +--> Remove the array element and try access again: +bool(false) + +Notice: Undefined index: p in %s on line 10 +NULL + +Notice: Undefined index: p in %s on line 12 +string(8) ".changed" diff --git a/ext/spl/tests/arrayObject_setFlags_basic2.phpt b/ext/spl/tests/arrayObject_setFlags_basic2.phpt index 1af312ab4..806f8129a 100644 --- a/ext/spl/tests/arrayObject_setFlags_basic2.phpt +++ b/ext/spl/tests/arrayObject_setFlags_basic2.phpt @@ -1,29 +1,29 @@ ---TEST-- -SPL: Ensure access to non-visible properties falls back to dimension access with ArrayObject::ARRAY_AS_PROPS. ---FILE-- -x); - } -} - -$c = new C(array('x'=>'public')); - -$c->setFlags(ArrayObject::ARRAY_AS_PROPS); -C::go($c); -var_dump($c->x); - - -$c->setFlags(0); -C::go($c); -var_dump($c->x); -?> ---EXPECTF-- -string(6) "secret" -string(6) "public" -string(6) "secret" - -Fatal error: Cannot access private property C::$x in %s on line 19 +--TEST-- +SPL: Ensure access to non-visible properties falls back to dimension access with ArrayObject::ARRAY_AS_PROPS. +--FILE-- +x); + } +} + +$c = new C(array('x'=>'public')); + +$c->setFlags(ArrayObject::ARRAY_AS_PROPS); +C::go($c); +var_dump($c->x); + + +$c->setFlags(0); +C::go($c); +var_dump($c->x); +?> +--EXPECTF-- +string(6) "secret" +string(6) "public" +string(6) "secret" + +Fatal error: Cannot access private property C::$x in %s on line 19 diff --git a/ext/spl/tests/arrayObject_setIteratorClass_error1.phpt b/ext/spl/tests/arrayObject_setIteratorClass_error1.phpt index 1cba535ce..4715eea98 100644 --- a/ext/spl/tests/arrayObject_setIteratorClass_error1.phpt +++ b/ext/spl/tests/arrayObject_setIteratorClass_error1.phpt @@ -1,48 +1,48 @@ ---TEST-- -SPL: ArrayObject with bad iterator class. ---FILE-- -1,'b'=>2,'c'=>3)); - $ao->setIteratorClass("nonExistentClass"); - foreach($ao as $key=>$value) { - echo " $key=>$value\n"; - } -} catch (Exception $e) { - var_dump($e->getMessage()); -} - -try { - $ao = new ArrayObject(array('a'=>1,'b'=>2,'c'=>3)); - $ao->setIteratorClass("stdClass"); - foreach($ao as $key=>$value) { - echo " $key=>$value\n"; - } -} catch (Exception $e) { - var_dump($e->getMessage()); -} - - -try { - $ao = new ArrayObject(array('a'=>1,'b'=>2,'c'=>3), 0, "nonExistentClass"); - foreach($ao as $key=>$value) { - echo " $key=>$value\n"; - } -} catch (Exception $e) { - var_dump($e->getMessage()); -} - -try { - $ao = new ArrayObject(array('a'=>1,'b'=>2,'c'=>3), 0, "stdClass"); - foreach($ao as $key=>$value) { - echo " $key=>$value\n"; - } -} catch (Exception $e) { - var_dump($e->getMessage()); -} - -?> ---EXPECTF-- +--TEST-- +SPL: ArrayObject with bad iterator class. +--FILE-- +1,'b'=>2,'c'=>3)); + $ao->setIteratorClass("nonExistentClass"); + foreach($ao as $key=>$value) { + echo " $key=>$value\n"; + } +} catch (Exception $e) { + var_dump($e->getMessage()); +} + +try { + $ao = new ArrayObject(array('a'=>1,'b'=>2,'c'=>3)); + $ao->setIteratorClass("stdClass"); + foreach($ao as $key=>$value) { + echo " $key=>$value\n"; + } +} catch (Exception $e) { + var_dump($e->getMessage()); +} + + +try { + $ao = new ArrayObject(array('a'=>1,'b'=>2,'c'=>3), 0, "nonExistentClass"); + foreach($ao as $key=>$value) { + echo " $key=>$value\n"; + } +} catch (Exception $e) { + var_dump($e->getMessage()); +} + +try { + $ao = new ArrayObject(array('a'=>1,'b'=>2,'c'=>3), 0, "stdClass"); + foreach($ao as $key=>$value) { + echo " $key=>$value\n"; + } +} catch (Exception $e) { + var_dump($e->getMessage()); +} + +?> +--EXPECTF-- Warning: ArrayObject::setIteratorClass() expects parameter 1 to be a class name derived from Iterator, 'nonExistentClass' given in %s on line 4 a=>1 b=>2 diff --git a/ext/spl/tests/arrayObject_uasort_basic1.phpt b/ext/spl/tests/arrayObject_uasort_basic1.phpt index 3cff53cdf..203edb6fb 100644 --- a/ext/spl/tests/arrayObject_uasort_basic1.phpt +++ b/ext/spl/tests/arrayObject_uasort_basic1.phpt @@ -3,7 +3,7 @@ SPL: Test ArrayObject::uasort() function : basic functionality --FILE-- + array(1) { + ["plop"]=> + object(AO)#1 (1) { + ["storage":"ArrayObject":private]=> + array(1) { + ["plop"]=> + *RECURSION* + } + } + } +} diff --git a/ext/spl/tests/bug42364.phpt b/ext/spl/tests/bug42364.phpt index e02a3c5bb..ad0bd8f24 100644 --- a/ext/spl/tests/bug42364.phpt +++ b/ext/spl/tests/bug42364.phpt @@ -17,7 +17,8 @@ foreach ($it as $e) { if ($count > 0) { echo "Found $count entries!\n"; } -echo "===DONE===" +?> +===DONE=== ?> --EXPECTF-- Found %i entries! diff --git a/ext/spl/tests/bug44144.phpt b/ext/spl/tests/bug44144.phpt new file mode 100644 index 000000000..2933d2f22 --- /dev/null +++ b/ext/spl/tests/bug44144.phpt @@ -0,0 +1,27 @@ +--TEST-- +Bug #44144 (spl_autoload_functions() should return object instance when appropriate) +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +array(1) { + [0]=> + array(2) { + [0]=> + object(Foo)#%d (0) { + } + [1]=> + string(15) "nonstaticMethod" + } +} + + diff --git a/ext/spl/tests/countable_class_basic1.phpt b/ext/spl/tests/countable_class_basic1.phpt index 7b084f878..c64aad6b6 100644 --- a/ext/spl/tests/countable_class_basic1.phpt +++ b/ext/spl/tests/countable_class_basic1.phpt @@ -1,34 +1,37 @@ ---TEST-- -SPL: Test shape of interface Countable. ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -Interface [ interface Countable ] { - - - Constants [0] { - } - - - Static properties [0] { - } - - - Static methods [0] { - } - - - Properties [0] { - } - - - Methods [1] { - Method [ abstract public method count ] { - } - } -} +--TEST-- +SPL: Test shape of interface Countable. +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Interface [ interface Countable ] { + + - Constants [0] { + } + + - Static properties [0] { + } + + - Static methods [0] { + } + + - Properties [0] { + } + + - Methods [1] { + Method [ abstract public method count ] { + + - Parameters [0] { + } + } + } +} diff --git a/ext/spl/tests/countable_count_variation1.phpt b/ext/spl/tests/countable_count_variation1.phpt index 3538a20b2..642887d0c 100644 --- a/ext/spl/tests/countable_count_variation1.phpt +++ b/ext/spl/tests/countable_count_variation1.phpt @@ -1,68 +1,68 @@ ---TEST-- -SPL: Countable::count() with wrong return types and exception. ---FILE-- -getMessage(); -} - -?> ---EXPECTF-- -Count returns null: -int(0) -Count returns a string: -int(0) -Count returns an object: - -Notice: Object of class returnObject could not be converted to int in %s on line 40 -int(1) -Count returns an array: -int(1) -Count throws an exception: +--TEST-- +SPL: Countable::count() with wrong return types and exception. +--FILE-- +getMessage(); +} + +?> +--EXPECTF-- +Count returns null: +int(0) +Count returns a string: +int(0) +Count returns an object: + +Notice: Object of class returnObject could not be converted to int in %s on line 40 +int(1) +Count returns an array: +int(1) +Count throws an exception: Thrown from count \ No newline at end of file diff --git a/ext/spl/tests/dit_002.phpt b/ext/spl/tests/dit_002.phpt index 49e2f4ec7..5e825a1fe 100755 --- a/ext/spl/tests/dit_002.phpt +++ b/ext/spl/tests/dit_002.phpt @@ -44,12 +44,12 @@ foreach ($classes as $class => $flags) { } ?> ===DONE=== ---EXPECT-- +--EXPECTF-- ===DirectoryIterator=== DirectoryIterator ===FilesystemIterator=== SplFileInfo -int(0) +int(%d) int(0) SplFileInfo int(16) diff --git a/ext/spl/tests/dllist_012.phpt b/ext/spl/tests/dllist_012.phpt new file mode 100644 index 000000000..75783fc8c --- /dev/null +++ b/ext/spl/tests/dllist_012.phpt @@ -0,0 +1,29 @@ +--TEST-- +SPL: DoublyLinkedList: recursive var_dump +--FILE-- + +===DONE=== +--EXPECT-- +object(SplDoublyLinkedList)#1 (2) { + ["flags":"SplDoublyLinkedList":private]=> + int(0) + ["dllist":"SplDoublyLinkedList":private]=> + array(1) { + [0]=> + object(SplDoublyLinkedList)#1 (2) { + ["flags":"SplDoublyLinkedList":private]=> + int(0) + ["dllist":"SplDoublyLinkedList":private]=> + array(1) { + [0]=> + *RECURSION* + } + } + } +} +===DONE=== diff --git a/ext/spl/tests/heap_012.phpt b/ext/spl/tests/heap_012.phpt new file mode 100644 index 000000000..bf00f50cc --- /dev/null +++ b/ext/spl/tests/heap_012.phpt @@ -0,0 +1,32 @@ +--TEST-- +SPL: SplHeap recursive var_dump +--FILE-- +insert($a); +var_dump($a) +?> +===DONE=== +--EXPECT-- +object(SplMaxHeap)#1 (3) { + ["flags":"SplHeap":private]=> + int(0) + ["isCorrupted":"SplHeap":private]=> + bool(false) + ["heap":"SplHeap":private]=> + array(1) { + [0]=> + object(SplMaxHeap)#1 (3) { + ["flags":"SplHeap":private]=> + int(0) + ["isCorrupted":"SplHeap":private]=> + bool(false) + ["heap":"SplHeap":private]=> + array(1) { + [0]=> + *RECURSION* + } + } + } +} +===DONE=== diff --git a/ext/spl/tests/heap_corruption.phpt b/ext/spl/tests/heap_corruption.phpt index 17f0ac8c2..284ee1db8 100644 --- a/ext/spl/tests/heap_corruption.phpt +++ b/ext/spl/tests/heap_corruption.phpt @@ -1,62 +1,62 @@ ---TEST-- -SPL: SplHeap - heap corruption via compare exception (with top element deletion) ---CREDITS-- -Mike Sullivan -#TestFest 2009 (London) ---FILE-- -allow_compare == true) - { - if ($v1 > $v2) - { - return 1; - } - else if ($v1 < $v2) - { - return -1; - } - else - { - return 0; - } - } - else - { - throw new Exception('Compare exception'); - } - } -} - -$heap = new myHeap(); -$heap->insert(1); -$heap->insert(2); -$heap->insert(3); -$heap->insert(4); - -$heap->allow_compare = false; - -try { - $heap->extract(); -} -catch (Exception $e) { - echo "Compare Exception: " . $e->getMessage() . PHP_EOL; -} - -try { - $heap->top(); -} -catch (Exception $e) { - echo "Corruption Exception: " . $e->getMessage() . PHP_EOL; -} - -?> ---EXPECT-- -Compare Exception: Compare exception +--TEST-- +SPL: SplHeap - heap corruption via compare exception (with top element deletion) +--CREDITS-- +Mike Sullivan +#TestFest 2009 (London) +--FILE-- +allow_compare == true) + { + if ($v1 > $v2) + { + return 1; + } + else if ($v1 < $v2) + { + return -1; + } + else + { + return 0; + } + } + else + { + throw new Exception('Compare exception'); + } + } +} + +$heap = new myHeap(); +$heap->insert(1); +$heap->insert(2); +$heap->insert(3); +$heap->insert(4); + +$heap->allow_compare = false; + +try { + $heap->extract(); +} +catch (Exception $e) { + echo "Compare Exception: " . $e->getMessage() . PHP_EOL; +} + +try { + $heap->top(); +} +catch (Exception $e) { + echo "Corruption Exception: " . $e->getMessage() . PHP_EOL; +} + +?> +--EXPECT-- +Compare Exception: Compare exception Corruption Exception: Heap is corrupted, heap properties are no longer ensured. \ No newline at end of file diff --git a/ext/spl/tests/heap_current_variation_001.phpt b/ext/spl/tests/heap_current_variation_001.phpt index a514fb898..eb6df2b88 100644 --- a/ext/spl/tests/heap_current_variation_001.phpt +++ b/ext/spl/tests/heap_current_variation_001.phpt @@ -1,22 +1,22 @@ ---TEST-- -SPL: SplHeap::current - get current value from empty heap ---CREDITS-- -Mike Sullivan -#TestFest 2009 (London) ---FILE-- -current()); - -?> ---EXPECT-- +--TEST-- +SPL: SplHeap::current - get current value from empty heap +--CREDITS-- +Mike Sullivan +#TestFest 2009 (London) +--FILE-- +current()); + +?> +--EXPECT-- NULL \ No newline at end of file diff --git a/ext/spl/tests/heap_isempty_variation_001.phpt b/ext/spl/tests/heap_isempty_variation_001.phpt index 78deaa892..dac470fcc 100644 --- a/ext/spl/tests/heap_isempty_variation_001.phpt +++ b/ext/spl/tests/heap_isempty_variation_001.phpt @@ -1,16 +1,16 @@ ---TEST-- -SPL: SplHeap: isEmpty argument variation. ---FILE-- -isEmpty(1); -?> ---EXPECTF-- -Warning: SplHeap::isEmpty() expects exactly 0 parameters, 1 given in %s +--TEST-- +SPL: SplHeap: isEmpty argument variation. +--FILE-- +isEmpty(1); +?> +--EXPECTF-- +Warning: SplHeap::isEmpty() expects exactly 0 parameters, 1 given in %s diff --git a/ext/spl/tests/iterator_count.phpt b/ext/spl/tests/iterator_count.phpt index 1db568d14..9aa4e1197 100644 --- a/ext/spl/tests/iterator_count.phpt +++ b/ext/spl/tests/iterator_count.phpt @@ -1,26 +1,26 @@ ---TEST-- -SPL: iterator_count() exceptions test ---CREDITS-- -Lance Kesson jac_kesson@hotmail.com -#testfest London 2009-05-09 ---FILE-- - ---EXPECTF-- -Warning: iterator_count() expects exactly 1 parameter, 0 given in %s - -Warning: iterator_count() expects exactly 1 parameter, 2 given in %s - -Catchable fatal error: Argument 1 passed to iterator_count() must implement interface Traversable, %unicode_string_optional% given %s +--TEST-- +SPL: iterator_count() exceptions test +--CREDITS-- +Lance Kesson jac_kesson@hotmail.com +#testfest London 2009-05-09 +--FILE-- + +--EXPECTF-- +Warning: iterator_count() expects exactly 1 parameter, 0 given in %s + +Warning: iterator_count() expects exactly 1 parameter, 2 given in %s + +Catchable fatal error: Argument 1 passed to iterator_count() must implement interface Traversable, %unicode_string_optional% given %s diff --git a/ext/spl/tests/iterator_to_array.phpt b/ext/spl/tests/iterator_to_array.phpt index 574e050b9..958d370cc 100644 --- a/ext/spl/tests/iterator_to_array.phpt +++ b/ext/spl/tests/iterator_to_array.phpt @@ -1,25 +1,25 @@ ---TEST-- -SPL: iterator_to_array() exceptions test ---CREDITS-- -Lance Kesson jac_kesson@hotmail.com -#testfest London 2009-05-09 ---FILE-- - ---EXPECTF-- -Warning: iterator_to_array() expects at least 1 parameter, 0 given in %s - -Warning: iterator_to_array() expects at most 2 parameters, 3 given in %s - -Catchable fatal error: Argument 1 passed to iterator_to_array() must implement interface Traversable, %unicode_string_optional% given %s +--TEST-- +SPL: iterator_to_array() exceptions test +--CREDITS-- +Lance Kesson jac_kesson@hotmail.com +#testfest London 2009-05-09 +--FILE-- + +--EXPECTF-- +Warning: iterator_to_array() expects at least 1 parameter, 0 given in %s + +Warning: iterator_to_array() expects at most 2 parameters, 3 given in %s + +Catchable fatal error: Argument 1 passed to iterator_to_array() must implement interface Traversable, %unicode_string_optional% given %s diff --git a/ext/spl/tests/recursive_tree_iterator_setprefixpart.phpt b/ext/spl/tests/recursive_tree_iterator_setprefixpart.phpt index f5af0dd4a..81c853f30 100644 --- a/ext/spl/tests/recursive_tree_iterator_setprefixpart.phpt +++ b/ext/spl/tests/recursive_tree_iterator_setprefixpart.phpt @@ -1,32 +1,32 @@ ---TEST-- -SPL: RecursiveTreeIterator::setPrefixPart() Test arguments ---CREDITS-- -Roshan Abraham (roshanabrahams@gmail.com) -TestFest London May 2009 ---FILE-- - array("b") -); - -$it = new RecursiveArrayIterator($arr); -$it = new RecursiveTreeIterator($it); - -$it->setPrefixPart(1); // Should throw a warning as setPrefixPart expects 2 arguments - -$a = new stdClass(); -$it->setPrefixPart($a, 1); // Should throw a warning as setPrefixPart expects argument 1 to be long integer - -$it->setPrefixPart(1, $a); // Should throw a warning as setPrefixPart expects argument 2 to be a string - - -?> -===DONE=== ---EXPECTF-- -Warning: RecursiveTreeIterator::setPrefixPart() expects exactly 2 parameters, 1 given in %s on line %d - -Warning: RecursiveTreeIterator::setPrefixPart() expects parameter 1 to be long, object given in %s on line %d - -Warning: RecursiveTreeIterator::setPrefixPart() expects parameter 2 to be %binary_string_optional%, object given in %s on line %d -===DONE=== +--TEST-- +SPL: RecursiveTreeIterator::setPrefixPart() Test arguments +--CREDITS-- +Roshan Abraham (roshanabrahams@gmail.com) +TestFest London May 2009 +--FILE-- + array("b") +); + +$it = new RecursiveArrayIterator($arr); +$it = new RecursiveTreeIterator($it); + +$it->setPrefixPart(1); // Should throw a warning as setPrefixPart expects 2 arguments + +$a = new stdClass(); +$it->setPrefixPart($a, 1); // Should throw a warning as setPrefixPart expects argument 1 to be long integer + +$it->setPrefixPart(1, $a); // Should throw a warning as setPrefixPart expects argument 2 to be a string + + +?> +===DONE=== +--EXPECTF-- +Warning: RecursiveTreeIterator::setPrefixPart() expects exactly 2 parameters, 1 given in %s on line %d + +Warning: RecursiveTreeIterator::setPrefixPart() expects parameter 1 to be long, object given in %s on line %d + +Warning: RecursiveTreeIterator::setPrefixPart() expects parameter 2 to be %binary_string_optional%, object given in %s on line %d +===DONE=== diff --git a/ext/spl/tests/regexiterator_getpregflags.phpt b/ext/spl/tests/regexiterator_getpregflags.phpt index db961538d..58a4dc4a3 100644 --- a/ext/spl/tests/regexiterator_getpregflags.phpt +++ b/ext/spl/tests/regexiterator_getpregflags.phpt @@ -1,33 +1,33 @@ ---TEST-- -SPL: RegexIterator::getPregFlags() ---CREDITS-- -Lance Kesson jac_kesson@hotmail.com -#testfest London 2009-05-09 ---FILE-- -setPregFlags(PREG_OFFSET_CAPTURE); - -echo is_long($r->getPregFlags()); - -?> ---EXPECTF-- +--TEST-- +SPL: RegexIterator::getPregFlags() +--CREDITS-- +Lance Kesson jac_kesson@hotmail.com +#testfest London 2009-05-09 +--FILE-- +setPregFlags(PREG_OFFSET_CAPTURE); + +echo is_long($r->getPregFlags()); + +?> +--EXPECTF-- 1 \ No newline at end of file diff --git a/ext/spl/tests/regexiterator_setflags_exception.phpt b/ext/spl/tests/regexiterator_setflags_exception.phpt index 66c82b159..fdc8bca64 100644 --- a/ext/spl/tests/regexiterator_setflags_exception.phpt +++ b/ext/spl/tests/regexiterator_setflags_exception.phpt @@ -1,35 +1,35 @@ ---TEST-- -SPL: RegexIterator::setFlags() exceptions test ---CREDITS-- -Lance Kesson jac_kesson@hotmail.com -#testfest London 2009-05-09 ---FILE-- -setFlags(); -}catch (Exception $e) { - echo $e->getMessage(); -} - -?> ---EXPECTF-- +--TEST-- +SPL: RegexIterator::setFlags() exceptions test +--CREDITS-- +Lance Kesson jac_kesson@hotmail.com +#testfest London 2009-05-09 +--FILE-- +setFlags(); +}catch (Exception $e) { + echo $e->getMessage(); +} + +?> +--EXPECTF-- Warning: RegexIterator::setFlags() expects exactly 1 parameter, 0 given in %s \ No newline at end of file diff --git a/ext/spl/tests/regexiterator_setpregflags.phpt b/ext/spl/tests/regexiterator_setpregflags.phpt index a14da6164..ea1b45548 100644 --- a/ext/spl/tests/regexiterator_setpregflags.phpt +++ b/ext/spl/tests/regexiterator_setpregflags.phpt @@ -1,34 +1,34 @@ ---TEST-- -SPL: RegexIterator::setPregFlags() ---CREDITS-- -Lance Kesson jac_kesson@hotmail.com -#testfest London 2009-05-09 ---FILE-- -setPregFlags(PREG_OFFSET_CAPTURE); - -echo $r->getPregFlags(); - - -?> ---EXPECTF-- +--TEST-- +SPL: RegexIterator::setPregFlags() +--CREDITS-- +Lance Kesson jac_kesson@hotmail.com +#testfest London 2009-05-09 +--FILE-- +setPregFlags(PREG_OFFSET_CAPTURE); + +echo $r->getPregFlags(); + + +?> +--EXPECTF-- 256 \ No newline at end of file diff --git a/ext/spl/tests/regexiterator_setpregflags_exception.phpt b/ext/spl/tests/regexiterator_setpregflags_exception.phpt index 489505ce5..cc7c17c27 100644 --- a/ext/spl/tests/regexiterator_setpregflags_exception.phpt +++ b/ext/spl/tests/regexiterator_setpregflags_exception.phpt @@ -1,36 +1,36 @@ ---TEST-- -SPL: RegexIterator::getPregFlags() exception test ---CREDITS-- -Lance Kesson jac_kesson@hotmail.com -#testfest London 2009-05-09 ---FILE-- -setPregFlags(); -}catch (Exception $e) { - echo $e->getMessage(); -} - -?> ---EXPECTF-- +--TEST-- +SPL: RegexIterator::getPregFlags() exception test +--CREDITS-- +Lance Kesson jac_kesson@hotmail.com +#testfest London 2009-05-09 +--FILE-- +setPregFlags(); +}catch (Exception $e) { + echo $e->getMessage(); +} + +?> +--EXPECTF-- Warning: RegexIterator::setPregFlags() expects exactly 1 parameter, 0 given in %s \ No newline at end of file diff --git a/ext/spl/tests/splDoublyLinkedList_shift_noParams.phpt b/ext/spl/tests/splDoublyLinkedList_shift_noParams.phpt new file mode 100644 index 000000000..cd4ea5b03 --- /dev/null +++ b/ext/spl/tests/splDoublyLinkedList_shift_noParams.phpt @@ -0,0 +1,15 @@ +--TEST-- +Checks that the shift() method of DoublyLinkedList does not accept args. +--CREDITS-- +PHPNW Test Fest 2009 - Rick Ogden +--FILE-- +push(1); +$ll->push(2); + +var_dump($ll->shift(1)); +?> +--EXPECTF-- +Warning: SplDoublyLinkedList::shift() expects exactly 0 parameters, 1 given in %s on line %d +NULL diff --git a/ext/spl/tests/spl_autoload_013.phpt b/ext/spl/tests/spl_autoload_013.phpt new file mode 100644 index 000000000..44d4d857f --- /dev/null +++ b/ext/spl/tests/spl_autoload_013.phpt @@ -0,0 +1,51 @@ +--TEST-- +SPL: spl_autoload_functions() with closures and invokables +--FILE-- +dir = $dir; + } + public function __invoke($class) { + var_dump("{$this->dir}/$class.php"); + } +} + +$al1 = new Autoloader('d1'); +$al2 = new Autoloader('d2'); + +spl_autoload_register($closure); +spl_autoload_register($al1); +spl_autoload_register($al2); + +var_dump(spl_autoload_functions()); + +?> +===DONE=== +--EXPECTF-- +array(3) { + [0]=> + object(Closure)#%d (1) { + ["parameter"]=> + array(1) { + ["$class"]=> + string(10) "" + } + } + [1]=> + object(Autoloader)#%d (1) { + ["dir":"Autoloader":private]=> + string(2) "d1" + } + [2]=> + object(Autoloader)#%d (1) { + ["dir":"Autoloader":private]=> + string(2) "d2" + } +} +===DONE=== \ No newline at end of file diff --git a/ext/spl/tests/spl_autoload_014.phpt b/ext/spl/tests/spl_autoload_014.phpt new file mode 100644 index 000000000..a68fcb7e6 --- /dev/null +++ b/ext/spl/tests/spl_autoload_014.phpt @@ -0,0 +1,47 @@ +--TEST-- +SPL: spl_autoload_unregister() with closures and invokables +--FILE-- +dir = $dir; + } + public function __invoke($class) { + echo ("Autoloader('{$this->dir}') called with $class\n"); + } +} + +class WorkingAutoloader { + public function __invoke($class) { + echo ("WorkingAutoloader() called with $class\n"); + eval("class $class { }"); + } +} + +$al1 = new Autoloader('d1'); +$al2 = new WorkingAutoloader('d2'); + +spl_autoload_register($closure); +spl_autoload_register($al1); +spl_autoload_register($al2); + +$x = new TestX; + +spl_autoload_unregister($closure); +spl_autoload_unregister($al1); + +$y = new TestY; + +?> +===DONE=== +--EXPECT-- +closure called with class TestX +Autoloader('d1') called with TestX +WorkingAutoloader() called with TestX +WorkingAutoloader() called with TestY +===DONE=== \ No newline at end of file diff --git a/ext/spl/tests/spl_autoload_bug48541.phpt b/ext/spl/tests/spl_autoload_bug48541.phpt index eef81bd03..9937a7f42 100644 --- a/ext/spl/tests/spl_autoload_bug48541.phpt +++ b/ext/spl/tests/spl_autoload_bug48541.phpt @@ -2,23 +2,38 @@ SPL: spl_autoload_register() Bug #48541: registering multiple closures fails with memleaks --FILE-- getClosure(); $b = function ($class) { eval('class ' . $class . '{function __construct(){echo "foo\n";}}'); echo "b called\n"; }; spl_autoload_register($a); +spl_autoload_register($a2); spl_autoload_register($b); $c = $a; +$c2 = $a2; spl_autoload_register($c); +spl_autoload_register($c2); $c = new foo; ?> ===DONE=== --EXPECT-- a called +a2 called b called foo ===DONE=== \ No newline at end of file diff --git a/ext/spl/tests/spl_fileinfo_getlinktarget_basic.phpt b/ext/spl/tests/spl_fileinfo_getlinktarget_basic.phpt index 9e3debfa9..399d9a31a 100755 --- a/ext/spl/tests/spl_fileinfo_getlinktarget_basic.phpt +++ b/ext/spl/tests/spl_fileinfo_getlinktarget_basic.phpt @@ -1,22 +1,22 @@ ---TEST-- -SPL: Spl File Info test getLinkTarget ---CREDITS-- -Nataniel McHugh nat@fishtrap.co.uk ---SKIPIF-- - ---FILE-- -isLink()) { - echo $fileInfo->getLinkTarget() == __FILE__ ? 'same' : 'different',PHP_EOL; -} -var_dump(unlink($link)); -?> ---EXPECT-- -same -bool(true) +--TEST-- +SPL: Spl File Info test getLinkTarget +--CREDITS-- +Nataniel McHugh nat@fishtrap.co.uk +--SKIPIF-- + +--FILE-- +isLink()) { + echo $fileInfo->getLinkTarget() == __FILE__ ? 'same' : 'different',PHP_EOL; +} +var_dump(unlink($link)); +?> +--EXPECT-- +same +bool(true) diff --git a/ext/spl/tests/spl_heap_is_empty_basic.phpt b/ext/spl/tests/spl_heap_is_empty_basic.phpt index 7c2937918..47d7ccce9 100644 --- a/ext/spl/tests/spl_heap_is_empty_basic.phpt +++ b/ext/spl/tests/spl_heap_is_empty_basic.phpt @@ -1,31 +1,31 @@ ---TEST-- -SPL: SplHeap, test trivial method to find if a heap is empty ---CREDITS-- -Nathaniel McHugh nat@fishtrap.co.uk -#testfest London 2009-05-09 ---FILE-- -isEmpty()); -$heap->insert(1); -var_dump($heap->isEmpty()); -$heap->extract(); -var_dump($heap->isEmpty()); -$heap->isEmpty('var'); -?> ---EXPECTF-- -bool(true) -bool(false) -bool(true) - -Warning: SplHeap::isEmpty() expects exactly 0 parameters, 1 given in %s +--TEST-- +SPL: SplHeap, test trivial method to find if a heap is empty +--CREDITS-- +Nathaniel McHugh nat@fishtrap.co.uk +#testfest London 2009-05-09 +--FILE-- +isEmpty()); +$heap->insert(1); +var_dump($heap->isEmpty()); +$heap->extract(); +var_dump($heap->isEmpty()); +$heap->isEmpty('var'); +?> +--EXPECTF-- +bool(true) +bool(false) +bool(true) + +Warning: SplHeap::isEmpty() expects exactly 0 parameters, 1 given in %s diff --git a/ext/spl/tests/spl_heap_isempty.phpt b/ext/spl/tests/spl_heap_isempty.phpt index 5d3e4cafc..2729c7fa8 100644 --- a/ext/spl/tests/spl_heap_isempty.phpt +++ b/ext/spl/tests/spl_heap_isempty.phpt @@ -1,21 +1,21 @@ ---TEST-- -SPL: Test of isEmpty for SPL Max Heap ---CREDITS-- -Rohan Abraham (rohanabrahams@gmail.com) -TestFest London May 2009 ---FILE-- -isEmpty())."\n"; - $h->insert(2); - echo "Checking after insert: "; - var_dump($h->isEmpty())."\n"; - $h->extract(); - echo "Checking after extract: "; - var_dump($h->isEmpty())."\n"; -?> ---EXPECT-- -Checking a new heap is empty: bool(true) -Checking after insert: bool(false) +--TEST-- +SPL: Test of isEmpty for SPL Max Heap +--CREDITS-- +Rohan Abraham (rohanabrahams@gmail.com) +TestFest London May 2009 +--FILE-- +isEmpty())."\n"; + $h->insert(2); + echo "Checking after insert: "; + var_dump($h->isEmpty())."\n"; + $h->extract(); + echo "Checking after extract: "; + var_dump($h->isEmpty())."\n"; +?> +--EXPECT-- +Checking a new heap is empty: bool(true) +Checking after insert: bool(false) Checking after extract: bool(true) \ No newline at end of file diff --git a/ext/spl/tests/spl_pq_top_basic.phpt b/ext/spl/tests/spl_pq_top_basic.phpt index df85237a8..dcc1cbe4c 100644 --- a/ext/spl/tests/spl_pq_top_basic.phpt +++ b/ext/spl/tests/spl_pq_top_basic.phpt @@ -1,42 +1,42 @@ ---TEST-- -SPL: SplPriorityQueue: top and extract flags ---CREDITS-- -Nathaniel McHugh nat@fishtrap.co.uk -#testfest London 2009-05-09 ---FILE-- -insert("a", 1); -$priorityQueue->insert("b", 2); -$priorityQueue->insert("c", 0); - -echo "EXTR DEFAULT",PHP_EOL; -echo "value: ",$priorityQueue->top(),PHP_EOL; - -$priorityQueue->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY); -echo "EXTR_PRIORITY",PHP_EOL; -echo "priority: ",$priorityQueue->top(),PHP_EOL; - -$priorityQueue->setExtractFlags(SplPriorityQueue::EXTR_BOTH); -echo "EXTR_BOTH",PHP_EOL; -print_r($priorityQueue->top()); - -echo "EXTR_DATA",PHP_EOL; -$priorityQueue->setExtractFlags(SplPriorityQueue::EXTR_DATA); -echo "value: ",$priorityQueue->top(),PHP_EOL; -?> ---EXPECT-- -EXTR DEFAULT -value: b -EXTR_PRIORITY -priority: 2 -EXTR_BOTH -Array -( - [data] => b - [priority] => 2 -) -EXTR_DATA +--TEST-- +SPL: SplPriorityQueue: top and extract flags +--CREDITS-- +Nathaniel McHugh nat@fishtrap.co.uk +#testfest London 2009-05-09 +--FILE-- +insert("a", 1); +$priorityQueue->insert("b", 2); +$priorityQueue->insert("c", 0); + +echo "EXTR DEFAULT",PHP_EOL; +echo "value: ",$priorityQueue->top(),PHP_EOL; + +$priorityQueue->setExtractFlags(SplPriorityQueue::EXTR_PRIORITY); +echo "EXTR_PRIORITY",PHP_EOL; +echo "priority: ",$priorityQueue->top(),PHP_EOL; + +$priorityQueue->setExtractFlags(SplPriorityQueue::EXTR_BOTH); +echo "EXTR_BOTH",PHP_EOL; +print_r($priorityQueue->top()); + +echo "EXTR_DATA",PHP_EOL; +$priorityQueue->setExtractFlags(SplPriorityQueue::EXTR_DATA); +echo "value: ",$priorityQueue->top(),PHP_EOL; +?> +--EXPECT-- +EXTR DEFAULT +value: b +EXTR_PRIORITY +priority: 2 +EXTR_BOTH +Array +( + [data] => b + [priority] => 2 +) +EXTR_DATA value: b \ No newline at end of file diff --git a/ext/spl/tests/spl_pq_top_error_corrupt.phpt b/ext/spl/tests/spl_pq_top_error_corrupt.phpt index ea3e1fe50..30b6fde5a 100644 --- a/ext/spl/tests/spl_pq_top_error_corrupt.phpt +++ b/ext/spl/tests/spl_pq_top_error_corrupt.phpt @@ -1,9 +1,9 @@ ---TEST-- -SPL: SplPriorityQueue: top and extract flags ---CREDITS-- -Nathaniel McHugh nat@fishtrap.co.uk -#testfest 2009-05-09 ---FILE-- +--TEST-- +SPL: SplPriorityQueue: top and extract flags +--CREDITS-- +Nathaniel McHugh nat@fishtrap.co.uk +#testfest 2009-05-09 +--FILE-- insert("a", 1); -try { - //corrupt heap +$priorityQueue = new myPriorityQueue(); +$priorityQueue->insert("a", 1); + +try { + //corrupt heap $priorityQueue->insert("b", 2); - // ignore exception tested elsewhere -} catch (Exception $e) { -} - -try { - $priorityQueue->top(); -} catch (RuntimeException $e) { - echo "Exception: ".$e->getMessage().PHP_EOL; -} - -?> ---EXPECT-- + // ignore exception tested elsewhere +} catch (Exception $e) { +} + +try { + $priorityQueue->top(); +} catch (RuntimeException $e) { + echo "Exception: ".$e->getMessage().PHP_EOL; +} + +?> +--EXPECT-- Exception: Heap is corrupted, heap properties are no longer ensured. diff --git a/ext/spl/tests/spl_pq_top_error_empty.phpt b/ext/spl/tests/spl_pq_top_error_empty.phpt index 129a04891..9e2a31bbc 100644 --- a/ext/spl/tests/spl_pq_top_error_empty.phpt +++ b/ext/spl/tests/spl_pq_top_error_empty.phpt @@ -1,19 +1,19 @@ ---TEST-- -SPL: SplPriorityQueue: top exception on empty heap ---CREDITS-- -Nathaniel McHugh nat@fishtrap.co.uk -#testfest 2009-05-09 ---FILE-- +--TEST-- +SPL: SplPriorityQueue: top exception on empty heap +--CREDITS-- +Nathaniel McHugh nat@fishtrap.co.uk +#testfest 2009-05-09 +--FILE-- top(); -} catch (RuntimeException $e) { - echo "Exception: ".$e->getMessage().PHP_EOL; -} - -?> ---EXPECT-- + +$priorityQueue = new SplPriorityQueue(); + +try { + $priorityQueue->top(); +} catch (RuntimeException $e) { + echo "Exception: ".$e->getMessage().PHP_EOL; +} + +?> +--EXPECT-- Exception: Can't peek at an empty heap diff --git a/ext/spl/tests/spl_recursive_iterator_iterator_key_case.phpt b/ext/spl/tests/spl_recursive_iterator_iterator_key_case.phpt index 249830859..1262ec0d6 100644 --- a/ext/spl/tests/spl_recursive_iterator_iterator_key_case.phpt +++ b/ext/spl/tests/spl_recursive_iterator_iterator_key_case.phpt @@ -1,33 +1,33 @@ ---TEST-- -SPL: Test on RecursiveIteratorIterator key function checking switch statements ---CREDITS-- -Rohan Abraham (rohanabrahams@gmail.com) -TestFest London May 2009 ---FILE-- -1, "two"=>2, "three"=>array("four"=>4, "five"=>5, "six"=>array("seven"=>7)), "eight"=>8, -100 => 10, NULL => "null"); - $it = new RecursiveArrayIterator($ar); - $it = new RecursiveIteratorIterator($it); - foreach($it as $k=>$v) - { - echo "$k=>$v\n"; - var_dump($k); - } -?> ---EXPECTF-- -one=>1 -%unicode|string%(3) "one" -two=>2 -%unicode|string%(3) "two" -four=>4 -%unicode|string%(4) "four" -five=>5 -%unicode|string%(4) "five" -seven=>7 -%unicode|string%(5) "seven" -eight=>8 -%unicode|string%(5) "eight" --100=>10 -int(-100) -=>null -%unicode|string%(0) "" +--TEST-- +SPL: Test on RecursiveIteratorIterator key function checking switch statements +--CREDITS-- +Rohan Abraham (rohanabrahams@gmail.com) +TestFest London May 2009 +--FILE-- +1, "two"=>2, "three"=>array("four"=>4, "five"=>5, "six"=>array("seven"=>7)), "eight"=>8, -100 => 10, NULL => "null"); + $it = new RecursiveArrayIterator($ar); + $it = new RecursiveIteratorIterator($it); + foreach($it as $k=>$v) + { + echo "$k=>$v\n"; + var_dump($k); + } +?> +--EXPECTF-- +one=>1 +%unicode|string%(3) "one" +two=>2 +%unicode|string%(3) "two" +four=>4 +%unicode|string%(4) "four" +five=>5 +%unicode|string%(4) "five" +seven=>7 +%unicode|string%(5) "seven" +eight=>8 +%unicode|string%(5) "eight" +-100=>10 +int(-100) +=>null +%unicode|string%(0) "" diff --git a/ext/spl/tests/splfixedarray_offsetExists_larger.phpt b/ext/spl/tests/splfixedarray_offsetExists_larger.phpt new file mode 100644 index 000000000..9449d64d8 --- /dev/null +++ b/ext/spl/tests/splfixedarray_offsetExists_larger.phpt @@ -0,0 +1,15 @@ +--TEST-- +Checks that offsetExists() does not accept a value larger than the array. +--CREDITS-- + PHPNW Test Fest 2009 - Rick Ogden +--FILE-- +offsetExists(4)); +?> +--EXPECT-- +bool(false) diff --git a/ext/sqlite/config.m4 b/ext/sqlite/config.m4 index 3f33c4151..25af84696 100644 --- a/ext/sqlite/config.m4 +++ b/ext/sqlite/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.41.2.1.2.2.2.2 2008/09/13 00:23:48 moriyoshi Exp $ +dnl $Id: config.m4 266233 2008-09-13 00:23:48Z moriyoshi $ dnl config.m4 for extension sqlite dnl vim:et:ts=2:sw=2 diff --git a/ext/sqlite/config.w32 b/ext/sqlite/config.w32 index b0778fc3b..f8aa6e558 100644 --- a/ext/sqlite/config.w32 +++ b/ext/sqlite/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.8.2.1 2005/09/24 15:13:13 edink Exp $ +// $Id: config.w32 242949 2007-09-26 15:44:16Z cvs2svn $ // vim:ft=javascript ARG_WITH("sqlite", "SQLite support", "no"); diff --git a/ext/sqlite/libsqlite/src/attach.c b/ext/sqlite/libsqlite/src/attach.c index d50c218b6..f5b7e6b8d 100644 --- a/ext/sqlite/libsqlite/src/attach.c +++ b/ext/sqlite/libsqlite/src/attach.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** -** $Id: attach.c,v 1.4.4.1 2005/09/07 15:11:31 iliaa Exp $ +** $Id: attach.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" diff --git a/ext/sqlite/libsqlite/src/auth.c b/ext/sqlite/libsqlite/src/auth.c index 9143971c7..9649423e2 100644 --- a/ext/sqlite/libsqlite/src/auth.c +++ b/ext/sqlite/libsqlite/src/auth.c @@ -14,7 +14,7 @@ ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 ** -** $Id: auth.c,v 1.6.2.1 2005/09/07 15:11:31 iliaa Exp $ +** $Id: auth.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" diff --git a/ext/sqlite/libsqlite/src/btree.c b/ext/sqlite/libsqlite/src/btree.c index f56d869c4..afe58d07e 100644 --- a/ext/sqlite/libsqlite/src/btree.c +++ b/ext/sqlite/libsqlite/src/btree.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree.c,v 1.5.4.1 2005/09/07 15:11:31 iliaa Exp $ +** $Id: btree.c 195361 2005-09-07 15:11:33Z iliaa $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to diff --git a/ext/sqlite/libsqlite/src/btree.h b/ext/sqlite/libsqlite/src/btree.h index ce124cfe9..865a004c7 100644 --- a/ext/sqlite/libsqlite/src/btree.h +++ b/ext/sqlite/libsqlite/src/btree.h @@ -13,7 +13,7 @@ ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: btree.h,v 1.5.4.1 2005/09/07 15:11:31 iliaa Exp $ +** @(#) $Id: btree.h 195361 2005-09-07 15:11:33Z iliaa $ */ #ifndef _BTREE_H_ #define _BTREE_H_ diff --git a/ext/sqlite/libsqlite/src/btree_rb.c b/ext/sqlite/libsqlite/src/btree_rb.c index b9da43515..4d08e00cb 100644 --- a/ext/sqlite/libsqlite/src/btree_rb.c +++ b/ext/sqlite/libsqlite/src/btree_rb.c @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: btree_rb.c,v 1.5.4.1 2005/09/07 15:11:31 iliaa Exp $ +** $Id: btree_rb.c 195361 2005-09-07 15:11:33Z iliaa $ ** ** This file implements an in-core database using Red-Black balanced ** binary trees. diff --git a/ext/sqlite/libsqlite/src/build.c b/ext/sqlite/libsqlite/src/build.c index a18112ace..015e5405b 100644 --- a/ext/sqlite/libsqlite/src/build.c +++ b/ext/sqlite/libsqlite/src/build.c @@ -23,7 +23,7 @@ ** ROLLBACK ** PRAGMA ** -** $Id: build.c,v 1.6.4.1 2005/09/07 15:11:31 iliaa Exp $ +** $Id: build.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" #include diff --git a/ext/sqlite/libsqlite/src/copy.c b/ext/sqlite/libsqlite/src/copy.c index 1dc5a0ddb..95bc80412 100644 --- a/ext/sqlite/libsqlite/src/copy.c +++ b/ext/sqlite/libsqlite/src/copy.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the COPY command. ** -** $Id: copy.c,v 1.4.4.1 2005/09/07 15:11:32 iliaa Exp $ +** $Id: copy.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" diff --git a/ext/sqlite/libsqlite/src/date.c b/ext/sqlite/libsqlite/src/date.c index 59cd0530a..7e0a810c1 100644 --- a/ext/sqlite/libsqlite/src/date.c +++ b/ext/sqlite/libsqlite/src/date.c @@ -16,7 +16,7 @@ ** sqliteRegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: date.c,v 1.3.4.1.2.3.2.2 2009/04/07 11:45:13 kalle Exp $ +** $Id: date.c 278363 2009-04-07 11:45:13Z kalle $ ** ** NOTES: ** diff --git a/ext/sqlite/libsqlite/src/delete.c b/ext/sqlite/libsqlite/src/delete.c index b5db904dd..cd0b2cae0 100644 --- a/ext/sqlite/libsqlite/src/delete.c +++ b/ext/sqlite/libsqlite/src/delete.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle DELETE FROM statements. ** -** $Id: delete.c,v 1.5.4.1 2005/09/07 15:11:32 iliaa Exp $ +** $Id: delete.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" diff --git a/ext/sqlite/libsqlite/src/encode.c b/ext/sqlite/libsqlite/src/encode.c index 956d7d128..16060742b 100644 --- a/ext/sqlite/libsqlite/src/encode.c +++ b/ext/sqlite/libsqlite/src/encode.c @@ -15,7 +15,7 @@ ** data in an SQLite database. The code in this file is not used by any other ** part of the SQLite library. ** -** $Id: encode.c,v 1.5.4.1.2.1 2006/12/24 20:50:02 iliaa Exp $ +** $Id: encode.c 225725 2006-12-24 20:50:02Z iliaa $ */ #include #include diff --git a/ext/sqlite/libsqlite/src/expr.c b/ext/sqlite/libsqlite/src/expr.c index 11d298d69..1a0da7a20 100644 --- a/ext/sqlite/libsqlite/src/expr.c +++ b/ext/sqlite/libsqlite/src/expr.c @@ -12,7 +12,7 @@ ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. ** -** $Id: expr.c,v 1.5.4.1 2005/09/07 15:11:32 iliaa Exp $ +** $Id: expr.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" #include diff --git a/ext/sqlite/libsqlite/src/func.c b/ext/sqlite/libsqlite/src/func.c index 0d553f4a1..b8be4361a 100644 --- a/ext/sqlite/libsqlite/src/func.c +++ b/ext/sqlite/libsqlite/src/func.c @@ -16,7 +16,7 @@ ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: func.c,v 1.5.4.1 2005/09/07 15:11:32 iliaa Exp $ +** $Id: func.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include #include diff --git a/ext/sqlite/libsqlite/src/hash.c b/ext/sqlite/libsqlite/src/hash.c index 5ecb9e50a..582570f72 100644 --- a/ext/sqlite/libsqlite/src/hash.c +++ b/ext/sqlite/libsqlite/src/hash.c @@ -12,7 +12,7 @@ ** This is the implementation of generic hash-tables ** used in SQLite. ** -** $Id: hash.c,v 1.6.4.1 2005/09/07 15:11:32 iliaa Exp $ +** $Id: hash.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" #include diff --git a/ext/sqlite/libsqlite/src/hash.h b/ext/sqlite/libsqlite/src/hash.h index ea86c1b88..19488416f 100644 --- a/ext/sqlite/libsqlite/src/hash.h +++ b/ext/sqlite/libsqlite/src/hash.h @@ -12,7 +12,7 @@ ** This is the header file for the generic hash-table implemenation ** used in SQLite. ** -** $Id: hash.h,v 1.6.4.1 2005/09/07 15:11:32 iliaa Exp $ +** $Id: hash.h 195361 2005-09-07 15:11:33Z iliaa $ */ #ifndef _SQLITE_HASH_H_ #define _SQLITE_HASH_H_ diff --git a/ext/sqlite/libsqlite/src/insert.c b/ext/sqlite/libsqlite/src/insert.c index 6ec361977..59f8c9b4c 100644 --- a/ext/sqlite/libsqlite/src/insert.c +++ b/ext/sqlite/libsqlite/src/insert.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: insert.c,v 1.5.4.1 2005/09/07 15:11:32 iliaa Exp $ +** $Id: insert.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" diff --git a/ext/sqlite/libsqlite/src/main.c b/ext/sqlite/libsqlite/src/main.c index e7c6ab685..2af43d834 100644 --- a/ext/sqlite/libsqlite/src/main.c +++ b/ext/sqlite/libsqlite/src/main.c @@ -14,7 +14,7 @@ ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: main.c,v 1.7.4.1 2005/09/07 15:11:32 iliaa Exp $ +** $Id: main.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" #include "os.h" diff --git a/ext/sqlite/libsqlite/src/pager.c b/ext/sqlite/libsqlite/src/pager.c index 64c3e4d7b..7f26cac89 100644 --- a/ext/sqlite/libsqlite/src/pager.c +++ b/ext/sqlite/libsqlite/src/pager.c @@ -18,7 +18,7 @@ ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: pager.c,v 1.6.4.2 2005/12/20 15:26:26 iliaa Exp $ +** @(#) $Id: pager.c 203289 2005-12-20 15:26:26Z iliaa $ */ #include "os.h" /* Must be first to enable large file support */ #include "sqliteInt.h" diff --git a/ext/sqlite/libsqlite/src/pager.h b/ext/sqlite/libsqlite/src/pager.h index 3e68b7f83..8d3600f6c 100644 --- a/ext/sqlite/libsqlite/src/pager.h +++ b/ext/sqlite/libsqlite/src/pager.h @@ -13,7 +13,7 @@ ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** -** @(#) $Id: pager.h,v 1.5.4.1 2005/09/07 15:11:32 iliaa Exp $ +** @(#) $Id: pager.h 195361 2005-09-07 15:11:33Z iliaa $ */ /* diff --git a/ext/sqlite/libsqlite/src/parse.y b/ext/sqlite/libsqlite/src/parse.y index da2ac2d3c..0b4c2ef55 100644 --- a/ext/sqlite/libsqlite/src/parse.y +++ b/ext/sqlite/libsqlite/src/parse.y @@ -14,7 +14,7 @@ ** the parser. Lemon will also generate a header file containing ** numeric codes for all of the tokens. ** -** @(#) $Id: parse.y,v 1.5.4.1 2005/09/07 15:11:32 iliaa Exp $ +** @(#) $Id: parse.y 195361 2005-09-07 15:11:33Z iliaa $ */ %token_prefix TK_ %token_type {Token} diff --git a/ext/sqlite/libsqlite/src/pragma.c b/ext/sqlite/libsqlite/src/pragma.c index 9d958246b..bd0bd3b6d 100644 --- a/ext/sqlite/libsqlite/src/pragma.c +++ b/ext/sqlite/libsqlite/src/pragma.c @@ -11,7 +11,7 @@ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: pragma.c,v 1.4.4.1 2005/09/07 15:11:32 iliaa Exp $ +** $Id: pragma.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" #include diff --git a/ext/sqlite/libsqlite/src/random.c b/ext/sqlite/libsqlite/src/random.c index 602c88813..4e8139e78 100644 --- a/ext/sqlite/libsqlite/src/random.c +++ b/ext/sqlite/libsqlite/src/random.c @@ -15,7 +15,7 @@ ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** -** $Id: random.c,v 1.5.4.1 2005/09/07 15:11:32 iliaa Exp $ +** $Id: random.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" #include "os.h" diff --git a/ext/sqlite/libsqlite/src/select.c b/ext/sqlite/libsqlite/src/select.c index 1c48da9cd..8d83c5698 100644 --- a/ext/sqlite/libsqlite/src/select.c +++ b/ext/sqlite/libsqlite/src/select.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: select.c,v 1.6.4.1 2005/09/07 15:11:32 iliaa Exp $ +** $Id: select.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" diff --git a/ext/sqlite/libsqlite/src/sqlite.h.in b/ext/sqlite/libsqlite/src/sqlite.h.in index e92e41897..855ca061f 100644 --- a/ext/sqlite/libsqlite/src/sqlite.h.in +++ b/ext/sqlite/libsqlite/src/sqlite.h.in @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.h.in,v 1.6.4.1 2005/09/07 15:11:33 iliaa Exp $ +** @(#) $Id: sqlite.h.in 195361 2005-09-07 15:11:33Z iliaa $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ diff --git a/ext/sqlite/libsqlite/src/sqlite.w32.h b/ext/sqlite/libsqlite/src/sqlite.w32.h index b85216f16..abdd30c4c 100644 --- a/ext/sqlite/libsqlite/src/sqlite.w32.h +++ b/ext/sqlite/libsqlite/src/sqlite.w32.h @@ -12,7 +12,7 @@ ** This header file defines the interface that the SQLite library ** presents to client programs. ** -** @(#) $Id: sqlite.w32.h,v 1.6.2.2 2005/12/20 15:26:26 iliaa Exp $ +** @(#) $Id: sqlite.w32.h 203289 2005-12-20 15:26:26Z iliaa $ */ #ifndef _SQLITE_H_ #define _SQLITE_H_ diff --git a/ext/sqlite/libsqlite/src/sqliteInt.h b/ext/sqlite/libsqlite/src/sqliteInt.h index 7ab879cd3..4c819de69 100644 --- a/ext/sqlite/libsqlite/src/sqliteInt.h +++ b/ext/sqlite/libsqlite/src/sqliteInt.h @@ -11,7 +11,7 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqliteInt.h,v 1.6.4.2 2005/12/20 15:26:26 iliaa Exp $ +** @(#) $Id: sqliteInt.h 203289 2005-12-20 15:26:26Z iliaa $ */ #include "config.h" #include "sqlite.h" diff --git a/ext/sqlite/libsqlite/src/tokenize.c b/ext/sqlite/libsqlite/src/tokenize.c index 67b55e26d..f9b6afeda 100644 --- a/ext/sqlite/libsqlite/src/tokenize.c +++ b/ext/sqlite/libsqlite/src/tokenize.c @@ -15,7 +15,7 @@ ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: tokenize.c,v 1.6.4.1 2005/09/07 15:11:33 iliaa Exp $ +** $Id: tokenize.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" #include "os.h" diff --git a/ext/sqlite/libsqlite/src/update.c b/ext/sqlite/libsqlite/src/update.c index 5afe0699f..95a83b142 100644 --- a/ext/sqlite/libsqlite/src/update.c +++ b/ext/sqlite/libsqlite/src/update.c @@ -12,7 +12,7 @@ ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: update.c,v 1.5.4.1 2005/09/07 15:11:33 iliaa Exp $ +** $Id: update.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" diff --git a/ext/sqlite/libsqlite/src/util.c b/ext/sqlite/libsqlite/src/util.c index dc63d4dc8..563889c2f 100644 --- a/ext/sqlite/libsqlite/src/util.c +++ b/ext/sqlite/libsqlite/src/util.c @@ -14,7 +14,7 @@ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: util.c,v 1.6.4.2 2005/12/20 15:26:26 iliaa Exp $ +** $Id: util.c 203289 2005-12-20 15:26:26Z iliaa $ */ #include "sqliteInt.h" #include diff --git a/ext/sqlite/libsqlite/src/vacuum.c b/ext/sqlite/libsqlite/src/vacuum.c index efa8cb141..d89d9b701 100644 --- a/ext/sqlite/libsqlite/src/vacuum.c +++ b/ext/sqlite/libsqlite/src/vacuum.c @@ -14,7 +14,7 @@ ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** -** $Id: vacuum.c,v 1.4.4.1 2005/09/07 15:11:33 iliaa Exp $ +** $Id: vacuum.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" #include "os.h" diff --git a/ext/sqlite/libsqlite/src/vdbe.c b/ext/sqlite/libsqlite/src/vdbe.c index b540bdd22..6b04b9590 100644 --- a/ext/sqlite/libsqlite/src/vdbe.c +++ b/ext/sqlite/libsqlite/src/vdbe.c @@ -43,7 +43,7 @@ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: vdbe.c,v 1.7.4.1.2.1 2006/09/09 10:59:05 tony2001 Exp $ +** $Id: vdbe.c 219681 2006-09-09 10:59:05Z tony2001 $ */ #include "sqliteInt.h" #include "os.h" diff --git a/ext/sqlite/libsqlite/src/vdbe.h b/ext/sqlite/libsqlite/src/vdbe.h index 71d90786f..553a3354f 100644 --- a/ext/sqlite/libsqlite/src/vdbe.h +++ b/ext/sqlite/libsqlite/src/vdbe.h @@ -15,7 +15,7 @@ ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: vdbe.h,v 1.5.4.1 2005/09/07 15:11:33 iliaa Exp $ +** $Id: vdbe.h 195361 2005-09-07 15:11:33Z iliaa $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ diff --git a/ext/sqlite/libsqlite/src/where.c b/ext/sqlite/libsqlite/src/where.c index 89d689ac8..d9a626f84 100644 --- a/ext/sqlite/libsqlite/src/where.c +++ b/ext/sqlite/libsqlite/src/where.c @@ -12,7 +12,7 @@ ** This module contains C code that generates VDBE code used to process ** the WHERE clause of SQL statements. ** -** $Id: where.c,v 1.6.4.1 2005/09/07 15:11:33 iliaa Exp $ +** $Id: where.c 195361 2005-09-07 15:11:33Z iliaa $ */ #include "sqliteInt.h" diff --git a/ext/sqlite/pdo_sqlite2.c b/ext/sqlite/pdo_sqlite2.c index 3e4e6a8c7..663c6f5b2 100644 --- a/ext/sqlite/pdo_sqlite2.c +++ b/ext/sqlite/pdo_sqlite2.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pdo_sqlite2.c,v 1.6.2.3.2.2.2.3 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: pdo_sqlite2.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" #endif diff --git a/ext/sqlite/php_sqlite.h b/ext/sqlite/php_sqlite.h index d254ca79c..f0cd3112f 100644 --- a/ext/sqlite/php_sqlite.h +++ b/ext/sqlite/php_sqlite.h @@ -17,7 +17,7 @@ | Marcus Boerger | +----------------------------------------------------------------------+ - $Id: php_sqlite.h,v 1.32.2.2.2.2.2.3 2008/12/31 11:15:44 sebastian Exp $ + $Id: php_sqlite.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SQLITE_H diff --git a/ext/sqlite/sess_sqlite.c b/ext/sqlite/sess_sqlite.c index 154f4fb3d..877da8b69 100644 --- a/ext/sqlite/sess_sqlite.c +++ b/ext/sqlite/sess_sqlite.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sess_sqlite.c,v 1.18.2.1.2.2.2.2 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: sess_sqlite.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" diff --git a/ext/sqlite/sqlite.c b/ext/sqlite/sqlite.c index 7f483659e..d9a4a796d 100644 --- a/ext/sqlite/sqlite.c +++ b/ext/sqlite/sqlite.c @@ -17,7 +17,7 @@ | Marcus Boerger | +----------------------------------------------------------------------+ - $Id: sqlite.c,v 1.166.2.13.2.9.2.22 2009/06/25 09:38:04 johannes Exp $ + $Id: sqlite.c 289598 2009-10-12 22:37:52Z pajoye $ */ #ifdef HAVE_CONFIG_H @@ -129,7 +129,7 @@ PHP_INI_END() #define RES_FROM_OBJECT(res, object) RES_FROM_OBJECT_RESTORE_ERH(res, object, NULL) #define PHP_SQLITE_EMPTY_QUERY \ - if (!sql_len) { \ + if (!sql_len || !*sql) { \ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot execute empty query."); \ RETURN_FALSE; \ } @@ -1458,7 +1458,7 @@ PHP_MINFO_FUNCTION(sqlite) { php_info_print_table_start(); php_info_print_table_header(2, "SQLite support", "enabled"); - php_info_print_table_row(2, "PECL Module version", PHP_SQLITE_MODULE_VERSION " $Id: sqlite.c,v 1.166.2.13.2.9.2.22 2009/06/25 09:38:04 johannes Exp $"); + php_info_print_table_row(2, "PECL Module version", PHP_SQLITE_MODULE_VERSION " $Id: sqlite.c 289598 2009-10-12 22:37:52Z pajoye $"); php_info_print_table_row(2, "SQLite Library", sqlite_libversion()); php_info_print_table_row(2, "SQLite Encoding", sqlite_libencoding()); php_info_print_table_end(); diff --git a/ext/sqlite/tests/sqlitedatabase_arrayquery.phpt b/ext/sqlite/tests/sqlitedatabase_arrayquery.phpt new file mode 100644 index 000000000..1e3084ceb --- /dev/null +++ b/ext/sqlite/tests/sqlitedatabase_arrayquery.phpt @@ -0,0 +1,23 @@ +--TEST-- +Testing SQLiteDatabase::ArrayQuery with NULL-byte string +--SKIPIF-- + +--FILE-- +getDeclaringClass()->newInstanceArgs(array(':memory:')); + +$p = "\0"; + +$method->invokeArgs($class, array_fill(0, 2, $p)); +$method->invokeArgs($class, array_fill(0, 1, $p)); + +?> +--EXPECTF-- +Warning: SQLiteDatabase::arrayQuery() expects parameter 2 to be long, string given in %s on line %d + +Warning: SQLiteDatabase::arrayQuery(): Cannot execute empty query. in %s on line %d diff --git a/ext/sqlite3/CREDITS b/ext/sqlite3/CREDITS index 307f58e48..6b2d3f383 100644 --- a/ext/sqlite3/CREDITS +++ b/ext/sqlite3/CREDITS @@ -1,2 +1,2 @@ -SQLite3 -Scott MacVicar +SQLite3 +Scott MacVicar diff --git a/ext/sqlite3/config.w32 b/ext/sqlite3/config.w32 index e6e2cc2dd..3ea754659 100644 --- a/ext/sqlite3/config.w32 +++ b/ext/sqlite3/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.1.2.5 2009/05/31 11:16:46 kalle Exp $ +// $Id: config.w32 281461 2009-05-31 11:16:46Z kalle $ // vim:ft=javascript ARG_WITH("sqlite3", "SQLite 3 support", "no"); diff --git a/ext/sqlite3/config0.m4 b/ext/sqlite3/config0.m4 index a3257cbff..13aaf5a02 100644 --- a/ext/sqlite3/config0.m4 +++ b/ext/sqlite3/config0.m4 @@ -1,4 +1,4 @@ -dnl $Id: config0.m4,v 1.1.2.13 2009/03/29 21:34:13 scottmac Exp $ +dnl $Id: config0.m4 277992 2009-03-29 21:34:13Z scottmac $ dnl config.m4 for extension sqlite3 dnl vim:et:ts=2:sw=2 diff --git a/ext/sqlite3/libsqlite/sqlite3.c b/ext/sqlite3/libsqlite/sqlite3.c index 72cbd8e0a..db34d0c0e 100644 --- a/ext/sqlite3/libsqlite/sqlite3.c +++ b/ext/sqlite3/libsqlite/sqlite3.c @@ -4,7 +4,7 @@ /****************************************************************************** ** This file is an amalgamation of many separate C source files from SQLite -** version 3.6.15. By combining all the individual C code files into this +** version 3.6.19. By combining all the individual C code files into this ** single large file, the entire code can be compiled as a one translation ** unit. This allows many compilers to do optimizations that would not be ** possible if the files were compiled separately. Performance improvements @@ -14,14 +14,14 @@ ** This file is all you need to compile SQLite. To use SQLite in other ** programs, you need this file and the "sqlite3.h" header file that defines ** the programming interface to the SQLite library. (If you do not have -** the "sqlite3.h" header file at hand, you will find a copy in the first -** 5615 lines past this header comment.) Additional code files may be -** needed if you want a wrapper to interface SQLite with your choice of -** programming language. The code for the "sqlite3" command-line shell -** is also in a separate file. This file contains only code for the core -** SQLite library. +** the "sqlite3.h" header file at hand, you will find a copy embedded within +** the text of this file. Search for "Begin file sqlite3.h" to find the start +** of the embedded sqlite3.h header file.) Additional code files may be needed +** if you want a wrapper to interface SQLite with your choice of programming +** language. The code for the "sqlite3" command-line shell is also in a +** separate file. This file contains only code for the core SQLite library. ** -** This amalgamation was generated on 2009-06-15 00:07:42 UTC. +** This amalgamation was generated on 2009-10-14 11:35:02 UTC. */ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1 @@ -45,11 +45,37 @@ ************************************************************************* ** Internal interface definitions for SQLite. ** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ */ #ifndef _SQLITEINT_H_ #define _SQLITEINT_H_ +/* +** These #defines should enable >2GB file support on POSIX if the +** underlying operating system supports it. If the OS lacks +** large file support, or if the OS is windows, these should be no-ops. +** +** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any +** system #includes. Hence, this block of code must be the very first +** code in all source files. +** +** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch +** on the compiler command line. This is necessary if you are compiling +** on a recent machine (ex: Red Hat 7.2) but you want your code to work +** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2 +** without this option, LFS is enable. But LFS does not exist in the kernel +** in Red Hat 6.0, so the code won't work. Hence, for maximum binary +** portability you should omit LFS. +** +** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later. +*/ +#ifndef SQLITE_DISABLE_LFS +# define _LARGE_FILE 1 +# ifndef _FILE_OFFSET_BITS +# define _FILE_OFFSET_BITS 64 +# endif +# define _LARGEFILE_SOURCE 1 +#endif + /* ** Include the configuration header output by 'configure' if we're using the ** autoconf-based build @@ -74,7 +100,7 @@ ** ** This file defines various limits of what SQLite can process. ** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** @(#) $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -251,6 +277,21 @@ # define SQLITE_MAX_LIKE_PATTERN_LENGTH 50000 #endif +/* +** Maximum depth of recursion for triggers. +** +** A value of 1 means that a trigger program will not be able to itself +** fire any triggers. A value of 0 means that no trigger programs at all +** may be executed. +*/ +#ifndef SQLITE_MAX_TRIGGER_DEPTH +#if defined(SQLITE_SMALL_STACK) +# define SQLITE_MAX_TRIGGER_DEPTH 10 +#else +# define SQLITE_MAX_TRIGGER_DEPTH 1000 +#endif +#endif + /************** End of sqliteLimit.h *****************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -278,6 +319,8 @@ #include #endif +#define SQLITE_INDEX_SAMPLES 10 + /* ** This macro is used to "hide" some ugliness in casting an int ** value to a ptr value under the MSVC 64-bit compiler. Casting @@ -310,33 +353,6 @@ # define SQLITE_PTR_TO_INT(X) ((int)(((char*)X)-(char*)0)) #endif -/* -** These #defines should enable >2GB file support on POSIX if the -** underlying operating system supports it. If the OS lacks -** large file support, or if the OS is windows, these should be no-ops. -** -** Ticket #2739: The _LARGEFILE_SOURCE macro must appear before any -** system #includes. Hence, this block of code must be the very first -** code in all source files. -** -** Large file support can be disabled using the -DSQLITE_DISABLE_LFS switch -** on the compiler command line. This is necessary if you are compiling -** on a recent machine (ex: Red Hat 7.2) but you want your code to work -** on an older machine (ex: Red Hat 6.0). If you compile on Red Hat 7.2 -** without this option, LFS is enable. But LFS does not exist in the kernel -** in Red Hat 6.0, so the code won't work. Hence, for maximum binary -** portability you should omit LFS. -** -** Similar is true for Mac OS X. LFS is only supported on Mac OS X 9 and later. -*/ -#ifndef SQLITE_DISABLE_LFS -# define _LARGE_FILE 1 -# ifndef _FILE_OFFSET_BITS -# define _FILE_OFFSET_BITS 64 -# endif -# define _LARGEFILE_SOURCE 1 -#endif - /* ** The SQLITE_THREADSAFE macro must be defined as either 0 or 1. @@ -491,9 +507,8 @@ SQLITE_PRIVATE void sqlite3Coverage(int); # define ALWAYS(X) (1) # define NEVER(X) (0) #elif !defined(NDEBUG) -SQLITE_PRIVATE int sqlite3Assert(void); -# define ALWAYS(X) ((X)?1:sqlite3Assert()) -# define NEVER(X) ((X)?sqlite3Assert():0) +# define ALWAYS(X) ((X)?1:(assert(0),0)) +# define NEVER(X) ((X)?(assert(0),1):0) #else # define ALWAYS(X) (X) # define NEVER(X) (X) @@ -535,8 +550,8 @@ SQLITE_PRIVATE int sqlite3Assert(void); ** Some of the definitions that are in this file are marked as ** "experimental". Experimental interfaces are normally new ** features recently added to SQLite. We do not anticipate changes -** to experimental interfaces but reserve to make minor changes if -** experience from use "in the wild" suggest such changes are prudent. +** to experimental interfaces but reserve the right to make minor changes +** if experience from use "in the wild" suggest such changes are prudent. ** ** The official C-language API documentation for SQLite is derived ** from comments in this file. This file is the authoritative source @@ -546,8 +561,6 @@ SQLITE_PRIVATE int sqlite3Assert(void); ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. -** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -568,10 +581,15 @@ extern "C" { # define SQLITE_EXTERN extern #endif +#ifndef SQLITE_API +# define SQLITE_API +#endif + + /* ** These no-op macros are used in front of interfaces to mark those ** interfaces as either deprecated or experimental. New applications -** should not use deprecated intrfaces - they are support for backwards +** should not use deprecated interfaces - they are support for backwards ** compatibility only. Application writers should be aware that ** experimental interfaces are subject to change in point releases. ** @@ -601,51 +619,81 @@ extern "C" { ** the sqlite3.h file specify the version of SQLite with which ** that header file is associated. ** -** The "version" of SQLite is a string of the form "X.Y.Z". -** The phrase "alpha" or "beta" might be appended after the Z. -** The X value is major version number always 3 in SQLite3. -** The X value only changes when backwards compatibility is +** The "version" of SQLite is a string of the form "W.X.Y" or "W.X.Y.Z". +** The W value is major version number and is always 3 in SQLite3. +** The W value only changes when backwards compatibility is ** broken and we intend to never break backwards compatibility. -** The Y value is the minor version number and only changes when +** The X value is the minor version number and only changes when ** there are major feature enhancements that are forwards compatible ** but not backwards compatible. -** The Z value is the release number and is incremented with -** each release but resets back to 0 whenever Y is incremented. +** The Y value is the release number and is incremented with +** each release but resets back to 0 whenever X is incremented. +** The Z value only appears on branch releases. +** +** The SQLITE_VERSION_NUMBER is an integer that is computed as +** follows: ** -** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. +**
+** SQLITE_VERSION_NUMBER = W*1000000 + X*1000 + Y
+** 
+** +** Since version 3.6.18, SQLite source code has been stored in the +** fossil configuration management +** system. The SQLITE_SOURCE_ID +** macro is a string which identifies a particular check-in of SQLite +** within its configuration management system. The string contains the +** date and time of the check-in (UTC) and an SHA1 hash of the entire +** source tree. +** +** See also: [sqlite3_libversion()], +** [sqlite3_libversion_number()], [sqlite3_sourceid()], +** [sqlite_version()] and [sqlite_source_id()]. ** ** Requirements: [H10011] [H10014] */ -#define SQLITE_VERSION "3.6.15" -#define SQLITE_VERSION_NUMBER 3006015 +#define SQLITE_VERSION "3.6.19" +#define SQLITE_VERSION_NUMBER 3006019 +#define SQLITE_SOURCE_ID "2009-10-14 11:33:55 c1d499afc50d54b376945b4efb65c56c787a073d" /* ** CAPI3REF: Run-Time Library Version Numbers {H10020} ** KEYWORDS: sqlite3_version ** -** These features provide the same information as the [SQLITE_VERSION] -** and [SQLITE_VERSION_NUMBER] #defines in the header, but are associated -** with the library instead of the header file. Cautious programmers might -** include a check in their application to verify that -** sqlite3_libversion_number() always returns the value -** [SQLITE_VERSION_NUMBER]. +** These interfaces provide the same information as the [SQLITE_VERSION], +** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] #defines in the header, +** but are associated with the library instead of the header file. Cautious +** programmers might include assert() statements in their application to +** verify that values returned by these interfaces match the macros in +** the header, and thus insure that the application is +** compiled with matching library and header files. +** +**
+** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
+** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
+** assert( strcmp(sqlite3_libversion,SQLITE_VERSION)==0 );
+** 
** ** The sqlite3_libversion() function returns the same information as is ** in the sqlite3_version[] string constant. The function is provided ** for use in DLLs since DLL users usually do not have direct access to string -** constants within the DLL. +** constants within the DLL. Similarly, the sqlite3_sourceid() function +** returns the same information as is in the [SQLITE_SOURCE_ID] #define of +** the header file. +** +** See also: [sqlite_version()] and [sqlite_source_id()]. ** ** Requirements: [H10021] [H10022] [H10023] */ SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; SQLITE_API const char *sqlite3_libversion(void); +SQLITE_API const char *sqlite3_sourceid(void); SQLITE_API int sqlite3_libversion_number(void); /* ** CAPI3REF: Test To See If The Library Is Threadsafe {H10100} ** ** SQLite can be compiled with or without mutexes. When -** the [SQLITE_THREADSAFE] C preprocessor macro 1 or 2, mutexes +** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes ** are enabled and SQLite is threadsafe. When the ** [SQLITE_THREADSAFE] macro is 0, ** the mutexes are omitted. Without the mutexes, it is not safe @@ -656,7 +704,7 @@ SQLITE_API int sqlite3_libversion_number(void); ** the mutexes. But for maximum safety, mutexes should be enabled. ** The default behavior is for mutexes to be enabled. ** -** This interface can be used by a program to make sure that the +** This interface can be used by an application to make sure that the ** version of SQLite that it is linking against was compiled with ** the desired setting of the [SQLITE_THREADSAFE] macro. ** @@ -923,6 +971,8 @@ SQLITE_API int sqlite3_exec( #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ #define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ /* ** CAPI3REF: Device Characteristics {H10240} @@ -990,8 +1040,9 @@ SQLITE_API int sqlite3_exec( /* ** CAPI3REF: OS Interface Open File Handle {H11110} ** -** An [sqlite3_file] object represents an open file in the OS -** interface layer. Individual OS interface implementations will +** An [sqlite3_file] object represents an open file in the +** [sqlite3_vfs | OS interface layer]. Individual OS interface +** implementations will ** want to subclass this object by appending additional fields ** for their own use. The pMethods entry is a pointer to an ** [sqlite3_io_methods] object that defines methods for performing @@ -1011,6 +1062,12 @@ struct sqlite3_file { ** This object defines the methods used to perform various operations ** against the open file represented by the [sqlite3_file] object. ** +** If the xOpen method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the xOpen reported that it failed. The +** only way to prevent a call to xClose following a failed xOpen +** is for the xOpen to set the sqlite3_file.pMethods element to NULL. +** ** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or ** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). ** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] @@ -1171,11 +1228,11 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** is either a NULL pointer or string obtained ** from xFullPathname(). SQLite further guarantees that ** the string will be valid and unchanged until xClose() is -** called. Because of the previous sentense, +** called. Because of the previous sentence, ** the [sqlite3_file] can safely store a pointer to the ** filename if it needs to remember the filename for some reason. ** If the zFilename parameter is xOpen is a NULL pointer then xOpen -** must invite its own temporary name for the file. Whenever the +** must invent its own temporary name for the file. Whenever the ** xFilename parameter is NULL it will also be the case that the ** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. ** @@ -1231,7 +1288,12 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** At least szOsFile bytes of memory are allocated by SQLite ** to hold the [sqlite3_file] structure passed as the third ** argument to xOpen. The xOpen method does not have to -** allocate the structure; it should just fill it in. +** allocate the structure; it should just fill it in. Note that +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods +** element will be valid after xOpen returns regardless of the success +** or failure of the xOpen call. ** ** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] ** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to @@ -1356,8 +1418,9 @@ struct sqlite3_vfs { ** interface is called automatically by sqlite3_initialize() and ** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate ** implementations for sqlite3_os_init() and sqlite3_os_end() -** are built into SQLite when it is compiled for unix, windows, or os/2. -** When built for other platforms (using the [SQLITE_OS_OTHER=1] compile-time +** are built into SQLite when it is compiled for Unix, Windows, or OS/2. +** When [custom builds | built for other platforms] +** (using the [SQLITE_OS_OTHER=1] compile-time ** option) the application must supply a suitable implementation for ** sqlite3_os_init() and sqlite3_os_end(). An application-supplied ** implementation of sqlite3_os_init() or sqlite3_os_end() @@ -1438,13 +1501,15 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); ** This object is used in only one place in the SQLite interface. ** A pointer to an instance of this object is the argument to ** [sqlite3_config()] when the configuration option is -** [SQLITE_CONFIG_MALLOC]. By creating an instance of this object -** and passing it to [sqlite3_config()] during configuration, an -** application can specify an alternative memory allocation subsystem -** for SQLite to use for all of its dynamic memory needs. -** -** Note that SQLite comes with a built-in memory allocator that is -** perfectly adequate for the overwhelming majority of applications +** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. +** By creating an instance of this object +** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) +** during configuration, an application can specify an alternative +** memory allocation subsystem for SQLite to use for all of its +** dynamic memory needs. +** +** Note that SQLite comes with several [built-in memory allocators] +** that are perfectly adequate for the overwhelming majority of applications ** and that this object is only useful to a tiny minority of applications ** with specialized memory allocation requirements. This object is ** also used during testing of SQLite in order to specify an alternative @@ -1452,8 +1517,16 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); ** order to verify that SQLite recovers gracefully from such ** conditions. ** -** The xMalloc, xFree, and xRealloc methods must work like the -** malloc(), free(), and realloc() functions from the standard library. +** The xMalloc and xFree methods must work like the +** malloc() and free() functions from the standard C library. +** The xRealloc method must work like realloc() from the standard C library +** with the exception that if the second argument to xRealloc is zero, +** xRealloc must be a no-op - it must not perform any allocation or +** deallocation. SQLite guaranteeds that the second argument to +** xRealloc is always a value returned by a prior call to xRoundup. +** And so in cases where xRoundup always returns a positive number, +** xRealloc can perform exactly as the standard library realloc() and +** still be in compliance with this specification. ** ** xSize should return the allocated size of a memory allocation ** previously obtained from xMalloc or xRealloc. The allocated size @@ -1463,6 +1536,9 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); ** a memory allocation given a particular requested size. Most memory ** allocators round up memory allocations at least to the next multiple ** of 8. Some allocators round up to a larger multiple or to a power of 2. +** Every memory allocation request coming in through [sqlite3_malloc()] +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** that causes the corresponding memory allocation to fail. ** ** The xInit method initializes the memory allocator. (For example, ** it might allocate any require mutexes or initialize internal data @@ -1470,6 +1546,20 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); ** [sqlite3_shutdown()] and should deallocate any resources acquired ** by xInit. The pAppData pointer is used as the only parameter to ** xInit and xShutdown. +** +** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. For all other methods, SQLite +** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the +** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which +** it is by default) and so the methods are automatically serialized. +** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other +** methods must be threadsafe or else make their own arrangements for +** serialization. +** +** SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). */ typedef struct sqlite3_mem_methods sqlite3_mem_methods; struct sqlite3_mem_methods { @@ -1623,9 +1713,12 @@ struct sqlite3_mem_methods { ** **
SQLITE_CONFIG_LOOKASIDE
**
This option takes two arguments that determine the default -** memory allcation lookaside optimization. The first argument is the +** memory allocation lookaside optimization. The first argument is the ** size of each lookaside buffer slot and the second is the number of -** slots allocated to each database connection.
+** slots allocated to each database connection. This option sets the +** default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] +** verb to [sqlite3_db_config()] can be used to change the lookaside +** configuration on individual connections. ** **
SQLITE_CONFIG_PCACHE
**
This option takes a single argument which is a pointer to @@ -1675,12 +1768,15 @@ struct sqlite3_mem_methods { **
This option takes three additional arguments that determine the ** [lookaside memory allocator] configuration for the [database connection]. ** The first argument (the third parameter to [sqlite3_db_config()] is a -** pointer to an 8-byte aligned memory buffer to use for lookaside memory. +** pointer to an memory buffer to use for lookaside memory. ** The first argument may be NULL in which case SQLite will allocate the ** lookaside buffer itself using [sqlite3_malloc()]. The second argument is the ** size of each lookaside buffer slot and the third argument is the number of ** slots. The size of the buffer in the first argument must be greater than -** or equal to the product of the second and third arguments.
+** or equal to the product of the second and third arguments. The buffer +** must be aligned to an 8-byte boundary. If the second argument is not +** a multiple of 8, it is internally rounded down to the next smaller +** multiple of 8. See also: [SQLITE_CONFIG_LOOKASIDE] ** ** */ @@ -1752,8 +1848,9 @@ SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); ** on the [database connection] specified by the first parameter. ** Only changes that are directly specified by the [INSERT], [UPDATE], ** or [DELETE] statement are counted. Auxiliary changes caused by -** triggers are not counted. Use the [sqlite3_total_changes()] function -** to find the total number of changes including changes caused by triggers. +** triggers or [foreign key actions] are not counted. Use the +** [sqlite3_total_changes()] function to find the total number of changes +** including changes caused by triggers and foreign key actions. ** ** Changes to a view that are simulated by an [INSTEAD OF trigger] ** are not counted. Only real table changes are counted. @@ -1805,8 +1902,8 @@ SQLITE_API int sqlite3_changes(sqlite3*); ** ** This function returns the number of row changes caused by [INSERT], ** [UPDATE] or [DELETE] statements since the [database connection] was opened. -** The count includes all changes from all -** [CREATE TRIGGER | trigger] contexts. However, +** The count includes all changes from all [CREATE TRIGGER | trigger] +** contexts and changes made by [foreign key actions]. However, ** the count does not include changes used to implement [REPLACE] constraints, ** do rollbacks or ABORT processing, or [DROP TABLE] processing. The ** count does not include rows of views that fire an [INSTEAD OF trigger], @@ -2084,7 +2181,7 @@ SQLITE_API void sqlite3_free_table(char **result); /* ** CAPI3REF: Formatted String Printing Functions {H17400} ** -** These routines are workalikes of the "printf()" family of functions +** These routines are work-alikes of the "printf()" family of functions ** from the standard C library. ** ** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their @@ -2371,7 +2468,7 @@ SQLITE_API void sqlite3_randomness(int N, void *P); ** database connections for the meaning of "modify" in this paragraph. ** ** When [sqlite3_prepare_v2()] is used to prepare a statement, the -** statement might be reprepared during [sqlite3_step()] due to a +** statement might be re-prepared during [sqlite3_step()] due to a ** schema change. Hence, the application should ensure that the ** correct authorizer callback remains in place during the [sqlite3_step()]. ** @@ -2538,7 +2635,8 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** except that it accepts two additional parameters for additional control ** over the new database connection. The flags parameter can take one of ** the following three values, optionally combined with the -** [SQLITE_OPEN_NOMUTEX] or [SQLITE_OPEN_FULLMUTEX] flags: +** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE], +** and/or [SQLITE_OPEN_PRIVATECACHE] flags: ** **
**
[SQLITE_OPEN_READONLY]
@@ -2558,7 +2656,8 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ** If the 3rd parameter to sqlite3_open_v2() is not one of the ** combinations shown above or one of the combinations shown above combined -** with the [SQLITE_OPEN_NOMUTEX] or [SQLITE_OPEN_FULLMUTEX] flags, +** with the [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], +** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_SHAREDCACHE] flags, ** then the behavior is undefined. ** ** If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection @@ -2567,6 +2666,11 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens ** in the serialized [threading mode] unless single-thread was ** previously selected at compile-time or start-time. +** The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be +** eligible to use [shared cache mode], regardless of whether or not shared +** cache is enabled using [sqlite3_enable_shared_cache()]. The +** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not +** participate in [shared cache mode] even if it is enabled. ** ** If the filename is ":memory:", then a private, temporary in-memory database ** is created for the connection. This in-memory database will vanish when @@ -2760,6 +2864,9 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); **
SQLITE_LIMIT_VARIABLE_NUMBER
**
The maximum number of variables in an SQL statement that can ** be bound.
+** +**
SQLITE_LIMIT_TRIGGER_DEPTH
+**
The maximum depth of recursion for triggers.
**
*/ #define SQLITE_LIMIT_LENGTH 0 @@ -2772,6 +2879,7 @@ SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); #define SQLITE_LIMIT_ATTACHED 7 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 #define SQLITE_LIMIT_VARIABLE_NUMBER 9 +#define SQLITE_LIMIT_TRIGGER_DEPTH 10 /* ** CAPI3REF: Compiling An SQL Statement {H13010} @@ -2948,7 +3056,8 @@ typedef struct sqlite3_context sqlite3_context; ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} ** ** In the SQL strings input to [sqlite3_prepare_v2()] and its variants, -** literals may be replaced by a [parameter] in one of these forms: +** literals may be replaced by a [parameter] that matches one of following +** templates: ** **
    **
  • ? @@ -2958,8 +3067,8 @@ typedef struct sqlite3_context sqlite3_context; **
  • $VVV **
** -** In the parameter forms shown above NNN is an integer literal, -** and VVV is an alpha-numeric parameter name. The values of these +** In the templates above, NNN represents an integer literal, +** and VVV represents an alphanumeric identifer. The values of these ** parameters (also called "host parameter names" or "SQL parameters") ** can be set using the sqlite3_bind_*() routines defined here. ** @@ -3611,7 +3720,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** [SQLITE_UTF8 | text encoding] this SQL function prefers for ** its parameters. Any SQL function implementation should be able to work ** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be -** more efficient with one encoding than another. It is allowed to +** more efficient with one encoding than another. An application may ** invoke sqlite3_create_function() or sqlite3_create_function16() multiple ** times with the same function but with different values of eTextRep. ** When multiple implementations of the same function are available, SQLite @@ -3633,7 +3742,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); ** It is permitted to register multiple implementations of the same ** functions with the same name but with either differing numbers of ** arguments or differing preferred text encodings. SQLite will use -** the implementation most closely matches the way in which the +** the implementation that most closely matches the way in which the ** SQL function is used. A function implementation with a non-negative ** nArg parameter is a better match than a function implementation with ** a negative nArg. A function where the preferred text encoding @@ -3981,10 +4090,11 @@ typedef void (*sqlite3_destructor_type)(void*); ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that ** function as the destructor on the text or BLOB result when it has ** finished using that result. -** If the 4th parameter to the sqlite3_result_text* interfaces or +** If the 4th parameter to the sqlite3_result_text* interfaces or to ** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite ** assumes that the text or BLOB result is in constant space and does not -** copy the it or call a destructor when it has finished using that result. +** copy the content of the parameter nor call a destructor on the content +** when it has finished using that result. ** If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT ** then SQLite makes a copy of the result into space obtained from @@ -4374,7 +4484,7 @@ SQLITE_API void *sqlite3_update_hook( /* ** CAPI3REF: Enable Or Disable Shared Pager Cache {H10330} -** KEYWORDS: {shared cache} {shared cache mode} +** KEYWORDS: {shared cache} ** ** This routine enables or disables the sharing of the database cache ** and schema data structures between [database connection | connections] @@ -4837,7 +4947,7 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module_v2( */ struct sqlite3_vtab { const sqlite3_module *pModule; /* The module for this virtual table */ - int nRef; /* Used internally */ + int nRef; /* NO LONGER USED */ char *zErrMsg; /* Error message from sqlite3_mprintf() */ /* Virtual table implementations will typically add additional fields */ }; @@ -4934,6 +5044,9 @@ typedef struct sqlite3_blob sqlite3_blob; ** ** If the flags parameter is non-zero, then the BLOB is opened for read ** and write access. If it is zero, the BLOB is opened for read access. +** It is not possible to open a column that is part of an index or primary +** key for writing. ^If [foreign key constraints] are enabled, it is +** not possible to open a column that is part of a [child key] for writing. ** ** Note that the database name is not the filename that contains ** the database but rather the symbolic name of the database that @@ -4963,7 +5076,7 @@ typedef struct sqlite3_blob sqlite3_blob; ** ** Use the [sqlite3_blob_bytes()] interface to determine the size of ** the opened blob. The size of a blob may not be changed by this -** underface. Use the [UPDATE] SQL command to change the size of a +** interface. Use the [UPDATE] SQL command to change the size of a ** blob. ** ** The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces @@ -5203,7 +5316,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); ** might return such a mutex in response to SQLITE_MUTEX_FAST. ** ** {H17017} The other allowed parameters to sqlite3_mutex_alloc() each return -** a pointer to a static preexisting mutex. {END} Four static mutexes are +** a pointer to a static preexisting mutex. {END} Six static mutexes are ** used by the current version of SQLite. Future versions of SQLite ** may add additional static mutexes. Static mutexes are for internal ** use by SQLite only. Applications that use SQLite mutexes should @@ -5309,6 +5422,21 @@ SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); ** of passing a NULL pointer instead of a valid mutex handle are undefined ** (i.e. it is acceptable to provide an implementation that segfaults if ** it is passed a NULL pointer). +** +** The xMutexInit() method must be threadsafe. It must be harmless to +** invoke xMutexInit() mutiple times within the same process and without +** intervening calls to xMutexEnd(). Second and subsequent calls to +** xMutexInit() must be no-ops. +** +** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] +** and its associates). Similarly, xMutexAlloc() must not use SQLite memory +** allocation for a static mutex. However xMutexAlloc() may use SQLite +** memory allocation for a fast or recursive mutex. +** +** SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is +** called, but only if the prior call to xMutexInit returned SQLITE_OK. +** If xMutexInit fails in any way, it is expected to clean up after itself +** prior to returning. */ typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; struct sqlite3_mutex_methods { @@ -5451,6 +5579,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PENDING_BYTE 11 #define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ALWAYS 13 +#define SQLITE_TESTCTRL_RESERVE 14 /* ** CAPI3REF: SQLite Runtime Status {H17200} @@ -5473,7 +5602,7 @@ SQLITE_API int sqlite3_test_control(int op, ...); ** This routine returns SQLITE_OK on success and a non-zero ** [error code] on failure. ** -** This routine is threadsafe but is not atomic. This routine can +** This routine is threadsafe but is not atomic. This routine can be ** called while other threads are running the same or different SQLite ** interfaces. However the values returned in *pCurrent and ** *pHighwater reflect the status of SQLite at different points in time @@ -5596,7 +5725,14 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur ** CAPI3REF: Status Parameters for database connections {H17520} ** EXPERIMENTAL ** -** Status verbs for [sqlite3_db_status()]. +** These constants are the available integer "verbs" that can be passed as +** the second argument to the [sqlite3_db_status()] interface. +** +** New verbs may be added in future releases of SQLite. Existing verbs +** might be discontinued. Applications should check the return code from +** [sqlite3_db_status()] to make sure that the call worked. +** The [sqlite3_db_status()] interface will return a non-zero error code +** if a discontinued or unsupported verb is invoked. ** **
**
SQLITE_DBSTATUS_LOOKASIDE_USED
@@ -5674,95 +5810,109 @@ typedef struct sqlite3_pcache sqlite3_pcache; /* ** CAPI3REF: Application Defined Page Cache. +** KEYWORDS: {page cache} ** EXPERIMENTAL ** ** The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can ** register an alternative page cache implementation by passing in an ** instance of the sqlite3_pcache_methods structure. The majority of the -** heap memory used by sqlite is used by the page cache to cache data read +** heap memory used by SQLite is used by the page cache to cache data read ** from, or ready to be written to, the database file. By implementing a ** custom page cache using this API, an application can control more -** precisely the amount of memory consumed by sqlite, the way in which -** said memory is allocated and released, and the policies used to +** precisely the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to ** determine exactly which parts of a database file are cached and for ** how long. ** -** The contents of the structure are copied to an internal buffer by sqlite -** within the call to [sqlite3_config]. +** The contents of the sqlite3_pcache_methods structure are copied to an +** internal buffer by SQLite within the call to [sqlite3_config]. Hence +** the application may discard the parameter after the call to +** [sqlite3_config()] returns. ** ** The xInit() method is called once for each call to [sqlite3_initialize()] ** (usually only once during the lifetime of the process). It is passed ** a copy of the sqlite3_pcache_methods.pArg value. It can be used to set ** up global structures and mutexes required by the custom page cache -** implementation. The xShutdown() method is called from within -** [sqlite3_shutdown()], if the application invokes this API. It can be used -** to clean up any outstanding resources before process shutdown, if required. +** implementation. +** +** The xShutdown() method is called from within [sqlite3_shutdown()], +** if the application invokes this API. It can be used to clean up +** any outstanding resources before process shutdown, if required. ** -** The xCreate() method is used to construct a new cache instance. The +** SQLite holds a [SQLITE_MUTEX_RECURSIVE] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. All other methods must be threadsafe +** in multithreaded applications. +** +** SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). +** +** The xCreate() method is used to construct a new cache instance. SQLite +** will typically create one cache instance for each open database file, +** though this is not guaranteed. The ** first parameter, szPage, is the size in bytes of the pages that must -** be allocated by the cache. szPage will not be a power of two. The -** second argument, bPurgeable, is true if the cache being created will -** be used to cache database pages read from a file stored on disk, or +** be allocated by the cache. szPage will not be a power of two. szPage +** will the page size of the database file that is to be cached plus an +** increment (here called "R") of about 100 or 200. SQLite will use the +** extra R bytes on each page to store metadata about the underlying +** database page on disk. The value of R depends +** on the SQLite version, the target platform, and how SQLite was compiled. +** R is constant for a particular build of SQLite. The second argument to +** xCreate(), bPurgeable, is true if the cache being created will +** be used to cache database pages of a file stored on disk, or ** false if it is used for an in-memory database. The cache implementation -** does not have to do anything special based on the value of bPurgeable, -** it is purely advisory. +** does not have to do anything special based with the value of bPurgeable; +** it is purely advisory. On a cache where bPurgeable is false, SQLite will +** never invoke xUnpin() except to deliberately delete a page. +** In other words, a cache created with bPurgeable set to false will +** never contain any unpinned pages. ** ** The xCachesize() method may be called at any time by SQLite to set the ** suggested maximum cache-size (number of pages stored by) the cache ** instance passed as the first argument. This is the value configured using ** the SQLite "[PRAGMA cache_size]" command. As with the bPurgeable parameter, -** the implementation is not required to do anything special with this -** value, it is advisory only. +** the implementation is not required to do anything with this +** value; it is advisory only. ** ** The xPagecount() method should return the number of pages currently -** stored in the cache supplied as an argument. +** stored in the cache. ** ** The xFetch() method is used to fetch a page and return a pointer to it. ** A 'page', in this context, is a buffer of szPage bytes aligned at an ** 8-byte boundary. The page to be fetched is determined by the key. The ** mimimum key value is 1. After it has been retrieved using xFetch, the page -** is considered to be pinned. +** is considered to be "pinned". ** -** If the requested page is already in the page cache, then a pointer to -** the cached buffer should be returned with its contents intact. If the -** page is not already in the cache, then the expected behaviour of the -** cache is determined by the value of the createFlag parameter passed -** to xFetch, according to the following table: +** If the requested page is already in the page cache, then the page cache +** implementation must return a pointer to the page buffer with its content +** intact. If the requested page is not already in the cache, then the +** behavior of the cache implementation is determined by the value of the +** createFlag parameter passed to xFetch, according to the following table: ** ** -**
createFlagExpected Behaviour -**
0NULL should be returned. No new cache entry is created. -**
1If createFlag is set to 1, this indicates that -** SQLite is holding pinned pages that can be unpinned -** by writing their contents to the database file (a -** relatively expensive operation). In this situation the -** cache implementation has two choices: it can return NULL, -** in which case SQLite will attempt to unpin one or more -** pages before re-requesting the same page, or it can -** allocate a new page and return a pointer to it. If a new -** page is allocated, then the first sizeof(void*) bytes of -** it (at least) must be zeroed before it is returned. -**
2If createFlag is set to 2, then SQLite is not holding any -** pinned pages associated with the specific cache passed -** as the first argument to xFetch() that can be unpinned. The -** cache implementation should attempt to allocate a new -** cache entry and return a pointer to it. Again, the first -** sizeof(void*) bytes of the page should be zeroed before -** it is returned. If the xFetch() method returns NULL when -** createFlag==2, SQLite assumes that a memory allocation -** failed and returns SQLITE_NOMEM to the user. +**
createFlag Behaviour when page is not already in cache +**
0 Do not allocate a new page. Return NULL. +**
1 Allocate a new page if it easy and convenient to do so. +** Otherwise return NULL. +**
2 Make every effort to allocate a new page. Only return +** NULL if allocating a new page is effectively impossible. **
** +** SQLite will normally invoke xFetch() with a createFlag of 0 or 1. If +** a call to xFetch() with createFlag==1 returns NULL, then SQLite will +** attempt to unpin one or more cache pages by spilling the content of +** pinned pages to disk and synching the operating system disk cache. After +** attempting to unpin pages, the xFetch() method will be invoked again with +** a createFlag of 2. +** ** xUnpin() is called by SQLite with a pointer to a currently pinned page ** as its second argument. If the third parameter, discard, is non-zero, ** then the page should be evicted from the cache. In this case SQLite ** assumes that the next time the page is retrieved from the cache using ** the xFetch() method, it will be zeroed. If the discard parameter is ** zero, then the page is considered to be unpinned. The cache implementation -** may choose to reclaim (free or recycle) unpinned pages at any time. -** SQLite assumes that next time the page is retrieved from the cache -** it will either be zeroed, or contain the same data that it did when it -** was unpinned. +** may choose to evict unpinned pages at any time. ** ** The cache is not required to perform any reference counting. A single ** call to xUnpin() unpins the page regardless of the number of prior calls @@ -6118,6 +6268,18 @@ SQLITE_API int sqlite3_unlock_notify( void *pNotifyArg /* Argument to pass to xNotify */ ); + +/* +** CAPI3REF: String Comparison +** EXPERIMENTAL +** +** The [sqlite3_strnicmp()] API allows applications and extensions to +** compare the contents of two buffers containing UTF-8 strings in a +** case-indendent fashion, using the same definition of case independence +** that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); + /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. @@ -6131,6 +6293,7 @@ SQLITE_API int sqlite3_unlock_notify( #endif #endif + /************** End of sqlite3.h *********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ /************** Include hash.h in the middle of sqliteInt.h ******************/ @@ -6149,7 +6312,7 @@ SQLITE_API int sqlite3_unlock_notify( ** This is the header file for the generic hash-table implemenation ** used in SQLite. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _SQLITE_HASH_H_ #define _SQLITE_HASH_H_ @@ -6266,70 +6429,70 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_ID 26 #define TK_INDEXED 27 #define TK_ABORT 28 -#define TK_AFTER 29 -#define TK_ANALYZE 30 -#define TK_ASC 31 -#define TK_ATTACH 32 -#define TK_BEFORE 33 -#define TK_BY 34 -#define TK_CASCADE 35 -#define TK_CAST 36 -#define TK_COLUMNKW 37 -#define TK_CONFLICT 38 -#define TK_DATABASE 39 -#define TK_DESC 40 -#define TK_DETACH 41 -#define TK_EACH 42 -#define TK_FAIL 43 -#define TK_FOR 44 -#define TK_IGNORE 45 -#define TK_INITIALLY 46 -#define TK_INSTEAD 47 -#define TK_LIKE_KW 48 -#define TK_MATCH 49 -#define TK_KEY 50 -#define TK_OF 51 -#define TK_OFFSET 52 -#define TK_PRAGMA 53 -#define TK_RAISE 54 -#define TK_REPLACE 55 -#define TK_RESTRICT 56 -#define TK_ROW 57 -#define TK_TRIGGER 58 -#define TK_VACUUM 59 -#define TK_VIEW 60 -#define TK_VIRTUAL 61 -#define TK_REINDEX 62 -#define TK_RENAME 63 -#define TK_CTIME_KW 64 -#define TK_ANY 65 -#define TK_OR 66 -#define TK_AND 67 -#define TK_IS 68 -#define TK_BETWEEN 69 -#define TK_IN 70 -#define TK_ISNULL 71 -#define TK_NOTNULL 72 -#define TK_NE 73 -#define TK_EQ 74 -#define TK_GT 75 -#define TK_LE 76 -#define TK_LT 77 -#define TK_GE 78 -#define TK_ESCAPE 79 -#define TK_BITAND 80 -#define TK_BITOR 81 -#define TK_LSHIFT 82 -#define TK_RSHIFT 83 -#define TK_PLUS 84 -#define TK_MINUS 85 -#define TK_STAR 86 -#define TK_SLASH 87 -#define TK_REM 88 -#define TK_CONCAT 89 -#define TK_COLLATE 90 -#define TK_UMINUS 91 -#define TK_UPLUS 92 +#define TK_ACTION 29 +#define TK_AFTER 30 +#define TK_ANALYZE 31 +#define TK_ASC 32 +#define TK_ATTACH 33 +#define TK_BEFORE 34 +#define TK_BY 35 +#define TK_CASCADE 36 +#define TK_CAST 37 +#define TK_COLUMNKW 38 +#define TK_CONFLICT 39 +#define TK_DATABASE 40 +#define TK_DESC 41 +#define TK_DETACH 42 +#define TK_EACH 43 +#define TK_FAIL 44 +#define TK_FOR 45 +#define TK_IGNORE 46 +#define TK_INITIALLY 47 +#define TK_INSTEAD 48 +#define TK_LIKE_KW 49 +#define TK_MATCH 50 +#define TK_NO 51 +#define TK_KEY 52 +#define TK_OF 53 +#define TK_OFFSET 54 +#define TK_PRAGMA 55 +#define TK_RAISE 56 +#define TK_REPLACE 57 +#define TK_RESTRICT 58 +#define TK_ROW 59 +#define TK_TRIGGER 60 +#define TK_VACUUM 61 +#define TK_VIEW 62 +#define TK_VIRTUAL 63 +#define TK_REINDEX 64 +#define TK_RENAME 65 +#define TK_CTIME_KW 66 +#define TK_ANY 67 +#define TK_OR 68 +#define TK_AND 69 +#define TK_IS 70 +#define TK_BETWEEN 71 +#define TK_IN 72 +#define TK_ISNULL 73 +#define TK_NOTNULL 74 +#define TK_NE 75 +#define TK_EQ 76 +#define TK_GT 77 +#define TK_LE 78 +#define TK_LT 79 +#define TK_GE 80 +#define TK_ESCAPE 81 +#define TK_BITAND 82 +#define TK_BITOR 83 +#define TK_LSHIFT 84 +#define TK_RSHIFT 85 +#define TK_PLUS 86 +#define TK_MINUS 87 +#define TK_STAR 88 +#define TK_SLASH 89 +#define TK_REM 90 +#define TK_CONCAT 91 +#define TK_COLLATE 92 #define TK_BITNOT 93 #define TK_STRING 94 #define TK_JOIN_KW 95 @@ -6344,28 +6507,28 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_ON 104 #define TK_DELETE 105 #define TK_UPDATE 106 -#define TK_INSERT 107 -#define TK_SET 108 -#define TK_DEFERRABLE 109 -#define TK_FOREIGN 110 -#define TK_DROP 111 -#define TK_UNION 112 -#define TK_ALL 113 -#define TK_EXCEPT 114 -#define TK_INTERSECT 115 -#define TK_SELECT 116 -#define TK_DISTINCT 117 -#define TK_DOT 118 -#define TK_FROM 119 -#define TK_JOIN 120 -#define TK_USING 121 -#define TK_ORDER 122 -#define TK_GROUP 123 -#define TK_HAVING 124 -#define TK_LIMIT 125 -#define TK_WHERE 126 -#define TK_INTO 127 -#define TK_VALUES 128 +#define TK_SET 107 +#define TK_DEFERRABLE 108 +#define TK_FOREIGN 109 +#define TK_DROP 110 +#define TK_UNION 111 +#define TK_ALL 112 +#define TK_EXCEPT 113 +#define TK_INTERSECT 114 +#define TK_SELECT 115 +#define TK_DISTINCT 116 +#define TK_DOT 117 +#define TK_FROM 118 +#define TK_JOIN 119 +#define TK_USING 120 +#define TK_ORDER 121 +#define TK_GROUP 122 +#define TK_HAVING 123 +#define TK_LIMIT 124 +#define TK_WHERE 125 +#define TK_INTO 126 +#define TK_VALUES 127 +#define TK_INSERT 128 #define TK_INTEGER 129 #define TK_FLOAT 130 #define TK_BLOB 131 @@ -6383,15 +6546,18 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); #define TK_TO_NUMERIC 143 #define TK_TO_INT 144 #define TK_TO_REAL 145 -#define TK_END_OF_FILE 146 -#define TK_ILLEGAL 147 -#define TK_SPACE 148 -#define TK_UNCLOSED_STRING 149 -#define TK_FUNCTION 150 -#define TK_COLUMN 151 -#define TK_AGG_FUNCTION 152 -#define TK_AGG_COLUMN 153 -#define TK_CONST_FUNC 154 +#define TK_ISNOT 146 +#define TK_END_OF_FILE 147 +#define TK_ILLEGAL 148 +#define TK_SPACE 149 +#define TK_UNCLOSED_STRING 150 +#define TK_FUNCTION 151 +#define TK_COLUMN 152 +#define TK_AGG_FUNCTION 153 +#define TK_AGG_COLUMN 154 +#define TK_CONST_FUNC 155 +#define TK_UMINUS 156 +#define TK_UPLUS 157 /************** End of parse.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -6409,11 +6575,12 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); # define double sqlite_int64 # define LONGDOUBLE_TYPE sqlite_int64 # ifndef SQLITE_BIG_DBL -# define SQLITE_BIG_DBL (0x7fffffffffffffff) +# define SQLITE_BIG_DBL (((sqlite3_int64)1)<<50) # endif # define SQLITE_OMIT_DATETIME_FUNCS 1 # define SQLITE_OMIT_TRACE 1 # undef SQLITE_MIXED_ENDIAN_64BIT_FLOAT +# undef SQLITE_HAVE_ISNAN #endif #ifndef SQLITE_BIG_DBL # define SQLITE_BIG_DBL (1e99) @@ -6455,6 +6622,10 @@ SQLITE_PRIVATE void sqlite3HashClear(Hash*); # define SQLITE_DEFAULT_FILE_FORMAT 1 #endif +#ifndef SQLITE_DEFAULT_RECURSIVE_TRIGGERS +# define SQLITE_DEFAULT_RECURSIVE_TRIGGERS 0 +#endif + /* ** Provide a default value for SQLITE_TEMP_STORE in case it is not specified ** on the command-line @@ -6683,6 +6854,7 @@ SQLITE_API void *sqlite3_wsd_find(void *K, int L); */ typedef struct AggInfo AggInfo; typedef struct AuthContext AuthContext; +typedef struct AutoincInfo AutoincInfo; typedef struct Bitvec Bitvec; typedef struct RowSet RowSet; typedef struct CollSeq CollSeq; @@ -6697,6 +6869,7 @@ typedef struct FuncDef FuncDef; typedef struct FuncDefHash FuncDefHash; typedef struct IdList IdList; typedef struct Index Index; +typedef struct IndexSample IndexSample; typedef struct KeyClass KeyClass; typedef struct KeyInfo KeyInfo; typedef struct Lookaside Lookaside; @@ -6711,10 +6884,11 @@ typedef struct StrAccum StrAccum; typedef struct Table Table; typedef struct TableLock TableLock; typedef struct Token Token; -typedef struct TriggerStack TriggerStack; +typedef struct TriggerPrg TriggerPrg; typedef struct TriggerStep TriggerStep; typedef struct Trigger Trigger; typedef struct UnpackedRecord UnpackedRecord; +typedef struct VTable VTable; typedef struct Walker Walker; typedef struct WherePlan WherePlan; typedef struct WhereInfo WhereInfo; @@ -6742,7 +6916,7 @@ typedef struct WhereLevel WhereLevel; ** subsystem. See comments in the source code for a detailed description ** of what each interface routine does. ** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** @(#) $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _BTREE_H_ #define _BTREE_H_ @@ -6826,8 +7000,8 @@ SQLITE_PRIVATE int sqlite3BtreeIsInTrans(Btree*); SQLITE_PRIVATE int sqlite3BtreeIsInReadTrans(Btree*); SQLITE_PRIVATE int sqlite3BtreeIsInBackup(Btree*); SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *, int, void(*)(void *)); -SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *); -SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *, int, u8); +SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *pBtree); +SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *pBtree, int iTab, u8 isWriteLock); SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *, int, int); SQLITE_PRIVATE const char *sqlite3BtreeGetFilename(Btree *); @@ -6847,7 +7021,7 @@ SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree*, int, int*); SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree*, int, int*); SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree*, int); -SQLITE_PRIVATE int sqlite3BtreeGetMeta(Btree*, int idx, u32 *pValue); +SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *pBtree, int idx, u32 *pValue); SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree*, int idx, u32 value); /* @@ -6881,13 +7055,6 @@ SQLITE_PRIVATE int sqlite3BtreeCursor( SQLITE_PRIVATE int sqlite3BtreeCursorSize(void); SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreeMoveto( - BtCursor*, - const void *pKey, - i64 nKey, - int bias, - int *pRes -); SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( BtCursor*, UnpackedRecord *pUnKey, @@ -6904,7 +7071,6 @@ SQLITE_PRIVATE int sqlite3BtreeFirst(BtCursor*, int *pRes); SQLITE_PRIVATE int sqlite3BtreeLast(BtCursor*, int *pRes); SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor*, int *pRes); SQLITE_PRIVATE int sqlite3BtreeEof(BtCursor*); -SQLITE_PRIVATE int sqlite3BtreeFlags(BtCursor*); SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor*, int *pRes); SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor*, i64 *pSize); SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor*, u32 offset, u32 amt, void*); @@ -6922,6 +7088,10 @@ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor*, u32 offset, u32 amt, void*); SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *); SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *); +#ifndef NDEBUG +SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor*); +#endif + #ifndef SQLITE_OMIT_BTREECOUNT SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *, i64 *); #endif @@ -6995,7 +7165,7 @@ SQLITE_PRIVATE int sqlite3BtreeHoldsAllMutexes(sqlite3*); ** or VDBE. The VDBE implements an abstract machine that runs a ** simple program to access and modify the underlying database. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _SQLITE_VDBE_H_ #define _SQLITE_VDBE_H_ @@ -7013,6 +7183,7 @@ typedef struct Vdbe Vdbe; */ typedef struct VdbeFunc VdbeFunc; typedef struct Mem Mem; +typedef struct SubProgram SubProgram; /* ** A single instruction of the virtual machine has an opcode @@ -7027,7 +7198,7 @@ struct VdbeOp { int p1; /* First operand */ int p2; /* Second parameter (often the jump destination) */ int p3; /* The third parameter */ - union { /* forth parameter */ + union { /* fourth parameter */ int i; /* Integer value if p4type==P4_INT32 */ void *p; /* Generic pointer */ char *z; /* Pointer to data for string (char array) types */ @@ -7037,9 +7208,10 @@ struct VdbeOp { VdbeFunc *pVdbeFunc; /* Used when p4type is P4_VDBEFUNC */ CollSeq *pColl; /* Used when p4type is P4_COLLSEQ */ Mem *pMem; /* Used when p4type is P4_MEM */ - sqlite3_vtab *pVtab; /* Used when p4type is P4_VTAB */ + VTable *pVtab; /* Used when p4type is P4_VTAB */ KeyInfo *pKeyInfo; /* Used when p4type is P4_KEYINFO */ int *ai; /* Used when p4type is P4_INTARRAY */ + SubProgram *pProgram; /* Used when p4type is P4_SUBPROGRAM */ } p4; #ifdef SQLITE_DEBUG char *zComment; /* Comment to improve readability */ @@ -7051,6 +7223,19 @@ struct VdbeOp { }; typedef struct VdbeOp VdbeOp; + +/* +** A sub-routine used to implement a trigger program. +*/ +struct SubProgram { + VdbeOp *aOp; /* Array of opcodes for sub-program */ + int nOp; /* Elements in aOp[] */ + int nMem; /* Number of memory cells required */ + int nCsr; /* Number of cursors required */ + int nRef; /* Number of pointers to this structure */ + void *token; /* id that may be used to recursive triggers */ +}; + /* ** A smaller version of VdbeOp used for the VdbeAddOpList() function because ** it takes up less space. @@ -7064,7 +7249,7 @@ struct VdbeOpList { typedef struct VdbeOpList VdbeOpList; /* -** Allowed values of VdbeOp.p3type +** Allowed values of VdbeOp.p4type */ #define P4_NOTUSED 0 /* The P4 parameter is not used */ #define P4_DYNAMIC (-1) /* Pointer to a string obtained from sqliteMalloc() */ @@ -7081,6 +7266,7 @@ typedef struct VdbeOpList VdbeOpList; #define P4_INT64 (-13) /* P4 is a 64-bit signed integer */ #define P4_INT32 (-14) /* P4 is a 32-bit signed integer */ #define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */ +#define P4_SUBPROGRAM (-18) /* P4 is a pointer to a SubProgram structure */ /* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure ** is made. That copy is freed when the Vdbe is finalized. But if the @@ -7135,12 +7321,12 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Real 130 /* same as TK_FLOAT */ #define OP_Sequence 6 #define OP_Savepoint 7 -#define OP_Ge 78 /* same as TK_GE */ +#define OP_Ge 80 /* same as TK_GE */ #define OP_RowKey 8 #define OP_SCopy 9 -#define OP_Eq 74 /* same as TK_EQ */ +#define OP_Eq 76 /* same as TK_EQ */ #define OP_OpenWrite 10 -#define OP_NotNull 72 /* same as TK_NOTNULL */ +#define OP_NotNull 74 /* same as TK_NOTNULL */ #define OP_If 11 #define OP_ToInt 144 /* same as TK_TO_INT */ #define OP_String8 94 /* same as TK_STRING */ @@ -7148,7 +7334,7 @@ typedef struct VdbeOpList VdbeOpList; #define OP_OpenRead 13 #define OP_Expire 14 #define OP_AutoCommit 15 -#define OP_Gt 75 /* same as TK_GT */ +#define OP_Gt 77 /* same as TK_GT */ #define OP_Pagecount 16 #define OP_IntegrityCk 17 #define OP_Sort 18 @@ -7156,89 +7342,89 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Trace 21 #define OP_Function 22 #define OP_IfNeg 23 -#define OP_And 67 /* same as TK_AND */ -#define OP_Subtract 85 /* same as TK_MINUS */ +#define OP_And 69 /* same as TK_AND */ +#define OP_Subtract 87 /* same as TK_MINUS */ #define OP_Noop 24 -#define OP_Return 25 -#define OP_Remainder 88 /* same as TK_REM */ -#define OP_NewRowid 26 -#define OP_Multiply 86 /* same as TK_STAR */ -#define OP_Variable 27 -#define OP_String 28 -#define OP_RealAffinity 29 -#define OP_VRename 30 -#define OP_ParseSchema 31 -#define OP_VOpen 32 -#define OP_Close 33 -#define OP_CreateIndex 34 -#define OP_IsUnique 35 -#define OP_NotFound 36 -#define OP_Int64 37 -#define OP_MustBeInt 38 -#define OP_Halt 39 -#define OP_Rowid 40 -#define OP_IdxLT 41 -#define OP_AddImm 42 -#define OP_Statement 43 -#define OP_RowData 44 -#define OP_MemMax 45 -#define OP_Or 66 /* same as TK_OR */ -#define OP_NotExists 46 -#define OP_Gosub 47 -#define OP_Divide 87 /* same as TK_SLASH */ -#define OP_Integer 48 +#define OP_Program 25 +#define OP_Return 26 +#define OP_Remainder 90 /* same as TK_REM */ +#define OP_NewRowid 27 +#define OP_Multiply 88 /* same as TK_STAR */ +#define OP_FkCounter 28 +#define OP_Variable 29 +#define OP_String 30 +#define OP_RealAffinity 31 +#define OP_VRename 32 +#define OP_ParseSchema 33 +#define OP_VOpen 34 +#define OP_Close 35 +#define OP_CreateIndex 36 +#define OP_IsUnique 37 +#define OP_NotFound 38 +#define OP_Int64 39 +#define OP_MustBeInt 40 +#define OP_Halt 41 +#define OP_Rowid 42 +#define OP_IdxLT 43 +#define OP_AddImm 44 +#define OP_RowData 45 +#define OP_MemMax 46 +#define OP_Or 68 /* same as TK_OR */ +#define OP_NotExists 47 +#define OP_Gosub 48 +#define OP_Divide 89 /* same as TK_SLASH */ +#define OP_Integer 49 #define OP_ToNumeric 143 /* same as TK_TO_NUMERIC*/ -#define OP_Prev 49 -#define OP_RowSetRead 50 -#define OP_Concat 89 /* same as TK_CONCAT */ -#define OP_RowSetAdd 51 -#define OP_BitAnd 80 /* same as TK_BITAND */ -#define OP_VColumn 52 -#define OP_CreateTable 53 -#define OP_Last 54 -#define OP_SeekLe 55 -#define OP_IsNull 71 /* same as TK_ISNULL */ -#define OP_IncrVacuum 56 -#define OP_IdxRowid 57 -#define OP_ShiftRight 83 /* same as TK_RSHIFT */ -#define OP_ResetCount 58 -#define OP_ContextPush 59 +#define OP_Prev 50 +#define OP_RowSetRead 51 +#define OP_Concat 91 /* same as TK_CONCAT */ +#define OP_RowSetAdd 52 +#define OP_BitAnd 82 /* same as TK_BITAND */ +#define OP_VColumn 53 +#define OP_CreateTable 54 +#define OP_Last 55 +#define OP_SeekLe 56 +#define OP_IsNull 73 /* same as TK_ISNULL */ +#define OP_IncrVacuum 57 +#define OP_IdxRowid 58 +#define OP_ShiftRight 85 /* same as TK_RSHIFT */ +#define OP_ResetCount 59 #define OP_Yield 60 #define OP_DropTrigger 61 #define OP_DropIndex 62 -#define OP_IdxGE 63 -#define OP_IdxDelete 64 -#define OP_Vacuum 65 -#define OP_IfNot 68 -#define OP_DropTable 69 -#define OP_SeekLt 70 -#define OP_MakeRecord 79 +#define OP_Param 63 +#define OP_IdxGE 64 +#define OP_IdxDelete 65 +#define OP_Vacuum 66 +#define OP_IfNot 67 +#define OP_DropTable 70 +#define OP_SeekLt 71 +#define OP_MakeRecord 72 #define OP_ToBlob 142 /* same as TK_TO_BLOB */ -#define OP_ResultRow 90 -#define OP_Delete 91 -#define OP_AggFinal 92 -#define OP_Compare 95 -#define OP_ShiftLeft 82 /* same as TK_LSHIFT */ -#define OP_Goto 96 -#define OP_TableLock 97 -#define OP_Clear 98 -#define OP_Le 76 /* same as TK_LE */ -#define OP_VerifyCookie 99 -#define OP_AggStep 100 +#define OP_ResultRow 81 +#define OP_Delete 92 +#define OP_AggFinal 95 +#define OP_Compare 96 +#define OP_ShiftLeft 84 /* same as TK_LSHIFT */ +#define OP_Goto 97 +#define OP_TableLock 98 +#define OP_Clear 99 +#define OP_Le 78 /* same as TK_LE */ +#define OP_VerifyCookie 100 +#define OP_AggStep 101 #define OP_ToText 141 /* same as TK_TO_TEXT */ #define OP_Not 19 /* same as TK_NOT */ #define OP_ToReal 145 /* same as TK_TO_REAL */ -#define OP_SetNumColumns 101 #define OP_Transaction 102 #define OP_VFilter 103 -#define OP_Ne 73 /* same as TK_NE */ +#define OP_Ne 75 /* same as TK_NE */ #define OP_VDestroy 104 -#define OP_ContextPop 105 -#define OP_BitOr 81 /* same as TK_BITOR */ -#define OP_Next 106 -#define OP_Count 107 -#define OP_IdxInsert 108 -#define OP_Lt 77 /* same as TK_LT */ +#define OP_BitOr 83 /* same as TK_BITOR */ +#define OP_Next 105 +#define OP_Count 106 +#define OP_IdxInsert 107 +#define OP_Lt 79 /* same as TK_LT */ +#define OP_FkIfZero 108 #define OP_SeekGe 109 #define OP_Insert 110 #define OP_Destroy 111 @@ -7252,7 +7438,7 @@ typedef struct VdbeOpList VdbeOpList; #define OP_Null 119 #define OP_Move 120 #define OP_Blob 121 -#define OP_Add 84 /* same as TK_PLUS */ +#define OP_Add 86 /* same as TK_PLUS */ #define OP_Rewind 122 #define OP_SeekGt 123 #define OP_VBegin 124 @@ -7290,17 +7476,17 @@ typedef struct VdbeOpList VdbeOpList; /* 0 */ 0x00, 0x01, 0x00, 0x00, 0x10, 0x08, 0x02, 0x00,\ /* 8 */ 0x00, 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00,\ /* 16 */ 0x02, 0x00, 0x01, 0x04, 0x04, 0x00, 0x00, 0x05,\ -/* 24 */ 0x00, 0x04, 0x02, 0x00, 0x02, 0x04, 0x00, 0x00,\ -/* 32 */ 0x00, 0x00, 0x02, 0x11, 0x11, 0x02, 0x05, 0x00,\ -/* 40 */ 0x02, 0x11, 0x04, 0x00, 0x00, 0x0c, 0x11, 0x01,\ -/* 48 */ 0x02, 0x01, 0x21, 0x08, 0x00, 0x02, 0x01, 0x11,\ -/* 56 */ 0x01, 0x02, 0x00, 0x00, 0x04, 0x00, 0x00, 0x11,\ -/* 64 */ 0x00, 0x00, 0x2c, 0x2c, 0x05, 0x00, 0x11, 0x05,\ -/* 72 */ 0x05, 0x15, 0x15, 0x15, 0x15, 0x15, 0x15, 0x00,\ -/* 80 */ 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,\ -/* 88 */ 0x2c, 0x2c, 0x00, 0x00, 0x00, 0x04, 0x02, 0x00,\ -/* 96 */ 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\ -/* 104 */ 0x00, 0x00, 0x01, 0x02, 0x08, 0x11, 0x00, 0x02,\ +/* 24 */ 0x00, 0x01, 0x04, 0x02, 0x00, 0x00, 0x02, 0x04,\ +/* 32 */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x11, 0x11, 0x02,\ +/* 40 */ 0x05, 0x00, 0x02, 0x11, 0x04, 0x00, 0x08, 0x11,\ +/* 48 */ 0x01, 0x02, 0x01, 0x21, 0x08, 0x00, 0x02, 0x01,\ +/* 56 */ 0x11, 0x01, 0x02, 0x00, 0x04, 0x00, 0x00, 0x02,\ +/* 64 */ 0x11, 0x00, 0x00, 0x05, 0x2c, 0x2c, 0x00, 0x11,\ +/* 72 */ 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\ +/* 80 */ 0x15, 0x00, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,\ +/* 88 */ 0x2c, 0x2c, 0x2c, 0x2c, 0x00, 0x04, 0x02, 0x00,\ +/* 96 */ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,\ +/* 104 */ 0x00, 0x01, 0x02, 0x08, 0x01, 0x11, 0x00, 0x02,\ /* 112 */ 0x02, 0x15, 0x00, 0x00, 0x10, 0x00, 0x00, 0x02,\ /* 120 */ 0x00, 0x02, 0x01, 0x11, 0x00, 0x00, 0x05, 0x00,\ /* 128 */ 0x11, 0x05, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,\ @@ -7332,11 +7518,12 @@ SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe*, int); SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe*, int); SQLITE_PRIVATE int sqlite3VdbeMakeLabel(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe*); -SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int); +SQLITE_PRIVATE void sqlite3VdbeMakeReady(Vdbe*,int,int,int,int,int,int); SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe*, int); SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe*); #ifdef SQLITE_DEBUG +SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *, int); SQLITE_PRIVATE void sqlite3VdbeTrace(Vdbe*,FILE*); #endif SQLITE_PRIVATE void sqlite3VdbeResetStepResult(Vdbe*); @@ -7347,6 +7534,8 @@ SQLITE_PRIVATE void sqlite3VdbeCountChanges(Vdbe*); SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe*); SQLITE_PRIVATE void sqlite3VdbeSetSql(Vdbe*, const char *z, int n, int); SQLITE_PRIVATE void sqlite3VdbeSwap(Vdbe*,Vdbe*); +SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe*, int*, int*); +SQLITE_PRIVATE void sqlite3VdbeProgramDelete(sqlite3 *, SubProgram *, int); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT SQLITE_PRIVATE int sqlite3VdbeReleaseMemory(int); @@ -7387,7 +7576,7 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe*, const char*, ...); ** subsystem. The page cache subsystem reads and writes a file a page ** at a time and provides a journal for rollback. ** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** @(#) $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _PAGER_H_ @@ -7460,14 +7649,21 @@ typedef struct PgHdr DbPage; */ /* Open and close a Pager connection. */ -SQLITE_PRIVATE int sqlite3PagerOpen(sqlite3_vfs *, Pager **ppPager, const char*, int,int,int); +SQLITE_PRIVATE int sqlite3PagerOpen( + sqlite3_vfs*, + Pager **ppPager, + const char*, + int, + int, + int, + void(*)(DbPage*) +); SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager); SQLITE_PRIVATE int sqlite3PagerReadFileheader(Pager*, int, unsigned char*); /* Functions used to configure a Pager object. */ SQLITE_PRIVATE void sqlite3PagerSetBusyhandler(Pager*, int(*)(void *), void *); -SQLITE_PRIVATE void sqlite3PagerSetReiniter(Pager*, void(*)(DbPage*)); -SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u16*); +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager*, u16*, int); SQLITE_PRIVATE int sqlite3PagerMaxPageCount(Pager*, int); SQLITE_PRIVATE void sqlite3PagerSetCachesize(Pager*, int); SQLITE_PRIVATE void sqlite3PagerSetSafetyLevel(Pager*,int,int); @@ -7500,6 +7696,7 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager*); SQLITE_PRIVATE int sqlite3PagerRollback(Pager*); SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int n); SQLITE_PRIVATE int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint); +SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager); /* Functions used to query pager state and configuration. */ SQLITE_PRIVATE u8 sqlite3PagerIsreadonly(Pager*); @@ -7515,11 +7712,6 @@ SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager*); /* Functions used to truncate the database file. */ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager*,Pgno); -/* Used by encryption extensions. */ -#ifdef SQLITE_HAS_CODEC -SQLITE_PRIVATE void sqlite3PagerSetCodec(Pager*,void*(*)(void*,void*,Pgno,int),void*); -#endif - /* Functions to support testing and debugging. */ #if !defined(NDEBUG) || defined(SQLITE_TEST) SQLITE_PRIVATE Pgno sqlite3PagerPagenumber(DbPage*); @@ -7555,7 +7747,7 @@ SQLITE_PRIVATE void sqlite3PagerRefdump(Pager*); ** This header file defines the interface that the sqlite page cache ** subsystem. ** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** @(#) $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _PCACHE_H_ @@ -7667,7 +7859,7 @@ SQLITE_PRIVATE int sqlite3PcachePageRefcount(PgHdr*); /* Return the total number of pages stored in the cache */ SQLITE_PRIVATE int sqlite3PcachePagecount(PCache*); -#ifdef SQLITE_CHECK_PAGES +#if defined(SQLITE_CHECK_PAGES) || defined(SQLITE_DEBUG) /* Iterate through all dirty pages currently stored in the cache. This ** interface is only available if SQLITE_CHECK_PAGES is defined when the ** library is built. @@ -7723,7 +7915,7 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); ** This header file is #include-ed by sqliteInt.h and thus ends up ** being included by every source file. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _SQLITE_OS_H_ #define _SQLITE_OS_H_ @@ -7930,6 +8122,11 @@ SQLITE_PRIVATE void sqlite3PCacheSetDefault(void); #define SHARED_FIRST (PENDING_BYTE+2) #define SHARED_SIZE 510 +/* +** Wrapper around OS specific sqlite3_os_init() function. +*/ +SQLITE_PRIVATE int sqlite3OsInit(void); + /* ** Functions for accessing sqlite3_file methods */ @@ -7998,7 +8195,7 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *); ** Source files should #include the sqliteInt.h file and let that file ** include this one indirectly. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ @@ -8049,7 +8246,7 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *); #define sqlite3MutexAlloc(X) ((sqlite3_mutex*)8) #define sqlite3MutexInit() SQLITE_OK #define sqlite3MutexEnd() -#endif /* defined(SQLITE_OMIT_MUTEX) */ +#endif /* defined(SQLITE_MUTEX_OMIT) */ /************** End of mutex.h ***********************************************/ /************** Continuing where we left off in sqliteInt.h ******************/ @@ -8068,10 +8265,6 @@ struct Db { u8 inTrans; /* 0: not writable. 1: Transaction. 2: Checkpoint */ u8 safety_level; /* How aggressive at syncing data to disk */ Schema *pSchema; /* Pointer to database schema (possibly shared) */ -#ifdef SQLITE_HAS_CODEC - void *pAux; /* Auxiliary data. Usually NULL */ - void (*xFreeAux)(void*); /* Routine to free pAux */ -#endif }; /* @@ -8090,6 +8283,7 @@ struct Schema { Hash tblHash; /* All tables indexed by name */ Hash idxHash; /* All (named) indices indexed by name */ Hash trigHash; /* All triggers indexed by name */ + Hash fkeyHash; /* All foreign keys by referenced table name */ Table *pSeqTab; /* The sqlite_sequence table used by AUTOINCREMENT */ u8 file_format; /* Schema format version for this file */ u8 enc; /* Text encoding used by this database */ @@ -8127,7 +8321,7 @@ struct Schema { ** The number of different kinds of things that can be limited ** using the sqlite3_limit() interface. */ -#define SQLITE_N_LIMIT (SQLITE_LIMIT_VARIABLE_NUMBER+1) +#define SQLITE_N_LIMIT (SQLITE_LIMIT_TRIGGER_DEPTH+1) /* ** Lookaside malloc is a set of fixed-size buffers that can be used @@ -8217,7 +8411,6 @@ struct sqlite3 { int nTable; /* Number of tables in the database */ CollSeq *pDfltColl; /* The default collating sequence (BINARY) */ i64 lastRowid; /* ROWID of most recent insert (see above) */ - i64 priorNewRowid; /* Last randomly generated ROWID */ u32 magic; /* Magic number for detect library misuse */ int nChange; /* Value returned by sqlite3_changes() */ int nTotalChange; /* Value returned by sqlite3_total_changes() */ @@ -8227,6 +8420,7 @@ struct sqlite3 { int iDb; /* When back is being initialized */ int newTnum; /* Rootpage of table being initialized */ u8 busy; /* TRUE if currently initializing */ + u8 orphanTrigger; /* Last statement is orphaned TEMP trigger */ } init; int nExtension; /* Number of loaded extensions */ void **aExtension; /* Array of shared library handles */ @@ -8267,21 +8461,20 @@ struct sqlite3 { #ifndef SQLITE_OMIT_VIRTUALTABLE Hash aModule; /* populated by sqlite3_create_module() */ Table *pVTab; /* vtab with active Connect/Create method */ - sqlite3_vtab **aVTrans; /* Virtual tables with open transactions */ + VTable **aVTrans; /* Virtual tables with open transactions */ int nVTrans; /* Allocated size of aVTrans */ + VTable *pDisconnect; /* Disconnect these in next sqlite3_prepare() */ #endif FuncDefHash aFunc; /* Hash table of connection functions */ Hash aCollSeq; /* All collating sequences */ BusyHandler busyHandler; /* Busy callback */ int busyTimeout; /* Busy handler timeout, in msec */ Db aDbStatic[2]; /* Static space for the 2 default backends */ -#ifdef SQLITE_SSE - sqlite3_stmt *pFetch; /* Used by SSE to fetch stored statements */ -#endif Savepoint *pSavepoint; /* List of active savepoints */ int nSavepoint; /* Number of non-transaction savepoints */ int nStatement; /* Number of nested statement-transactions */ u8 isTransactionSavepoint; /* True if the outermost savepoint is a TS */ + i64 nDeferredCons; /* Net deferred constraints this transaction. */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY /* The following variables are all protected by the STATIC_MASTER @@ -8336,9 +8529,9 @@ struct sqlite3 { #define SQLITE_LoadExtension 0x00020000 /* Enable load_extension */ #define SQLITE_RecoveryMode 0x00040000 /* Ignore schema errors */ -#define SQLITE_SharedCache 0x00080000 /* Cache sharing is enabled */ -#define SQLITE_CommitBusy 0x00200000 /* In the process of committing */ -#define SQLITE_ReverseOrder 0x00400000 /* Reverse unordered SELECTs */ +#define SQLITE_ReverseOrder 0x00100000 /* Reverse unordered SELECTs */ +#define SQLITE_RecTriggers 0x00200000 /* Enable recursive triggers */ +#define SQLITE_ForeignKeys 0x00400000 /* Enforce foreign key constraints */ /* ** Possible values for the sqlite.magic field. @@ -8425,6 +8618,7 @@ struct FuncDef { */ struct Savepoint { char *zName; /* Savepoint name (nul-terminated) */ + i64 nDeferredCons; /* Number of deferred fk violations */ Savepoint *pNext; /* Parent savepoint (if any) */ }; @@ -8545,6 +8739,57 @@ struct CollSeq { */ #define SQLITE_JUMPIFNULL 0x08 /* jumps if either operand is NULL */ #define SQLITE_STOREP2 0x10 /* Store result in reg[P2] rather than jump */ +#define SQLITE_NULLEQ 0x80 /* NULL=NULL */ + +/* +** An object of this type is created for each virtual table present in +** the database schema. +** +** If the database schema is shared, then there is one instance of this +** structure for each database connection (sqlite3*) that uses the shared +** schema. This is because each database connection requires its own unique +** instance of the sqlite3_vtab* handle used to access the virtual table +** implementation. sqlite3_vtab* handles can not be shared between +** database connections, even when the rest of the in-memory database +** schema is shared, as the implementation often stores the database +** connection handle passed to it via the xConnect() or xCreate() method +** during initialization internally. This database connection handle may +** then used by the virtual table implementation to access real tables +** within the database. So that they appear as part of the callers +** transaction, these accesses need to be made via the same database +** connection as that used to execute SQL operations on the virtual table. +** +** All VTable objects that correspond to a single table in a shared +** database schema are initially stored in a linked-list pointed to by +** the Table.pVTable member variable of the corresponding Table object. +** When an sqlite3_prepare() operation is required to access the virtual +** table, it searches the list for the VTable that corresponds to the +** database connection doing the preparing so as to use the correct +** sqlite3_vtab* handle in the compiled query. +** +** When an in-memory Table object is deleted (for example when the +** schema is being reloaded for some reason), the VTable objects are not +** deleted and the sqlite3_vtab* handles are not xDisconnect()ed +** immediately. Instead, they are moved from the Table.pVTable list to +** another linked list headed by the sqlite3.pDisconnect member of the +** corresponding sqlite3 structure. They are then deleted/xDisconnected +** next time a statement is prepared using said sqlite3*. This is done +** to avoid deadlock issues involving multiple sqlite3.mutex mutexes. +** Refer to comments above function sqlite3VtabUnlockList() for an +** explanation as to why it is safe to add an entry to an sqlite3.pDisconnect +** list without holding the corresponding sqlite3.mutex mutex. +** +** The memory for objects of this type is always allocated by +** sqlite3DbMalloc(), using the connection handle stored in VTable.db as +** the first argument. +*/ +struct VTable { + sqlite3 *db; /* Database connection associated with this table */ + Module *pMod; /* Pointer to module implementation */ + sqlite3_vtab *pVtab; /* Pointer to vtab instance */ + int nRef; /* Number of pointers to this structure */ + VTable *pNext; /* Next in linked list (see above) */ +}; /* ** Each SQL table is represented in memory by an instance of the @@ -8597,8 +8842,7 @@ struct Table { int addColOffset; /* Offset in CREATE TABLE stmt to add a new column */ #endif #ifndef SQLITE_OMIT_VIRTUALTABLE - Module *pMod; /* Pointer to the implementation of the module */ - sqlite3_vtab *pVtab; /* Pointer to the module instance */ + VTable *pVTable; /* List of VTable objects. */ int nModuleArg; /* Number of arguments to the module */ char **azModuleArg; /* Text of all module args. [0] is module name */ #endif @@ -8652,14 +8896,16 @@ struct Table { ** the from-table is created. The existence of the to-table is not checked. */ struct FKey { - Table *pFrom; /* The table that contains the REFERENCES clause */ + Table *pFrom; /* Table containing the REFERENCES clause (aka: Child) */ FKey *pNextFrom; /* Next foreign key in pFrom */ - char *zTo; /* Name of table that the key points to */ + char *zTo; /* Name of table that the key points to (aka: Parent) */ + FKey *pNextTo; /* Next foreign key on table named zTo */ + FKey *pPrevTo; /* Previous foreign key on table named zTo */ int nCol; /* Number of columns in this key */ + /* EV: R-30323-21917 */ u8 isDeferred; /* True if constraint checking is deferred till COMMIT */ - u8 updateConf; /* How to resolve conflicts that occur on UPDATE */ - u8 deleteConf; /* How to resolve conflicts that occur on DELETE */ - u8 insertConf; /* How to resolve conflicts that occur on INSERT */ + u8 aAction[2]; /* ON DELETE and ON UPDATE actions, respectively */ + Trigger *apTrigger[2]; /* Triggers for aAction[] actions */ struct sColMap { /* Mapping of columns in pFrom to columns in zTo */ int iFrom; /* Index of column in pFrom */ char *zCol; /* Name of column in zTo. If 0 use PRIMARY KEY */ @@ -8791,6 +9037,20 @@ struct Index { Schema *pSchema; /* Schema containing this index */ u8 *aSortOrder; /* Array of size Index.nColumn. True==DESC, False==ASC */ char **azColl; /* Array of collation sequence names for index */ + IndexSample *aSample; /* Array of SQLITE_INDEX_SAMPLES samples */ +}; + +/* +** Each sample stored in the sqlite_stat2 table is represented in memory +** using a structure of this type. +*/ +struct IndexSample { + union { + char *z; /* Value if eType is SQLITE_TEXT or SQLITE_BLOB */ + double r; /* Value if eType is SQLITE_FLOAT or SQLITE_INTEGER */ + } u; + u8 eType; /* SQLITE_NULL, SQLITE_INTEGER ... etc. */ + u8 nByte; /* Size in byte of text or blob. */ }; /* @@ -8941,11 +9201,13 @@ struct Expr { *********************************************************************/ int iTable; /* TK_COLUMN: cursor number of table holding column - ** TK_REGISTER: register number */ + ** TK_REGISTER: register number + ** TK_TRIGGER: 1 -> new, 0 -> old */ i16 iColumn; /* TK_COLUMN: column index. -1 for rowid */ i16 iAgg; /* Which entry in pAggInfo->aCol[] or ->aFunc[] */ i16 iRightJoinTable; /* If EP_FromJoin, the right table of the join */ - u16 flags2; /* Second set of flags. EP2_... */ + u8 flags2; /* Second set of flags. EP2_... */ + u8 op2; /* If a TK_REGISTER, the original value of Expr.op */ AggInfo *pAggInfo; /* Used by TK_AGG_COLUMN and TK_AGG_FUNCTION */ Table *pTab; /* Table for TK_COLUMN expressions. */ #if SQLITE_MAX_EXPR_DEPTH>0 @@ -9356,6 +9618,22 @@ struct SelectDest { int nMem; /* Number of registers allocated */ }; +/* +** During code generation of statements that do inserts into AUTOINCREMENT +** tables, the following information is attached to the Table.u.autoInc.p +** pointer of each autoincrement table to record some side information that +** the code generator needs. We have to keep per-table autoincrement +** information in case inserts are down within triggers. Triggers do not +** normally coordinate their activities, but we do need to coordinate the +** loading and saving of autoincrement information. +*/ +struct AutoincInfo { + AutoincInfo *pNext; /* Next info block in a list of them all */ + Table *pTab; /* Table this info block refers to */ + int iDb; /* Index in sqlite3.aDb[] of database holding pTab */ + int regCtr; /* Memory register holding the rowid counter */ +}; + /* ** Size of the column cache */ @@ -9363,6 +9641,31 @@ struct SelectDest { # define SQLITE_N_COLCACHE 10 #endif +/* +** At least one instance of the following structure is created for each +** trigger that may be fired while parsing an INSERT, UPDATE or DELETE +** statement. All such objects are stored in the linked list headed at +** Parse.pTriggerPrg and deleted once statement compilation has been +** completed. +** +** A Vdbe sub-program that implements the body and WHEN clause of trigger +** TriggerPrg.pTrigger, assuming a default ON CONFLICT clause of +** TriggerPrg.orconf, is stored in the TriggerPrg.pProgram variable. +** The Parse.pTriggerPrg list never contains two entries with the same +** values for both pTrigger and orconf. +** +** The TriggerPrg.oldmask variable is set to a mask of old.* columns +** accessed (or set to 0 for triggers fired as a result of INSERT +** statements). +*/ +struct TriggerPrg { + Trigger *pTrigger; /* Trigger this program was coded from */ + int orconf; /* Default ON CONFLICT policy */ + SubProgram *pProgram; /* Program implementing pTrigger/orconf */ + u32 oldmask; /* Mask of old.* columns accessed */ + TriggerPrg *pNext; /* Next entry in Parse.pTriggerPrg list */ +}; + /* ** An SQL parser context. A copy of this structure is passed through ** the parser and down into all the parser action routine in order to @@ -9414,6 +9717,8 @@ struct Parse { } aColCache[SQLITE_N_COLCACHE]; /* One for each column cache entry */ u32 writeMask; /* Start a write transaction on these databases */ u32 cookieMask; /* Bitmask of schema verified databases */ + u8 isMultiWrite; /* True if statement may affect/insert multiple rows */ + u8 mayAbort; /* True if statement may throw an ABORT exception */ int cookieGoto; /* Address of OP_Goto to cookie verifier subroutine */ int cookieValue[SQLITE_MAX_ATTACHED+2]; /* Values of cookies to verify */ #ifndef SQLITE_OMIT_SHARED_CACHE @@ -9422,6 +9727,16 @@ struct Parse { #endif int regRowid; /* Register holding rowid of CREATE TABLE entry */ int regRoot; /* Register holding root page number for new objects */ + AutoincInfo *pAinc; /* Information about AUTOINCREMENT counters */ + int nMaxArg; /* Max args passed to user function by sub-program */ + + /* Information used while coding trigger programs. */ + Parse *pToplevel; /* Parse structure for main program (or NULL) */ + Table *pTriggerTab; /* Table triggers are being coded for */ + u32 oldmask; /* Mask of old.* columns referenced */ + u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ + u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ + u8 disableTriggers; /* True to disable triggers */ /* Above is constant between recursions. Below is reset before and after ** each recursion */ @@ -9434,14 +9749,11 @@ struct Parse { int nAliasAlloc; /* Number of allocated slots for aAlias[] */ int *aAlias; /* Register used to hold aliased result */ u8 explain; /* True if the EXPLAIN flag is found on the query */ - Token sErrToken; /* The token at which the error occurred */ Token sNameToken; /* Token with unqualified schema object name */ Token sLastToken; /* The last token parsed */ - const char *zSql; /* All SQL text */ const char *zTail; /* All SQL text past the last semicolon parsed */ Table *pNewTable; /* A table being constructed by CREATE TABLE */ Trigger *pNewTrigger; /* Trigger under construct by a CREATE TRIGGER */ - TriggerStack *trigStack; /* Trigger actions being coded */ const char *zAuthContext; /* The 6th parameter to db->xAuth callbacks */ #ifndef SQLITE_OMIT_VIRTUALTABLE Token sArg; /* Complete text of a module argument */ @@ -9451,6 +9763,7 @@ struct Parse { #endif int nHeight; /* Expression tree height of current sub-select */ Table *pZombieTab; /* List of Table objects to delete after code gen */ + TriggerPrg *pTriggerPrg; /* Linked list of coded triggers */ }; #ifdef SQLITE_OMIT_VIRTUALTABLE @@ -9471,11 +9784,12 @@ struct AuthContext { /* ** Bitfield flags for P5 value in OP_Insert and OP_Delete */ -#define OPFLAG_NCHANGE 1 /* Set to update db->nChange */ -#define OPFLAG_LASTROWID 2 /* Set to update db->lastRowid */ -#define OPFLAG_ISUPDATE 4 /* This OP_Insert is an sql UPDATE */ -#define OPFLAG_APPEND 8 /* This is likely to be an append */ -#define OPFLAG_USESEEKRESULT 16 /* Try to avoid a seek in BtreeInsert() */ +#define OPFLAG_NCHANGE 0x01 /* Set to update db->nChange */ +#define OPFLAG_LASTROWID 0x02 /* Set to update db->lastRowid */ +#define OPFLAG_ISUPDATE 0x04 /* This OP_Insert is an sql UPDATE */ +#define OPFLAG_APPEND 0x08 /* This is likely to be an append */ +#define OPFLAG_USESEEKRESULT 0x10 /* Try to avoid a seek in BtreeInsert() */ +#define OPFLAG_CLEARCACHE 0x20 /* Clear pseudo-table cache in OP_Column */ /* * Each trigger present in the database schema is stored as an instance of @@ -9493,7 +9807,7 @@ struct AuthContext { * containing the SQL statements specified as the trigger program. */ struct Trigger { - char *name; /* The name of the trigger */ + char *zName; /* The name of the trigger */ char *table; /* The table or view to which the trigger applies */ u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT */ u8 tr_tm; /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ @@ -9555,60 +9869,18 @@ struct Trigger { * */ struct TriggerStep { - int op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */ - int orconf; /* OE_Rollback etc. */ + u8 op; /* One of TK_DELETE, TK_UPDATE, TK_INSERT, TK_SELECT */ + u8 orconf; /* OE_Rollback etc. */ Trigger *pTrig; /* The trigger that this step is a part of */ - - Select *pSelect; /* Valid for SELECT and sometimes - INSERT steps (when pExprList == 0) */ - Token target; /* Target table for DELETE, UPDATE, INSERT. Quoted */ - Expr *pWhere; /* Valid for DELETE, UPDATE steps */ - ExprList *pExprList; /* Valid for UPDATE statements and sometimes - INSERT steps (when pSelect == 0) */ - IdList *pIdList; /* Valid for INSERT statements only */ + Select *pSelect; /* SELECT statment or RHS of INSERT INTO .. SELECT ... */ + Token target; /* Target table for DELETE, UPDATE, INSERT */ + Expr *pWhere; /* The WHERE clause for DELETE or UPDATE steps */ + ExprList *pExprList; /* SET clause for UPDATE. VALUES clause for INSERT */ + IdList *pIdList; /* Column names for INSERT */ TriggerStep *pNext; /* Next in the link-list */ TriggerStep *pLast; /* Last element in link-list. Valid for 1st elem only */ }; -/* - * An instance of struct TriggerStack stores information required during code - * generation of a single trigger program. While the trigger program is being - * coded, its associated TriggerStack instance is pointed to by the - * "pTriggerStack" member of the Parse structure. - * - * The pTab member points to the table that triggers are being coded on. The - * newIdx member contains the index of the vdbe cursor that points at the temp - * table that stores the new.* references. If new.* references are not valid - * for the trigger being coded (for example an ON DELETE trigger), then newIdx - * is set to -1. The oldIdx member is analogous to newIdx, for old.* references. - * - * The ON CONFLICT policy to be used for the trigger program steps is stored - * as the orconf member. If this is OE_Default, then the ON CONFLICT clause - * specified for individual triggers steps is used. - * - * struct TriggerStack has a "pNext" member, to allow linked lists to be - * constructed. When coding nested triggers (triggers fired by other triggers) - * each nested trigger stores its parent trigger's TriggerStack as the "pNext" - * pointer. Once the nested trigger has been coded, the pNext value is restored - * to the pTriggerStack member of the Parse stucture and coding of the parent - * trigger continues. - * - * Before a nested trigger is coded, the linked list pointed to by the - * pTriggerStack is scanned to ensure that the trigger is not about to be coded - * recursively. If this condition is detected, the nested trigger is not coded. - */ -struct TriggerStack { - Table *pTab; /* Table that triggers are currently being coded on */ - int newIdx; /* Index of vdbe cursor to "new" temp table */ - int oldIdx; /* Index of vdbe cursor to "old" temp table */ - u32 newColMask; - u32 oldColMask; - int orconf; /* Current orconf policy */ - int ignoreJump; /* where to jump to for a RAISE(IGNORE) */ - Trigger *pTrigger; /* The trigger currently being coded */ - TriggerStack *pNext; /* Next trigger down on the trigger stack */ -}; - /* ** The following structure contains information used by the sqliteFix... ** routines as they walk the parse tree to make database references @@ -9679,7 +9951,9 @@ struct Sqlite3Config { ** initially be zero, however. */ int isInit; /* True after initialization has finished */ int inProgress; /* True while initialization in progress */ + int isMutexInit; /* True after mutexes are initialized */ int isMallocInit; /* True after malloc is initialized */ + int isPCacheInit; /* True after malloc is initialized */ sqlite3_mutex *pInitMutex; /* Mutex used by sqlite3_initialize() */ int nRefInitMutex; /* Number of users of pInitMutex */ }; @@ -9771,9 +10045,9 @@ SQLITE_PRIVATE int sqlite3Corrupt(void); ** Internal function prototypes */ SQLITE_PRIVATE int sqlite3StrICmp(const char *, const char *); -SQLITE_PRIVATE int sqlite3StrNICmp(const char *, const char *, int); SQLITE_PRIVATE int sqlite3IsNumber(const char*, int*, u8); SQLITE_PRIVATE int sqlite3Strlen30(const char*); +#define sqlite3StrNICmp sqlite3_strnicmp SQLITE_PRIVATE int sqlite3MallocInit(void); SQLITE_PRIVATE void sqlite3MallocEnd(void); @@ -9912,6 +10186,13 @@ SQLITE_PRIVATE int sqlite3ViewGetColumnNames(Parse*,Table*); SQLITE_PRIVATE void sqlite3DropTable(Parse*, SrcList*, int, int); SQLITE_PRIVATE void sqlite3DeleteTable(Table*); +#ifndef SQLITE_OMIT_AUTOINCREMENT +SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse); +SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse); +#else +# define sqlite3AutoincrementBegin(X) +# define sqlite3AutoincrementEnd(X) +#endif SQLITE_PRIVATE void sqlite3Insert(Parse*, SrcList*, ExprList*, Select*, IdList*, int); SQLITE_PRIVATE void *sqlite3ArrayAllocate(sqlite3*,void*,int,int,int*,int*,int*); SQLITE_PRIVATE IdList *sqlite3IdListAppend(sqlite3*, IdList*, Token*); @@ -9926,7 +10207,7 @@ SQLITE_PRIVATE void sqlite3SrcListShiftJoinType(SrcList*); SQLITE_PRIVATE void sqlite3SrcListAssignCursors(Parse*, SrcList*); SQLITE_PRIVATE void sqlite3IdListDelete(sqlite3*, IdList*); SQLITE_PRIVATE void sqlite3SrcListDelete(sqlite3*, SrcList*); -SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, +SQLITE_PRIVATE Index *sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*, Token*, int, int); SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int); SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*); @@ -9989,14 +10270,17 @@ SQLITE_PRIVATE int sqlite3ExprIsConstantNotJoin(Expr*); SQLITE_PRIVATE int sqlite3ExprIsConstantOrFunction(Expr*); SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr*, int*); SQLITE_PRIVATE int sqlite3IsRowid(const char*); -SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int); +SQLITE_PRIVATE void sqlite3GenerateRowDelete(Parse*, Table*, int, int, int, Trigger *, int); SQLITE_PRIVATE void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int*); SQLITE_PRIVATE int sqlite3GenerateIndexKey(Parse*, Index*, int, int, int); SQLITE_PRIVATE void sqlite3GenerateConstraintChecks(Parse*,Table*,int,int, int*,int,int,int,int,int*); -SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int,int,int); +SQLITE_PRIVATE void sqlite3CompleteInsertion(Parse*, Table*, int, int, int*, int, int, int); SQLITE_PRIVATE int sqlite3OpenTableAndIndices(Parse*, Table*, int, int); SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse*, int, int); +SQLITE_PRIVATE void sqlite3MultiWrite(Parse*); +SQLITE_PRIVATE void sqlite3MayAbort(Parse*); +SQLITE_PRIVATE void sqlite3HaltConstraint(Parse*, int, char*, int); SQLITE_PRIVATE Expr *sqlite3ExprDup(sqlite3*,Expr*,int); SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3*,ExprList*,int); SQLITE_PRIVATE SrcList *sqlite3SrcListDup(sqlite3*,SrcList*,int); @@ -10030,24 +10314,30 @@ SQLITE_PRIVATE void sqlite3DropTrigger(Parse*, SrcList*, int); SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse*, Trigger*); SQLITE_PRIVATE Trigger *sqlite3TriggersExist(Parse *, Table*, int, ExprList*, int *pMask); SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *, Table *); -SQLITE_PRIVATE int sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *, - int, int, int, int, u32*, u32*); +SQLITE_PRIVATE void sqlite3CodeRowTrigger(Parse*, Trigger *, int, ExprList*, int, Table *, + int, int, int); +SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect(Parse *, Trigger *, Table *, int, int, int); void sqliteViewTriggers(Parse*, Table*, Expr*, int, ExprList*); SQLITE_PRIVATE void sqlite3DeleteTriggerStep(sqlite3*, TriggerStep*); SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3*,Select*); SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep(sqlite3*,Token*, IdList*, - ExprList*,Select*,int); -SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, int); + ExprList*,Select*,u8); +SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep(sqlite3*,Token*,ExprList*, Expr*, u8); SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep(sqlite3*,Token*, Expr*); SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3*, Trigger*); SQLITE_PRIVATE void sqlite3UnlinkAndDeleteTrigger(sqlite3*,int,const char*); +SQLITE_PRIVATE u32 sqlite3TriggerOldmask(Parse*,Trigger*,ExprList*,Table*,int); +# define sqlite3ParseToplevel(p) ((p)->pToplevel ? (p)->pToplevel : (p)) #else # define sqlite3TriggersExist(B,C,D,E,F) 0 # define sqlite3DeleteTrigger(A,B) # define sqlite3DropTriggerPtr(A,B) # define sqlite3UnlinkAndDeleteTrigger(A,B,C) -# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I,J,K,L) 0 +# define sqlite3CodeRowTrigger(A,B,C,D,E,F,G,H,I) +# define sqlite3CodeRowTriggerDirect(A,B,C,D,E,F) # define sqlite3TriggerList(X, Y) 0 +# define sqlite3ParseToplevel(p) p +# define sqlite3TriggerOldmask(A,B,C,D,E) 0 #endif SQLITE_PRIVATE int sqlite3JoinType(Parse*, Token*, Token*, Token*); @@ -10058,6 +10348,7 @@ SQLITE_PRIVATE void sqlite3AuthRead(Parse*,Expr*,Schema*,SrcList*); SQLITE_PRIVATE int sqlite3AuthCheck(Parse*,int, const char*, const char*, const char*); SQLITE_PRIVATE void sqlite3AuthContextPush(Parse*, AuthContext*, const char*); SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext*); +SQLITE_PRIVATE int sqlite3AuthReadCol(Parse*, const char *, const char *, int); #else # define sqlite3AuthRead(a,b,c,d) # define sqlite3AuthCheck(a,b,c,d,e) SQLITE_OK @@ -10117,7 +10408,7 @@ SQLITE_PRIVATE int sqlite3VarintLen(u64 v); #define putVarint sqlite3PutVarint -SQLITE_PRIVATE void sqlite3IndexAffinityStr(Vdbe *, Index *); +SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *, Index *); SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *, Table *); SQLITE_PRIVATE char sqlite3CompareAffinity(Expr *pExpr, char aff2); SQLITE_PRIVATE int sqlite3IndexAffinityOk(Expr *pExpr, char idx_affinity); @@ -10143,6 +10434,9 @@ SQLITE_PRIVATE void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, SQLITE_PRIVATE void sqlite3ValueFree(sqlite3_value*); SQLITE_PRIVATE sqlite3_value *sqlite3ValueNew(sqlite3 *); SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *, const void*, int); +#ifdef SQLITE_ENABLE_STAT2 +SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *, u8, char *, int, int *); +#endif SQLITE_PRIVATE int sqlite3ValueFromExpr(sqlite3 *, Expr *, u8, u8, sqlite3_value **); SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8); #ifndef SQLITE_AMALGAMATION @@ -10164,16 +10458,17 @@ SQLITE_PRIVATE void sqlite3SelectPrep(Parse*, Select*, NameContext*); SQLITE_PRIVATE int sqlite3ResolveExprNames(NameContext*, Expr*); SQLITE_PRIVATE void sqlite3ResolveSelectNames(Parse*, Select*, NameContext*); SQLITE_PRIVATE int sqlite3ResolveOrderGroupBy(Parse*, Select*, ExprList*, const char*); -SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int); +SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int, int); SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *); SQLITE_PRIVATE void sqlite3AlterBeginAddColumn(Parse *, SrcList *); -SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(sqlite3*, CollSeq *, const char*); +SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq(sqlite3*, u8, CollSeq *, const char*); SQLITE_PRIVATE char sqlite3AffinityType(const char*); SQLITE_PRIVATE void sqlite3Analyze(Parse*, Token*, Token*); SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler*); SQLITE_PRIVATE int sqlite3FindDb(sqlite3*, Token*); SQLITE_PRIVATE int sqlite3FindDbName(sqlite3 *, const char *); SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3*,int iDB); +SQLITE_PRIVATE void sqlite3DeleteIndexSamples(Index*); SQLITE_PRIVATE void sqlite3DefaultRowEst(Index*); SQLITE_PRIVATE void sqlite3RegisterLikeFunctions(sqlite3*, int); SQLITE_PRIVATE int sqlite3IsLikeFunction(sqlite3*,Expr*,int*,char*); @@ -10225,21 +10520,25 @@ SQLITE_PRIVATE int sqlite3Utf8To8(unsigned char*); #endif #ifdef SQLITE_OMIT_VIRTUALTABLE -# define sqlite3VtabClear(X) +# define sqlite3VtabClear(Y) # define sqlite3VtabSync(X,Y) SQLITE_OK # define sqlite3VtabRollback(X) # define sqlite3VtabCommit(X) # define sqlite3VtabInSync(db) 0 +# define sqlite3VtabLock(X) +# define sqlite3VtabUnlock(X) +# define sqlite3VtabUnlockList(X) #else SQLITE_PRIVATE void sqlite3VtabClear(Table*); SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **); SQLITE_PRIVATE int sqlite3VtabRollback(sqlite3 *db); SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db); +SQLITE_PRIVATE void sqlite3VtabLock(VTable *); +SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *); +SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3*); # define sqlite3VtabInSync(db) ((db)->nVTrans>0 && (db)->aVTrans==0) #endif SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse*,Table*); -SQLITE_PRIVATE void sqlite3VtabLock(sqlite3_vtab*); -SQLITE_PRIVATE void sqlite3VtabUnlock(sqlite3*, sqlite3_vtab*); SQLITE_PRIVATE void sqlite3VtabBeginParse(Parse*, Token*, Token*, Token*); SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse*, Token*); SQLITE_PRIVATE void sqlite3VtabArgInit(Parse*); @@ -10247,7 +10546,7 @@ SQLITE_PRIVATE void sqlite3VtabArgExtend(Parse*, Token*); SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3*, int, const char *, char **); SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse*, Table*); SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3*, int, const char *); -SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, sqlite3_vtab *); +SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *, VTable *); SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction(sqlite3 *,FuncDef*, int nArg, Expr*); SQLITE_PRIVATE void sqlite3InvalidFunction(sqlite3_context*,int,sqlite3_value**); SQLITE_PRIVATE int sqlite3TransferBindings(sqlite3_stmt *, sqlite3_stmt *); @@ -10255,7 +10554,34 @@ SQLITE_PRIVATE int sqlite3Reprepare(Vdbe*); SQLITE_PRIVATE void sqlite3ExprListCheckLength(Parse*, ExprList*, const char*); SQLITE_PRIVATE CollSeq *sqlite3BinaryCompareCollSeq(Parse *, Expr *, Expr *); SQLITE_PRIVATE int sqlite3TempInMemory(const sqlite3*); - +SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3*, Table*); + +/* Declarations for functions in fkey.c. All of these are replaced by +** no-op macros if OMIT_FOREIGN_KEY is defined. In this case no foreign +** key functionality is available. If OMIT_TRIGGER is defined but +** OMIT_FOREIGN_KEY is not, only some of the functions are no-oped. In +** this case foreign keys are parsed, but no other functionality is +** provided (enforcement of FK constraints requires the triggers sub-system). +*/ +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) +SQLITE_PRIVATE void sqlite3FkCheck(Parse*, Table*, int, int); +SQLITE_PRIVATE void sqlite3FkDropTable(Parse*, SrcList *, Table*); +SQLITE_PRIVATE void sqlite3FkActions(Parse*, Table*, ExprList*, int); +SQLITE_PRIVATE int sqlite3FkRequired(Parse*, Table*, int*, int); +SQLITE_PRIVATE u32 sqlite3FkOldmask(Parse*, Table*); +SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *); +#else + #define sqlite3FkActions(a,b,c,d) + #define sqlite3FkCheck(a,b,c,d) + #define sqlite3FkDropTable(a,b,c) + #define sqlite3FkOldmask(a,b) 0 + #define sqlite3FkRequired(a,b,c,d) 0 +#endif +#ifndef SQLITE_OMIT_FOREIGN_KEY +SQLITE_PRIVATE void sqlite3FkDelete(Table*); +#else + #define sqlite3FkDelete(a) +#endif /* @@ -10317,11 +10643,6 @@ SQLITE_PRIVATE void sqlite3ConnectionClosed(sqlite3 *db); #define sqlite3ConnectionClosed(x) #endif - -#ifdef SQLITE_SSE -#include "sseInt.h" -#endif - #ifdef SQLITE_DEBUG SQLITE_PRIVATE void sqlite3ParserTrace(FILE*, char *); #endif @@ -10357,8 +10678,6 @@ SQLITE_PRIVATE void (*sqlite3IoTrace)(const char*,...); ************************************************************************* ** ** This file contains definitions of global variables and contants. -** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ */ @@ -10498,10 +10817,12 @@ SQLITE_PRIVATE SQLITE_WSD struct Sqlite3Config sqlite3Config = { 0, /* nPage */ 0, /* mxParserStack */ 0, /* sharedCacheEnabled */ - /* All the rest need to always be zero */ + /* All the rest should always be initialized to zero */ 0, /* isInit */ 0, /* inProgress */ + 0, /* isMutexInit */ 0, /* isMallocInit */ + 0, /* isPCacheInit */ 0, /* pInitMutex */ 0, /* nRefInitMutex */ }; @@ -10551,7 +10872,7 @@ SQLITE_PRIVATE int sqlite3PendingByte = 0x40000000; ** This module implements the sqlite3_status() interface and related ** functionality. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -10678,7 +10999,7 @@ SQLITE_API int sqlite3_db_status( ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file. ** All other code has file scope. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ ** ** SQLite processes all times and dates as Julian Day numbers. The ** dates and times are stored as the number of days since noon @@ -11107,7 +11428,7 @@ static sqlite3_int64 localtimeOffset(DateTime *p){ x.tz = 0; x.validJD = 0; computeJD(&x); - t = x.iJD/1000 - 21086676*(i64)10000; + t = (time_t)(x.iJD/1000 - 21086676*(i64)10000); #ifdef HAVE_LOCALTIME_R { struct tm sLocal; @@ -11119,7 +11440,7 @@ static sqlite3_int64 localtimeOffset(DateTime *p){ y.m = sLocal.tm_min; y.s = sLocal.tm_sec; } -#elif defined(HAVE_LOCALTIME_S) +#elif defined(HAVE_LOCALTIME_S) && HAVE_LOCALTIME_S { struct tm sLocal; localtime_s(&sLocal, &t); @@ -11783,7 +12104,7 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ ** This file contains OS interface code that is common to all ** architectures. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #define _SQLITE_OS_C_ 1 #undef _SQLITE_OS_C_ @@ -11806,13 +12127,13 @@ SQLITE_PRIVATE void sqlite3RegisterDateTimeFunctions(void){ ** */ #if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0) - #define DO_OS_MALLOC_TEST if (1) { \ - void *pTstAlloc = sqlite3Malloc(10); \ - if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ - sqlite3_free(pTstAlloc); \ + #define DO_OS_MALLOC_TEST(x) if (!x || !sqlite3IsMemJournal(x)) { \ + void *pTstAlloc = sqlite3Malloc(10); \ + if (!pTstAlloc) return SQLITE_IOERR_NOMEM; \ + sqlite3_free(pTstAlloc); \ } #else - #define DO_OS_MALLOC_TEST + #define DO_OS_MALLOC_TEST(x) #endif /* @@ -11830,33 +12151,33 @@ SQLITE_PRIVATE int sqlite3OsClose(sqlite3_file *pId){ return rc; } SQLITE_PRIVATE int sqlite3OsRead(sqlite3_file *id, void *pBuf, int amt, i64 offset){ - DO_OS_MALLOC_TEST; + DO_OS_MALLOC_TEST(id); return id->pMethods->xRead(id, pBuf, amt, offset); } SQLITE_PRIVATE int sqlite3OsWrite(sqlite3_file *id, const void *pBuf, int amt, i64 offset){ - DO_OS_MALLOC_TEST; + DO_OS_MALLOC_TEST(id); return id->pMethods->xWrite(id, pBuf, amt, offset); } SQLITE_PRIVATE int sqlite3OsTruncate(sqlite3_file *id, i64 size){ return id->pMethods->xTruncate(id, size); } SQLITE_PRIVATE int sqlite3OsSync(sqlite3_file *id, int flags){ - DO_OS_MALLOC_TEST; + DO_OS_MALLOC_TEST(id); return id->pMethods->xSync(id, flags); } SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){ - DO_OS_MALLOC_TEST; + DO_OS_MALLOC_TEST(id); return id->pMethods->xFileSize(id, pSize); } SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){ - DO_OS_MALLOC_TEST; + DO_OS_MALLOC_TEST(id); return id->pMethods->xLock(id, lockType); } SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){ return id->pMethods->xUnlock(id, lockType); } SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){ - DO_OS_MALLOC_TEST; + DO_OS_MALLOC_TEST(id); return id->pMethods->xCheckReservedLock(id, pResOut); } SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){ @@ -11882,8 +12203,12 @@ SQLITE_PRIVATE int sqlite3OsOpen( int *pFlagsOut ){ int rc; - DO_OS_MALLOC_TEST; - rc = pVfs->xOpen(pVfs, zPath, pFile, flags, pFlagsOut); + DO_OS_MALLOC_TEST(0); + /* 0x7f1f is a mask of SQLITE_OPEN_ flags that are valid to be passed + ** down into the VFS layer. Some SQLITE_OPEN_ flags (for example, + ** SQLITE_OPEN_FULLMUTEX or SQLITE_OPEN_SHAREDCACHE) are blocked before + ** reaching the VFS. */ + rc = pVfs->xOpen(pVfs, zPath, pFile, flags & 0x7f1f, pFlagsOut); assert( rc==SQLITE_OK || pFile->pMethods==0 ); return rc; } @@ -11896,7 +12221,7 @@ SQLITE_PRIVATE int sqlite3OsAccess( int flags, int *pResOut ){ - DO_OS_MALLOC_TEST; + DO_OS_MALLOC_TEST(0); return pVfs->xAccess(pVfs, zPath, flags, pResOut); } SQLITE_PRIVATE int sqlite3OsFullPathname( @@ -11959,6 +12284,19 @@ SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *pFile){ return rc; } +/* +** This function is a wrapper around the OS specific implementation of +** sqlite3_os_init(). The purpose of the wrapper is to provide the +** ability to simulate a malloc failure, so that the handling of an +** error in sqlite3_os_init() by the upper layers can be tested. +*/ +SQLITE_PRIVATE int sqlite3OsInit(void){ + void *p = sqlite3_malloc(10); + if( p==0 ) return SQLITE_NOMEM; + sqlite3_free(p); + return sqlite3_os_init(); +} + /* ** The list of all registered VFS implementations. */ @@ -12063,7 +12401,7 @@ SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){ ** ************************************************************************* ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -12162,7 +12500,7 @@ SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){ ** are merely placeholders. Real drivers must be substituted using ** sqlite3_config() before SQLite will operate. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -12226,7 +12564,7 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){ ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -12375,7 +12713,7 @@ SQLITE_PRIVATE void sqlite3MemSetDefault(void){ ** This file contains implementations of the low-level memory allocation ** routines specified in the sqlite3_mem_methods object. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -12824,7 +13162,7 @@ SQLITE_PRIVATE int sqlite3MemdebugMallocCount(){ ** This version of the memory allocation subsystem is included ** in the build only if SQLITE_ENABLE_MEMSYS3 is defined. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -13378,6 +13716,7 @@ static int memsys3Init(void *NotUsed){ */ static void memsys3Shutdown(void *NotUsed){ UNUSED_PARAMETER(NotUsed); + mem3.mutex = 0; return; } @@ -13504,7 +13843,7 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){ ** allocation subsystem for use by SQLite. ** ** This version of the memory allocation subsystem omits all -** use of malloc(). The SQLite user supplies a block of memory +** use of malloc(). The application gives SQLite a block of memory ** before calling sqlite3_initialize() from which allocations ** are made and returned by the xMalloc() and xRealloc() ** implementations. Once sqlite3_initialize() has been called, @@ -13514,7 +13853,30 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){ ** This version of the memory allocation subsystem is included ** in the build only if SQLITE_ENABLE_MEMSYS5 is defined. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** This memory allocator uses the following algorithm: +** +** 1. All memory allocations sizes are rounded up to a power of 2. +** +** 2. If two adjacent free blocks are the halves of a larger block, +** then the two blocks are coalesed into the single larger block. +** +** 3. New memory is allocated from the first available free block. +** +** This algorithm is described in: J. M. Robson. "Bounds for Some Functions +** Concerning Dynamic Storage Allocation". Journal of the Association for +** Computing Machinery, Volume 21, Number 8, July 1974, pages 491-499. +** +** Let n be the size of the largest allocation divided by the minimum +** allocation size (after rounding all sizes up to a power of 2.) Let M +** be the maximum amount of memory ever outstanding at one time. Let +** N be the total amount of memory available for allocation. Robson +** proved that this memory allocator will never breakdown due to +** fragmentation as long as the following constraint holds: +** +** N >= M*(1 + log2(n)/2) - n + 1 +** +** The sqlite3_status() logic tracks the maximum values of n and M so +** that an application can, at any time, verify this constraint. */ /* @@ -13527,6 +13889,9 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){ ** A minimum allocation is an instance of the following structure. ** Larger allocations are an array of these structures where the ** size of the array is a power of 2. +** +** The size of this object must be a power of two. That fact is +** verified in memsys5Init(). */ typedef struct Mem5Link Mem5Link; struct Mem5Link { @@ -13535,16 +13900,16 @@ struct Mem5Link { }; /* -** Maximum size of any allocation is ((1<=0 && i0 ); + /* Keep track of the maximum allocation request. Even unfulfilled ** requests are counted */ if( (u32)nByte>mem5.maxRequest ){ mem5.maxRequest = nByte; } + /* Abort if the requested allocation size is larger than the largest + ** power of two that we can represent using 32-bit signed integers. + */ + if( nByte > 0x40000000 ){ + return 0; + } + /* Round nByte up to the next valid power of two */ - for(iFullSz=mem5.nAtom, iLogsize=0; iFullSz=0 && iBlock0 ); - assert( mem5.currentOut>=(size*mem5.nAtom) ); + assert( mem5.currentOut>=(size*mem5.szAtom) ); mem5.currentCount--; - mem5.currentOut -= size*mem5.nAtom; + mem5.currentOut -= size*mem5.szAtom; assert( mem5.currentOut>0 || mem5.currentCount==0 ); assert( mem5.currentCount>0 || mem5.currentOut==0 ); mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize; - while( iLogsize>iLogsize) & 1 ){ iBuddy = iBlock - size; @@ -13806,28 +14193,36 @@ static void *memsys5Malloc(int nBytes){ /* ** Free memory. +** +** The outer layer memory allocator prevents this routine from +** being called with pPrior==0. */ static void memsys5Free(void *pPrior){ - if( pPrior==0 ){ -assert(0); - return; - } + assert( pPrior!=0 ); memsys5Enter(); memsys5FreeUnsafe(pPrior); memsys5Leave(); } /* -** Change the size of an existing memory allocation +** Change the size of an existing memory allocation. +** +** The outer layer memory allocator prevents this routine from +** being called with pPrior==0. +** +** nBytes is always a value obtained from a prior call to +** memsys5Round(). Hence nBytes is always a non-negative power +** of two. If nBytes==0 that means that an oversize allocation +** (an allocation larger than 0x40000000) was requested and this +** routine should return 0 without freeing pPrior. */ static void *memsys5Realloc(void *pPrior, int nBytes){ int nOld; void *p; - if( pPrior==0 ){ - return memsys5Malloc(nBytes); - } - if( nBytes<=0 ){ - memsys5Free(pPrior); + assert( pPrior!=0 ); + assert( (nBytes&(nBytes-1))==0 ); + assert( nBytes>=0 ); + if( nBytes==0 ){ return 0; } nOld = memsys5Size(pPrior); @@ -13845,14 +14240,31 @@ static void *memsys5Realloc(void *pPrior, int nBytes){ } /* -** Round up a request size to the next valid allocation size. +** Round up a request size to the next valid allocation size. If +** the allocation is too large to be handled by this allocation system, +** return 0. +** +** All allocations must be a power of two and must be expressed by a +** 32-bit signed integer. Hence the largest allocation is 0x40000000 +** or 1073741824 bytes. */ static int memsys5Roundup(int n){ int iFullSz; - for(iFullSz=mem5.nAtom; iFullSz 0x40000000 ) return 0; + for(iFullSz=mem5.szAtom; iFullSz 0 +** memsys5Log(2) -> 1 +** memsys5Log(4) -> 2 +** memsys5Log(5) -> 3 +** memsys5Log(8) -> 3 +** memsys5Log(9) -> 4 +*/ static int memsys5Log(int iValue){ int iLog; for(iLog=0; (1<mem5.nAtom ){ - mem5.nAtom = mem5.nAtom << 1; + mem5.szAtom = (1<mem5.szAtom ){ + mem5.szAtom = mem5.szAtom << 1; } - mem5.nBlock = (nByte / (mem5.nAtom+sizeof(u8))); + mem5.nBlock = (nByte / (mem5.szAtom+sizeof(u8))); mem5.zPool = zByte; - mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.nAtom]; + mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.szAtom]; for(ii=0; ii<=LOGMAX; ii++){ mem5.aiFreelist[ii] = -1; @@ -13900,6 +14323,11 @@ static int memsys5Init(void *NotUsed){ assert((iOffset+nAlloc)>mem5.nBlock); } + /* If a mutex is required for normal operation, allocate one */ + if( sqlite3GlobalConfig.bMemstat==0 ){ + mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM); + } + return SQLITE_OK; } @@ -13908,15 +14336,16 @@ static int memsys5Init(void *NotUsed){ */ static void memsys5Shutdown(void *NotUsed){ UNUSED_PARAMETER(NotUsed); + mem5.mutex = 0; return; } +#ifdef SQLITE_TEST /* ** Open the file indicated and write a log of all unfreed memory ** allocations into that log. */ SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){ -#ifdef SQLITE_DEBUG FILE *out; int i, j, n; int nMinLog; @@ -13932,10 +14361,10 @@ SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){ } } memsys5Enter(); - nMinLog = memsys5Log(mem5.nAtom); + nMinLog = memsys5Log(mem5.szAtom); for(i=0; i<=LOGMAX && i+nMinLog<32; i++){ for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){} - fprintf(out, "freelist items of size %d: %d\n", mem5.nAtom << i, n); + fprintf(out, "freelist items of size %d: %d\n", mem5.szAtom << i, n); } fprintf(out, "mem5.nAlloc = %llu\n", mem5.nAlloc); fprintf(out, "mem5.totalAlloc = %llu\n", mem5.totalAlloc); @@ -13951,10 +14380,8 @@ SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){ }else{ fclose(out); } -#else - UNUSED_PARAMETER(zFilename); -#endif } +#endif /* ** This routine is the only routine in this file with external @@ -13995,9 +14422,19 @@ SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){ ** This file contains code that is common across all mutex implementations. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ +#if defined(SQLITE_DEBUG) && !defined(SQLITE_MUTEX_OMIT) +/* +** For debugging purposes, record when the mutex subsystem is initialized +** and uninitialized so that we can assert() if there is an attempt to +** allocate a mutex while the system is uninitialized. +*/ +static SQLITE_WSD int mutexIsInit = 0; +#endif /* SQLITE_DEBUG */ + + #ifndef SQLITE_MUTEX_OMIT /* ** Initialize the mutex system. @@ -14010,34 +14447,22 @@ SQLITE_PRIVATE int sqlite3MutexInit(void){ ** install a mutex implementation via sqlite3_config() prior to ** sqlite3_initialize() being called. This block copies pointers to ** the default implementation into the sqlite3GlobalConfig structure. - ** - ** The danger is that although sqlite3_config() is not a threadsafe - ** API, sqlite3_initialize() is, and so multiple threads may be - ** attempting to run this function simultaneously. To guard write - ** access to the sqlite3GlobalConfig structure, the 'MASTER' static mutex - ** is obtained before modifying it. */ - sqlite3_mutex_methods *p = sqlite3DefaultMutex(); - sqlite3_mutex *pMaster = 0; - - rc = p->xMutexInit(); - if( rc==SQLITE_OK ){ - pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER); - assert(pMaster); - p->xMutexEnter(pMaster); - assert( sqlite3GlobalConfig.mutex.xMutexAlloc==0 - || sqlite3GlobalConfig.mutex.xMutexAlloc==p->xMutexAlloc - ); - if( !sqlite3GlobalConfig.mutex.xMutexAlloc ){ - sqlite3GlobalConfig.mutex = *p; - } - p->xMutexLeave(pMaster); - } - }else{ - rc = sqlite3GlobalConfig.mutex.xMutexInit(); + sqlite3_mutex_methods *pFrom = sqlite3DefaultMutex(); + sqlite3_mutex_methods *pTo = &sqlite3GlobalConfig.mutex; + + memcpy(pTo, pFrom, offsetof(sqlite3_mutex_methods, xMutexAlloc)); + memcpy(&pTo->xMutexFree, &pFrom->xMutexFree, + sizeof(*pTo) - offsetof(sqlite3_mutex_methods, xMutexFree)); + pTo->xMutexAlloc = pFrom->xMutexAlloc; } + rc = sqlite3GlobalConfig.mutex.xMutexInit(); } +#ifdef SQLITE_DEBUG + GLOBAL(int, mutexIsInit) = 1; +#endif + return rc; } @@ -14050,6 +14475,11 @@ SQLITE_PRIVATE int sqlite3MutexEnd(void){ if( sqlite3GlobalConfig.mutex.xMutexEnd ){ rc = sqlite3GlobalConfig.mutex.xMutexEnd(); } + +#ifdef SQLITE_DEBUG + GLOBAL(int, mutexIsInit) = 0; +#endif + return rc; } @@ -14067,6 +14497,7 @@ SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){ if( !sqlite3GlobalConfig.bCoreMutex ){ return 0; } + assert( GLOBAL(int, mutexIsInit) ); return sqlite3GlobalConfig.mutex.xMutexAlloc(id); } @@ -14126,7 +14557,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ } #endif -#endif /* SQLITE_OMIT_MUTEX */ +#endif /* SQLITE_MUTEX_OMIT */ /************** End of mutex.c ***********************************************/ /************** Begin file mutex_noop.c **************************************/ @@ -14157,7 +14588,7 @@ SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){ ** that does error checking on mutexes to make sure they are being ** called correctly. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ @@ -14331,7 +14762,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ ************************************************************************* ** This file contains the C functions that implement mutexes for OS/2 ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -14606,7 +15037,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ ************************************************************************* ** This file contains the C functions that implement mutexes for pthreads ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -14685,6 +15116,7 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; } **
  • SQLITE_MUTEX_STATIC_MEM2 **
  • SQLITE_MUTEX_STATIC_PRNG **
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_LRU2 ** ** ** The first two constants cause sqlite3_mutex_alloc() to create @@ -14698,7 +15130,7 @@ static int pthreadMutexEnd(void){ return SQLITE_OK; } ** might return such a mutex in response to SQLITE_MUTEX_FAST. ** ** The other allowed parameters to sqlite3_mutex_alloc() each return -** a pointer to a static preexisting mutex. Three static mutexes are +** a pointer to a static preexisting mutex. Six static mutexes are ** used by the current version of SQLite. Future versions of SQLite ** may add additional static mutexes. Static mutexes are for internal ** use by SQLite only. Applications that use SQLite mutexes should @@ -14936,7 +15368,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ ************************************************************************* ** This file contains the C functions that implement mutexes for win32 ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -15017,13 +15449,14 @@ static long winMutex_lock = 0; static int winMutexInit(void){ /* The first to increment to 1 does actual initialization */ - if( InterlockedIncrement(&winMutex_lock)==1 ){ + if( InterlockedCompareExchange(&winMutex_lock, 1, 0)==0 ){ int i; - for(i=0; i -**
  • SQLITE_MUTEX_FAST 0 -**
  • SQLITE_MUTEX_RECURSIVE 1 -**
  • SQLITE_MUTEX_STATIC_MASTER 2 -**
  • SQLITE_MUTEX_STATIC_MEM 3 -**
  • SQLITE_MUTEX_STATIC_PRNG 4 +**
  • SQLITE_MUTEX_FAST +**
  • SQLITE_MUTEX_RECURSIVE +**
  • SQLITE_MUTEX_STATIC_MASTER +**
  • SQLITE_MUTEX_STATIC_MEM +**
  • SQLITE_MUTEX_STATIC_MEM2 +**
  • SQLITE_MUTEX_STATIC_PRNG +**
  • SQLITE_MUTEX_STATIC_LRU +**
  • SQLITE_MUTEX_STATIC_LRU2 ** ** ** The first two constants cause sqlite3_mutex_alloc() to create @@ -15072,7 +15508,7 @@ static int winMutexEnd(void){ ** might return such a mutex in response to SQLITE_MUTEX_FAST. ** ** The other allowed parameters to sqlite3_mutex_alloc() each return -** a pointer to a static preexisting mutex. Three static mutexes are +** a pointer to a static preexisting mutex. Six static mutexes are ** used by the current version of SQLite. Future versions of SQLite ** may add additional static mutexes. Static mutexes are for internal ** use by SQLite only. Applications that use SQLite mutexes should @@ -15101,7 +15537,7 @@ static sqlite3_mutex *winMutexAlloc(int iType){ default: { assert( winMutex_isInit==1 ); assert( iType-2 >= 0 ); - assert( iType-2 < sizeof(winMutex_staticMutexes)/sizeof(winMutex_staticMutexes[0]) ); + assert( iType-2 < ArraySize(winMutex_staticMutexes) ); p = &winMutex_staticMutexes[iType-2]; p->id = iType; break; @@ -15219,7 +15655,7 @@ SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){ ** ** Memory allocation functions used throughout sqlite. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -15248,7 +15684,9 @@ SQLITE_API void sqlite3_soft_heap_limit(int n){ }else{ iLimit = n; } +#ifndef SQLITE_OMIT_AUTOINIT sqlite3_initialize(); +#endif if( iLimit>0 ){ sqlite3MemoryAlarm(softHeapLimitEnforcer, 0, iLimit); }else{ @@ -15293,13 +15731,11 @@ static SQLITE_WSD struct Mem0Global { ** The alarm callback and its arguments. The mem0.mutex lock will ** be held while the callback is running. Recursive calls into ** the memory subsystem are allowed, but no new callbacks will be - ** issued. The alarmBusy variable is set to prevent recursive - ** callbacks. + ** issued. */ sqlite3_int64 alarmThreshold; void (*alarmCallback)(void*, sqlite3_int64,int); void *alarmArg; - int alarmBusy; /* ** Pointers to the end of sqlite3GlobalConfig.pScratch and @@ -15308,7 +15744,7 @@ static SQLITE_WSD struct Mem0Global { */ u32 *aScratchFree; u32 *aPageFree; -} mem0 = { 62560955, 0, 0, 0, 0, 0, 0, 0, 0 }; +} mem0 = { 0, 0, 0, 0, 0, 0, 0, 0 }; #define mem0 GLOBAL(struct Mem0Global, mem0) @@ -15425,15 +15861,16 @@ static void sqlite3MallocAlarm(int nByte){ void (*xCallback)(void*,sqlite3_int64,int); sqlite3_int64 nowUsed; void *pArg; - if( mem0.alarmCallback==0 || mem0.alarmBusy ) return; - mem0.alarmBusy = 1; + if( mem0.alarmCallback==0 ) return; xCallback = mem0.alarmCallback; nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED); pArg = mem0.alarmArg; + mem0.alarmCallback = 0; sqlite3_mutex_leave(mem0.mutex); xCallback(pArg, nowUsed, nByte); sqlite3_mutex_enter(mem0.mutex); - mem0.alarmBusy = 0; + mem0.alarmCallback = xCallback; + mem0.alarmArg = pArg; } /* @@ -15471,15 +15908,12 @@ static int mallocWithAlarm(int n, void **pp){ */ SQLITE_PRIVATE void *sqlite3Malloc(int n){ void *p; - if( n<=0 || NEVER(n>=0x7fffff00) ){ - /* The NEVER(n>=0x7fffff00) term is added out of paranoia. We want to make - ** absolutely sure that there is nothing within SQLite that can cause a - ** memory allocation of a number of bytes which is near the maximum signed - ** integer value and thus cause an integer overflow inside of the xMalloc() - ** implementation. The n>=0x7fffff00 gives us 255 bytes of headroom. The - ** test should never be true because SQLITE_MAX_LENGTH should be much - ** less than 0x7fffff00 and it should catch large memory allocations - ** before they reach this point. */ + if( n<=0 || n>=0x7fffff00 ){ + /* A memory allocation of a number of bytes which is near the maximum + ** signed integer value might cause an integer overflow inside of the + ** xMalloc(). Hence we limit the maximum size to 0x7fffff00, giving + ** 255 bytes of overhead. SQLite itself will never use anything near + ** this amount. The only way to reach the limit is with sqlite3_malloc() */ p = 0; }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); @@ -15632,9 +16066,7 @@ SQLITE_PRIVATE int sqlite3MallocSize(void *p){ } SQLITE_PRIVATE int sqlite3DbMallocSize(sqlite3 *db, void *p){ assert( db==0 || sqlite3_mutex_held(db->mutex) ); - if( p==0 ){ - return 0; - }else if( isLookaside(db, p) ){ + if( isLookaside(db, p) ){ return db->lookaside.sz; }else{ return sqlite3GlobalConfig.m.xSize(p); @@ -15681,36 +16113,37 @@ SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){ if( pOld==0 ){ return sqlite3Malloc(nBytes); } - if( nBytes<=0 || NEVER(nBytes>=0x7fffff00) ){ - /* The NEVER(...) term is explained in comments on sqlite3Malloc() */ + if( nBytes<=0 ){ sqlite3_free(pOld); return 0; } + if( nBytes>=0x7fffff00 ){ + /* The 0x7ffff00 limit term is explained in comments on sqlite3Malloc() */ + return 0; + } nOld = sqlite3MallocSize(pOld); - if( sqlite3GlobalConfig.bMemstat ){ + nNew = sqlite3GlobalConfig.m.xRoundup(nBytes); + if( nOld==nNew ){ + pNew = pOld; + }else if( sqlite3GlobalConfig.bMemstat ){ sqlite3_mutex_enter(mem0.mutex); sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes); - nNew = sqlite3GlobalConfig.m.xRoundup(nBytes); - if( nOld==nNew ){ - pNew = pOld; - }else{ - if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= - mem0.alarmThreshold ){ - sqlite3MallocAlarm(nNew-nOld); - } + if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= + mem0.alarmThreshold ){ + sqlite3MallocAlarm(nNew-nOld); + } + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); + if( pNew==0 && mem0.alarmCallback ){ + sqlite3MallocAlarm(nBytes); pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); - if( pNew==0 && mem0.alarmCallback ){ - sqlite3MallocAlarm(nBytes); - pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); - } - if( pNew ){ - nNew = sqlite3MallocSize(pNew); - sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld); - } + } + if( pNew ){ + nNew = sqlite3MallocSize(pNew); + sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld); } sqlite3_mutex_leave(mem0.mutex); }else{ - pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nBytes); + pNew = sqlite3GlobalConfig.m.xRealloc(pOld, nNew); } return pNew; } @@ -15931,7 +16364,7 @@ SQLITE_PRIVATE int sqlite3ApiExit(sqlite3* db, int rc){ ** an historical reference. Most of the "enhancements" have been backed ** out so that the functionality is now the same as standard printf(). ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ ** ************************************************************************** ** @@ -16901,7 +17334,7 @@ SQLITE_PRIVATE void sqlite3DebugPrintf(const char *zFormat, ...){ ** Random numbers are used by some of the database backends in order ** to generate random integer keys for tables or random filenames. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ @@ -17047,7 +17480,7 @@ SQLITE_PRIVATE void sqlite3PrngResetState(void){ ** This file contains routines used to translate between UTF-8, ** UTF-16, UTF-16BE, and UTF-16LE. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ ** ** Notes on UTF-8: ** @@ -17089,19 +17522,11 @@ SQLITE_PRIVATE void sqlite3PrngResetState(void){ ** 6000 lines long) it was split up into several smaller files and ** this header information was factored out. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _VDBEINT_H_ #define _VDBEINT_H_ -/* -** intToKey() and keyToInt() used to transform the rowid. But with -** the latest versions of the design they are no-ops. -*/ -#define keyToInt(X) (X) -#define intToKey(X) (X) - - /* ** SQL is translated into a sequence of instructions to be ** executed by a virtual machine. Each instruction is an instance @@ -17138,16 +17563,12 @@ struct VdbeCursor { Bool atFirst; /* True if pointing to first entry */ Bool useRandomRowid; /* Generate new record numbers semi-randomly */ Bool nullRow; /* True if pointing to a row with no data */ - Bool pseudoTable; /* This is a NEW or OLD pseudo-tables of a trigger */ - Bool ephemPseudoTable; Bool deferredMoveto; /* A call to sqlite3BtreeMoveto() is needed */ Bool isTable; /* True if a table requiring integer keys */ Bool isIndex; /* True if an index containing keys only - no data */ i64 movetoTarget; /* Argument to the deferred sqlite3BtreeMoveto() */ Btree *pBt; /* Separate file holding temporary table */ - int nData; /* Number of bytes in pData */ - char *pData; /* Data for a NEW or OLD pseudo-table */ - i64 iKey; /* Key for the NEW or OLD pseudo-table row */ + int pseudoTableReg; /* Register holding pseudotable content. */ KeyInfo *pKeyInfo; /* Info about index keys needed by index cursors */ int nField; /* Number of fields in the header */ i64 seqCount; /* Sequence counter */ @@ -17159,11 +17580,15 @@ struct VdbeCursor { int seekResult; /* Cached information about the header for the data record that the - ** cursor is currently pointing to. Only valid if cacheValid is true. + ** cursor is currently pointing to. Only valid if cacheStatus matches + ** Vdbe.cacheCtr. Vdbe.cacheCtr will never take on the value of + ** CACHE_STALE and so setting cacheStatus=CACHE_STALE guarantees that + ** the cache is out of date. + ** ** aRow might point to (ephemeral) data for the current row, or it might ** be NULL. */ - int cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ + u32 cacheStatus; /* Cache is valid if this matches Vdbe.cacheCtr */ int payloadSize; /* Total number of bytes in the record */ u32 *aType; /* Type values for all entries in the record */ u32 *aOffset; /* Cached offsets to the start of each columns data */ @@ -17171,6 +17596,39 @@ struct VdbeCursor { }; typedef struct VdbeCursor VdbeCursor; +/* +** When a sub-program is executed (OP_Program), a structure of this type +** is allocated to store the current value of the program counter, as +** well as the current memory cell array and various other frame specific +** values stored in the Vdbe struct. When the sub-program is finished, +** these values are copied back to the Vdbe from the VdbeFrame structure, +** restoring the state of the VM to as it was before the sub-program +** began executing. +** +** Frames are stored in a linked list headed at Vdbe.pParent. Vdbe.pParent +** is the parent of the current frame, or zero if the current frame +** is the main Vdbe program. +*/ +typedef struct VdbeFrame VdbeFrame; +struct VdbeFrame { + Vdbe *v; /* VM this frame belongs to */ + int pc; /* Program Counter */ + Op *aOp; /* Program instructions */ + int nOp; /* Size of aOp array */ + Mem *aMem; /* Array of memory cells */ + int nMem; /* Number of entries in aMem */ + VdbeCursor **apCsr; /* Element of Vdbe cursors */ + u16 nCursor; /* Number of entries in apCsr */ + void *token; /* Copy of SubProgram.token */ + int nChildMem; /* Number of memory cells for child frame */ + int nChildCsr; /* Number of cursors for child frame */ + i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ + int nChange; /* Statement changes (Vdbe.nChanges) */ + VdbeFrame *pParent; /* Parent of this frame */ +}; + +#define VdbeFrameMem(p) ((Mem *)&((u8 *)p)[ROUND8(sizeof(VdbeFrame))]) + /* ** A value for VdbeCursor.cacheValid that means the cache is always invalid. */ @@ -17193,6 +17651,7 @@ struct Mem { int nZero; /* Used when bit MEM_Zero is set in flags */ FuncDef *pDef; /* Used only when flags==MEM_Agg */ RowSet *pRowSet; /* Used only when flags==MEM_RowSet */ + VdbeFrame *pFrame; /* Used when flags==MEM_Frame */ } u; double r; /* Real value */ sqlite3 *db; /* The associated database connection */ @@ -17226,6 +17685,7 @@ struct Mem { #define MEM_Real 0x0008 /* Value is a real number */ #define MEM_Blob 0x0010 /* Value is a BLOB */ #define MEM_RowSet 0x0020 /* Value is a RowSet object */ +#define MEM_Frame 0x0040 /* Value is a VdbeFrame object */ #define MEM_TypeMask 0x00ff /* Mask of type bits */ /* Whenever Mem contains a valid string or blob representation, one of @@ -17305,21 +17765,6 @@ struct Set { HashElem *prev; /* Previously accessed hash elemen */ }; -/* -** A Context stores the last insert rowid, the last statement change count, -** and the current statement change count (i.e. changes since last statement). -** The current keylist is also stored in the context. -** Elements of Context structure type make up the ContextStack, which is -** updated by the ContextPush and ContextPop opcodes (used by triggers). -** The context is pushed before executing a trigger a popped when the -** trigger finishes. -*/ -typedef struct Context Context; -struct Context { - i64 lastRowid; /* Last insert rowid (sqlite3.lastRowid) */ - int nChange; /* Statement changes (Vdbe.nChanges) */ -}; - /* ** An instance of the virtual machine. This structure contains the complete ** state of the virtual machine. @@ -17336,36 +17781,32 @@ struct Context { ** method function. */ struct Vdbe { - sqlite3 *db; /* The whole database */ - Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ - int nOp; /* Number of instructions in the program */ - int nOpAlloc; /* Number of slots allocated for aOp[] */ - Op *aOp; /* Space to hold the virtual machine's program */ - int nLabel; /* Number of labels used */ - int nLabelAlloc; /* Number of slots allocated in aLabel[] */ - int *aLabel; /* Space to hold the labels */ - Mem **apArg; /* Arguments to currently executing user function */ - Mem *aColName; /* Column names to return */ - int nCursor; /* Number of slots in apCsr[] */ - VdbeCursor **apCsr; /* One element of this array for each open cursor */ - int nVar; /* Number of entries in aVar[] */ - Mem *aVar; /* Values for the OP_Variable opcode. */ - char **azVar; /* Name of variables */ - int okVar; /* True if azVar[] has been initialized */ + sqlite3 *db; /* The database connection that owns this statement */ + Vdbe *pPrev,*pNext; /* Linked list of VDBEs with the same Vdbe.db */ + int nOp; /* Number of instructions in the program */ + int nOpAlloc; /* Number of slots allocated for aOp[] */ + Op *aOp; /* Space to hold the virtual machine's program */ + int nLabel; /* Number of labels used */ + int nLabelAlloc; /* Number of slots allocated in aLabel[] */ + int *aLabel; /* Space to hold the labels */ + Mem **apArg; /* Arguments to currently executing user function */ + Mem *aColName; /* Column names to return */ + Mem *pResultSet; /* Pointer to an array of results */ + u16 nResColumn; /* Number of columns in one row of the result set */ + u16 nCursor; /* Number of slots in apCsr[] */ + VdbeCursor **apCsr; /* One element of this array for each open cursor */ + u8 errorAction; /* Recovery action to do in case of an error */ + u8 okVar; /* True if azVar[] has been initialized */ + u16 nVar; /* Number of entries in aVar[] */ + Mem *aVar; /* Values for the OP_Variable opcode. */ + char **azVar; /* Name of variables */ u32 magic; /* Magic number for sanity checking */ int nMem; /* Number of memory locations currently allocated */ Mem *aMem; /* The memory locations */ - int cacheCtr; /* VdbeCursor row cache generation counter */ - int contextStackTop; /* Index of top element in the context stack */ - int contextStackDepth; /* The size of the "context" stack */ - Context *contextStack; /* Stack used by opcodes ContextPush & ContextPop*/ + u32 cacheCtr; /* VdbeCursor row cache generation counter */ int pc; /* The program counter */ int rc; /* Value to return */ - int errorAction; /* Recovery action to do in case of an error */ - int nResColumn; /* Number of columns in one row of the result set */ - char **azResColumn; /* Values for one row of result */ char *zErrMsg; /* Error message written here */ - Mem *pResultSet; /* Pointer to an array of results */ u8 explain; /* True if EXPLAIN present on SQL command */ u8 changeCntOn; /* True to update the change-counter */ u8 expired; /* True if the VM needs to be recompiled */ @@ -17375,24 +17816,20 @@ struct Vdbe { u8 readOnly; /* True for read-only statements */ u8 isPrepareV2; /* True if prepared with prepare_v2() */ int nChange; /* Number of db changes made since last reset */ - i64 startTime; /* Time when query started - used for profiling */ int btreeMask; /* Bitmask of db->aDb[] entries referenced */ + i64 startTime; /* Time when query started - used for profiling */ BtreeMutexArray aMutex; /* An array of Btree used here and needing locks */ int aCounter[2]; /* Counters used by sqlite3_stmt_status() */ - char *zSql; /* Text of the SQL statement that generated this */ + char *zSql; /* Text of the SQL statement that generated this */ void *pFree; /* Free this when deleting the vdbe */ -#ifdef SQLITE_DEBUG - FILE *trace; /* Write an execution trace here, if not NULL */ -#endif + i64 nFkConstraint; /* Number of imm. FK constraints this VM */ + i64 nStmtDefCons; /* Number of def. constraints when stmt started */ int iStatement; /* Statement number (or 0 if has not opened stmt) */ -#ifdef SQLITE_SSE - int fetchId; /* Statement number used by sqlite3_fetch_statement */ - int lru; /* Counter used for LRU cache replacement */ -#endif -#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT - Vdbe *pLruPrev; - Vdbe *pLruNext; +#ifdef SQLITE_DEBUG + FILE *trace; /* Write an execution trace here, if not NULL */ #endif + VdbeFrame *pFrame; /* Parent frame */ + int nFrame; /* Number of frames in pFrame list */ }; /* @@ -17420,7 +17857,7 @@ SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc*, int); int sqlite2BtreeKeyCompare(BtCursor *, const void *, int, int, int *); SQLITE_PRIVATE int sqlite3VdbeIdxKeyCompare(VdbeCursor*,UnpackedRecord*,int*); -SQLITE_PRIVATE int sqlite3VdbeIdxRowid(BtCursor *, i64 *); +SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3*, BtCursor *, i64 *); SQLITE_PRIVATE int sqlite3MemCompare(const Mem*, const Mem*, const CollSeq*); SQLITE_PRIVATE int sqlite3VdbeExec(Vdbe*); SQLITE_PRIVATE int sqlite3VdbeList(Vdbe*); @@ -17453,10 +17890,18 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int); SQLITE_PRIVATE int sqlite3VdbeOpcodeHasProperty(int, int); SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve); SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *, int); +SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame*); +SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *); #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT SQLITE_PRIVATE int sqlite3VdbeReleaseBuffers(Vdbe *p); #endif +#ifndef SQLITE_OMIT_FOREIGN_KEY +SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *, int); +#else +# define sqlite3VdbeCheckFk(p,i) 0 +#endif + #ifndef SQLITE_OMIT_SHARED_CACHE SQLITE_PRIVATE void sqlite3VdbeMutexArrayEnter(Vdbe *p); #else @@ -17896,6 +18341,32 @@ SQLITE_PRIVATE char *sqlite3Utf16to8(sqlite3 *db, const void *z, int nByte){ return (m.flags & MEM_Dyn)!=0 ? m.z : sqlite3DbStrDup(db, m.z); } +/* +** Convert a UTF-8 string to the UTF-16 encoding specified by parameter +** enc. A pointer to the new string is returned, and the value of *pnOut +** is set to the length of the returned string in bytes. The call should +** arrange to call sqlite3DbFree() on the returned pointer when it is +** no longer required. +** +** If a malloc failure occurs, NULL is returned and the db.mallocFailed +** flag set. +*/ +#ifdef SQLITE_ENABLE_STAT2 +SQLITE_PRIVATE char *sqlite3Utf8to16(sqlite3 *db, u8 enc, char *z, int n, int *pnOut){ + Mem m; + memset(&m, 0, sizeof(m)); + m.db = db; + sqlite3VdbeMemSetStr(&m, z, n, SQLITE_UTF8, SQLITE_STATIC); + if( sqlite3VdbeMemTranslate(&m, enc) ){ + assert( db->mallocFailed ); + return 0; + } + assert( m.z==m.zMalloc ); + *pnOut = m.n; + return m.z; +} +#endif + /* ** pZ is a UTF-16 encoded unicode string at least nChar characters long. ** Return the number of bytes in the first nChar unicode characters @@ -18001,7 +18472,6 @@ SQLITE_PRIVATE void sqlite3UtfSelfTest(void){ ** This file contains functions for allocating memory, comparing ** strings, and stuff like that. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ */ #ifdef SQLITE_HAVE_ISNAN # include @@ -18017,27 +18487,6 @@ SQLITE_PRIVATE void sqlite3Coverage(int x){ } #endif -/* -** Routine needed to support the ALWAYS() and NEVER() macros. -** -** The argument to ALWAYS() should always be true and the argument -** to NEVER() should always be false. If either is not the case -** then this routine is called in order to throw an error. -** -** This routine only exists if assert() is operational. It always -** throws an assert on its first invocation. The variable has a long -** name to help the assert() message be more readable. The variable -** is used to prevent a too-clever optimizer from optimizing out the -** entire call. -*/ -#ifndef NDEBUG -SQLITE_PRIVATE int sqlite3Assert(void){ - static volatile int ALWAYS_was_false_or_NEVER_was_true = 0; - assert( ALWAYS_was_false_or_NEVER_was_true ); /* Always fails */ - return ALWAYS_was_false_or_NEVER_was_true++; /* Not Reached */ -} -#endif - /* ** Return true if the floating point value is Not a Number (NaN). ** @@ -18231,7 +18680,7 @@ SQLITE_PRIVATE int sqlite3StrICmp(const char *zLeft, const char *zRight){ while( *a!=0 && UpperToLower[*a]==UpperToLower[*b]){ a++; b++; } return UpperToLower[*a] - UpperToLower[*b]; } -SQLITE_PRIVATE int sqlite3StrNICmp(const char *zLeft, const char *zRight, int N){ +SQLITE_API int sqlite3_strnicmp(const char *zLeft, const char *zRight, int N){ register unsigned char *a, *b; a = (unsigned char *)zLeft; b = (unsigned char *)zRight; @@ -18279,7 +18728,7 @@ SQLITE_PRIVATE int sqlite3IsNumber(const char *z, int *realnum, u8 enc){ } /* -** The string z[] is an ascii representation of a real number. +** The string z[] is an ASCII representation of a real number. ** Convert this string to a double. ** ** This routine assumes that z[] really is a valid number. If it @@ -18292,70 +18741,126 @@ SQLITE_PRIVATE int sqlite3IsNumber(const char *z, int *realnum, u8 enc){ */ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult){ #ifndef SQLITE_OMIT_FLOATING_POINT - int sign = 1; const char *zBegin = z; - LONGDOUBLE_TYPE v1 = 0.0; - int nSignificant = 0; + /* sign * significand * (10 ^ (esign * exponent)) */ + int sign = 1; /* sign of significand */ + i64 s = 0; /* significand */ + int d = 0; /* adjust exponent for shifting decimal point */ + int esign = 1; /* sign of exponent */ + int e = 0; /* exponent */ + double result; + int nDigits = 0; + + /* skip leading spaces */ while( sqlite3Isspace(*z) ) z++; + /* get sign of significand */ if( *z=='-' ){ sign = -1; z++; }else if( *z=='+' ){ z++; } - while( z[0]=='0' ){ - z++; - } - while( sqlite3Isdigit(*z) ){ - v1 = v1*10.0 + (*z - '0'); - z++; - nSignificant++; + /* skip leading zeroes */ + while( z[0]=='0' ) z++, nDigits++; + + /* copy max significant digits to significand */ + while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ + s = s*10 + (*z - '0'); + z++, nDigits++; } + /* skip non-significant significand digits + ** (increase exponent by d to shift decimal left) */ + while( sqlite3Isdigit(*z) ) z++, nDigits++, d++; + + /* if decimal point is present */ if( *z=='.' ){ - LONGDOUBLE_TYPE divisor = 1.0; z++; - if( nSignificant==0 ){ - while( z[0]=='0' ){ - divisor *= 10.0; - z++; - } + /* copy digits from after decimal to significand + ** (decrease exponent by d to shift decimal right) */ + while( sqlite3Isdigit(*z) && s<((LARGEST_INT64-9)/10) ){ + s = s*10 + (*z - '0'); + z++, nDigits++, d--; } - while( sqlite3Isdigit(*z) ){ - if( nSignificant<18 ){ - v1 = v1*10.0 + (*z - '0'); - divisor *= 10.0; - nSignificant++; - } - z++; - } - v1 /= divisor; + /* skip non-significant digits */ + while( sqlite3Isdigit(*z) ) z++, nDigits++; } + + /* if exponent is present */ if( *z=='e' || *z=='E' ){ - int esign = 1; - int eval = 0; - LONGDOUBLE_TYPE scale = 1.0; z++; + /* get sign of exponent */ if( *z=='-' ){ esign = -1; z++; }else if( *z=='+' ){ z++; } + /* copy digits to exponent */ while( sqlite3Isdigit(*z) ){ - eval = eval*10 + *z - '0'; + e = e*10 + (*z - '0'); z++; } - while( eval>=64 ){ scale *= 1.0e+64; eval -= 64; } - while( eval>=16 ){ scale *= 1.0e+16; eval -= 16; } - while( eval>=4 ){ scale *= 1.0e+4; eval -= 4; } - while( eval>=1 ){ scale *= 1.0e+1; eval -= 1; } - if( esign<0 ){ - v1 /= scale; + } + + /* adjust exponent by d, and update sign */ + e = (e*esign) + d; + if( e<0 ) { + esign = -1; + e *= -1; + } else { + esign = 1; + } + + /* if 0 significand */ + if( !s ) { + /* In the IEEE 754 standard, zero is signed. + ** Add the sign if we've seen at least one digit */ + result = (sign<0 && nDigits) ? -(double)0 : (double)0; + } else { + /* attempt to reduce exponent */ + if( esign>0 ){ + while( s<(LARGEST_INT64/10) && e>0 ) e--,s*=10; }else{ - v1 *= scale; + while( !(s%10) && e>0 ) e--,s/=10; + } + + /* adjust the sign of significand */ + s = sign<0 ? -s : s; + + /* if exponent, scale significand as appropriate + ** and store in result. */ + if( e ){ + double scale = 1.0; + /* attempt to handle extremely small/large numbers better */ + if( e>307 && e<342 ){ + while( e%308 ) { scale *= 1.0e+1; e -= 1; } + if( esign<0 ){ + result = s / scale; + result /= 1.0e+308; + }else{ + result = s * scale; + result *= 1.0e+308; + } + }else{ + /* 1.0e+22 is the largest power of 10 than can be + ** represented exactly. */ + while( e%22 ) { scale *= 1.0e+1; e -= 1; } + while( e>0 ) { scale *= 1.0e+22; e -= 22; } + if( esign<0 ){ + result = s / scale; + }else{ + result = s * scale; + } + } + } else { + result = (double)s; } } - *pResult = (double)(sign<0 ? -v1 : v1); + + /* store the result */ + *pResult = result; + + /* return number of characters used */ return (int)(z - zBegin); #else return sqlite3Atoi64(z, pResult); @@ -18377,7 +18882,7 @@ SQLITE_PRIVATE int sqlite3AtoF(const char *z, double *pResult){ */ static int compare2pow63(const char *zNum){ int c; - c = memcmp(zNum,"922337203685477580",18); + c = memcmp(zNum,"922337203685477580",18)*10; if( c==0 ){ c = zNum[18] - '8'; } @@ -18910,7 +19415,7 @@ SQLITE_PRIVATE void sqlite3Put4byte(unsigned char *p, u32 v){ #if !defined(SQLITE_OMIT_BLOB_LITERAL) || defined(SQLITE_HAS_CODEC) /* ** Translate a single byte of Hex into an integer. -** This routinen only works if h really is a valid hexadecimal +** This routine only works if h really is a valid hexadecimal ** character: 0..9a..fA..F */ static u8 hexToInt(int h){ @@ -19060,7 +19565,7 @@ SQLITE_PRIVATE int sqlite3SafetyCheckSickOrOk(sqlite3 *db){ ** This is the implementation of generic hash-tables ** used in SQLite. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* Turn bulk memory into a hash table object by initializing the @@ -19355,90 +19860,90 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ /* 22 */ "Function", /* 23 */ "IfNeg", /* 24 */ "Noop", - /* 25 */ "Return", - /* 26 */ "NewRowid", - /* 27 */ "Variable", - /* 28 */ "String", - /* 29 */ "RealAffinity", - /* 30 */ "VRename", - /* 31 */ "ParseSchema", - /* 32 */ "VOpen", - /* 33 */ "Close", - /* 34 */ "CreateIndex", - /* 35 */ "IsUnique", - /* 36 */ "NotFound", - /* 37 */ "Int64", - /* 38 */ "MustBeInt", - /* 39 */ "Halt", - /* 40 */ "Rowid", - /* 41 */ "IdxLT", - /* 42 */ "AddImm", - /* 43 */ "Statement", - /* 44 */ "RowData", - /* 45 */ "MemMax", - /* 46 */ "NotExists", - /* 47 */ "Gosub", - /* 48 */ "Integer", - /* 49 */ "Prev", - /* 50 */ "RowSetRead", - /* 51 */ "RowSetAdd", - /* 52 */ "VColumn", - /* 53 */ "CreateTable", - /* 54 */ "Last", - /* 55 */ "SeekLe", - /* 56 */ "IncrVacuum", - /* 57 */ "IdxRowid", - /* 58 */ "ResetCount", - /* 59 */ "ContextPush", + /* 25 */ "Program", + /* 26 */ "Return", + /* 27 */ "NewRowid", + /* 28 */ "FkCounter", + /* 29 */ "Variable", + /* 30 */ "String", + /* 31 */ "RealAffinity", + /* 32 */ "VRename", + /* 33 */ "ParseSchema", + /* 34 */ "VOpen", + /* 35 */ "Close", + /* 36 */ "CreateIndex", + /* 37 */ "IsUnique", + /* 38 */ "NotFound", + /* 39 */ "Int64", + /* 40 */ "MustBeInt", + /* 41 */ "Halt", + /* 42 */ "Rowid", + /* 43 */ "IdxLT", + /* 44 */ "AddImm", + /* 45 */ "RowData", + /* 46 */ "MemMax", + /* 47 */ "NotExists", + /* 48 */ "Gosub", + /* 49 */ "Integer", + /* 50 */ "Prev", + /* 51 */ "RowSetRead", + /* 52 */ "RowSetAdd", + /* 53 */ "VColumn", + /* 54 */ "CreateTable", + /* 55 */ "Last", + /* 56 */ "SeekLe", + /* 57 */ "IncrVacuum", + /* 58 */ "IdxRowid", + /* 59 */ "ResetCount", /* 60 */ "Yield", /* 61 */ "DropTrigger", /* 62 */ "DropIndex", - /* 63 */ "IdxGE", - /* 64 */ "IdxDelete", - /* 65 */ "Vacuum", - /* 66 */ "Or", - /* 67 */ "And", - /* 68 */ "IfNot", - /* 69 */ "DropTable", - /* 70 */ "SeekLt", - /* 71 */ "IsNull", - /* 72 */ "NotNull", - /* 73 */ "Ne", - /* 74 */ "Eq", - /* 75 */ "Gt", - /* 76 */ "Le", - /* 77 */ "Lt", - /* 78 */ "Ge", - /* 79 */ "MakeRecord", - /* 80 */ "BitAnd", - /* 81 */ "BitOr", - /* 82 */ "ShiftLeft", - /* 83 */ "ShiftRight", - /* 84 */ "Add", - /* 85 */ "Subtract", - /* 86 */ "Multiply", - /* 87 */ "Divide", - /* 88 */ "Remainder", - /* 89 */ "Concat", - /* 90 */ "ResultRow", - /* 91 */ "Delete", - /* 92 */ "AggFinal", + /* 63 */ "Param", + /* 64 */ "IdxGE", + /* 65 */ "IdxDelete", + /* 66 */ "Vacuum", + /* 67 */ "IfNot", + /* 68 */ "Or", + /* 69 */ "And", + /* 70 */ "DropTable", + /* 71 */ "SeekLt", + /* 72 */ "MakeRecord", + /* 73 */ "IsNull", + /* 74 */ "NotNull", + /* 75 */ "Ne", + /* 76 */ "Eq", + /* 77 */ "Gt", + /* 78 */ "Le", + /* 79 */ "Lt", + /* 80 */ "Ge", + /* 81 */ "ResultRow", + /* 82 */ "BitAnd", + /* 83 */ "BitOr", + /* 84 */ "ShiftLeft", + /* 85 */ "ShiftRight", + /* 86 */ "Add", + /* 87 */ "Subtract", + /* 88 */ "Multiply", + /* 89 */ "Divide", + /* 90 */ "Remainder", + /* 91 */ "Concat", + /* 92 */ "Delete", /* 93 */ "BitNot", /* 94 */ "String8", - /* 95 */ "Compare", - /* 96 */ "Goto", - /* 97 */ "TableLock", - /* 98 */ "Clear", - /* 99 */ "VerifyCookie", - /* 100 */ "AggStep", - /* 101 */ "SetNumColumns", + /* 95 */ "AggFinal", + /* 96 */ "Compare", + /* 97 */ "Goto", + /* 98 */ "TableLock", + /* 99 */ "Clear", + /* 100 */ "VerifyCookie", + /* 101 */ "AggStep", /* 102 */ "Transaction", /* 103 */ "VFilter", /* 104 */ "VDestroy", - /* 105 */ "ContextPop", - /* 106 */ "Next", - /* 107 */ "Count", - /* 108 */ "IdxInsert", + /* 105 */ "Next", + /* 106 */ "Count", + /* 107 */ "IdxInsert", + /* 108 */ "FkIfZero", /* 109 */ "SeekGe", /* 110 */ "Insert", /* 111 */ "Destroy", @@ -19497,7 +20002,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ ** ** This file contains code that is specific to OS/2. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ @@ -19560,7 +20065,7 @@ SQLITE_PRIVATE const char *sqlite3OpcodeName(int i){ ** This file should be #included by the os_*.c files only. It is not a ** general purpose header file. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _OS_COMMON_H_ #define _OS_COMMON_H_ @@ -19622,7 +20127,7 @@ SQLITE_PRIVATE int sqlite3OSTrace = 0; ** This file contains inline asm code for retrieving "high-performance" ** counters for x86 class CPUs. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _HWTIME_H_ #define _HWTIME_H_ @@ -20879,8 +21384,6 @@ SQLITE_API int sqlite3_os_end(void){ ** * Locking primitives for the proxy uber-locking-method. (MacOSX only) ** * Definitions of sqlite3_vfs objects for all locking methods ** plus implementations of sqlite3_os_init() and sqlite3_os_end(). -** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ */ #if SQLITE_OS_UNIX /* This file is used on unix only */ @@ -21003,6 +21506,19 @@ SQLITE_API int sqlite3_os_end(void){ #define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY)) +/* +** Sometimes, after a file handle is closed by SQLite, the file descriptor +** cannot be closed immediately. In these cases, instances of the following +** structure are used to store the file descriptor while waiting for an +** opportunity to either close or reuse it. +*/ +typedef struct UnixUnusedFd UnixUnusedFd; +struct UnixUnusedFd { + int fd; /* File descriptor to close */ + int flags; /* Flags this file descriptor was opened with */ + UnixUnusedFd *pNext; /* Next unused file descriptor on same file */ +}; + /* ** The unixFile structure is subclass of sqlite3_file specific to the unix ** VFS implementations. @@ -21017,6 +21533,8 @@ struct unixFile { unsigned char locktype; /* The type of lock held on this fd */ int lastErrno; /* The unix errno from the last I/O error */ void *lockingContext; /* Locking style specific state */ + UnixUnusedFd *pUnused; /* Pre-allocated UnixUnusedFd */ + int fileFlags; /* Miscellanous flags */ #if SQLITE_ENABLE_LOCKING_STYLE int openFlags; /* The flags specified at open() */ #endif @@ -21038,11 +21556,6 @@ struct unixFile { unsigned char transCntrChng; /* True if the transaction counter changed */ unsigned char dbUpdate; /* True if any part of database file changed */ unsigned char inNormalWrite; /* True if in a normal write operation */ - - /* If true, that means we are dealing with a database file that has - ** a range of locking bytes from PENDING_BYTE through PENDING_BYTE+511 - ** which should never be read or written. Asserts() will verify this */ - unsigned char isLockable; /* True if file might be locked */ #endif #ifdef SQLITE_TEST /* In test mode, increase the size of this structure a bit so that @@ -21052,6 +21565,11 @@ struct unixFile { #endif }; +/* +** The following macros define bits in unixFile.fileFlags +*/ +#define SQLITE_WHOLE_FILE_LOCKING 0x0001 /* Use whole-file locking */ + /* ** Include code that is common to all os_*.c files */ @@ -21076,7 +21594,7 @@ struct unixFile { ** This file should be #included by the os_*.c files only. It is not a ** general purpose header file. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _OS_COMMON_H_ #define _OS_COMMON_H_ @@ -21138,7 +21656,7 @@ SQLITE_PRIVATE int sqlite3OSTrace = 0; ** This file contains inline asm code for retrieving "high-performance" ** counters for x86 class CPUs. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _HWTIME_H_ #define _HWTIME_H_ @@ -21319,7 +21837,18 @@ SQLITE_API int sqlite3_open_file_count = 0; /* -** Helper functions to obtain and relinquish the global mutex. +** Helper functions to obtain and relinquish the global mutex. The +** global mutex is used to protect the unixOpenCnt, unixLockInfo and +** vxworksFileId objects used by this file, all of which may be +** shared by multiple threads. +** +** Function unixMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() +** statements. e.g. +** +** unixEnterMutex() +** assert( unixMutexHeld() ); +** unixEnterLeave() */ static void unixEnterMutex(void){ sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); @@ -21327,6 +21856,11 @@ static void unixEnterMutex(void){ static void unixLeaveMutex(void){ sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); } +#ifdef SQLITE_DEBUG +static int unixMutexHeld(void) { + return sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)); +} +#endif #ifdef SQLITE_DEBUG @@ -21337,11 +21871,11 @@ static void unixLeaveMutex(void){ */ static const char *locktypeName(int locktype){ switch( locktype ){ - case NO_LOCK: return "NONE"; - case SHARED_LOCK: return "SHARED"; - case RESERVED_LOCK: return "RESERVED"; - case PENDING_LOCK: return "PENDING"; - case EXCLUSIVE_LOCK: return "EXCLUSIVE"; + case NO_LOCK: return "NONE"; + case SHARED_LOCK: return "SHARED"; + case RESERVED_LOCK: return "RESERVED"; + case PENDING_LOCK: return "PENDING"; + case EXCLUSIVE_LOCK: return "EXCLUSIVE"; } return "ERROR"; } @@ -21795,11 +22329,10 @@ struct unixOpenCnt { struct unixFileId fileId; /* The lookup key */ int nRef; /* Number of pointers to this structure */ int nLock; /* Number of outstanding locks */ - int nPending; /* Number of pending close() operations */ - int *aPending; /* Malloced space holding fd's awaiting a close() */ + UnixUnusedFd *pUnused; /* Unused file descriptors to close */ #if OS_VXWORKS sem_t *pSem; /* Named POSIX semaphore */ - char aSemName[MAX_PATHNAME+1]; /* Name of that semaphore */ + char aSemName[MAX_PATHNAME+2]; /* Name of that semaphore */ #endif struct unixOpenCnt *pNext, *pPrev; /* List of all unixOpenCnt objects */ }; @@ -21896,18 +22429,23 @@ static void testThreadLockingBehavior(int fd_orig){ d.fd = fd; d.lock = l; d.lock.l_type = F_WRLCK; - pthread_create(&t, 0, threadLockingTest, &d); - pthread_join(t, 0); + if( pthread_create(&t, 0, threadLockingTest, &d)==0 ){ + pthread_join(t, 0); + } close(fd); if( d.result!=0 ) return; threadsOverrideEachOthersLocks = (d.lock.l_type==F_UNLCK); } -#endif /* SQLITE_THERADSAFE && defined(__linux__) */ +#endif /* SQLITE_THREADSAFE && defined(__linux__) */ /* ** Release a unixLockInfo structure previously allocated by findLockInfo(). +** +** The mutex entered using the unixEnterMutex() function must be held +** when this function is called. */ static void releaseLockInfo(struct unixLockInfo *pLock){ + assert( unixMutexHeld() ); if( pLock ){ pLock->nRef--; if( pLock->nRef==0 ){ @@ -21929,8 +22467,12 @@ static void releaseLockInfo(struct unixLockInfo *pLock){ /* ** Release a unixOpenCnt structure previously allocated by findLockInfo(). +** +** The mutex entered using the unixEnterMutex() function must be held +** when this function is called. */ static void releaseOpenCnt(struct unixOpenCnt *pOpen){ + assert( unixMutexHeld() ); if( pOpen ){ pOpen->nRef--; if( pOpen->nRef==0 ){ @@ -21945,7 +22487,17 @@ static void releaseOpenCnt(struct unixOpenCnt *pOpen){ assert( pOpen->pNext->pPrev==pOpen ); pOpen->pNext->pPrev = pOpen->pPrev; } - sqlite3_free(pOpen->aPending); +#if SQLITE_THREADSAFE && defined(__linux__) + assert( !pOpen->pUnused || threadsOverrideEachOthersLocks==0 ); +#endif + + /* If pOpen->pUnused is not null, then memory and file-descriptors + ** are leaked. + ** + ** This will only happen if, under Linuxthreads, the user has opened + ** a transaction in one thread, then attempts to close the database + ** handle from another thread (without first unlocking the db file). + ** This is a misuse. */ sqlite3_free(pOpen); } } @@ -21956,6 +22508,9 @@ static void releaseOpenCnt(struct unixOpenCnt *pOpen){ ** describes that file descriptor. Create new ones if necessary. The ** return values might be uninitialized if an error occurs. ** +** The mutex entered using the unixEnterMutex() function must be held +** when this function is called. +** ** Return an appropriate error code. */ static int findLockInfo( @@ -21968,9 +22523,11 @@ static int findLockInfo( struct unixLockKey lockKey; /* Lookup key for the unixLockInfo structure */ struct unixFileId fileId; /* Lookup key for the unixOpenCnt struct */ struct stat statbuf; /* Low-level file information */ - struct unixLockInfo *pLock; /* Candidate unixLockInfo object */ + struct unixLockInfo *pLock = 0;/* Candidate unixLockInfo object */ struct unixOpenCnt *pOpen; /* Candidate unixOpenCnt object */ + assert( unixMutexHeld() ); + /* Get low-level information about the file that we can used to ** create a unique name for the file. */ @@ -22033,7 +22590,7 @@ static int findLockInfo( rc = SQLITE_NOMEM; goto exit_findlockinfo; } - pLock->lockKey = lockKey; + memcpy(&pLock->lockKey,&lockKey,sizeof(lockKey)); pLock->nRef = 1; pLock->cnt = 0; pLock->locktype = 0; @@ -22058,19 +22615,12 @@ static int findLockInfo( rc = SQLITE_NOMEM; goto exit_findlockinfo; } + memset(pOpen, 0, sizeof(*pOpen)); pOpen->fileId = fileId; pOpen->nRef = 1; - pOpen->nLock = 0; - pOpen->nPending = 0; - pOpen->aPending = 0; pOpen->pNext = openList; - pOpen->pPrev = 0; if( openList ) openList->pPrev = pOpen; openList = pOpen; -#if OS_VXWORKS - pOpen->pSem = NULL; - pOpen->aSemName[0] = '\0'; -#endif }else{ pOpen->nRef++; } @@ -22177,6 +22727,62 @@ static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){ return rc; } +/* +** Perform a file locking operation on a range of bytes in a file. +** The "op" parameter should be one of F_RDLCK, F_WRLCK, or F_UNLCK. +** Return 0 on success or -1 for failure. On failure, write the error +** code into *pErrcode. +** +** If the SQLITE_WHOLE_FILE_LOCKING bit is clear, then only lock +** the range of bytes on the locking page between SHARED_FIRST and +** SHARED_SIZE. If SQLITE_WHOLE_FILE_LOCKING is set, then lock all +** bytes from 0 up to but not including PENDING_BYTE, and all bytes +** that follow SHARED_FIRST. +** +** In other words, of SQLITE_WHOLE_FILE_LOCKING if false (the historical +** default case) then only lock a small range of bytes from SHARED_FIRST +** through SHARED_FIRST+SHARED_SIZE-1. But if SQLITE_WHOLE_FILE_LOCKING is +** true then lock every byte in the file except for PENDING_BYTE and +** RESERVED_BYTE. +** +** SQLITE_WHOLE_FILE_LOCKING=true overlaps SQLITE_WHOLE_FILE_LOCKING=false +** and so the locking schemes are compatible. One type of lock will +** effectively exclude the other type. The reason for using the +** SQLITE_WHOLE_FILE_LOCKING=true is that by indicating the full range +** of bytes to be read or written, we give hints to NFS to help it +** maintain cache coherency. On the other hand, whole file locking +** is slower, so we don't want to use it except for NFS. +*/ +static int rangeLock(unixFile *pFile, int op, int *pErrcode){ + struct flock lock; + int rc; + lock.l_type = op; + lock.l_start = SHARED_FIRST; + lock.l_whence = SEEK_SET; + if( (pFile->fileFlags & SQLITE_WHOLE_FILE_LOCKING)==0 ){ + lock.l_len = SHARED_SIZE; + rc = fcntl(pFile->h, F_SETLK, &lock); + *pErrcode = errno; + }else{ + lock.l_len = 0; + rc = fcntl(pFile->h, F_SETLK, &lock); + *pErrcode = errno; + if( NEVER(op==F_UNLCK) || rc!=(-1) ){ + lock.l_start = 0; + lock.l_len = PENDING_BYTE; + rc = fcntl(pFile->h, F_SETLK, &lock); + if( ALWAYS(op!=F_UNLCK) && rc==(-1) ){ + *pErrcode = errno; + lock.l_type = F_UNLCK; + lock.l_start = SHARED_FIRST; + lock.l_len = 0; + fcntl(pFile->h, F_SETLK, &lock); + } + } + } + return rc; +} + /* ** Lock the file with the lock specified by parameter locktype - one ** of the following: @@ -22244,7 +22850,8 @@ static int unixLock(sqlite3_file *id, int locktype){ unixFile *pFile = (unixFile*)id; struct unixLockInfo *pLock = pFile->pLock; struct flock lock; - int s; + int s = 0; + int tErrno; assert( pFile ); OSTRACE7("LOCK %d %s was %s(%s,%d) pid=%d\n", pFile->h, @@ -22261,7 +22868,10 @@ static int unixLock(sqlite3_file *id, int locktype){ return SQLITE_OK; } - /* Make sure the locking sequence is correct + /* Make sure the locking sequence is correct. + ** (1) We never move from unlocked to anything higher than shared lock. + ** (2) SQLite never explicitly requests a pendig lock. + ** (3) A shared lock is always held when a reserve lock is requested. */ assert( pFile->locktype!=NO_LOCK || locktype==SHARED_LOCK ); assert( locktype!=PENDING_LOCK ); @@ -22305,14 +22915,13 @@ static int unixLock(sqlite3_file *id, int locktype){ goto end_lock; } - lock.l_len = 1L; - - lock.l_whence = SEEK_SET; /* A PENDING lock is needed before acquiring a SHARED lock and before ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will ** be released. */ + lock.l_len = 1L; + lock.l_whence = SEEK_SET; if( locktype==SHARED_LOCK || (locktype==EXCLUSIVE_LOCK && pFile->locktypeh, F_SETLK, &lock); if( s==(-1) ){ - int tErrno = errno; + tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; @@ -22334,16 +22943,12 @@ static int unixLock(sqlite3_file *id, int locktype){ ** operating system calls for the specified lock. */ if( locktype==SHARED_LOCK ){ - int tErrno = 0; assert( pLock->cnt==0 ); assert( pLock->locktype==0 ); /* Now get the read-lock */ - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - if( (s = fcntl(pFile->h, F_SETLK, &lock))==(-1) ){ - tErrno = errno; - } + s = rangeLock(pFile, F_RDLCK, &tErrno); + /* Drop the temporary PENDING lock */ lock.l_start = PENDING_BYTE; lock.l_len = 1L; @@ -22383,17 +22988,16 @@ static int unixLock(sqlite3_file *id, int locktype){ switch( locktype ){ case RESERVED_LOCK: lock.l_start = RESERVED_BYTE; + s = fcntl(pFile->h, F_SETLK, &lock); + tErrno = errno; break; case EXCLUSIVE_LOCK: - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; + s = rangeLock(pFile, F_WRLCK, &tErrno); break; default: assert(0); } - s = fcntl(pFile->h, F_SETLK, &lock); if( s==(-1) ){ - int tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; @@ -22434,6 +23038,49 @@ end_lock: return rc; } +/* +** Close all file descriptors accumuated in the unixOpenCnt->pUnused list. +** If all such file descriptors are closed without error, the list is +** cleared and SQLITE_OK returned. +** +** Otherwise, if an error occurs, then successfully closed file descriptor +** entries are removed from the list, and SQLITE_IOERR_CLOSE returned. +** not deleted and SQLITE_IOERR_CLOSE returned. +*/ +static int closePendingFds(unixFile *pFile){ + int rc = SQLITE_OK; + struct unixOpenCnt *pOpen = pFile->pOpen; + UnixUnusedFd *pError = 0; + UnixUnusedFd *p; + UnixUnusedFd *pNext; + for(p=pOpen->pUnused; p; p=pNext){ + pNext = p->pNext; + if( close(p->fd) ){ + pFile->lastErrno = errno; + rc = SQLITE_IOERR_CLOSE; + p->pNext = pError; + pError = p; + }else{ + sqlite3_free(p); + } + } + pOpen->pUnused = pError; + return rc; +} + +/* +** Add the file descriptor used by file handle pFile to the corresponding +** pUnused list. +*/ +static void setPendingFd(unixFile *pFile){ + struct unixOpenCnt *pOpen = pFile->pOpen; + UnixUnusedFd *p = pFile->pUnused; + p->pNext = pOpen->pUnused; + pOpen->pUnused = p; + pFile->h = -1; + pFile->pUnused = 0; +} + /* ** Lower the locking level on file descriptor pFile to locktype. locktype ** must be either NO_LOCK or SHARED_LOCK. @@ -22442,11 +23089,12 @@ end_lock: ** the requested locking level, this routine is a no-op. */ static int unixUnlock(sqlite3_file *id, int locktype){ - struct unixLockInfo *pLock; - struct flock lock; - int rc = SQLITE_OK; - unixFile *pFile = (unixFile*)id; - int h; + unixFile *pFile = (unixFile*)id; /* The open file */ + struct unixLockInfo *pLock; /* Structure describing current lock state */ + struct flock lock; /* Information passed into fcntl() */ + int rc = SQLITE_OK; /* Return code from this interface */ + int h; /* The underlying file descriptor */ + int tErrno; /* Error code from system call errors */ assert( pFile ); OSTRACE7("UNLOCK %d %d was %d(%d,%d) pid=%d\n", pFile->h, locktype, @@ -22486,12 +23134,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){ if( locktype==SHARED_LOCK ){ - lock.l_type = F_RDLCK; - lock.l_whence = SEEK_SET; - lock.l_start = SHARED_FIRST; - lock.l_len = SHARED_SIZE; - if( fcntl(h, F_SETLK, &lock)==(-1) ){ - int tErrno = errno; + if( rangeLock(pFile, F_RDLCK, &tErrno)==(-1) ){ rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_RDLOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; @@ -22506,7 +23149,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){ if( fcntl(h, F_SETLK, &lock)!=(-1) ){ pLock->locktype = SHARED_LOCK; }else{ - int tErrno = errno; + tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; @@ -22516,7 +23159,6 @@ static int unixUnlock(sqlite3_file *id, int locktype){ } if( locktype==NO_LOCK ){ struct unixOpenCnt *pOpen; - int rc2 = SQLITE_OK; /* Decrement the shared lock counter. Release the lock using an ** OS call only when all threads in this same process have released @@ -22533,7 +23175,7 @@ static int unixUnlock(sqlite3_file *id, int locktype){ if( fcntl(h, F_SETLK, &lock)!=(-1) ){ pLock->locktype = NO_LOCK; }else{ - int tErrno = errno; + tErrno = errno; rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); if( IS_LOCK_ERROR(rc) ){ pFile->lastErrno = tErrno; @@ -22550,29 +23192,12 @@ static int unixUnlock(sqlite3_file *id, int locktype){ pOpen = pFile->pOpen; pOpen->nLock--; assert( pOpen->nLock>=0 ); - if( pOpen->nLock==0 && pOpen->nPending>0 ){ - int i; - for(i=0; inPending; i++){ - /* close pending fds, but if closing fails don't free the array - ** assign -1 to the successfully closed descriptors and record the - ** error. The next attempt to unlock will try again. */ - if( pOpen->aPending[i] < 0 ) continue; - if( close(pOpen->aPending[i]) ){ - pFile->lastErrno = errno; - rc2 = SQLITE_IOERR_CLOSE; - }else{ - pOpen->aPending[i] = -1; - } - } - if( rc2==SQLITE_OK ){ - sqlite3_free(pOpen->aPending); - pOpen->nPending = 0; - pOpen->aPending = 0; + if( pOpen->nLock==0 ){ + int rc2 = closePendingFds(pFile); + if( rc==SQLITE_OK ){ + rc = rc2; } } - if( rc==SQLITE_OK ){ - rc = rc2; - } } end_unlock: @@ -22621,6 +23246,7 @@ static int closeUnixFile(sqlite3_file *id){ #endif OSTRACE2("CLOSE %-3d\n", pFile->h); OpenCounter(-1); + sqlite3_free(pFile->pUnused); memset(pFile, 0, sizeof(unixFile)); } return SQLITE_OK; @@ -22638,20 +23264,10 @@ static int unixClose(sqlite3_file *id){ if( pFile->pOpen && pFile->pOpen->nLock ){ /* If there are outstanding locks, do not actually close the file just ** yet because that would clear those locks. Instead, add the file - ** descriptor to pOpen->aPending. It will be automatically closed when - ** the last lock is cleared. + ** descriptor to pOpen->pUnused list. It will be automatically closed + ** when the last lock is cleared. */ - int *aNew; - struct unixOpenCnt *pOpen = pFile->pOpen; - aNew = sqlite3_realloc(pOpen->aPending, (pOpen->nPending+1)*sizeof(int) ); - if( aNew==0 ){ - /* If a malloc fails, just leak the file descriptor */ - }else{ - pOpen->aPending = aNew; - pOpen->aPending[pOpen->nPending] = pFile->h; - pOpen->nPending++; - pFile->h = -1; - } + setPendingFd(pFile); } releaseLockInfo(pFile->pLock); releaseOpenCnt(pFile->pOpen); @@ -22708,7 +23324,7 @@ static int nolockClose(sqlite3_file *id) { /****************************************************************************** ************************* Begin dot-file Locking ****************************** ** -** The dotfile locking implementation uses the existing of separate lock +** The dotfile locking implementation uses the existance of separate lock ** files in order to control access to the database. This works on just ** about every filesystem imaginable. But there are serious downsides: ** @@ -22872,7 +23488,8 @@ static int dotlockUnlock(sqlite3_file *id, int locktype) { /* To fully unlock the database, delete the lock file */ assert( locktype==NO_LOCK ); if( unlink(zLockFile) ){ - int rc, tErrno = errno; + int rc = 0; + int tErrno = errno; if( ENOENT != tErrno ){ rc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_UNLOCK); } @@ -23619,27 +24236,15 @@ static int afpUnlock(sqlite3_file *id, int locktype) { struct unixOpenCnt *pOpen = pFile->pOpen; pOpen->nLock--; assert( pOpen->nLock>=0 ); - if( pOpen->nLock==0 && pOpen->nPending>0 ){ - int i; - for(i=0; inPending; i++){ - if( pOpen->aPending[i] < 0 ) continue; - if( close(pOpen->aPending[i]) ){ - pFile->lastErrno = errno; - rc = SQLITE_IOERR_CLOSE; - }else{ - pOpen->aPending[i] = -1; - } - } - if( rc==SQLITE_OK ){ - sqlite3_free(pOpen->aPending); - pOpen->nPending = 0; - pOpen->aPending = 0; - } + if( pOpen->nLock==0 ){ + rc = closePendingFds(pFile); } } } unixLeaveMutex(); - if( rc==SQLITE_OK ) pFile->locktype = locktype; + if( rc==SQLITE_OK ){ + pFile->locktype = locktype; + } return rc; } @@ -23657,17 +24262,7 @@ static int afpClose(sqlite3_file *id) { ** descriptor to pOpen->aPending. It will be automatically closed when ** the last lock is cleared. */ - int *aNew; - struct unixOpenCnt *pOpen = pFile->pOpen; - aNew = sqlite3_realloc(pOpen->aPending, (pOpen->nPending+1)*sizeof(int) ); - if( aNew==0 ){ - /* If a malloc fails, just leak the file descriptor */ - }else{ - pOpen->aPending = aNew; - pOpen->aPending[pOpen->nPending] = pFile->h; - pOpen->nPending++; - pFile->h = -1; - } + setPendingFd(pFile); } releaseOpenCnt(pFile->pOpen); sqlite3_free(pFile->lockingContext); @@ -23753,22 +24348,25 @@ static int unixRead( int amt, sqlite3_int64 offset ){ + unixFile *pFile = (unixFile *)id; int got; assert( id ); - /* Never read or write any of the bytes in the locking range */ - assert( ((unixFile*)id)->isLockable==0 - || offset>=PENDING_BYTE+512 - || offset+amt<=PENDING_BYTE ); + /* If this is a database file (not a journal, master-journal or temp + ** file), the bytes in the locking range should never be read or written. */ + assert( pFile->pUnused==0 + || offset>=PENDING_BYTE+512 + || offset+amt<=PENDING_BYTE + ); - got = seekAndRead((unixFile*)id, offset, pBuf, amt); + got = seekAndRead(pFile, offset, pBuf, amt); if( got==amt ){ return SQLITE_OK; }else if( got<0 ){ /* lastErrno set by seekAndRead */ return SQLITE_IOERR_READ; }else{ - ((unixFile*)id)->lastErrno = 0; /* not a system error */ + pFile->lastErrno = 0; /* not a system error */ /* Unread parts of the buffer must be zero-filled */ memset(&((char*)pBuf)[got], 0, amt-got); return SQLITE_IOERR_SHORT_READ; @@ -23822,14 +24420,17 @@ static int unixWrite( int amt, sqlite3_int64 offset ){ + unixFile *pFile = (unixFile*)id; int wrote = 0; assert( id ); assert( amt>0 ); - /* Never read or write any of the bytes in the locking range */ - assert( ((unixFile*)id)->isLockable==0 - || offset>=PENDING_BYTE+512 - || offset+amt<=PENDING_BYTE ); + /* If this is a database file (not a journal, master-journal or temp + ** file), the bytes in the locking range should never be read or written. */ + assert( pFile->pUnused==0 + || offset>=PENDING_BYTE+512 + || offset+amt<=PENDING_BYTE + ); #ifndef NDEBUG /* If we are doing a normal write to a database file (as opposed to @@ -23838,8 +24439,7 @@ static int unixWrite( ** has changed. If the transaction counter is modified, record that ** fact too. */ - if( ((unixFile*)id)->inNormalWrite ){ - unixFile *pFile = (unixFile*)id; + if( pFile->inNormalWrite ){ pFile->dbUpdate = 1; /* The database has been modified */ if( offset<=24 && offset+amt>=27 ){ int rc; @@ -23854,7 +24454,7 @@ static int unixWrite( } #endif - while( amt>0 && (wrote = seekAndWrite((unixFile*)id, offset, pBuf, amt))>0 ){ + while( amt>0 && (wrote = seekAndWrite(pFile, offset, pBuf, amt))>0 ){ amt -= wrote; offset += wrote; pBuf = &((char*)pBuf)[wrote]; @@ -23866,7 +24466,7 @@ static int unixWrite( /* lastErrno set by seekAndWrite */ return SQLITE_IOERR_WRITE; }else{ - ((unixFile*)id)->lastErrno = 0; /* not a system error */ + pFile->lastErrno = 0; /* not a system error */ return SQLITE_FULL; } } @@ -24194,7 +24794,7 @@ static int unixDeviceCharacteristics(sqlite3_file *NotUsed){ ** ** (1) The real finder-function named "FImpt()". ** -** (2) A constant pointer to this functio named just "F". +** (2) A constant pointer to this function named just "F". ** ** ** A pointer to the F pointer is used as the pAppData value for VFS @@ -24227,11 +24827,11 @@ static const sqlite3_io_methods METHOD = { \ unixSectorSize, /* xSectorSize */ \ unixDeviceCharacteristics /* xDeviceCapabilities */ \ }; \ -static const sqlite3_io_methods *FINDER##Impl(const char *z, int h){ \ - UNUSED_PARAMETER(z); UNUSED_PARAMETER(h); \ +static const sqlite3_io_methods *FINDER##Impl(const char *z, unixFile *p){ \ + UNUSED_PARAMETER(z); UNUSED_PARAMETER(p); \ return &METHOD; \ } \ -static const sqlite3_io_methods *(*const FINDER)(const char*,int) \ +static const sqlite3_io_methods *(*const FINDER)(const char*,unixFile *p) \ = FINDER##Impl; /* @@ -24297,6 +24897,23 @@ IOMETHODS( ) #endif +/* +** The "Whole File Locking" finder returns the same set of methods as +** the posix locking finder. But it also sets the SQLITE_WHOLE_FILE_LOCKING +** flag to force the posix advisory locks to cover the whole file instead +** of just a small span of bytes near the 1GiB boundary. Whole File Locking +** is useful on NFS-mounted files since it helps NFS to maintain cache +** coherency. But it is a detriment to other filesystems since it runs +** slower. +*/ +static const sqlite3_io_methods *posixWflIoFinderImpl(const char*z, unixFile*p){ + UNUSED_PARAMETER(z); + p->fileFlags = SQLITE_WHOLE_FILE_LOCKING; + return &posixIoMethods; +} +static const sqlite3_io_methods + *(*const posixWflIoFinder)(const char*,unixFile *p) = posixWflIoFinderImpl; + /* ** The proxy locking method is a "super-method" in the sense that it ** opens secondary file descriptors for the conch and lock files and @@ -24332,7 +24949,7 @@ IOMETHODS( */ static const sqlite3_io_methods *autolockIoFinderImpl( const char *filePath, /* name of the database file */ - int fd /* file descriptor open on the database file */ + unixFile *pNew /* open file object for the database file */ ){ static const struct Mapping { const char *zFilesystem; /* Filesystem type name */ @@ -24377,14 +24994,15 @@ static const sqlite3_io_methods *autolockIoFinderImpl( lockInfo.l_start = 0; lockInfo.l_whence = SEEK_SET; lockInfo.l_type = F_RDLCK; - if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) { + if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { + pNew->fileFlags = SQLITE_WHOLE_FILE_LOCKING; return &posixIoMethods; }else{ return &dotlockIoMethods; } } -static const sqlite3_io_methods *(*const autolockIoFinder)(const char*,int) - = autolockIoFinderImpl; +static const sqlite3_io_methods + *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ @@ -24398,7 +25016,7 @@ static const sqlite3_io_methods *(*const autolockIoFinder)(const char*,int) */ static const sqlite3_io_methods *autolockIoFinderImpl( const char *filePath, /* name of the database file */ - int fd /* file descriptor open on the database file */ + unixFile *pNew /* the open file object */ ){ struct flock lockInfo; @@ -24415,21 +25033,21 @@ static const sqlite3_io_methods *autolockIoFinderImpl( lockInfo.l_start = 0; lockInfo.l_whence = SEEK_SET; lockInfo.l_type = F_RDLCK; - if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) { + if( fcntl(pNew->h, F_GETLK, &lockInfo)!=-1 ) { return &posixIoMethods; }else{ return &semIoMethods; } } -static const sqlite3_io_methods *(*const autolockIoFinder)(const char*,int) - = autolockIoFinderImpl; +static const sqlite3_io_methods + *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; #endif /* OS_VXWORKS && SQLITE_ENABLE_LOCKING_STYLE */ /* ** An abstract type for a pointer to a IO method finder function: */ -typedef const sqlite3_io_methods *(*finder_type)(const char*,int); +typedef const sqlite3_io_methods *(*finder_type)(const char*,unixFile*); /**************************************************************************** @@ -24458,18 +25076,16 @@ static int fillInUnixFile( assert( pNew->pLock==NULL ); assert( pNew->pOpen==NULL ); - /* Parameter isDelete is only used on vxworks. - ** Express this explicitly here to prevent compiler warnings - ** about unused parameters. + /* Parameter isDelete is only used on vxworks. Express this explicitly + ** here to prevent compiler warnings about unused parameters. */ -#if !OS_VXWORKS UNUSED_PARAMETER(isDelete); -#endif OSTRACE3("OPEN %-3d %s\n", h, zFilename); pNew->h = h; pNew->dirfd = dirfd; SET_THREADID(pNew); + pNew->fileFlags = 0; #if OS_VXWORKS pNew->pId = vxworksFindFileId(zFilename); @@ -24482,7 +25098,7 @@ static int fillInUnixFile( if( noLock ){ pLockingStyle = &nolockIoMethods; }else{ - pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, h); + pLockingStyle = (**(finder_type*)pVfs->pAppData)(zFilename, pNew); #if SQLITE_ENABLE_LOCKING_STYLE /* Cache zFilename in the locking context (AFP and dotlock override) for ** proxyLock activation is possible (remote proxy is based on db name) @@ -24494,6 +25110,28 @@ static int fillInUnixFile( if( pLockingStyle == &posixIoMethods ){ unixEnterMutex(); rc = findLockInfo(pNew, &pNew->pLock, &pNew->pOpen); + if( rc!=SQLITE_OK ){ + /* If an error occured in findLockInfo(), close the file descriptor + ** immediately, before releasing the mutex. findLockInfo() may fail + ** in two scenarios: + ** + ** (a) A call to fstat() failed. + ** (b) A malloc failed. + ** + ** Scenario (b) may only occur if the process is holding no other + ** file descriptors open on the same file. If there were other file + ** descriptors on this file, then no malloc would be required by + ** findLockInfo(). If this is the case, it is quite safe to close + ** handle h - as it is guaranteed that no posix locks will be released + ** by doing so. + ** + ** If scenario (a) caused the error then things are not so safe. The + ** implicit assumption here is that if fstat() fails, things are in + ** such bad shape that dropping a lock or two doesn't matter much. + */ + close(h); + h = -1; + } unixLeaveMutex(); } @@ -24545,9 +25183,9 @@ static int fillInUnixFile( if( (rc==SQLITE_OK) && (pNew->pOpen->pSem==NULL) ){ char *zSemName = pNew->pOpen->aSemName; int n; - sqlite3_snprintf(MAX_PATHNAME, zSemName, "%s.sem", + sqlite3_snprintf(MAX_PATHNAME, zSemName, "/%s.sem", pNew->pId->zCanonicalName); - for( n=0; zSemName[n]; n++ ) + for( n=1; zSemName[n]; n++ ) if( zSemName[n]=='/' ) zSemName[n] = '_'; pNew->pOpen->pSem = sem_open(zSemName, O_CREAT, 0666, 1); if( pNew->pOpen->pSem == SEM_FAILED ){ @@ -24569,7 +25207,7 @@ static int fillInUnixFile( #endif if( rc!=SQLITE_OK ){ if( dirfd>=0 ) close(dirfd); /* silent leak if fail, already in error */ - close(h); + if( h>=0 ) close(h); }else{ pNew->pMethod = pLockingStyle; OpenCounter(+1); @@ -24678,6 +25316,62 @@ static int getTempname(int nBuf, char *zBuf){ static int proxyTransformUnixFile(unixFile*, const char*); #endif +/* +** Search for an unused file descriptor that was opened on the database +** file (not a journal or master-journal file) identified by pathname +** zPath with SQLITE_OPEN_XXX flags matching those passed as the second +** argument to this function. +** +** Such a file descriptor may exist if a database connection was closed +** but the associated file descriptor could not be closed because some +** other file descriptor open on the same file is holding a file-lock. +** Refer to comments in the unixClose() function and the lengthy comment +** describing "Posix Advisory Locking" at the start of this file for +** further details. Also, ticket #4018. +** +** If a suitable file descriptor is found, then it is returned. If no +** such file descriptor is located, -1 is returned. +*/ +static UnixUnusedFd *findReusableFd(const char *zPath, int flags){ + UnixUnusedFd *pUnused = 0; + + /* Do not search for an unused file descriptor on vxworks. Not because + ** vxworks would not benefit from the change (it might, we're not sure), + ** but because no way to test it is currently available. It is better + ** not to risk breaking vxworks support for the sake of such an obscure + ** feature. */ +#if !OS_VXWORKS + struct stat sStat; /* Results of stat() call */ + + /* A stat() call may fail for various reasons. If this happens, it is + ** almost certain that an open() call on the same path will also fail. + ** For this reason, if an error occurs in the stat() call here, it is + ** ignored and -1 is returned. The caller will try to open a new file + ** descriptor on the same path, fail, and return an error to SQLite. + ** + ** Even if a subsequent open() call does succeed, the consequences of + ** not searching for a resusable file descriptor are not dire. */ + if( 0==stat(zPath, &sStat) ){ + struct unixOpenCnt *pO; + struct unixFileId id; + id.dev = sStat.st_dev; + id.ino = sStat.st_ino; + + unixEnterMutex(); + for(pO=openList; pO && memcmp(&id, &pO->fileId, sizeof(id)); pO=pO->pNext); + if( pO ){ + UnixUnusedFd **pp; + for(pp=&pO->pUnused; *pp && (*pp)->flags!=flags; pp=&((*pp)->pNext)); + pUnused = *pp; + if( pUnused ){ + *pp = pUnused->pNext; + } + } + unixLeaveMutex(); + } +#endif /* if !OS_VXWORKS */ + return pUnused; +} /* ** Open the file zPath. @@ -24708,12 +25402,13 @@ static int unixOpen( int flags, /* Input flags to control the opening */ int *pOutFlags /* Output flags returned to SQLite core */ ){ - int fd = -1; /* File descriptor returned by open() */ + unixFile *p = (unixFile *)pFile; + int fd = -1; /* File descriptor returned by open() */ int dirfd = -1; /* Directory file descriptor */ int openFlags = 0; /* Flags to pass to open() */ int eType = flags&0xFFFFFF00; /* Type of file to open */ int noLock; /* True to omit locking primitives */ - int rc = SQLITE_OK; + int rc = SQLITE_OK; /* Function Return Code */ int isExclusive = (flags & SQLITE_OPEN_EXCLUSIVE); int isDelete = (flags & SQLITE_OPEN_DELETEONCLOSE); @@ -24748,11 +25443,10 @@ static int unixOpen( assert(isDelete==0 || isCreate); /* The main DB, main journal, and master journal are never automatically - ** deleted - */ - assert( eType!=SQLITE_OPEN_MAIN_DB || !isDelete ); - assert( eType!=SQLITE_OPEN_MAIN_JOURNAL || !isDelete ); - assert( eType!=SQLITE_OPEN_MASTER_JOURNAL || !isDelete ); + ** deleted. Nor are they ever temporary files. */ + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); + assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MASTER_JOURNAL ); /* Assert that the upper layer has set one of the "file-type" flags. */ assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB @@ -24761,9 +25455,22 @@ static int unixOpen( || eType==SQLITE_OPEN_TRANSIENT_DB ); - memset(pFile, 0, sizeof(unixFile)); + memset(p, 0, sizeof(unixFile)); - if( !zName ){ + if( eType==SQLITE_OPEN_MAIN_DB ){ + UnixUnusedFd *pUnused; + pUnused = findReusableFd(zName, flags); + if( pUnused ){ + fd = pUnused->fd; + }else{ + pUnused = sqlite3_malloc(sizeof(*pUnused)); + if( !pUnused ){ + return SQLITE_NOMEM; + } + } + p->pUnused = pUnused; + }else if( !zName ){ + /* If zName is NULL, the upper layer is requesting a temp file. */ assert(isDelete && !isOpenDirectory); rc = getTempname(MAX_PATHNAME+1, zTmpname); if( rc!=SQLITE_OK ){ @@ -24772,23 +25479,43 @@ static int unixOpen( zName = zTmpname; } + /* Determine the value of the flags parameter passed to POSIX function + ** open(). These must be calculated even if open() is not called, as + ** they may be stored as part of the file handle and used by the + ** 'conch file' locking functions later on. */ if( isReadonly ) openFlags |= O_RDONLY; if( isReadWrite ) openFlags |= O_RDWR; if( isCreate ) openFlags |= O_CREAT; if( isExclusive ) openFlags |= (O_EXCL|O_NOFOLLOW); openFlags |= (O_LARGEFILE|O_BINARY); - fd = open(zName, openFlags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS); - OSTRACE4("OPENX %-3d %s 0%o\n", fd, zName, openFlags); - if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){ - /* Failed to open the file for read/write access. Try read-only. */ - flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); - flags |= SQLITE_OPEN_READONLY; - return unixOpen(pVfs, zPath, pFile, flags, pOutFlags); - } if( fd<0 ){ - return SQLITE_CANTOPEN; + mode_t openMode = (isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS); + fd = open(zName, openFlags, openMode); + OSTRACE4("OPENX %-3d %s 0%o\n", fd, zName, openFlags); + if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){ + /* Failed to open the file for read/write access. Try read-only. */ + flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE); + openFlags &= ~(O_RDWR|O_CREAT); + flags |= SQLITE_OPEN_READONLY; + openFlags |= O_RDONLY; + fd = open(zName, openFlags, openMode); + } + if( fd<0 ){ + rc = SQLITE_CANTOPEN; + goto open_finished; + } + } + assert( fd>=0 ); + if( pOutFlags ){ + *pOutFlags = flags; + } + + if( p->pUnused ){ + p->pUnused->fd = fd; + p->pUnused->flags = flags; } + if( isDelete ){ #if OS_VXWORKS zPath = zName; @@ -24798,25 +25525,20 @@ static int unixOpen( } #if SQLITE_ENABLE_LOCKING_STYLE else{ - ((unixFile*)pFile)->openFlags = openFlags; + p->openFlags = openFlags; } #endif - if( pOutFlags ){ - *pOutFlags = flags; - } -#ifndef NDEBUG - if( (flags & SQLITE_OPEN_MAIN_DB)!=0 ){ - ((unixFile*)pFile)->isLockable = 1; - } -#endif - - assert( fd>=0 ); if( isOpenDirectory ){ rc = openDirectory(zPath, &dirfd); if( rc!=SQLITE_OK ){ - close(fd); /* silently leak if fail, already in error */ - return rc; + /* It is safe to close fd at this point, because it is guaranteed not + ** to be open on a database file. If it were open on a database file, + ** it would not be safe to close as this would release any locks held + ** on the file by this process. */ + assert( eType!=SQLITE_OPEN_MAIN_DB ); + close(fd); /* silently leak if fail, already in error */ + goto open_finished; } } @@ -24827,23 +25549,31 @@ static int unixOpen( noLock = eType!=SQLITE_OPEN_MAIN_DB; #if SQLITE_PREFER_PROXY_LOCKING - if( zPath!=NULL && !noLock ){ + if( zPath!=NULL && !noLock && pVfs->xOpen ){ char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING"); int useProxy = 0; - /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, - ** 0 means never use proxy, NULL means use proxy for non-local files only - */ + /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means + ** never use proxy, NULL means use proxy for non-local files only. */ if( envforce!=NULL ){ useProxy = atoi(envforce)>0; }else{ struct statfs fsInfo; - if( statfs(zPath, &fsInfo) == -1 ){ - ((unixFile*)pFile)->lastErrno = errno; - if( dirfd>=0 ) close(dirfd); /* silently leak if fail, in error */ + /* In theory, the close(fd) call is sub-optimal. If the file opened + ** with fd is a database file, and there are other connections open + ** on that file that are currently holding advisory locks on it, + ** then the call to close() will cancel those locks. In practice, + ** we're assuming that statfs() doesn't fail very often. At least + ** not while other file descriptors opened by the same process on + ** the same file are working. */ + p->lastErrno = errno; + if( dirfd>=0 ){ + close(dirfd); /* silently leak if fail, in error */ + } close(fd); /* silently leak if fail, in error */ - return SQLITE_IOERR_ACCESS; + rc = SQLITE_IOERR_ACCESS; + goto open_finished; } useProxy = !(fsInfo.f_flags&MNT_LOCAL); } @@ -24852,14 +25582,20 @@ static int unixOpen( if( rc==SQLITE_OK ){ rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); } - return rc; + goto open_finished; } } #endif - return fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); + rc = fillInUnixFile(pVfs, fd, dirfd, pFile, zPath, noLock, isDelete); +open_finished: + if( rc!=SQLITE_OK ){ + sqlite3_free(p->pUnused); + } + return rc; } + /* ** Delete the file at zPath. If the dirSync argument is true, fsync() ** the directory after deleting the file. @@ -25122,7 +25858,11 @@ SQLITE_API int sqlite3_current_time = 0; /* Fake system time in seconds since 1 ** return 0. Return 1 if the time and date cannot be found. */ static int unixCurrentTime(sqlite3_vfs *NotUsed, double *prNow){ -#if defined(NO_GETTOD) +#if defined(SQLITE_OMIT_FLOATING_POINT) + time_t t; + time(&t); + *prNow = (((sqlite3_int64)t)/8640 + 24405875)/10; +#elif defined(NO_GETTOD) time_t t; time(&t); *prNow = t/86400.0 + 2440587.5; @@ -25524,33 +26264,43 @@ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ ** but also for freeing the memory associated with the file descriptor. */ static int proxyCreateUnixFile(const char *path, unixFile **ppFile) { - int fd; - int dirfd = -1; unixFile *pNew; + int flags = SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE; int rc = SQLITE_OK; sqlite3_vfs dummyVfs; - fd = open(path, O_RDWR | O_CREAT, SQLITE_DEFAULT_FILE_PERMISSIONS); - if( fd<0 ){ - return SQLITE_CANTOPEN; - } - pNew = (unixFile *)sqlite3_malloc(sizeof(unixFile)); - if( pNew==NULL ){ - rc = SQLITE_NOMEM; - goto end_create_proxy; + if( !pNew ){ + return SQLITE_NOMEM; } memset(pNew, 0, sizeof(unixFile)); + /* Call unixOpen() to open the proxy file. The flags passed to unixOpen() + ** suggest that the file being opened is a "main database". This is + ** necessary as other file types do not necessarily support locking. It + ** is better to use unixOpen() instead of opening the file directly with + ** open(), as unixOpen() sets up the various mechanisms required to + ** make sure a call to close() does not cause the system to discard + ** POSIX locks prematurely. + ** + ** It is important that the xOpen member of the VFS object passed to + ** unixOpen() is NULL. This tells unixOpen() may try to open a proxy-file + ** for the proxy-file (creating a potential infinite loop). + */ dummyVfs.pAppData = (void*)&autolockIoFinder; - rc = fillInUnixFile(&dummyVfs, fd, dirfd, (sqlite3_file*)pNew, path, 0, 0); - if( rc==SQLITE_OK ){ - *ppFile = pNew; - return SQLITE_OK; + dummyVfs.xOpen = 0; + rc = unixOpen(&dummyVfs, path, (sqlite3_file *)pNew, flags, &flags); + if( rc==SQLITE_OK && (flags&SQLITE_OPEN_READONLY) ){ + pNew->pMethod->xClose((sqlite3_file *)pNew); + rc = SQLITE_CANTOPEN; } -end_create_proxy: - close(fd); /* silently leak fd if error, we're already in error */ - sqlite3_free(pNew); + + if( rc!=SQLITE_OK ){ + sqlite3_free(pNew); + pNew = 0; + } + + *ppFile = pNew; return rc; } @@ -26163,6 +26913,7 @@ SQLITE_API int sqlite3_os_init(void){ #endif UNIXVFS("unix-none", nolockIoFinder ), UNIXVFS("unix-dotfile", dotlockIoFinder ), + UNIXVFS("unix-wfl", posixWflIoFinder ), #if OS_VXWORKS UNIXVFS("unix-namedsem", semIoFinder ), #endif @@ -26214,8 +26965,6 @@ SQLITE_API int sqlite3_os_end(void){ ****************************************************************************** ** ** This file contains code that is specific to windows. -** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ */ #if SQLITE_OS_WIN /* This file is used for windows only */ @@ -26283,7 +27032,7 @@ SQLITE_API int sqlite3_os_end(void){ ** This file should be #included by the os_*.c files only. It is not a ** general purpose header file. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _OS_COMMON_H_ #define _OS_COMMON_H_ @@ -26345,7 +27094,7 @@ SQLITE_PRIVATE int sqlite3OSTrace = 0; ** This file contains inline asm code for retrieving "high-performance" ** counters for x86 class CPUs. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _HWTIME_H_ #define _HWTIME_H_ @@ -26733,8 +27482,8 @@ struct tm *__cdecl localtime(const time_t *t) sqlite3_int64 t64; t64 = *t; t64 = (t64 + 11644473600)*10000000; - uTm.dwLowDateTime = t64 & 0xFFFFFFFF; - uTm.dwHighDateTime= t64 >> 32; + uTm.dwLowDateTime = (DWORD)(t64 & 0xFFFFFFFF); + uTm.dwHighDateTime= (DWORD)(t64 >> 32); FileTimeToLocalFileTime(&uTm,&lTm); FileTimeToSystemTime(&lTm,&pTm); y.tm_year = pTm.wYear - 1900; @@ -26754,7 +27503,7 @@ struct tm *__cdecl localtime(const time_t *t) #define UnlockFile(a,b,c,d,e) winceUnlockFile(&a, b, c, d, e) #define LockFileEx(a,b,c,d,e,f) winceLockFileEx(&a, b, c, d, e, f) -#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-offsetof(winFile,h)] +#define HANDLE_TO_WINFILE(a) (winFile*)&((char*)a)[-(int)offsetof(winFile,h)] /* ** Acquire a lock on the handle h @@ -26893,12 +27642,15 @@ static BOOL winceLockFile( winFile *pFile = HANDLE_TO_WINFILE(phFile); BOOL bReturn = FALSE; + UNUSED_PARAMETER(dwFileOffsetHigh); + UNUSED_PARAMETER(nNumberOfBytesToLockHigh); + if (!pFile->hMutex) return TRUE; winceMutexAcquire(pFile->hMutex); /* Wanting an exclusive lock? */ - if (dwFileOffsetLow == SHARED_FIRST - && nNumberOfBytesToLockLow == SHARED_SIZE){ + if (dwFileOffsetLow == (DWORD)SHARED_FIRST + && nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){ if (pFile->shared->nReaders == 0 && pFile->shared->bExclusive == 0){ pFile->shared->bExclusive = TRUE; pFile->local.bExclusive = TRUE; @@ -26907,9 +27659,8 @@ static BOOL winceLockFile( } /* Want a read-only lock? */ - else if ((dwFileOffsetLow >= SHARED_FIRST && - dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE) && - nNumberOfBytesToLockLow == 1){ + else if (dwFileOffsetLow == (DWORD)SHARED_FIRST && + nNumberOfBytesToLockLow == 1){ if (pFile->shared->bExclusive == 0){ pFile->local.nReaders ++; if (pFile->local.nReaders == 1){ @@ -26920,7 +27671,7 @@ static BOOL winceLockFile( } /* Want a pending lock? */ - else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToLockLow == 1){ + else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToLockLow == 1){ /* If no pending lock has been acquired, then acquire it */ if (pFile->shared->bPending == 0) { pFile->shared->bPending = TRUE; @@ -26928,8 +27679,9 @@ static BOOL winceLockFile( bReturn = TRUE; } } + /* Want a reserved lock? */ - else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToLockLow == 1){ + else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToLockLow == 1){ if (pFile->shared->bReserved == 0) { pFile->shared->bReserved = TRUE; pFile->local.bReserved = TRUE; @@ -26954,14 +27706,17 @@ static BOOL winceUnlockFile( winFile *pFile = HANDLE_TO_WINFILE(phFile); BOOL bReturn = FALSE; + UNUSED_PARAMETER(dwFileOffsetHigh); + UNUSED_PARAMETER(nNumberOfBytesToUnlockHigh); + if (!pFile->hMutex) return TRUE; winceMutexAcquire(pFile->hMutex); /* Releasing a reader lock or an exclusive lock */ - if (dwFileOffsetLow >= SHARED_FIRST && - dwFileOffsetLow < SHARED_FIRST + SHARED_SIZE){ + if (dwFileOffsetLow == (DWORD)SHARED_FIRST){ /* Did we have an exclusive lock? */ if (pFile->local.bExclusive){ + assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE); pFile->local.bExclusive = FALSE; pFile->shared->bExclusive = FALSE; bReturn = TRUE; @@ -26969,6 +27724,7 @@ static BOOL winceUnlockFile( /* Did we just have a reader lock? */ else if (pFile->local.nReaders){ + assert(nNumberOfBytesToUnlockLow == (DWORD)SHARED_SIZE || nNumberOfBytesToUnlockLow == 1); pFile->local.nReaders --; if (pFile->local.nReaders == 0) { @@ -26979,7 +27735,7 @@ static BOOL winceUnlockFile( } /* Releasing a pending lock */ - else if (dwFileOffsetLow == PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){ + else if (dwFileOffsetLow == (DWORD)PENDING_BYTE && nNumberOfBytesToUnlockLow == 1){ if (pFile->local.bPending){ pFile->local.bPending = FALSE; pFile->shared->bPending = FALSE; @@ -26987,7 +27743,7 @@ static BOOL winceUnlockFile( } } /* Releasing a reserved lock */ - else if (dwFileOffsetLow == RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){ + else if (dwFileOffsetLow == (DWORD)RESERVED_BYTE && nNumberOfBytesToUnlockLow == 1){ if (pFile->local.bReserved) { pFile->local.bReserved = FALSE; pFile->shared->bReserved = FALSE; @@ -27010,11 +27766,14 @@ static BOOL winceLockFileEx( DWORD nNumberOfBytesToLockHigh, LPOVERLAPPED lpOverlapped ){ + UNUSED_PARAMETER(dwReserved); + UNUSED_PARAMETER(nNumberOfBytesToLockHigh); + /* If the caller wants a shared read lock, forward this call ** to winceLockFile */ - if (lpOverlapped->Offset == SHARED_FIRST && + if (lpOverlapped->Offset == (DWORD)SHARED_FIRST && dwFlags == 1 && - nNumberOfBytesToLockLow == SHARED_SIZE){ + nNumberOfBytesToLockLow == (DWORD)SHARED_SIZE){ return winceLockFile(phFile, SHARED_FIRST, 0, 1, 0); } return FALSE; @@ -28016,9 +28775,15 @@ static int getSectorSize( const char *zRelative /* UTF-8 file name */ ){ DWORD bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE; + /* GetDiskFreeSpace is not supported under WINCE */ +#if SQLITE_OS_WINCE + UNUSED_PARAMETER(pVfs); + UNUSED_PARAMETER(zRelative); +#else char zFullpath[MAX_PATH+1]; int rc; - DWORD dwRet = 0, dwDummy; + DWORD dwRet = 0; + DWORD dwDummy; /* ** We need to get the full path name of the file @@ -28044,7 +28809,6 @@ static int getSectorSize( &bytesPerSector, &dwDummy, &dwDummy); -#if SQLITE_OS_WINCE==0 }else{ /* trim path to just drive reference */ CHAR *p = (CHAR *)zConverted; @@ -28059,7 +28823,6 @@ static int getSectorSize( &bytesPerSector, &dwDummy, &dwDummy); -#endif } free(zConverted); } @@ -28067,6 +28830,7 @@ static int getSectorSize( bytesPerSector = SQLITE_DEFAULT_SECTOR_SIZE; } } +#endif return (int) bytesPerSector; } @@ -28293,6 +29057,7 @@ SQLITE_API int sqlite3_os_init(void){ winCurrentTime, /* xCurrentTime */ winGetLastError /* xGetLastError */ }; + sqlite3_vfs_register(&winVfs, 1); return SQLITE_OK; } @@ -28340,11 +29105,11 @@ SQLITE_API int sqlite3_os_end(void){ ** start of a transaction, and is thus usually less than a few thousand, ** but can be as large as 2 billion for a really big database. ** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** @(#) $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* Size of the Bitvec structure in bytes. */ -#define BITVEC_SZ 512 +#define BITVEC_SZ (sizeof(void*)*128) /* 512 on 32bit. 1024 on 64bit */ /* Round the union size down to the nearest pointer boundary, since that's how ** it will be aligned within the Bitvec struct. */ @@ -28451,8 +29216,7 @@ SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){ u32 h = BITVEC_HASH(i++); while( p->u.aHash[h] ){ if( p->u.aHash[h]==i ) return 1; - h++; - if( h>=BITVEC_NINT ) h = 0; + h = (h+1) % BITVEC_NINT; } return 0; } @@ -28472,7 +29236,7 @@ SQLITE_PRIVATE int sqlite3BitvecTest(Bitvec *p, u32 i){ */ SQLITE_PRIVATE int sqlite3BitvecSet(Bitvec *p, u32 i){ u32 h; - assert( p!=0 ); + if( p==0 ) return SQLITE_OK; assert( i>0 ); assert( i<=p->iSize ); i--; @@ -28542,7 +29306,7 @@ bitvec_set_end: ** that BitvecClear can use to rebuilt its hash table. */ SQLITE_PRIVATE void sqlite3BitvecClear(Bitvec *p, u32 i, void *pBuf){ - assert( p!=0 ); + if( p==0 ) return; assert( i>0 ); i--; while( p->iDivisor ){ @@ -28653,6 +29417,10 @@ SQLITE_PRIVATE int sqlite3BitvecBuiltinTest(int sz, int *aOp){ if( pBitvec==0 || pV==0 || pTmpSpace==0 ) goto bitvec_end; memset(pV, 0, (sz+7)/8 + 1); + /* NULL pBitvec tests */ + sqlite3BitvecSet(0, 1); + sqlite3BitvecClear(0, 1, pTmpSpace); + /* Run the program */ pc = 0; while( (op = aOp[pc])!=0 ){ @@ -28726,7 +29494,7 @@ bitvec_end: ************************************************************************* ** This file implements that page cache. ** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** @(#) $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -28922,6 +29690,7 @@ SQLITE_PRIVATE int sqlite3PcacheFetch( int eCreate; assert( pCache!=0 ); + assert( createFlag==1 || createFlag==0 ); assert( pgno>0 ); /* If the pluggable cache (sqlite3_pcache*) has not been allocated, @@ -28939,10 +29708,7 @@ SQLITE_PRIVATE int sqlite3PcacheFetch( pCache->pCache = p; } - eCreate = createFlag ? 1 : 0; - if( eCreate && (!pCache->bPurgeable || !pCache->pDirty) ){ - eCreate = 2; - } + eCreate = createFlag * (1 + (!pCache->bPurgeable || !pCache->pDirty)); if( pCache->pCache ){ pPage = sqlite3GlobalConfig.pcache.xFetch(pCache->pCache, pgno, eCreate); } @@ -29184,24 +29950,22 @@ static PgHdr *pcacheMergeDirtyList(PgHdr *pA, PgHdr *pB){ ** Sort the list of pages in accending order by pgno. Pages are ** connected by pDirty pointers. The pDirtyPrev pointers are ** corrupted by this sort. +** +** Since there cannot be more than 2^31 distinct pages in a database, +** there cannot be more than 31 buckets required by the merge sorter. +** One extra bucket is added to catch overflow in case something +** ever changes to make the previous sentence incorrect. */ -#define N_SORT_BUCKET_ALLOC 25 -#define N_SORT_BUCKET 25 -#ifdef SQLITE_TEST - int sqlite3_pager_n_sort_bucket = 0; - #undef N_SORT_BUCKET - #define N_SORT_BUCKET \ - (sqlite3_pager_n_sort_bucket?sqlite3_pager_n_sort_bucket:N_SORT_BUCKET_ALLOC) -#endif +#define N_SORT_BUCKET 32 static PgHdr *pcacheSortDirtyList(PgHdr *pIn){ - PgHdr *a[N_SORT_BUCKET_ALLOC], *p; + PgHdr *a[N_SORT_BUCKET], *p; int i; memset(a, 0, sizeof(a)); while( pIn ){ p = pIn; pIn = p->pDirty; p->pDirty = 0; - for(i=0; ipCache->bPurgeable ){ pcache1.nCurrentPage--; } @@ -29706,6 +30472,8 @@ static int pcache1Init(void *NotUsed){ /* ** Implementation of the sqlite3_pcache.xShutdown method. +** Note that the static mutex allocated in xInit does +** not need to be freed. */ static void pcache1Shutdown(void *NotUsed){ UNUSED_PARAMETER(NotUsed); @@ -29769,7 +30537,14 @@ static int pcache1Pagecount(sqlite3_pcache *p){ ** Fetch a page by key value. ** ** Whether or not a new page may be allocated by this function depends on -** the value of the createFlag argument. +** the value of the createFlag argument. 0 means do not allocate a new +** page. 1 means allocate a new page if space is easily available. 2 +** means to try really hard to allocate a new page. +** +** For a non-purgeable cache (a cache used as the storage for an in-memory +** database) there is really no difference between createFlag 1 and 2. So +** the calling function (pcache.c) will never have a createFlag of 1 on +** a non-purgable cache. ** ** There are three different approaches to obtaining space for a page, ** depending on the value of parameter createFlag (which may be 0, 1 or 2). @@ -29780,9 +30555,8 @@ static int pcache1Pagecount(sqlite3_pcache *p){ ** 2. If createFlag==0 and the page is not already in the cache, NULL is ** returned. ** -** 3. If createFlag is 1, the cache is marked as purgeable and the page is -** not already in the cache, and if either of the following are true, -** return NULL: +** 3. If createFlag is 1, and the page is not already in the cache, +** and if either of the following are true, return NULL: ** ** (a) the number of pages pinned by the cache is greater than ** PCache1.nMax, or @@ -29811,6 +30585,7 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ PCache1 *pCache = (PCache1 *)p; PgHdr1 *pPage = 0; + assert( pCache->bPurgeable || createFlag!=1 ); pcache1EnterMutex(); if( createFlag==1 ) sqlite3BeginBenignMalloc(); @@ -29827,7 +30602,7 @@ static void *pcache1Fetch(sqlite3_pcache *p, unsigned int iKey, int createFlag){ /* Step 3 of header comment. */ nPinned = pCache->nPage - pCache->nRecyclable; - if( createFlag==1 && pCache->bPurgeable && ( + if( createFlag==1 && ( nPinned>=(pcache1.nMaxPage+pCache->nMin-pcache1.nMinPage) || nPinned>=(pCache->nMax * 9 / 10) )){ @@ -29953,7 +30728,14 @@ static void pcache1Rekey( pPage->pNext = pCache->apHash[h]; pCache->apHash[h] = pPage; - if( iNew>pCache->iMaxKey ){ + /* The xRekey() interface is only used to move pages earlier in the + ** database file (in order to move all free pages to the end of the + ** file where they can be truncated off.) Hence, it is not possible + ** for the new page number to be greater than the largest previously + ** fetched page. But we retain the following test in case xRekey() + ** begins to be used in different ways in the future. + */ + if( NEVER(iNew>pCache->iMaxKey) ){ pCache->iMaxKey = iNew; } @@ -30130,7 +30912,7 @@ SQLITE_PRIVATE void sqlite3PcacheStats( ** There is an added cost of O(N) when switching between TEST and ** SMALLEST primitives. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ @@ -30514,7 +31296,7 @@ SQLITE_PRIVATE int sqlite3RowSetTest(RowSet *pRowSet, u8 iBatch, sqlite3_int64 i ** file simultaneously, or one process from reading the database while ** another is writing. ** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** @(#) $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef SQLITE_OMIT_DISKIO @@ -30599,22 +31381,22 @@ int sqlite3PagerTrace=1; /* True to enable tracing */ */ #ifdef SQLITE_HAS_CODEC # define CODEC1(P,D,N,X,E) \ - if( P->xCodec && P->xCodec(P->pCodecArg,D,N,X)==0 ){ E; } + if( P->xCodec && P->xCodec(P->pCodec,D,N,X)==0 ){ E; } # define CODEC2(P,D,N,X,E,O) \ if( P->xCodec==0 ){ O=(char*)D; }else \ - if( (O=(char*)(P->xCodec(P->pCodecArg,D,N,X)))==0 ){ E; } + if( (O=(char*)(P->xCodec(P->pCodec,D,N,X)))==0 ){ E; } #else # define CODEC1(P,D,N,X,E) /* NO-OP */ # define CODEC2(P,D,N,X,E,O) O=(char*)D #endif /* -** The maximum allowed sector size. 16MB. If the xSectorsize() method +** The maximum allowed sector size. 64KiB. If the xSectorsize() method ** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. ** This could conceivably cause corruption following a power failure on ** such a system. This is currently an undocumented limit. */ -#define MAX_SECTOR_SIZE 0x0100000 +#define MAX_SECTOR_SIZE 0x10000 /* ** An instance of the following structure is allocated for each active @@ -30785,7 +31567,8 @@ struct Pager { char dbFileVers[16]; /* Changes whenever database file changes */ u32 sectorSize; /* Assumed sector size during rollback */ - int nExtra; /* Add this many bytes to each in-memory page */ + u16 nExtra; /* Add this many bytes to each in-memory page */ + i16 nReserve; /* Number of unused bytes at end of each page */ u32 vfsFlags; /* Flags for sqlite3_vfs.xOpen() */ int pageSize; /* Number of bytes in a page */ Pgno mxPgno; /* Maximum allowed size of the database */ @@ -30800,7 +31583,9 @@ struct Pager { void (*xReiniter)(DbPage*); /* Call this routine when reloading pages */ #ifdef SQLITE_HAS_CODEC void *(*xCodec)(void*,void*,Pgno,int); /* Routine for en/decoding data */ - void *pCodecArg; /* First argument to xCodec() */ + void (*xCodecSizeChng)(void*,int,int); /* Notify of page size changes */ + void (*xCodecFree)(void*); /* Destructor for the codec */ + void *pCodec; /* First argument to xCodec... methods */ #endif char *pTmpSpace; /* Pager.pageSize bytes of space for tmp use */ i64 journalSizeLimit; /* Size limit for persistent journal files */ @@ -31249,7 +32034,6 @@ static int writeJournalHdr(Pager *pPager){ } pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager); - memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); /* ** Write the nRec Field - the number of page records that follow this @@ -31275,9 +32059,10 @@ static int writeJournalHdr(Pager *pPager){ if( (pPager->noSync) || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY) || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) ){ + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff); }else{ - put32bits(&zHeader[sizeof(aJournalMagic)], 0); + memset(zHeader, 0, sizeof(aJournalMagic)+4); } /* The random check-hash initialiser */ @@ -31344,6 +32129,7 @@ static int writeJournalHdr(Pager *pPager){ */ static int readJournalHdr( Pager *pPager, /* Pager object */ + int isHot, i64 journalSize, /* Size of the open journal file in bytes */ u32 *pNRec, /* OUT: Value read from the nRec field */ u32 *pDbSize /* OUT: Value of original database size field */ @@ -31369,12 +32155,14 @@ static int readJournalHdr( ** SQLITE_DONE. If an IO error occurs, return an error code. Otherwise, ** proceed. */ - rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff); - if( rc ){ - return rc; - } - if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ - return SQLITE_DONE; + if( isHot || iHdrOff!=pPager->journalHdr ){ + rc = sqlite3OsRead(pPager->jfd, aMagic, sizeof(aMagic), iHdrOff); + if( rc ){ + return rc; + } + if( memcmp(aMagic, aJournalMagic, sizeof(aMagic))!=0 ){ + return SQLITE_DONE; + } } /* Read the first three 32-bit fields of the journal header: The nRec @@ -31422,7 +32210,7 @@ static int readJournalHdr( ** PagerSetPagesize() is tested. */ iPageSize16 = (u16)iPageSize; - rc = sqlite3PagerSetPagesize(pPager, &iPageSize16); + rc = sqlite3PagerSetPagesize(pPager, &iPageSize16, -1); testcase( rc!=SQLITE_OK ); assert( rc!=SQLITE_OK || iPageSize16==(u16)iPageSize ); @@ -31615,7 +32403,7 @@ static void pager_unlock(Pager *pPager){ /* If the file is unlocked, somebody else might change it. The ** values stored in Pager.dbSize etc. might become invalid if ** this happens. TODO: Really, this doesn't need to be cleared - ** until the change-counter check fails in pagerSharedLock(). + ** until the change-counter check fails in PagerSharedLock(). */ pPager->dbSizeValid = 0; @@ -31662,26 +32450,14 @@ static void pager_unlock(Pager *pPager){ */ static int pager_error(Pager *pPager, int rc){ int rc2 = rc & 0xff; + assert( rc==SQLITE_OK || !MEMDB ); assert( pPager->errCode==SQLITE_FULL || pPager->errCode==SQLITE_OK || (pPager->errCode & 0xff)==SQLITE_IOERR ); - if( - rc2==SQLITE_FULL || - rc2==SQLITE_IOERR || - rc2==SQLITE_CORRUPT - ){ + if( rc2==SQLITE_FULL || rc2==SQLITE_IOERR ){ pPager->errCode = rc; - if( pPager->state==PAGER_UNLOCK - && sqlite3PcacheRefCount(pPager->pPCache)==0 - ){ - /* If the pager is already unlocked, call pager_unlock() now to - ** clear the error state and ensure that the pager-cache is - ** completely empty. - */ - pager_unlock(pPager); - } } return rc; } @@ -31780,21 +32556,10 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){ assert( isOpen(pPager->jfd) || pPager->pInJournal==0 ); if( isOpen(pPager->jfd) ){ - /* TODO: There's a problem here if a journal-file was opened in MEMORY - ** mode and then the journal-mode is changed to TRUNCATE or PERSIST - ** during the transaction. This code should be changed to assume - ** that the journal mode has not changed since the transaction was - ** started. And the sqlite3PagerJournalMode() function should be - ** changed to make sure that this is the case too. - */ - /* Finalize the journal file. */ - if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ - int isMemoryJournal = sqlite3IsMemJournal(pPager->jfd); + if( sqlite3IsMemJournal(pPager->jfd) ){ + assert( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ); sqlite3OsClose(pPager->jfd); - if( !isMemoryJournal ){ - rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); - } }else if( pPager->journalMode==PAGER_JOURNALMODE_TRUNCATE ){ if( pPager->journalOff==0 ){ rc = SQLITE_OK; @@ -31811,9 +32576,15 @@ static int pager_end_transaction(Pager *pPager, int hasMaster){ pPager->journalOff = 0; pPager->journalStarted = 0; }else{ - assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE || rc ); + /* This branch may be executed with Pager.journalMode==MEMORY if + ** a hot-journal was just rolled back. In this case the journal + ** file should be closed and deleted. If this connection writes to + ** the database file, it will do so using an in-memory journal. */ + assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + ); sqlite3OsClose(pPager->jfd); - if( rc==SQLITE_OK && !pPager->tempFile ){ + if( !pPager->tempFile ){ rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0); } } @@ -32024,7 +32795,11 @@ static int pager_playback_one_page( if( pgno>pPager->dbFileSize ){ pPager->dbFileSize = pgno; } - sqlite3BackupUpdate(pPager->pBackup, pgno, aData); + if( pPager->pBackup ){ + CODEC1(pPager, aData, pgno, 3, rc=SQLITE_NOMEM); + sqlite3BackupUpdate(pPager->pBackup, pgno, aData); + CODEC1(pPager, aData, pgno, 0, rc=SQLITE_NOMEM); + } }else if( !isMainJrnl && pPg==0 ){ /* If this is a rollback of a savepoint and data was not written to ** the database and the page is not in-memory, there is a potential @@ -32059,9 +32834,7 @@ static int pager_playback_one_page( void *pData; pData = pPg->pData; memcpy(pData, aData, pPager->pageSize); - if( pPager->xReiniter ){ - pPager->xReiniter(pPg); - } + pPager->xReiniter(pPg); if( isMainJrnl && (!isSavepnt || *pOffset<=pPager->journalHdr) ){ /* If the contents of this page were just restored from the main ** journal file, then its content must be as they were when the @@ -32099,46 +32872,6 @@ static int pager_playback_one_page( return rc; } -#if !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST) -/* -** This routine looks ahead into the main journal file and determines -** whether or not the next record (the record that begins at file -** offset pPager->journalOff) is a well-formed page record consisting -** of a valid page number, pPage->pageSize bytes of content, followed -** by a valid checksum. -** -** The pager never needs to know this in order to do its job. This -** routine is only used from with assert() and testcase() macros. -*/ -static int pagerNextJournalPageIsValid(Pager *pPager){ - Pgno pgno; /* The page number of the page */ - u32 cksum; /* The page checksum */ - int rc; /* Return code from read operations */ - sqlite3_file *fd; /* The file descriptor from which we are reading */ - u8 *aData; /* Content of the page */ - - /* Read the page number header */ - fd = pPager->jfd; - rc = read32bits(fd, pPager->journalOff, &pgno); - if( rc!=SQLITE_OK ){ return 0; } /*NO_TEST*/ - if( pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){ return 0; } /*NO_TEST*/ - if( pgno>(Pgno)pPager->dbSize ){ return 0; } /*NO_TEST*/ - - /* Read the checksum */ - rc = read32bits(fd, pPager->journalOff+pPager->pageSize+4, &cksum); - if( rc!=SQLITE_OK ){ return 0; } /*NO_TEST*/ - - /* Read the data and verify the checksum */ - aData = (u8*)pPager->pTmpSpace; - rc = sqlite3OsRead(fd, aData, pPager->pageSize, pPager->journalOff+4); - if( rc!=SQLITE_OK ){ return 0; } /*NO_TEST*/ - if( pager_cksum(pPager, aData)!=cksum ){ return 0; } /*NO_TEST*/ - - /* Reach this point only if the page is valid */ - return 1; -} -#endif /* !defined(NDEBUG) || defined(SQLITE_COVERAGE_TEST) */ - /* ** Parameter zMaster is the name of a master journal file. A single journal ** file that referred to the master journal file has just been rolled back. @@ -32214,14 +32947,15 @@ static int pager_delmaster(Pager *pPager, const char *zMaster){ /* Load the entire master journal file into space obtained from ** sqlite3_malloc() and pointed to by zMasterJournal. */ - zMasterJournal = (char *)sqlite3Malloc((int)nMasterJournal + nMasterPtr); + zMasterJournal = sqlite3Malloc((int)nMasterJournal + nMasterPtr + 1); if( !zMasterJournal ){ rc = SQLITE_NOMEM; goto delmaster_out; } - zMasterPtr = &zMasterJournal[nMasterJournal]; + zMasterPtr = &zMasterJournal[nMasterJournal+1]; rc = sqlite3OsRead(pMaster, zMasterJournal, (int)nMasterJournal, 0); if( rc!=SQLITE_OK ) goto delmaster_out; + zMasterJournal[nMasterJournal] = 0; zJournal = zMasterJournal; while( (zJournal-zMasterJournal)journalHdr+JOURNAL_HDR_SZ(pPager)!=pPager->journalOff - && ((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager))>0 - && pagerNextJournalPageIsValid(pPager) - ); if( nRec==0 && !isHot && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){ nRec = (int)((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager)); @@ -32685,7 +33414,7 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ u32 ii; /* Loop counter */ u32 nJRec = 0; /* Number of Journal Records */ u32 dummy; - rc = readJournalHdr(pPager, szJ, &nJRec, &dummy); + rc = readJournalHdr(pPager, 0, szJ, &nJRec, &dummy); assert( rc!=SQLITE_DONE ); /* @@ -32693,11 +33422,6 @@ static int pagerPlaybackSavepoint(Pager *pPager, PagerSavepoint *pSavepoint){ ** test is related to ticket #2565. See the discussion in the ** pager_playback() function for additional information. */ - assert( !(nJRec==0 - && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)!=pPager->journalOff - && ((szJ - pPager->journalOff) / JOURNAL_PG_SZ(pPager))>0 - && pagerNextJournalPageIsValid(pPager)) - ); if( nJRec==0 && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){ @@ -32846,15 +33570,19 @@ SQLITE_PRIVATE void sqlite3PagerSetBusyhandler( } /* -** Set the reinitializer for this pager. If not NULL, the reinitializer -** is called when the content of a page in cache is modified (restored) -** as part of a transaction or savepoint rollback. The callback gives -** higher-level code an opportunity to restore the EXTRA section to -** agree with the restored page data. +** Report the current page size and number of reserved bytes back +** to the codec. */ -SQLITE_PRIVATE void sqlite3PagerSetReiniter(Pager *pPager, void (*xReinit)(DbPage*)){ - pPager->xReiniter = xReinit; +#ifdef SQLITE_HAS_CODEC +static void pagerReportSize(Pager *pPager){ + if( pPager->xCodecSizeChng ){ + pPager->xCodecSizeChng(pPager->pCodec, pPager->pageSize, + (int)pPager->nReserve); + } } +#else +# define pagerReportSize(X) /* No-op if we do not support a codec */ +#endif /* ** Change the page size used by the Pager object. The new page size @@ -32886,14 +33614,15 @@ SQLITE_PRIVATE void sqlite3PagerSetReiniter(Pager *pPager, void (*xReinit)(DbPag ** function was called, or because the memory allocation attempt failed, ** then *pPageSize is set to the old, retained page size before returning. */ -SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize){ +SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize, int nReserve){ int rc = pPager->errCode; + if( rc==SQLITE_OK ){ u16 pageSize = *pPageSize; assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); - if( pageSize && pageSize!=pPager->pageSize - && (pPager->memDb==0 || pPager->dbSize==0) + if( (pPager->memDb==0 || pPager->dbSize==0) && sqlite3PcacheRefCount(pPager->pPCache)==0 + && pageSize && pageSize!=pPager->pageSize ){ char *pNew = (char *)sqlite3PageMalloc(pageSize); if( !pNew ){ @@ -32907,6 +33636,10 @@ SQLITE_PRIVATE int sqlite3PagerSetPagesize(Pager *pPager, u16 *pPageSize){ } } *pPageSize = (u16)pPager->pageSize; + if( nReserve<0 ) nReserve = pPager->nReserve; + assert( nReserve>=0 && nReserve<1000 ); + pPager->nReserve = (i16)nReserve; + pagerReportSize(pPager); } return rc; } @@ -33102,6 +33835,40 @@ static int pager_wait_on_lock(Pager *pPager, int locktype){ return rc; } +/* +** Function assertTruncateConstraint(pPager) checks that one of the +** following is true for all dirty pages currently in the page-cache: +** +** a) The page number is less than or equal to the size of the +** current database image, in pages, OR +** +** b) if the page content were written at this time, it would not +** be necessary to write the current content out to the sub-journal +** (as determined by function subjRequiresPage()). +** +** If the condition asserted by this function were not true, and the +** dirty page were to be discarded from the cache via the pagerStress() +** routine, pagerStress() would not write the current page content to +** the database file. If a savepoint transaction were rolled back after +** this happened, the correct behaviour would be to restore the current +** content of the page. However, since this content is not present in either +** the database file or the portion of the rollback journal and +** sub-journal rolled back the content could not be restored and the +** database image would become corrupt. It is therefore fortunate that +** this circumstance cannot arise. +*/ +#if defined(SQLITE_DEBUG) +static void assertTruncateConstraintCb(PgHdr *pPg){ + assert( pPg->flags&PGHDR_DIRTY ); + assert( !subjRequiresPage(pPg) || pPg->pgno<=pPg->pPager->dbSize ); +} +static void assertTruncateConstraint(Pager *pPager){ + sqlite3PcacheIterateDirty(pPager->pPCache, assertTruncateConstraintCb); +} +#else +# define assertTruncateConstraint(pPager) +#endif + /* ** Truncate the in-memory database file image to nPage pages. This ** function does not actually modify the database file on disk. It @@ -33113,6 +33880,7 @@ SQLITE_PRIVATE void sqlite3PagerTruncateImage(Pager *pPager, Pgno nPage){ assert( pPager->dbSize>=nPage ); assert( pPager->state>=PAGER_RESERVED ); pPager->dbSize = nPage; + assertTruncateConstraint(pPager); } /* @@ -33155,6 +33923,10 @@ SQLITE_PRIVATE int sqlite3PagerClose(Pager *pPager){ sqlite3PageFree(pPager->pTmpSpace); sqlite3PcacheClose(pPager->pPCache); +#ifdef SQLITE_HAS_CODEC + if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); +#endif + assert( !pPager->aSavepoint && !pPager->pInJournal ); assert( !isOpen(pPager->jfd) && !isOpen(pPager->sjfd) ); @@ -33225,12 +33997,6 @@ static int syncJournal(Pager *pPager){ assert( isOpen(pPager->jfd) ); if( 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){ - /* Variable iNRecOffset is set to the offset in the journal file - ** of the nRec field of the most recently written journal header. - ** This field will be updated following the xSync() operation - ** on the journal file. */ - i64 iNRecOffset = pPager->journalHdr + sizeof(aJournalMagic); - /* This block deals with an obscure problem. If the last connection ** that wrote to this database was operating in persistent-journal ** mode, then the journal file may at this point actually be larger @@ -33253,8 +34019,14 @@ static int syncJournal(Pager *pPager){ ** as a temporary buffer to inspect the first couple of bytes of ** the potential journal header. */ - i64 iNextHdrOffset = journalHdrOffset(pPager); + i64 iNextHdrOffset; u8 aMagic[8]; + u8 zHeader[sizeof(aJournalMagic)+4]; + + memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); + put32bits(&zHeader[sizeof(aJournalMagic)], pPager->nRec); + + iNextHdrOffset = journalHdrOffset(pPager); rc = sqlite3OsRead(pPager->jfd, aMagic, 8, iNextHdrOffset); if( rc==SQLITE_OK && 0==memcmp(aMagic, aJournalMagic, 8) ){ static const u8 zerobyte = 0; @@ -33281,8 +34053,10 @@ static int syncJournal(Pager *pPager){ rc = sqlite3OsSync(pPager->jfd, pPager->sync_flags); if( rc!=SQLITE_OK ) return rc; } - IOTRACE(("JHDR %p %lld %d\n", pPager, iNRecOffset, 4)); - rc = write32bits(pPager->jfd, iNRecOffset, pPager->nRec); + IOTRACE(("JHDR %p %lld\n", pPager, pPager->journalHdr)); + rc = sqlite3OsWrite( + pPager->jfd, zHeader, sizeof(zHeader), pPager->journalHdr + ); if( rc!=SQLITE_OK ) return rc; } if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ @@ -33342,7 +34116,7 @@ static int pager_write_pagelist(PgHdr *pList){ Pager *pPager; /* Pager object */ int rc; /* Return code */ - if( pList==0 ) return SQLITE_OK; + if( NEVER(pList==0) ) return SQLITE_OK; pPager = pList->pPager; /* At this point there may be either a RESERVED or EXCLUSIVE lock on the @@ -33406,7 +34180,7 @@ static int pager_write_pagelist(PgHdr *pList){ } /* Update any backup objects copying the contents of this pager. */ - sqlite3BackupUpdate(pPager->pBackup, pgno, (u8 *)pData); + sqlite3BackupUpdate(pPager->pBackup, pgno, (u8*)pList->pData); PAGERTRACE(("STORE %d page %d hash(%08x)\n", PAGERID(pPager), pgno, pager_pagehash(pList))); @@ -33459,7 +34233,6 @@ static int subjournalPage(PgHdr *pPg){ pPager->nSubRec++; assert( pPager->nSavepoint>0 ); rc = addToSavepointBitvecs(pPager, pPg->pgno); - testcase( rc!=SQLITE_OK ); } return rc; } @@ -33504,7 +34277,9 @@ static int pagerStress(void *p, PgHdr *pPg){ ** Similarly, if the pager has already entered the error state, do not ** try to write the contents of pPg to disk. */ - if( pPager->errCode || (pPager->doNotSync && pPg->flags&PGHDR_NEED_SYNC) ){ + if( NEVER(pPager->errCode) + || (pPager->doNotSync && pPg->flags&PGHDR_NEED_SYNC) + ){ return SQLITE_OK; } @@ -33547,7 +34322,9 @@ static int pagerStress(void *p, PgHdr *pPg){ ** be restored to its current value when the "ROLLBACK TO sp" is ** executed. */ - if( rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg) ){ + if( NEVER( + rc==SQLITE_OK && pPg->pgno>pPager->dbSize && subjRequiresPage(pPg) + ) ){ rc = subjournalPage(pPg); } @@ -33603,7 +34380,8 @@ SQLITE_PRIVATE int sqlite3PagerOpen( const char *zFilename, /* Name of the database file to open */ int nExtra, /* Extra bytes append to each in-memory page */ int flags, /* flags controlling this file */ - int vfsFlags /* flags passed through to sqlite3_vfs.xOpen() */ + int vfsFlags, /* flags passed through to sqlite3_vfs.xOpen() */ + void (*xReinit)(DbPage*) /* Function to reinitialize pages */ ){ u8 *pPtr; Pager *pPager = 0; /* Pager object to allocate and return */ @@ -33712,6 +34490,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( memcpy(pPager->zFilename, zPathname, nPathname); memcpy(pPager->zJournal, zPathname, nPathname); memcpy(&pPager->zJournal[nPathname], "-journal", 8); + if( pPager->zFilename[0]==0 ) pPager->zJournal[0] = 0; sqlite3_free(zPathname); } pPager->pVfs = pVfs; @@ -33776,7 +34555,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( */ if( rc==SQLITE_OK ){ assert( pPager->memDb==0 ); - rc = sqlite3PagerSetPagesize(pPager, &szPageDflt); + rc = sqlite3PagerSetPagesize(pPager, &szPageDflt, -1); testcase( rc!=SQLITE_OK ); } @@ -33791,6 +34570,7 @@ SQLITE_PRIVATE int sqlite3PagerOpen( } /* Initialize the PCache object. */ + assert( nExtra<1000 ); nExtra = ROUND8(nExtra); sqlite3PcacheOpen(szPageDflt, nExtra, !memDb, !memDb?pagerStress:0, (void *)pPager, pPager->pPCache); @@ -33820,21 +34600,25 @@ SQLITE_PRIVATE int sqlite3PagerOpen( pPager->memDb = (u8)memDb; pPager->readOnly = (u8)readOnly; /* pPager->needSync = 0; */ - pPager->noSync = (pPager->tempFile || !useJournal) ?1:0; + assert( useJournal || pPager->tempFile ); + pPager->noSync = pPager->tempFile; pPager->fullSync = pPager->noSync ?0:1; pPager->sync_flags = SQLITE_SYNC_NORMAL; /* pPager->pFirst = 0; */ /* pPager->pFirstSynced = 0; */ /* pPager->pLast = 0; */ - pPager->nExtra = nExtra; + pPager->nExtra = (u16)nExtra; pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT; assert( isOpen(pPager->fd) || tempFile ); setSectorSize(pPager); - if( memDb ){ + if( !useJournal ){ + pPager->journalMode = PAGER_JOURNALMODE_OFF; + }else if( memDb ){ pPager->journalMode = PAGER_JOURNALMODE_MEMORY; } /* pPager->xBusyHandler = 0; */ /* pPager->pBusyHandlerArg = 0; */ + pPager->xReiniter = xReinit; /* memset(pPager->aHash, 0, sizeof(pPager->aHash)); */ *ppPager = pPager; return SQLITE_OK; @@ -33882,6 +34666,7 @@ static int hasHotJournal(Pager *pPager, int *pExists){ assert( pPager->useJournal ); assert( isOpen(pPager->fd) ); assert( !isOpen(pPager->jfd) ); + assert( pPager->state <= PAGER_SHARED ); *pExists = 0; rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists); @@ -33910,13 +34695,9 @@ static int hasHotJournal(Pager *pPager, int *pExists){ if( rc==SQLITE_OK ){ if( nPage==0 ){ sqlite3BeginBenignMalloc(); - if( pPager->state>=PAGER_RESERVED - || sqlite3OsLock(pPager->fd, RESERVED_LOCK)==SQLITE_OK ){ + if( sqlite3OsLock(pPager->fd, RESERVED_LOCK)==SQLITE_OK ){ sqlite3OsDelete(pVfs, pPager->zJournal, 0); - assert( pPager->state>=PAGER_SHARED ); - if( pPager->state==PAGER_SHARED ){ - sqlite3OsUnlock(pPager->fd, SHARED_LOCK); - } + sqlite3OsUnlock(pPager->fd, SHARED_LOCK); } sqlite3EndBenignMalloc(); }else{ @@ -33975,8 +34756,9 @@ static int readDbPage(PgHdr *pPg){ i64 iOffset; /* Byte offset of file to read from */ assert( pPager->state>=PAGER_SHARED && !MEMDB ); + assert( isOpen(pPager->fd) ); - if( !isOpen(pPager->fd) ){ + if( NEVER(!isOpen(pPager->fd)) ){ assert( pPager->tempFile ); memset(pPg->pData, 0, pPager->pageSize); return SQLITE_OK; @@ -34002,10 +34784,12 @@ static int readDbPage(PgHdr *pPg){ } /* -** This function is called whenever the upper layer requests a database -** page is requested, before the cache is checked for a suitable page -** or any data is read from the database. It performs the following -** two functions: +** This function is called to obtain a shared lock on the database file. +** It is illegal to call sqlite3PagerAcquire() until after this function +** has been successfully called. If a shared-lock is already held when +** this function is called, it is a no-op. +** +** The following operations are also performed by this function. ** ** 1) If the pager is currently in PAGER_UNLOCK state (no lock held ** on the database file), then an attempt is made to obtain a @@ -34031,46 +34815,41 @@ static int readDbPage(PgHdr *pPg){ ** IO error occurs while locking the database, checking for a hot-journal ** file or rolling back a journal file, the IO error code is returned. */ -static int pagerSharedLock(Pager *pPager){ +SQLITE_PRIVATE int sqlite3PagerSharedLock(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ int isErrorReset = 0; /* True if recovering from error state */ - /* If this database is opened for exclusive access, has no outstanding - ** page references and is in an error-state, this is a chance to clear - ** the error. Discard the contents of the pager-cache and treat any - ** open journal file as a hot-journal. + /* This routine is only called from b-tree and only when there are no + ** outstanding pages */ + assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); + if( NEVER(MEMDB && pPager->errCode) ){ return pPager->errCode; } + + /* If this database is in an error-state, now is a chance to clear + ** the error. Discard the contents of the pager-cache and rollback + ** any hot journal in the file-system. */ - if( !MEMDB && pPager->exclusiveMode - && sqlite3PcacheRefCount(pPager->pPCache)==0 && pPager->errCode - ){ - if( isOpen(pPager->jfd) ){ + if( pPager->errCode ){ + if( isOpen(pPager->jfd) || pPager->zJournal ){ isErrorReset = 1; } pPager->errCode = SQLITE_OK; pager_reset(pPager); } - /* If the pager is still in an error state, do not proceed. The error - ** state will be cleared at some point in the future when all page - ** references are dropped and the cache can be discarded. - */ - if( pPager->errCode && pPager->errCode!=SQLITE_FULL ){ - return pPager->errCode; - } - if( pPager->state==PAGER_UNLOCK || isErrorReset ){ sqlite3_vfs * const pVfs = pPager->pVfs; int isHotJournal = 0; assert( !MEMDB ); assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); - if( !pPager->noReadlock ){ + if( pPager->noReadlock ){ + assert( pPager->readOnly ); + pPager->state = PAGER_SHARED; + }else{ rc = pager_wait_on_lock(pPager, SHARED_LOCK); if( rc!=SQLITE_OK ){ assert( pPager->state==PAGER_UNLOCK ); return pager_error(pPager, rc); } - }else if( pPager->state==PAGER_UNLOCK ){ - pPager->state = PAGER_SHARED; } assert( pPager->state>=SHARED_LOCK ); @@ -34078,6 +34857,7 @@ static int pagerSharedLock(Pager *pPager){ ** database file, then it either needs to be played back or deleted. */ if( !isErrorReset ){ + assert( pPager->state <= PAGER_SHARED ); rc = hasHotJournal(pPager, &isHotJournal); if( rc!=SQLITE_OK ){ goto failed; @@ -34126,9 +34906,12 @@ static int pagerSharedLock(Pager *pPager){ sqlite3OsClose(pPager->jfd); } }else{ - /* If the journal does not exist, that means some other process - ** has already rolled it back */ - rc = SQLITE_BUSY; + /* If the journal does not exist, it usually means that some + ** other connection managed to get in and roll it back before + ** this connection obtained the exclusive lock above. Or, it + ** may mean that the pager was in the error-state when this + ** function was called and the journal file does not exist. */ + rc = pager_end_transaction(pPager, 0); } } } @@ -34147,10 +34930,12 @@ static int pagerSharedLock(Pager *pPager){ ** playing back the hot-journal so that we don't end up with ** an inconsistent cache. */ - rc = pager_playback(pPager, 1); - if( rc!=SQLITE_OK ){ - rc = pager_error(pPager, rc); - goto failed; + if( isOpen(pPager->jfd) ){ + rc = pager_playback(pPager, 1); + if( rc!=SQLITE_OK ){ + rc = pager_error(pPager, rc); + goto failed; + } } assert( (pPager->state==PAGER_SHARED) || (pPager->exclusiveMode && pPager->state>PAGER_SHARED) @@ -34224,28 +35009,11 @@ static void pagerUnlockIfUnused(Pager *pPager){ } } -/* -** Drop a page from the cache using sqlite3PcacheDrop(). -** -** If this means there are now no pages with references to them, a rollback -** occurs and the lock on the database is removed. -*/ -static void pagerDropPage(DbPage *pPg){ - Pager *pPager = pPg->pPager; - sqlite3PcacheDrop(pPg); - pagerUnlockIfUnused(pPager); -} - /* ** Acquire a reference to page number pgno in pager pPager (a page ** reference has type DbPage*). If the requested reference is ** successfully obtained, it is copied to *ppPage and SQLITE_OK returned. ** -** This function calls pagerSharedLock() to obtain a SHARED lock on -** the database file if such a lock or greater is not already held. -** This may cause hot-journal rollback or a cache purge. See comments -** above function pagerSharedLock() for details. -** ** If the requested page is already in the cache, it is returned. ** Otherwise, a new page object is allocated and populated with data ** read from the database file. In some cases, the pcache module may @@ -34297,61 +35065,66 @@ SQLITE_PRIVATE int sqlite3PagerAcquire( DbPage **ppPage, /* Write a pointer to the page here */ int noContent /* Do not bother reading content from disk if true */ ){ - PgHdr *pPg = 0; int rc; + PgHdr *pPg; assert( assert_pager_state(pPager) ); - assert( pPager->state==PAGER_UNLOCK - || sqlite3PcacheRefCount(pPager->pPCache)>0 - || pgno==1 - ); + assert( pPager->state>PAGER_UNLOCK ); - /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page - ** number greater than this, or zero, is requested. - */ - if( pgno>PAGER_MAX_PGNO || pgno==0 || pgno==PAGER_MJ_PGNO(pPager) ){ + if( pgno==0 ){ return SQLITE_CORRUPT_BKPT; } - /* Make sure we have not hit any critical errors. - */ - assert( pPager!=0 ); - *ppPage = 0; - - /* If this is the first page accessed, then get a SHARED lock - ** on the database file. pagerSharedLock() is a no-op if - ** a database lock is already held. - */ - rc = pagerSharedLock(pPager); - if( rc!=SQLITE_OK ){ - return rc; + /* If the pager is in the error state, return an error immediately. + ** Otherwise, request the page from the PCache layer. */ + if( pPager->errCode!=SQLITE_OK && pPager->errCode!=SQLITE_FULL ){ + rc = pPager->errCode; + }else{ + rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, ppPage); } - assert( pPager->state!=PAGER_UNLOCK ); - rc = sqlite3PcacheFetch(pPager->pPCache, pgno, 1, &pPg); if( rc!=SQLITE_OK ){ - return rc; - } - assert( pPg->pgno==pgno ); - assert( pPg->pPager==pPager || pPg->pPager==0 ); - if( pPg->pPager==0 ){ + /* Either the call to sqlite3PcacheFetch() returned an error or the + ** pager was already in the error-state when this function was called. + ** Set pPg to 0 and jump to the exception handler. */ + pPg = 0; + goto pager_acquire_err; + } + assert( (*ppPage)->pgno==pgno ); + assert( (*ppPage)->pPager==pPager || (*ppPage)->pPager==0 ); + + if( (*ppPage)->pPager ){ + /* In this case the pcache already contains an initialized copy of + ** the page. Return without further ado. */ + assert( pgno<=PAGER_MAX_PGNO && pgno!=PAGER_MJ_PGNO(pPager) ); + PAGER_INCR(pPager->nHit); + return SQLITE_OK; + + }else{ /* The pager cache has created a new page. Its content needs to - ** be initialized. - */ + ** be initialized. */ int nMax; + PAGER_INCR(pPager->nMiss); + pPg = *ppPage; pPg->pPager = pPager; + /* The maximum page number is 2^31. Return SQLITE_CORRUPT if a page + ** number greater than this, or the unused locking-page, is requested. */ + if( pgno>PAGER_MAX_PGNO || pgno==PAGER_MJ_PGNO(pPager) ){ + rc = SQLITE_CORRUPT_BKPT; + goto pager_acquire_err; + } + rc = sqlite3PagerPagecount(pPager, &nMax); if( rc!=SQLITE_OK ){ - sqlite3PagerUnref(pPg); - return rc; + goto pager_acquire_err; } if( nMax<(int)pgno || MEMDB || noContent ){ if( pgno>pPager->mxPgno ){ - sqlite3PagerUnref(pPg); - return SQLITE_FULL; + rc = SQLITE_FULL; + goto pager_acquire_err; } if( noContent ){ /* Failure to set the bits in the InJournal bit-vectors is benign. @@ -34376,20 +35149,25 @@ SQLITE_PRIVATE int sqlite3PagerAcquire( assert( pPg->pPager==pPager ); rc = readDbPage(pPg); if( rc!=SQLITE_OK ){ - pagerDropPage(pPg); - return rc; + goto pager_acquire_err; } } #ifdef SQLITE_CHECK_PAGES pPg->pageHash = pager_pagehash(pPg); #endif - }else{ - /* The requested page is in the page cache. */ - PAGER_INCR(pPager->nHit); } - *ppPage = pPg; return SQLITE_OK; + +pager_acquire_err: + assert( rc!=SQLITE_OK ); + if( pPg ){ + sqlite3PcacheDrop(pPg); + } + pagerUnlockIfUnused(pPager); + + *ppPage = 0; + return rc; } /* @@ -34409,13 +35187,9 @@ SQLITE_PRIVATE DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ PgHdr *pPg = 0; assert( pPager!=0 ); assert( pgno!=0 ); - - if( (pPager->state!=PAGER_UNLOCK) - && (pPager->errCode==SQLITE_OK || pPager->errCode==SQLITE_FULL) - ){ - sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg); - } - + assert( pPager->pPCache!=0 ); + assert( pPager->state > PAGER_UNLOCK ); + sqlite3PcacheFetch(pPager->pPCache, pgno, 0, &pPg); return pPg; } @@ -34484,12 +35258,13 @@ static int pager_open_journal(Pager *pPager){ assert( pPager->state>=PAGER_RESERVED ); assert( pPager->useJournal ); + assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF ); assert( pPager->pInJournal==0 ); - /* If already in the error state, this function is a no-op. */ - if( pPager->errCode ){ - return pPager->errCode; - } + /* If already in the error state, this function is a no-op. But on + ** the other hand, this routine is never called if we are already in + ** an error state. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; /* TODO: Is it really possible to get here with dbSizeValid==0? If not, ** the call to PagerPagecount() can be removed. @@ -34599,9 +35374,7 @@ SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory /* If the required locks were successfully obtained, open the journal ** file and write the first journal-header to it. */ - if( rc==SQLITE_OK && pPager->useJournal - && pPager->journalMode!=PAGER_JOURNALMODE_OFF - ){ + if( rc==SQLITE_OK && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ rc = pager_open_journal(pPager); } }else if( isOpen(pPager->jfd) && pPager->journalOff==0 ){ @@ -34619,6 +35392,15 @@ SQLITE_PRIVATE int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory PAGERTRACE(("TRANSACTION %d\n", PAGERID(pPager))); assert( !isOpen(pPager->jfd) || pPager->journalOff>0 || rc!=SQLITE_OK ); + if( rc!=SQLITE_OK ){ + assert( !pPager->dbModified ); + /* Ignore any IO error that occurs within pager_end_transaction(). The + ** purpose of this call is to reset the internal state of the pager + ** sub-system. It doesn't matter if the journal-file is not properly + ** finalized at this point (since it is not a valid journal file anyway). + */ + pager_end_transaction(pPager, 0); + } return rc; } @@ -34634,14 +35416,19 @@ static int pager_write(PgHdr *pPg){ Pager *pPager = pPg->pPager; int rc = SQLITE_OK; - /* Check for errors + /* This routine is not called unless a transaction has already been + ** started. */ - if( pPager->errCode ){ - return pPager->errCode; - } - if( pPager->readOnly ){ - return SQLITE_PERM; - } + assert( pPager->state>=PAGER_RESERVED ); + + /* If an error has been previously detected, we should not be + ** calling this routine. Repeat the error for robustness. + */ + if( NEVER(pPager->errCode) ) return pPager->errCode; + + /* Higher-level routines never call this function if database is not + ** writable. But check anyway, just for robustness. */ + if( NEVER(pPager->readOnly) ) return SQLITE_PERM; assert( !pPager->setMaster ); @@ -34659,17 +35446,16 @@ static int pager_write(PgHdr *pPg){ ** written to the transaction journal or the ckeckpoint journal ** or both. ** - ** First check to see that the transaction journal exists and - ** create it if it does not. + ** Higher level routines should have already started a transaction, + ** which means they have acquired the necessary locks and opened + ** a rollback journal. Double-check to makes sure this is the case. */ - assert( pPager->state!=PAGER_UNLOCK ); rc = sqlite3PagerBegin(pPager, 0, pPager->subjInMemory); - if( rc!=SQLITE_OK ){ + if( NEVER(rc!=SQLITE_OK) ){ return rc; } - assert( pPager->state>=PAGER_RESERVED ); - if( !isOpen(pPager->jfd) && pPager->useJournal - && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + if( !isOpen(pPager->jfd) && pPager->journalMode!=PAGER_JOURNALMODE_OFF ){ + assert( pPager->useJournal ); rc = pager_open_journal(pPager); if( rc!=SQLITE_OK ) return rc; } @@ -34848,9 +35634,9 @@ SQLITE_PRIVATE int sqlite3PagerWrite(DbPage *pDbPage){ ** journal file must contain sync()ed copies of all of them ** before any of them can be written out to the database file. */ - if( needSync ){ + if( rc==SQLITE_OK && needSync ){ assert( !MEMDB && pPager->noSync==0 ); - for(ii=0; iiflags |= PGHDR_NEED_SYNC; @@ -34910,12 +35696,12 @@ SQLITE_PRIVATE void sqlite3PagerDontWrite(PgHdr *pPg){ ** change-counter, stored as a 4-byte big-endian integer starting at ** byte offset 24 of the pager file. ** -** If the isDirect flag is zero, then this is done by calling +** If the isDirectMode flag is zero, then this is done by calling ** sqlite3PagerWrite() on page 1, then modifying the contents of the ** page data. In this case the file will be updated when the current ** transaction is committed. ** -** The isDirect flag may only be non-zero if the library was compiled +** The isDirectMode flag may only be non-zero if the library was compiled ** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case, ** if isDirect is non-zero, then the database file is updated directly ** by writing an updated version of page 1 using a call to the @@ -34935,15 +35721,15 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ ** "if( isDirect )" condition. */ #ifndef SQLITE_ENABLE_ATOMIC_WRITE - const int isDirect = 0; +# define DIRECT_MODE 0 assert( isDirectMode==0 ); UNUSED_PARAMETER(isDirectMode); #else - const int isDirect = isDirectMode; +# define DIRECT_MODE isDirectMode #endif assert( pPager->state>=PAGER_RESERVED ); - if( !pPager->changeCountDone && pPager->dbSize>0 ){ + if( !pPager->changeCountDone && ALWAYS(pPager->dbSize>0) ){ PgHdr *pPgHdr; /* Reference to page 1 */ u32 change_counter; /* Initial value of change-counter field */ @@ -34954,9 +35740,11 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ assert( pPgHdr==0 || rc==SQLITE_OK ); /* If page one was fetched successfully, and this function is not - ** operating in direct-mode, make page 1 writable. + ** operating in direct-mode, make page 1 writable. When not in + ** direct mode, page 1 is always held in cache and hence the PagerGet() + ** above is always successful - hence the ALWAYS on rc==SQLITE_OK. */ - if( rc==SQLITE_OK && !isDirect ){ + if( !DIRECT_MODE && ALWAYS(rc==SQLITE_OK) ){ rc = sqlite3PagerWrite(pPgHdr); } @@ -34967,14 +35755,14 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ put32bits(((char*)pPgHdr->pData)+24, change_counter); /* If running in direct mode, write the contents of page 1 to the file. */ - if( isDirect ){ + if( DIRECT_MODE ){ const void *zBuf = pPgHdr->pData; assert( pPager->dbFileSize>0 ); rc = sqlite3OsWrite(pPager->fd, zBuf, pPager->pageSize, 0); - } - - /* If everything worked, set the changeCountDone flag. */ - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK ){ + pPager->changeCountDone = 1; + } + }else{ pPager->changeCountDone = 1; } } @@ -34994,7 +35782,8 @@ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ */ SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager){ int rc; /* Return code */ - if( MEMDB || pPager->noSync ){ + assert( !MEMDB ); + if( pPager->noSync ){ rc = SQLITE_OK; }else{ rc = sqlite3OsSync(pPager->fd, pPager->sync_flags); @@ -35035,17 +35824,22 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( ){ int rc = SQLITE_OK; /* Return code */ - if( pPager->errCode ){ - return pPager->errCode; - } + /* The dbOrigSize is never set if journal_mode=OFF */ + assert( pPager->journalMode!=PAGER_JOURNALMODE_OFF || pPager->dbOrigSize==0 ); + + /* If a prior error occurred, this routine should not be called. ROLLBACK + ** is the appropriate response to an error, not COMMIT. Guard against + ** coding errors by repeating the prior error. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; PAGERTRACE(("DATABASE SYNC: File=%s zMaster=%s nSize=%d\n", pPager->zFilename, zMaster, pPager->dbSize)); - /* If this is an in-memory db, or no pages have been written to, or this - ** function has already been called, it is a no-op. - */ if( MEMDB && pPager->dbModified ){ + /* If this is an in-memory db, or no pages have been written to, or this + ** function has already been called, it is mostly a no-op. However, any + ** backup in progress needs to be restarted. + */ sqlite3BackupRestart(pPager->pBackup); }else if( pPager->state!=PAGER_SYNCED && pPager->dbModified ){ @@ -35107,10 +35901,13 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( ** that it took at the start of the transaction. Otherwise, the ** calls to sqlite3PagerGet() return zeroed pages instead of ** reading data from the database file. + ** + ** When journal_mode==OFF the dbOrigSize is always zero, so this + ** block never runs if journal_mode=OFF. */ #ifndef SQLITE_OMIT_AUTOVACUUM - if( pPager->dbSizedbOrigSize - && pPager->journalMode!=PAGER_JOURNALMODE_OFF + if( pPager->dbSizedbOrigSize + && ALWAYS(pPager->journalMode!=PAGER_JOURNALMODE_OFF) ){ Pgno i; /* Iterator variable */ const Pgno iSkip = PAGER_MJ_PGNO(pPager); /* Pending lock page */ @@ -35172,14 +35969,6 @@ SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne( } commit_phase_one_exit: - if( rc==SQLITE_IOERR_BLOCKED ){ - /* pager_incr_changecounter() may attempt to obtain an exclusive - ** lock to spill the cache and return IOERR_BLOCKED. But since - ** there is no chance the cache is inconsistent, it is - ** better to return SQLITE_BUSY. - **/ - rc = SQLITE_BUSY; - } return rc; } @@ -35202,18 +35991,16 @@ commit_phase_one_exit: SQLITE_PRIVATE int sqlite3PagerCommitPhaseTwo(Pager *pPager){ int rc = SQLITE_OK; /* Return code */ - /* Do not proceed if the pager is already in the error state. */ - if( pPager->errCode ){ - return pPager->errCode; - } + /* This routine should not be called if a prior error has occurred. + ** But if (due to a coding error elsewhere in the system) it does get + ** called, just return the same error code without doing anything. */ + if( NEVER(pPager->errCode) ) return pPager->errCode; /* This function should not be called if the pager is not in at least ** PAGER_RESERVED state. And indeed SQLite never does this. But it is - ** nice to have this defensive block here anyway. + ** nice to have this defensive test here anyway. */ - if( NEVER(pPager->statestatedbSizeValid ); aNew[ii].nOrig = pPager->dbSize; - if( isOpen(pPager->jfd) && pPager->journalOff>0 ){ + if( isOpen(pPager->jfd) && ALWAYS(pPager->journalOff>0) ){ aNew[ii].iOffset = pPager->journalOff; }else{ aNew[ii].iOffset = JOURNAL_HDR_SZ(pPager); @@ -35422,6 +36209,7 @@ SQLITE_PRIVATE int sqlite3PagerOpenSavepoint(Pager *pPager, int nSavepoint){ /* Open the sub-journal, if it is not already opened. */ rc = openSubJournal(pPager); + assertTruncateConstraint(pPager); } return rc; @@ -35539,15 +36327,24 @@ SQLITE_PRIVATE int sqlite3PagerNosync(Pager *pPager){ #ifdef SQLITE_HAS_CODEC /* -** Set the codec for this pager +** Set or retrieve the codec for this pager */ -SQLITE_PRIVATE void sqlite3PagerSetCodec( +static void sqlite3PagerSetCodec( Pager *pPager, void *(*xCodec)(void*,void*,Pgno,int), - void *pCodecArg + void (*xCodecSizeChng)(void*,int,int), + void (*xCodecFree)(void*), + void *pCodec ){ + if( pPager->xCodecFree ) pPager->xCodecFree(pPager->pCodec); pPager->xCodec = xCodec; - pPager->pCodecArg = pCodecArg; + pPager->xCodecSizeChng = xCodecSizeChng; + pPager->xCodecFree = xCodecFree; + pPager->pCodec = pCodec; + pagerReportSize(pPager); +} +static void *sqlite3PagerGetCodec(Pager *pPager){ + return pPager->pCodec; } #endif @@ -35668,7 +36465,7 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i assert( pPager->needSync ); rc = sqlite3PagerGet(pPager, needSyncPgno, &pPgHdr); if( rc!=SQLITE_OK ){ - if( pPager->pInJournal && needSyncPgno<=pPager->dbOrigSize ){ + if( needSyncPgno<=pPager->dbOrigSize ){ assert( pPager->pTmpSpace!=0 ); sqlite3BitvecClear(pPager->pInJournal, needSyncPgno, pPager->pTmpSpace); } @@ -35690,7 +36487,10 @@ SQLITE_PRIVATE int sqlite3PagerMovepage(Pager *pPager, DbPage *pPg, Pgno pgno, i if( MEMDB ){ DbPage *pNew; rc = sqlite3PagerAcquire(pPager, origPgno, &pNew, 1); - if( rc!=SQLITE_OK ) return rc; + if( rc!=SQLITE_OK ){ + sqlite3PcacheMove(pPg, origPgno); + return rc; + } sqlite3PagerUnref(pNew); } @@ -35711,8 +36511,7 @@ SQLITE_PRIVATE void *sqlite3PagerGetData(DbPage *pPg){ ** allocated along with the specified page. */ SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *pPg){ - Pager *pPager = pPg->pPager; - return (pPager?pPg->pExtra:0); + return pPg->pExtra; } /* @@ -35819,7 +36618,7 @@ SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ ** ************************************************************************* ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ ** ** This file contains code used to implement mutexes on Btree objects. ** This code really belongs in btree.c. But btree.c is getting too @@ -35839,7 +36638,7 @@ SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ ** ** This file implements a external (disk-based) database using BTrees. ** For a detailed discussion of BTrees, refer to @@ -35901,6 +36700,17 @@ SQLITE_PRIVATE sqlite3_backup **sqlite3PagerBackupPtr(Pager *pPager){ ** 36 4 Number of freelist pages in the file ** 40 60 15 4-byte meta values passed to higher layers ** +** 40 4 Schema cookie +** 44 4 File format of schema layer +** 48 4 Size of page cache +** 52 4 Largest root-page (auto/incr_vacuum) +** 56 4 1=UTF-8 2=UTF16le 3=UTF16be +** 60 4 User version +** 64 4 Incremental vacuum mode +** 68 4 unused +** 72 4 unused +** 76 4 unused +** ** All of the integer values are big-endian (most significant byte first). ** ** The file change counter is incremented when the database is changed @@ -36120,6 +36930,24 @@ struct MemPage { */ #define EXTRA_SIZE sizeof(MemPage) +/* +** A linked list of the following structures is stored at BtShared.pLock. +** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor +** is opened on the table with root page BtShared.iTable. Locks are removed +** from this list when a transaction is committed or rolled back, or when +** a btree handle is closed. +*/ +struct BtLock { + Btree *pBtree; /* Btree handle holding this lock */ + Pgno iTable; /* Root page of table */ + u8 eLock; /* READ_LOCK or WRITE_LOCK */ + BtLock *pNext; /* Next in BtShared.pLock list */ +}; + +/* Candidate values for BtLock.eLock */ +#define READ_LOCK 1 +#define WRITE_LOCK 2 + /* A Btree handle ** ** A database connection contains a pointer to an instance of @@ -36151,6 +36979,9 @@ struct Btree { int nBackup; /* Number of backup operations reading this btree */ Btree *pNext; /* List of other sharable Btrees from the same db */ Btree *pPrev; /* Back pointer of the same list */ +#ifndef SQLITE_OMIT_SHARED_CACHE + BtLock lock; /* Object used to lock page 1 */ +#endif }; /* @@ -36289,13 +37120,10 @@ struct BtCursor { u8 eState; /* One of the CURSOR_XXX constants (see below) */ void *pKey; /* Saved key that was cursor's last known position */ i64 nKey; /* Size of pKey, or last integer key */ - int skip; /* (skip<0) -> Prev() is a no-op. (skip>0) -> Next() is */ + int skipNext; /* Prev() is noop if negative. Next() is noop if positive */ #ifndef SQLITE_OMIT_INCRBLOB u8 isIncrblobHandle; /* True if this cursor is an incr. io handle */ Pgno *aOverflow; /* Cache of overflow page locations */ -#endif -#ifndef NDEBUG - u8 pagesShuffled; /* True if Btree pages are rearranged by balance()*/ #endif i16 iPage; /* Index of current page in apPage */ MemPage *apPage[BTCURSOR_MAX_DEPTH]; /* Pages from root to current page */ @@ -36337,24 +37165,6 @@ struct BtCursor { */ # define PENDING_BYTE_PAGE(pBt) PAGER_MJ_PGNO(pBt) -/* -** A linked list of the following structures is stored at BtShared.pLock. -** Locks are added (or upgraded from READ_LOCK to WRITE_LOCK) when a cursor -** is opened on the table with root page BtShared.iTable. Locks are removed -** from this list when a transaction is committed or rolled back, or when -** a btree handle is closed. -*/ -struct BtLock { - Btree *pBtree; /* Btree handle holding this lock */ - Pgno iTable; /* Root page of table */ - u8 eLock; /* READ_LOCK or WRITE_LOCK */ - BtLock *pNext; /* Next in BtShared.pLock list */ -}; - -/* Candidate values for BtLock.eLock */ -#define READ_LOCK 1 -#define WRITE_LOCK 2 - /* ** These macros define the location of the pointer-map entry for a ** database page. The first argument to each is the number of usable @@ -36457,18 +37267,6 @@ struct IntegrityCk { #define get4byte sqlite3Get4byte #define put4byte sqlite3Put4byte -/* -** Internal routines that should be accessed by the btree layer only. -*/ -SQLITE_PRIVATE int sqlite3BtreeGetPage(BtShared*, Pgno, MemPage**, int); -SQLITE_PRIVATE int sqlite3BtreeInitPage(MemPage *pPage); -SQLITE_PRIVATE void sqlite3BtreeParseCellPtr(MemPage*, u8*, CellInfo*); -SQLITE_PRIVATE void sqlite3BtreeParseCell(MemPage*, int, CellInfo*); -SQLITE_PRIVATE int sqlite3BtreeRestoreCursorPosition(BtCursor *pCur); -SQLITE_PRIVATE void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur); -SQLITE_PRIVATE void sqlite3BtreeReleaseTempCursor(BtCursor *pCur); -SQLITE_PRIVATE void sqlite3BtreeMoveToParent(BtCursor *pCur); - /************** End of btreeInt.h ********************************************/ /************** Continuing where we left off in btmutex.c ********************/ #ifndef SQLITE_OMIT_SHARED_CACHE @@ -36650,7 +37448,9 @@ SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ if( !p->locked ){ assert( p->wantToLock==1 ); while( p->pPrev ) p = p->pPrev; - while( p->locked && p->pNext ) p = p->pNext; + /* Reason for ALWAYS: There must be at least on unlocked Btree in + ** the chain. Otherwise the !p->locked test above would have failed */ + while( p->locked && ALWAYS(p->pNext) ) p = p->pNext; for(pLater = p->pNext; pLater; pLater=pLater->pNext){ if( pLater->locked ){ unlockBtreeMutex(pLater); @@ -36761,8 +37561,12 @@ SQLITE_PRIVATE void sqlite3BtreeMutexArrayEnter(BtreeMutexArray *pArray){ /* We should already hold a lock on the database connection */ assert( sqlite3_mutex_held(p->db->mutex) ); + /* The Btree is sharable because only sharable Btrees are entered + ** into the array in the first place. */ + assert( p->sharable ); + p->wantToLock++; - if( !p->locked && p->sharable ){ + if( !p->locked ){ lockBtreeMutex(p); } } @@ -36777,14 +37581,14 @@ SQLITE_PRIVATE void sqlite3BtreeMutexArrayLeave(BtreeMutexArray *pArray){ Btree *p = pArray->aBtree[i]; /* Some basic sanity checking */ assert( i==0 || pArray->aBtree[i-1]->pBtpBt ); - assert( p->locked || !p->sharable ); + assert( p->locked ); assert( p->wantToLock>0 ); /* We should already hold a lock on the database connection */ assert( sqlite3_mutex_held(p->db->mutex) ); p->wantToLock--; - if( p->wantToLock==0 && p->locked ){ + if( p->wantToLock==0 ){ unlockBtreeMutex(p); } } @@ -36819,7 +37623,7 @@ SQLITE_PRIVATE void sqlite3BtreeEnterAll(sqlite3 *db){ ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ ** ** This file implements a external (disk-based) database using BTrees. ** See the header comment on "btreeInt.h" for additional information. @@ -36876,11 +37680,6 @@ SQLITE_API int sqlite3_enable_shared_cache(int enable){ #endif -/* -** Forward declaration -*/ -static int checkForReadConflicts(Btree*, Pgno, BtCursor*, i64); - #ifdef SQLITE_OMIT_SHARED_CACHE /* @@ -36895,9 +37694,114 @@ static int checkForReadConflicts(Btree*, Pgno, BtCursor*, i64); #define querySharedCacheTableLock(a,b,c) SQLITE_OK #define setSharedCacheTableLock(a,b,c) SQLITE_OK #define clearAllSharedCacheTableLocks(a) + #define downgradeAllSharedCacheTableLocks(a) + #define hasSharedCacheTableLock(a,b,c,d) 1 + #define hasReadConflicts(a, b) 0 #endif #ifndef SQLITE_OMIT_SHARED_CACHE + +#ifdef SQLITE_DEBUG +/* +** This function is only used as part of an assert() statement. It checks +** that connection p holds the required locks to read or write to the +** b-tree with root page iRoot. If so, true is returned. Otherwise, false. +** For example, when writing to a table b-tree with root-page iRoot via +** Btree connection pBtree: +** +** assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) ); +** +** When writing to an index b-tree that resides in a sharable database, the +** caller should have first obtained a lock specifying the root page of +** the corresponding table b-tree. This makes things a bit more complicated, +** as this module treats each b-tree as a separate structure. To determine +** the table b-tree corresponding to the index b-tree being written, this +** function has to search through the database schema. +** +** Instead of a lock on the b-tree rooted at page iRoot, the caller may +** hold a write-lock on the schema table (root page 1). This is also +** acceptable. +*/ +static int hasSharedCacheTableLock( + Btree *pBtree, /* Handle that must hold lock */ + Pgno iRoot, /* Root page of b-tree */ + int isIndex, /* True if iRoot is the root of an index b-tree */ + int eLockType /* Required lock type (READ_LOCK or WRITE_LOCK) */ +){ + Schema *pSchema = (Schema *)pBtree->pBt->pSchema; + Pgno iTab = 0; + BtLock *pLock; + + /* If this b-tree database is not shareable, or if the client is reading + ** and has the read-uncommitted flag set, then no lock is required. + ** In these cases return true immediately. If the client is reading + ** or writing an index b-tree, but the schema is not loaded, then return + ** true also. In this case the lock is required, but it is too difficult + ** to check if the client actually holds it. This doesn't happen very + ** often. */ + if( (pBtree->sharable==0) + || (eLockType==READ_LOCK && (pBtree->db->flags & SQLITE_ReadUncommitted)) + || (isIndex && (!pSchema || (pSchema->flags&DB_SchemaLoaded)==0 )) + ){ + return 1; + } + + /* Figure out the root-page that the lock should be held on. For table + ** b-trees, this is just the root page of the b-tree being read or + ** written. For index b-trees, it is the root page of the associated + ** table. */ + if( isIndex ){ + HashElem *p; + for(p=sqliteHashFirst(&pSchema->idxHash); p; p=sqliteHashNext(p)){ + Index *pIdx = (Index *)sqliteHashData(p); + if( pIdx->tnum==(int)iRoot ){ + iTab = pIdx->pTable->tnum; + } + } + }else{ + iTab = iRoot; + } + + /* Search for the required lock. Either a write-lock on root-page iTab, a + ** write-lock on the schema table, or (if the client is reading) a + ** read-lock on iTab will suffice. Return 1 if any of these are found. */ + for(pLock=pBtree->pBt->pLock; pLock; pLock=pLock->pNext){ + if( pLock->pBtree==pBtree + && (pLock->iTable==iTab || (pLock->eLock==WRITE_LOCK && pLock->iTable==1)) + && pLock->eLock>=eLockType + ){ + return 1; + } + } + + /* Failed to find the required lock. */ + return 0; +} + +/* +** This function is also used as part of assert() statements only. It +** returns true if there exist one or more cursors open on the table +** with root page iRoot that do not belong to either connection pBtree +** or some other connection that has the read-uncommitted flag set. +** +** For example, before writing to page iRoot: +** +** assert( !hasReadConflicts(pBtree, iRoot) ); +*/ +static int hasReadConflicts(Btree *pBtree, Pgno iRoot){ + BtCursor *p; + for(p=pBtree->pBt->pCursor; p; p=p->pNext){ + if( p->pgnoRoot==iRoot + && p->pBtree!=pBtree + && 0==(p->pBtree->db->flags & SQLITE_ReadUncommitted) + ){ + return 1; + } + } + return 0; +} +#endif /* #ifdef SQLITE_DEBUG */ + /* ** Query to see if btree handle p may obtain a lock of type eLock ** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return @@ -36911,6 +37815,7 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ assert( sqlite3BtreeHoldsMutex(p) ); assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); assert( p->db!=0 ); + assert( !(p->db->flags&SQLITE_ReadUncommitted)||eLock==WRITE_LOCK||iTab==1 ); /* If requesting a write-lock, then the Btree must have an open write ** transaction on this file. And, obviously, for this to be so there @@ -36932,47 +37837,25 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ return SQLITE_LOCKED_SHAREDCACHE; } - /* This (along with setSharedCacheTableLock()) is where - ** the ReadUncommitted flag is dealt with. - ** If the caller is querying for a read-lock on any table - ** other than the sqlite_master table (table 1) and if the ReadUncommitted - ** flag is set, then the lock granted even if there are write-locks - ** on the table. If a write-lock is requested, the ReadUncommitted flag - ** is not considered. - ** - ** In function setSharedCacheTableLock(), if a read-lock is demanded and the - ** ReadUncommitted flag is set, no entry is added to the locks list - ** (BtShared.pLock). - ** - ** To summarize: If the ReadUncommitted flag is set, then read cursors - ** on non-schema tables do not create or respect table locks. The locking - ** procedure for a write-cursor does not change. - */ - if( - 0==(p->db->flags&SQLITE_ReadUncommitted) || - eLock==WRITE_LOCK || - iTab==MASTER_ROOT - ){ - for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ - /* The condition (pIter->eLock!=eLock) in the following if(...) - ** statement is a simplification of: - ** - ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK) - ** - ** since we know that if eLock==WRITE_LOCK, then no other connection - ** may hold a WRITE_LOCK on any table in this file (since there can - ** only be a single writer). - */ - assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK ); - assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK); - if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){ - sqlite3ConnectionBlocked(p->db, pIter->pBtree->db); - if( eLock==WRITE_LOCK ){ - assert( p==pBt->pWriter ); - pBt->isPending = 1; - } - return SQLITE_LOCKED_SHAREDCACHE; + for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ + /* The condition (pIter->eLock!=eLock) in the following if(...) + ** statement is a simplification of: + ** + ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK) + ** + ** since we know that if eLock==WRITE_LOCK, then no other connection + ** may hold a WRITE_LOCK on any table in this file (since there can + ** only be a single writer). + */ + assert( pIter->eLock==READ_LOCK || pIter->eLock==WRITE_LOCK ); + assert( eLock==READ_LOCK || pIter->pBtree==p || pIter->eLock==READ_LOCK); + if( pIter->pBtree!=p && pIter->iTable==iTab && pIter->eLock!=eLock ){ + sqlite3ConnectionBlocked(p->db, pIter->pBtree->db); + if( eLock==WRITE_LOCK ){ + assert( p==pBt->pWriter ); + pBt->isPending = 1; } + return SQLITE_LOCKED_SHAREDCACHE; } } return SQLITE_OK; @@ -36985,8 +37868,17 @@ static int querySharedCacheTableLock(Btree *p, Pgno iTab, u8 eLock){ ** by Btree handle p. Parameter eLock must be either READ_LOCK or ** WRITE_LOCK. ** -** SQLITE_OK is returned if the lock is added successfully. SQLITE_BUSY and -** SQLITE_NOMEM may also be returned. +** This function assumes the following: +** +** (a) The specified b-tree connection handle is connected to a sharable +** b-tree database (one with the BtShared.sharable) flag set, and +** +** (b) No other b-tree connection handle holds a lock that conflicts +** with the requested lock (i.e. querySharedCacheTableLock() has +** already been called and returned SQLITE_OK). +** +** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM +** is returned if a malloc attempt fails. */ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ BtShared *pBt = p->pBt; @@ -36997,27 +37889,17 @@ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); assert( p->db!=0 ); - /* This is a no-op if the shared-cache is not enabled */ - if( !p->sharable ){ - return SQLITE_OK; - } + /* A connection with the read-uncommitted flag set will never try to + ** obtain a read-lock using this function. The only read-lock obtained + ** by a connection in read-uncommitted mode is on the sqlite_master + ** table, and that lock is obtained in BtreeBeginTrans(). */ + assert( 0==(p->db->flags&SQLITE_ReadUncommitted) || eLock==WRITE_LOCK ); + /* This function should only be called on a sharable b-tree after it + ** has been determined that no other b-tree holds a conflicting lock. */ + assert( p->sharable ); assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) ); - /* If the read-uncommitted flag is set and a read-lock is requested on - ** a non-schema table, then the lock is always granted. Return early - ** without adding an entry to the BtShared.pLock list. See - ** comment in function querySharedCacheTableLock() for more info - ** on handling the ReadUncommitted flag. - */ - if( - (p->db->flags&SQLITE_ReadUncommitted) && - (eLock==READ_LOCK) && - iTable!=MASTER_ROOT - ){ - return SQLITE_OK; - } - /* First search the list for an existing lock on this table. */ for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ if( pIter->iTable==iTable && pIter->pBtree==p ){ @@ -37076,7 +37958,10 @@ static void clearAllSharedCacheTableLocks(Btree *p){ assert( pLock->pBtree->inTrans>=pLock->eLock ); if( pLock->pBtree==p ){ *ppIter = pLock->pNext; - sqlite3_free(pLock); + assert( pLock->iTable!=1 || pLock==&p->lock ); + if( pLock->iTable!=1 ){ + sqlite3_free(pLock); + } }else{ ppIter = &pLock->pNext; } @@ -37100,6 +37985,24 @@ static void clearAllSharedCacheTableLocks(Btree *p){ pBt->isPending = 0; } } + +/* +** This function changes all write-locks held by connection p to read-locks. +*/ +static void downgradeAllSharedCacheTableLocks(Btree *p){ + BtShared *pBt = p->pBt; + if( pBt->pWriter==p ){ + BtLock *pLock; + pBt->pWriter = 0; + pBt->isExclusive = 0; + pBt->isPending = 0; + for(pLock=pBt->pLock; pLock; pLock=pLock->pNext){ + assert( pLock->eLock==READ_LOCK || pLock->pBtree==p ); + pLock->eLock = READ_LOCK; + } + } +} + #endif /* SQLITE_OMIT_SHARED_CACHE */ static void releasePage(MemPage *pPage); /* Forward reference */ @@ -37135,9 +38038,39 @@ static void invalidateAllOverflowCache(BtShared *pBt){ invalidateOverflowCache(p); } } + +/* +** This function is called before modifying the contents of a table +** b-tree to invalidate any incrblob cursors that are open on the +** row or one of the rows being modified. +** +** If argument isClearTable is true, then the entire contents of the +** table is about to be deleted. In this case invalidate all incrblob +** cursors open on any row within the table with root-page pgnoRoot. +** +** Otherwise, if argument isClearTable is false, then the row with +** rowid iRow is being replaced or deleted. In this case invalidate +** only those incrblob cursors open on this specific row. +*/ +static void invalidateIncrblobCursors( + Btree *pBtree, /* The database file to check */ + i64 iRow, /* The rowid that might be changing */ + int isClearTable /* True if all rows are being deleted */ +){ + BtCursor *p; + BtShared *pBt = pBtree->pBt; + assert( sqlite3BtreeHoldsMutex(pBtree) ); + for(p=pBt->pCursor; p; p=p->pNext){ + if( p->isIncrblobHandle && (isClearTable || p->info.nKey==iRow) ){ + p->eState = CURSOR_INVALID; + } + } +} + #else #define invalidateOverflowCache(x) #define invalidateAllOverflowCache(x) + #define invalidateIncrblobCursors(x,y,z) #endif /* @@ -37178,13 +38111,13 @@ static void invalidateAllOverflowCache(BtShared *pBt){ static int btreeSetHasContent(BtShared *pBt, Pgno pgno){ int rc = SQLITE_OK; if( !pBt->pHasContent ){ - int nPage; - rc = sqlite3PagerPagecount(pBt->pPager, &nPage); - if( rc==SQLITE_OK ){ - pBt->pHasContent = sqlite3BitvecCreate((u32)nPage); - if( !pBt->pHasContent ){ - rc = SQLITE_NOMEM; - } + int nPage = 100; + sqlite3PagerPagecount(pBt->pPager, &nPage); + /* If sqlite3PagerPagecount() fails there is no harm because the + ** nPage variable is unchanged from its default value of 100 */ + pBt->pHasContent = sqlite3BitvecCreate((u32)nPage); + if( !pBt->pHasContent ){ + rc = SQLITE_NOMEM; } } if( rc==SQLITE_OK && pgno<=sqlite3BitvecSize(pBt->pHasContent) ){ @@ -37217,6 +38150,9 @@ static void btreeClearHasContent(BtShared *pBt){ /* ** Save the current cursor position in the variables BtCursor.nKey ** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. +** +** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID) +** prior to calling this routine. */ static int saveCursorPosition(BtCursor *pCur){ int rc; @@ -37226,6 +38162,7 @@ static int saveCursorPosition(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); rc = sqlite3BtreeKeySize(pCur, &pCur->nKey); + assert( rc==SQLITE_OK ); /* KeySize() cannot fail */ /* If this is an intKey table, then the above call to BtreeKeySize() ** stores the integer key in pCur->nKey. In this case this value is @@ -37233,7 +38170,7 @@ static int saveCursorPosition(BtCursor *pCur){ ** table, then malloc space for and store the pCur->nKey bytes of key ** data. */ - if( rc==SQLITE_OK && 0==pCur->apPage[0]->intKey){ + if( 0==pCur->apPage[0]->intKey ){ void *pKey = sqlite3Malloc( (int)pCur->nKey ); if( pKey ){ rc = sqlite3BtreeKey(pCur, 0, (int)pCur->nKey, pKey); @@ -37293,6 +38230,37 @@ SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *pCur){ pCur->eState = CURSOR_INVALID; } +/* +** In this version of BtreeMoveto, pKey is a packed index record +** such as is generated by the OP_MakeRecord opcode. Unpack the +** record and then call BtreeMovetoUnpacked() to do the work. +*/ +static int btreeMoveto( + BtCursor *pCur, /* Cursor open on the btree to be searched */ + const void *pKey, /* Packed key if the btree is an index */ + i64 nKey, /* Integer key for tables. Size of pKey for indices */ + int bias, /* Bias search to the high end */ + int *pRes /* Write search results here */ +){ + int rc; /* Status code */ + UnpackedRecord *pIdxKey; /* Unpacked index key */ + char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */ + + if( pKey ){ + assert( nKey==(i64)(int)nKey ); + pIdxKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, + aSpace, sizeof(aSpace)); + if( pIdxKey==0 ) return SQLITE_NOMEM; + }else{ + pIdxKey = 0; + } + rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); + if( pKey ){ + sqlite3VdbeDeleteUnpackedRecord(pIdxKey); + } + return rc; +} + /* ** Restore the cursor to the position it was in (or as close to as possible) ** when saveCursorPosition() was called. Note that this call deletes the @@ -37300,15 +38268,15 @@ SQLITE_PRIVATE void sqlite3BtreeClearCursor(BtCursor *pCur){ ** at most one effective restoreCursorPosition() call after each ** saveCursorPosition(). */ -SQLITE_PRIVATE int sqlite3BtreeRestoreCursorPosition(BtCursor *pCur){ +static int btreeRestoreCursorPosition(BtCursor *pCur){ int rc; assert( cursorHoldsMutex(pCur) ); assert( pCur->eState>=CURSOR_REQUIRESEEK ); if( pCur->eState==CURSOR_FAULT ){ - return pCur->skip; + return pCur->skipNext; } pCur->eState = CURSOR_INVALID; - rc = sqlite3BtreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skip); + rc = btreeMoveto(pCur, pCur->pKey, pCur->nKey, 0, &pCur->skipNext); if( rc==SQLITE_OK ){ sqlite3_free(pCur->pKey); pCur->pKey = 0; @@ -37319,7 +38287,7 @@ SQLITE_PRIVATE int sqlite3BtreeRestoreCursorPosition(BtCursor *pCur){ #define restoreCursorPosition(p) \ (p->eState>=CURSOR_REQUIRESEEK ? \ - sqlite3BtreeRestoreCursorPosition(p) : \ + btreeRestoreCursorPosition(p) : \ SQLITE_OK) /* @@ -37338,7 +38306,7 @@ SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){ *pHasMoved = 1; return rc; } - if( pCur->eState!=CURSOR_VALID || pCur->skip!=0 ){ + if( pCur->eState!=CURSOR_VALID || pCur->skipNext!=0 ){ *pHasMoved = 1; }else{ *pHasMoved = 0; @@ -37370,14 +38338,19 @@ static Pgno ptrmapPageno(BtShared *pBt, Pgno pgno){ ** ** This routine updates the pointer map entry for page number 'key' ** so that it maps to type 'eType' and parent page number 'pgno'. -** An error code is returned if something goes wrong, otherwise SQLITE_OK. +** +** If *pRC is initially non-zero (non-SQLITE_OK) then this routine is +** a no-op. If an error occurs, the appropriate error code is written +** into *pRC. */ -static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){ +static void ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent, int *pRC){ DbPage *pDbPage; /* The pointer map page */ u8 *pPtrmap; /* The pointer map data */ Pgno iPtrmap; /* The pointer map page number */ int offset; /* Offset in pointer map page */ - int rc; + int rc; /* Return code from subfunctions */ + + if( *pRC ) return; assert( sqlite3_mutex_held(pBt->mutex) ); /* The master-journal page number must never be used as a pointer map page */ @@ -37385,30 +38358,33 @@ static int ptrmapPut(BtShared *pBt, Pgno key, u8 eType, Pgno parent){ assert( pBt->autoVacuum ); if( key==0 ){ - return SQLITE_CORRUPT_BKPT; + *pRC = SQLITE_CORRUPT_BKPT; + return; } iPtrmap = PTRMAP_PAGENO(pBt, key); rc = sqlite3PagerGet(pBt->pPager, iPtrmap, &pDbPage); if( rc!=SQLITE_OK ){ - return rc; + *pRC = rc; + return; } offset = PTRMAP_PTROFFSET(iPtrmap, key); if( offset<0 ){ - return SQLITE_CORRUPT_BKPT; + *pRC = SQLITE_CORRUPT_BKPT; + goto ptrmap_exit; } pPtrmap = (u8 *)sqlite3PagerGetData(pDbPage); if( eType!=pPtrmap[offset] || get4byte(&pPtrmap[offset+1])!=parent ){ TRACE(("PTRMAP_UPDATE: %d->(%d,%d)\n", key, eType, parent)); - rc = sqlite3PagerWrite(pDbPage); + *pRC= rc = sqlite3PagerWrite(pDbPage); if( rc==SQLITE_OK ){ pPtrmap[offset] = eType; put4byte(&pPtrmap[offset+1], parent); } } +ptrmap_exit: sqlite3PagerUnref(pDbPage); - return rc; } /* @@ -37445,9 +38421,9 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ } #else /* if defined SQLITE_OMIT_AUTOVACUUM */ - #define ptrmapPut(w,x,y,z) SQLITE_OK + #define ptrmapPut(w,x,y,z,rc) #define ptrmapGet(w,x,y,z) SQLITE_OK - #define ptrmapPutOvfl(y,z) SQLITE_OK + #define ptrmapPutOvflPtr(x, y, rc) #endif /* @@ -37462,7 +38438,7 @@ static int ptrmapGet(BtShared *pBt, Pgno key, u8 *pEType, Pgno *pPgno){ /* ** This a more complex version of findCell() that works for -** pages that do contain overflow cells. See insert +** pages that do contain overflow cells. */ static u8 *findOverflowCell(MemPage *pPage, int iCell){ int i; @@ -37484,14 +38460,14 @@ static u8 *findOverflowCell(MemPage *pPage, int iCell){ /* ** Parse a cell content block and fill in the CellInfo structure. There -** are two versions of this function. sqlite3BtreeParseCell() takes a -** cell index as the second argument and sqlite3BtreeParseCellPtr() +** are two versions of this function. btreeParseCell() takes a +** cell index as the second argument and btreeParseCellPtr() ** takes a pointer to the body of the cell as its second argument. ** ** Within this file, the parseCell() macro can be called instead of -** sqlite3BtreeParseCellPtr(). Using some compilers, this will be faster. +** btreeParseCellPtr(). Using some compilers, this will be faster. */ -SQLITE_PRIVATE void sqlite3BtreeParseCellPtr( +static void btreeParseCellPtr( MemPage *pPage, /* Page containing the cell */ u8 *pCell, /* Pointer to the cell text. */ CellInfo *pInfo /* Fill in this structure */ @@ -37520,6 +38496,8 @@ SQLITE_PRIVATE void sqlite3BtreeParseCellPtr( } pInfo->nPayload = nPayload; pInfo->nHeader = n; + testcase( nPayload==pPage->maxLocal ); + testcase( nPayload==pPage->maxLocal+1 ); if( likely(nPayload<=pPage->maxLocal) ){ /* This is the (easy) common case where the entire payload fits ** on the local page. No overflow is required. @@ -37549,6 +38527,8 @@ SQLITE_PRIVATE void sqlite3BtreeParseCellPtr( minLocal = pPage->minLocal; maxLocal = pPage->maxLocal; surplus = minLocal + (nPayload - minLocal)%(pPage->pBt->usableSize - 4); + testcase( surplus==maxLocal ); + testcase( surplus==maxLocal+1 ); if( surplus <= maxLocal ){ pInfo->nLocal = (u16)surplus; }else{ @@ -37559,8 +38539,8 @@ SQLITE_PRIVATE void sqlite3BtreeParseCellPtr( } } #define parseCell(pPage, iCell, pInfo) \ - sqlite3BtreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo)) -SQLITE_PRIVATE void sqlite3BtreeParseCell( + btreeParseCellPtr((pPage), findCell((pPage), (iCell)), (pInfo)) +static void btreeParseCell( MemPage *pPage, /* Page containing the cell */ int iCell, /* The cell index. First cell is 0 */ CellInfo *pInfo /* Fill in this structure */ @@ -37584,7 +38564,7 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ ** cell. If SQLITE_DEBUG is defined, an assert() at the bottom of ** this function verifies that this invariant is not violated. */ CellInfo debuginfo; - sqlite3BtreeParseCellPtr(pPage, pCell, &debuginfo); + btreeParseCellPtr(pPage, pCell, &debuginfo); #endif if( pPage->intKey ){ @@ -37604,9 +38584,13 @@ static u16 cellSizePtr(MemPage *pPage, u8 *pCell){ pIter += getVarint32(pIter, nSize); } + testcase( nSize==pPage->maxLocal ); + testcase( nSize==pPage->maxLocal+1 ); if( nSize>pPage->maxLocal ){ int minLocal = pPage->minLocal; nSize = minLocal + (nSize - minLocal) % (pPage->pBt->usableSize - 4); + testcase( nSize==pPage->maxLocal ); + testcase( nSize==pPage->maxLocal+1 ); if( nSize>pPage->maxLocal ){ nSize = minLocal; } @@ -37634,27 +38618,16 @@ static u16 cellSize(MemPage *pPage, int iCell){ ** to an overflow page, insert an entry into the pointer-map ** for the overflow page. */ -static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){ +static void ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell, int *pRC){ CellInfo info; + if( *pRC ) return; assert( pCell!=0 ); - sqlite3BtreeParseCellPtr(pPage, pCell, &info); + btreeParseCellPtr(pPage, pCell, &info); assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload ); - if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){ + if( info.iOverflow ){ Pgno ovfl = get4byte(&pCell[info.iOverflow]); - return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno); + ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno, pRC); } - return SQLITE_OK; -} -/* -** If the cell with index iCell on page pPage contains a pointer -** to an overflow page, insert an entry into the pointer-map -** for the overflow page. -*/ -static int ptrmapPutOvfl(MemPage *pPage, int iCell){ - u8 *pCell; - assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - pCell = findOverflowCell(pPage, iCell); - return ptrmapPutOvflPtr(pPage, pCell); } #endif @@ -37668,7 +38641,6 @@ static int ptrmapPutOvfl(MemPage *pPage, int iCell){ static int defragmentPage(MemPage *pPage){ int i; /* Loop counter */ int pc; /* Address of a i-th cell */ - int addr; /* Offset of first byte after cell pointer array */ int hdr; /* Offset to the page header */ int size; /* Size of a cell */ int usableSize; /* Number of usable bytes on a page */ @@ -37677,6 +38649,9 @@ static int defragmentPage(MemPage *pPage){ int nCell; /* Number of cells on the page */ unsigned char *data; /* The page data */ unsigned char *temp; /* Temp area for cell content */ + int iCellFirst; /* First allowable cell index */ + int iCellLast; /* Last possible cell index */ + assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt!=0 ); @@ -37693,31 +38668,48 @@ static int defragmentPage(MemPage *pPage){ cbrk = get2byte(&data[hdr+5]); memcpy(&temp[cbrk], &data[cbrk], usableSize - cbrk); cbrk = usableSize; + iCellFirst = cellOffset + 2*nCell; + iCellLast = usableSize - 4; for(i=0; i=usableSize ){ + testcase( pc==iCellFirst ); + testcase( pc==iCellLast ); +#if !defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) + /* These conditions have already been verified in btreeInitPage() + ** if SQLITE_ENABLE_OVERSIZE_CELL_CHECK is defined + */ + if( pciCellLast ){ return SQLITE_CORRUPT_BKPT; } +#endif + assert( pc>=iCellFirst && pc<=iCellLast ); size = cellSizePtr(pPage, &temp[pc]); cbrk -= size; - if( cbrkusableSize ){ +#if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) + if( cbrkusableSize ){ return SQLITE_CORRUPT_BKPT; } - assert( cbrk+size<=usableSize && cbrk>=0 ); +#endif + assert( cbrk+size<=usableSize && cbrk>=iCellFirst ); + testcase( cbrk+size==usableSize ); + testcase( pc+size==usableSize ); memcpy(&data[cbrk], &temp[pc], size); put2byte(pAddr, cbrk); } - assert( cbrk>=cellOffset+2*nCell ); + assert( cbrk>=iCellFirst ); put2byte(&data[hdr+5], cbrk); data[hdr+1] = 0; data[hdr+2] = 0; data[hdr+7] = 0; - addr = cellOffset+2*nCell; - memset(&data[addr], 0, cbrk-addr); + memset(&data[iCellFirst], 0, cbrk-iCellFirst); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - if( cbrk-addr!=pPage->nFree ){ + if( cbrk-iCellFirst!=pPage->nFree ){ return SQLITE_CORRUPT_BKPT; } return SQLITE_OK; @@ -37725,24 +38717,24 @@ static int defragmentPage(MemPage *pPage){ /* ** Allocate nByte bytes of space from within the B-Tree page passed -** as the first argument. Return the index into pPage->aData[] of the -** first byte of allocated space. -** -** The caller guarantees that the space between the end of the cell-offset -** array and the start of the cell-content area is at least nByte bytes -** in size. So this routine can never fail. -** -** If there are already 60 or more bytes of fragments within the page, -** the page is defragmented before returning. If this were not done there -** is a chance that the number of fragmented bytes could eventually -** overflow the single-byte field of the page-header in which this value -** is stored. -*/ -static int allocateSpace(MemPage *pPage, int nByte){ +** as the first argument. Write into *pIdx the index into pPage->aData[] +** of the first byte of allocated space. Return either SQLITE_OK or +** an error code (usually SQLITE_CORRUPT). +** +** The caller guarantees that there is sufficient space to make the +** allocation. This routine might need to defragment in order to bring +** all the space together, however. This routine will avoid using +** the first two bytes past the cell pointer area since presumably this +** allocation is being made in order to insert a new cell, so we will +** also end up needing a new cell pointer. +*/ +static int allocateSpace(MemPage *pPage, int nByte, int *pIdx){ const int hdr = pPage->hdrOffset; /* Local cache of pPage->hdrOffset */ u8 * const data = pPage->aData; /* Local cache of pPage->aData */ int nFrag; /* Number of fragmented bytes on pPage */ - int top; + int top; /* First byte of cell content area */ + int gap; /* First byte of gap between cell pointers and cell content */ + int rc; /* Integer return code */ assert( sqlite3PagerIswriteable(pPage->pDbPage) ); assert( pPage->pBt ); @@ -37750,19 +38742,23 @@ static int allocateSpace(MemPage *pPage, int nByte){ assert( nByte>=0 ); /* Minimum cell size is 4 */ assert( pPage->nFree>=nByte ); assert( pPage->nOverflow==0 ); + assert( nBytepBt->usableSize-8 ); - /* Assert that the space between the cell-offset array and the - ** cell-content area is greater than nByte bytes. - */ - assert( nByte <= ( - get2byte(&data[hdr+5])-(hdr+8+(pPage->leaf?0:4)+2*get2byte(&data[hdr+3])) - )); - - pPage->nFree -= (u16)nByte; nFrag = data[hdr+7]; + assert( pPage->cellOffset == hdr + 12 - 4*pPage->leaf ); + gap = pPage->cellOffset + 2*pPage->nCell; + top = get2byte(&data[hdr+5]); + if( gap>top ) return SQLITE_CORRUPT_BKPT; + testcase( gap+2==top ); + testcase( gap+1==top ); + testcase( gap==top ); + if( nFrag>=60 ){ - defragmentPage(pPage); - }else{ + /* Always defragment highly fragmented pages */ + rc = defragmentPage(pPage); + if( rc ) return rc; + top = get2byte(&data[hdr+5]); + }else if( gap+2<=top ){ /* Search the freelist looking for a free slot big enough to satisfy ** the request. The allocation is made from the first free slot in ** the list that is large enough to accomadate it. @@ -37772,6 +38768,8 @@ static int allocateSpace(MemPage *pPage, int nByte){ int size = get2byte(&data[pc+2]); /* Size of free slot */ if( size>=nByte ){ int x = size - nByte; + testcase( x==4 ); + testcase( x==3 ); if( x<4 ){ /* Remove the slot from the free-list. Update the number of ** fragmented bytes within the page. */ @@ -37782,17 +38780,35 @@ static int allocateSpace(MemPage *pPage, int nByte){ ** for the portion used by the new allocation. */ put2byte(&data[pc+2], x); } - return pc + x; + *pIdx = pc + x; + return SQLITE_OK; } } } + /* Check to make sure there is enough space in the gap to satisfy + ** the allocation. If not, defragment. + */ + testcase( gap+2+nByte==top ); + if( gap+2+nByte>top ){ + rc = defragmentPage(pPage); + if( rc ) return rc; + top = get2byte(&data[hdr+5]); + assert( gap+nByte<=top ); + } + + /* Allocate memory from the gap in between the cell pointer array - ** and the cell content area. + ** and the cell content area. The btreeInitPage() call has already + ** validated the freelist. Given that the freelist is valid, there + ** is no way that the allocation can extend off the end of the page. + ** The assert() below verifies the previous sentence. */ - top = get2byte(&data[hdr+5]) - nByte; + top -= nByte; put2byte(&data[hdr+5], top); - return top; + assert( top+nByte <= pPage->pBt->usableSize ); + *pIdx = top; + return SQLITE_OK; } /* @@ -37805,11 +38821,12 @@ static int allocateSpace(MemPage *pPage, int nByte){ */ static int freeSpace(MemPage *pPage, int start, int size){ int addr, pbegin, hdr; + int iLast; /* Largest possible freeblock offset */ unsigned char *data = pPage->aData; assert( pPage->pBt!=0 ); assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - assert( start>=pPage->hdrOffset+6+(pPage->leaf?0:4) ); + assert( start>=pPage->hdrOffset+6+pPage->childPtrSize ); assert( (start + size)<=pPage->pBt->usableSize ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( size>=0 ); /* Minimum cell size is 4 */ @@ -37820,27 +38837,36 @@ static int freeSpace(MemPage *pPage, int start, int size){ memset(&data[start], 0, size); #endif - /* Add the space back into the linked list of freeblocks */ + /* Add the space back into the linked list of freeblocks. Note that + ** even though the freeblock list was checked by btreeInitPage(), + ** btreeInitPage() did not detect overlapping cells or + ** freeblocks that overlapped cells. Nor does it detect when the + ** cell content area exceeds the value in the page header. If these + ** situations arise, then subsequent insert operations might corrupt + ** the freelist. So we do need to check for corruption while scanning + ** the freelist. + */ hdr = pPage->hdrOffset; addr = hdr + 1; + iLast = pPage->pBt->usableSize - 4; + assert( start<=iLast ); while( (pbegin = get2byte(&data[addr]))0 ){ - assert( pbegin<=pPage->pBt->usableSize-4 ); - if( pbegin<=addr ) { + if( pbeginpPage->pBt->usableSize-4 ) { + if( pbegin>iLast ){ return SQLITE_CORRUPT_BKPT; } assert( pbegin>addr || pbegin==0 ); put2byte(&data[addr], start); put2byte(&data[start], pbegin); put2byte(&data[start+2], size); - pPage->nFree += (u16)size; + pPage->nFree = pPage->nFree + (u16)size; /* Coalesce adjacent free blocks */ - addr = pPage->hdrOffset + 1; + addr = hdr + 1; while( (pbegin = get2byte(&data[addr]))>0 ){ int pnext, psize, x; assert( pbegin>addr ); @@ -37849,10 +38875,10 @@ static int freeSpace(MemPage *pPage, int start, int size){ psize = get2byte(&data[pbegin+2]); if( pbegin + psize + 3 >= pnext && pnext>0 ){ int frag = pnext - (pbegin+psize); - if( (frag<0) || (frag>(int)data[pPage->hdrOffset+7]) ){ + if( (frag<0) || (frag>(int)data[hdr+7]) ){ return SQLITE_CORRUPT_BKPT; } - data[pPage->hdrOffset+7] -= (u8)frag; + data[hdr+7] -= (u8)frag; x = get2byte(&data[pnext]); put2byte(&data[pbegin], x); x = pnext + get2byte(&data[pnext+2]) - pbegin; @@ -37920,7 +38946,7 @@ static int decodeFlags(MemPage *pPage, int flagByte){ ** guarantee that the page is well-formed. It only shows that ** we failed to detect any corruption. */ -SQLITE_PRIVATE int sqlite3BtreeInitPage(MemPage *pPage){ +static int btreeInitPage(MemPage *pPage){ assert( pPage->pBt!=0 ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); @@ -37937,6 +38963,8 @@ SQLITE_PRIVATE int sqlite3BtreeInitPage(MemPage *pPage){ u16 cellOffset; /* Offset from start of page to first cell pointer */ u16 nFree; /* Number of unused bytes on the page */ u16 top; /* First byte of the cell content area */ + int iCellFirst; /* First allowable cell or freeblock offset */ + int iCellLast; /* Last possible cell or freeblock offset */ pBt = pPage->pBt; @@ -37954,34 +38982,37 @@ SQLITE_PRIVATE int sqlite3BtreeInitPage(MemPage *pPage){ /* To many cells for a single page. The page must be corrupt */ return SQLITE_CORRUPT_BKPT; } + testcase( pPage->nCell==MX_CELL(pBt) ); - /* A malformed database page might cause use to read past the end + /* A malformed database page might cause us to read past the end ** of page when parsing a cell. ** ** The following block of code checks early to see if a cell extends ** past the end of a page boundary and causes SQLITE_CORRUPT to be ** returned if it does. */ + iCellFirst = cellOffset + 2*pPage->nCell; + iCellLast = usableSize - 4; #if defined(SQLITE_ENABLE_OVERSIZE_CELL_CHECK) { - int iCellFirst; /* First allowable cell index */ - int iCellLast; /* Last possible cell index */ int i; /* Index into the cell pointer array */ int sz; /* Size of a cell */ - iCellFirst = cellOffset + 2*pPage->nCell; - iCellLast = usableSize - 4; if( !pPage->leaf ) iCellLast--; for(i=0; inCell; i++){ pc = get2byte(&data[cellOffset+i*2]); + testcase( pc==iCellFirst ); + testcase( pc==iCellLast ); if( pciCellLast ){ return SQLITE_CORRUPT_BKPT; } sz = cellSizePtr(pPage, &data[pc]); + testcase( pc+sz==usableSize ); if( pc+sz>usableSize ){ return SQLITE_CORRUPT_BKPT; } } + if( !pPage->leaf ) iCellLast++; } #endif @@ -37990,17 +39021,18 @@ SQLITE_PRIVATE int sqlite3BtreeInitPage(MemPage *pPage){ nFree = data[hdr+7] + top; while( pc>0 ){ u16 next, size; - if( pc>usableSize-4 ){ - /* Free block is off the page */ + if( pciCellLast ){ + /* Start of free block is off the page */ return SQLITE_CORRUPT_BKPT; } next = get2byte(&data[pc]); size = get2byte(&data[pc+2]); - if( next>0 && next<=pc+size+3 ){ - /* Free blocks must be in accending order */ + if( (next>0 && next<=pc+size+3) || pc+size>usableSize ){ + /* Free blocks must be in ascending order. And the last byte of + ** the free-block must lie on the database page. */ return SQLITE_CORRUPT_BKPT; } - nFree += size; + nFree = nFree + size; pc = next; } @@ -38014,28 +39046,7 @@ SQLITE_PRIVATE int sqlite3BtreeInitPage(MemPage *pPage){ if( nFree>usableSize ){ return SQLITE_CORRUPT_BKPT; } - pPage->nFree = nFree - (cellOffset + 2*pPage->nCell); - -#if 0 - /* Check that all the offsets in the cell offset array are within range. - ** - ** Omitting this consistency check and using the pPage->maskPage mask - ** to prevent overrunning the page buffer in findCell() results in a - ** 2.5% performance gain. - */ - { - u8 *pOff; /* Iterator used to check all cell offsets are in range */ - u8 *pEnd; /* Pointer to end of cell offset array */ - u8 mask; /* Mask of bits that must be zero in MSB of cell offsets */ - mask = ~(((u8)(pBt->pageSize>>8))-1); - pEnd = &data[cellOffset + pPage->nCell*2]; - for(pOff=&data[cellOffset]; pOff!=pEnd && !((*pOff)&mask); pOff+=2); - if( pOff!=pEnd ){ - return SQLITE_CORRUPT_BKPT; - } - } -#endif - + pPage->nFree = (u16)(nFree - iCellFirst); pPage->isInit = 1; } return SQLITE_OK; @@ -38099,7 +39110,7 @@ static MemPage *btreePageFromDbPage(DbPage *pDbPage, Pgno pgno, BtShared *pBt){ ** means we have started to be concerned about content and the disk ** read should occur at that point. */ -SQLITE_PRIVATE int sqlite3BtreeGetPage( +static int btreeGetPage( BtShared *pBt, /* The btree */ Pgno pgno, /* Number of the page to fetch */ MemPage **ppPage, /* Return the page in this parameter */ @@ -38144,9 +39155,12 @@ static Pgno pagerPagecount(BtShared *pBt){ } /* -** Get a page from the pager and initialize it. This routine -** is just a convenience wrapper around separate calls to -** sqlite3BtreeGetPage() and sqlite3BtreeInitPage(). +** Get a page from the pager and initialize it. This routine is just a +** convenience wrapper around separate calls to btreeGetPage() and +** btreeInitPage(). +** +** If an error occurs, then the value *ppPage is set to is undefined. It +** may remain unchanged, or it may be set to an invalid value. */ static int getAndInitPage( BtShared *pBt, /* The database file */ @@ -38154,44 +39168,31 @@ static int getAndInitPage( MemPage **ppPage /* Write the page pointer here */ ){ int rc; - MemPage *pPage; - + TESTONLY( Pgno iLastPg = pagerPagecount(pBt); ) assert( sqlite3_mutex_held(pBt->mutex) ); - if( pgno==0 ){ - return SQLITE_CORRUPT_BKPT; - } - /* It is often the case that the page we want is already in cache. - ** If so, get it directly. This saves us from having to call - ** pagerPagecount() to make sure pgno is within limits, which results - ** in a measureable performance improvements. - */ - *ppPage = pPage = btreePageLookup(pBt, pgno); - if( pPage ){ - /* Page is already in cache */ - rc = SQLITE_OK; - }else{ - /* Page not in cache. Acquire it. */ - if( pgno>pagerPagecount(pBt) ){ - return SQLITE_CORRUPT_BKPT; + rc = btreeGetPage(pBt, pgno, ppPage, 0); + if( rc==SQLITE_OK ){ + rc = btreeInitPage(*ppPage); + if( rc!=SQLITE_OK ){ + releasePage(*ppPage); } - rc = sqlite3BtreeGetPage(pBt, pgno, ppPage, 0); - if( rc ) return rc; - pPage = *ppPage; - } - if( !pPage->isInit ){ - rc = sqlite3BtreeInitPage(pPage); - } - if( rc!=SQLITE_OK ){ - releasePage(pPage); - *ppPage = 0; } + + /* If the requested page number was either 0 or greater than the page + ** number of the last page in the database, this function should return + ** SQLITE_CORRUPT or some other error (i.e. SQLITE_FULL). Check that this + ** is the case. */ + assert( (pgno>0 && pgno<=iLastPg) || rc!=SQLITE_OK ); + testcase( pgno==0 ); + testcase( pgno==iLastPg ); + return rc; } /* ** Release a MemPage. This should be called once for each prior -** call to sqlite3BtreeGetPage. +** call to btreeGetPage. */ static void releasePage(MemPage *pPage){ if( pPage ){ @@ -38223,11 +39224,11 @@ static void pageReinit(DbPage *pData){ if( sqlite3PagerPageRefcount(pData)>1 ){ /* pPage might not be a btree page; it might be an overflow page ** or ptrmap page or a free page. In those cases, the following - ** call to sqlite3BtreeInitPage() will likely return SQLITE_CORRUPT. + ** call to btreeInitPage() will likely return SQLITE_CORRUPT. ** But no harm is done by this. And it is very important that - ** sqlite3BtreeInitPage() be called on every btree page so we make + ** btreeInitPage() be called on every btree page so we make ** the call for every page that comes in for re-initing. */ - sqlite3BtreeInitPage(pPage); + btreeInitPage(pPage); } } } @@ -38295,6 +39296,10 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( } p->inTrans = TRANS_NONE; p->db = db; +#ifndef SQLITE_OMIT_SHARED_CACHE + p->lock.pBtree = p; + p->lock.iTable = 1; +#endif #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) /* @@ -38302,12 +39307,11 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( ** existing BtShared object that we can share with */ if( isMemdb==0 && zFilename && zFilename[0] ){ - if( sqlite3GlobalConfig.sharedCacheEnabled ){ + if( vfsFlags & SQLITE_OPEN_SHAREDCACHE ){ int nFullPathname = pVfs->mxPathname+1; char *zFullPathname = sqlite3Malloc(nFullPathname); sqlite3_mutex *mutexShared; p->sharable = 1; - db->flags |= SQLITE_SharedCache; if( !zFullPathname ){ sqlite3_free(p); return SQLITE_NOMEM; @@ -38370,7 +39374,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( goto btree_open_out; } rc = sqlite3PagerOpen(pVfs, &pBt->pPager, zFilename, - EXTRA_SIZE, flags, vfsFlags); + EXTRA_SIZE, flags, vfsFlags, pageReinit); if( rc==SQLITE_OK ){ rc = sqlite3PagerReadFileheader(pBt->pPager,sizeof(zDbHeader),zDbHeader); } @@ -38381,7 +39385,6 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( sqlite3PagerSetBusyhandler(pBt->pPager, btreeInvokeBusyHandler, pBt); p->pBt = pBt; - sqlite3PagerSetReiniter(pBt->pPager, pageReinit); pBt->pCursor = 0; pBt->pPage1 = 0; pBt->readOnly = sqlite3PagerIsreadonly(pBt->pPager); @@ -38410,7 +39413,7 @@ SQLITE_PRIVATE int sqlite3BtreeOpen( pBt->incrVacuum = (get4byte(&zDbHeader[36 + 7*4])?1:0); #endif } - rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); if( rc ) goto btree_open_out; pBt->usableSize = pBt->pageSize - nReserve; assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ @@ -38701,8 +39704,8 @@ SQLITE_PRIVATE int sqlite3BtreeSetPageSize(Btree *p, int pageSize, int nReserve, assert( !pBt->pPage1 && !pBt->pCursor ); pBt->pageSize = (u16)pageSize; freeTempSpace(pBt); - rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); } + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, nReserve); pBt->usableSize = pBt->pageSize - (u16)nReserve; if( iFix ) pBt->pageSizeFixed = 1; sqlite3BtreeLeave(p); @@ -38806,7 +39809,9 @@ static int lockBtree(BtShared *pBt){ assert( sqlite3_mutex_held(pBt->mutex) ); assert( pBt->pPage1==0 ); - rc = sqlite3BtreeGetPage(pBt, 1, &pPage1, 0); + rc = sqlite3PagerSharedLock(pBt->pPager); + if( rc!=SQLITE_OK ) return rc; + rc = btreeGetPage(pBt, 1, &pPage1, 0); if( rc!=SQLITE_OK ) return rc; /* Do some checking to help insure the file we opened really is @@ -38857,11 +39862,11 @@ static int lockBtree(BtShared *pBt){ pBt->usableSize = (u16)usableSize; pBt->pageSize = (u16)pageSize; freeTempSpace(pBt); - rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize); - if( rc ) goto page1_init_failed; - return SQLITE_OK; + rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, + pageSize-usableSize); + return rc; } - if( usableSize<500 ){ + if( usableSize<480 ){ goto page1_init_failed; } pBt->pageSize = (u16)pageSize; @@ -38899,53 +39904,30 @@ page1_init_failed: return rc; } -/* -** This routine works like lockBtree() except that it also invokes the -** busy callback if there is lock contention. -*/ -static int lockBtreeWithRetry(Btree *pRef){ - int rc = SQLITE_OK; - - assert( sqlite3BtreeHoldsMutex(pRef) ); - if( pRef->inTrans==TRANS_NONE ){ - u8 inTransaction = pRef->pBt->inTransaction; - btreeIntegrity(pRef); - rc = sqlite3BtreeBeginTrans(pRef, 0); - pRef->pBt->inTransaction = inTransaction; - pRef->inTrans = TRANS_NONE; - if( rc==SQLITE_OK ){ - pRef->pBt->nTransaction--; - } - btreeIntegrity(pRef); - } - return rc; -} - - /* ** If there are no outstanding cursors and we are not in the middle ** of a transaction but there is a read lock on the database, then ** this routine unrefs the first page of the database file which ** has the effect of releasing the read lock. ** -** If there are any outstanding cursors, this routine is a no-op. -** ** If there is a transaction in progress, this routine is a no-op. */ static void unlockBtreeIfUnused(BtShared *pBt){ assert( sqlite3_mutex_held(pBt->mutex) ); - if( pBt->inTransaction==TRANS_NONE && pBt->pCursor==0 && pBt->pPage1!=0 ){ - if( sqlite3PagerRefcount(pBt->pPager)>=1 ){ - assert( pBt->pPage1->aData ); - releasePage(pBt->pPage1); - } + assert( pBt->pCursor==0 || pBt->inTransaction>TRANS_NONE ); + if( pBt->inTransaction==TRANS_NONE && pBt->pPage1!=0 ){ + assert( pBt->pPage1->aData ); + assert( sqlite3PagerRefcount(pBt->pPager)==1 ); + assert( pBt->pPage1->aData ); + releasePage(pBt->pPage1); pBt->pPage1 = 0; } } /* -** Create a new database by initializing the first page of the -** file. +** If pBt points to an empty file then convert that empty file +** into a new empty database by initializing the first page of +** the database. */ static int newDatabase(BtShared *pBt){ MemPage *pP1; @@ -38954,8 +39936,11 @@ static int newDatabase(BtShared *pBt){ int nPage; assert( sqlite3_mutex_held(pBt->mutex) ); + /* The database size has already been measured and cached, so failure + ** is impossible here. If the original size measurement failed, then + ** processing aborts before entering this routine. */ rc = sqlite3PagerPagecount(pBt->pPager, &nPage); - if( rc!=SQLITE_OK || nPage>0 ){ + if( NEVER(rc!=SQLITE_OK) || nPage>0 ){ return rc; } pP1 = pBt->pPage1; @@ -39065,6 +40050,12 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ } #endif + /* Any read-only or read-write transaction implies a read-lock on + ** page 1. So if some other shared-cache client already has a write-lock + ** on page 1, the transaction cannot be opened. */ + rc = querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK); + if( SQLITE_OK!=rc ) goto trans_begun; + do { /* Call lockBtree() until either pBt->pPage1 is populated or ** lockBtree() returns something other than SQLITE_OK. lockBtree() @@ -39095,6 +40086,14 @@ SQLITE_PRIVATE int sqlite3BtreeBeginTrans(Btree *p, int wrflag){ if( rc==SQLITE_OK ){ if( p->inTrans==TRANS_NONE ){ pBt->nTransaction++; +#ifndef SQLITE_OMIT_SHARED_CACHE + if( p->sharable ){ + assert( p->lock.pBtree==p && p->lock.iTable==1 ); + p->lock.eLock = READ_LOCK; + p->lock.pNext = pBt->pLock; + pBt->pLock = &p->lock; + } +#endif } p->inTrans = (wrflag?TRANS_WRITE:TRANS_READ); if( p->inTrans>pBt->inTransaction ){ @@ -39140,7 +40139,7 @@ static int setChildPtrmaps(MemPage *pPage){ Pgno pgno = pPage->pgno; assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - rc = sqlite3BtreeInitPage(pPage); + rc = btreeInitPage(pPage); if( rc!=SQLITE_OK ){ goto set_child_ptrmaps_out; } @@ -39149,21 +40148,17 @@ static int setChildPtrmaps(MemPage *pPage){ for(i=0; ileaf ){ Pgno childPgno = get4byte(pCell); - rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno); - if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out; + ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); } } if( !pPage->leaf ){ Pgno childPgno = get4byte(&pPage->aData[pPage->hdrOffset+8]); - rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno); + ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno, &rc); } set_child_ptrmaps_out: @@ -39172,10 +40167,9 @@ set_child_ptrmaps_out: } /* -** Somewhere on pPage, which is guaranteed to be a btree page, not an overflow -** page, is a pointer to page iFrom. Modify this pointer so that it points to -** iTo. Parameter eType describes the type of pointer to be modified, as -** follows: +** Somewhere on pPage is a pointer to page iFrom. Modify this pointer so +** that it points to iTo. Parameter eType describes the type of pointer to +** be modified, as follows: ** ** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child ** page of pPage. @@ -39200,14 +40194,14 @@ static int modifyPagePointer(MemPage *pPage, Pgno iFrom, Pgno iTo, u8 eType){ int i; int nCell; - sqlite3BtreeInitPage(pPage); + btreeInitPage(pPage); nCell = pPage->nCell; for(i=0; ipgno +** can be written to. The caller has already promised not to write to that +** page. */ static int relocatePage( BtShared *pBt, /* Btree */ @@ -39246,7 +40245,7 @@ static int relocatePage( u8 eType, /* Pointer map 'type' entry for pDbPage */ Pgno iPtrPage, /* Pointer map 'page-no' entry for pDbPage */ Pgno iFreePage, /* The location to move pDbPage to */ - int isCommit + int isCommit /* isCommit flag passed to sqlite3PagerMovepage */ ){ MemPage *pPtrPage; /* The page that contains a pointer to pDbPage */ Pgno iDbPage = pDbPage->pgno; @@ -39283,7 +40282,7 @@ static int relocatePage( }else{ Pgno nextOvfl = get4byte(pDbPage->aData); if( nextOvfl!=0 ){ - rc = ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage); + ptrmapPut(pBt, nextOvfl, PTRMAP_OVERFLOW2, iFreePage, &rc); if( rc!=SQLITE_OK ){ return rc; } @@ -39295,7 +40294,7 @@ static int relocatePage( ** iPtrPage. */ if( eType!=PTRMAP_ROOTPAGE ){ - rc = sqlite3BtreeGetPage(pBt, iPtrPage, &pPtrPage, 0); + rc = btreeGetPage(pBt, iPtrPage, &pPtrPage, 0); if( rc!=SQLITE_OK ){ return rc; } @@ -39307,7 +40306,7 @@ static int relocatePage( rc = modifyPagePointer(pPtrPage, iDbPage, iFreePage, eType); releasePage(pPtrPage); if( rc==SQLITE_OK ){ - rc = ptrmapPut(pBt, iFreePage, eType, iPtrPage); + ptrmapPut(pBt, iFreePage, eType, iPtrPage, &rc); } } return rc; @@ -39325,11 +40324,14 @@ static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8); ** database so that the last page of the file currently in use ** is no longer in use. ** -** If the nFin parameter is non-zero, the implementation assumes +** If the nFin parameter is non-zero, this function assumes ** that the caller will keep calling incrVacuumStep() until ** it returns SQLITE_DONE or an error, and that nFin is the ** number of pages the database file will contain after this -** process is complete. +** process is complete. If nFin is zero, it is assumed that +** incrVacuumStep() will be called a finite amount of times +** which may or may not empty the freelist. A full autovacuum +** has nFin>0. A "PRAGMA incremental_vacuum" has nFin==0. */ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){ Pgno nFreeList; /* Number of pages still on the free-list */ @@ -39375,7 +40377,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){ Pgno iFreePg; /* Index of free page to move pLastPg to */ MemPage *pLastPg; - rc = sqlite3BtreeGetPage(pBt, iLastPg, &pLastPg, 0); + rc = btreeGetPage(pBt, iLastPg, &pLastPg, 0); if( rc!=SQLITE_OK ){ return rc; } @@ -39414,7 +40416,7 @@ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg){ while( iLastPg==PENDING_BYTE_PAGE(pBt)||PTRMAP_ISPAGE(pBt, iLastPg) ){ if( PTRMAP_ISPAGE(pBt, iLastPg) ){ MemPage *pPg; - int rc = sqlite3BtreeGetPage(pBt, iLastPg, &pPg, 0); + int rc = btreeGetPage(pBt, iLastPg, &pPg, 0); if( rc!=SQLITE_OK ){ return rc; } @@ -39473,13 +40475,14 @@ static int autoVacuumCommit(BtShared *pBt){ invalidateAllOverflowCache(pBt); assert(pBt->autoVacuum); if( !pBt->incrVacuum ){ - Pgno nFin; - Pgno nFree; - Pgno nPtrmap; - Pgno iFree; - const int pgsz = pBt->pageSize; - Pgno nOrig = pagerPagecount(pBt); - + Pgno nFin; /* Number of pages in database after autovacuuming */ + Pgno nFree; /* Number of pages on the freelist initially */ + Pgno nPtrmap; /* Number of PtrMap pages to be freed */ + Pgno iFree; /* The next page to be freed */ + int nEntry; /* Number of entries on one ptrmap page */ + Pgno nOrig; /* Database size before freeing */ + + nOrig = pagerPagecount(pBt); if( PTRMAP_ISPAGE(pBt, nOrig) || nOrig==PENDING_BYTE_PAGE(pBt) ){ /* It is not possible to create a database for which the final page ** is either a pointer-map page or the pending-byte page. If one @@ -39489,7 +40492,8 @@ static int autoVacuumCommit(BtShared *pBt){ } nFree = get4byte(&pBt->pPage1->aData[36]); - nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+pgsz/5)/(pgsz/5); + nEntry = pBt->usableSize/5; + nPtrmap = (nFree-nOrig+PTRMAP_PAGENO(pBt, nOrig)+nEntry)/nEntry; nFin = nOrig - nFree - nPtrmap; if( nOrig>PENDING_BYTE_PAGE(pBt) && nFinpBt; + BtCursor *pCsr; + assert( sqlite3BtreeHoldsMutex(p) ); + + /* Search for a cursor held open by this b-tree connection. If one exists, + ** then the transaction will be downgraded to a read-only transaction + ** instead of actually concluded. A subsequent call to CommitPhaseTwo() + ** or Rollback() will finish the transaction and unlock the database. */ + for(pCsr=pBt->pCursor; pCsr && pCsr->pBtree!=p; pCsr=pCsr->pNext); + assert( pCsr==0 || p->inTrans>TRANS_NONE ); + + btreeClearHasContent(pBt); + if( pCsr ){ + downgradeAllSharedCacheTableLocks(p); + p->inTrans = TRANS_READ; + }else{ + /* If the handle had any kind of transaction open, decrement the + ** transaction count of the shared btree. If the transaction count + ** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused() + ** call below will unlock the pager. */ + if( p->inTrans!=TRANS_NONE ){ + clearAllSharedCacheTableLocks(p); + pBt->nTransaction--; + if( 0==pBt->nTransaction ){ + pBt->inTransaction = TRANS_NONE; + } + } + + /* Set the current transaction state to TRANS_NONE and unlock the + ** pager if this call closed the only read or write transaction. */ + p->inTrans = TRANS_NONE; + unlockBtreeIfUnused(pBt); + } + + btreeIntegrity(p); +} + /* ** Commit the transaction currently in progress. ** @@ -39604,27 +40650,7 @@ SQLITE_PRIVATE int sqlite3BtreeCommitPhaseTwo(Btree *p){ pBt->inTransaction = TRANS_READ; } - /* If the handle has any kind of transaction open, decrement the transaction - ** count of the shared btree. If the transaction count reaches 0, set - ** the shared state to TRANS_NONE. The unlockBtreeIfUnused() call below - ** will unlock the pager. - */ - if( p->inTrans!=TRANS_NONE ){ - clearAllSharedCacheTableLocks(p); - pBt->nTransaction--; - if( 0==pBt->nTransaction ){ - pBt->inTransaction = TRANS_NONE; - } - } - - /* Set the current transaction state to TRANS_NONE and unlock - ** the pager if this call closed the only read or write transaction. - */ - btreeClearHasContent(pBt); - p->inTrans = TRANS_NONE; - unlockBtreeIfUnused(pBt); - - btreeIntegrity(p); + btreeEndTransaction(p); sqlite3BtreeLeave(p); return SQLITE_OK; } @@ -39688,7 +40714,7 @@ SQLITE_PRIVATE void sqlite3BtreeTripAllCursors(Btree *pBtree, int errCode){ int i; sqlite3BtreeClearCursor(p); p->eState = CURSOR_FAULT; - p->skip = errCode; + p->skipNext = errCode; for(i=0; i<=p->iPage; i++){ releasePage(p->apPage[i]); p->apPage[i] = 0; @@ -39737,29 +40763,16 @@ SQLITE_PRIVATE int sqlite3BtreeRollback(Btree *p){ } /* The rollback may have destroyed the pPage1->aData value. So - ** call sqlite3BtreeGetPage() on page 1 again to make + ** call btreeGetPage() on page 1 again to make ** sure pPage1->aData is set correctly. */ - if( sqlite3BtreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){ + if( btreeGetPage(pBt, 1, &pPage1, 0)==SQLITE_OK ){ releasePage(pPage1); } assert( countWriteCursors(pBt)==0 ); pBt->inTransaction = TRANS_READ; } - if( p->inTrans!=TRANS_NONE ){ - clearAllSharedCacheTableLocks(p); - assert( pBt->nTransaction>0 ); - pBt->nTransaction--; - if( 0==pBt->nTransaction ){ - pBt->inTransaction = TRANS_NONE; - } - } - - btreeClearHasContent(pBt); - p->inTrans = TRANS_NONE; - unlockBtreeIfUnused(pBt); - - btreeIntegrity(p); + btreeEndTransaction(p); sqlite3BtreeLeave(p); return rc; } @@ -39835,8 +40848,10 @@ SQLITE_PRIVATE int sqlite3BtreeSavepoint(Btree *p, int op, int iSavepoint){ /* ** Create a new cursor for the BTree whose root is on the page -** iTable. The act of acquiring a cursor gets a read lock on -** the database file. +** iTable. If a read-only cursor is requested, it is assumed that +** the caller already has at least a read-only transaction open +** on the database already. If a write-cursor is requested, then +** the caller is assumed to have an open write transaction. ** ** If wrFlag==0, then the cursor can only be used for reading. ** If wrFlag==1, then the cursor can be used for reading or for @@ -39870,48 +40885,34 @@ static int btreeCursor( struct KeyInfo *pKeyInfo, /* First arg to comparison function */ BtCursor *pCur /* Space for new cursor */ ){ - int rc; - Pgno nPage; - BtShared *pBt = p->pBt; + BtShared *pBt = p->pBt; /* Shared b-tree handle */ assert( sqlite3BtreeHoldsMutex(p) ); assert( wrFlag==0 || wrFlag==1 ); - if( wrFlag ){ - assert( !pBt->readOnly ); - if( NEVER(pBt->readOnly) ){ - return SQLITE_READONLY; - } - rc = checkForReadConflicts(p, iTable, 0, 0); - if( rc!=SQLITE_OK ){ - assert( rc==SQLITE_LOCKED_SHAREDCACHE ); - return rc; - } - } - if( pBt->pPage1==0 ){ - rc = lockBtreeWithRetry(p); - if( rc!=SQLITE_OK ){ - return rc; - } - } - pCur->pgnoRoot = (Pgno)iTable; - rc = sqlite3PagerPagecount(pBt->pPager, (int *)&nPage); - if( rc!=SQLITE_OK ){ - return rc; - } - if( iTable==1 && nPage==0 ){ - rc = SQLITE_EMPTY; - goto create_cursor_exception; + /* The following assert statements verify that if this is a sharable + ** b-tree database, the connection is holding the required table locks, + ** and that no other connection has any open cursor that conflicts with + ** this lock. */ + assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, wrFlag+1) ); + assert( wrFlag==0 || !hasReadConflicts(p, iTable) ); + + /* Assert that the caller has opened the required transaction. */ + assert( p->inTrans>TRANS_NONE ); + assert( wrFlag==0 || p->inTrans==TRANS_WRITE ); + assert( pBt->pPage1 && pBt->pPage1->aData ); + + if( NEVER(wrFlag && pBt->readOnly) ){ + return SQLITE_READONLY; } - rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]); - if( rc!=SQLITE_OK ){ - goto create_cursor_exception; + if( iTable==1 && pagerPagecount(pBt)==0 ){ + return SQLITE_EMPTY; } /* Now that no other errors can occur, finish filling in the BtCursor - ** variables, link the cursor into the BtShared list and set *ppCur (the - ** output argument to this function). - */ + ** variables and link the cursor into the BtShared list. */ + pCur->pgnoRoot = (Pgno)iTable; + pCur->iPage = -1; pCur->pKeyInfo = pKeyInfo; pCur->pBtree = p; pCur->pBt = pBt; @@ -39923,13 +40924,7 @@ static int btreeCursor( pBt->pCursor = pCur; pCur->eState = CURSOR_INVALID; pCur->cachedRowid = 0; - return SQLITE_OK; - -create_cursor_exception: - releasePage(pCur->apPage[0]); - unlockBtreeIfUnused(pBt); - return rc; } SQLITE_PRIVATE int sqlite3BtreeCursor( Btree *p, /* The btree */ @@ -40017,44 +41012,13 @@ SQLITE_PRIVATE int sqlite3BtreeCloseCursor(BtCursor *pCur){ return SQLITE_OK; } -/* -** Make a temporary cursor by filling in the fields of pTempCur. -** The temporary cursor is not on the cursor list for the Btree. -*/ -SQLITE_PRIVATE void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur){ - int i; - assert( cursorHoldsMutex(pCur) ); - memcpy(pTempCur, pCur, sizeof(BtCursor)); - pTempCur->pNext = 0; - pTempCur->pPrev = 0; - for(i=0; i<=pTempCur->iPage; i++){ - sqlite3PagerRef(pTempCur->apPage[i]->pDbPage); - } - assert( pTempCur->pKey==0 ); -} - -/* -** Delete a temporary cursor such as was made by the CreateTemporaryCursor() -** function above. -*/ -SQLITE_PRIVATE void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){ - int i; - assert( cursorHoldsMutex(pCur) ); - for(i=0; i<=pCur->iPage; i++){ - sqlite3PagerUnref(pCur->apPage[i]->pDbPage); - } - sqlite3_free(pCur->pKey); -} - - - /* ** Make sure the BtCursor* given in the argument has a valid ** BtCursor.info structure. If it is not already valid, call -** sqlite3BtreeParseCell() to fill it in. +** btreeParseCell() to fill it in. ** ** BtCursor.info is a cache of the information in the current cell. -** Using this cache reduces the number of calls to sqlite3BtreeParseCell(). +** Using this cache reduces the number of calls to btreeParseCell(). ** ** 2007-06-25: There is a bug in some versions of MSVC that cause the ** compiler to crash when getCellInfo() is implemented as a macro. @@ -40068,7 +41032,7 @@ SQLITE_PRIVATE void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){ CellInfo info; int iPage = pCur->iPage; memset(&info, 0, sizeof(info)); - sqlite3BtreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info); + btreeParseCell(pCur->apPage[iPage], pCur->aiIdx[iPage], &info); assert( memcmp(&info, &pCur->info, sizeof(info))==0 ); } #else @@ -40079,7 +41043,7 @@ SQLITE_PRIVATE void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){ static void getCellInfo(BtCursor *pCur){ if( pCur->info.nSize==0 ){ int iPage = pCur->iPage; - sqlite3BtreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); + btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); pCur->validNKey = 1; }else{ assertCellInfo(pCur); @@ -40090,13 +41054,24 @@ SQLITE_PRIVATE void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){ #define getCellInfo(pCur) \ if( pCur->info.nSize==0 ){ \ int iPage = pCur->iPage; \ - sqlite3BtreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \ + btreeParseCell(pCur->apPage[iPage],pCur->aiIdx[iPage],&pCur->info); \ pCur->validNKey = 1; \ }else{ \ assertCellInfo(pCur); \ } #endif /* _MSC_VER */ +#ifndef NDEBUG /* The next routine used only within assert() statements */ +/* +** Return true if the given BtCursor is valid. A valid cursor is one +** that is currently pointing to a row in a (non-empty) table. +** This is a verification routine is used only within assert() statements. +*/ +SQLITE_PRIVATE int sqlite3BtreeCursorIsValid(BtCursor *pCur){ + return pCur && pCur->eState==CURSOR_VALID; +} +#endif /* NDEBUG */ + /* ** Set *pSize to the size of the buffer needed to hold the value of ** the key for the current entry. If the cursor is not pointing @@ -40104,47 +41079,41 @@ SQLITE_PRIVATE void sqlite3BtreeReleaseTempCursor(BtCursor *pCur){ ** ** For a table with the INTKEY flag set, this routine returns the key ** itself, not the number of bytes in the key. +** +** The caller must position the cursor prior to invoking this routine. +** +** This routine cannot fail. It always returns SQLITE_OK. */ SQLITE_PRIVATE int sqlite3BtreeKeySize(BtCursor *pCur, i64 *pSize){ - int rc; - assert( cursorHoldsMutex(pCur) ); - rc = restoreCursorPosition(pCur); - if( rc==SQLITE_OK ){ - assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID ); - if( pCur->eState==CURSOR_INVALID ){ - *pSize = 0; - }else{ - getCellInfo(pCur); - *pSize = pCur->info.nKey; - } + assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID ); + if( pCur->eState!=CURSOR_VALID ){ + *pSize = 0; + }else{ + getCellInfo(pCur); + *pSize = pCur->info.nKey; } - return rc; + return SQLITE_OK; } /* ** Set *pSize to the number of bytes of data in the entry the -** cursor currently points to. Always return SQLITE_OK. -** Failure is not possible. If the cursor is not currently -** pointing to an entry (which can happen, for example, if -** the database is empty) then *pSize is set to 0. +** cursor currently points to. +** +** The caller must guarantee that the cursor is pointing to a non-NULL +** valid entry. In other words, the calling procedure must guarantee +** that the cursor has Cursor.eState==CURSOR_VALID. +** +** Failure is not possible. This function always returns SQLITE_OK. +** It might just as well be a procedure (returning void) but we continue +** to return an integer result code for historical reasons. */ SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){ - int rc; - assert( cursorHoldsMutex(pCur) ); - rc = restoreCursorPosition(pCur); - if( rc==SQLITE_OK ){ - assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID ); - if( pCur->eState==CURSOR_INVALID ){ - /* Not pointing at a valid entry - set *pSize to 0. */ - *pSize = 0; - }else{ - getCellInfo(pCur); - *pSize = pCur->info.nData; - } - } - return rc; + assert( pCur->eState==CURSOR_VALID ); + getCellInfo(pCur); + *pSize = pCur->info.nData; + return SQLITE_OK; } /* @@ -40167,8 +41136,8 @@ SQLITE_PRIVATE int sqlite3BtreeDataSize(BtCursor *pCur, u32 *pSize){ ** *ppPage is set to zero. */ static int getOverflowPage( - BtShared *pBt, - Pgno ovfl, /* Overflow page */ + BtShared *pBt, /* The database file */ + Pgno ovfl, /* Current overflow page number */ MemPage **ppPage, /* OUT: MemPage handle (may be NULL) */ Pgno *pPgnoNext /* OUT: Next overflow page number */ ){ @@ -40205,10 +41174,11 @@ static int getOverflowPage( } #endif + assert( next==0 || rc==SQLITE_DONE ); if( rc==SQLITE_OK ){ - rc = sqlite3BtreeGetPage(pBt, ovfl, &pPage, 0); - assert(rc==SQLITE_OK || pPage==0); - if( next==0 && rc==SQLITE_OK ){ + rc = btreeGetPage(pBt, ovfl, &pPage, 0); + assert( rc==SQLITE_OK || pPage==0 ); + if( rc==SQLITE_OK ){ next = get4byte(pPage->aData); } } @@ -40264,10 +41234,8 @@ static int copyPayload( ** A total of "amt" bytes are read or written beginning at "offset". ** Data is read to or from the buffer pBuf. ** -** This routine does not make a distinction between key and data. -** It just reads or writes bytes from the payload area. Data might -** appear on the main page or be scattered out on multiple overflow -** pages. +** The content being read or written might appear on the main page +** or be scattered out on multiple overflow pages. ** ** If the BtCursor.isIncrblobHandle flag is set, and the current ** cursor entry uses one or more overflow pages, this function @@ -40289,7 +41257,6 @@ static int accessPayload( u32 offset, /* Begin reading this far into payload */ u32 amt, /* Read this many bytes */ unsigned char *pBuf, /* Write the bytes into this buffer */ - int skipKey, /* offset begins at data if this is true */ int eOp /* zero to read. non-zero to write. */ ){ unsigned char *aPayload; @@ -40308,10 +41275,7 @@ static int accessPayload( aPayload = pCur->info.pCell + pCur->info.nHeader; nKey = (pPage->intKey ? 0 : (int)pCur->info.nKey); - if( skipKey ){ - offset += nKey; - } - if( offset+amt > nKey+pCur->info.nData + if( NEVER(offset+amt > nKey+pCur->info.nData) || &aPayload[pCur->info.nLocal] > &pPage->aData[pBt->usableSize] ){ /* Trying to read or write past the end of the data is an error */ @@ -40349,7 +41313,9 @@ static int accessPayload( if( pCur->isIncrblobHandle && !pCur->aOverflow ){ int nOvfl = (pCur->info.nPayload-pCur->info.nLocal+ovflSize-1)/ovflSize; pCur->aOverflow = (Pgno *)sqlite3MallocZero(sizeof(Pgno)*nOvfl); - if( nOvfl && !pCur->aOverflow ){ + /* nOvfl is always positive. If it were zero, fetchPayload would have + ** been used instead of this routine. */ + if( ALWAYS(nOvfl) && !pCur->aOverflow ){ rc = SQLITE_NOMEM; } } @@ -40423,25 +41389,19 @@ static int accessPayload( ** "amt" bytes will be transfered into pBuf[]. The transfer ** begins at "offset". ** +** The caller must ensure that pCur is pointing to a valid row +** in the table. +** ** Return SQLITE_OK on success or an error code if anything goes ** wrong. An error is returned if "offset+amt" is larger than ** the available payload. */ SQLITE_PRIVATE int sqlite3BtreeKey(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){ - int rc; - assert( cursorHoldsMutex(pCur) ); - rc = restoreCursorPosition(pCur); - if( rc==SQLITE_OK ){ - assert( pCur->eState==CURSOR_VALID ); - assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); - if( pCur->apPage[0]->intKey ){ - return SQLITE_CORRUPT_BKPT; - } - assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); - rc = accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0, 0); - } - return rc; + assert( pCur->eState==CURSOR_VALID ); + assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); + assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); + return accessPayload(pCur, offset, amt, (unsigned char*)pBuf, 0); } /* @@ -40468,7 +41428,7 @@ SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *p assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPage>=0 && pCur->apPage[pCur->iPage] ); assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); - rc = accessPayload(pCur, offset, amt, pBuf, 1, 0); + rc = accessPayload(pCur, offset, amt, pBuf, 0); } return rc; } @@ -40507,7 +41467,10 @@ static const unsigned char *fetchPayload( assert( cursorHoldsMutex(pCur) ); pPage = pCur->apPage[pCur->iPage]; assert( pCur->aiIdx[pCur->iPage]nCell ); - getCellInfo(pCur); + if( NEVER(pCur->info.nSize==0) ){ + btreeParseCell(pCur->apPage[pCur->iPage], pCur->aiIdx[pCur->iPage], + &pCur->info); + } aPayload = pCur->info.pCell; aPayload += pCur->info.nHeader; if( pPage->intKey ){ @@ -40520,9 +41483,7 @@ static const unsigned char *fetchPayload( nLocal = pCur->info.nLocal - nKey; }else{ nLocal = pCur->info.nLocal; - if( nLocal>nKey ){ - nLocal = nKey; - } + assert( nLocal<=nKey ); } *pAmt = nLocal; return aPayload; @@ -40544,26 +41505,33 @@ static const unsigned char *fetchPayload( ** in the common case where no overflow pages are used. */ SQLITE_PRIVATE const void *sqlite3BtreeKeyFetch(BtCursor *pCur, int *pAmt){ + const void *p = 0; assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorHoldsMutex(pCur) ); - if( pCur->eState==CURSOR_VALID ){ - return (const void*)fetchPayload(pCur, pAmt, 0); + if( ALWAYS(pCur->eState==CURSOR_VALID) ){ + p = (const void*)fetchPayload(pCur, pAmt, 0); } - return 0; + return p; } SQLITE_PRIVATE const void *sqlite3BtreeDataFetch(BtCursor *pCur, int *pAmt){ + const void *p = 0; assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); assert( cursorHoldsMutex(pCur) ); - if( pCur->eState==CURSOR_VALID ){ - return (const void*)fetchPayload(pCur, pAmt, 1); + if( ALWAYS(pCur->eState==CURSOR_VALID) ){ + p = (const void*)fetchPayload(pCur, pAmt, 1); } - return 0; + return p; } /* ** Move the cursor down to a new child page. The newPgno argument is the ** page number of the child page to move to. +** +** This function returns SQLITE_CORRUPT if the page-header flags field of +** the new child page does not match the flags field of the parent (i.e. +** if an intkey page appears to be the parent of a non-intkey page, or +** vice-versa). */ static int moveToChild(BtCursor *pCur, u32 newPgno){ int rc; @@ -40585,7 +41553,7 @@ static int moveToChild(BtCursor *pCur, u32 newPgno){ pCur->info.nSize = 0; pCur->validNKey = 0; - if( pNewPage->nCell<1 ){ + if( pNewPage->nCell<1 || pNewPage->intKey!=pCur->apPage[i]->intKey ){ return SQLITE_CORRUPT_BKPT; } return SQLITE_OK; @@ -40619,7 +41587,7 @@ static void assertParentIndex(MemPage *pParent, int iIdx, Pgno iChild){ ** right-most child page then pCur->idx is set to one more than ** the largest cell index. */ -SQLITE_PRIVATE void sqlite3BtreeMoveToParent(BtCursor *pCur){ +static void moveToParent(BtCursor *pCur){ assert( cursorHoldsMutex(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPage>0 ); @@ -40636,7 +41604,25 @@ SQLITE_PRIVATE void sqlite3BtreeMoveToParent(BtCursor *pCur){ } /* -** Move the cursor to the root page +** Move the cursor to point to the root page of its b-tree structure. +** +** If the table has a virtual root page, then the cursor is moved to point +** to the virtual root page instead of the actual root page. A table has a +** virtual root page when the actual root page contains no cells and a +** single child page. This can only happen with the table rooted at page 1. +** +** If the b-tree structure is empty, the cursor state is set to +** CURSOR_INVALID. Otherwise, the cursor is set to point to the first +** cell located on the root (or virtual root) page and the cursor state +** is set to CURSOR_VALID. +** +** If this function returns successfully, it may be assumed that the +** page-header flags indicate that the [virtual] root-page is the expected +** kind of b-tree page (i.e. if when opening the cursor the caller did not +** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D, +** indicating a table b-tree, or if the caller did specify a KeyInfo +** structure the flags byte is set to 0x02 or 0x0A, indicating an index +** b-tree). */ static int moveToRoot(BtCursor *pCur){ MemPage *pRoot; @@ -40650,7 +41636,8 @@ static int moveToRoot(BtCursor *pCur){ assert( CURSOR_FAULT > CURSOR_REQUIRESEEK ); if( pCur->eState>=CURSOR_REQUIRESEEK ){ if( pCur->eState==CURSOR_FAULT ){ - return pCur->skip; + assert( pCur->skipNext!=SQLITE_OK ); + return pCur->skipNext; } sqlite3BtreeClearCursor(pCur); } @@ -40660,18 +41647,35 @@ static int moveToRoot(BtCursor *pCur){ for(i=1; i<=pCur->iPage; i++){ releasePage(pCur->apPage[i]); } + pCur->iPage = 0; }else{ - if( - SQLITE_OK!=(rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0])) - ){ + rc = getAndInitPage(pBt, pCur->pgnoRoot, &pCur->apPage[0]); + if( rc!=SQLITE_OK ){ pCur->eState = CURSOR_INVALID; return rc; } + pCur->iPage = 0; + + /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor + ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is + ** NULL, the caller expects a table b-tree. If this is not the case, + ** return an SQLITE_CORRUPT error. */ + assert( pCur->apPage[0]->intKey==1 || pCur->apPage[0]->intKey==0 ); + if( (pCur->pKeyInfo==0)!=pCur->apPage[0]->intKey ){ + return SQLITE_CORRUPT_BKPT; + } } + /* Assert that the root page is of the correct type. This must be the + ** case as the call to this function that loaded the root-page (either + ** this call or a previous invocation) would have detected corruption + ** if the assumption were not true, and it is not possible for the flags + ** byte to have been modified while this cursor is holding a reference + ** to the page. */ pRoot = pCur->apPage[0]; assert( pRoot->pgno==pCur->pgnoRoot ); - pCur->iPage = 0; + assert( pRoot->isInit && (pCur->pKeyInfo==0)==pRoot->intKey ); + pCur->aiIdx[0] = 0; pCur->info.nSize = 0; pCur->atLast = 0; @@ -40680,9 +41684,7 @@ static int moveToRoot(BtCursor *pCur){ if( pRoot->nCell==0 && !pRoot->leaf ){ Pgno subpage; if( pRoot->pgno!=1 ) return SQLITE_CORRUPT_BKPT; - assert( pRoot->pgno==1 ); subpage = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); - assert( subpage>0 ); pCur->eState = CURSOR_VALID; rc = moveToChild(pCur, subpage); }else{ @@ -40846,6 +41848,8 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( assert( cursorHoldsMutex(pCur) ); assert( sqlite3_mutex_held(pCur->pBtree->db->mutex) ); + assert( pRes ); + assert( (pIdxKey==0)==(pCur->pKeyInfo==0) ); /* If the cursor is already positioned at the point we are trying ** to move to, then just return without doing any work */ @@ -40868,6 +41872,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( } assert( pCur->apPage[pCur->iPage] ); assert( pCur->apPage[pCur->iPage]->isInit ); + assert( pCur->apPage[pCur->iPage]->nCell>0 || pCur->eState==CURSOR_INVALID ); if( pCur->eState==CURSOR_INVALID ){ *pRes = -1; assert( pCur->apPage[pCur->iPage]->nCell==0 ); @@ -40878,13 +41883,18 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( int lwr, upr; Pgno chldPg; MemPage *pPage = pCur->apPage[pCur->iPage]; - int c = -1; /* pRes return if table is empty must be -1 */ + int c; + + /* pPage->nCell must be greater than zero. If this is the root-page + ** the cursor would have been INVALID above and this for(;;) loop + ** not run. If this is not the root-page, then the moveToChild() routine + ** would have already detected db corruption. Similarly, pPage must + ** be the right kind (index or table) of b-tree page. Otherwise + ** a moveToChild() or moveToRoot() call would have detected corruption. */ + assert( pPage->nCell>0 ); + assert( pPage->intKey==(pIdxKey==0) ); lwr = 0; upr = pPage->nCell-1; - if( (!pPage->intKey && pIdxKey==0) || upr<0 ){ - rc = SQLITE_CORRUPT_BKPT; - goto moveto_finish; - } if( biasRight ){ pCur->aiIdx[pCur->iPage] = (u16)upr; }else{ @@ -40941,17 +41951,20 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( ** buffer before VdbeRecordCompare() can be called. */ void *pCellKey; u8 * const pCellBody = pCell - pPage->childPtrSize; - sqlite3BtreeParseCellPtr(pPage, pCellBody, &pCur->info); + btreeParseCellPtr(pPage, pCellBody, &pCur->info); nCell = (int)pCur->info.nKey; pCellKey = sqlite3Malloc( nCell ); if( pCellKey==0 ){ rc = SQLITE_NOMEM; goto moveto_finish; } - rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0, 0); + rc = accessPayload(pCur, 0, nCell, (unsigned char*)pCellKey, 0); + if( rc ){ + sqlite3_free(pCellKey); + goto moveto_finish; + } c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); sqlite3_free(pCellKey); - if( rc ) goto moveto_finish; } } if( c==0 ){ @@ -40986,7 +41999,7 @@ SQLITE_PRIVATE int sqlite3BtreeMovetoUnpacked( } if( chldPg==0 ){ assert( pCur->aiIdx[pCur->iPage]apPage[pCur->iPage]->nCell ); - if( pRes ) *pRes = c; + *pRes = c; rc = SQLITE_OK; goto moveto_finish; } @@ -41000,38 +42013,6 @@ moveto_finish: return rc; } -/* -** In this version of BtreeMoveto, pKey is a packed index record -** such as is generated by the OP_MakeRecord opcode. Unpack the -** record and then call BtreeMovetoUnpacked() to do the work. -*/ -SQLITE_PRIVATE int sqlite3BtreeMoveto( - BtCursor *pCur, /* Cursor open on the btree to be searched */ - const void *pKey, /* Packed key if the btree is an index */ - i64 nKey, /* Integer key for tables. Size of pKey for indices */ - int bias, /* Bias search to the high end */ - int *pRes /* Write search results here */ -){ - int rc; /* Status code */ - UnpackedRecord *pIdxKey; /* Unpacked index key */ - char aSpace[150]; /* Temp space for pIdxKey - to avoid a malloc */ - - - if( pKey ){ - assert( nKey==(i64)(int)nKey ); - pIdxKey = sqlite3VdbeRecordUnpack(pCur->pKeyInfo, (int)nKey, pKey, - aSpace, sizeof(aSpace)); - if( pIdxKey==0 ) return SQLITE_NOMEM; - }else{ - pIdxKey = 0; - } - rc = sqlite3BtreeMovetoUnpacked(pCur, pIdxKey, nKey, bias, pRes); - if( pKey ){ - sqlite3VdbeDeleteUnpackedRecord(pIdxKey); - } - return rc; -} - /* ** Return TRUE if the cursor is not pointing at an entry of the table. @@ -41069,12 +42050,12 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ *pRes = 1; return SQLITE_OK; } - if( pCur->skip>0 ){ - pCur->skip = 0; + if( pCur->skipNext>0 ){ + pCur->skipNext = 0; *pRes = 0; return SQLITE_OK; } - pCur->skip = 0; + pCur->skipNext = 0; pPage = pCur->apPage[pCur->iPage]; idx = ++pCur->aiIdx[pCur->iPage]; @@ -41097,7 +42078,7 @@ SQLITE_PRIVATE int sqlite3BtreeNext(BtCursor *pCur, int *pRes){ pCur->eState = CURSOR_INVALID; return SQLITE_OK; } - sqlite3BtreeMoveToParent(pCur); + moveToParent(pCur); pPage = pCur->apPage[pCur->iPage]; }while( pCur->aiIdx[pCur->iPage]>=pPage->nCell ); *pRes = 0; @@ -41137,12 +42118,12 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ *pRes = 1; return SQLITE_OK; } - if( pCur->skip<0 ){ - pCur->skip = 0; + if( pCur->skipNext<0 ){ + pCur->skipNext = 0; *pRes = 0; return SQLITE_OK; } - pCur->skip = 0; + pCur->skipNext = 0; pPage = pCur->apPage[pCur->iPage]; assert( pPage->isInit ); @@ -41160,7 +42141,7 @@ SQLITE_PRIVATE int sqlite3BtreePrevious(BtCursor *pCur, int *pRes){ *pRes = 1; return SQLITE_OK; } - sqlite3BtreeMoveToParent(pCur); + moveToParent(pCur); } pCur->info.nSize = 0; pCur->validNKey = 0; @@ -41208,7 +42189,7 @@ static int allocateBtreePage( MemPage *pPage1; int rc; u32 n; /* Number of pages on the freelist */ - int k; /* Number of leaves on the trunk of the freelist */ + u32 k; /* Number of leaves on the trunk of the freelist */ MemPage *pTrunk = 0; MemPage *pPrevTrunk = 0; Pgno mxPage; /* Total size of the database file */ @@ -41217,7 +42198,8 @@ static int allocateBtreePage( pPage1 = pBt->pPage1; mxPage = pagerPagecount(pBt); n = get4byte(&pPage1->aData[36]); - if( n>mxPage ){ + testcase( n==mxPage-1 ); + if( n>=mxPage ){ return SQLITE_CORRUPT_BKPT; } if( n>0 ){ @@ -41261,10 +42243,11 @@ static int allocateBtreePage( }else{ iTrunk = get4byte(&pPage1->aData[32]); } + testcase( iTrunk==mxPage ); if( iTrunk>mxPage ){ rc = SQLITE_CORRUPT_BKPT; }else{ - rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0); + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); } if( rc ){ pTrunk = 0; @@ -41286,7 +42269,7 @@ static int allocateBtreePage( *ppPage = pTrunk; pTrunk = 0; TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); - }else if( k>pBt->usableSize/4 - 2 ){ + }else if( k>(u32)(pBt->usableSize/4 - 2) ){ /* Value of k is out of range. Database corruption */ rc = SQLITE_CORRUPT_BKPT; goto end_allocate_page; @@ -41319,7 +42302,8 @@ static int allocateBtreePage( rc = SQLITE_CORRUPT_BKPT; goto end_allocate_page; } - rc = sqlite3BtreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0); + testcase( iNewTrunk==mxPage ); + rc = btreeGetPage(pBt, iNewTrunk, &pNewTrunk, 0); if( rc!=SQLITE_OK ){ goto end_allocate_page; } @@ -41346,9 +42330,9 @@ static int allocateBtreePage( pTrunk = 0; TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1)); #endif - }else{ + }else if( k>0 ){ /* Extract a leaf from the trunk */ - int closest; + u32 closest; Pgno iPage; unsigned char *aData = pTrunk->aData; rc = sqlite3PagerWrite(pTrunk->pDbPage); @@ -41356,7 +42340,8 @@ static int allocateBtreePage( goto end_allocate_page; } if( nearby>0 ){ - int i, dist; + u32 i; + int dist; closest = 0; dist = get4byte(&aData[8]) - nearby; if( dist<0 ) dist = -dist; @@ -41373,20 +42358,15 @@ static int allocateBtreePage( } iPage = get4byte(&aData[8+closest*4]); + testcase( iPage==mxPage ); if( iPage>mxPage ){ rc = SQLITE_CORRUPT_BKPT; goto end_allocate_page; } + testcase( iPage==mxPage ); if( !searchList || iPage==nearby ){ int noContent; - Pgno nPage; *pPgno = iPage; - nPage = pagerPagecount(pBt); - if( *pPgno>nPage ){ - /* Free page off the end of the file */ - rc = SQLITE_CORRUPT_BKPT; - goto end_allocate_page; - } TRACE(("ALLOCATE: %d was leaf %d of %d on trunk %d" ": %d more free pages\n", *pPgno, closest+1, k, pTrunk->pgno, n-1)); @@ -41396,7 +42376,7 @@ static int allocateBtreePage( put4byte(&aData[4], k-1); assert( sqlite3PagerIswriteable(pTrunk->pDbPage) ); noContent = !btreeGetHasContent(pBt, *pPgno); - rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, noContent); + rc = btreeGetPage(pBt, *pPgno, ppPage, noContent); if( rc==SQLITE_OK ){ rc = sqlite3PagerWrite((*ppPage)->pDbPage); if( rc!=SQLITE_OK ){ @@ -41428,7 +42408,7 @@ static int allocateBtreePage( MemPage *pPg = 0; TRACE(("ALLOCATE: %d from end of file (pointer-map page)\n", *pPgno)); assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); - rc = sqlite3BtreeGetPage(pBt, *pPgno, &pPg, 0); + rc = btreeGetPage(pBt, *pPgno, &pPg, 0); if( rc==SQLITE_OK ){ rc = sqlite3PagerWrite(pPg->pDbPage); releasePage(pPg); @@ -41440,7 +42420,7 @@ static int allocateBtreePage( #endif assert( *pPgno!=PENDING_BYTE_PAGE(pBt) ); - rc = sqlite3BtreeGetPage(pBt, *pPgno, ppPage, 0); + rc = btreeGetPage(pBt, *pPgno, ppPage, 0); if( rc ) return rc; rc = sqlite3PagerWrite((*ppPage)->pDbPage); if( rc!=SQLITE_OK ){ @@ -41507,7 +42487,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ /* If the SQLITE_SECURE_DELETE compile-time option is enabled, then ** always fully overwrite deleted information with zeros. */ - if( (!pPage && (rc = sqlite3BtreeGetPage(pBt, iPage, &pPage, 0))) + if( (!pPage && (rc = btreeGetPage(pBt, iPage, &pPage, 0))) || (rc = sqlite3PagerWrite(pPage->pDbPage)) ){ goto freepage_out; @@ -41519,7 +42499,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ ** to indicate that the page is free. */ if( ISAUTOVACUUM ){ - rc = ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0); + ptrmapPut(pBt, iPage, PTRMAP_FREEPAGE, 0, &rc); if( rc ) goto freepage_out; } @@ -41531,20 +42511,21 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ ** is possible to add the page as a new free-list leaf. */ if( nFree!=0 ){ - int nLeaf; /* Initial number of leaf cells on trunk page */ + u32 nLeaf; /* Initial number of leaf cells on trunk page */ iTrunk = get4byte(&pPage1->aData[32]); - rc = sqlite3BtreeGetPage(pBt, iTrunk, &pTrunk, 0); + rc = btreeGetPage(pBt, iTrunk, &pTrunk, 0); if( rc!=SQLITE_OK ){ goto freepage_out; } nLeaf = get4byte(&pTrunk->aData[4]); - if( nLeaf<0 ){ + assert( pBt->usableSize>32 ); + if( nLeaf > (u32)pBt->usableSize/4 - 2 ){ rc = SQLITE_CORRUPT_BKPT; goto freepage_out; } - if( nLeafusableSize/4 - 8 ){ + if( nLeaf < (u32)pBt->usableSize/4 - 8 ){ /* In this case there is room on the trunk page to insert the page ** being freed as a new leaf. ** @@ -41554,7 +42535,7 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ ** 3.6.0, databases with freelist trunk pages holding more than ** usableSize/4 - 8 entries will be reported as corrupt. In order ** to maintain backwards compatibility with older versions of SQLite, - ** we will contain to restrict the number of entries to usableSize/4 - 8 + ** we will continue to restrict the number of entries to usableSize/4 - 8 ** for now. At some point in the future (once everyone has upgraded ** to 3.6.0 or later) we should consider fixing the conditional above ** to read "usableSize/4-2" instead of "usableSize/4-8". @@ -41581,9 +42562,11 @@ static int freePage2(BtShared *pBt, MemPage *pMemPage, Pgno iPage){ ** first trunk in the free-list is full. Either way, the page being freed ** will become the new first trunk page in the free-list. */ - if( ((!pPage) && (0 != (rc = sqlite3BtreeGetPage(pBt, iPage, &pPage, 0)))) - || (0 != (rc = sqlite3PagerWrite(pPage->pDbPage))) - ){ + if( pPage==0 && SQLITE_OK!=(rc = btreeGetPage(pBt, iPage, &pPage, 0)) ){ + goto freepage_out; + } + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc!=SQLITE_OK ){ goto freepage_out; } put4byte(pPage->aData, iTrunk); @@ -41599,8 +42582,10 @@ freepage_out: releasePage(pTrunk); return rc; } -static int freePage(MemPage *pPage){ - return freePage2(pPage->pBt, pPage, pPage->pgno); +static void freePage(MemPage *pPage, int *pRC){ + if( (*pRC)==SQLITE_OK ){ + *pRC = freePage2(pPage->pBt, pPage, pPage->pgno); + } } /* @@ -41615,7 +42600,7 @@ static int clearCell(MemPage *pPage, unsigned char *pCell){ u16 ovflPageSize; assert( sqlite3_mutex_held(pPage->pBt->mutex) ); - sqlite3BtreeParseCellPtr(pPage, pCell, &info); + btreeParseCellPtr(pPage, pCell, &info); if( info.iOverflow==0 ){ return SQLITE_OK; /* No overflow pages. Return without doing anything */ } @@ -41698,7 +42683,7 @@ static int fillInCell( nData = nZero = 0; } nHeader += putVarint(&pCell[nHeader], *(u64*)&nKey); - sqlite3BtreeParseCellPtr(pPage, pCell, &info); + btreeParseCellPtr(pPage, pCell, &info); assert( info.nHeader==nHeader ); assert( info.nKey==nKey ); assert( info.nData==(u32)(nData+nZero) ); @@ -41710,8 +42695,8 @@ static int fillInCell( nSrc = nData; nData = 0; }else{ - if( nKey>0x7fffffff || pKey==0 ){ - return SQLITE_CORRUPT; + if( NEVER(nKey>0x7fffffff || pKey==0) ){ + return SQLITE_CORRUPT_BKPT; } nPayload += (int)nKey; pSrc = pKey; @@ -41748,7 +42733,7 @@ static int fillInCell( */ if( pBt->autoVacuum && rc==SQLITE_OK ){ u8 eType = (pgnoPtrmap?PTRMAP_OVERFLOW2:PTRMAP_OVERFLOW1); - rc = ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap); + ptrmapPut(pBt, pgnoOvfl, eType, pgnoPtrmap, &rc); if( rc ){ releasePage(pOvfl); } @@ -41817,12 +42802,15 @@ static int fillInCell( ** ** "sz" must be the number of bytes in the cell. */ -static int dropCell(MemPage *pPage, int idx, int sz){ +static void dropCell(MemPage *pPage, int idx, int sz, int *pRC){ int i; /* Loop counter */ int pc; /* Offset to cell content of cell being deleted */ u8 *data; /* pPage->aData */ u8 *ptr; /* Used to move bytes around within data[] */ int rc; /* The return code */ + int hdr; /* Beginning of the header. 0 most pages. 100 page 1 */ + + if( *pRC ) return; assert( idx>=0 && idxnCell ); assert( sz==cellSize(pPage, idx) ); @@ -41831,22 +42819,25 @@ static int dropCell(MemPage *pPage, int idx, int sz){ data = pPage->aData; ptr = &data[pPage->cellOffset + 2*idx]; pc = get2byte(ptr); - if( (pchdrOffset+6+(pPage->leaf?0:4)) - || (pc+sz>pPage->pBt->usableSize) ){ - return SQLITE_CORRUPT_BKPT; + hdr = pPage->hdrOffset; + testcase( pc==get2byte(&data[hdr+5]) ); + testcase( pc+sz==pPage->pBt->usableSize ); + if( pc < get2byte(&data[hdr+5]) || pc+sz > pPage->pBt->usableSize ){ + *pRC = SQLITE_CORRUPT_BKPT; + return; } rc = freeSpace(pPage, pc, sz); - if( rc!=SQLITE_OK ){ - return rc; + if( rc ){ + *pRC = rc; + return; } for(i=idx+1; inCell; i++, ptr+=2){ ptr[0] = ptr[2]; ptr[1] = ptr[3]; } pPage->nCell--; - put2byte(&data[pPage->hdrOffset+3], pPage->nCell); + put2byte(&data[hdr+3], pPage->nCell); pPage->nFree += 2; - return SQLITE_OK; } /* @@ -41866,24 +42857,27 @@ static int dropCell(MemPage *pPage, int idx, int sz){ ** nSkip is non-zero, then pCell may not point to an invalid memory location ** (but pCell+nSkip is always valid). */ -static int insertCell( +static void insertCell( MemPage *pPage, /* Page into which we are copying */ int i, /* New cell becomes the i-th cell of the page */ u8 *pCell, /* Content of the new cell */ int sz, /* Bytes of content in pCell */ u8 *pTemp, /* Temp storage space for pCell, if needed */ - u8 nSkip /* Do not write the first nSkip bytes of the cell */ + Pgno iChild, /* If non-zero, replace first 4 bytes with this value */ + int *pRC /* Read and write return code from here */ ){ int idx; /* Where to write new cell content in data[] */ int j; /* Loop counter */ - int top; /* First byte of content for any cell in data[] */ int end; /* First byte past the last cell pointer in data[] */ int ins; /* Index in data[] where new cell pointer is inserted */ - int hdr; /* Offset into data[] of the page header */ int cellOffset; /* Address of first cell pointer in data[] */ u8 *data; /* The content of the whole page */ u8 *ptr; /* Used for moving information around in data[] */ + int nSkip = (iChild ? 4 : 0); + + if( *pRC ) return; + assert( i>=0 && i<=pPage->nCell+pPage->nOverflow ); assert( pPage->nCell<=MX_CELL(pPage->pBt) && MX_CELL(pPage->pBt)<=5460 ); assert( pPage->nOverflow<=ArraySize(pPage->aOvfl) ); @@ -41894,6 +42888,9 @@ static int insertCell( memcpy(pTemp+nSkip, pCell+nSkip, sz-nSkip); pCell = pTemp; } + if( iChild ){ + put4byte(pCell, iChild); + } j = pPage->nOverflow++; assert( j<(int)(sizeof(pPage->aOvfl)/sizeof(pPage->aOvfl[0])) ); pPage->aOvfl[j].pCell = pCell; @@ -41901,56 +42898,41 @@ static int insertCell( }else{ int rc = sqlite3PagerWrite(pPage->pDbPage); if( rc!=SQLITE_OK ){ - return rc; + *pRC = rc; + return; } assert( sqlite3PagerIswriteable(pPage->pDbPage) ); data = pPage->aData; - hdr = pPage->hdrOffset; - top = get2byte(&data[hdr+5]); cellOffset = pPage->cellOffset; - end = cellOffset + 2*pPage->nCell + 2; + end = cellOffset + 2*pPage->nCell; ins = cellOffset + 2*i; - if( end > top - sz ){ - rc = defragmentPage(pPage); - if( rc!=SQLITE_OK ){ - return rc; - } - top = get2byte(&data[hdr+5]); - assert( end + sz <= top ); - } - idx = allocateSpace(pPage, sz); - assert( idx>0 ); - assert( end <= get2byte(&data[hdr+5]) ); - if (idx+sz > pPage->pBt->usableSize) { - return SQLITE_CORRUPT_BKPT; - } + rc = allocateSpace(pPage, sz, &idx); + if( rc ){ *pRC = rc; return; } + /* The allocateSpace() routine guarantees the following two properties + ** if it returns success */ + assert( idx >= end+2 ); + assert( idx+sz <= pPage->pBt->usableSize ); pPage->nCell++; - pPage->nFree -= 2; + pPage->nFree -= (u16)(2 + sz); memcpy(&data[idx+nSkip], pCell+nSkip, sz-nSkip); - for(j=end-2, ptr=&data[j]; j>ins; j-=2, ptr-=2){ + if( iChild ){ + put4byte(&data[idx], iChild); + } + for(j=end, ptr=&data[j]; j>ins; j-=2, ptr-=2){ ptr[0] = ptr[-2]; ptr[1] = ptr[-1]; } put2byte(&data[ins], idx); - put2byte(&data[hdr+3], pPage->nCell); + put2byte(&data[pPage->hdrOffset+3], pPage->nCell); #ifndef SQLITE_OMIT_AUTOVACUUM if( pPage->pBt->autoVacuum ){ /* The cell may contain a pointer to an overflow page. If so, write ** the entry for the overflow page into the pointer map. */ - CellInfo info; - sqlite3BtreeParseCellPtr(pPage, pCell, &info); - assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload ); - if( info.iOverflow ){ - Pgno pgnoOvfl = get4byte(&pCell[info.iOverflow]); - rc = ptrmapPut(pPage->pBt, pgnoOvfl, PTRMAP_OVERFLOW1, pPage->pgno); - if( rc!=SQLITE_OK ) return rc; - } + ptrmapPutOvflPtr(pPage, pCell, pRC); } #endif } - - return SQLITE_OK; } /* @@ -42016,7 +42998,7 @@ static void assemblePage( ** tree, in other words, when the new entry will become the largest ** entry in the tree. ** -** Instead of trying balance the 3 right-most leaf pages, just add +** Instead of trying to balance the 3 right-most leaf pages, just add ** a new page to the right-hand side and put the one new entry in ** that page. This leaves the right side of the tree somewhat ** unbalanced. But odds are that we will be inserting new entries @@ -42035,7 +43017,7 @@ static void assemblePage( */ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ BtShared *const pBt = pPage->pBt; /* B-Tree Database */ - MemPage *pNew = 0; /* Newly allocated page */ + MemPage *pNew; /* Newly allocated page */ int rc; /* Return Code */ Pgno pgnoNew; /* Page number of pNew */ @@ -42050,6 +43032,7 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ ** may be inserted. If both these operations are successful, proceed. */ rc = allocateBtreePage(pBt, &pNew, &pgnoNew, 0, 0); + if( rc==SQLITE_OK ){ u8 *pOut = &pSpace[4]; @@ -42061,6 +43044,22 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ assert( pPage->aData[0]==(PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF) ); zeroPage(pNew, PTF_INTKEY|PTF_LEAFDATA|PTF_LEAF); assemblePage(pNew, 1, &pCell, &szCell); + + /* If this is an auto-vacuum database, update the pointer map + ** with entries for the new page, and any pointer from the + ** cell on the page to an overflow page. If either of these + ** operations fails, the return code is set, but the contents + ** of the parent page are still manipulated by thh code below. + ** That is Ok, at this point the parent page is guaranteed to + ** be marked as dirty. Returning an error code will cause a + ** rollback, undoing any changes made to the parent page. + */ + if( ISAUTOVACUUM ){ + ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno, &rc); + if( szCell>pNew->minLocal ){ + ptrmapPutOvflPtr(pNew, pCell, &rc); + } + } /* Create a divider cell to insert into pParent. The divider cell ** consists of a 4-byte page number (the page number of pPage) and @@ -42075,30 +43074,19 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ ** field. The second while(...) loop copies the key value from the ** cell on pPage into the pSpace buffer. */ - put4byte(pSpace, pPage->pgno); pCell = findCell(pPage, pPage->nCell-1); pStop = &pCell[9]; while( (*(pCell++)&0x80) && pCellnCell, pSpace, (int)(pOut-pSpace), 0, 0); + /* Insert the new divider cell into pParent. */ + insertCell(pParent, pParent->nCell, pSpace, (int)(pOut-pSpace), + 0, pPage->pgno, &rc); /* Set the right-child pointer of pParent to point to the new page. */ put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); - /* If this is an auto-vacuum database, update the pointer map - ** with entries for the new page, and any pointer from the - ** cell on the page to an overflow page. - */ - if( ISAUTOVACUUM ){ - rc = ptrmapPut(pBt, pgnoNew, PTRMAP_BTREE, pParent->pgno); - if( rc==SQLITE_OK ){ - rc = ptrmapPutOvfl(pNew, 0); - } - } - /* Release the reference to the new page. */ releasePage(pNew); } @@ -42107,45 +43095,156 @@ static int balance_quick(MemPage *pParent, MemPage *pPage, u8 *pSpace){ } #endif /* SQLITE_OMIT_QUICKBALANCE */ +#if 0 +/* +** This function does not contribute anything to the operation of SQLite. +** it is sometimes activated temporarily while debugging code responsible +** for setting pointer-map entries. +*/ +static int ptrmapCheckPages(MemPage **apPage, int nPage){ + int i, j; + for(i=0; ipBt; + assert( pPage->isInit ); + + for(j=0; jnCell; j++){ + CellInfo info; + u8 *z; + + z = findCell(pPage, j); + btreeParseCellPtr(pPage, z, &info); + if( info.iOverflow ){ + Pgno ovfl = get4byte(&z[info.iOverflow]); + ptrmapGet(pBt, ovfl, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_OVERFLOW1 ); + } + if( !pPage->leaf ){ + Pgno child = get4byte(z); + ptrmapGet(pBt, child, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_BTREE ); + } + } + if( !pPage->leaf ){ + Pgno child = get4byte(&pPage->aData[pPage->hdrOffset+8]); + ptrmapGet(pBt, child, &e, &n); + assert( n==pPage->pgno && e==PTRMAP_BTREE ); + } + } + return 1; +} +#endif + /* -** This routine redistributes Cells on pPage and up to NN*2 siblings -** of pPage so that all pages have about the same amount of free space. -** Usually NN siblings on either side of pPage is used in the balancing, -** though more siblings might come from one side if pPage is the first -** or last child of its parent. If pPage has fewer than 2*NN siblings -** (something which can only happen if pPage is the root page or a -** child of root) then all available siblings participate in the balancing. +** This function is used to copy the contents of the b-tree node stored +** on page pFrom to page pTo. If page pFrom was not a leaf page, then +** the pointer-map entries for each child page are updated so that the +** parent page stored in the pointer map is page pTo. If pFrom contained +** any cells with overflow page pointers, then the corresponding pointer +** map entries are also updated so that the parent page is page pTo. ** -** The number of siblings of pPage might be increased or decreased by one or -** two in an effort to keep pages nearly full but not over full. The root page -** is special and is allowed to be nearly empty. If pPage is -** the root page, then the depth of the tree might be increased -** or decreased by one, as necessary, to keep the root page from being -** overfull or completely empty. +** If pFrom is currently carrying any overflow cells (entries in the +** MemPage.aOvfl[] array), they are not copied to pTo. ** -** Note that when this routine is called, some of the Cells on pPage -** might not actually be stored in pPage->aData[]. This can happen -** if the page is overfull. Part of the job of this routine is to -** make sure all Cells for pPage once again fit in pPage->aData[]. +** Before returning, page pTo is reinitialized using btreeInitPage(). ** -** In the course of balancing the siblings of pPage, the parent of pPage -** might become overfull or underfull. If that happens, then this routine -** is called recursively on the parent. +** The performance of this function is not critical. It is only used by +** the balance_shallower() and balance_deeper() procedures, neither of +** which are called often under normal circumstances. +*/ +static void copyNodeContent(MemPage *pFrom, MemPage *pTo, int *pRC){ + if( (*pRC)==SQLITE_OK ){ + BtShared * const pBt = pFrom->pBt; + u8 * const aFrom = pFrom->aData; + u8 * const aTo = pTo->aData; + int const iFromHdr = pFrom->hdrOffset; + int const iToHdr = ((pTo->pgno==1) ? 100 : 0); + TESTONLY(int rc;) + int iData; + + + assert( pFrom->isInit ); + assert( pFrom->nFree>=iToHdr ); + assert( get2byte(&aFrom[iFromHdr+5])<=pBt->usableSize ); + + /* Copy the b-tree node content from page pFrom to page pTo. */ + iData = get2byte(&aFrom[iFromHdr+5]); + memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData); + memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell); + + /* Reinitialize page pTo so that the contents of the MemPage structure + ** match the new data. The initialization of pTo "cannot" fail, as the + ** data copied from pFrom is known to be valid. */ + pTo->isInit = 0; + TESTONLY(rc = ) btreeInitPage(pTo); + assert( rc==SQLITE_OK ); + + /* If this is an auto-vacuum database, update the pointer-map entries + ** for any b-tree or overflow pages that pTo now contains the pointers to. + */ + if( ISAUTOVACUUM ){ + *pRC = setChildPtrmaps(pTo); + } + } +} + +/* +** This routine redistributes cells on the iParentIdx'th child of pParent +** (hereafter "the page") and up to 2 siblings so that all pages have about the +** same amount of free space. Usually a single sibling on either side of the +** page are used in the balancing, though both siblings might come from one +** side if the page is the first or last child of its parent. If the page +** has fewer than 2 siblings (something which can only happen if the page +** is a root page or a child of a root page) then all available siblings +** participate in the balancing. +** +** The number of siblings of the page might be increased or decreased by +** one or two in an effort to keep pages nearly full but not over full. +** +** Note that when this routine is called, some of the cells on the page +** might not actually be stored in MemPage.aData[]. This can happen +** if the page is overfull. This routine ensures that all cells allocated +** to the page and its siblings fit into MemPage.aData[] before returning. +** +** In the course of balancing the page and its siblings, cells may be +** inserted into or removed from the parent page (pParent). Doing so +** may cause the parent page to become overfull or underfull. If this +** happens, it is the responsibility of the caller to invoke the correct +** balancing routine to fix this problem (see the balance() routine). ** ** If this routine fails for any reason, it might leave the database ** in a corrupted state. So if this routine fails, the database should ** be rolled back. -*/ -static int balance_nonroot(MemPage *pParent, int iParentIdx, u8 *aOvflSpace){ +** +** The third argument to this function, aOvflSpace, is a pointer to a +** buffer big enough to hold one page. If while inserting cells into the parent +** page (pParent) the parent page becomes overfull, this buffer is +** used to store the parent's overflow cells. Because this function inserts +** a maximum of four divider cells into the parent page, and the maximum +** size of a cell stored within an internal node is always less than 1/4 +** of the page-size, the aOvflSpace[] buffer is guaranteed to be large +** enough for all overflow cells. +** +** If aOvflSpace is set to a null pointer, this function returns +** SQLITE_NOMEM. +*/ +static int balance_nonroot( + MemPage *pParent, /* Parent page of siblings being balanced */ + int iParentIdx, /* Index of "the page" in pParent */ + u8 *aOvflSpace, /* page-size bytes of space for parent ovfl */ + int isRoot /* True if pParent is a root-page */ +){ BtShared *pBt; /* The whole database */ int nCell = 0; /* Number of cells in apCell[] */ int nMaxCells = 0; /* Allocated size of apCell, szCell, aFrom. */ - int nOld = 0; /* Number of pages in apOld[] */ int nNew = 0; /* Number of pages in apNew[] */ + int nOld; /* Number of pages in apOld[] */ int i, j, k; /* Loop counters */ int nxDiv; /* Next divider slot in pParent->aCell[] */ - int rc; /* The return code */ - int leafCorrection; /* 4 if pPage is a leaf. 0 if not */ + int rc = SQLITE_OK; /* The return code */ + u16 leafCorrection; /* 4 if pPage is a leaf. 0 if not */ int leafData; /* True if pPage is a leaf of a LEAFDATA tree */ int usableSpace; /* Bytes in pPage beyond the header */ int pageFlags; /* Value of pPage->aData[0] */ @@ -42154,54 +43253,106 @@ static int balance_nonroot(MemPage *pParent, int iParentIdx, u8 *aOvflSpace){ int iOvflSpace = 0; /* First unused byte of aOvflSpace[] */ int szScratch; /* Size of scratch memory requested */ MemPage *apOld[NB]; /* pPage and up to two siblings */ - Pgno pgnoOld[NB]; /* Page numbers for each page in apOld[] */ MemPage *apCopy[NB]; /* Private copies of apOld[] pages */ MemPage *apNew[NB+2]; /* pPage and up to NB siblings after balancing */ - Pgno pgnoNew[NB+2]; /* Page numbers for each page in apNew[] */ - u8 *apDiv[NB]; /* Divider cells in pParent */ + u8 *pRight; /* Location in parent of right-sibling pointer */ + u8 *apDiv[NB-1]; /* Divider cells in pParent */ int cntNew[NB+2]; /* Index in aCell[] of cell after i-th page */ int szNew[NB+2]; /* Combined size of cells place on i-th page */ u8 **apCell = 0; /* All cells begin balanced */ u16 *szCell; /* Local size of all cells in apCell[] */ - u8 *aCopy[NB]; /* Space for holding data of apCopy[] */ - u8 *aSpace1; /* Space for copies of dividers cells before balance */ - u8 *aFrom = 0; + u8 *aSpace1; /* Space for copies of dividers cells */ + Pgno pgno; /* Temp var to store a page number in */ pBt = pParent->pBt; assert( sqlite3_mutex_held(pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); +#if 0 TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno)); +#endif + + /* At this point pParent may have at most one overflow cell. And if + ** this overflow cell is present, it must be the cell with + ** index iParentIdx. This scenario comes about when this function + ** is called (indirectly) from sqlite3BtreeDelete(). + */ + assert( pParent->nOverflow==0 || pParent->nOverflow==1 ); + assert( pParent->nOverflow==0 || pParent->aOvfl[0].idx==iParentIdx ); + + if( !aOvflSpace ){ + return SQLITE_NOMEM; + } /* Find the sibling pages to balance. Also locate the cells in pParent ** that divide the siblings. An attempt is made to find NN siblings on ** either side of pPage. More siblings are taken from one side, however, ** if there are fewer than NN siblings on the other side. If pParent - ** has NB or fewer children then all children of pParent are taken. + ** has NB or fewer children then all children of pParent are taken. + ** + ** This loop also drops the divider cells from the parent page. This + ** way, the remainder of the function does not have to deal with any + ** overflow cells in the parent page, since if any existed they will + ** have already been removed. */ - nxDiv = iParentIdx - NN; - if( nxDiv + NB > pParent->nCell ){ - nxDiv = pParent->nCell - NB + 1; - } - if( nxDiv<0 ){ + i = pParent->nOverflow + pParent->nCell; + if( i<2 ){ nxDiv = 0; - } - for(i=0, k=nxDiv; inCell ){ - apDiv[i] = findCell(pParent, k); - assert( !pParent->leaf ); - pgnoOld[i] = get4byte(apDiv[i]); - }else if( k==pParent->nCell ){ - pgnoOld[i] = get4byte(&pParent->aData[pParent->hdrOffset+8]); + nOld = i+1; + }else{ + nOld = 3; + if( iParentIdx==0 ){ + nxDiv = 0; + }else if( iParentIdx==i ){ + nxDiv = i-2; }else{ - break; + nxDiv = iParentIdx-1; + } + i = 2; + } + if( (i+nxDiv-pParent->nOverflow)==pParent->nCell ){ + pRight = &pParent->aData[pParent->hdrOffset+8]; + }else{ + pRight = findCell(pParent, i+nxDiv-pParent->nOverflow); + } + pgno = get4byte(pRight); + while( 1 ){ + rc = getAndInitPage(pBt, pgno, &apOld[i]); + if( rc ){ + memset(apOld, 0, (i+1)*sizeof(MemPage*)); + goto balance_cleanup; } - rc = getAndInitPage(pBt, pgnoOld[i], &apOld[i]); - if( rc ) goto balance_cleanup; - apCopy[i] = 0; - assert( i==nOld ); - nOld++; nMaxCells += 1+apOld[i]->nCell+apOld[i]->nOverflow; + if( (i--)==0 ) break; + + if( i+nxDiv==pParent->aOvfl[0].idx && pParent->nOverflow ){ + apDiv[i] = pParent->aOvfl[0].pCell; + pgno = get4byte(apDiv[i]); + szNew[i] = cellSizePtr(pParent, apDiv[i]); + pParent->nOverflow = 0; + }else{ + apDiv[i] = findCell(pParent, i+nxDiv-pParent->nOverflow); + pgno = get4byte(apDiv[i]); + szNew[i] = cellSizePtr(pParent, apDiv[i]); + + /* Drop the cell from the parent page. apDiv[i] still points to + ** the cell within the parent, even though it has been dropped. + ** This is safe because dropping a cell only overwrites the first + ** four bytes of it, and this function does not need the first + ** four bytes of the divider cell. So the pointer is safe to use + ** later on. + ** + ** Unless SQLite is compiled in secure-delete mode. In this case, + ** the dropCell() routine will overwrite the entire cell with zeroes. + ** In this case, temporarily copy the cell into the aOvflSpace[] + ** buffer. It will be copied out again as soon as the aSpace[] buffer + ** is allocated. */ +#ifdef SQLITE_SECURE_DELETE + memcpy(&aOvflSpace[apDiv[i]-pParent->aData], apDiv[i], szNew[i]); + apDiv[i] = &aOvflSpace[apDiv[i]-pParent->aData]; +#endif + dropCell(pParent, i+nxDiv-pParent->nOverflow, szNew[i], &rc); + } } /* Make nMaxCells a multiple of 4 in order to preserve 8-byte @@ -42211,47 +43362,25 @@ static int balance_nonroot(MemPage *pParent, int iParentIdx, u8 *aOvflSpace){ /* ** Allocate space for memory structures */ + k = pBt->pageSize + ROUND8(sizeof(MemPage)); szScratch = nMaxCells*sizeof(u8*) /* apCell */ + nMaxCells*sizeof(u16) /* szCell */ - + (ROUND8(sizeof(MemPage))+pBt->pageSize)*NB /* aCopy */ + pBt->pageSize /* aSpace1 */ - + (ISAUTOVACUUM ? nMaxCells : 0); /* aFrom */ + + k*nOld; /* Page copies (apCopy) */ apCell = sqlite3ScratchMalloc( szScratch ); - if( apCell==0 || aOvflSpace==0 ){ + if( apCell==0 ){ rc = SQLITE_NOMEM; goto balance_cleanup; } szCell = (u16*)&apCell[nMaxCells]; - aCopy[0] = (u8*)&szCell[nMaxCells]; - assert( EIGHT_BYTE_ALIGNMENT(aCopy[0]) ); - for(i=1; ipageSize+ROUND8(sizeof(MemPage))]; - assert( ((aCopy[i] - (u8*)0) & 7)==0 ); /* 8-byte alignment required */ - } - aSpace1 = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))]; + aSpace1 = (u8*)&szCell[nMaxCells]; assert( EIGHT_BYTE_ALIGNMENT(aSpace1) ); - if( ISAUTOVACUUM ){ - aFrom = &aSpace1[pBt->pageSize]; - } - - /* - ** Make copies of the content of pPage and its siblings into aOld[]. - ** The rest of this function will use data from the copies rather - ** that the original pages since the original pages will be in the - ** process of being overwritten. - */ - for(i=0; iaData = (void*)&p[1]; - memcpy(p->aData, apOld[i]->aData, pBt->pageSize); - } /* ** Load pointers to all cells on sibling pages and the divider cells ** into the local apCell[] array. Make copies of the divider cells - ** into space obtained form aSpace1[] and remove the the divider Cells + ** into space obtained from aSpace1[] and remove the the divider Cells ** from pParent. ** ** If the siblings are on leaf pages, then the child pointers of the @@ -42264,68 +43393,54 @@ static int balance_nonroot(MemPage *pParent, int iParentIdx, u8 *aOvflSpace){ ** leafCorrection: 4 if pPage is a leaf. 0 if pPage is not a leaf. ** leafData: 1 if pPage holds key+data and pParent holds only keys. */ - nCell = 0; leafCorrection = apOld[0]->leaf*4; leafData = apOld[0]->hasData; for(i=0; inCell+pOld->nOverflow; + int limit; + + /* Before doing anything else, take a copy of the i'th original sibling + ** The rest of this function will use data from the copies rather + ** that the original pages since the original pages will be in the + ** process of being overwritten. */ + MemPage *pOld = apCopy[i] = (MemPage*)&aSpace1[pBt->pageSize + k*i]; + memcpy(pOld, apOld[i], sizeof(MemPage)); + pOld->aData = (void*)&pOld[1]; + memcpy(pOld->aData, apOld[i]->aData, pBt->pageSize); + + limit = pOld->nCell+pOld->nOverflow; for(j=0; j=0 && i<6 ); - for(a=0; anOverflow; a++){ - if( pOld->aOvfl[a].pCell==apCell[nCell] ){ - aFrom[nCell] = 0xFF; - break; - } - } - } nCell++; } - if( ipageSize/4 ); + assert( iSpace1<=pBt->pageSize ); + memcpy(pTemp, apDiv[i], sz); + apCell[nCell] = pTemp+leafCorrection; + assert( leafCorrection==0 || leafCorrection==4 ); + szCell[nCell] = szCell[nCell] - leafCorrection; + if( !pOld->leaf ){ + assert( leafCorrection==0 ); + assert( pOld->hdrOffset==0 ); + /* The right pointer of the child page pOld becomes the left + ** pointer of the divider cell */ + memcpy(apCell[nCell], &pOld->aData[8], 4); }else{ - u8 *pTemp; - assert( nCellpageSize/4 ); - assert( iSpace1<=pBt->pageSize ); - memcpy(pTemp, apDiv[i], sz); - apCell[nCell] = pTemp+leafCorrection; - if( ISAUTOVACUUM ){ - aFrom[nCell] = 0xFF; - } - dropCell(pParent, nxDiv, sz); - assert( leafCorrection==0 || leafCorrection==4 ); - szCell[nCell] -= (u16)leafCorrection; - assert( get4byte(pTemp)==pgnoOld[i] ); - if( !pOld->leaf ){ - assert( leafCorrection==0 ); - /* The right pointer of the child page pOld becomes the left - ** pointer of the divider cell */ - memcpy(apCell[nCell], &pOld->aData[pOld->hdrOffset+8], 4); - }else{ - assert( leafCorrection==4 ); - if( szCell[nCell]<4 ){ - /* Do not allow any cells smaller than 4 bytes. */ - szCell[nCell] = 4; - } + assert( leafCorrection==4 ); + if( szCell[nCell]<4 ){ + /* Do not allow any cells smaller than 4 bytes. */ + szCell[nCell] = 4; } - nCell++; } + nCell++; } } @@ -42399,6 +43514,12 @@ static int balance_nonroot(MemPage *pParent, int iParentIdx, u8 *aOvflSpace){ */ assert( cntNew[0]>0 || (pParent->pgno==1 && pParent->nCell==0) ); + TRACE(("BALANCE: old: %d %d %d ", + apOld[0]->pgno, + nOld>=2 ? apOld[1]->pgno : 0, + nOld>=3 ? apOld[2]->pgno : 0 + )); + /* ** Allocate k new pages. Reuse old pages where possible. */ @@ -42411,24 +43532,31 @@ static int balance_nonroot(MemPage *pParent, int iParentIdx, u8 *aOvflSpace){ MemPage *pNew; if( ipDbPage); nNew++; if( rc ) goto balance_cleanup; }else{ assert( i>0 ); - rc = allocateBtreePage(pBt, &pNew, &pgnoNew[i], pgnoNew[i-1], 0); + rc = allocateBtreePage(pBt, &pNew, &pgno, pgno, 0); if( rc ) goto balance_cleanup; apNew[i] = pNew; nNew++; + + /* Set the pointer-map entry for the new sibling page. */ + if( ISAUTOVACUUM ){ + ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno, &rc); + if( rc!=SQLITE_OK ){ + goto balance_cleanup; + } + } } } /* Free any old pages that were not reused as new pages. */ while( ipgno; int minI = i; for(j=i+1; jpgno<(unsigned)minV ){ minI = j; - minV = pgnoNew[j]; + minV = apNew[j]->pgno; } } if( minI>i ){ int t; MemPage *pT; - t = pgnoNew[i]; + t = apNew[i]->pgno; pT = apNew[i]; - pgnoNew[i] = pgnoNew[minI]; apNew[i] = apNew[minI]; - pgnoNew[minI] = t; apNew[minI] = pT; } } - TRACE(("BALANCE: old: %d %d %d new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n", - pgnoOld[0], - nOld>=2 ? pgnoOld[1] : 0, - nOld>=3 ? pgnoOld[2] : 0, - pgnoNew[0], szNew[0], - nNew>=2 ? pgnoNew[1] : 0, nNew>=2 ? szNew[1] : 0, - nNew>=3 ? pgnoNew[2] : 0, nNew>=3 ? szNew[2] : 0, - nNew>=4 ? pgnoNew[3] : 0, nNew>=4 ? szNew[3] : 0, - nNew>=5 ? pgnoNew[4] : 0, nNew>=5 ? szNew[4] : 0)); + TRACE(("new: %d(%d) %d(%d) %d(%d) %d(%d) %d(%d)\n", + apNew[0]->pgno, szNew[0], + nNew>=2 ? apNew[1]->pgno : 0, nNew>=2 ? szNew[1] : 0, + nNew>=3 ? apNew[2]->pgno : 0, nNew>=3 ? szNew[2] : 0, + nNew>=4 ? apNew[3]->pgno : 0, nNew>=4 ? szNew[3] : 0, + nNew>=5 ? apNew[4]->pgno : 0, nNew>=5 ? szNew[4] : 0)); + + assert( sqlite3PagerIswriteable(pParent->pDbPage) ); + put4byte(pRight, apNew[nNew-1]->pgno); /* ** Evenly distribute the data in apCell[] across the new pages. @@ -42488,38 +43614,18 @@ static int balance_nonroot(MemPage *pParent, int iParentIdx, u8 *aOvflSpace){ /* Assemble the new sibling page. */ MemPage *pNew = apNew[i]; assert( jpgno==pgnoNew[i] ); zeroPage(pNew, pageFlags); assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]); assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) ); assert( pNew->nOverflow==0 ); - /* If this is an auto-vacuum database, update the pointer map entries - ** that point to the siblings that were rearranged. These can be: left - ** children of cells, the right-child of the page, or overflow pages - ** pointed to by cells. - */ - if( ISAUTOVACUUM ){ - for(k=j; kpgno!=pNew->pgno ){ - rc = ptrmapPutOvfl(pNew, k-j); - if( rc==SQLITE_OK && leafCorrection==0 ){ - rc = ptrmapPut(pBt, get4byte(apCell[k]), PTRMAP_BTREE, pNew->pgno); - } - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } - } - } - } - j = cntNew[i]; /* If the sibling page assembled above was not the right-most sibling, ** insert a divider cell into the parent page. */ - if( ileaf ){ memcpy(&pNew->aData[8], pCell, 4); - if( ISAUTOVACUUM - && (aFrom[j]==0xFF || apCopy[aFrom[j]]->pgno!=pNew->pgno) - ){ - rc = ptrmapPut(pBt, get4byte(pCell), PTRMAP_BTREE, pNew->pgno); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } - } }else if( leafData ){ /* If the tree is a leaf-data tree, and the siblings are leaves, ** then there is no divider cell in apCell[]. Instead, the divider @@ -42546,16 +43644,16 @@ static int balance_nonroot(MemPage *pParent, int iParentIdx, u8 *aOvflSpace){ */ CellInfo info; j--; - sqlite3BtreeParseCellPtr(pNew, apCell[j], &info); + btreeParseCellPtr(pNew, apCell[j], &info); pCell = pTemp; - sz = 4 + putVarint(&pCell[4], info.nKey); + sz = 4 + putVarint(&pCell[4], info.nKey); pTemp = 0; }else{ pCell -= 4; /* Obscure case for non-leaf-data trees: If the cell at pCell was ** previously stored on a leaf node, and its reported size was 4 ** bytes, then it may actually be smaller than this - ** (see sqlite3BtreeParseCellPtr(), 4 bytes is the minimum size of + ** (see btreeParseCellPtr(), 4 bytes is the minimum size of ** any cell). But it is important to pass the correct size to ** insertCell(), so reparse the cell now. ** @@ -42571,32 +43669,13 @@ static int balance_nonroot(MemPage *pParent, int iParentIdx, u8 *aOvflSpace){ iOvflSpace += sz; assert( sz<=pBt->pageSize/4 ); assert( iOvflSpace<=pBt->pageSize ); - rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4); + insertCell(pParent, nxDiv, pCell, sz, pTemp, pNew->pgno, &rc); if( rc!=SQLITE_OK ) goto balance_cleanup; assert( sqlite3PagerIswriteable(pParent->pDbPage) ); - put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno); - /* If this is an auto-vacuum database, and not a leaf-data tree, - ** then update the pointer map with an entry for the overflow page - ** that the cell just inserted points to (if any). - */ - if( ISAUTOVACUUM && !leafData ){ - rc = ptrmapPutOvfl(pParent, nxDiv); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } - } j++; nxDiv++; } - - /* Set the pointer-map entry for the new sibling page. */ - if( ISAUTOVACUUM ){ - rc = ptrmapPut(pBt, pNew->pgno, PTRMAP_BTREE, pParent->pgno); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; - } - } } assert( j==nCell ); assert( nOld>0 ); @@ -42604,34 +43683,138 @@ static int balance_nonroot(MemPage *pParent, int iParentIdx, u8 *aOvflSpace){ if( (pageFlags & PTF_LEAF)==0 ){ u8 *zChild = &apCopy[nOld-1]->aData[8]; memcpy(&apNew[nNew-1]->aData[8], zChild, 4); - if( ISAUTOVACUUM ){ - rc = ptrmapPut(pBt, get4byte(zChild), PTRMAP_BTREE, apNew[nNew-1]->pgno); - if( rc!=SQLITE_OK ){ - goto balance_cleanup; + } + + if( isRoot && pParent->nCell==0 && pParent->hdrOffset<=apNew[0]->nFree ){ + /* The root page of the b-tree now contains no cells. The only sibling + ** page is the right-child of the parent. Copy the contents of the + ** child page into the parent, decreasing the overall height of the + ** b-tree structure by one. This is described as the "balance-shallower" + ** sub-algorithm in some documentation. + ** + ** If this is an auto-vacuum database, the call to copyNodeContent() + ** sets all pointer-map entries corresponding to database image pages + ** for which the pointer is stored within the content being copied. + ** + ** The second assert below verifies that the child page is defragmented + ** (it must be, as it was just reconstructed using assemblePage()). This + ** is important if the parent page happens to be page 1 of the database + ** image. */ + assert( nNew==1 ); + assert( apNew[0]->nFree == + (get2byte(&apNew[0]->aData[5])-apNew[0]->cellOffset-apNew[0]->nCell*2) + ); + copyNodeContent(apNew[0], pParent, &rc); + freePage(apNew[0], &rc); + }else if( ISAUTOVACUUM ){ + /* Fix the pointer-map entries for all the cells that were shifted around. + ** There are several different types of pointer-map entries that need to + ** be dealt with by this routine. Some of these have been set already, but + ** many have not. The following is a summary: + ** + ** 1) The entries associated with new sibling pages that were not + ** siblings when this function was called. These have already + ** been set. We don't need to worry about old siblings that were + ** moved to the free-list - the freePage() code has taken care + ** of those. + ** + ** 2) The pointer-map entries associated with the first overflow + ** page in any overflow chains used by new divider cells. These + ** have also already been taken care of by the insertCell() code. + ** + ** 3) If the sibling pages are not leaves, then the child pages of + ** cells stored on the sibling pages may need to be updated. + ** + ** 4) If the sibling pages are not internal intkey nodes, then any + ** overflow pages used by these cells may need to be updated + ** (internal intkey nodes never contain pointers to overflow pages). + ** + ** 5) If the sibling pages are not leaves, then the pointer-map + ** entries for the right-child pages of each sibling may need + ** to be updated. + ** + ** Cases 1 and 2 are dealt with above by other code. The next + ** block deals with cases 3 and 4 and the one after that, case 5. Since + ** setting a pointer map entry is a relatively expensive operation, this + ** code only sets pointer map entries for child or overflow pages that have + ** actually moved between pages. */ + MemPage *pNew = apNew[0]; + MemPage *pOld = apCopy[0]; + int nOverflow = pOld->nOverflow; + int iNextOld = pOld->nCell + nOverflow; + int iOverflow = (nOverflow ? pOld->aOvfl[0].idx : -1); + j = 0; /* Current 'old' sibling page */ + k = 0; /* Current 'new' sibling page */ + for(i=0; inCell + pOld->nOverflow; + if( pOld->nOverflow ){ + nOverflow = pOld->nOverflow; + iOverflow = i + !leafData + pOld->aOvfl[0].idx; + } + isDivider = !leafData; + } + + assert(nOverflow>0 || iOverflowaOvfl[0].idx==pOld->aOvfl[1].idx-1); + assert(nOverflow<3 || pOld->aOvfl[1].idx==pOld->aOvfl[2].idx-1); + if( i==iOverflow ){ + isDivider = 1; + if( (--nOverflow)>0 ){ + iOverflow++; + } + } + + if( i==cntNew[k] ){ + /* Cell i is the cell immediately following the last cell on new + ** sibling page k. If the siblings are not leaf pages of an + ** intkey b-tree, then cell i is a divider cell. */ + pNew = apNew[++k]; + if( !leafData ) continue; + } + assert( jpgno!=pNew->pgno ){ + if( !leafCorrection ){ + ptrmapPut(pBt, get4byte(apCell[i]), PTRMAP_BTREE, pNew->pgno, &rc); + } + if( szCell[i]>pNew->minLocal ){ + ptrmapPutOvflPtr(pNew, apCell[i], &rc); + } } } - } - assert( sqlite3PagerIswriteable(pParent->pDbPage) ); - if( nxDiv==pParent->nCell+pParent->nOverflow ){ - /* Right-most sibling is the right-most child of pParent */ - put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew[nNew-1]); - }else{ - /* Right-most sibling is the left child of the first entry in pParent - ** past the right-most divider entry */ - put4byte(findOverflowCell(pParent, nxDiv), pgnoNew[nNew-1]); + + if( !leafCorrection ){ + for(i=0; iaData[8]); + ptrmapPut(pBt, key, PTRMAP_BTREE, apNew[i]->pgno, &rc); + } + } + +#if 0 + /* The ptrmapCheckPages() contains assert() statements that verify that + ** all pointer map pages are set correctly. This is helpful while + ** debugging. This is usually disabled because a corrupt database may + ** cause an assert() statement to fail. */ + ptrmapCheckPages(apNew, nNew); + ptrmapCheckPages(&pParent, 1); +#endif } - /* - ** Balance the parent page. Note that the current page (pPage) might - ** have been added to the freelist so it might no longer be initialized. - ** But the parent page will always be initialized. - */ assert( pParent->isInit ); - sqlite3ScratchFree(apCell); - apCell = 0; - TRACE(("BALANCE: finished with %d: old=%d new=%d cells=%d\n", - pPage->pgno, nOld, nNew, nCell)); - + TRACE(("BALANCE: finished: old=%d new=%d cells=%d\n", + nOld, nNew, nCell)); + /* ** Cleanup before returning. */ @@ -42647,109 +43830,6 @@ balance_cleanup: return rc; } -/* -** This function is used to copy the contents of the b-tree node stored -** on page pFrom to page pTo. If page pFrom was not a leaf page, then -** the pointer-map entries for each child page are updated so that the -** parent page stored in the pointer map is page pTo. If pFrom contained -** any cells with overflow page pointers, then the corresponding pointer -** map entries are also updated so that the parent page is page pTo. -** -** If pFrom is currently carrying any overflow cells (entries in the -** MemPage.aOvfl[] array), they are not copied to pTo. -** -** Before returning, page pTo is reinitialized using sqlite3BtreeInitPage(). -** -** The performance of this function is not critical. It is only used by -** the balance_shallower() and balance_deeper() procedures, neither of -** which are called often under normal circumstances. -*/ -static int copyNodeContent(MemPage *pFrom, MemPage *pTo){ - BtShared * const pBt = pFrom->pBt; - u8 * const aFrom = pFrom->aData; - u8 * const aTo = pTo->aData; - int const iFromHdr = pFrom->hdrOffset; - int const iToHdr = ((pTo->pgno==1) ? 100 : 0); - int rc = SQLITE_OK; - int iData; - - assert( pFrom->isInit ); - assert( pFrom->nFree>=iToHdr ); - assert( get2byte(&aFrom[iFromHdr+5])<=pBt->usableSize ); - - /* Copy the b-tree node content from page pFrom to page pTo. */ - iData = get2byte(&aFrom[iFromHdr+5]); - memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData); - memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell); - - /* Reinitialize page pTo so that the contents of the MemPage structure - ** match the new data. The initialization of pTo "cannot" fail, as the - ** data copied from pFrom is known to be valid. */ - pTo->isInit = 0; - TESTONLY(rc = ) sqlite3BtreeInitPage(pTo); - assert( rc==SQLITE_OK ); - - /* If this is an auto-vacuum database, update the pointer-map entries - ** for any b-tree or overflow pages that pTo now contains the pointers to. */ - if( ISAUTOVACUUM ){ - rc = setChildPtrmaps(pTo); - } - return rc; -} - -/* -** This routine is called on the root page of a btree when the root -** page contains no cells. This is an opportunity to make the tree -** shallower by one level. -*/ -static int balance_shallower(MemPage *pRoot){ - /* The root page is empty but has one child. Transfer the - ** information from that one child into the root page if it - ** will fit. This reduces the depth of the tree by one. - ** - ** If the root page is page 1, it has less space available than - ** its child (due to the 100 byte header that occurs at the beginning - ** of the database fle), so it might not be able to hold all of the - ** information currently contained in the child. If this is the - ** case, then do not do the transfer. Leave page 1 empty except - ** for the right-pointer to the child page. The child page becomes - ** the virtual root of the tree. - */ - int rc = SQLITE_OK; /* Return code */ - int const hdr = pRoot->hdrOffset; /* Offset of root page header */ - MemPage *pChild; /* Only child of pRoot */ - Pgno const pgnoChild = get4byte(&pRoot->aData[pRoot->hdrOffset+8]); - - assert( pRoot->nCell==0 ); - assert( sqlite3_mutex_held(pRoot->pBt->mutex) ); - assert( !pRoot->leaf ); - assert( pgnoChild>0 ); - assert( pgnoChild<=pagerPagecount(pRoot->pBt) ); - assert( hdr==0 || pRoot->pgno==1 ); - - rc = sqlite3BtreeGetPage(pRoot->pBt, pgnoChild, &pChild, 0); - if( rc==SQLITE_OK ){ - if( pChild->nFree>=hdr ){ - if( hdr ){ - rc = defragmentPage(pChild); - } - if( rc==SQLITE_OK ){ - rc = copyNodeContent(pChild, pRoot); - } - if( rc==SQLITE_OK ){ - rc = freePage(pChild); - } - }else{ - /* The child has more information that will fit on the root. - ** The tree is already balanced. Do nothing. */ - TRACE(("BALANCE: child %d will not fit on page 1\n", pChild->pgno)); - } - releasePage(pChild); - } - - return rc; -} - /* ** This function is called when the root page of a b-tree structure is @@ -42773,7 +43853,7 @@ static int balance_shallower(MemPage *pRoot){ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ int rc; /* Return value from subprocedures */ MemPage *pChild = 0; /* Pointer to a new child page */ - Pgno pgnoChild; /* Page number of the new child page */ + Pgno pgnoChild = 0; /* Page number of the new child page */ BtShared *pBt = pRoot->pBt; /* The BTree */ assert( pRoot->nOverflow>0 ); @@ -42783,12 +43863,15 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ ** page that will become the new right-child of pPage. Copy the contents ** of the node stored on pRoot into the new child page. */ - if( SQLITE_OK!=(rc = sqlite3PagerWrite(pRoot->pDbPage)) - || SQLITE_OK!=(rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0)) - || SQLITE_OK!=(rc = copyNodeContent(pRoot, pChild)) - || (ISAUTOVACUUM && - SQLITE_OK!=(rc = ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno))) - ){ + rc = sqlite3PagerWrite(pRoot->pDbPage); + if( rc==SQLITE_OK ){ + rc = allocateBtreePage(pBt,&pChild,&pgnoChild,pRoot->pgno,0); + copyNodeContent(pRoot, pChild, &rc); + if( ISAUTOVACUUM ){ + ptrmapPut(pBt, pgnoChild, PTRMAP_BTREE, pRoot->pgno, &rc); + } + } + if( rc ){ *ppChild = 0; releasePage(pChild); return rc; @@ -42818,14 +43901,8 @@ static int balance_deeper(MemPage *pRoot, MemPage **ppChild){ ** routine. Balancing routines are: ** ** balance_quick() -** balance_shallower() ** balance_deeper() ** balance_nonroot() -** -** If built with SQLITE_DEBUG, pCur->pagesShuffled is set to true if -** balance_shallower(), balance_deeper() or balance_nonroot() is called. -** If none of these functions are invoked, pCur->pagesShuffled is left -** unmodified. */ static int balance(BtCursor *pCur){ int rc = SQLITE_OK; @@ -42855,21 +43932,7 @@ static int balance(BtCursor *pCur){ pCur->aiIdx[1] = 0; assert( pCur->apPage[1]->nOverflow ); } - VVA_ONLY( pCur->pagesShuffled = 1 ); }else{ - /* The root page of the b-tree is now empty. If the root-page is not - ** also a leaf page, it will have a single child page. Call - ** balance_shallower to attempt to copy the contents of the single - ** child-page into the root page (this may not be possible if the - ** root page is page 1). - ** - ** Whether or not this is possible , the tree is now balanced. - ** Therefore is no next iteration of the do-loop. - */ - if( pPage->nCell==0 && !pPage->leaf ){ - rc = balance_shallower(pPage); - VVA_ONLY( pCur->pagesShuffled = 1 ); - } break; } }else if( pPage->nOverflow==0 && pPage->nFree<=nMin ){ @@ -42923,7 +43986,7 @@ static int balance(BtCursor *pCur){ ** pSpace buffer passed to the latter call to balance_nonroot(). */ u8 *pSpace = sqlite3PageMalloc(pCur->pBt->pageSize); - rc = balance_nonroot(pParent, iIdx, pSpace); + rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1); if( pFree ){ /* If pFree is not NULL, it points to the pSpace buffer used ** by a previous call to balance_nonroot(). Its contents are @@ -42932,11 +43995,10 @@ static int balance(BtCursor *pCur){ sqlite3PageFree(pFree); } - /* The pSpace buffer will be freed after the next call to - ** balance_nonroot(), or just before this function returns, whichever - ** comes first. */ + /* The pSpace buffer will be freed after the next call to + ** balance_nonroot(), or just before this function returns, whichever + ** comes first. */ pFree = pSpace; - VVA_ONLY( pCur->pagesShuffled = 1 ); } } @@ -42954,75 +44016,6 @@ static int balance(BtCursor *pCur){ return rc; } -/* -** This routine checks all cursors that point to table pgnoRoot. -** If any of those cursors were opened with wrFlag==0 in a different -** database connection (a database connection that shares the pager -** cache with the current connection) and that other connection -** is not in the ReadUncommmitted state, then this routine returns -** SQLITE_LOCKED. -** -** As well as cursors with wrFlag==0, cursors with -** isIncrblobHandle==1 are also considered 'read' cursors because -** incremental blob cursors are used for both reading and writing. -** -** When pgnoRoot is the root page of an intkey table, this function is also -** responsible for invalidating incremental blob cursors when the table row -** on which they are opened is deleted or modified. Cursors are invalidated -** according to the following rules: -** -** 1) When BtreeClearTable() is called to completely delete the contents -** of a B-Tree table, pExclude is set to zero and parameter iRow is -** set to non-zero. In this case all incremental blob cursors open -** on the table rooted at pgnoRoot are invalidated. -** -** 2) When BtreeInsert(), BtreeDelete() or BtreePutData() is called to -** modify a table row via an SQL statement, pExclude is set to the -** write cursor used to do the modification and parameter iRow is set -** to the integer row id of the B-Tree entry being modified. Unless -** pExclude is itself an incremental blob cursor, then all incremental -** blob cursors open on row iRow of the B-Tree are invalidated. -** -** 3) If both pExclude and iRow are set to zero, no incremental blob -** cursors are invalidated. -*/ -static int checkForReadConflicts( - Btree *pBtree, /* The database file to check */ - Pgno pgnoRoot, /* Look for read cursors on this btree */ - BtCursor *pExclude, /* Ignore this cursor */ - i64 iRow /* The rowid that might be changing */ -){ - BtCursor *p; - BtShared *pBt = pBtree->pBt; - sqlite3 *db = pBtree->db; - assert( sqlite3BtreeHoldsMutex(pBtree) ); - for(p=pBt->pCursor; p; p=p->pNext){ - if( p==pExclude ) continue; - if( p->pgnoRoot!=pgnoRoot ) continue; -#ifndef SQLITE_OMIT_INCRBLOB - if( p->isIncrblobHandle && ( - (!pExclude && iRow) - || (pExclude && !pExclude->isIncrblobHandle && p->info.nKey==iRow) - )){ - p->eState = CURSOR_INVALID; - } -#endif - if( p->eState!=CURSOR_VALID ) continue; - if( p->wrFlag==0 -#ifndef SQLITE_OMIT_INCRBLOB - || p->isIncrblobHandle -#endif - ){ - sqlite3 *dbOther = p->pBtree->db; - assert(dbOther); - if( dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0 ){ - sqlite3ConnectionBlocked(db, dbOther); - return SQLITE_LOCKED_SHAREDCACHE; - } - } - } - return SQLITE_OK; -} /* ** Insert a new record into the BTree. The key is given by (pKey,nKey) @@ -43034,14 +44027,16 @@ static int checkForReadConflicts( ** ignored. For a ZERODATA table, the pData and nData are both ignored. ** ** If the seekResult parameter is non-zero, then a successful call to -** sqlite3BtreeMoveto() to seek cursor pCur to (pKey, nKey) has already +** MovetoUnpacked() to seek cursor pCur to (pKey, nKey) has already ** been performed. seekResult is the search result returned (a negative ** number if pCur points at an entry that is smaller than (pKey, nKey), or ** a positive value if pCur points at an etry that is larger than ** (pKey, nKey)). ** -** If the seekResult parameter is 0, then cursor pCur may point to any -** entry or to no entry at all. In this case this function has to seek +** If the seekResult parameter is non-zero, then the caller guarantees that +** cursor pCur is pointing at the existing copy of a row that is to be +** overwritten. If the seekResult parameter is 0, then cursor pCur may +** point to any entry or to no entry at all and so this function has to seek ** the cursor before the new key can be inserted. */ SQLITE_PRIVATE int sqlite3BtreeInsert( @@ -43050,10 +44045,10 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( const void *pData, int nData, /* The data of the new record */ int nZero, /* Number of extra 0 bytes to append to data */ int appendBias, /* True if this is likely an append */ - int seekResult /* Result of prior sqlite3BtreeMoveto() call */ + int seekResult /* Result of prior MovetoUnpacked() call */ ){ int rc; - int loc = seekResult; + int loc = seekResult; /* -1: before desired location +1: after */ int szNew; int idx; MemPage *pPage; @@ -43062,42 +44057,52 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( unsigned char *oldCell; unsigned char *newCell = 0; - assert( cursorHoldsMutex(pCur) ); - assert( pBt->inTransaction==TRANS_WRITE ); - assert( !pBt->readOnly ); - assert( pCur->wrFlag ); - rc = checkForReadConflicts(pCur->pBtree, pCur->pgnoRoot, pCur, nKey); - if( rc ){ - /* The table pCur points to has a read lock */ - assert( rc==SQLITE_LOCKED_SHAREDCACHE ); - return rc; - } if( pCur->eState==CURSOR_FAULT ){ - return pCur->skip; + assert( pCur->skipNext!=SQLITE_OK ); + return pCur->skipNext; + } + + assert( cursorHoldsMutex(pCur) ); + assert( pCur->wrFlag && pBt->inTransaction==TRANS_WRITE && !pBt->readOnly ); + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + + /* Assert that the caller has been consistent. If this cursor was opened + ** expecting an index b-tree, then the caller should be inserting blob + ** keys with no associated data. If the cursor was opened expecting an + ** intkey table, the caller should be inserting integer keys with a + ** blob of associated data. */ + assert( (pKey==0)==(pCur->pKeyInfo==0) ); + + /* If this is an insert into a table b-tree, invalidate any incrblob + ** cursors open on the row being replaced (assuming this is a replace + ** operation - if it is not, the following is a no-op). */ + if( pCur->pKeyInfo==0 ){ + invalidateIncrblobCursors(p, nKey, 0); } /* Save the positions of any other cursors open on this table. ** - ** In some cases, the call to sqlite3BtreeMoveto() below is a no-op. For + ** In some cases, the call to btreeMoveto() below is a no-op. For ** example, when inserting data into a table with auto-generated integer ** keys, the VDBE layer invokes sqlite3BtreeLast() to figure out the ** integer key to use. It then calls this function to actually insert the - ** data into the intkey B-Tree. In this case sqlite3BtreeMoveto() recognizes + ** data into the intkey B-Tree. In this case btreeMoveto() recognizes ** that the cursor is already where it needs to be and returns without ** doing any work. To avoid thwarting these optimizations, it is important ** not to clear the cursor here. */ - if( - SQLITE_OK!=(rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur)) || (!loc && - SQLITE_OK!=(rc = sqlite3BtreeMoveto(pCur, pKey, nKey, appendBias, &loc)) - )){ - return rc; + rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); + if( rc ) return rc; + if( !loc ){ + rc = btreeMoveto(pCur, pKey, nKey, appendBias, &loc); + if( rc ) return rc; } + assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) ); pPage = pCur->apPage[pCur->iPage]; assert( pPage->intKey || nKey>=0 ); - assert( pPage->intKey || nKey>=0 ); assert( pPage->leaf || !pPage->intKey ); + TRACE(("INSERT: table=%d nkey=%lld ndata=%d page=%d %s\n", pCur->pgnoRoot, nKey, nData, pPage->pgno, loc==0 ? "overwrite" : "new entry")); @@ -43110,7 +44115,7 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( assert( szNew==cellSizePtr(pPage, newCell) ); assert( szNew<=MX_CELL_SIZE(pBt) ); idx = pCur->aiIdx[pCur->iPage]; - if( loc==0 && CURSOR_VALID==pCur->eState ){ + if( loc==0 ){ u16 szOld; assert( idxnCell ); rc = sqlite3PagerWrite(pPage->pDbPage); @@ -43123,18 +44128,15 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( } szOld = cellSizePtr(pPage, oldCell); rc = clearCell(pPage, oldCell); + dropCell(pPage, idx, szOld, &rc); if( rc ) goto end_insert; - rc = dropCell(pPage, idx, szOld); - if( rc!=SQLITE_OK ) { - goto end_insert; - } }else if( loc<0 && pPage->nCell>0 ){ assert( pPage->leaf ); idx = ++pCur->aiIdx[pCur->iPage]; }else{ assert( pPage->leaf ); } - rc = insertCell(pPage, idx, newCell, szNew, 0, 0); + insertCell(pPage, idx, newCell, szNew, 0, 0, &rc); assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); /* If no error has occured and pPage has an overflow cell, call balance() @@ -43144,8 +44146,9 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( ** ** Previous versions of SQLite called moveToRoot() to move the cursor ** back to the root page as balance() used to invalidate the contents - ** of BtCursor.apPage[] and BtCursor.aiIdx[]. This is no longer necessary, - ** as balance() always leaves the cursor pointing to a valid entry. + ** of BtCursor.apPage[] and BtCursor.aiIdx[]. Instead of doing that, + ** set the cursor state to "invalid". This makes common insert operations + ** slightly faster. ** ** There is a subtle but important optimization here too. When inserting ** multiple records into an intkey b-tree using a single cursor (as can @@ -43159,12 +44162,14 @@ SQLITE_PRIVATE int sqlite3BtreeInsert( pCur->info.nSize = 0; pCur->validNKey = 0; if( rc==SQLITE_OK && pPage->nOverflow ){ - pCur->atLast = 0; rc = balance(pCur); /* Must make sure nOverflow is reset to zero even if the balance() - ** fails. Internal data structure corruption will result otherwise. */ + ** fails. Internal data structure corruption will result otherwise. + ** Also, set the cursor state to invalid. This stops saveCursorPosition() + ** from trying to save the current position of the cursor. */ pCur->apPage[pCur->iPage]->nOverflow = 0; + pCur->eState = CURSOR_INVALID; } assert( pCur->apPage[pCur->iPage]->nOverflow==0 ); @@ -43177,198 +44182,111 @@ end_insert: ** is left pointing at a arbitrary location. */ SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor *pCur){ - MemPage *pPage = pCur->apPage[pCur->iPage]; - int idx; - unsigned char *pCell; - int rc; - Pgno pgnoChild = 0; Btree *p = pCur->pBtree; - BtShared *pBt = p->pBt; + BtShared *pBt = p->pBt; + int rc; /* Return code */ + MemPage *pPage; /* Page to delete cell from */ + unsigned char *pCell; /* Pointer to cell to delete */ + int iCellIdx; /* Index of cell to delete */ + int iCellDepth; /* Depth of node containing pCell */ assert( cursorHoldsMutex(pCur) ); - assert( pPage->isInit ); assert( pBt->inTransaction==TRANS_WRITE ); assert( !pBt->readOnly ); - if( pCur->eState==CURSOR_FAULT ){ - return pCur->skip; - } - if( NEVER(pCur->aiIdx[pCur->iPage]>=pPage->nCell) ){ - return SQLITE_ERROR; /* The cursor is not pointing to anything */ - } assert( pCur->wrFlag ); - rc = checkForReadConflicts(p, pCur->pgnoRoot, pCur, pCur->info.nKey); - if( rc!=SQLITE_OK ){ - /* The table pCur points to has a read lock */ - assert( rc==SQLITE_LOCKED_SHAREDCACHE ); - return rc; - } + assert( hasSharedCacheTableLock(p, pCur->pgnoRoot, pCur->pKeyInfo!=0, 2) ); + assert( !hasReadConflicts(p, pCur->pgnoRoot) ); - /* Restore the current cursor position (a no-op if the cursor is not in - ** CURSOR_REQUIRESEEK state) and save the positions of any other cursors - ** open on the same table. Then call sqlite3PagerWrite() on the page - ** that the entry will be deleted from. - */ - if( - (rc = restoreCursorPosition(pCur))!=0 || - (rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur))!=0 || - (rc = sqlite3PagerWrite(pPage->pDbPage))!=0 + if( NEVER(pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell) + || NEVER(pCur->eState!=CURSOR_VALID) ){ - return rc; + return SQLITE_ERROR; /* Something has gone awry. */ } - /* Locate the cell within its page and leave pCell pointing to the - ** data. The clearCell() call frees any overflow pages associated with the - ** cell. The cell itself is still intact. - */ - idx = pCur->aiIdx[pCur->iPage]; - pCell = findCell(pPage, idx); + /* If this is a delete operation to remove a row from a table b-tree, + ** invalidate any incrblob cursors open on the row being deleted. */ + if( pCur->pKeyInfo==0 ){ + invalidateIncrblobCursors(p, pCur->info.nKey, 0); + } + + iCellDepth = pCur->iPage; + iCellIdx = pCur->aiIdx[iCellDepth]; + pPage = pCur->apPage[iCellDepth]; + pCell = findCell(pPage, iCellIdx); + + /* If the page containing the entry to delete is not a leaf page, move + ** the cursor to the largest entry in the tree that is smaller than + ** the entry being deleted. This cell will replace the cell being deleted + ** from the internal node. The 'previous' entry is used for this instead + ** of the 'next' entry, as the previous entry is always a part of the + ** sub-tree headed by the child page of the cell being deleted. This makes + ** balancing the tree following the delete operation easier. */ if( !pPage->leaf ){ - pgnoChild = get4byte(pCell); + int notUsed; + rc = sqlite3BtreePrevious(pCur, ¬Used); + if( rc ) return rc; } + + /* Save the positions of any other cursors open on this table before + ** making any modifications. Make the page containing the entry to be + ** deleted writable. Then free any overflow pages associated with the + ** entry and finally remove the cell itself from within the page. + */ + rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur); + if( rc ) return rc; + rc = sqlite3PagerWrite(pPage->pDbPage); + if( rc ) return rc; rc = clearCell(pPage, pCell); - if( rc ){ - return rc; - } + dropCell(pPage, iCellIdx, cellSizePtr(pPage, pCell), &rc); + if( rc ) return rc; + /* If the cell deleted was not located on a leaf page, then the cursor + ** is currently pointing to the largest entry in the sub-tree headed + ** by the child-page of the cell that was just deleted from an internal + ** node. The cell from the leaf node needs to be moved to the internal + ** node to replace the deleted cell. */ if( !pPage->leaf ){ - /* - ** The entry we are about to delete is not a leaf so if we do not - ** do something we will leave a hole on an internal page. - ** We have to fill the hole by moving in a cell from a leaf. The - ** next Cell after the one to be deleted is guaranteed to exist and - ** to be a leaf so we can use it. - */ - BtCursor leafCur; - MemPage *pLeafPage = 0; - - unsigned char *pNext; - int notUsed; - unsigned char *tempCell = 0; - assert( !pPage->intKey ); - sqlite3BtreeGetTempCursor(pCur, &leafCur); - rc = sqlite3BtreeNext(&leafCur, ¬Used); - if( rc==SQLITE_OK ){ - assert( leafCur.aiIdx[leafCur.iPage]==0 ); - pLeafPage = leafCur.apPage[leafCur.iPage]; - rc = sqlite3PagerWrite(pLeafPage->pDbPage); - } - if( rc==SQLITE_OK ){ - int leafCursorInvalid = 0; - u16 szNext; - TRACE(("DELETE: table=%d delete internal from %d replace from leaf %d\n", - pCur->pgnoRoot, pPage->pgno, pLeafPage->pgno)); - dropCell(pPage, idx, cellSizePtr(pPage, pCell)); - pNext = findCell(pLeafPage, 0); - szNext = cellSizePtr(pLeafPage, pNext); - assert( MX_CELL_SIZE(pBt)>=szNext+4 ); - allocateTempSpace(pBt); - tempCell = pBt->pTmpSpace; - if( tempCell==0 ){ - rc = SQLITE_NOMEM; - } - if( rc==SQLITE_OK ){ - rc = insertCell(pPage, idx, pNext-4, szNext+4, tempCell, 0); - } + MemPage *pLeaf = pCur->apPage[pCur->iPage]; + int nCell; + Pgno n = pCur->apPage[iCellDepth+1]->pgno; + unsigned char *pTmp; + pCell = findCell(pLeaf, pLeaf->nCell-1); + nCell = cellSizePtr(pLeaf, pCell); + assert( MX_CELL_SIZE(pBt)>=nCell ); - /* The "if" statement in the next code block is critical. The - ** slightest error in that statement would allow SQLite to operate - ** correctly most of the time but produce very rare failures. To - ** guard against this, the following macros help to verify that - ** the "if" statement is well tested. - */ - testcase( pPage->nOverflow==0 && pPage->nFreeusableSize*2/3 - && pLeafPage->nFree+2+szNext > pBt->usableSize*2/3 ); - testcase( pPage->nOverflow==0 && pPage->nFree==pBt->usableSize*2/3 - && pLeafPage->nFree+2+szNext > pBt->usableSize*2/3 ); - testcase( pPage->nOverflow==0 && pPage->nFree==pBt->usableSize*2/3+1 - && pLeafPage->nFree+2+szNext > pBt->usableSize*2/3 ); - testcase( pPage->nOverflow>0 && pPage->nFree<=pBt->usableSize*2/3 - && pLeafPage->nFree+2+szNext > pBt->usableSize*2/3 ); - testcase( (pPage->nOverflow>0 || (pPage->nFree > pBt->usableSize*2/3)) - && pLeafPage->nFree+2+szNext == pBt->usableSize*2/3 ); - - - if( (pPage->nOverflow>0 || (pPage->nFree > pBt->usableSize*2/3)) && - (pLeafPage->nFree+2+szNext > pBt->usableSize*2/3) - ){ - /* This branch is taken if the internal node is now either overflowing - ** or underfull and the leaf node will be underfull after the just cell - ** copied to the internal node is deleted from it. This is a special - ** case because the call to balance() to correct the internal node - ** may change the tree structure and invalidate the contents of - ** the leafCur.apPage[] and leafCur.aiIdx[] arrays, which will be - ** used by the balance() required to correct the underfull leaf - ** node. - ** - ** The formula used in the expression above are based on facets of - ** the SQLite file-format that do not change over time. - */ - testcase( pPage->nFree==pBt->usableSize*2/3+1 ); - testcase( pLeafPage->nFree+2+szNext==pBt->usableSize*2/3+1 ); - leafCursorInvalid = 1; - } + allocateTempSpace(pBt); + pTmp = pBt->pTmpSpace; - if( rc==SQLITE_OK ){ - assert( sqlite3PagerIswriteable(pPage->pDbPage) ); - put4byte(findOverflowCell(pPage, idx), pgnoChild); - VVA_ONLY( pCur->pagesShuffled = 0 ); - rc = balance(pCur); - } - - if( rc==SQLITE_OK && leafCursorInvalid ){ - /* The leaf-node is now underfull and so the tree needs to be - ** rebalanced. However, the balance() operation on the internal - ** node above may have modified the structure of the B-Tree and - ** so the current contents of leafCur.apPage[] and leafCur.aiIdx[] - ** may not be trusted. - ** - ** It is not possible to copy the ancestry from pCur, as the same - ** balance() call has invalidated the pCur->apPage[] and aiIdx[] - ** arrays. - ** - ** The call to saveCursorPosition() below internally saves the - ** key that leafCur is currently pointing to. Currently, there - ** are two copies of that key in the tree - one here on the leaf - ** page and one on some internal node in the tree. The copy on - ** the leaf node is always the next key in tree-order after the - ** copy on the internal node. So, the call to sqlite3BtreeNext() - ** calls restoreCursorPosition() to point the cursor to the copy - ** stored on the internal node, then advances to the next entry, - ** which happens to be the copy of the key on the internal node. - ** Net effect: leafCur is pointing back to the duplicate cell - ** that needs to be removed, and the leafCur.apPage[] and - ** leafCur.aiIdx[] arrays are correct. - */ - VVA_ONLY( Pgno leafPgno = pLeafPage->pgno ); - rc = saveCursorPosition(&leafCur); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeNext(&leafCur, ¬Used); - } - pLeafPage = leafCur.apPage[leafCur.iPage]; - assert( rc!=SQLITE_OK || pLeafPage->pgno==leafPgno ); - assert( rc!=SQLITE_OK || leafCur.aiIdx[leafCur.iPage]==0 ); - } + rc = sqlite3PagerWrite(pLeaf->pDbPage); + insertCell(pPage, iCellIdx, pCell-4, nCell+4, pTmp, n, &rc); + dropCell(pLeaf, pLeaf->nCell-1, nCell, &rc); + if( rc ) return rc; + } - if( SQLITE_OK==rc - && SQLITE_OK==(rc = sqlite3PagerWrite(pLeafPage->pDbPage)) - ){ - dropCell(pLeafPage, 0, szNext); - VVA_ONLY( leafCur.pagesShuffled = 0 ); - rc = balance(&leafCur); - assert( leafCursorInvalid || !leafCur.pagesShuffled - || !pCur->pagesShuffled ); - } - } - sqlite3BtreeReleaseTempCursor(&leafCur); - }else{ - TRACE(("DELETE: table=%d delete from leaf %d\n", - pCur->pgnoRoot, pPage->pgno)); - rc = dropCell(pPage, idx, cellSizePtr(pPage, pCell)); - if( rc==SQLITE_OK ){ - rc = balance(pCur); + /* Balance the tree. If the entry deleted was located on a leaf page, + ** then the cursor still points to that page. In this case the first + ** call to balance() repairs the tree, and the if(...) condition is + ** never true. + ** + ** Otherwise, if the entry deleted was on an internal node page, then + ** pCur is pointing to the leaf page from which a cell was removed to + ** replace the cell deleted from the internal node. This is slightly + ** tricky as the leaf node may be underfull, and the internal node may + ** be either under or overfull. In this case run the balancing algorithm + ** on the leaf node first. If the balance proceeds far enough up the + ** tree that we can be sure that any problem in the internal node has + ** been corrected, so be it. Otherwise, after balancing the leaf node, + ** walk the cursor up the tree to the internal node and balance it as + ** well. */ + rc = balance(pCur); + if( rc==SQLITE_OK && pCur->iPage>iCellDepth ){ + while( pCur->iPage>iCellDepth ){ + releasePage(pCur->apPage[pCur->iPage--]); } + rc = balance(pCur); } + if( rc==SQLITE_OK ){ moveToRoot(pCur); } @@ -43417,10 +44335,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int flags){ ** root page of the new table should go. meta[3] is the largest root-page ** created so far, so the new root-page is (meta[3]+1). */ - rc = sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); - if( rc!=SQLITE_OK ){ - return rc; - } + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &pgnoRoot); pgnoRoot++; /* The new root-page may not be allocated on a pointer-map page, or the @@ -43448,18 +44363,21 @@ static int btreeCreateTable(Btree *p, int *piTable, int flags){ ** by extending the file), the current page at position pgnoMove ** is already journaled. */ - u8 eType; - Pgno iPtrPage; + u8 eType = 0; + Pgno iPtrPage = 0; releasePage(pPageMove); /* Move the page currently at pgnoRoot to pgnoMove. */ - rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0); + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); if( rc!=SQLITE_OK ){ return rc; } rc = ptrmapGet(pBt, pgnoRoot, &eType, &iPtrPage); - if( rc!=SQLITE_OK || eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ + if( eType==PTRMAP_ROOTPAGE || eType==PTRMAP_FREEPAGE ){ + rc = SQLITE_CORRUPT_BKPT; + } + if( rc!=SQLITE_OK ){ releasePage(pRoot); return rc; } @@ -43472,7 +44390,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int flags){ if( rc!=SQLITE_OK ){ return rc; } - rc = sqlite3BtreeGetPage(pBt, pgnoRoot, &pRoot, 0); + rc = btreeGetPage(pBt, pgnoRoot, &pRoot, 0); if( rc!=SQLITE_OK ){ return rc; } @@ -43486,7 +44404,7 @@ static int btreeCreateTable(Btree *p, int *piTable, int flags){ } /* Update the pointer-map and meta-data with the new root-page number. */ - rc = ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0); + ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, &rc); if( rc ){ releasePage(pRoot); return rc; @@ -43526,7 +44444,7 @@ static int clearDatabasePage( int freePageFlag, /* Deallocate page if true */ int *pnChange ){ - MemPage *pPage = 0; + MemPage *pPage; int rc; unsigned char *pCell; int i; @@ -43537,7 +44455,7 @@ static int clearDatabasePage( } rc = getAndInitPage(pBt, pgno, &pPage); - if( rc ) goto cleardatabasepage_out; + if( rc ) return rc; for(i=0; inCell; i++){ pCell = findCell(pPage, i); if( !pPage->leaf ){ @@ -43555,7 +44473,7 @@ static int clearDatabasePage( *pnChange += pPage->nCell; } if( freePageFlag ){ - rc = freePage(pPage); + freePage(pPage, &rc); }else if( (rc = sqlite3PagerWrite(pPage->pDbPage))==0 ){ zeroPage(pPage, pPage->aData[0] | PTF_LEAF); } @@ -43583,11 +44501,14 @@ SQLITE_PRIVATE int sqlite3BtreeClearTable(Btree *p, int iTable, int *pnChange){ BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); assert( p->inTrans==TRANS_WRITE ); - if( (rc = checkForReadConflicts(p, iTable, 0, 1))!=SQLITE_OK ){ - /* nothing to do */ - }else if( SQLITE_OK!=(rc = saveAllCursors(pBt, iTable, 0)) ){ - /* nothing to do */ - }else{ + + /* Invalidate all incrblob cursors open on table iTable (assuming iTable + ** is the root of a table b-tree - if it is not, the following call is + ** a no-op). */ + invalidateIncrblobCursors(p, 0, 1); + + rc = saveAllCursors(pBt, (Pgno)iTable, 0); + if( SQLITE_OK==rc ){ rc = clearDatabasePage(pBt, (Pgno)iTable, 0, pnChange); } sqlite3BtreeLeave(p); @@ -43627,13 +44548,15 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ ** need to move another root-page to fill a gap left by the deleted ** root page. If an open cursor was using this page a problem would ** occur. + ** + ** This error is caught long before control reaches this point. */ - if( pBt->pCursor ){ + if( NEVER(pBt->pCursor) ){ sqlite3ConnectionBlocked(p->db, pBt->pCursor->pBtree->db); return SQLITE_LOCKED_SHAREDCACHE; } - rc = sqlite3BtreeGetPage(pBt, (Pgno)iTable, &pPage, 0); + rc = btreeGetPage(pBt, (Pgno)iTable, &pPage, 0); if( rc ) return rc; rc = sqlite3BtreeClearTable(p, iTable, 0); if( rc ){ @@ -43645,22 +44568,18 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ if( iTable>1 ){ #ifdef SQLITE_OMIT_AUTOVACUUM - rc = freePage(pPage); + freePage(pPage, &rc); releasePage(pPage); #else if( pBt->autoVacuum ){ Pgno maxRootPgno; - rc = sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno); - if( rc!=SQLITE_OK ){ - releasePage(pPage); - return rc; - } + sqlite3BtreeGetMeta(p, BTREE_LARGEST_ROOT_PAGE, &maxRootPgno); if( iTable==maxRootPgno ){ /* If the table being dropped is the table with the largest root-page ** number in the database, put the root page on the free list. */ - rc = freePage(pPage); + freePage(pPage, &rc); releasePage(pPage); if( rc!=SQLITE_OK ){ return rc; @@ -43672,7 +44591,7 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ */ MemPage *pMove; releasePage(pPage); - rc = sqlite3BtreeGetPage(pBt, maxRootPgno, &pMove, 0); + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); if( rc!=SQLITE_OK ){ return rc; } @@ -43681,11 +44600,9 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ if( rc!=SQLITE_OK ){ return rc; } - rc = sqlite3BtreeGetPage(pBt, maxRootPgno, &pMove, 0); - if( rc!=SQLITE_OK ){ - return rc; - } - rc = freePage(pMove); + pMove = 0; + rc = btreeGetPage(pBt, maxRootPgno, &pMove, 0); + freePage(pMove, &rc); releasePage(pMove); if( rc!=SQLITE_OK ){ return rc; @@ -43699,22 +44616,23 @@ static int btreeDropTable(Btree *p, Pgno iTable, int *piMoved){ ** PENDING_BYTE_PAGE. */ maxRootPgno--; - if( maxRootPgno==PENDING_BYTE_PAGE(pBt) ){ - maxRootPgno--; - } - if( maxRootPgno==PTRMAP_PAGENO(pBt, maxRootPgno) ){ + while( maxRootPgno==PENDING_BYTE_PAGE(pBt) + || PTRMAP_ISPAGE(pBt, maxRootPgno) ){ maxRootPgno--; } assert( maxRootPgno!=PENDING_BYTE_PAGE(pBt) ); rc = sqlite3BtreeUpdateMeta(p, 4, maxRootPgno); }else{ - rc = freePage(pPage); + freePage(pPage, &rc); releasePage(pPage); } #endif }else{ - /* If sqlite3BtreeDropTable was called on page 1. */ + /* If sqlite3BtreeDropTable was called on page 1. + ** This really never should happen except in a corrupt + ** database. + */ zeroPage(pPage, PTF_INTKEY|PTF_LEAF ); releasePage(pPage); } @@ -43730,6 +44648,9 @@ SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ /* +** This function may only be called if the b-tree connection already +** has a read or write transaction open on the database. +** ** Read the meta-information out of a database file. Meta[0] ** is the number of free pages currently in the database. Meta[1] ** through meta[15] are available for use by higher layers. Meta[0] @@ -43739,71 +44660,24 @@ SQLITE_PRIVATE int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ ** layer (and the SetCookie and ReadCookie opcodes) the number of ** free pages is not visible. So Cookie[0] is the same as Meta[1]. */ -SQLITE_PRIVATE int sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ - DbPage *pDbPage = 0; - int rc; - unsigned char *pP1; +SQLITE_PRIVATE void sqlite3BtreeGetMeta(Btree *p, int idx, u32 *pMeta){ BtShared *pBt = p->pBt; sqlite3BtreeEnter(p); - - /* Reading a meta-data value requires a read-lock on page 1 (and hence - ** the sqlite_master table. We grab this lock regardless of whether or - ** not the SQLITE_ReadUncommitted flag is set (the table rooted at page - ** 1 is treated as a special case by querySharedCacheTableLock() - ** and setSharedCacheTableLock()). - */ - rc = querySharedCacheTableLock(p, 1, READ_LOCK); - if( rc!=SQLITE_OK ){ - sqlite3BtreeLeave(p); - return rc; - } - + assert( p->inTrans>TRANS_NONE ); + assert( SQLITE_OK==querySharedCacheTableLock(p, MASTER_ROOT, READ_LOCK) ); + assert( pBt->pPage1 ); assert( idx>=0 && idx<=15 ); - if( pBt->pPage1 ){ - /* The b-tree is already holding a reference to page 1 of the database - ** file. In this case the required meta-data value can be read directly - ** from the page data of this reference. This is slightly faster than - ** requesting a new reference from the pager layer. - */ - pP1 = (unsigned char *)pBt->pPage1->aData; - }else{ - /* The b-tree does not have a reference to page 1 of the database file. - ** Obtain one from the pager layer. - */ - rc = sqlite3PagerGet(pBt->pPager, 1, &pDbPage); - if( rc ){ - sqlite3BtreeLeave(p); - return rc; - } - pP1 = (unsigned char *)sqlite3PagerGetData(pDbPage); - } - *pMeta = get4byte(&pP1[36 + idx*4]); - /* If the b-tree is not holding a reference to page 1, then one was - ** requested from the pager layer in the above block. Release it now. - */ - if( !pBt->pPage1 ){ - sqlite3PagerUnref(pDbPage); - } + *pMeta = get4byte(&pBt->pPage1->aData[36 + idx*4]); - /* If autovacuumed is disabled in this build but we are trying to - ** access an autovacuumed database, then make the database readonly. - */ + /* If auto-vacuum is disabled in this build and this is an auto-vacuum + ** database, mark the database as read-only. */ #ifdef SQLITE_OMIT_AUTOVACUUM if( idx==BTREE_LARGEST_ROOT_PAGE && *pMeta>0 ) pBt->readOnly = 1; #endif - /* If there is currently an open transaction, grab a read-lock - ** on page 1 of the database file. This is done to make sure that - ** no other connection can modify the meta value just read from - ** the database until the transaction is concluded. - */ - if( p->inTrans>0 ){ - rc = setSharedCacheTableLock(p, 1, READ_LOCK); - } sqlite3BtreeLeave(p); - return rc; } /* @@ -43834,23 +44708,6 @@ SQLITE_PRIVATE int sqlite3BtreeUpdateMeta(Btree *p, int idx, u32 iMeta){ return rc; } -/* -** Return the flag byte at the beginning of the page that the cursor -** is currently pointing to. -*/ -SQLITE_PRIVATE int sqlite3BtreeFlags(BtCursor *pCur){ - /* TODO: What about CURSOR_REQUIRESEEK state? Probably need to call - ** restoreCursorPosition() here. - */ - MemPage *pPage; - restoreCursorPosition(pCur); - pPage = pCur->apPage[pCur->iPage]; - assert( cursorHoldsMutex(pCur) ); - assert( pPage!=0 ); - assert( pPage->pBt==pCur->pBt ); - return pPage->aData[pPage->hdrOffset]; -} - #ifndef SQLITE_OMIT_BTREECOUNT /* ** The first argument, pCur, is a cursor opened on some b-tree. Count the @@ -43898,7 +44755,7 @@ SQLITE_PRIVATE int sqlite3BtreeCount(BtCursor *pCur, i64 *pnEntry){ *pnEntry = nEntry; return SQLITE_OK; } - sqlite3BtreeMoveToParent(pCur); + moveToParent(pCur); }while ( pCur->aiIdx[pCur->iPage]>=pCur->apPage[pCur->iPage]->nCell ); pCur->aiIdx[pCur->iPage]++; @@ -44125,16 +44982,19 @@ static int checkTreePage( usableSize = pBt->usableSize; if( iPage==0 ) return 0; if( checkRef(pCheck, iPage, zParentContext) ) return 0; - if( (rc = sqlite3BtreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){ - if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ) pCheck->mallocFailed = 1; + if( (rc = btreeGetPage(pBt, (Pgno)iPage, &pPage, 0))!=0 ){ checkAppendMsg(pCheck, zContext, "unable to get the page. error code=%d", rc); return 0; } - if( (rc = sqlite3BtreeInitPage(pPage))!=0 ){ + + /* Clear MemPage.isInit to make sure the corruption detection code in + ** btreeInitPage() is executed. */ + pPage->isInit = 0; + if( (rc = btreeInitPage(pPage))!=0 ){ assert( rc==SQLITE_CORRUPT ); /* The only possible error from InitPage */ checkAppendMsg(pCheck, zContext, - "sqlite3BtreeInitPage() returns error code %d", rc); + "btreeInitPage() returns error code %d", rc); releasePage(pPage); return 0; } @@ -44152,7 +45012,7 @@ static int checkTreePage( sqlite3_snprintf(sizeof(zContext), zContext, "On tree page %d cell %d: ", iPage, i); pCell = findCell(pPage,i); - sqlite3BtreeParseCellPtr(pPage, pCell, &info); + btreeParseCellPtr(pPage, pCell, &info); sz = info.nData; if( !pPage->intKey ) sz += (int)info.nKey; assert( sz==info.nPayload ); @@ -44206,11 +45066,7 @@ static int checkTreePage( pCheck->mallocFailed = 1; }else{ u16 contentOffset = get2byte(&data[hdr+5]); - if (contentOffset > usableSize) { - checkAppendMsg(pCheck, 0, - "Corruption detected in header on page %d",iPage,0); - goto check_page_abort; - } + assert( contentOffset<=usableSize ); /* Enforced by btreeInitPage() */ memset(hit+contentOffset, 0, usableSize-contentOffset); memset(hit, 1, contentOffset); nCell = get2byte(&data[hdr+3]); @@ -44219,27 +45075,27 @@ static int checkTreePage( int pc = get2byte(&data[cellStart+i*2]); u16 size = 1024; int j; - if( pc<=usableSize ){ + if( pc<=usableSize-4 ){ size = cellSizePtr(pPage, &data[pc]); } - if( (pc+size-1)>=usableSize || pc<0 ){ + if( (pc+size-1)>=usableSize ){ checkAppendMsg(pCheck, 0, "Corruption detected in cell %d on page %d",i,iPage,0); }else{ for(j=pc+size-1; j>=pc; j--) hit[j]++; } } - for(cnt=0, i=get2byte(&data[hdr+1]); i>0 && i=usableSize || i<0 ){ - checkAppendMsg(pCheck, 0, - "Corruption detected in cell %d on page %d",i,iPage,0); - }else{ - for(j=i+size-1; j>=i; j--) hit[j]++; - } - i = get2byte(&data[i]); + i = get2byte(&data[hdr+1]); + while( i>0 ){ + int size, j; + assert( i<=usableSize-4 ); /* Enforced by btreeInitPage() */ + size = get2byte(&data[i+2]); + assert( i+size<=usableSize ); /* Enforced by btreeInitPage() */ + for(j=i+size-1; j>=i; j--) hit[j]++; + j = get2byte(&data[i]); + assert( j==0 || j>i+size ); /* Enforced by btreeInitPage() */ + assert( j<=usableSize-4 ); /* Enforced by btreeInitPage() */ + i = j; } for(i=cnt=0; iinTrans>TRANS_NONE && pBt->inTransaction>TRANS_NONE ); nRef = sqlite3PagerRefcount(pBt->pPager); - if( lockBtreeWithRetry(p)!=SQLITE_OK ){ - *pnErr = 1; - sqlite3BtreeLeave(p); - return sqlite3DbStrDup(0, "cannot acquire a read lock on the database"); - } sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; sCheck.nPage = pagerPagecount(sCheck.pBt); @@ -44303,13 +45156,11 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( sCheck.mallocFailed = 0; *pnErr = 0; if( sCheck.nPage==0 ){ - unlockBtreeIfUnused(pBt); sqlite3BtreeLeave(p); return 0; } sCheck.anRef = sqlite3Malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) ); if( !sCheck.anRef ){ - unlockBtreeIfUnused(pBt); *pnErr = 1; sqlite3BtreeLeave(p); return 0; @@ -44364,7 +45215,6 @@ SQLITE_PRIVATE char *sqlite3BtreeIntegrityCheck( ** This is an internal consistency check; an integrity check ** of the integrity check. */ - unlockBtreeIfUnused(pBt); if( NEVER(nRef != sqlite3PagerRefcount(pBt->pPager)) ){ checkAppendMsg(&sCheck, 0, "Outstanding page count goes from %d to %d during this analysis", @@ -44489,10 +45339,12 @@ SQLITE_PRIVATE int sqlite3BtreeSchemaLocked(Btree *p){ */ SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ int rc = SQLITE_OK; + assert( p->inTrans!=TRANS_NONE ); if( p->sharable ){ u8 lockType = READ_LOCK + isWriteLock; assert( READ_LOCK+1==WRITE_LOCK ); assert( isWriteLock==0 || isWriteLock==1 ); + sqlite3BtreeEnter(p); rc = querySharedCacheTableLock(p, iTab, lockType); if( rc==SQLITE_OK ){ @@ -44509,43 +45361,43 @@ SQLITE_PRIVATE int sqlite3BtreeLockTable(Btree *p, int iTab, u8 isWriteLock){ ** Argument pCsr must be a cursor opened for writing on an ** INTKEY table currently pointing at a valid table entry. ** This function modifies the data stored as part of that entry. -** Only the data content may only be modified, it is not possible -** to change the length of the data stored. +** +** Only the data content may only be modified, it is not possible to +** change the length of the data stored. If this function is called with +** parameters that attempt to write past the end of the existing data, +** no modifications are made and SQLITE_CORRUPT is returned. */ SQLITE_PRIVATE int sqlite3BtreePutData(BtCursor *pCsr, u32 offset, u32 amt, void *z){ int rc; - assert( cursorHoldsMutex(pCsr) ); assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) ); - assert(pCsr->isIncrblobHandle); + assert( pCsr->isIncrblobHandle ); - restoreCursorPosition(pCsr); + rc = restoreCursorPosition(pCsr); + if( rc!=SQLITE_OK ){ + return rc; + } assert( pCsr->eState!=CURSOR_REQUIRESEEK ); if( pCsr->eState!=CURSOR_VALID ){ return SQLITE_ABORT; } - /* Check some preconditions: + /* Check some assumptions: ** (a) the cursor is open for writing, - ** (b) there is no read-lock on the table being modified and - ** (c) the cursor points at a valid row of an intKey table. + ** (b) there is a read/write transaction open, + ** (c) the connection holds a write-lock on the table (if required), + ** (d) there are no conflicting read-locks, and + ** (e) the cursor points at a valid row of an intKey table. */ if( !pCsr->wrFlag ){ return SQLITE_READONLY; } - assert( !pCsr->pBt->readOnly - && pCsr->pBt->inTransaction==TRANS_WRITE ); - rc = checkForReadConflicts(pCsr->pBtree, pCsr->pgnoRoot, pCsr, 0); - if( rc!=SQLITE_OK ){ - /* The table pCur points to has a read lock */ - assert( rc==SQLITE_LOCKED_SHAREDCACHE ); - return rc; - } - if( pCsr->eState==CURSOR_INVALID || !pCsr->apPage[pCsr->iPage]->intKey ){ - return SQLITE_ERROR; - } + assert( !pCsr->pBt->readOnly && pCsr->pBt->inTransaction==TRANS_WRITE ); + assert( hasSharedCacheTableLock(pCsr->pBtree, pCsr->pgnoRoot, 0, 2) ); + assert( !hasReadConflicts(pCsr->pBtree, pCsr->pgnoRoot) ); + assert( pCsr->apPage[pCsr->iPage]->intKey ); - return accessPayload(pCsr, offset, amt, (unsigned char *)z, 0, 1); + return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); } /* @@ -44583,7 +45435,7 @@ SQLITE_PRIVATE void sqlite3BtreeCacheOverflow(BtCursor *pCur){ ** This file contains the implementation of the sqlite3_backup_XXX() ** API functions and the related features. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* Macro to find the minimum of two numeric values. @@ -44887,7 +45739,7 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ && SQLITE_OK==(rc = sqlite3BtreeBeginTrans(p->pDest, 2)) ){ p->bDestLocked = 1; - rc = sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); + sqlite3BtreeGetMeta(p->pDest, BTREE_SCHEMA_VERSION, &p->iDestSchema); } /* If there is no open read-transaction on the source database, open @@ -44927,17 +45779,18 @@ SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage){ } } - if( rc==SQLITE_DONE ){ + /* Update the schema version field in the destination database. This + ** is to make sure that the schema-version really does change in + ** the case where the source and destination databases have the + ** same schema version. + */ + if( rc==SQLITE_DONE + && (rc = sqlite3BtreeUpdateMeta(p->pDest,1,p->iDestSchema+1))==SQLITE_OK + ){ const int nSrcPagesize = sqlite3BtreeGetPageSize(p->pSrc); const int nDestPagesize = sqlite3BtreeGetPageSize(p->pDest); int nDestTruncate; - /* Update the schema version field in the destination database. This - ** is to make sure that the schema-version really does change in - ** the case where the source and destination databases have the - ** same schema version. - */ - sqlite3BtreeUpdateMeta(p->pDest, 1, p->iDestSchema+1); if( p->pDestDb ){ sqlite3ResetInternalSchema(p->pDestDb, 0); } @@ -45216,7 +46069,7 @@ SQLITE_PRIVATE int sqlite3BtreeCopyFile(Btree *pTo, Btree *pFrom){ ** only within the VDBE. Interface routines refer to a Mem using the ** name sqlite_value ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -45295,7 +46148,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemGrow(Mem *pMem, int n, int preserve){ } } - if( preserve && pMem->z && pMem->zMalloc && pMem->z!=pMem->zMalloc ){ + if( pMem->z && preserve && pMem->zMalloc && pMem->z!=pMem->zMalloc ){ memcpy(pMem->zMalloc, pMem->z, pMem->n); } if( pMem->flags&MEM_Dyn && pMem->xDel ){ @@ -45444,7 +46297,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemStringify(Mem *pMem, int enc){ */ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ int rc = SQLITE_OK; - if( pFunc && pFunc->xFinalize ){ + if( ALWAYS(pFunc && pFunc->xFinalize) ){ sqlite3_context ctx; assert( (pMem->flags & MEM_Null)!=0 || pFunc==pMem->u.pDef ); assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) ); @@ -45457,7 +46310,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ assert( 0==(pMem->flags&MEM_Dyn) && !pMem->xDel ); sqlite3DbFree(pMem->db, pMem->zMalloc); memcpy(pMem, &ctx.s, sizeof(ctx.s)); - rc = (ctx.isError?SQLITE_ERROR:SQLITE_OK); + rc = ctx.isError; } return rc; } @@ -45469,7 +46322,11 @@ SQLITE_PRIVATE int sqlite3VdbeMemFinalize(Mem *pMem, FuncDef *pFunc){ */ SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){ assert( p->db==0 || sqlite3_mutex_held(p->db->mutex) ); - if( p->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet) ){ + testcase( p->flags & MEM_Agg ); + testcase( p->flags & MEM_Dyn ); + testcase( p->flags & MEM_RowSet ); + testcase( p->flags & MEM_Frame ); + if( p->flags&(MEM_Agg|MEM_Dyn|MEM_RowSet|MEM_Frame) ){ if( p->flags&MEM_Agg ){ sqlite3VdbeMemFinalize(p, p->u.pDef); assert( (p->flags & MEM_Agg)==0 ); @@ -45480,6 +46337,8 @@ SQLITE_PRIVATE void sqlite3VdbeMemReleaseExternal(Mem *p){ p->xDel = 0; }else if( p->flags&MEM_RowSet ){ sqlite3RowSetClear(p->u.pRowSet); + }else if( p->flags&MEM_Frame ){ + sqlite3VdbeMemSetNull(p); } } } @@ -45610,7 +46469,21 @@ SQLITE_PRIVATE void sqlite3VdbeIntegerAffinity(Mem *pMem){ assert( EIGHT_BYTE_ALIGNMENT(pMem) ); pMem->u.i = doubleToInt64(pMem->r); - if( pMem->r==(double)pMem->u.i ){ + + /* Only mark the value as an integer if + ** + ** (1) the round-trip conversion real->int->real is a no-op, and + ** (2) The integer is neither the largest nor the smallest + ** possible integer (ticket #3922) + ** + ** The second and third terms in the following conditional enforces + ** the second condition under the assumption that addition overflow causes + ** values to wrap around. On x86 hardware, the third term is always + ** true and could be omitted. But we leave it in because other + ** architectures might behave differently. + */ + if( pMem->r==(double)pMem->u.i && pMem->u.i>SMALLEST_INT64 + && ALWAYS(pMem->u.iflags |= MEM_Int; } } @@ -45667,6 +46540,9 @@ SQLITE_PRIVATE int sqlite3VdbeMemNumerify(Mem *pMem){ ** Delete any previous value and set the value stored in *pMem to NULL. */ SQLITE_PRIVATE void sqlite3VdbeMemSetNull(Mem *pMem){ + if( pMem->flags & MEM_Frame ){ + sqlite3VdbeFrameDelete(pMem->u.pFrame); + } if( pMem->flags & MEM_RowSet ){ sqlite3RowSetClear(pMem->u.pRowSet); } @@ -45686,6 +46562,14 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetZeroBlob(Mem *pMem, int n){ if( n<0 ) n = 0; pMem->u.nZero = n; pMem->enc = SQLITE_UTF8; + +#ifdef SQLITE_OMIT_INCRBLOB + sqlite3VdbeMemGrow(pMem, n, 0); + if( pMem->z ){ + pMem->n = n; + memset(pMem->z, 0, n); + } +#endif } /* @@ -45721,12 +46605,9 @@ SQLITE_PRIVATE void sqlite3VdbeMemSetDouble(Mem *pMem, double val){ SQLITE_PRIVATE void sqlite3VdbeMemSetRowSet(Mem *pMem){ sqlite3 *db = pMem->db; assert( db!=0 ); - if( pMem->flags & MEM_RowSet ){ - sqlite3RowSetClear(pMem->u.pRowSet); - }else{ - sqlite3VdbeMemRelease(pMem); - pMem->zMalloc = sqlite3DbMallocRaw(db, 64); - } + assert( (pMem->flags & MEM_RowSet)==0 ); + sqlite3VdbeMemRelease(pMem); + pMem->zMalloc = sqlite3DbMallocRaw(db, 64); if( db->mallocFailed ){ pMem->flags = MEM_Null; }else{ @@ -45825,6 +46706,12 @@ SQLITE_PRIVATE void sqlite3VdbeMemMove(Mem *pTo, Mem *pFrom){ ** string is copied into a (possibly existing) buffer managed by the ** Mem structure. Otherwise, any existing buffer is freed and the ** pointer copied. +** +** If the string is too large (if it exceeds the SQLITE_LIMIT_LENGTH +** size limit) then no memory allocation occurs. If the string can be +** stored without allocating memory, then it is. If a memory allocation +** is required to store the string, then value of pMem is unchanged. In +** either case, SQLITE_TOOBIG is returned. */ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( Mem *pMem, /* Memory cell to set to string value */ @@ -45888,9 +46775,6 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( pMem->xDel = xDel; flags |= ((xDel==SQLITE_STATIC)?MEM_Static:MEM_Dyn); } - if( nByte>iLimit ){ - return SQLITE_TOOBIG; - } pMem->n = nByte; pMem->flags = flags; @@ -45903,6 +46787,10 @@ SQLITE_PRIVATE int sqlite3VdbeMemSetStr( } #endif + if( nByte>iLimit ){ + return SQLITE_TOOBIG; + } + return SQLITE_OK; } @@ -46051,6 +46939,8 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( int available = 0; /* Number of bytes available on the local btree page */ int rc = SQLITE_OK; /* Return code */ + assert( sqlite3BtreeCursorIsValid(pCur) ); + /* Note: the calls to BtreeKeyFetch() and DataFetch() below assert() ** that both the BtShared and database handle mutexes are held. */ assert( (pMem->flags & MEM_RowSet)==0 ); @@ -46061,7 +46951,7 @@ SQLITE_PRIVATE int sqlite3VdbeMemFromBtree( } assert( zData!=0 ); - if( offset+amt<=available && ((pMem->flags&MEM_Dyn)==0 || pMem->xDel) ){ + if( offset+amt<=available && (pMem->flags&MEM_Dyn)==0 ){ sqlite3VdbeMemRelease(pMem); pMem->z = &zData[offset]; pMem->flags = MEM_Blob|MEM_Ephem; @@ -46170,6 +47060,9 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr( return SQLITE_OK; } op = pExpr->op; + if( op==TK_REGISTER ){ + op = pExpr->op2; + } if( op==TK_STRING || op==TK_FLOAT || op==TK_INTEGER ){ pVal = sqlite3ValueNew(db); @@ -46180,6 +47073,7 @@ SQLITE_PRIVATE int sqlite3ValueFromExpr( zVal = sqlite3DbStrDup(db, pExpr->u.zToken); if( zVal==0 ) goto no_mem; sqlite3ValueSetStr(pVal, -1, zVal, SQLITE_UTF8, SQLITE_DYNAMIC); + if( op==TK_FLOAT ) pVal->type = SQLITE_FLOAT; } if( (op==TK_INTEGER || op==TK_FLOAT ) && affinity==SQLITE_AFF_NONE ){ sqlite3ValueApplyAffinity(pVal, SQLITE_AFF_NUMERIC, SQLITE_UTF8); @@ -46278,7 +47172,7 @@ SQLITE_PRIVATE int sqlite3ValueBytes(sqlite3_value *pVal, u8 enc){ ** to version 2.8.7, all this code was combined into the vdbe.c source file. ** But that file was getting too big so this subroutines were split out. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ @@ -46407,7 +47301,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ assert( op>0 && op<0xff ); if( p->nOpAlloc<=i ){ if( growOpArray(p) ){ - return 0; + return 1; } } p->nOp++; @@ -46502,6 +47396,127 @@ SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){ } } +#ifdef SQLITE_DEBUG /* sqlite3AssertMayAbort() logic */ + +/* +** The following type and function are used to iterate through all opcodes +** in a Vdbe main program and each of the sub-programs (triggers) it may +** invoke directly or indirectly. It should be used as follows: +** +** Op *pOp; +** VdbeOpIter sIter; +** +** memset(&sIter, 0, sizeof(sIter)); +** sIter.v = v; // v is of type Vdbe* +** while( (pOp = opIterNext(&sIter)) ){ +** // Do something with pOp +** } +** sqlite3DbFree(v->db, sIter.apSub); +** +*/ +typedef struct VdbeOpIter VdbeOpIter; +struct VdbeOpIter { + Vdbe *v; /* Vdbe to iterate through the opcodes of */ + SubProgram **apSub; /* Array of subprograms */ + int nSub; /* Number of entries in apSub */ + int iAddr; /* Address of next instruction to return */ + int iSub; /* 0 = main program, 1 = first sub-program etc. */ +}; +static Op *opIterNext(VdbeOpIter *p){ + Vdbe *v = p->v; + Op *pRet = 0; + Op *aOp; + int nOp; + + if( p->iSub<=p->nSub ){ + + if( p->iSub==0 ){ + aOp = v->aOp; + nOp = v->nOp; + }else{ + aOp = p->apSub[p->iSub-1]->aOp; + nOp = p->apSub[p->iSub-1]->nOp; + } + assert( p->iAddriAddr]; + p->iAddr++; + if( p->iAddr==nOp ){ + p->iSub++; + p->iAddr = 0; + } + + if( pRet->p4type==P4_SUBPROGRAM ){ + int nByte = (p->nSub+1)*sizeof(SubProgram*); + int j; + for(j=0; jnSub; j++){ + if( p->apSub[j]==pRet->p4.pProgram ) break; + } + if( j==p->nSub ){ + p->apSub = sqlite3DbReallocOrFree(v->db, p->apSub, nByte); + if( !p->apSub ){ + pRet = 0; + }else{ + p->apSub[p->nSub++] = pRet->p4.pProgram; + } + } + } + } + + return pRet; +} + +/* +** Check if the program stored in the VM associated with pParse may +** throw an ABORT exception (causing the statement, but not entire transaction +** to be rolled back). This condition is true if the main program or any +** sub-programs contains any of the following: +** +** * OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort. +** * OP_HaltIfNull with P1=SQLITE_CONSTRAINT and P2=OE_Abort. +** * OP_Destroy +** * OP_VUpdate +** * OP_VRename +** * OP_FkCounter with P2==0 (immediate foreign key constraint) +** +** Then check that the value of Parse.mayAbort is true if an +** ABORT may be thrown, or false otherwise. Return true if it does +** match, or false otherwise. This function is intended to be used as +** part of an assert statement in the compiler. Similar to: +** +** assert( sqlite3VdbeAssertMayAbort(pParse->pVdbe, pParse->mayAbort) ); +*/ +SQLITE_PRIVATE int sqlite3VdbeAssertMayAbort(Vdbe *v, int mayAbort){ + int hasAbort = 0; + Op *pOp; + VdbeOpIter sIter; + memset(&sIter, 0, sizeof(sIter)); + sIter.v = v; + + while( (pOp = opIterNext(&sIter))!=0 ){ + int opcode = pOp->opcode; + if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename +#ifndef SQLITE_OMIT_FOREIGN_KEY + || (opcode==OP_FkCounter && pOp->p1==0 && pOp->p2==1) +#endif + || ((opcode==OP_Halt || opcode==OP_HaltIfNull) + && (pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort)) + ){ + hasAbort = 1; + break; + } + } + sqlite3DbFree(v->db, sIter.apSub); + + /* Return true if hasAbort==mayAbort. Or if a malloc failure occured. + ** If malloc failed, then the while() loop above may not have iterated + ** through all opcodes and hasAbort may be set incorrectly. Return + ** true for this case to prevent the assert() in the callers frame + ** from failing. */ + return ( v->db->mallocFailed || hasAbort==mayAbort ); +} +#endif /* SQLITE_DEBUG - the sqlite3AssertMayAbort() function */ + /* ** Loop through the program looking for P2 values that are negative ** on jump instructions. Each such value is a label. Resolve the @@ -46512,29 +47527,13 @@ SQLITE_PRIVATE void sqlite3VdbeResolveLabel(Vdbe *p, int x){ ** Variable *pMaxFuncArgs is set to the maximum value of any P2 argument ** to an OP_Function, OP_AggStep or OP_VFilter opcode. This is used by ** sqlite3VdbeMakeReady() to size the Vdbe.apArg[] array. -** -** This routine also does the following optimization: It scans for -** instructions that might cause a statement rollback. Such instructions -** are: -** -** * OP_Halt with P1=SQLITE_CONSTRAINT and P2=OE_Abort. -** * OP_Destroy -** * OP_VUpdate -** * OP_VRename -** -** If no such instruction is found, then every Statement instruction -** is changed to a Noop. In this way, we avoid creating the statement -** journal file unnecessarily. */ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ int i; - int nMaxArgs = 0; + int nMaxArgs = *pMaxFuncArgs; Op *pOp; int *aLabel = p->aLabel; - int doesStatementRollback = 0; - int hasStatementBegin = 0; p->readOnly = 1; - p->usesStmtJournal = 0; for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ u8 opcode = pOp->opcode; @@ -46544,21 +47543,9 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ }else if( opcode==OP_VUpdate ){ if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2; #endif - } - if( opcode==OP_Halt ){ - if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){ - doesStatementRollback = 1; - } - }else if( opcode==OP_Statement ){ - hasStatementBegin = 1; - p->usesStmtJournal = 1; - }else if( opcode==OP_Destroy ){ - doesStatementRollback = 1; }else if( opcode==OP_Transaction && pOp->p2!=0 ){ p->readOnly = 0; #ifndef SQLITE_OMIT_VIRTUALTABLE - }else if( opcode==OP_VUpdate || opcode==OP_VRename ){ - doesStatementRollback = 1; }else if( opcode==OP_VFilter ){ int n; assert( p->nOp - i >= 3 ); @@ -46577,20 +47564,6 @@ static void resolveP2Values(Vdbe *p, int *pMaxFuncArgs){ p->aLabel = 0; *pMaxFuncArgs = nMaxArgs; - - /* If we never rollback a statement transaction, then statement - ** transactions are not needed. So change every OP_Statement - ** opcode into an OP_Noop. This avoid a call to sqlite3OsOpenExclusive() - ** which can be expensive on some platforms. - */ - if( hasStatementBegin && !doesStatementRollback ){ - p->usesStmtJournal = 0; - for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){ - if( pOp->opcode==OP_Statement ){ - pOp->opcode = OP_Noop; - } - } - } } /* @@ -46601,6 +47574,30 @@ SQLITE_PRIVATE int sqlite3VdbeCurrentAddr(Vdbe *p){ return p->nOp; } +/* +** This function returns a pointer to the array of opcodes associated with +** the Vdbe passed as the first argument. It is the callers responsibility +** to arrange for the returned array to be eventually freed using the +** vdbeFreeOpArray() function. +** +** Before returning, *pnOp is set to the number of entries in the returned +** array. Also, *pnMaxArg is set to the larger of its current value and +** the number of entries in the Vdbe.apArg[] array required to execute the +** returned program. +*/ +SQLITE_PRIVATE VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ + VdbeOp *aOp = p->aOp; + assert( aOp && !p->db->mallocFailed ); + + /* Check that sqlite3VdbeUsesBtree() was not called on this VM */ + assert( p->aMutex.nMutex==0 ); + + resolveP2Values(p, pnMaxArg); + *pnOp = p->nOp; + p->aOp = 0; + return aOp; +} + /* ** Add a whole list of operations to the operation stack. Return the ** address of the first operation added. @@ -46612,7 +47609,7 @@ SQLITE_PRIVATE int sqlite3VdbeAddOpList(Vdbe *p, int nOp, VdbeOpList const *aOp) return 0; } addr = p->nOp; - if( nOp>0 ){ + if( ALWAYS(nOp>0) ){ int i; VdbeOpList const *pIn = aOp; for(i=0; imagic==VDBE_MAGIC_INIT ); - if( p && addr>=0 && p->nOp>addr && p->aOp ){ + assert( p!=0 ); + assert( addr>=0 ); + if( p->nOp>addr ){ p->aOp[addr].p1 = val; } } @@ -46659,8 +47657,9 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP1(Vdbe *p, int addr, int val){ ** This routine is useful for setting a jump destination. */ SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ - assert( p==0 || p->magic==VDBE_MAGIC_INIT ); - if( p && addr>=0 && p->nOp>addr && p->aOp ){ + assert( p!=0 ); + assert( addr>=0 ); + if( p->nOp>addr ){ p->aOp[addr].p2 = val; } } @@ -46669,8 +47668,9 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP2(Vdbe *p, int addr, int val){ ** Change the value of the P3 operand for a specific instruction. */ SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){ - assert( p==0 || p->magic==VDBE_MAGIC_INIT ); - if( p && addr>=0 && p->nOp>addr && p->aOp ){ + assert( p!=0 ); + assert( addr>=0 ); + if( p->nOp>addr ){ p->aOp[addr].p3 = val; } } @@ -46680,8 +47680,8 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP3(Vdbe *p, int addr, int val){ ** added operation. */ SQLITE_PRIVATE void sqlite3VdbeChangeP5(Vdbe *p, u8 val){ - assert( p==0 || p->magic==VDBE_MAGIC_INIT ); - if( p && p->aOp ){ + assert( p!=0 ); + if( p->aOp ){ assert( p->nOp>0 ); p->aOp[p->nOp-1].p5 = val; } @@ -46701,7 +47701,7 @@ SQLITE_PRIVATE void sqlite3VdbeJumpHere(Vdbe *p, int addr){ ** the FuncDef is not ephermal, then do nothing. */ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ - if( pDef && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){ + if( ALWAYS(pDef) && (pDef->flags & SQLITE_FUNC_EPHEM)!=0 ){ sqlite3DbFree(db, pDef); } } @@ -46737,6 +47737,61 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ sqlite3ValueFree((sqlite3_value*)p4); break; } + case P4_VTAB : { + sqlite3VtabUnlock((VTable *)p4); + break; + } + case P4_SUBPROGRAM : { + sqlite3VdbeProgramDelete(db, (SubProgram *)p4, 1); + break; + } + } + } +} + +/* +** Free the space allocated for aOp and any p4 values allocated for the +** opcodes contained within. If aOp is not NULL it is assumed to contain +** nOp entries. +*/ +static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ + if( aOp ){ + Op *pOp; + for(pOp=aOp; pOp<&aOp[nOp]; pOp++){ + freeP4(db, pOp->p4type, pOp->p4.p); +#ifdef SQLITE_DEBUG + sqlite3DbFree(db, pOp->zComment); +#endif + } + } + sqlite3DbFree(db, aOp); +} + +/* +** Decrement the ref-count on the SubProgram structure passed as the +** second argument. If the ref-count reaches zero, free the structure. +** +** The array of VDBE opcodes stored as SubProgram.aOp is freed if +** either the ref-count reaches zero or parameter freeop is non-zero. +** +** Since the array of opcodes pointed to by SubProgram.aOp may directly +** or indirectly contain a reference to the SubProgram structure itself. +** By passing a non-zero freeop parameter, the caller may ensure that all +** SubProgram structures and their aOp arrays are freed, even when there +** are such circular references. +*/ +SQLITE_PRIVATE void sqlite3VdbeProgramDelete(sqlite3 *db, SubProgram *p, int freeop){ + if( p ){ + assert( p->nRef>0 ); + if( freeop || p->nRef==1 ){ + Op *aOp = p->aOp; + p->aOp = 0; + vdbeFreeOpArray(db, aOp, p->nOp); + p->nOp = 0; + } + p->nRef--; + if( p->nRef==0 ){ + sqlite3DbFree(db, p); } } } @@ -46746,7 +47801,7 @@ static void freeP4(sqlite3 *db, int p4type, void *p4){ ** Change N opcodes starting at addr to No-ops. */ SQLITE_PRIVATE void sqlite3VdbeChangeToNoop(Vdbe *p, int addr, int N){ - if( p && p->aOp ){ + if( p->aOp ){ VdbeOp *pOp = &p->aOp[addr]; sqlite3 *db = p->db; while( N-- ){ @@ -46790,15 +47845,15 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int db = p->db; assert( p->magic==VDBE_MAGIC_INIT ); if( p->aOp==0 || db->mallocFailed ){ - if (n != P4_KEYINFO) { + if ( n!=P4_KEYINFO && n!=P4_VTAB ) { freeP4(db, n, (void*)*(char**)&zP4); } return; } + assert( p->nOp>0 ); assert( addrnOp ); if( addr<0 ){ addr = p->nOp - 1; - if( addr<0 ) return; } pOp = &p->aOp[addr]; freeP4(db, pOp->p4type, pOp->p4.p); @@ -46835,6 +47890,11 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int }else if( n==P4_KEYINFO_HANDOFF ){ pOp->p4.p = (void*)zP4; pOp->p4type = P4_KEYINFO; + }else if( n==P4_VTAB ){ + pOp->p4.p = (void*)zP4; + pOp->p4type = P4_VTAB; + sqlite3VtabLock((VTable *)zP4); + assert( ((VTable *)zP4)->db==p->db ); }else if( n<0 ){ pOp->p4.p = (void*)zP4; pOp->p4type = (signed char)n; @@ -46854,6 +47914,7 @@ SQLITE_PRIVATE void sqlite3VdbeChangeP4(Vdbe *p, int addr, const char *zP4, int */ SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ va_list ap; + if( !p ) return; assert( p->nOp>0 || p->aOp==0 ); assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed ); if( p->nOp ){ @@ -46866,6 +47927,7 @@ SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){ } SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ va_list ap; + if( !p ) return; sqlite3VdbeAddOp0(p, OP_Noop); assert( p->nOp>0 || p->aOp==0 ); assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed ); @@ -46888,11 +47950,24 @@ SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){ ** is readable and writable, but it has no effect. The return of a dummy ** opcode allows the call to continue functioning after a OOM fault without ** having to check to see if the return from this routine is a valid pointer. +** +** About the #ifdef SQLITE_OMIT_TRACE: Normally, this routine is never called +** unless p->nOp>0. This is because in the absense of SQLITE_OMIT_TRACE, +** an OP_Trace instruction is always inserted by sqlite3VdbeGet() as soon as +** a new VDBE is created. So we are free to set addr to p->nOp-1 without +** having to double-check to make sure that the result is non-negative. But +** if SQLITE_OMIT_TRACE is defined, the OP_Trace is omitted and we do need to +** check the value of p->nOp-1 before continuing. */ SQLITE_PRIVATE VdbeOp *sqlite3VdbeGetOp(Vdbe *p, int addr){ static VdbeOp dummy; assert( p->magic==VDBE_MAGIC_INIT ); - if( addr<0 ) addr = p->nOp - 1; + if( addr<0 ){ +#ifdef SQLITE_OMIT_TRACE + if( p->nOp==0 ) return &dummy; +#endif + addr = p->nOp - 1; + } assert( (addr>=0 && addrnOp) || p->db->mallocFailed ); if( p->db->mallocFailed ){ return &dummy; @@ -46972,12 +48047,15 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ sqlite3_snprintf(nTemp, zTemp, "%lld", pMem->u.i); }else if( pMem->flags & MEM_Real ){ sqlite3_snprintf(nTemp, zTemp, "%.16g", pMem->r); + }else{ + assert( pMem->flags & MEM_Blob ); + zP4 = "(blob)"; } break; } #ifndef SQLITE_OMIT_VIRTUALTABLE case P4_VTAB: { - sqlite3_vtab *pVtab = pOp->p4.pVtab; + sqlite3_vtab *pVtab = pOp->p4.pVtab->pVtab; sqlite3_snprintf(nTemp, zTemp, "vtab:%p:%p", pVtab, pVtab->pModule); break; } @@ -46986,6 +48064,10 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ sqlite3_snprintf(nTemp, zTemp, "intarray"); break; } + case P4_SUBPROGRAM: { + sqlite3_snprintf(nTemp, zTemp, "program"); + break; + } default: { zP4 = pOp->p4.z; if( zP4==0 ){ @@ -47001,7 +48083,6 @@ static char *displayP4(Op *pOp, char *zTemp, int nTemp){ /* ** Declare to the Vdbe that the BTree object at db->aDb[i] is used. -** */ SQLITE_PRIVATE void sqlite3VdbeUsesBtree(Vdbe *p, int i){ int mask; @@ -47060,7 +48141,7 @@ static void releaseMemArray(Mem *p, int N){ ** with no indexes using a single prepared INSERT statement, bind() ** and reset(). Inserts are grouped into a transaction. */ - if( p->flags&(MEM_Agg|MEM_Dyn) ){ + if( p->flags&(MEM_Agg|MEM_Dyn|MEM_Frame|MEM_RowSet) ){ sqlite3VdbeMemRelease(p); }else if( p->zMalloc ){ sqlite3DbFree(db, p->zMalloc); @@ -47073,6 +48154,22 @@ static void releaseMemArray(Mem *p, int N){ } } +/* +** Delete a VdbeFrame object and its contents. VdbeFrame objects are +** allocated by the OP_Program opcode in sqlite3VdbeExec(). +*/ +SQLITE_PRIVATE void sqlite3VdbeFrameDelete(VdbeFrame *p){ + int i; + Mem *aMem = VdbeFrameMem(p); + VdbeCursor **apCsr = (VdbeCursor **)&aMem[p->nChildMem]; + for(i=0; inChildCsr; i++){ + sqlite3VdbeFreeCursor(p->v, apCsr[i]); + } + releaseMemArray(aMem, p->nChildMem); + sqlite3DbFree(p->v->db, p); +} + + #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT SQLITE_PRIVATE int sqlite3VdbeReleaseBuffers(Vdbe *p){ int ii; @@ -47109,13 +48206,17 @@ SQLITE_PRIVATE int sqlite3VdbeReleaseBuffers(Vdbe *p){ SQLITE_PRIVATE int sqlite3VdbeList( Vdbe *p /* The VDBE */ ){ + int nRow; /* Total number of rows to return */ + int nSub = 0; /* Number of sub-vdbes seen so far */ + SubProgram **apSub = 0; /* Array of sub-vdbes */ + Mem *pSub = 0; sqlite3 *db = p->db; int i; int rc = SQLITE_OK; Mem *pMem = p->pResultSet = &p->aMem[1]; assert( p->explain ); - if( p->magic!=VDBE_MAGIC_RUN ) return SQLITE_MISUSE; + assert( p->magic==VDBE_MAGIC_RUN ); assert( db->magic==SQLITE_MAGIC_BUSY ); assert( p->rc==SQLITE_OK || p->rc==SQLITE_BUSY || p->rc==SQLITE_NOMEM ); @@ -47123,7 +48224,7 @@ SQLITE_PRIVATE int sqlite3VdbeList( ** the result, result columns may become dynamic if the user calls ** sqlite3_column_text16(), causing a translation to UTF-16 encoding. */ - releaseMemArray(pMem, p->nMem); + releaseMemArray(pMem, 8); if( p->rc==SQLITE_NOMEM ){ /* This happens if a malloc() inside a call to sqlite3_column_text() or @@ -47132,10 +48233,24 @@ SQLITE_PRIVATE int sqlite3VdbeList( return SQLITE_ERROR; } + /* Figure out total number of rows that will be returned by this + ** EXPLAIN program. */ + nRow = p->nOp; + if( p->explain==1 ){ + pSub = &p->aMem[9]; + if( pSub->flags&MEM_Blob ){ + nSub = pSub->n/sizeof(Vdbe*); + apSub = (SubProgram **)pSub->z; + } + for(i=0; inOp; + } + } + do{ i = p->pc++; - }while( inOp && p->explain==2 && p->aOp[i].opcode!=OP_Explain ); - if( i>=p->nOp ){ + }while( iexplain==2 && p->aOp[i].opcode!=OP_Explain ); + if( i>=nRow ){ p->rc = SQLITE_OK; rc = SQLITE_DONE; }else if( db->u1.isInterrupted ){ @@ -47144,7 +48259,17 @@ SQLITE_PRIVATE int sqlite3VdbeList( sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc)); }else{ char *z; - Op *pOp = &p->aOp[i]; + Op *pOp; + if( inOp ){ + pOp = &p->aOp[i]; + }else{ + int j; + i -= p->nOp; + for(j=0; i>=apSub[j]->nOp; j++){ + i -= apSub[j]->nOp; + } + pOp = &apSub[j]->aOp[i]; + } if( p->explain==1 ){ pMem->flags = MEM_Int; pMem->type = SQLITE_INTEGER; @@ -47158,6 +48283,20 @@ SQLITE_PRIVATE int sqlite3VdbeList( pMem->type = SQLITE_TEXT; pMem->enc = SQLITE_UTF8; pMem++; + + if( pOp->p4type==P4_SUBPROGRAM ){ + int nByte = (nSub+1)*sizeof(SubProgram*); + int j; + for(j=0; jp4.pProgram ) break; + } + if( j==nSub && SQLITE_OK==sqlite3VdbeMemGrow(pSub, nByte, 1) ){ + apSub = (SubProgram **)pSub->z; + apSub[nSub++] = pOp->p4.pProgram; + pSub->flags |= MEM_Blob; + pSub->n = nSub*sizeof(SubProgram*); + } + } } pMem->flags = MEM_Int; @@ -47301,7 +48440,7 @@ static void allocSpace( assert( EIGHT_BYTE_ALIGNMENT(*ppFrom) ); if( (*(void**)pp)==0 ){ nByte = ROUND8(nByte); - if( (pEnd - *ppFrom)>=nByte ){ + if( &(*ppFrom)[nByte] <= pEnd ){ *(void**)pp = (void *)*ppFrom; *ppFrom += nByte; }else{ @@ -47332,7 +48471,9 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( int nVar, /* Number of '?' see in the SQL statement */ int nMem, /* Number of memory cells to allocate */ int nCursor, /* Number of cursors to allocate */ - int isExplain /* True if the EXPLAIN keywords is present */ + int nArg, /* Maximum number of args in SubPrograms */ + int isExplain, /* True if the EXPLAIN keywords is present */ + int usesStmtJournal /* True to set Vdbe.usesStmtJournal */ ){ int n; sqlite3 *db = p->db; @@ -47363,21 +48504,20 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( ** first time this function is called for a given VDBE, not when it is ** being called from sqlite3_reset() to reset the virtual machine. */ - if( nVar>=0 && !db->mallocFailed ){ + if( nVar>=0 && ALWAYS(db->mallocFailed==0) ){ u8 *zCsr = (u8 *)&p->aOp[p->nOp]; u8 *zEnd = (u8 *)&p->aOp[p->nOpAlloc]; int nByte; - int nArg; /* Maximum number of args passed to a user function. */ resolveP2Values(p, &nArg); + p->usesStmtJournal = (u8)usesStmtJournal; if( isExplain && nMem<10 ){ nMem = 10; } + memset(zCsr, 0, zEnd-zCsr); zCsr += (zCsr - (u8*)0)&7; assert( EIGHT_BYTE_ALIGNMENT(zCsr) ); - if( zEndaMem, nMem*sizeof(Mem), &zCsr, zEnd, &nByte); allocSpace((char*)&p->aVar, nVar*sizeof(Mem), &zCsr, zEnd, &nByte); @@ -47387,15 +48527,15 @@ SQLITE_PRIVATE void sqlite3VdbeMakeReady( nCursor*sizeof(VdbeCursor*), &zCsr, zEnd, &nByte ); if( nByte ){ - p->pFree = sqlite3DbMallocRaw(db, nByte); + p->pFree = sqlite3DbMallocZero(db, nByte); } zCsr = p->pFree; zEnd = &zCsr[nByte]; }while( nByte && !db->mallocFailed ); - p->nCursor = nCursor; + p->nCursor = (u16)nCursor; if( p->aVar ){ - p->nVar = nVar; + p->nVar = (u16)nVar; for(n=0; naVar[n].flags = MEM_Null; p->aVar[n].db = db; @@ -47462,25 +48602,56 @@ SQLITE_PRIVATE void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ p->inVtabMethod = 0; } #endif - if( !pCx->ephemPseudoTable ){ - sqlite3DbFree(p->db, pCx->pData); - } } /* -** Close all cursors except for VTab cursors that are currently -** in use. +** Copy the values stored in the VdbeFrame structure to its Vdbe. This +** is used, for example, when a trigger sub-program is halted to restore +** control to the main program. */ -static void closeAllCursorsExceptActiveVtabs(Vdbe *p){ - int i; - if( p->apCsr==0 ) return; - for(i=0; inCursor; i++){ - VdbeCursor *pC = p->apCsr[i]; - if( pC && (!p->inVtabMethod || !pC->pVtabCursor) ){ - sqlite3VdbeFreeCursor(p, pC); - p->apCsr[i] = 0; +SQLITE_PRIVATE int sqlite3VdbeFrameRestore(VdbeFrame *pFrame){ + Vdbe *v = pFrame->v; + v->aOp = pFrame->aOp; + v->nOp = pFrame->nOp; + v->aMem = pFrame->aMem; + v->nMem = pFrame->nMem; + v->apCsr = pFrame->apCsr; + v->nCursor = pFrame->nCursor; + v->db->lastRowid = pFrame->lastRowid; + v->nChange = pFrame->nChange; + return pFrame->pc; +} + +/* +** Close all cursors. +** +** Also release any dynamic memory held by the VM in the Vdbe.aMem memory +** cell array. This is necessary as the memory cell array may contain +** pointers to VdbeFrame objects, which may in turn contain pointers to +** open cursors. +*/ +static void closeAllCursors(Vdbe *p){ + if( p->pFrame ){ + VdbeFrame *pFrame = p->pFrame; + for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); + sqlite3VdbeFrameRestore(pFrame); + } + p->pFrame = 0; + p->nFrame = 0; + + if( p->apCsr ){ + int i; + for(i=0; inCursor; i++){ + VdbeCursor *pC = p->apCsr[i]; + if( pC ){ + sqlite3VdbeFreeCursor(p, pC); + p->apCsr[i] = 0; + } } } + if( p->aMem ){ + releaseMemArray(&p->aMem[1], p->nMem); + } } /* @@ -47491,23 +48662,16 @@ static void closeAllCursorsExceptActiveVtabs(Vdbe *p){ ** variables in the aVar[] array. */ static void Cleanup(Vdbe *p){ - int i; sqlite3 *db = p->db; - Mem *pMem; - closeAllCursorsExceptActiveVtabs(p); - for(pMem=&p->aMem[1], i=1; i<=p->nMem; i++, pMem++){ - if( pMem->flags & MEM_RowSet ){ - sqlite3RowSetClear(pMem->u.pRowSet); - } - MemSetTypeFlag(pMem, MEM_Null); - } - releaseMemArray(&p->aMem[1], p->nMem); - if( p->contextStack ){ - sqlite3DbFree(db, p->contextStack); - } - p->contextStack = 0; - p->contextStackDepth = 0; - p->contextStackTop = 0; + +#ifdef SQLITE_DEBUG + /* Execute assert() statements to ensure that the Vdbe.apCsr[] and + ** Vdbe.aMem[] arrays have already been cleaned up. */ + int i; + for(i=0; inCursor; i++) assert( p->apCsr==0 || p->apCsr[i]==0 ); + for(i=1; i<=p->nMem; i++) assert( p->aMem==0 || p->aMem[i].flags==MEM_Null ); +#endif + sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = 0; p->pResultSet = 0; @@ -47527,7 +48691,7 @@ SQLITE_PRIVATE void sqlite3VdbeSetNumCols(Vdbe *p, int nResColumn){ releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); sqlite3DbFree(db, p->aColName); n = nResColumn*COLNAME_N; - p->nResColumn = nResColumn; + p->nResColumn = (u16)nResColumn; p->aColName = pColName = (Mem*)sqlite3DbMallocZero(db, sizeof(Mem)*n ); if( p->aColName==0 ) return; while( n-- > 0 ){ @@ -47581,6 +48745,13 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ int rc = SQLITE_OK; int needXcommit = 0; +#ifdef SQLITE_OMIT_VIRTUALTABLE + /* With this option, sqlite3VtabSync() is defined to be simply + ** SQLITE_OK so p is not used. + */ + UNUSED_PARAMETER(p); +#endif + /* Before doing anything else, call the xSync() callback for any ** virtual module tables written in this transaction. This has to ** be done before determining whether a master journal file is @@ -47608,12 +48779,9 @@ static int vdbeCommit(sqlite3 *db, Vdbe *p){ /* If there are any write-transactions at all, invoke the commit hook */ if( needXcommit && db->xCommitCallback ){ - assert( (db->flags & SQLITE_CommitBusy)==0 ); - db->flags |= SQLITE_CommitBusy; (void)sqlite3SafetyOff(db); rc = db->xCommitCallback(db->pCommitArg); (void)sqlite3SafetyOn(db); - db->flags &= ~SQLITE_CommitBusy; if( rc ){ return SQLITE_CONSTRAINT; } @@ -47856,7 +49024,13 @@ static void invalidateCursorsOnModifiedBtrees(sqlite3 *db){ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ sqlite3 *const db = p->db; int rc = SQLITE_OK; - if( p->iStatement && db->nStatement ){ + + /* If p->iStatement is greater than zero, then this Vdbe opened a + ** statement transaction that should be closed here. The only exception + ** is that an IO error may have occured, causing an emergency rollback. + ** In this case (db->nStatement==0), and there is nothing to do. + */ + if( db->nStatement && p->iStatement ){ int i; const int iSavepoint = p->iStatement-1; @@ -47881,6 +49055,13 @@ SQLITE_PRIVATE int sqlite3VdbeCloseStatement(Vdbe *p, int eOp){ } db->nStatement--; p->iStatement = 0; + + /* If the statement transaction is being rolled back, also restore the + ** database handles deferred constraint counter to the value it had when + ** the statement transaction was opened. */ + if( eOp==SAVEPOINT_ROLLBACK ){ + db->nDeferredCons = p->nStmtDefCons; + } } return rc; } @@ -47912,6 +49093,29 @@ SQLITE_PRIVATE void sqlite3VdbeMutexArrayEnter(Vdbe *p){ } #endif +/* +** This function is called when a transaction opened by the database +** handle associated with the VM passed as an argument is about to be +** committed. If there are outstanding deferred foreign key constraint +** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK. +** +** If there are outstanding FK violations and this function returns +** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT and write +** an error message to it. Then return SQLITE_ERROR. +*/ +#ifndef SQLITE_OMIT_FOREIGN_KEY +SQLITE_PRIVATE int sqlite3VdbeCheckFk(Vdbe *p, int deferred){ + sqlite3 *db = p->db; + if( (deferred && db->nDeferredCons>0) || (!deferred && p->nFkConstraint>0) ){ + p->rc = SQLITE_CONSTRAINT; + p->errorAction = OE_Abort; + sqlite3SetString(&p->zErrMsg, db, "foreign key constraint failed"); + return SQLITE_ERROR; + } + return SQLITE_OK; +} +#endif + /* ** This routine is called the when a VDBE tries to halt. If the VDBE ** has made changes and is in autocommit mode, then commit those @@ -47948,7 +49152,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ if( p->db->mallocFailed ){ p->rc = SQLITE_NOMEM; } - closeAllCursorsExceptActiveVtabs(p); + closeAllCursors(p); if( p->magic!=VDBE_MAGIC_RUN ){ return SQLITE_OK; } @@ -47965,6 +49169,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ /* Check for one of the special errors */ mrc = p->rc & 0xff; + assert( p->rc!=SQLITE_IOERR_BLOCKED ); /* This error no longer exists */ isSpecialError = mrc==SQLITE_NOMEM || mrc==SQLITE_IOERR || mrc==SQLITE_INTERRUPT || mrc==SQLITE_FULL; if( isSpecialError ){ @@ -47972,11 +49177,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ ** proceed with the special handling. */ if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){ - if( p->rc==SQLITE_IOERR_BLOCKED && p->usesStmtJournal ){ - eStatementOp = SAVEPOINT_ROLLBACK; - p->rc = SQLITE_BUSY; - }else if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) - && p->usesStmtJournal ){ + if( (mrc==SQLITE_NOMEM || mrc==SQLITE_FULL) && p->usesStmtJournal ){ eStatementOp = SAVEPOINT_ROLLBACK; }else{ /* We are forced to roll back the active transaction. Before doing @@ -47989,6 +49190,11 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ } } } + + /* Check for immediate foreign key violations. */ + if( p->rc==SQLITE_OK ){ + sqlite3VdbeCheckFk(p, 0); + } /* If the auto-commit flag is set and this is the only active writer ** VM, then we do either a commit or rollback of the current transaction. @@ -47999,13 +49205,16 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ if( !sqlite3VtabInSync(db) && db->autoCommit && db->writeVdbeCnt==(p->readOnly==0) - && (db->flags & SQLITE_CommitBusy)==0 ){ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ - /* The auto-commit flag is true, and the vdbe program was - ** successful or hit an 'OR FAIL' constraint. This means a commit - ** is required. - */ + if( sqlite3VdbeCheckFk(p, 1) ){ + sqlite3BtreeMutexArrayLeave(&p->aMutex); + return SQLITE_ERROR; + } + /* The auto-commit flag is true, the vdbe program was successful + ** or hit an 'OR FAIL' constraint and there are no deferred foreign + ** key constraints to hold up the transaction. This means a commit + ** is required. */ rc = vdbeCommit(db, p); if( rc==SQLITE_BUSY ){ sqlite3BtreeMutexArrayLeave(&p->aMutex); @@ -48014,6 +49223,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ p->rc = rc; sqlite3RollbackAll(db); }else{ + db->nDeferredCons = 0; sqlite3CommitInternalChanges(db); } }else{ @@ -48051,7 +49261,7 @@ SQLITE_PRIVATE int sqlite3VdbeHalt(Vdbe *p){ /* If this was an INSERT, UPDATE or DELETE and no statement transaction ** has been rolled back, update the database connection change-counter. */ - if( p->changeCntOn && p->pc>=0 ){ + if( p->changeCntOn ){ if( eStatementOp!=SAVEPOINT_ROLLBACK ){ sqlite3VdbeSetChanges(db, p->nChange); }else{ @@ -48198,8 +49408,6 @@ SQLITE_PRIVATE int sqlite3VdbeFinalize(Vdbe *p){ if( p->magic==VDBE_MAGIC_RUN || p->magic==VDBE_MAGIC_HALT ){ rc = sqlite3VdbeReset(p); assert( (rc & p->db->errMask)==rc ); - }else if( p->magic!=VDBE_MAGIC_INIT ){ - return SQLITE_MISUSE; } sqlite3VdbeDelete(p); return rc; @@ -48228,10 +49436,9 @@ SQLITE_PRIVATE void sqlite3VdbeDeleteAuxData(VdbeFunc *pVdbeFunc, int mask){ ** Delete an entire VDBE. */ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ - int i; sqlite3 *db; - if( p==0 ) return; + if( NEVER(p==0) ) return; db = p->db; if( p->pPrev ){ p->pPrev->pNext = p->pNext; @@ -48242,30 +49449,29 @@ SQLITE_PRIVATE void sqlite3VdbeDelete(Vdbe *p){ if( p->pNext ){ p->pNext->pPrev = p->pPrev; } - if( p->aOp ){ - Op *pOp = p->aOp; - for(i=0; inOp; i++, pOp++){ - freeP4(db, pOp->p4type, pOp->p4.p); -#ifdef SQLITE_DEBUG - sqlite3DbFree(db, pOp->zComment); -#endif - } - } releaseMemArray(p->aVar, p->nVar); - sqlite3DbFree(db, p->aLabel); releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); + vdbeFreeOpArray(db, p->aOp, p->nOp); + sqlite3DbFree(db, p->aLabel); sqlite3DbFree(db, p->aColName); sqlite3DbFree(db, p->zSql); p->magic = VDBE_MAGIC_DEAD; - sqlite3DbFree(db, p->aOp); sqlite3DbFree(db, p->pFree); sqlite3DbFree(db, p); } /* +** Make sure the cursor p is ready to read or write the row to which it +** was last positioned. Return an error code if an OOM fault or I/O error +** prevents us from positioning the cursor to its correct position. +** ** If a MoveTo operation is pending on the given cursor, then do that -** MoveTo now. Return an error code. If no MoveTo is pending, this -** routine does nothing and returns SQLITE_OK. +** MoveTo now. If no move is pending, check to see if the row has been +** deleted out from under the cursor and if it has, mark the row as +** a NULL row. +** +** If the cursor is already pointing to the correct row and that row has +** not been deleted out from under the cursor, then this routine is a no-op. */ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){ if( p->deferredMoveto ){ @@ -48276,7 +49482,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){ assert( p->isTable ); rc = sqlite3BtreeMovetoUnpacked(p->pCursor, 0, p->movetoTarget, 0, &res); if( rc ) return rc; - p->lastRowid = keyToInt(p->movetoTarget); + p->lastRowid = p->movetoTarget; p->rowidIsValid = ALWAYS(res==0) ?1:0; if( NEVER(res<0) ){ rc = sqlite3BtreeNext(p->pCursor, &res); @@ -48287,7 +49493,7 @@ SQLITE_PRIVATE int sqlite3VdbeCursorMoveto(VdbeCursor *p){ #endif p->deferredMoveto = 0; p->cacheStatus = CACHE_STALE; - }else if( p->pCursor ){ + }else if( ALWAYS(p->pCursor) ){ int hasMoved; int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved); if( rc ) return rc; @@ -48660,11 +49866,10 @@ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack( idx = getVarint32(aKey, szHdr); d = szHdr; u = 0; - while( idxnField ){ + while( idxnField && d<=nKey ){ u32 serial_type; idx += getVarint32(&aKey[idx], serial_type); - if( d>=nKey && sqlite3VdbeSerialTypeLen(serial_type)>0 ) break; pMem->enc = pKeyInfo->enc; pMem->db = pKeyInfo->db; pMem->flags = 0; @@ -48679,22 +49884,24 @@ SQLITE_PRIVATE UnpackedRecord *sqlite3VdbeRecordUnpack( } /* -** This routine destroys a UnpackedRecord object +** This routine destroys a UnpackedRecord object. */ SQLITE_PRIVATE void sqlite3VdbeDeleteUnpackedRecord(UnpackedRecord *p){ - if( p ){ - if( p->flags & UNPACKED_NEED_DESTROY ){ - int i; - Mem *pMem; - for(i=0, pMem=p->aMem; inField; i++, pMem++){ - if( pMem->zMalloc ){ - sqlite3VdbeMemRelease(pMem); - } - } - } - if( p->flags & UNPACKED_NEED_FREE ){ - sqlite3DbFree(p->pKeyInfo->db, p); - } + int i; + Mem *pMem; + + assert( p!=0 ); + assert( p->flags & UNPACKED_NEED_DESTROY ); + for(i=0, pMem=p->aMem; inField; i++, pMem++){ + /* The unpacked record is always constructed by the + ** sqlite3VdbeUnpackRecord() function above, which makes all + ** strings and blobs static. And none of the elements are + ** ever transformed, so there is never anything to delete. + */ + if( NEVER(pMem->zMalloc) ) sqlite3VdbeMemRelease(pMem); + } + if( p->flags & UNPACKED_NEED_FREE ){ + sqlite3DbFree(p->pKeyInfo->db, p); } } @@ -48771,7 +49978,9 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare( } i++; } - if( mem1.zMalloc ) sqlite3VdbeMemRelease(&mem1); + + /* No memory allocation is ever used on mem1. */ + if( NEVER(mem1.zMalloc) ) sqlite3VdbeMemRelease(&mem1); /* If the PREFIX_SEARCH flag is set and all fields except the final ** rowid field were equal, then clear the PREFIX_SEARCH flag and set @@ -48818,7 +50027,7 @@ SQLITE_PRIVATE int sqlite3VdbeRecordCompare( ** pCur might be pointing to text obtained from a corrupt database file. ** So the content cannot be trusted. Do appropriate checks on the content. */ -SQLITE_PRIVATE int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ +SQLITE_PRIVATE int sqlite3VdbeIdxRowid(sqlite3 *db, BtCursor *pCur, i64 *rowid){ i64 nCellKey = 0; int rc; u32 szHdr; /* Size of the header */ @@ -48826,17 +50035,20 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ u32 lenRowid; /* Size of the rowid */ Mem m, v; + UNUSED_PARAMETER(db); + /* Get the size of the index entry. Only indices entries of less - ** than 2GiB are support - anything large must be database corruption */ - sqlite3BtreeKeySize(pCur, &nCellKey); - if( unlikely(nCellKey<=0 || nCellKey>0x7fffffff) ){ - return SQLITE_CORRUPT_BKPT; - } + ** than 2GiB are support - anything large must be database corruption. + ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so + ** this code can safely assume that nCellKey is 32-bits + */ + assert( sqlite3BtreeCursorIsValid(pCur) ); + rc = sqlite3BtreeKeySize(pCur, &nCellKey); + assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */ + assert( (nCellKey & SQLITE_MAX_U32)==(u64)nCellKey ); /* Read in the complete content of the index entry */ - m.flags = 0; - m.db = 0; - m.zMalloc = 0; + memset(&m, 0, sizeof(m)); rc = sqlite3VdbeMemFromBtree(pCur, 0, (int)nCellKey, 1, &m); if( rc ){ return rc; @@ -48844,9 +50056,9 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ /* The index entry must begin with a header size */ (void)getVarint32((u8*)m.z, szHdr); - testcase( szHdr==2 ); + testcase( szHdr==3 ); testcase( szHdr==m.n ); - if( unlikely(szHdr<2 || (int)szHdr>m.n) ){ + if( unlikely(szHdr<3 || (int)szHdr>m.n) ){ goto idx_rowid_corruption; } @@ -48865,8 +50077,8 @@ SQLITE_PRIVATE int sqlite3VdbeIdxRowid(BtCursor *pCur, i64 *rowid){ goto idx_rowid_corruption; } lenRowid = sqlite3VdbeSerialTypeLen(typeRowid); - testcase( m.n-lenRowid==szHdr ); - if( unlikely(m.n-lenRowidpCursor; Mem m; - sqlite3BtreeKeySize(pCur, &nCellKey); + assert( sqlite3BtreeCursorIsValid(pCur) ); + rc = sqlite3BtreeKeySize(pCur, &nCellKey); + assert( rc==SQLITE_OK ); /* pCur is always valid so KeySize cannot fail */ + /* nCellKey will always be between 0 and 0xffffffff because of the say + ** that btreeParseCellPtr() and sqlite3GetVarint32() are implemented */ if( nCellKey<=0 || nCellKey>0x7fffffff ){ *res = 0; - return SQLITE_OK; + return SQLITE_CORRUPT; } - m.db = 0; - m.flags = 0; - m.zMalloc = 0; + memset(&m, 0, sizeof(m)); rc = sqlite3VdbeMemFromBtree(pC->pCursor, 0, (int)nCellKey, 1, &m); if( rc ){ return rc; @@ -48985,164 +50196,8 @@ SQLITE_PRIVATE sqlite3 *sqlite3VdbeDb(Vdbe *v){ ** This file contains code use to implement APIs that are part of the ** VDBE. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ -*/ - -#if 0 && defined(SQLITE_ENABLE_MEMORY_MANAGEMENT) -/* -** The following structure contains pointers to the end points of a -** doubly-linked list of all compiled SQL statements that may be holding -** buffers eligible for release when the sqlite3_release_memory() interface is -** invoked. Access to this list is protected by the SQLITE_MUTEX_STATIC_LRU2 -** mutex. -** -** Statements are added to the end of this list when sqlite3_reset() is -** called. They are removed either when sqlite3_step() or sqlite3_finalize() -** is called. When statements are added to this list, the associated -** register array (p->aMem[1..p->nMem]) may contain dynamic buffers that -** can be freed using sqlite3VdbeReleaseMemory(). -** -** When statements are added or removed from this list, the mutex -** associated with the Vdbe being added or removed (Vdbe.db->mutex) is -** already held. The LRU2 mutex is then obtained, blocking if necessary, -** the linked-list pointers manipulated and the LRU2 mutex relinquished. +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ -struct StatementLruList { - Vdbe *pFirst; - Vdbe *pLast; -}; -static struct StatementLruList sqlite3LruStatements; - -/* -** Check that the list looks to be internally consistent. This is used -** as part of an assert() statement as follows: -** -** assert( stmtLruCheck() ); -*/ -#ifndef NDEBUG -static int stmtLruCheck(){ - Vdbe *p; - for(p=sqlite3LruStatements.pFirst; p; p=p->pLruNext){ - assert(p->pLruNext || p==sqlite3LruStatements.pLast); - assert(!p->pLruNext || p->pLruNext->pLruPrev==p); - assert(p->pLruPrev || p==sqlite3LruStatements.pFirst); - assert(!p->pLruPrev || p->pLruPrev->pLruNext==p); - } - return 1; -} -#endif - -/* -** Add vdbe p to the end of the statement lru list. It is assumed that -** p is not already part of the list when this is called. The lru list -** is protected by the SQLITE_MUTEX_STATIC_LRU mutex. -*/ -static void stmtLruAdd(Vdbe *p){ - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); - - if( p->pLruPrev || p->pLruNext || sqlite3LruStatements.pFirst==p ){ - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); - return; - } - - assert( stmtLruCheck() ); - - if( !sqlite3LruStatements.pFirst ){ - assert( !sqlite3LruStatements.pLast ); - sqlite3LruStatements.pFirst = p; - sqlite3LruStatements.pLast = p; - }else{ - assert( !sqlite3LruStatements.pLast->pLruNext ); - p->pLruPrev = sqlite3LruStatements.pLast; - sqlite3LruStatements.pLast->pLruNext = p; - sqlite3LruStatements.pLast = p; - } - - assert( stmtLruCheck() ); - - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); -} - -/* -** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is already held, remove -** statement p from the least-recently-used statement list. If the -** statement is not currently part of the list, this call is a no-op. -*/ -static void stmtLruRemoveNomutex(Vdbe *p){ - if( p->pLruPrev || p->pLruNext || p==sqlite3LruStatements.pFirst ){ - assert( stmtLruCheck() ); - if( p->pLruNext ){ - p->pLruNext->pLruPrev = p->pLruPrev; - }else{ - sqlite3LruStatements.pLast = p->pLruPrev; - } - if( p->pLruPrev ){ - p->pLruPrev->pLruNext = p->pLruNext; - }else{ - sqlite3LruStatements.pFirst = p->pLruNext; - } - p->pLruNext = 0; - p->pLruPrev = 0; - assert( stmtLruCheck() ); - } -} - -/* -** Assuming the SQLITE_MUTEX_STATIC_LRU2 mutext is not held, remove -** statement p from the least-recently-used statement list. If the -** statement is not currently part of the list, this call is a no-op. -*/ -static void stmtLruRemove(Vdbe *p){ - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); - stmtLruRemoveNomutex(p); - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); -} - -/* -** Try to release n bytes of memory by freeing buffers associated -** with the memory registers of currently unused vdbes. -*/ -SQLITE_PRIVATE int sqlite3VdbeReleaseMemory(int n){ - Vdbe *p; - Vdbe *pNext; - int nFree = 0; - - sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); - for(p=sqlite3LruStatements.pFirst; p && nFreepLruNext; - - /* For each statement handle in the lru list, attempt to obtain the - ** associated database mutex. If it cannot be obtained, continue - ** to the next statement handle. It is not possible to block on - ** the database mutex - that could cause deadlock. - */ - if( SQLITE_OK==sqlite3_mutex_try(p->db->mutex) ){ - nFree += sqlite3VdbeReleaseBuffers(p); - stmtLruRemoveNomutex(p); - sqlite3_mutex_leave(p->db->mutex); - } - } - sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2)); - - return nFree; -} - -/* -** Call sqlite3Reprepare() on the statement. Remove it from the -** lru list before doing so, as Reprepare() will free all the -** memory register buffers anyway. -*/ -int vdbeReprepare(Vdbe *p){ - stmtLruRemove(p); - return sqlite3Reprepare(p); -} - -#else /* !SQLITE_ENABLE_MEMORY_MANAGEMENT */ - #define stmtLruRemove(x) - #define stmtLruAdd(x) - #define vdbeReprepare(x) sqlite3Reprepare(x) -#endif - #ifndef SQLITE_OMIT_DEPRECATED /* @@ -49179,7 +50234,6 @@ SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt){ sqlite3_mutex *mutex = v->db->mutex; #endif sqlite3_mutex_enter(mutex); - stmtLruRemove(v); rc = sqlite3VdbeFinalize(v); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(mutex); @@ -49203,8 +50257,7 @@ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt){ Vdbe *v = (Vdbe*)pStmt; sqlite3_mutex_enter(v->db->mutex); rc = sqlite3VdbeReset(v); - stmtLruAdd(v); - sqlite3VdbeMakeReady(v, -1, 0, 0, 0); + sqlite3VdbeMakeReady(v, -1, 0, 0, 0, 0, 0); assert( (rc & (v->db->errMask))==rc ); rc = sqlite3ApiExit(v->db, rc); sqlite3_mutex_leave(v->db->mutex); @@ -49283,7 +50336,22 @@ SQLITE_API int sqlite3_value_type(sqlite3_value* pVal){ /**************************** sqlite3_result_ ******************************* ** The following routines are used by user-defined functions to specify ** the function result. +** +** The setStrOrError() funtion calls sqlite3VdbeMemSetStr() to store the +** result as a string or blob but if the string or blob is too large, it +** then sets the error code to SQLITE_TOOBIG */ +static void setResultStrOrError( + sqlite3_context *pCtx, /* Function context */ + const char *z, /* String pointer */ + int n, /* Bytes in string, or negative */ + u8 enc, /* Encoding of z. 0 for BLOBs */ + void (*xDel)(void*) /* Destructor function */ +){ + if( sqlite3VdbeMemSetStr(&pCtx->s, z, n, enc, xDel)==SQLITE_TOOBIG ){ + sqlite3_result_error_toobig(pCtx); + } +} SQLITE_API void sqlite3_result_blob( sqlite3_context *pCtx, const void *z, @@ -49292,7 +50360,7 @@ SQLITE_API void sqlite3_result_blob( ){ assert( n>=0 ); assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - sqlite3VdbeMemSetStr(&pCtx->s, z, n, 0, xDel); + setResultStrOrError(pCtx, z, n, 0, xDel); } SQLITE_API void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); @@ -49329,7 +50397,7 @@ SQLITE_API void sqlite3_result_text( void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF8, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); } #ifndef SQLITE_OMIT_UTF16 SQLITE_API void sqlite3_result_text16( @@ -49339,7 +50407,7 @@ SQLITE_API void sqlite3_result_text16( void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16NATIVE, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16NATIVE, xDel); } SQLITE_API void sqlite3_result_text16be( sqlite3_context *pCtx, @@ -49348,7 +50416,7 @@ SQLITE_API void sqlite3_result_text16be( void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16BE, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16BE, xDel); } SQLITE_API void sqlite3_result_text16le( sqlite3_context *pCtx, @@ -49357,7 +50425,7 @@ SQLITE_API void sqlite3_result_text16le( void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->s.db->mutex) ); - sqlite3VdbeMemSetStr(&pCtx->s, z, n, SQLITE_UTF16LE, xDel); + setResultStrOrError(pCtx, z, n, SQLITE_UTF16LE, xDel); } #endif /* SQLITE_OMIT_UTF16 */ SQLITE_API void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ @@ -49436,6 +50504,8 @@ static int sqlite3Step(Vdbe *p){ db->u1.isInterrupted = 0; } + assert( db->writeVdbeCnt>0 || db->autoCommit==0 || db->nDeferredCons==0 ); + #ifndef SQLITE_OMIT_TRACE if( db->xProfile && !db->init.busy ){ double rNow; @@ -49447,7 +50517,6 @@ static int sqlite3Step(Vdbe *p){ db->activeVdbeCnt++; if( p->readOnly==0 ) db->writeVdbeCnt++; p->pc = 0; - stmtLruRemove(p); } #ifndef SQLITE_OMIT_EXPLAIN if( p->explain ){ @@ -49507,19 +50576,6 @@ end_of_step: ** sqlite3Step() to do most of the work. If a schema error occurs, ** call sqlite3Reprepare() and try again. */ -#ifdef SQLITE_OMIT_PARSER -SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ - int rc = SQLITE_MISUSE; - if( pStmt ){ - Vdbe *v; - v = (Vdbe*)pStmt; - sqlite3_mutex_enter(v->db->mutex); - rc = sqlite3Step(v); - sqlite3_mutex_leave(v->db->mutex); - } - return rc; -} -#else SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ int rc = SQLITE_MISUSE; if( pStmt ){ @@ -49529,7 +50585,7 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ sqlite3_mutex_enter(db->mutex); while( (rc = sqlite3Step(v))==SQLITE_SCHEMA && cnt++ < 5 - && (rc = vdbeReprepare(v))==SQLITE_OK ){ + && (rc = sqlite3Reprepare(v))==SQLITE_OK ){ sqlite3_reset(pStmt); v->expired = 0; } @@ -49556,7 +50612,6 @@ SQLITE_API int sqlite3_step(sqlite3_stmt *pStmt){ } return rc; } -#endif /* ** Extract the user data from a sqlite3_context structure and return a @@ -50379,7 +51434,7 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt *pStmt, int op, int resetFlag){ ** in this file for details. If in doubt, do not deviate from existing ** commenting and indentation practices when changing or adding code. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -50432,6 +51487,17 @@ static void updateMaxBlobsize(Mem *p){ } #endif +/* +** The next global variable is incremented each type the OP_Found opcode +** is executed. This is used to test whether or not the foreign key +** operation implemented using OP_FkIsZero is working. This variable +** has no function other than to help verify the correct operation of the +** library. +*/ +#ifdef SQLITE_TEST +SQLITE_API int sqlite3_found_count = 0; +#endif + /* ** Test a register to see if it exceeds the current maximum blob size. ** If it does, record the new maximum blob size. @@ -50523,7 +51589,7 @@ static VdbeCursor *allocateCursor( int iCur, /* Index of the new VdbeCursor */ int nField, /* Number of fields in the table or index */ int iDb, /* When database the cursor belongs to, or -1 */ - int isBtreeCursor /* */ + int isBtreeCursor /* True for B-Tree. False for pseudo-table or vtab */ ){ /* Find the memory cell that will be used to store the blob of memory ** required for this VdbeCursor structure. It is convenient to use a @@ -50760,8 +51826,10 @@ static void memTracePrint(FILE *out, Mem *p){ fprintf(out, " si:%lld", p->u.i); }else if( p->flags & MEM_Int ){ fprintf(out, " i:%lld", p->u.i); +#ifndef SQLITE_OMIT_FLOATING_POINT }else if( p->flags & MEM_Real ){ fprintf(out, " r:%g", p->r); +#endif }else if( p->flags & MEM_RowSet ){ fprintf(out, " (rowset)"); }else{ @@ -50808,7 +51876,7 @@ static void registerTrace(FILE *out, int iReg, Mem *p){ ** This file contains inline asm code for retrieving "high-performance" ** counters for x86 class CPUs. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _HWTIME_H_ #define _HWTIME_H_ @@ -51039,9 +52107,8 @@ SQLITE_PRIVATE int sqlite3VdbeExec( i64 b; } ah; struct OP_Ge_stack_vars { - int flags; - int res; - char affinity; + int res; /* Result of the comparison of pIn1 against pIn3 */ + char affinity; /* Affinity to use for comparison */ } ai; struct OP_Compare_stack_vars { int n; @@ -51060,9 +52127,6 @@ SQLITE_PRIVATE int sqlite3VdbeExec( struct OP_IfNot_stack_vars { int c; } al; - struct OP_IsNull_stack_vars { - int n; - } am; struct OP_Column_stack_vars { u32 payloadSize; /* Number of bytes in the record */ i64 payloadSize64; /* Number of bytes in the record */ @@ -51085,13 +52149,14 @@ SQLITE_PRIVATE int sqlite3VdbeExec( u64 offset64; /* 64-bit offset. 64 bits needed to catch overflow */ int szHdr; /* Size of the header size field at start of record */ int avail; /* Number of bytes of available data */ - } an; + Mem *pReg; /* PseudoTable input register */ + } am; struct OP_Affinity_stack_vars { char *zAffinity; /* The affinity to be applied */ Mem *pData0; /* First register to which to apply affinity */ Mem *pLast; /* Last register to which to apply affinity */ Mem *pRec; /* Current register */ - } ao; + } an; struct OP_MakeRecord_stack_vars { u8 *zNewRecord; /* A buffer to hold the data for the new record */ Mem *pRec; /* The new record */ @@ -51108,15 +52173,11 @@ SQLITE_PRIVATE int sqlite3VdbeExec( int file_format; /* File format to use for encoding */ int i; /* Space used in zNewRecord[] */ int len; /* Length of a field */ - } ap; + } ao; struct OP_Count_stack_vars { i64 nEntry; BtCursor *pCrsr; - } aq; - struct OP_Statement_stack_vars { - int i; - Btree *pBt; - } ar; + } ap; struct OP_Savepoint_stack_vars { int p1; /* Value of P1 operand */ char *zName; /* Name of savepoint */ @@ -51126,72 +52187,61 @@ SQLITE_PRIVATE int sqlite3VdbeExec( Savepoint *pTmp; int iSavepoint; int ii; - } as; + } aq; struct OP_AutoCommit_stack_vars { int desiredAutoCommit; int iRollback; int turnOnAC; - } at; + } ar; struct OP_Transaction_stack_vars { - int i; Btree *pBt; - } au; + } as; struct OP_ReadCookie_stack_vars { int iMeta; int iDb; int iCookie; - } av; + } at; struct OP_SetCookie_stack_vars { Db *pDb; - } aw; + } au; struct OP_VerifyCookie_stack_vars { int iMeta; Btree *pBt; - } ax; + } av; struct OP_OpenWrite_stack_vars { int nField; KeyInfo *pKeyInfo; - int i; int p2; int iDb; int wrFlag; Btree *pX; VdbeCursor *pCur; Db *pDb; - int flags; - } ay; + } aw; struct OP_OpenEphemeral_stack_vars { - int i; VdbeCursor *pCx; - } az; + } ax; struct OP_OpenPseudo_stack_vars { - int i; VdbeCursor *pCx; - } ba; - struct OP_Close_stack_vars { - int i; - } bb; + } ay; struct OP_SeekGt_stack_vars { - int i; int res; int oc; VdbeCursor *pC; UnpackedRecord r; int nField; i64 iKey; /* The rowid we are to seek to */ - } bc; + } az; struct OP_Seek_stack_vars { - int i; VdbeCursor *pC; - } bd; + } ba; struct OP_Found_stack_vars { - int i; int alreadyExists; VdbeCursor *pC; int res; UnpackedRecord *pIdxKey; char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; - } be; + } bb; struct OP_IsUnique_stack_vars { u16 ii; VdbeCursor *pCx; @@ -51200,120 +52250,108 @@ SQLITE_PRIVATE int sqlite3VdbeExec( Mem *aMem; UnpackedRecord r; /* B-Tree index search key */ i64 R; /* Rowid stored in register P3 */ - } bf; + } bc; struct OP_NotExists_stack_vars { - int i; VdbeCursor *pC; BtCursor *pCrsr; int res; u64 iKey; - } bg; + } bd; struct OP_NewRowid_stack_vars { - int i; - i64 v; - VdbeCursor *pC; - int res; - int rx; - int cnt; - i64 x; - Mem *pMem; - } bh; + i64 v; /* The new rowid */ + VdbeCursor *pC; /* Cursor of table to get the new rowid */ + int res; /* Result of an sqlite3BtreeLast() */ + int cnt; /* Counter to limit the number of searches */ + Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ + VdbeFrame *pFrame; /* Root frame of VDBE */ + } be; struct OP_Insert_stack_vars { - Mem *pData; - Mem *pKey; - i64 iKey; /* The integer ROWID or key for the record to be inserted */ - int i; - VdbeCursor *pC; - int nZero; - int seekResult; - const char *zDb; - const char *zTbl; - int op; - } bi; + Mem *pData; /* MEM cell holding data for the record to be inserted */ + Mem *pKey; /* MEM cell holding key for the record */ + i64 iKey; /* The integer ROWID or key for the record to be inserted */ + VdbeCursor *pC; /* Cursor to table into which insert is written */ + int nZero; /* Number of zero-bytes to append */ + int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ + const char *zDb; /* database name - used by the update hook */ + const char *zTbl; /* Table name - used by the opdate hook */ + int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ + } bf; struct OP_Delete_stack_vars { - int i; i64 iKey; VdbeCursor *pC; - } bj; + } bg; struct OP_RowData_stack_vars { - int i; VdbeCursor *pC; BtCursor *pCrsr; u32 n; i64 n64; - } bk; + } bh; struct OP_Rowid_stack_vars { - int i; VdbeCursor *pC; i64 v; sqlite3_vtab *pVtab; const sqlite3_module *pModule; - } bl; + } bi; struct OP_NullRow_stack_vars { - int i; VdbeCursor *pC; - } bm; + } bj; struct OP_Last_stack_vars { - int i; VdbeCursor *pC; BtCursor *pCrsr; int res; - } bn; + } bk; struct OP_Rewind_stack_vars { - int i; VdbeCursor *pC; BtCursor *pCrsr; int res; - } bo; + } bl; struct OP_Next_stack_vars { VdbeCursor *pC; BtCursor *pCrsr; int res; - } bp; + } bm; struct OP_IdxInsert_stack_vars { - int i; VdbeCursor *pC; BtCursor *pCrsr; int nKey; const char *zKey; - } bq; + } bn; struct OP_IdxDelete_stack_vars { - int i; VdbeCursor *pC; BtCursor *pCrsr; - } br; + int res; + UnpackedRecord r; + } bo; struct OP_IdxRowid_stack_vars { - int i; BtCursor *pCrsr; VdbeCursor *pC; i64 rowid; - } bs; + } bp; struct OP_IdxGE_stack_vars { - int i; VdbeCursor *pC; int res; UnpackedRecord r; - } bt; + } bq; struct OP_Destroy_stack_vars { int iMoved; int iCnt; Vdbe *pVdbe; int iDb; - } bu; + } br; struct OP_Clear_stack_vars { int nChange; - } bv; + } bs; struct OP_CreateTable_stack_vars { int pgno; int flags; Db *pDb; - } bw; + } bt; struct OP_ParseSchema_stack_vars { int iDb; const char *zMaster; char *zSql; InitData initData; - } bx; + } bu; struct OP_IntegrityCk_stack_vars { int nRoot; /* Number of tables to check. (Number of root pages.) */ int *aRoot; /* Array of rootpage numbers for tables to be checked */ @@ -51321,26 +52359,37 @@ SQLITE_PRIVATE int sqlite3VdbeExec( int nErr; /* Number of errors reported */ char *z; /* Text of the error report */ Mem *pnErr; /* Register keeping track of errors remaining */ - } by; + } bv; struct OP_RowSetAdd_stack_vars { Mem *pIdx; Mem *pVal; - } bz; + } bw; struct OP_RowSetRead_stack_vars { Mem *pIdx; i64 val; - } ca; + } bx; struct OP_RowSetTest_stack_vars { int iSet; int exists; + } by; + struct OP_Program_stack_vars { + int nMem; /* Number of memory registers for sub-program */ + int nByte; /* Bytes of runtime space required for sub-program */ + Mem *pRt; /* Register to allocate runtime space */ + Mem *pMem; /* Used to iterate through memory cells */ + Mem *pEnd; /* Last memory cell in new array */ + VdbeFrame *pFrame; /* New vdbe frame to execute in */ + SubProgram *pProgram; /* Sub-program to execute */ + void *t; /* Token identifying trigger */ + } bz; + struct OP_Param_stack_vars { + VdbeFrame *pFrame; + Mem *pIn; + } ca; + struct OP_MemMax_stack_vars { + Mem *pIn1; + VdbeFrame *pFrame; } cb; - struct OP_ContextPush_stack_vars { - int i; - Context *pContext; - } cc; - struct OP_ContextPop_stack_vars { - Context *pContext; - } cd; struct OP_AggStep_stack_vars { int n; int i; @@ -51348,26 +52397,22 @@ SQLITE_PRIVATE int sqlite3VdbeExec( Mem *pRec; sqlite3_context ctx; sqlite3_value **apVal; - } ce; + } cc; struct OP_AggFinal_stack_vars { Mem *pMem; - } cf; + } cd; struct OP_IncrVacuum_stack_vars { Btree *pBt; - } cg; - struct OP_TableLock_stack_vars { - int p1; - u8 isWriteLock; - } ch; + } ce; struct OP_VBegin_stack_vars { - sqlite3_vtab *pVtab; - } ci; + VTable *pVTab; + } cf; struct OP_VOpen_stack_vars { VdbeCursor *pCur; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; sqlite3_module *pModule; - } cj; + } cg; struct OP_VFilter_stack_vars { int nArg; int iQuery; @@ -51380,23 +52425,23 @@ SQLITE_PRIVATE int sqlite3VdbeExec( int res; int i; Mem **apArg; - } ck; + } ch; struct OP_VColumn_stack_vars { sqlite3_vtab *pVtab; const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; - } cl; + } ci; struct OP_VNext_stack_vars { sqlite3_vtab *pVtab; const sqlite3_module *pModule; int res; VdbeCursor *pCur; - } cm; + } cj; struct OP_VRename_stack_vars { sqlite3_vtab *pVtab; Mem *pName; - } cn; + } ck; struct OP_VUpdate_stack_vars { sqlite3_vtab *pVtab; sqlite3_module *pModule; @@ -51405,15 +52450,15 @@ SQLITE_PRIVATE int sqlite3VdbeExec( sqlite_int64 rowid; Mem **apArg; Mem *pX; - } co; + } cl; struct OP_Pagecount_stack_vars { int p1; int nPage; Pager *pPager; - } cp; + } cm; struct OP_Trace_stack_vars { char *zTrace; - } cq; + } cn; } u; /* End automatically generated code ********************************************************************/ @@ -51550,11 +52595,12 @@ SQLITE_PRIVATE int sqlite3VdbeExec( assert( pOp->p2<=p->nMem ); pIn2 = &p->aMem[pOp->p2]; REGISTER_TRACE(pOp->p2, pIn2); - if( (opProperty & OPFLG_OUT3)!=0 ){ - assert( pOp->p3>0 ); - assert( pOp->p3<=p->nMem ); - pOut = &p->aMem[pOp->p3]; - } + /* As currently implemented, in2 implies out3. There is no reason + ** why this has to be, it just worked out that way. */ + assert( (opProperty & OPFLG_OUT3)!=0 ); + assert( pOp->p3>0 ); + assert( pOp->p3<=p->nMem ); + pOut = &p->aMem[pOp->p3]; }else if( (opProperty & OPFLG_IN3)!=0 ){ assert( pOp->p3>0 ); assert( pOp->p3<=p->nMem ); @@ -51698,17 +52744,37 @@ case OP_HaltIfNull: { /* in3 */ ** is the same as executing Halt. */ case OP_Halt: { + if( pOp->p1==SQLITE_OK && p->pFrame ){ + /* Halt the sub-program. Return control to the parent frame. */ + VdbeFrame *pFrame = p->pFrame; + p->pFrame = pFrame->pParent; + p->nFrame--; + sqlite3VdbeSetChanges(db, p->nChange); + pc = sqlite3VdbeFrameRestore(pFrame); + if( pOp->p2==OE_Ignore ){ + /* Instruction pc is the OP_Program that invoked the sub-program + ** currently being halted. If the p2 instruction of this OP_Halt + ** instruction is set to OE_Ignore, then the sub-program is throwing + ** an IGNORE exception. In this case jump to the address specified + ** as the p2 of the calling OP_Program. */ + pc = p->aOp[pc].p2-1; + } + break; + } + p->rc = pOp->p1; + p->errorAction = (u8)pOp->p2; p->pc = pc; - p->errorAction = pOp->p2; if( pOp->p4.z ){ sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z); } rc = sqlite3VdbeHalt(p); - assert( rc==SQLITE_BUSY || rc==SQLITE_OK ); + assert( rc==SQLITE_BUSY || rc==SQLITE_OK || rc==SQLITE_ERROR ); if( rc==SQLITE_BUSY ){ p->rc = rc = SQLITE_BUSY; }else{ + assert( rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT ); + assert( rc==SQLITE_OK || db->nDeferredCons>0 ); rc = p->rc ? SQLITE_ERROR : SQLITE_DONE; } goto vdbe_return; @@ -51760,9 +52826,11 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */ #ifndef SQLITE_OMIT_UTF16 if( encoding!=SQLITE_UTF8 ){ - sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); + rc = sqlite3VdbeMemSetStr(pOut, pOp->p4.z, -1, SQLITE_UTF8, SQLITE_STATIC); + if( rc==SQLITE_TOOBIG ) goto too_big; if( SQLITE_OK!=sqlite3VdbeChangeEncoding(pOut, encoding) ) goto no_mem; - if( SQLITE_OK!=sqlite3VdbeMemMakeWriteable(pOut) ) goto no_mem; + assert( pOut->zMalloc==pOut->z ); + assert( pOut->flags & MEM_Dyn ); pOut->zMalloc = 0; pOut->flags |= MEM_Static; pOut->flags &= ~MEM_Dyn; @@ -51772,11 +52840,6 @@ case OP_String8: { /* same as TK_STRING, out2-prerelease */ pOp->p4type = P4_DYNAMIC; pOp->p4.z = pOut->z; pOp->p1 = pOut->n; - if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ - goto too_big; - } - UPDATE_MAX_BLOBSIZE(pOut); - break; } #endif if( pOp->p1>db->aLimit[SQLITE_LIMIT_LENGTH] ){ @@ -51957,6 +53020,15 @@ case OP_ResultRow: { assert( pOp->p1>0 ); assert( pOp->p1+pOp->p2<=p->nMem+1 ); + /* If this statement has violated immediate foreign key constraints, do + ** not return the number of rows modified. And do not RELEASE the statement + ** transaction. It needs to be rolled back. */ + if( SQLITE_OK!=(rc = sqlite3VdbeCheckFk(p, 0)) ){ + assert( db->flags&SQLITE_CountRows ); + assert( p->usesStmtJournal ); + break; + } + /* If the SQLITE_CountRows flag is set in sqlite3.flags mask, then ** DML statements invoke this opcode to return the number of rows ** modified to the user. This is the only way that a VM that @@ -51968,9 +53040,13 @@ case OP_ResultRow: { ** If the open statement-transaction is not closed here, then the user ** may step another VM that opens its own statement transaction. This ** may lead to overlapping statement transactions. + ** + ** The statement transaction is never a top-level transaction. Hence + ** the RELEASE call below can never fail. */ assert( p->iStatement==0 || db->flags&SQLITE_CountRows ); - if( SQLITE_OK!=(rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE)) ){ + rc = sqlite3VdbeCloseStatement(p, SAVEPOINT_RELEASE); + if( NEVER(rc!=SQLITE_OK) ){ break; } @@ -52018,9 +53094,8 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ sqlite3VdbeMemSetNull(pOut); break; } - ExpandBlob(pIn1); + if( ExpandBlob(pIn1) || ExpandBlob(pIn2) ) goto no_mem; Stringify(pIn1, encoding); - ExpandBlob(pIn2); Stringify(pIn2, encoding); u.ae.nByte = pIn1->n + pIn2->n; if( u.ae.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ @@ -52065,9 +53140,9 @@ case OP_Concat: { /* same as TK_CONCAT, in1, in2, out3 */ /* Opcode: Divide P1 P2 P3 * * ** ** Divide the value in register P1 by the value in register P2 -** and store the result in register P3. If the value in register P2 -** is zero, then the result is NULL. -** If either input is NULL, the result is NULL. +** and store the result in register P3 (P3=P2/P1). If the value in +** register P1 is zero, then the result is NULL. If either input is +** NULL, the result is NULL. */ /* Opcode: Remainder P1 P2 P3 * * ** @@ -52525,12 +53600,24 @@ case OP_ToReal: { /* same as TK_TO_REAL, in1 */ ** This works just like the Lt opcode except that the jump is taken if ** the operands in registers P1 and P3 are not equal. See the Lt opcode for ** additional information. +** +** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either +** true or false and is never NULL. If both operands are NULL then the result +** of comparison is false. If either operand is NULL then the result is true. +** If neither operand is NULL the the result is the same as it would be if +** the SQLITE_NULLEQ flag were omitted from P5. */ /* Opcode: Eq P1 P2 P3 P4 P5 ** ** This works just like the Lt opcode except that the jump is taken if ** the operands in registers P1 and P3 are equal. ** See the Lt opcode for additional information. +** +** If SQLITE_NULLEQ is set in P5 then the result of comparison is always either +** true or false and is never NULL. If both operands are NULL then the result +** of comparison is true. If either operand is NULL then the result is false. +** If neither operand is NULL the the result is the same as it would be if +** the SQLITE_NULLEQ flag were omitted from P5. */ /* Opcode: Le P1 P2 P3 P4 P5 ** @@ -52557,38 +53644,47 @@ case OP_Le: /* same as TK_LE, jump, in1, in3 */ case OP_Gt: /* same as TK_GT, jump, in1, in3 */ case OP_Ge: { /* same as TK_GE, jump, in1, in3 */ #if 0 /* local variables moved into u.ai */ - int flags; - int res; - char affinity; + int res; /* Result of the comparison of pIn1 against pIn3 */ + char affinity; /* Affinity to use for comparison */ #endif /* local variables moved into u.ai */ - u.ai.flags = pIn1->flags|pIn3->flags; - - if( u.ai.flags&MEM_Null ){ - /* If either operand is NULL then the result is always NULL. - ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. - */ - if( pOp->p5 & SQLITE_STOREP2 ){ - pOut = &p->aMem[pOp->p2]; - MemSetTypeFlag(pOut, MEM_Null); - REGISTER_TRACE(pOp->p2, pOut); - }else if( pOp->p5 & SQLITE_JUMPIFNULL ){ - pc = pOp->p2-1; + if( (pIn1->flags | pIn3->flags)&MEM_Null ){ + /* One or both operands are NULL */ + if( pOp->p5 & SQLITE_NULLEQ ){ + /* If SQLITE_NULLEQ is set (which will only happen if the operator is + ** OP_Eq or OP_Ne) then take the jump or not depending on whether + ** or not both operands are null. + */ + assert( pOp->opcode==OP_Eq || pOp->opcode==OP_Ne ); + u.ai.res = (pIn1->flags & pIn3->flags & MEM_Null)==0; + }else{ + /* SQLITE_NULLEQ is clear and at least one operand is NULL, + ** then the result is always NULL. + ** The jump is taken if the SQLITE_JUMPIFNULL bit is set. + */ + if( pOp->p5 & SQLITE_STOREP2 ){ + pOut = &p->aMem[pOp->p2]; + MemSetTypeFlag(pOut, MEM_Null); + REGISTER_TRACE(pOp->p2, pOut); + }else if( pOp->p5 & SQLITE_JUMPIFNULL ){ + pc = pOp->p2-1; + } + break; + } + }else{ + /* Neither operand is NULL. Do a comparison. */ + u.ai.affinity = pOp->p5 & SQLITE_AFF_MASK; + if( u.ai.affinity ){ + applyAffinity(pIn1, u.ai.affinity, encoding); + applyAffinity(pIn3, u.ai.affinity, encoding); + if( db->mallocFailed ) goto no_mem; } - break; - } - u.ai.affinity = pOp->p5 & SQLITE_AFF_MASK; - if( u.ai.affinity ){ - applyAffinity(pIn1, u.ai.affinity, encoding); - applyAffinity(pIn3, u.ai.affinity, encoding); - if( db->mallocFailed ) goto no_mem; + assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); + ExpandBlob(pIn1); + ExpandBlob(pIn3); + u.ai.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); } - - assert( pOp->p4type==P4_COLLSEQ || pOp->p4.pColl==0 ); - ExpandBlob(pIn1); - ExpandBlob(pIn3); - u.ai.res = sqlite3MemCompare(pIn3, pIn1, pOp->p4.pColl); switch( pOp->opcode ){ case OP_Eq: u.ai.res = u.ai.res==0; break; case OP_Ne: u.ai.res = u.ai.res!=0; break; @@ -52656,9 +53752,18 @@ case OP_Compare: { assert( u.aj.n>0 ); assert( u.aj.pKeyInfo!=0 ); u.aj.p1 = pOp->p1; - assert( u.aj.p1>0 && u.aj.p1+u.aj.n<=p->nMem+1 ); u.aj.p2 = pOp->p2; - assert( u.aj.p2>0 && u.aj.p2+u.aj.n<=p->nMem+1 ); +#if SQLITE_DEBUG + if( aPermute ){ + int k, mx = 0; + for(k=0; kmx ) mx = aPermute[k]; + assert( u.aj.p1>0 && u.aj.p1+mx<=p->nMem+1 ); + assert( u.aj.p2>0 && u.aj.p2+mx<=p->nMem+1 ); + }else{ + assert( u.aj.p1>0 && u.aj.p1+u.aj.n<=p->nMem+1 ); + assert( u.aj.p2>0 && u.aj.p2+u.aj.n<=p->nMem+1 ); + } +#endif /* SQLITE_DEBUG */ for(u.aj.i=0; u.aj.iaMem[u.aj.p1+u.aj.idx]); @@ -52809,26 +53914,14 @@ case OP_IfNot: { /* jump, in1 */ break; } -/* Opcode: IsNull P1 P2 P3 * * +/* Opcode: IsNull P1 P2 * * * ** -** Jump to P2 if the value in register P1 is NULL. If P3 is greater -** than zero, then check all values reg(P1), reg(P1+1), -** reg(P1+2), ..., reg(P1+P3-1). +** Jump to P2 if the value in register P1 is NULL. */ case OP_IsNull: { /* same as TK_ISNULL, jump, in1 */ -#if 0 /* local variables moved into u.am */ - int n; -#endif /* local variables moved into u.am */ - - u.am.n = pOp->p3; - assert( pOp->p3==0 || pOp->p1>0 ); - do{ - if( (pIn1->flags & MEM_Null)!=0 ){ - pc = pOp->p2 - 1; - break; - } - pIn1++; - }while( --u.am.n > 0 ); + if( (pIn1->flags & MEM_Null)!=0 ){ + pc = pOp->p2 - 1; + } break; } @@ -52843,29 +53936,7 @@ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ break; } -/* Opcode: SetNumColumns * P2 * * * -** -** This opcode sets the number of columns for the cursor opened by the -** following instruction to P2. -** -** An OP_SetNumColumns is only useful if it occurs immediately before -** one of the following opcodes: -** -** OpenRead -** OpenWrite -** OpenPseudo -** -** If the OP_Column opcode is to be executed on a cursor, then -** this opcode must be present immediately before the opcode that -** opens the cursor. -*/ -#if 0 -case OP_SetNumColumns: { - break; -} -#endif - -/* Opcode: Column P1 P2 P3 P4 * +/* Opcode: Column P1 P2 P3 P4 P5 ** ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional @@ -52878,9 +53949,14 @@ case OP_SetNumColumns: { ** If the column contains fewer than P2 fields, then extract a NULL. Or, ** if the P4 argument is a P4_MEM use the value of the P4 argument as ** the result. +** +** If the OPFLAG_CLEARCACHE bit is set on P5 and P1 is a pseudo-table cursor, +** then the cache of the cursor is reset prior to extracting the column. +** The first OP_Column against a pseudo-table after the value of the content +** register has changed should have this bit set. */ case OP_Column: { -#if 0 /* local variables moved into u.an */ +#if 0 /* local variables moved into u.am */ u32 payloadSize; /* Number of bytes in the record */ i64 payloadSize64; /* Number of bytes in the record */ int p1; /* P1 value of the opcode */ @@ -52902,119 +53978,125 @@ case OP_Column: { u64 offset64; /* 64-bit offset. 64 bits needed to catch overflow */ int szHdr; /* Size of the header size field at start of record */ int avail; /* Number of bytes of available data */ -#endif /* local variables moved into u.an */ + Mem *pReg; /* PseudoTable input register */ +#endif /* local variables moved into u.am */ - u.an.p1 = pOp->p1; - u.an.p2 = pOp->p2; - u.an.pC = 0; - memset(&u.an.sMem, 0, sizeof(u.an.sMem)); - assert( u.an.p1nCursor ); + u.am.p1 = pOp->p1; + u.am.p2 = pOp->p2; + u.am.pC = 0; + memset(&u.am.sMem, 0, sizeof(u.am.sMem)); + assert( u.am.p1nCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); - u.an.pDest = &p->aMem[pOp->p3]; - MemSetTypeFlag(u.an.pDest, MEM_Null); + u.am.pDest = &p->aMem[pOp->p3]; + MemSetTypeFlag(u.am.pDest, MEM_Null); + u.am.zRec = 0; - /* This block sets the variable u.an.payloadSize to be the total number of + /* This block sets the variable u.am.payloadSize to be the total number of ** bytes in the record. ** - ** u.an.zRec is set to be the complete text of the record if it is available. + ** u.am.zRec is set to be the complete text of the record if it is available. ** The complete record text is always available for pseudo-tables ** If the record is stored in a cursor, the complete record text - ** might be available in the u.an.pC->aRow cache. Or it might not be. - ** If the data is unavailable, u.an.zRec is set to NULL. + ** might be available in the u.am.pC->aRow cache. Or it might not be. + ** If the data is unavailable, u.am.zRec is set to NULL. ** ** We also compute the number of columns in the record. For cursors, ** the number of columns is stored in the VdbeCursor.nField element. */ - u.an.pC = p->apCsr[u.an.p1]; - assert( u.an.pC!=0 ); + u.am.pC = p->apCsr[u.am.p1]; + assert( u.am.pC!=0 ); #ifndef SQLITE_OMIT_VIRTUALTABLE - assert( u.an.pC->pVtabCursor==0 ); + assert( u.am.pC->pVtabCursor==0 ); #endif - if( u.an.pC->pCursor!=0 ){ + u.am.pCrsr = u.am.pC->pCursor; + if( u.am.pCrsr!=0 ){ /* The record is stored in a B-Tree */ - rc = sqlite3VdbeCursorMoveto(u.an.pC); + rc = sqlite3VdbeCursorMoveto(u.am.pC); if( rc ) goto abort_due_to_error; - u.an.zRec = 0; - u.an.pCrsr = u.an.pC->pCursor; - if( u.an.pC->nullRow ){ - u.an.payloadSize = 0; - }else if( u.an.pC->cacheStatus==p->cacheCtr ){ - u.an.payloadSize = u.an.pC->payloadSize; - u.an.zRec = (char*)u.an.pC->aRow; - }else if( u.an.pC->isIndex ){ - sqlite3BtreeKeySize(u.an.pCrsr, &u.an.payloadSize64); - if( (u.an.payloadSize64 & SQLITE_MAX_U32)!=(u64)u.an.payloadSize64 ){ - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; - } - u.an.payloadSize = (u32)u.an.payloadSize64; + if( u.am.pC->nullRow ){ + u.am.payloadSize = 0; + }else if( u.am.pC->cacheStatus==p->cacheCtr ){ + u.am.payloadSize = u.am.pC->payloadSize; + u.am.zRec = (char*)u.am.pC->aRow; + }else if( u.am.pC->isIndex ){ + assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) ); + rc = sqlite3BtreeKeySize(u.am.pCrsr, &u.am.payloadSize64); + assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ + /* sqlite3BtreeParseCellPtr() uses getVarint32() to extract the + ** payload size, so it is impossible for u.am.payloadSize64 to be + ** larger than 32 bits. */ + assert( (u.am.payloadSize64 & SQLITE_MAX_U32)==(u64)u.am.payloadSize64 ); + u.am.payloadSize = (u32)u.am.payloadSize64; }else{ - sqlite3BtreeDataSize(u.an.pCrsr, &u.an.payloadSize); - } - u.an.nField = u.an.pC->nField; + assert( sqlite3BtreeCursorIsValid(u.am.pCrsr) ); + rc = sqlite3BtreeDataSize(u.am.pCrsr, &u.am.payloadSize); + assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ + } + }else if( u.am.pC->pseudoTableReg>0 ){ + u.am.pReg = &p->aMem[u.am.pC->pseudoTableReg]; + assert( u.am.pReg->flags & MEM_Blob ); + u.am.payloadSize = u.am.pReg->n; + u.am.zRec = u.am.pReg->z; + u.am.pC->cacheStatus = (pOp->p5&OPFLAG_CLEARCACHE) ? CACHE_STALE : p->cacheCtr; + assert( u.am.payloadSize==0 || u.am.zRec!=0 ); }else{ - assert( u.an.pC->pseudoTable ); - /* The record is the sole entry of a pseudo-table */ - u.an.payloadSize = u.an.pC->nData; - u.an.zRec = u.an.pC->pData; - u.an.pC->cacheStatus = CACHE_STALE; - assert( u.an.payloadSize==0 || u.an.zRec!=0 ); - u.an.nField = u.an.pC->nField; - u.an.pCrsr = 0; - } - - /* If u.an.payloadSize is 0, then just store a NULL */ - if( u.an.payloadSize==0 ){ - assert( u.an.pDest->flags&MEM_Null ); + /* Consider the row to be NULL */ + u.am.payloadSize = 0; + } + + /* If u.am.payloadSize is 0, then just store a NULL */ + if( u.am.payloadSize==0 ){ + assert( u.am.pDest->flags&MEM_Null ); goto op_column_out; } assert( db->aLimit[SQLITE_LIMIT_LENGTH]>=0 ); - if( u.an.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + if( u.am.payloadSize > (u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } - assert( u.an.p2nField; + assert( u.am.p2aType; - if( u.an.pC->cacheStatus==p->cacheCtr ){ - u.an.aOffset = u.an.pC->aOffset; + u.am.aType = u.am.pC->aType; + if( u.am.pC->cacheStatus==p->cacheCtr ){ + u.am.aOffset = u.am.pC->aOffset; }else{ - assert(u.an.aType); - u.an.avail = 0; - u.an.pC->aOffset = u.an.aOffset = &u.an.aType[u.an.nField]; - u.an.pC->payloadSize = u.an.payloadSize; - u.an.pC->cacheStatus = p->cacheCtr; + assert(u.am.aType); + u.am.avail = 0; + u.am.pC->aOffset = u.am.aOffset = &u.am.aType[u.am.nField]; + u.am.pC->payloadSize = u.am.payloadSize; + u.am.pC->cacheStatus = p->cacheCtr; /* Figure out how many bytes are in the header */ - if( u.an.zRec ){ - u.an.zData = u.an.zRec; + if( u.am.zRec ){ + u.am.zData = u.am.zRec; }else{ - if( u.an.pC->isIndex ){ - u.an.zData = (char*)sqlite3BtreeKeyFetch(u.an.pCrsr, &u.an.avail); + if( u.am.pC->isIndex ){ + u.am.zData = (char*)sqlite3BtreeKeyFetch(u.am.pCrsr, &u.am.avail); }else{ - u.an.zData = (char*)sqlite3BtreeDataFetch(u.an.pCrsr, &u.an.avail); + u.am.zData = (char*)sqlite3BtreeDataFetch(u.am.pCrsr, &u.am.avail); } /* If KeyFetch()/DataFetch() managed to get the entire payload, - ** save the payload in the u.an.pC->aRow cache. That will save us from + ** save the payload in the u.am.pC->aRow cache. That will save us from ** having to make additional calls to fetch the content portion of ** the record. */ - assert( u.an.avail>=0 ); - if( u.an.payloadSize <= (u32)u.an.avail ){ - u.an.zRec = u.an.zData; - u.an.pC->aRow = (u8*)u.an.zData; + assert( u.am.avail>=0 ); + if( u.am.payloadSize <= (u32)u.am.avail ){ + u.am.zRec = u.am.zData; + u.am.pC->aRow = (u8*)u.am.zData; }else{ - u.an.pC->aRow = 0; + u.am.pC->aRow = 0; } } /* The following assert is true in all cases accept when ** the database file has been corrupted externally. - ** assert( u.an.zRec!=0 || u.an.avail>=u.an.payloadSize || u.an.avail>=9 ); */ - u.an.szHdr = getVarint32((u8*)u.an.zData, u.an.offset); + ** assert( u.am.zRec!=0 || u.am.avail>=u.am.payloadSize || u.am.avail>=9 ); */ + u.am.szHdr = getVarint32((u8*)u.am.zData, u.am.offset); /* Make sure a corrupt database has not given us an oversize header. ** Do this now to avoid an oversize memory allocation. @@ -53025,26 +54107,26 @@ case OP_Column: { ** 3-byte type for each of the maximum of 32768 columns plus three ** extra bytes for the header length itself. 32768*3 + 3 = 98307. */ - if( u.an.offset > 98307 ){ + if( u.am.offset > 98307 ){ rc = SQLITE_CORRUPT_BKPT; goto op_column_out; } - /* Compute in u.an.len the number of bytes of data we need to read in order - ** to get u.an.nField type values. u.an.offset is an upper bound on this. But - ** u.an.nField might be significantly less than the true number of columns - ** in the table, and in that case, 5*u.an.nField+3 might be smaller than u.an.offset. - ** We want to minimize u.an.len in order to limit the size of the memory - ** allocation, especially if a corrupt database file has caused u.an.offset + /* Compute in u.am.len the number of bytes of data we need to read in order + ** to get u.am.nField type values. u.am.offset is an upper bound on this. But + ** u.am.nField might be significantly less than the true number of columns + ** in the table, and in that case, 5*u.am.nField+3 might be smaller than u.am.offset. + ** We want to minimize u.am.len in order to limit the size of the memory + ** allocation, especially if a corrupt database file has caused u.am.offset ** to be oversized. Offset is limited to 98307 above. But 98307 might ** still exceed Robson memory allocation limits on some configurations. - ** On systems that cannot tolerate large memory allocations, u.an.nField*5+3 - ** will likely be much smaller since u.an.nField will likely be less than + ** On systems that cannot tolerate large memory allocations, u.am.nField*5+3 + ** will likely be much smaller since u.am.nField will likely be less than ** 20 or so. This insures that Robson memory allocation limits are ** not exceeded even for corrupt database files. */ - u.an.len = u.an.nField*5 + 3; - if( u.an.len > (int)u.an.offset ) u.an.len = (int)u.an.offset; + u.am.len = u.am.nField*5 + 3; + if( u.am.len > (int)u.am.offset ) u.am.len = (int)u.am.offset; /* The KeyFetch() or DataFetch() above are fast and will get the entire ** record header in most cases. But they will fail to get the complete @@ -53052,41 +54134,41 @@ case OP_Column: { ** in the B-Tree. When that happens, use sqlite3VdbeMemFromBtree() to ** acquire the complete header text. */ - if( !u.an.zRec && u.an.availisIndex, &u.an.sMem); + if( !u.am.zRec && u.am.availisIndex, &u.am.sMem); if( rc!=SQLITE_OK ){ goto op_column_out; } - u.an.zData = u.an.sMem.z; + u.am.zData = u.am.sMem.z; } - u.an.zEndHdr = (u8 *)&u.an.zData[u.an.len]; - u.an.zIdx = (u8 *)&u.an.zData[u.an.szHdr]; + u.am.zEndHdr = (u8 *)&u.am.zData[u.am.len]; + u.am.zIdx = (u8 *)&u.am.zData[u.am.szHdr]; - /* Scan the header and use it to fill in the u.an.aType[] and u.an.aOffset[] - ** arrays. u.an.aType[u.an.i] will contain the type integer for the u.an.i-th - ** column and u.an.aOffset[u.an.i] will contain the u.an.offset from the beginning - ** of the record to the start of the data for the u.an.i-th column + /* Scan the header and use it to fill in the u.am.aType[] and u.am.aOffset[] + ** arrays. u.am.aType[u.am.i] will contain the type integer for the u.am.i-th + ** column and u.am.aOffset[u.am.i] will contain the u.am.offset from the beginning + ** of the record to the start of the data for the u.am.i-th column */ - u.an.offset64 = u.an.offset; - for(u.an.i=0; u.an.i u.an.zEndHdr)|| (u.an.offset64 > u.an.payloadSize) - || (u.an.zIdx==u.an.zEndHdr && u.an.offset64!=(u64)u.an.payloadSize) ){ + if( (u.am.zIdx > u.am.zEndHdr)|| (u.am.offset64 > u.am.payloadSize) + || (u.am.zIdx==u.am.zEndHdr && u.am.offset64!=(u64)u.am.payloadSize) ){ rc = SQLITE_CORRUPT_BKPT; goto op_column_out; } } - /* Get the column information. If u.an.aOffset[u.an.p2] is non-zero, then - ** deserialize the value from the record. If u.an.aOffset[u.an.p2] is zero, + /* Get the column information. If u.am.aOffset[u.am.p2] is non-zero, then + ** deserialize the value from the record. If u.am.aOffset[u.am.p2] is zero, ** then there are not enough fields in the record to satisfy the ** request. In this case, set the value NULL or to P4 if P4 is ** a pointer to a Mem object. */ - if( u.an.aOffset[u.an.p2] ){ + if( u.am.aOffset[u.am.p2] ){ assert( rc==SQLITE_OK ); - if( u.an.zRec ){ - sqlite3VdbeMemReleaseExternal(u.an.pDest); - sqlite3VdbeSerialGet((u8 *)&u.an.zRec[u.an.aOffset[u.an.p2]], u.an.aType[u.an.p2], u.an.pDest); + if( u.am.zRec ){ + sqlite3VdbeMemReleaseExternal(u.am.pDest); + sqlite3VdbeSerialGet((u8 *)&u.am.zRec[u.am.aOffset[u.am.p2]], u.am.aType[u.am.p2], u.am.pDest); }else{ - u.an.len = sqlite3VdbeSerialTypeLen(u.an.aType[u.an.p2]); - sqlite3VdbeMemMove(&u.an.sMem, u.an.pDest); - rc = sqlite3VdbeMemFromBtree(u.an.pCrsr, u.an.aOffset[u.an.p2], u.an.len, u.an.pC->isIndex, &u.an.sMem); + u.am.len = sqlite3VdbeSerialTypeLen(u.am.aType[u.am.p2]); + sqlite3VdbeMemMove(&u.am.sMem, u.am.pDest); + rc = sqlite3VdbeMemFromBtree(u.am.pCrsr, u.am.aOffset[u.am.p2], u.am.len, u.am.pC->isIndex, &u.am.sMem); if( rc!=SQLITE_OK ){ goto op_column_out; } - u.an.zData = u.an.sMem.z; - sqlite3VdbeSerialGet((u8*)u.an.zData, u.an.aType[u.an.p2], u.an.pDest); + u.am.zData = u.am.sMem.z; + sqlite3VdbeSerialGet((u8*)u.am.zData, u.am.aType[u.am.p2], u.am.pDest); } - u.an.pDest->enc = encoding; + u.am.pDest->enc = encoding; }else{ if( pOp->p4type==P4_MEM ){ - sqlite3VdbeMemShallowCopy(u.an.pDest, pOp->p4.pMem, MEM_Static); + sqlite3VdbeMemShallowCopy(u.am.pDest, pOp->p4.pMem, MEM_Static); }else{ - assert( u.an.pDest->flags&MEM_Null ); + assert( u.am.pDest->flags&MEM_Null ); } } /* If we dynamically allocated space to hold the data (in the ** sqlite3VdbeMemFromBtree() call above) then transfer control of that - ** dynamically allocated space over to the u.an.pDest structure. + ** dynamically allocated space over to the u.am.pDest structure. ** This prevents a memory copy. */ - if( u.an.sMem.zMalloc ){ - assert( u.an.sMem.z==u.an.sMem.zMalloc ); - assert( !(u.an.pDest->flags & MEM_Dyn) ); - assert( !(u.an.pDest->flags & (MEM_Blob|MEM_Str)) || u.an.pDest->z==u.an.sMem.z ); - u.an.pDest->flags &= ~(MEM_Ephem|MEM_Static); - u.an.pDest->flags |= MEM_Term; - u.an.pDest->z = u.an.sMem.z; - u.an.pDest->zMalloc = u.an.sMem.zMalloc; + if( u.am.sMem.zMalloc ){ + assert( u.am.sMem.z==u.am.sMem.zMalloc ); + assert( !(u.am.pDest->flags & MEM_Dyn) ); + assert( !(u.am.pDest->flags & (MEM_Blob|MEM_Str)) || u.am.pDest->z==u.am.sMem.z ); + u.am.pDest->flags &= ~(MEM_Ephem|MEM_Static); + u.am.pDest->flags |= MEM_Term; + u.am.pDest->z = u.am.sMem.z; + u.am.pDest->zMalloc = u.am.sMem.zMalloc; } - rc = sqlite3VdbeMemMakeWriteable(u.an.pDest); + rc = sqlite3VdbeMemMakeWriteable(u.am.pDest); op_column_out: - UPDATE_MAX_BLOBSIZE(u.an.pDest); - REGISTER_TRACE(pOp->p3, u.an.pDest); + UPDATE_MAX_BLOBSIZE(u.am.pDest); + REGISTER_TRACE(pOp->p3, u.am.pDest); break; } @@ -53163,19 +54245,19 @@ op_column_out: ** memory cell in the range. */ case OP_Affinity: { -#if 0 /* local variables moved into u.ao */ +#if 0 /* local variables moved into u.an */ char *zAffinity; /* The affinity to be applied */ Mem *pData0; /* First register to which to apply affinity */ Mem *pLast; /* Last register to which to apply affinity */ Mem *pRec; /* Current register */ -#endif /* local variables moved into u.ao */ +#endif /* local variables moved into u.an */ - u.ao.zAffinity = pOp->p4.z; - u.ao.pData0 = &p->aMem[pOp->p1]; - u.ao.pLast = &u.ao.pData0[pOp->p2-1]; - for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){ - ExpandBlob(u.ao.pRec); - applyAffinity(u.ao.pRec, u.ao.zAffinity[u.ao.pRec-u.ao.pData0], encoding); + u.an.zAffinity = pOp->p4.z; + u.an.pData0 = &p->aMem[pOp->p1]; + u.an.pLast = &u.an.pData0[pOp->p2-1]; + for(u.an.pRec=u.an.pData0; u.an.pRec<=u.an.pLast; u.an.pRec++){ + ExpandBlob(u.an.pRec); + applyAffinity(u.an.pRec, u.an.zAffinity[u.an.pRec-u.an.pData0], encoding); } break; } @@ -53199,7 +54281,7 @@ case OP_Affinity: { ** If P4 is NULL then all index fields have the affinity NONE. */ case OP_MakeRecord: { -#if 0 /* local variables moved into u.ap */ +#if 0 /* local variables moved into u.ao */ u8 *zNewRecord; /* A buffer to hold the data for the new record */ Mem *pRec; /* The new record */ u64 nData; /* Number of bytes of data space */ @@ -53215,7 +54297,7 @@ case OP_MakeRecord: { int file_format; /* File format to use for encoding */ int i; /* Space used in zNewRecord[] */ int len; /* Length of a field */ -#endif /* local variables moved into u.ap */ +#endif /* local variables moved into u.ao */ /* Assuming the record contains N fields, the record format looks ** like this: @@ -53232,48 +54314,48 @@ case OP_MakeRecord: { ** hdr-size field is also a varint which is the offset from the beginning ** of the record to data0. */ - u.ap.nData = 0; /* Number of bytes of data space */ - u.ap.nHdr = 0; /* Number of bytes of header space */ - u.ap.nByte = 0; /* Data space required for this record */ - u.ap.nZero = 0; /* Number of zero bytes at the end of the record */ - u.ap.nField = pOp->p1; - u.ap.zAffinity = pOp->p4.z; - assert( u.ap.nField>0 && pOp->p2>0 && pOp->p2+u.ap.nField<=p->nMem+1 ); - u.ap.pData0 = &p->aMem[u.ap.nField]; - u.ap.nField = pOp->p2; - u.ap.pLast = &u.ap.pData0[u.ap.nField-1]; - u.ap.file_format = p->minWriteFileFormat; + u.ao.nData = 0; /* Number of bytes of data space */ + u.ao.nHdr = 0; /* Number of bytes of header space */ + u.ao.nByte = 0; /* Data space required for this record */ + u.ao.nZero = 0; /* Number of zero bytes at the end of the record */ + u.ao.nField = pOp->p1; + u.ao.zAffinity = pOp->p4.z; + assert( u.ao.nField>0 && pOp->p2>0 && pOp->p2+u.ao.nField<=p->nMem+1 ); + u.ao.pData0 = &p->aMem[u.ao.nField]; + u.ao.nField = pOp->p2; + u.ao.pLast = &u.ao.pData0[u.ao.nField-1]; + u.ao.file_format = p->minWriteFileFormat; /* Loop through the elements that will make up the record to figure ** out how much space is required for the new record. */ - for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){ - if( u.ap.zAffinity ){ - applyAffinity(u.ap.pRec, u.ap.zAffinity[u.ap.pRec-u.ap.pData0], encoding); + for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){ + if( u.ao.zAffinity ){ + applyAffinity(u.ao.pRec, u.ao.zAffinity[u.ao.pRec-u.ao.pData0], encoding); } - if( u.ap.pRec->flags&MEM_Zero && u.ap.pRec->n>0 ){ - sqlite3VdbeMemExpandBlob(u.ap.pRec); + if( u.ao.pRec->flags&MEM_Zero && u.ao.pRec->n>0 ){ + sqlite3VdbeMemExpandBlob(u.ao.pRec); } - u.ap.serial_type = sqlite3VdbeSerialType(u.ap.pRec, u.ap.file_format); - u.ap.len = sqlite3VdbeSerialTypeLen(u.ap.serial_type); - u.ap.nData += u.ap.len; - u.ap.nHdr += sqlite3VarintLen(u.ap.serial_type); - if( u.ap.pRec->flags & MEM_Zero ){ + u.ao.serial_type = sqlite3VdbeSerialType(u.ao.pRec, u.ao.file_format); + u.ao.len = sqlite3VdbeSerialTypeLen(u.ao.serial_type); + u.ao.nData += u.ao.len; + u.ao.nHdr += sqlite3VarintLen(u.ao.serial_type); + if( u.ao.pRec->flags & MEM_Zero ){ /* Only pure zero-filled BLOBs can be input to this Opcode. ** We do not allow blobs with a prefix and a zero-filled tail. */ - u.ap.nZero += u.ap.pRec->u.nZero; - }else if( u.ap.len ){ - u.ap.nZero = 0; + u.ao.nZero += u.ao.pRec->u.nZero; + }else if( u.ao.len ){ + u.ao.nZero = 0; } } /* Add the initial header varint and total the size */ - u.ap.nHdr += u.ap.nVarint = sqlite3VarintLen(u.ap.nHdr); - if( u.ap.nVarintdb->aLimit[SQLITE_LIMIT_LENGTH] ){ + u.ao.nByte = u.ao.nHdr+u.ao.nData-u.ao.nZero; + if( u.ao.nByte>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } @@ -53284,28 +54366,28 @@ case OP_MakeRecord: { */ assert( pOp->p3p1 || pOp->p3>=pOp->p1+pOp->p2 ); pOut = &p->aMem[pOp->p3]; - if( sqlite3VdbeMemGrow(pOut, (int)u.ap.nByte, 0) ){ + if( sqlite3VdbeMemGrow(pOut, (int)u.ao.nByte, 0) ){ goto no_mem; } - u.ap.zNewRecord = (u8 *)pOut->z; + u.ao.zNewRecord = (u8 *)pOut->z; /* Write the record */ - u.ap.i = putVarint32(u.ap.zNewRecord, u.ap.nHdr); - for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){ - u.ap.serial_type = sqlite3VdbeSerialType(u.ap.pRec, u.ap.file_format); - u.ap.i += putVarint32(&u.ap.zNewRecord[u.ap.i], u.ap.serial_type); /* serial type */ + u.ao.i = putVarint32(u.ao.zNewRecord, u.ao.nHdr); + for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){ + u.ao.serial_type = sqlite3VdbeSerialType(u.ao.pRec, u.ao.file_format); + u.ao.i += putVarint32(&u.ao.zNewRecord[u.ao.i], u.ao.serial_type); /* serial type */ } - for(u.ap.pRec=u.ap.pData0; u.ap.pRec<=u.ap.pLast; u.ap.pRec++){ /* serial data */ - u.ap.i += sqlite3VdbeSerialPut(&u.ap.zNewRecord[u.ap.i], (int)(u.ap.nByte-u.ap.i), u.ap.pRec,u.ap.file_format); + for(u.ao.pRec=u.ao.pData0; u.ao.pRec<=u.ao.pLast; u.ao.pRec++){ /* serial data */ + u.ao.i += sqlite3VdbeSerialPut(&u.ao.zNewRecord[u.ao.i], (int)(u.ao.nByte-u.ao.i), u.ao.pRec,u.ao.file_format); } - assert( u.ap.i==u.ap.nByte ); + assert( u.ao.i==u.ao.nByte ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); - pOut->n = (int)u.ap.nByte; + pOut->n = (int)u.ao.nByte; pOut->flags = MEM_Blob | MEM_Dyn; pOut->xDel = 0; - if( u.ap.nZero ){ - pOut->u.nZero = u.ap.nZero; + if( u.ao.nZero ){ + pOut->u.nZero = u.ao.nZero; pOut->flags |= MEM_Zero; } pOut->enc = SQLITE_UTF8; /* In case the blob is ever converted to text */ @@ -53321,67 +54403,23 @@ case OP_MakeRecord: { */ #ifndef SQLITE_OMIT_BTREECOUNT case OP_Count: { /* out2-prerelease */ -#if 0 /* local variables moved into u.aq */ +#if 0 /* local variables moved into u.ap */ i64 nEntry; BtCursor *pCrsr; -#endif /* local variables moved into u.aq */ +#endif /* local variables moved into u.ap */ - u.aq.pCrsr = p->apCsr[pOp->p1]->pCursor; - if( u.aq.pCrsr ){ - rc = sqlite3BtreeCount(u.aq.pCrsr, &u.aq.nEntry); + u.ap.pCrsr = p->apCsr[pOp->p1]->pCursor; + if( u.ap.pCrsr ){ + rc = sqlite3BtreeCount(u.ap.pCrsr, &u.ap.nEntry); }else{ - u.aq.nEntry = 0; + u.ap.nEntry = 0; } pOut->flags = MEM_Int; - pOut->u.i = u.aq.nEntry; + pOut->u.i = u.ap.nEntry; break; } #endif -/* Opcode: Statement P1 * * * * -** -** Begin an individual statement transaction which is part of a larger -** transaction. This is needed so that the statement -** can be rolled back after an error without having to roll back the -** entire transaction. The statement transaction will automatically -** commit when the VDBE halts. -** -** If the database connection is currently in autocommit mode (that -** is to say, if it is in between BEGIN and COMMIT) -** and if there are no other active statements on the same database -** connection, then this operation is a no-op. No statement transaction -** is needed since any error can use the normal ROLLBACK process to -** undo changes. -** -** If a statement transaction is started, then a statement journal file -** will be allocated and initialized. -** -** The statement is begun on the database file with index P1. The main -** database file has an index of 0 and the file used for temporary tables -** has an index of 1. -*/ -case OP_Statement: { -#if 0 /* local variables moved into u.ar */ - int i; - Btree *pBt; -#endif /* local variables moved into u.ar */ - if( db->autoCommit==0 || db->activeVdbeCnt>1 ){ - u.ar.i = pOp->p1; - assert( u.ar.i>=0 && u.ar.inDb ); - assert( db->aDb[u.ar.i].pBt!=0 ); - u.ar.pBt = db->aDb[u.ar.i].pBt; - assert( sqlite3BtreeIsInTrans(u.ar.pBt) ); - assert( (p->btreeMask & (1<iStatement==0 ){ - assert( db->nStatement>=0 && db->nSavepoint>=0 ); - db->nStatement++; - p->iStatement = db->nSavepoint + db->nStatement; - } - rc = sqlite3BtreeBeginStmt(u.ar.pBt, p->iStatement); - } - break; -} - /* Opcode: Savepoint P1 * * P4 * ** ** Open, release or rollback the savepoint named by parameter P4, depending @@ -53389,7 +54427,7 @@ case OP_Statement: { ** existing savepoint, P1==1, or to rollback an existing savepoint P1==2. */ case OP_Savepoint: { -#if 0 /* local variables moved into u.as */ +#if 0 /* local variables moved into u.aq */ int p1; /* Value of P1 operand */ char *zName; /* Name of savepoint */ int nName; @@ -53398,20 +54436,20 @@ case OP_Savepoint: { Savepoint *pTmp; int iSavepoint; int ii; -#endif /* local variables moved into u.as */ +#endif /* local variables moved into u.aq */ - u.as.p1 = pOp->p1; - u.as.zName = pOp->p4.z; + u.aq.p1 = pOp->p1; + u.aq.zName = pOp->p4.z; - /* Assert that the u.as.p1 parameter is valid. Also that if there is no open + /* Assert that the u.aq.p1 parameter is valid. Also that if there is no open ** transaction, then there cannot be any savepoints. */ assert( db->pSavepoint==0 || db->autoCommit==0 ); - assert( u.as.p1==SAVEPOINT_BEGIN||u.as.p1==SAVEPOINT_RELEASE||u.as.p1==SAVEPOINT_ROLLBACK ); + assert( u.aq.p1==SAVEPOINT_BEGIN||u.aq.p1==SAVEPOINT_RELEASE||u.aq.p1==SAVEPOINT_ROLLBACK ); assert( db->pSavepoint || db->isTransactionSavepoint==0 ); assert( checkSavepointCount(db) ); - if( u.as.p1==SAVEPOINT_BEGIN ){ + if( u.aq.p1==SAVEPOINT_BEGIN ){ if( db->writeVdbeCnt>0 ){ /* A new savepoint cannot be created if there are active write ** statements (i.e. open read/write incremental blob handles). @@ -53420,13 +54458,13 @@ case OP_Savepoint: { "SQL statements in progress"); rc = SQLITE_BUSY; }else{ - u.as.nName = sqlite3Strlen30(u.as.zName); + u.aq.nName = sqlite3Strlen30(u.aq.zName); /* Create a new savepoint structure. */ - u.as.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.as.nName+1); - if( u.as.pNew ){ - u.as.pNew->zName = (char *)&u.as.pNew[1]; - memcpy(u.as.pNew->zName, u.as.zName, u.as.nName+1); + u.aq.pNew = sqlite3DbMallocRaw(db, sizeof(Savepoint)+u.aq.nName+1); + if( u.aq.pNew ){ + u.aq.pNew->zName = (char *)&u.aq.pNew[1]; + memcpy(u.aq.pNew->zName, u.aq.zName, u.aq.nName+1); /* If there is no open transaction, then mark this as a special ** "transaction savepoint". */ @@ -53438,27 +54476,28 @@ case OP_Savepoint: { } /* Link the new savepoint into the database handle's list. */ - u.as.pNew->pNext = db->pSavepoint; - db->pSavepoint = u.as.pNew; + u.aq.pNew->pNext = db->pSavepoint; + db->pSavepoint = u.aq.pNew; + u.aq.pNew->nDeferredCons = db->nDeferredCons; } } }else{ - u.as.iSavepoint = 0; + u.aq.iSavepoint = 0; /* Find the named savepoint. If there is no such savepoint, then an ** an error is returned to the user. */ for( - u.as.pSavepoint = db->pSavepoint; - u.as.pSavepoint && sqlite3StrICmp(u.as.pSavepoint->zName, u.as.zName); - u.as.pSavepoint = u.as.pSavepoint->pNext + u.aq.pSavepoint = db->pSavepoint; + u.aq.pSavepoint && sqlite3StrICmp(u.aq.pSavepoint->zName, u.aq.zName); + u.aq.pSavepoint = u.aq.pSavepoint->pNext ){ - u.as.iSavepoint++; + u.aq.iSavepoint++; } - if( !u.as.pSavepoint ){ - sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.as.zName); + if( !u.aq.pSavepoint ){ + sqlite3SetString(&p->zErrMsg, db, "no such savepoint: %s", u.aq.zName); rc = SQLITE_ERROR; }else if( - db->writeVdbeCnt>0 || (u.as.p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1) + db->writeVdbeCnt>0 || (u.aq.p1==SAVEPOINT_ROLLBACK && db->activeVdbeCnt>1) ){ /* It is not possible to release (commit) a savepoint if there are ** active write statements. It is not possible to rollback a savepoint @@ -53466,7 +54505,7 @@ case OP_Savepoint: { */ sqlite3SetString(&p->zErrMsg, db, "cannot %s savepoint - SQL statements in progress", - (u.as.p1==SAVEPOINT_ROLLBACK ? "rollback": "release") + (u.aq.p1==SAVEPOINT_ROLLBACK ? "rollback": "release") ); rc = SQLITE_BUSY; }else{ @@ -53475,8 +54514,11 @@ case OP_Savepoint: { ** and this is a RELEASE command, then the current transaction ** is committed. */ - int isTransaction = u.as.pSavepoint->pNext==0 && db->isTransactionSavepoint; - if( isTransaction && u.as.p1==SAVEPOINT_RELEASE ){ + int isTransaction = u.aq.pSavepoint->pNext==0 && db->isTransactionSavepoint; + if( isTransaction && u.aq.p1==SAVEPOINT_RELEASE ){ + if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ + goto vdbe_return; + } db->autoCommit = 1; if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ p->pc = pc; @@ -53487,14 +54529,14 @@ case OP_Savepoint: { db->isTransactionSavepoint = 0; rc = p->rc; }else{ - u.as.iSavepoint = db->nSavepoint - u.as.iSavepoint - 1; - for(u.as.ii=0; u.as.iinDb; u.as.ii++){ - rc = sqlite3BtreeSavepoint(db->aDb[u.as.ii].pBt, u.as.p1, u.as.iSavepoint); + u.aq.iSavepoint = db->nSavepoint - u.aq.iSavepoint - 1; + for(u.aq.ii=0; u.aq.iinDb; u.aq.ii++){ + rc = sqlite3BtreeSavepoint(db->aDb[u.aq.ii].pBt, u.aq.p1, u.aq.iSavepoint); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } } - if( u.as.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ + if( u.aq.p1==SAVEPOINT_ROLLBACK && (db->flags&SQLITE_InternChanges)!=0 ){ sqlite3ExpirePreparedStatements(db); sqlite3ResetInternalSchema(db, 0); } @@ -53502,21 +54544,26 @@ case OP_Savepoint: { /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all ** savepoints nested inside of the savepoint being operated on. */ - while( db->pSavepoint!=u.as.pSavepoint ){ - u.as.pTmp = db->pSavepoint; - db->pSavepoint = u.as.pTmp->pNext; - sqlite3DbFree(db, u.as.pTmp); + while( db->pSavepoint!=u.aq.pSavepoint ){ + u.aq.pTmp = db->pSavepoint; + db->pSavepoint = u.aq.pTmp->pNext; + sqlite3DbFree(db, u.aq.pTmp); db->nSavepoint--; } - /* If it is a RELEASE, then destroy the savepoint being operated on too */ - if( u.as.p1==SAVEPOINT_RELEASE ){ - assert( u.as.pSavepoint==db->pSavepoint ); - db->pSavepoint = u.as.pSavepoint->pNext; - sqlite3DbFree(db, u.as.pSavepoint); + /* If it is a RELEASE, then destroy the savepoint being operated on + ** too. If it is a ROLLBACK TO, then set the number of deferred + ** constraint violations present in the database to the value stored + ** when the savepoint was created. */ + if( u.aq.p1==SAVEPOINT_RELEASE ){ + assert( u.aq.pSavepoint==db->pSavepoint ); + db->pSavepoint = u.aq.pSavepoint->pNext; + sqlite3DbFree(db, u.aq.pSavepoint); if( !isTransaction ){ db->nSavepoint--; } + }else{ + db->nDeferredCons = u.aq.pSavepoint->nDeferredCons; } } } @@ -53534,20 +54581,20 @@ case OP_Savepoint: { ** This instruction causes the VM to halt. */ case OP_AutoCommit: { -#if 0 /* local variables moved into u.at */ +#if 0 /* local variables moved into u.ar */ int desiredAutoCommit; int iRollback; int turnOnAC; -#endif /* local variables moved into u.at */ +#endif /* local variables moved into u.ar */ - u.at.desiredAutoCommit = pOp->p1; - u.at.iRollback = pOp->p2; - u.at.turnOnAC = u.at.desiredAutoCommit && !db->autoCommit; - assert( u.at.desiredAutoCommit==1 || u.at.desiredAutoCommit==0 ); - assert( u.at.desiredAutoCommit==1 || u.at.iRollback==0 ); + u.ar.desiredAutoCommit = pOp->p1; + u.ar.iRollback = pOp->p2; + u.ar.turnOnAC = u.ar.desiredAutoCommit && !db->autoCommit; + assert( u.ar.desiredAutoCommit==1 || u.ar.desiredAutoCommit==0 ); + assert( u.ar.desiredAutoCommit==1 || u.ar.iRollback==0 ); assert( db->activeVdbeCnt>0 ); /* At least this one VM is active */ - if( u.at.turnOnAC && u.at.iRollback && db->activeVdbeCnt>1 ){ + if( u.ar.turnOnAC && u.ar.iRollback && db->activeVdbeCnt>1 ){ /* If this instruction implements a ROLLBACK and other VMs are ** still running, and a transaction is active, return an error indicating ** that the other VMs must complete first. @@ -53555,23 +54602,25 @@ case OP_AutoCommit: { sqlite3SetString(&p->zErrMsg, db, "cannot rollback transaction - " "SQL statements in progress"); rc = SQLITE_BUSY; - }else if( u.at.turnOnAC && !u.at.iRollback && db->writeVdbeCnt>1 ){ + }else if( u.ar.turnOnAC && !u.ar.iRollback && db->writeVdbeCnt>0 ){ /* If this instruction implements a COMMIT and other VMs are writing ** return an error indicating that the other VMs must complete first. */ sqlite3SetString(&p->zErrMsg, db, "cannot commit transaction - " "SQL statements in progress"); rc = SQLITE_BUSY; - }else if( u.at.desiredAutoCommit!=db->autoCommit ){ - if( u.at.iRollback ){ - assert( u.at.desiredAutoCommit==1 ); + }else if( u.ar.desiredAutoCommit!=db->autoCommit ){ + if( u.ar.iRollback ){ + assert( u.ar.desiredAutoCommit==1 ); sqlite3RollbackAll(db); db->autoCommit = 1; + }else if( (rc = sqlite3VdbeCheckFk(p, 1))!=SQLITE_OK ){ + goto vdbe_return; }else{ - db->autoCommit = (u8)u.at.desiredAutoCommit; + db->autoCommit = (u8)u.ar.desiredAutoCommit; if( sqlite3VdbeHalt(p)==SQLITE_BUSY ){ p->pc = pc; - db->autoCommit = (u8)(1-u.at.desiredAutoCommit); + db->autoCommit = (u8)(1-u.ar.desiredAutoCommit); p->rc = rc = SQLITE_BUSY; goto vdbe_return; } @@ -53586,8 +54635,8 @@ case OP_AutoCommit: { goto vdbe_return; }else{ sqlite3SetString(&p->zErrMsg, db, - (!u.at.desiredAutoCommit)?"cannot start a transaction within a transaction":( - (u.at.iRollback)?"cannot rollback - no transaction is active": + (!u.ar.desiredAutoCommit)?"cannot start a transaction within a transaction":( + (u.ar.iRollback)?"cannot rollback - no transaction is active": "cannot commit - no transaction is active")); rc = SQLITE_ERROR; @@ -53614,29 +54663,54 @@ case OP_AutoCommit: { ** database. If P2 is 2 or greater then an EXCLUSIVE lock is also obtained ** on the file. ** +** If a write-transaction is started and the Vdbe.usesStmtJournal flag is +** true (this flag is set if the Vdbe may modify more than one row and may +** throw an ABORT exception), a statement transaction may also be opened. +** More specifically, a statement transaction is opened iff the database +** connection is currently not in autocommit mode, or if there are other +** active statements. A statement transaction allows the affects of this +** VDBE to be rolled back after an error without having to roll back the +** entire transaction. If no error is encountered, the statement transaction +** will automatically commit when the VDBE halts. +** ** If P2 is zero, then a read-lock is obtained on the database file. */ case OP_Transaction: { -#if 0 /* local variables moved into u.au */ - int i; +#if 0 /* local variables moved into u.as */ Btree *pBt; -#endif /* local variables moved into u.au */ +#endif /* local variables moved into u.as */ - u.au.i = pOp->p1; - assert( u.au.i>=0 && u.au.inDb ); - assert( (p->btreeMask & (1<aDb[u.au.i].pBt; + assert( pOp->p1>=0 && pOp->p1nDb ); + assert( (p->btreeMask & (1<p1))!=0 ); + u.as.pBt = db->aDb[pOp->p1].pBt; - if( u.au.pBt ){ - rc = sqlite3BtreeBeginTrans(u.au.pBt, pOp->p2); + if( u.as.pBt ){ + rc = sqlite3BtreeBeginTrans(u.as.pBt, pOp->p2); if( rc==SQLITE_BUSY ){ p->pc = pc; p->rc = rc = SQLITE_BUSY; goto vdbe_return; } - if( rc!=SQLITE_OK && rc!=SQLITE_READONLY /* && rc!=SQLITE_BUSY */ ){ + if( rc!=SQLITE_OK ){ goto abort_due_to_error; } + + if( pOp->p2 && p->usesStmtJournal + && (db->autoCommit==0 || db->activeVdbeCnt>1) + ){ + assert( sqlite3BtreeIsInTrans(u.as.pBt) ); + if( p->iStatement==0 ){ + assert( db->nStatement>=0 && db->nSavepoint>=0 ); + db->nStatement++; + p->iStatement = db->nSavepoint + db->nStatement; + } + rc = sqlite3BtreeBeginStmt(u.as.pBt, p->iStatement); + + /* Store the current value of the database handles deferred constraint + ** counter. If the statement transaction needs to be rolled back, + ** the value of this counter needs to be restored too. */ + p->nStmtDefCons = db->nDeferredCons; + } } break; } @@ -53654,21 +54728,21 @@ case OP_Transaction: { ** executing this instruction. */ case OP_ReadCookie: { /* out2-prerelease */ -#if 0 /* local variables moved into u.av */ +#if 0 /* local variables moved into u.at */ int iMeta; int iDb; int iCookie; -#endif /* local variables moved into u.av */ +#endif /* local variables moved into u.at */ - u.av.iDb = pOp->p1; - u.av.iCookie = pOp->p3; + u.at.iDb = pOp->p1; + u.at.iCookie = pOp->p3; assert( pOp->p3=0 && u.av.iDbnDb ); - assert( db->aDb[u.av.iDb].pBt!=0 ); - assert( (p->btreeMask & (1<=0 && u.at.iDbnDb ); + assert( db->aDb[u.at.iDb].pBt!=0 ); + assert( (p->btreeMask & (1<aDb[u.av.iDb].pBt, u.av.iCookie, (u32 *)&u.av.iMeta); - pOut->u.i = u.av.iMeta; + sqlite3BtreeGetMeta(db->aDb[u.at.iDb].pBt, u.at.iCookie, (u32 *)&u.at.iMeta); + pOut->u.i = u.at.iMeta; MemSetTypeFlag(pOut, MEM_Int); break; } @@ -53684,24 +54758,24 @@ case OP_ReadCookie: { /* out2-prerelease */ ** A transaction must be started before executing this opcode. */ case OP_SetCookie: { /* in3 */ -#if 0 /* local variables moved into u.aw */ +#if 0 /* local variables moved into u.au */ Db *pDb; -#endif /* local variables moved into u.aw */ +#endif /* local variables moved into u.au */ assert( pOp->p2p1>=0 && pOp->p1nDb ); assert( (p->btreeMask & (1<p1))!=0 ); - u.aw.pDb = &db->aDb[pOp->p1]; - assert( u.aw.pDb->pBt!=0 ); + u.au.pDb = &db->aDb[pOp->p1]; + assert( u.au.pDb->pBt!=0 ); sqlite3VdbeMemIntegerify(pIn3); /* See note about index shifting on OP_ReadCookie */ - rc = sqlite3BtreeUpdateMeta(u.aw.pDb->pBt, pOp->p2, (int)pIn3->u.i); + rc = sqlite3BtreeUpdateMeta(u.au.pDb->pBt, pOp->p2, (int)pIn3->u.i); if( pOp->p2==BTREE_SCHEMA_VERSION ){ /* When the schema cookie changes, record the new cookie internally */ - u.aw.pDb->pSchema->schema_cookie = (int)pIn3->u.i; + u.au.pDb->pSchema->schema_cookie = (int)pIn3->u.i; db->flags |= SQLITE_InternChanges; }else if( pOp->p2==BTREE_FILE_FORMAT ){ /* Record changes in the file format */ - u.aw.pDb->pSchema->file_format = (u8)pIn3->u.i; + u.au.pDb->pSchema->file_format = (u8)pIn3->u.i; } if( pOp->p1==1 ){ /* Invalidate all prepared statements whenever the TEMP database @@ -53728,20 +54802,19 @@ case OP_SetCookie: { /* in3 */ ** invoked. */ case OP_VerifyCookie: { -#if 0 /* local variables moved into u.ax */ +#if 0 /* local variables moved into u.av */ int iMeta; Btree *pBt; -#endif /* local variables moved into u.ax */ +#endif /* local variables moved into u.av */ assert( pOp->p1>=0 && pOp->p1nDb ); assert( (p->btreeMask & (1<p1))!=0 ); - u.ax.pBt = db->aDb[pOp->p1].pBt; - if( u.ax.pBt ){ - rc = sqlite3BtreeGetMeta(u.ax.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.ax.iMeta); + u.av.pBt = db->aDb[pOp->p1].pBt; + if( u.av.pBt ){ + sqlite3BtreeGetMeta(u.av.pBt, BTREE_SCHEMA_VERSION, (u32 *)&u.av.iMeta); }else{ - rc = SQLITE_OK; - u.ax.iMeta = 0; + u.av.iMeta = 0; } - if( rc==SQLITE_OK && u.ax.iMeta!=pOp->p2 ){ + if( u.av.iMeta!=pOp->p2 ){ sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); /* If the schema-cookie from the database file matches the cookie @@ -53757,7 +54830,7 @@ case OP_VerifyCookie: { ** to be invalidated whenever sqlite3_step() is called from within ** a v-table method. */ - if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.ax.iMeta ){ + if( db->aDb[pOp->p1].pSchema->schema_cookie!=u.av.iMeta ){ sqlite3ResetInternalSchema(db, pOp->p1); } @@ -53818,104 +54891,79 @@ case OP_VerifyCookie: { */ case OP_OpenRead: case OP_OpenWrite: { -#if 0 /* local variables moved into u.ay */ +#if 0 /* local variables moved into u.aw */ int nField; KeyInfo *pKeyInfo; - int i; int p2; int iDb; int wrFlag; Btree *pX; VdbeCursor *pCur; Db *pDb; - int flags; -#endif /* local variables moved into u.ay */ +#endif /* local variables moved into u.aw */ - u.ay.nField = 0; - u.ay.pKeyInfo = 0; - u.ay.i = pOp->p1; - u.ay.p2 = pOp->p2; - u.ay.iDb = pOp->p3; - assert( u.ay.iDb>=0 && u.ay.iDbnDb ); - assert( (p->btreeMask & (1<aDb[u.ay.iDb]; - u.ay.pX = u.ay.pDb->pBt; - assert( u.ay.pX!=0 ); + u.aw.nField = 0; + u.aw.pKeyInfo = 0; + u.aw.p2 = pOp->p2; + u.aw.iDb = pOp->p3; + assert( u.aw.iDb>=0 && u.aw.iDbnDb ); + assert( (p->btreeMask & (1<aDb[u.aw.iDb]; + u.aw.pX = u.aw.pDb->pBt; + assert( u.aw.pX!=0 ); if( pOp->opcode==OP_OpenWrite ){ - u.ay.wrFlag = 1; - if( u.ay.pDb->pSchema->file_format < p->minWriteFileFormat ){ - p->minWriteFileFormat = u.ay.pDb->pSchema->file_format; + u.aw.wrFlag = 1; + if( u.aw.pDb->pSchema->file_format < p->minWriteFileFormat ){ + p->minWriteFileFormat = u.aw.pDb->pSchema->file_format; } }else{ - u.ay.wrFlag = 0; + u.aw.wrFlag = 0; } if( pOp->p5 ){ - assert( u.ay.p2>0 ); - assert( u.ay.p2<=p->nMem ); - pIn2 = &p->aMem[u.ay.p2]; + assert( u.aw.p2>0 ); + assert( u.aw.p2<=p->nMem ); + pIn2 = &p->aMem[u.aw.p2]; sqlite3VdbeMemIntegerify(pIn2); - u.ay.p2 = (int)pIn2->u.i; - if( u.ay.p2<2 ) { + u.aw.p2 = (int)pIn2->u.i; + /* The u.aw.p2 value always comes from a prior OP_CreateTable opcode and + ** that opcode will always set the u.aw.p2 value to 2 or more or else fail. + ** If there were a failure, the prepared statement would have halted + ** before reaching this instruction. */ + if( NEVER(u.aw.p2<2) ) { rc = SQLITE_CORRUPT_BKPT; goto abort_due_to_error; } } - assert( u.ay.i>=0 ); if( pOp->p4type==P4_KEYINFO ){ - u.ay.pKeyInfo = pOp->p4.pKeyInfo; - u.ay.pKeyInfo->enc = ENC(p->db); - u.ay.nField = u.ay.pKeyInfo->nField+1; + u.aw.pKeyInfo = pOp->p4.pKeyInfo; + u.aw.pKeyInfo->enc = ENC(p->db); + u.aw.nField = u.aw.pKeyInfo->nField+1; }else if( pOp->p4type==P4_INT32 ){ - u.ay.nField = pOp->p4.i; + u.aw.nField = pOp->p4.i; + } + assert( pOp->p1>=0 ); + u.aw.pCur = allocateCursor(p, pOp->p1, u.aw.nField, u.aw.iDb, 1); + if( u.aw.pCur==0 ) goto no_mem; + u.aw.pCur->nullRow = 1; + rc = sqlite3BtreeCursor(u.aw.pX, u.aw.p2, u.aw.wrFlag, u.aw.pKeyInfo, u.aw.pCur->pCursor); + u.aw.pCur->pKeyInfo = u.aw.pKeyInfo; + + /* Since it performs no memory allocation or IO, the only values that + ** sqlite3BtreeCursor() may return are SQLITE_EMPTY and SQLITE_OK. + ** SQLITE_EMPTY is only returned when attempting to open the table + ** rooted at page 1 of a zero-byte database. */ + assert( rc==SQLITE_EMPTY || rc==SQLITE_OK ); + if( rc==SQLITE_EMPTY ){ + u.aw.pCur->pCursor = 0; + rc = SQLITE_OK; } - u.ay.pCur = allocateCursor(p, u.ay.i, u.ay.nField, u.ay.iDb, 1); - if( u.ay.pCur==0 ) goto no_mem; - u.ay.pCur->nullRow = 1; - rc = sqlite3BtreeCursor(u.ay.pX, u.ay.p2, u.ay.wrFlag, u.ay.pKeyInfo, u.ay.pCur->pCursor); - u.ay.pCur->pKeyInfo = u.ay.pKeyInfo; - switch( rc ){ - case SQLITE_BUSY: { - p->pc = pc; - p->rc = rc = SQLITE_BUSY; - goto vdbe_return; - } - case SQLITE_OK: { - u.ay.flags = sqlite3BtreeFlags(u.ay.pCur->pCursor); - /* Sanity checking. Only the lower four bits of the u.ay.flags byte should - ** be used. Bit 3 (mask 0x08) is unpredictable. The lower 3 bits - ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or - ** 2 (zerodata for indices). If these conditions are not met it can - ** only mean that we are dealing with a corrupt database file - */ - if( (u.ay.flags & 0xf0)!=0 || ((u.ay.flags & 0x07)!=5 && (u.ay.flags & 0x07)!=2) ){ - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; - } - u.ay.pCur->isTable = (u.ay.flags & BTREE_INTKEY)!=0 ?1:0; - u.ay.pCur->isIndex = (u.ay.flags & BTREE_ZERODATA)!=0 ?1:0; - /* If P4==0 it means we are expected to open a table. If P4!=0 then - ** we expect to be opening an index. If this is not what happened, - ** then the database is corrupt - */ - if( (u.ay.pCur->isTable && pOp->p4type==P4_KEYINFO) - || (u.ay.pCur->isIndex && pOp->p4type!=P4_KEYINFO) ){ - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; - } - break; - } - case SQLITE_EMPTY: { - u.ay.pCur->isTable = pOp->p4type!=P4_KEYINFO; - u.ay.pCur->isIndex = !u.ay.pCur->isTable; - u.ay.pCur->pCursor = 0; - rc = SQLITE_OK; - break; - } - default: { - goto abort_due_to_error; - } - } + /* Set the VdbeCursor.isTable and isIndex variables. Previous versions of + ** SQLite used to check if the root-page flags were sane at this point + ** and report database corruption if they were not, but this check has + ** since moved into the btree layer. */ + u.aw.pCur->isTable = pOp->p4type!=P4_KEYINFO; + u.aw.pCur->isIndex = !u.aw.pCur->isTable; break; } @@ -53938,10 +54986,9 @@ case OP_OpenWrite: { ** that created confusion with the whole virtual-table idea. */ case OP_OpenEphemeral: { -#if 0 /* local variables moved into u.az */ - int i; +#if 0 /* local variables moved into u.ax */ VdbeCursor *pCx; -#endif /* local variables moved into u.az */ +#endif /* local variables moved into u.ax */ static const int openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | @@ -53949,15 +54996,14 @@ case OP_OpenEphemeral: { SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_TRANSIENT_DB; - u.az.i = pOp->p1; - assert( u.az.i>=0 ); - u.az.pCx = allocateCursor(p, u.az.i, pOp->p2, -1, 1); - if( u.az.pCx==0 ) goto no_mem; - u.az.pCx->nullRow = 1; + assert( pOp->p1>=0 ); + u.ax.pCx = allocateCursor(p, pOp->p1, pOp->p2, -1, 1); + if( u.ax.pCx==0 ) goto no_mem; + u.ax.pCx->nullRow = 1; rc = sqlite3BtreeFactory(db, 0, 1, SQLITE_DEFAULT_TEMP_CACHE_SIZE, openFlags, - &u.az.pCx->pBt); + &u.ax.pCx->pBt); if( rc==SQLITE_OK ){ - rc = sqlite3BtreeBeginTrans(u.az.pCx->pBt, 1); + rc = sqlite3BtreeBeginTrans(u.ax.pCx->pBt, 1); } if( rc==SQLITE_OK ){ /* If a transient index is required, create it by calling @@ -53968,62 +55014,51 @@ case OP_OpenEphemeral: { if( pOp->p4.pKeyInfo ){ int pgno; assert( pOp->p4type==P4_KEYINFO ); - rc = sqlite3BtreeCreateTable(u.az.pCx->pBt, &pgno, BTREE_ZERODATA); + rc = sqlite3BtreeCreateTable(u.ax.pCx->pBt, &pgno, BTREE_ZERODATA); if( rc==SQLITE_OK ){ assert( pgno==MASTER_ROOT+1 ); - rc = sqlite3BtreeCursor(u.az.pCx->pBt, pgno, 1, - (KeyInfo*)pOp->p4.z, u.az.pCx->pCursor); - u.az.pCx->pKeyInfo = pOp->p4.pKeyInfo; - u.az.pCx->pKeyInfo->enc = ENC(p->db); + rc = sqlite3BtreeCursor(u.ax.pCx->pBt, pgno, 1, + (KeyInfo*)pOp->p4.z, u.ax.pCx->pCursor); + u.ax.pCx->pKeyInfo = pOp->p4.pKeyInfo; + u.ax.pCx->pKeyInfo->enc = ENC(p->db); } - u.az.pCx->isTable = 0; + u.ax.pCx->isTable = 0; }else{ - rc = sqlite3BtreeCursor(u.az.pCx->pBt, MASTER_ROOT, 1, 0, u.az.pCx->pCursor); - u.az.pCx->isTable = 1; + rc = sqlite3BtreeCursor(u.ax.pCx->pBt, MASTER_ROOT, 1, 0, u.ax.pCx->pCursor); + u.ax.pCx->isTable = 1; } } - u.az.pCx->isIndex = !u.az.pCx->isTable; + u.ax.pCx->isIndex = !u.ax.pCx->isTable; break; } /* Opcode: OpenPseudo P1 P2 P3 * * ** ** Open a new cursor that points to a fake table that contains a single -** row of data. Any attempt to write a second row of data causes the -** first row to be deleted. All data is deleted when the cursor is -** closed. +** row of data. The content of that one row in the content of memory +** register P2. In other words, cursor P1 becomes an alias for the +** MEM_Blob content contained in register P2. ** -** A pseudo-table created by this opcode is useful for holding the -** NEW or OLD tables in a trigger. Also used to hold the a single +** A pseudo-table created by this opcode is used to hold the a single ** row output from the sorter so that the row can be decomposed into -** individual columns using the OP_Column opcode. -** -** When OP_Insert is executed to insert a row in to the pseudo table, -** the pseudo-table cursor may or may not make it's own copy of the -** original row data. If P2 is 0, then the pseudo-table will copy the -** original row data. Otherwise, a pointer to the original memory cell -** is stored. In this case, the vdbe program must ensure that the -** memory cell containing the row data is not overwritten until the -** pseudo table is closed (or a new row is inserted into it). +** individual columns using the OP_Column opcode. The OP_Column opcode +** is the only cursor opcode that works with a pseudo-table. ** ** P3 is the number of fields in the records that will be stored by ** the pseudo-table. */ case OP_OpenPseudo: { -#if 0 /* local variables moved into u.ba */ - int i; +#if 0 /* local variables moved into u.ay */ VdbeCursor *pCx; -#endif /* local variables moved into u.ba */ +#endif /* local variables moved into u.ay */ - u.ba.i = pOp->p1; - assert( u.ba.i>=0 ); - u.ba.pCx = allocateCursor(p, u.ba.i, pOp->p3, -1, 0); - if( u.ba.pCx==0 ) goto no_mem; - u.ba.pCx->nullRow = 1; - u.ba.pCx->pseudoTable = 1; - u.ba.pCx->ephemPseudoTable = (u8)pOp->p2; - u.ba.pCx->isTable = 1; - u.ba.pCx->isIndex = 0; + assert( pOp->p1>=0 ); + u.ay.pCx = allocateCursor(p, pOp->p1, pOp->p3, -1, 0); + if( u.ay.pCx==0 ) goto no_mem; + u.ay.pCx->nullRow = 1; + u.ay.pCx->pseudoTableReg = pOp->p2; + u.ay.pCx->isTable = 1; + u.ay.pCx->isIndex = 0; break; } @@ -54033,13 +55068,9 @@ case OP_OpenPseudo: { ** currently open, this instruction is a no-op. */ case OP_Close: { -#if 0 /* local variables moved into u.bb */ - int i; -#endif /* local variables moved into u.bb */ - u.bb.i = pOp->p1; - assert( u.bb.i>=0 && u.bb.inCursor ); - sqlite3VdbeFreeCursor(p, p->apCsr[u.bb.i]); - p->apCsr[u.bb.i] = 0; + assert( pOp->p1>=0 && pOp->p1nCursor ); + sqlite3VdbeFreeCursor(p, p->apCsr[pOp->p1]); + p->apCsr[pOp->p1] = 0; break; } @@ -54099,31 +55130,30 @@ case OP_SeekLt: /* jump, in3 */ case OP_SeekLe: /* jump, in3 */ case OP_SeekGe: /* jump, in3 */ case OP_SeekGt: { /* jump, in3 */ -#if 0 /* local variables moved into u.bc */ - int i; +#if 0 /* local variables moved into u.az */ int res; int oc; VdbeCursor *pC; UnpackedRecord r; int nField; i64 iKey; /* The rowid we are to seek to */ -#endif /* local variables moved into u.bc */ +#endif /* local variables moved into u.az */ - u.bc.i = pOp->p1; - assert( u.bc.i>=0 && u.bc.inCursor ); + assert( pOp->p1>=0 && pOp->p1nCursor ); assert( pOp->p2!=0 ); - u.bc.pC = p->apCsr[u.bc.i]; - assert( u.bc.pC!=0 ); - if( u.bc.pC->pCursor!=0 ){ - u.bc.oc = pOp->opcode; - u.bc.pC->nullRow = 0; - if( u.bc.pC->isTable ){ + u.az.pC = p->apCsr[pOp->p1]; + assert( u.az.pC!=0 ); + assert( u.az.pC->pseudoTableReg==0 ); + if( u.az.pC->pCursor!=0 ){ + u.az.oc = pOp->opcode; + u.az.pC->nullRow = 0; + if( u.az.pC->isTable ){ /* The input value in P3 might be of any type: integer, real, string, ** blob, or NULL. But it needs to be an integer before we can do ** the seek, so covert it. */ applyNumericAffinity(pIn3); - u.bc.iKey = sqlite3VdbeIntValue(pIn3); - u.bc.pC->rowidIsValid = 0; + u.az.iKey = sqlite3VdbeIntValue(pIn3); + u.az.pC->rowidIsValid = 0; /* If the P3 value could not be converted into an integer without ** loss of information, then special processing is required... */ @@ -54138,91 +55168,91 @@ case OP_SeekGt: { /* jump, in3 */ ** point number. */ assert( (pIn3->flags & MEM_Real)!=0 ); - if( u.bc.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.bc.iKey || pIn3->r>0) ){ - /* The P3 value is to large in magnitude to be expressed as an + if( u.az.iKey==SMALLEST_INT64 && (pIn3->r<(double)u.az.iKey || pIn3->r>0) ){ + /* The P3 value is too large in magnitude to be expressed as an ** integer. */ - u.bc.res = 1; + u.az.res = 1; if( pIn3->r<0 ){ - if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekGe ){ - rc = sqlite3BtreeFirst(u.bc.pC->pCursor, &u.bc.res); + if( u.az.oc==OP_SeekGt || u.az.oc==OP_SeekGe ){ + rc = sqlite3BtreeFirst(u.az.pC->pCursor, &u.az.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; } }else{ - if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe ){ - rc = sqlite3BtreeLast(u.bc.pC->pCursor, &u.bc.res); + if( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekLe ){ + rc = sqlite3BtreeLast(u.az.pC->pCursor, &u.az.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; } } - if( u.bc.res ){ + if( u.az.res ){ pc = pOp->p2 - 1; } break; - }else if( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekGe ){ + }else if( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekGe ){ /* Use the ceiling() function to convert real->int */ - if( pIn3->r > (double)u.bc.iKey ) u.bc.iKey++; + if( pIn3->r > (double)u.az.iKey ) u.az.iKey++; }else{ /* Use the floor() function to convert real->int */ - assert( u.bc.oc==OP_SeekLe || u.bc.oc==OP_SeekGt ); - if( pIn3->r < (double)u.bc.iKey ) u.bc.iKey--; + assert( u.az.oc==OP_SeekLe || u.az.oc==OP_SeekGt ); + if( pIn3->r < (double)u.az.iKey ) u.az.iKey--; } } - rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, 0, (u64)u.bc.iKey, 0, &u.bc.res); + rc = sqlite3BtreeMovetoUnpacked(u.az.pC->pCursor, 0, (u64)u.az.iKey, 0, &u.az.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - if( u.bc.res==0 ){ - u.bc.pC->rowidIsValid = 1; - u.bc.pC->lastRowid = u.bc.iKey; + if( u.az.res==0 ){ + u.az.pC->rowidIsValid = 1; + u.az.pC->lastRowid = u.az.iKey; } }else{ - u.bc.nField = pOp->p4.i; + u.az.nField = pOp->p4.i; assert( pOp->p4type==P4_INT32 ); - assert( u.bc.nField>0 ); - u.bc.r.pKeyInfo = u.bc.pC->pKeyInfo; - u.bc.r.nField = (u16)u.bc.nField; - if( u.bc.oc==OP_SeekGt || u.bc.oc==OP_SeekLe ){ - u.bc.r.flags = UNPACKED_INCRKEY; + assert( u.az.nField>0 ); + u.az.r.pKeyInfo = u.az.pC->pKeyInfo; + u.az.r.nField = (u16)u.az.nField; + if( u.az.oc==OP_SeekGt || u.az.oc==OP_SeekLe ){ + u.az.r.flags = UNPACKED_INCRKEY; }else{ - u.bc.r.flags = 0; + u.az.r.flags = 0; } - u.bc.r.aMem = &p->aMem[pOp->p3]; - rc = sqlite3BtreeMovetoUnpacked(u.bc.pC->pCursor, &u.bc.r, 0, 0, &u.bc.res); + u.az.r.aMem = &p->aMem[pOp->p3]; + rc = sqlite3BtreeMovetoUnpacked(u.az.pC->pCursor, &u.az.r, 0, 0, &u.az.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - u.bc.pC->rowidIsValid = 0; + u.az.pC->rowidIsValid = 0; } - u.bc.pC->deferredMoveto = 0; - u.bc.pC->cacheStatus = CACHE_STALE; + u.az.pC->deferredMoveto = 0; + u.az.pC->cacheStatus = CACHE_STALE; #ifdef SQLITE_TEST sqlite3_search_count++; #endif - if( u.bc.oc==OP_SeekGe || u.bc.oc==OP_SeekGt ){ - if( u.bc.res<0 || (u.bc.res==0 && u.bc.oc==OP_SeekGt) ){ - rc = sqlite3BtreeNext(u.bc.pC->pCursor, &u.bc.res); + if( u.az.oc==OP_SeekGe || u.az.oc==OP_SeekGt ){ + if( u.az.res<0 || (u.az.res==0 && u.az.oc==OP_SeekGt) ){ + rc = sqlite3BtreeNext(u.az.pC->pCursor, &u.az.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; - u.bc.pC->rowidIsValid = 0; + u.az.pC->rowidIsValid = 0; }else{ - u.bc.res = 0; + u.az.res = 0; } }else{ - assert( u.bc.oc==OP_SeekLt || u.bc.oc==OP_SeekLe ); - if( u.bc.res>0 || (u.bc.res==0 && u.bc.oc==OP_SeekLt) ){ - rc = sqlite3BtreePrevious(u.bc.pC->pCursor, &u.bc.res); + assert( u.az.oc==OP_SeekLt || u.az.oc==OP_SeekLe ); + if( u.az.res>0 || (u.az.res==0 && u.az.oc==OP_SeekLt) ){ + rc = sqlite3BtreePrevious(u.az.pC->pCursor, &u.az.res); if( rc!=SQLITE_OK ) goto abort_due_to_error; - u.bc.pC->rowidIsValid = 0; + u.az.pC->rowidIsValid = 0; }else{ - /* u.bc.res might be negative because the table is empty. Check to + /* u.az.res might be negative because the table is empty. Check to ** see if this is the case. */ - u.bc.res = sqlite3BtreeEof(u.bc.pC->pCursor); + u.az.res = sqlite3BtreeEof(u.az.pC->pCursor); } } assert( pOp->p2>0 ); - if( u.bc.res ){ + if( u.az.res ){ pc = pOp->p2 - 1; } - }else if( !u.bc.pC->pseudoTable ){ + }else{ /* This happens when attempting to open the sqlite3_master table ** for read access returns SQLITE_EMPTY. In this case always ** take the jump (since there are no records in the table). @@ -54242,21 +55272,19 @@ case OP_SeekGt: { /* jump, in3 */ ** occur, no unnecessary I/O happens. */ case OP_Seek: { /* in2 */ -#if 0 /* local variables moved into u.bd */ - int i; +#if 0 /* local variables moved into u.ba */ VdbeCursor *pC; -#endif /* local variables moved into u.bd */ +#endif /* local variables moved into u.ba */ - u.bd.i = pOp->p1; - assert( u.bd.i>=0 && u.bd.inCursor ); - u.bd.pC = p->apCsr[u.bd.i]; - assert( u.bd.pC!=0 ); - if( u.bd.pC->pCursor!=0 ){ - assert( u.bd.pC->isTable ); - u.bd.pC->nullRow = 0; - u.bd.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); - u.bd.pC->rowidIsValid = 0; - u.bd.pC->deferredMoveto = 1; + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.ba.pC = p->apCsr[pOp->p1]; + assert( u.ba.pC!=0 ); + if( ALWAYS(u.ba.pC->pCursor!=0) ){ + assert( u.ba.pC->isTable ); + u.ba.pC->nullRow = 0; + u.ba.pC->movetoTarget = sqlite3VdbeIntValue(pIn2); + u.ba.pC->rowidIsValid = 0; + u.ba.pC->deferredMoveto = 1; } break; } @@ -54294,44 +55322,48 @@ case OP_Seek: { /* in2 */ */ case OP_NotFound: /* jump, in3 */ case OP_Found: { /* jump, in3 */ -#if 0 /* local variables moved into u.be */ - int i; +#if 0 /* local variables moved into u.bb */ int alreadyExists; VdbeCursor *pC; int res; UnpackedRecord *pIdxKey; char aTempRec[ROUND8(sizeof(UnpackedRecord)) + sizeof(Mem)*3 + 7]; -#endif /* local variables moved into u.be */ +#endif /* local variables moved into u.bb */ - u.be.i = pOp->p1; - u.be.alreadyExists = 0; - assert( u.be.i>=0 && u.be.inCursor ); - assert( p->apCsr[u.be.i]!=0 ); - if( (u.be.pC = p->apCsr[u.be.i])->pCursor!=0 ){ +#ifdef SQLITE_TEST + sqlite3_found_count++; +#endif + + u.bb.alreadyExists = 0; + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bb.pC = p->apCsr[pOp->p1]; + assert( u.bb.pC!=0 ); + if( ALWAYS(u.bb.pC->pCursor!=0) ){ - assert( u.be.pC->isTable==0 ); + assert( u.bb.pC->isTable==0 ); assert( pIn3->flags & MEM_Blob ); - u.be.pIdxKey = sqlite3VdbeRecordUnpack(u.be.pC->pKeyInfo, pIn3->n, pIn3->z, - u.be.aTempRec, sizeof(u.be.aTempRec)); - if( u.be.pIdxKey==0 ){ + ExpandBlob(pIn3); + u.bb.pIdxKey = sqlite3VdbeRecordUnpack(u.bb.pC->pKeyInfo, pIn3->n, pIn3->z, + u.bb.aTempRec, sizeof(u.bb.aTempRec)); + if( u.bb.pIdxKey==0 ){ goto no_mem; } if( pOp->opcode==OP_Found ){ - u.be.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; + u.bb.pIdxKey->flags |= UNPACKED_PREFIX_MATCH; } - rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, u.be.pIdxKey, 0, 0, &u.be.res); - sqlite3VdbeDeleteUnpackedRecord(u.be.pIdxKey); + rc = sqlite3BtreeMovetoUnpacked(u.bb.pC->pCursor, u.bb.pIdxKey, 0, 0, &u.bb.res); + sqlite3VdbeDeleteUnpackedRecord(u.bb.pIdxKey); if( rc!=SQLITE_OK ){ break; } - u.be.alreadyExists = (u.be.res==0); - u.be.pC->deferredMoveto = 0; - u.be.pC->cacheStatus = CACHE_STALE; + u.bb.alreadyExists = (u.bb.res==0); + u.bb.pC->deferredMoveto = 0; + u.bb.pC->cacheStatus = CACHE_STALE; } if( pOp->opcode==OP_Found ){ - if( u.be.alreadyExists ) pc = pOp->p2 - 1; + if( u.bb.alreadyExists ) pc = pOp->p2 - 1; }else{ - if( !u.be.alreadyExists ) pc = pOp->p2 - 1; + if( !u.bb.alreadyExists ) pc = pOp->p2 - 1; } break; } @@ -54362,7 +55394,7 @@ case OP_Found: { /* jump, in3 */ ** See also: NotFound, NotExists, Found */ case OP_IsUnique: { /* jump, in3 */ -#if 0 /* local variables moved into u.bf */ +#if 0 /* local variables moved into u.bc */ u16 ii; VdbeCursor *pCx; BtCursor *pCrsr; @@ -54370,51 +55402,51 @@ case OP_IsUnique: { /* jump, in3 */ Mem *aMem; UnpackedRecord r; /* B-Tree index search key */ i64 R; /* Rowid stored in register P3 */ -#endif /* local variables moved into u.bf */ +#endif /* local variables moved into u.bc */ - u.bf.aMem = &p->aMem[pOp->p4.i]; + u.bc.aMem = &p->aMem[pOp->p4.i]; /* Assert that the values of parameters P1 and P4 are in range. */ assert( pOp->p4type==P4_INT32 ); assert( pOp->p4.i>0 && pOp->p4.i<=p->nMem ); assert( pOp->p1>=0 && pOp->p1nCursor ); /* Find the index cursor. */ - u.bf.pCx = p->apCsr[pOp->p1]; - assert( u.bf.pCx->deferredMoveto==0 ); - u.bf.pCx->seekResult = 0; - u.bf.pCx->cacheStatus = CACHE_STALE; - u.bf.pCrsr = u.bf.pCx->pCursor; + u.bc.pCx = p->apCsr[pOp->p1]; + assert( u.bc.pCx->deferredMoveto==0 ); + u.bc.pCx->seekResult = 0; + u.bc.pCx->cacheStatus = CACHE_STALE; + u.bc.pCrsr = u.bc.pCx->pCursor; /* If any of the values are NULL, take the jump. */ - u.bf.nField = u.bf.pCx->pKeyInfo->nField; - for(u.bf.ii=0; u.bf.iipKeyInfo->nField; + for(u.bc.ii=0; u.bc.iip2 - 1; - u.bf.pCrsr = 0; + u.bc.pCrsr = 0; break; } } - assert( (u.bf.aMem[u.bf.nField].flags & MEM_Null)==0 ); + assert( (u.bc.aMem[u.bc.nField].flags & MEM_Null)==0 ); - if( u.bf.pCrsr!=0 ){ + if( u.bc.pCrsr!=0 ){ /* Populate the index search key. */ - u.bf.r.pKeyInfo = u.bf.pCx->pKeyInfo; - u.bf.r.nField = u.bf.nField + 1; - u.bf.r.flags = UNPACKED_PREFIX_SEARCH; - u.bf.r.aMem = u.bf.aMem; + u.bc.r.pKeyInfo = u.bc.pCx->pKeyInfo; + u.bc.r.nField = u.bc.nField + 1; + u.bc.r.flags = UNPACKED_PREFIX_SEARCH; + u.bc.r.aMem = u.bc.aMem; - /* Extract the value of u.bf.R from register P3. */ + /* Extract the value of u.bc.R from register P3. */ sqlite3VdbeMemIntegerify(pIn3); - u.bf.R = pIn3->u.i; + u.bc.R = pIn3->u.i; /* Search the B-Tree index. If no conflicting record is found, jump ** to P2. Otherwise, copy the rowid of the conflicting record to ** register P3 and fall through to the next instruction. */ - rc = sqlite3BtreeMovetoUnpacked(u.bf.pCrsr, &u.bf.r, 0, 0, &u.bf.pCx->seekResult); - if( (u.bf.r.flags & UNPACKED_PREFIX_SEARCH) || u.bf.r.rowid==u.bf.R ){ + rc = sqlite3BtreeMovetoUnpacked(u.bc.pCrsr, &u.bc.r, 0, 0, &u.bc.pCx->seekResult); + if( (u.bc.r.flags & UNPACKED_PREFIX_SEARCH) || u.bc.r.rowid==u.bc.R ){ pc = pOp->p2 - 1; }else{ - pIn3->u.i = u.bf.r.rowid; + pIn3->u.i = u.bc.r.rowid; } } break; @@ -54435,41 +55467,41 @@ case OP_IsUnique: { /* jump, in3 */ ** See also: Found, NotFound, IsUnique */ case OP_NotExists: { /* jump, in3 */ -#if 0 /* local variables moved into u.bg */ - int i; +#if 0 /* local variables moved into u.bd */ VdbeCursor *pC; BtCursor *pCrsr; int res; u64 iKey; -#endif /* local variables moved into u.bg */ +#endif /* local variables moved into u.bd */ - u.bg.i = pOp->p1; - assert( u.bg.i>=0 && u.bg.inCursor ); - assert( p->apCsr[u.bg.i]!=0 ); - if( (u.bg.pCrsr = (u.bg.pC = p->apCsr[u.bg.i])->pCursor)!=0 ){ - u.bg.res = 0; - assert( pIn3->flags & MEM_Int ); - assert( p->apCsr[u.bg.i]->isTable ); - u.bg.iKey = intToKey(pIn3->u.i); - rc = sqlite3BtreeMovetoUnpacked(u.bg.pCrsr, 0, u.bg.iKey, 0, &u.bg.res); - u.bg.pC->lastRowid = pIn3->u.i; - u.bg.pC->rowidIsValid = u.bg.res==0 ?1:0; - u.bg.pC->nullRow = 0; - u.bg.pC->cacheStatus = CACHE_STALE; - u.bg.pC->deferredMoveto = 0; - if( u.bg.res!=0 ){ + assert( pIn3->flags & MEM_Int ); + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bd.pC = p->apCsr[pOp->p1]; + assert( u.bd.pC!=0 ); + assert( u.bd.pC->isTable ); + assert( u.bd.pC->pseudoTableReg==0 ); + u.bd.pCrsr = u.bd.pC->pCursor; + if( u.bd.pCrsr!=0 ){ + u.bd.res = 0; + u.bd.iKey = pIn3->u.i; + rc = sqlite3BtreeMovetoUnpacked(u.bd.pCrsr, 0, u.bd.iKey, 0, &u.bd.res); + u.bd.pC->lastRowid = pIn3->u.i; + u.bd.pC->rowidIsValid = u.bd.res==0 ?1:0; + u.bd.pC->nullRow = 0; + u.bd.pC->cacheStatus = CACHE_STALE; + u.bd.pC->deferredMoveto = 0; + if( u.bd.res!=0 ){ pc = pOp->p2 - 1; - assert( u.bg.pC->rowidIsValid==0 ); + assert( u.bd.pC->rowidIsValid==0 ); } - u.bg.pC->seekResult = u.bg.res; - }else if( !u.bg.pC->pseudoTable ){ + u.bd.pC->seekResult = u.bd.res; + }else{ /* This happens when an attempt to open a read cursor on the ** sqlite_master table returns SQLITE_EMPTY. */ - assert( u.bg.pC->isTable ); pc = pOp->p2 - 1; - assert( u.bg.pC->rowidIsValid==0 ); - u.bg.pC->seekResult = 0; + assert( u.bd.pC->rowidIsValid==0 ); + u.bd.pC->seekResult = 0; } break; } @@ -54482,10 +55514,9 @@ case OP_NotExists: { /* jump, in3 */ ** instruction. */ case OP_Sequence: { /* out2-prerelease */ - int i = pOp->p1; - assert( i>=0 && inCursor ); - assert( p->apCsr[i]!=0 ); - pOut->u.i = p->apCsr[i]->seqCount++; + assert( pOp->p1>=0 && pOp->p1nCursor ); + assert( p->apCsr[pOp->p1]!=0 ); + pOut->u.i = p->apCsr[pOp->p1]->seqCount++; MemSetTypeFlag(pOut, MEM_Int); break; } @@ -54498,32 +55529,29 @@ case OP_Sequence: { /* out2-prerelease */ ** table that cursor P1 points to. The new record number is written ** written to register P2. ** -** If P3>0 then P3 is a register that holds the largest previously -** generated record number. No new record numbers are allowed to be less -** than this value. When this value reaches its maximum, a SQLITE_FULL -** error is generated. The P3 register is updated with the generated -** record number. This P3 mechanism is used to help implement the +** If P3>0 then P3 is a register in the root frame of this VDBE that holds +** the largest previously generated record number. No new record numbers are +** allowed to be less than this value. When this value reaches its maximum, +** a SQLITE_FULL error is generated. The P3 register is updated with the ' +** generated record number. This P3 mechanism is used to help implement the ** AUTOINCREMENT feature. */ case OP_NewRowid: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bh */ - int i; - i64 v; - VdbeCursor *pC; - int res; - int rx; - int cnt; - i64 x; - Mem *pMem; -#endif /* local variables moved into u.bh */ +#if 0 /* local variables moved into u.be */ + i64 v; /* The new rowid */ + VdbeCursor *pC; /* Cursor of table to get the new rowid */ + int res; /* Result of an sqlite3BtreeLast() */ + int cnt; /* Counter to limit the number of searches */ + Mem *pMem; /* Register holding largest rowid for AUTOINCREMENT */ + VdbeFrame *pFrame; /* Root frame of VDBE */ +#endif /* local variables moved into u.be */ - u.bh.i = pOp->p1; - u.bh.v = 0; - u.bh.res = 0; - u.bh.rx = SQLITE_OK; - assert( u.bh.i>=0 && u.bh.inCursor ); - assert( p->apCsr[u.bh.i]!=0 ); - if( (u.bh.pC = p->apCsr[u.bh.i])->pCursor==0 ){ + u.be.v = 0; + u.be.res = 0; + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.be.pC = p->apCsr[pOp->p1]; + assert( u.be.pC!=0 ); + if( NEVER(u.be.pC->pCursor==0) ){ /* The zero initialization above is all that is needed */ }else{ /* The next rowid or record number (different terms for the same @@ -54537,34 +55565,10 @@ case OP_NewRowid: { /* out2-prerelease */ ** The second algorithm is to select a rowid at random and see if ** it already exists in the table. If it does not exist, we have ** succeeded. If the random rowid does exist, we select a new one - ** and try again, up to 1000 times. - ** - ** For a table with less than 2 billion entries, the probability - ** of not finding a unused rowid is about 1.0e-300. This is a - ** non-zero probability, but it is still vanishingly small and should - ** never cause a problem. You are much, much more likely to have a - ** hardware failure than for this algorithm to fail. - ** - ** The analysis in the previous paragraph assumes that you have a good - ** source of random numbers. Is a library function like lrand48() - ** good enough? Maybe. Maybe not. It's hard to know whether there - ** might be subtle bugs is some implementations of lrand48() that - ** could cause problems. To avoid uncertainty, SQLite uses its own - ** random number generator based on the RC4 algorithm. - ** - ** To promote locality of reference for repetitive inserts, the - ** first few attempts at choosing a random rowid pick values just a little - ** larger than the previous rowid. This has been shown experimentally - ** to double the speed of the COPY operation. + ** and try again, up to 100 times. */ - u.bh.cnt = 0; - if( (sqlite3BtreeFlags(u.bh.pC->pCursor)&(BTREE_INTKEY|BTREE_ZERODATA)) != - BTREE_INTKEY ){ - rc = SQLITE_CORRUPT_BKPT; - goto abort_due_to_error; - } - assert( (sqlite3BtreeFlags(u.bh.pC->pCursor) & BTREE_INTKEY)!=0 ); - assert( (sqlite3BtreeFlags(u.bh.pC->pCursor) & BTREE_ZERODATA)==0 ); + assert( u.be.pC->isTable ); + u.be.cnt = 0; #ifdef SQLITE_32BIT_ROWID # define MAX_ROWID 0x7fffffff @@ -54576,74 +55580,84 @@ case OP_NewRowid: { /* out2-prerelease */ # define MAX_ROWID (i64)( (((u64)0x7fffffff)<<32) | (u64)0xffffffff ) #endif - if( !u.bh.pC->useRandomRowid ){ - u.bh.v = sqlite3BtreeGetCachedRowid(u.bh.pC->pCursor); - if( u.bh.v==0 ){ - rc = sqlite3BtreeLast(u.bh.pC->pCursor, &u.bh.res); + if( !u.be.pC->useRandomRowid ){ + u.be.v = sqlite3BtreeGetCachedRowid(u.be.pC->pCursor); + if( u.be.v==0 ){ + rc = sqlite3BtreeLast(u.be.pC->pCursor, &u.be.res); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } - if( u.bh.res ){ - u.bh.v = 1; + if( u.be.res ){ + u.be.v = 1; }else{ - sqlite3BtreeKeySize(u.bh.pC->pCursor, &u.bh.v); - u.bh.v = keyToInt(u.bh.v); - if( u.bh.v==MAX_ROWID ){ - u.bh.pC->useRandomRowid = 1; + assert( sqlite3BtreeCursorIsValid(u.be.pC->pCursor) ); + rc = sqlite3BtreeKeySize(u.be.pC->pCursor, &u.be.v); + assert( rc==SQLITE_OK ); /* Cannot fail following BtreeLast() */ + if( u.be.v==MAX_ROWID ){ + u.be.pC->useRandomRowid = 1; }else{ - u.bh.v++; + u.be.v++; } } } #ifndef SQLITE_OMIT_AUTOINCREMENT if( pOp->p3 ){ - assert( pOp->p3>0 && pOp->p3<=p->nMem ); /* P3 is a valid memory cell */ - u.bh.pMem = &p->aMem[pOp->p3]; - REGISTER_TRACE(pOp->p3, u.bh.pMem); - sqlite3VdbeMemIntegerify(u.bh.pMem); - assert( (u.bh.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ - if( u.bh.pMem->u.i==MAX_ROWID || u.bh.pC->useRandomRowid ){ + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3>0 ); + if( p->pFrame ){ + for(u.be.pFrame=p->pFrame; u.be.pFrame->pParent; u.be.pFrame=u.be.pFrame->pParent); + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3<=u.be.pFrame->nMem ); + u.be.pMem = &u.be.pFrame->aMem[pOp->p3]; + }else{ + /* Assert that P3 is a valid memory cell. */ + assert( pOp->p3<=p->nMem ); + u.be.pMem = &p->aMem[pOp->p3]; + } + + REGISTER_TRACE(pOp->p3, u.be.pMem); + sqlite3VdbeMemIntegerify(u.be.pMem); + assert( (u.be.pMem->flags & MEM_Int)!=0 ); /* mem(P3) holds an integer */ + if( u.be.pMem->u.i==MAX_ROWID || u.be.pC->useRandomRowid ){ rc = SQLITE_FULL; goto abort_due_to_error; } - if( u.bh.vu.i+1 ){ - u.bh.v = u.bh.pMem->u.i + 1; + if( u.be.vu.i+1 ){ + u.be.v = u.be.pMem->u.i + 1; } - u.bh.pMem->u.i = u.bh.v; + u.be.pMem->u.i = u.be.v; } #endif - sqlite3BtreeSetCachedRowid(u.bh.pC->pCursor, u.bh.vpCursor, u.be.vuseRandomRowid ){ - assert( pOp->p3==0 ); /* SQLITE_FULL must have occurred prior to this */ - u.bh.v = db->priorNewRowid; - u.bh.cnt = 0; + if( u.be.pC->useRandomRowid ){ + assert( pOp->p3==0 ); /* We cannot be in random rowid mode if this is + ** an AUTOINCREMENT table. */ + u.be.v = db->lastRowid; + u.be.cnt = 0; do{ - if( u.bh.cnt==0 && (u.bh.v&0xffffff)==u.bh.v ){ - u.bh.v++; + if( u.be.cnt==0 && (u.be.v&0xffffff)==u.be.v ){ + u.be.v++; }else{ - sqlite3_randomness(sizeof(u.bh.v), &u.bh.v); - if( u.bh.cnt<5 ) u.bh.v &= 0xffffff; + sqlite3_randomness(sizeof(u.be.v), &u.be.v); + if( u.be.cnt<5 ) u.be.v &= 0xffffff; } - if( u.bh.v==0 ) continue; - u.bh.x = intToKey(u.bh.v); - u.bh.rx = sqlite3BtreeMovetoUnpacked(u.bh.pC->pCursor, 0, (u64)u.bh.x, 0, &u.bh.res); - u.bh.cnt++; - }while( u.bh.cnt<100 && u.bh.rx==SQLITE_OK && u.bh.res==0 ); - db->priorNewRowid = u.bh.v; - if( u.bh.rx==SQLITE_OK && u.bh.res==0 ){ + rc = sqlite3BtreeMovetoUnpacked(u.be.pC->pCursor, 0, (u64)u.be.v, 0, &u.be.res); + u.be.cnt++; + }while( u.be.cnt<100 && rc==SQLITE_OK && u.be.res==0 ); + if( rc==SQLITE_OK && u.be.res==0 ){ rc = SQLITE_FULL; goto abort_due_to_error; } } - u.bh.pC->rowidIsValid = 0; - u.bh.pC->deferredMoveto = 0; - u.bh.pC->cacheStatus = CACHE_STALE; + u.be.pC->rowidIsValid = 0; + u.be.pC->deferredMoveto = 0; + u.be.pC->cacheStatus = CACHE_STALE; } MemSetTypeFlag(pOut, MEM_Int); - pOut->u.i = u.bh.v; + pOut->u.i = u.be.v; break; } @@ -54651,15 +55665,28 @@ case OP_NewRowid: { /* out2-prerelease */ ** ** Write an entry into the table of cursor P1. A new entry is ** created if it doesn't already exist or the data for an existing -** entry is overwritten. The data is the value stored register +** entry is overwritten. The data is the value MEM_Blob stored in register ** number P2. The key is stored in register P3. The key must -** be an integer. +** be a MEM_Int. ** ** If the OPFLAG_NCHANGE flag of P5 is set, then the row change count is ** incremented (otherwise not). If the OPFLAG_LASTROWID flag of P5 is set, ** then rowid is stored for subsequent return by the ** sqlite3_last_insert_rowid() function (otherwise it is unmodified). ** +** If the OPFLAG_USESEEKRESULT flag of P5 is set and if the result of +** the last seek operation (OP_NotExists) was a success, then this +** operation will not attempt to find the appropriate row before doing +** the insert but will instead overwrite the row that the cursor is +** currently pointing to. Presumably, the prior OP_NotExists opcode +** has already positioned the cursor correctly. This is an optimization +** that boosts performance by avoiding redundant seeks. +** +** If the OPFLAG_ISUPDATE flag is set, then this opcode is part of an +** UPDATE operation. Otherwise (if the flag is clear) then this opcode +** is part of an INSERT operation. The difference is only important to +** the update hook. +** ** Parameter P4 may point to a string containing the table-name, or ** may be NULL. If it is not NULL, then the update-hook ** (sqlite3.xUpdateCallback) is invoked following a successful insert. @@ -54674,87 +55701,62 @@ case OP_NewRowid: { /* out2-prerelease */ ** for indices is OP_IdxInsert. */ case OP_Insert: { -#if 0 /* local variables moved into u.bi */ - Mem *pData; - Mem *pKey; - i64 iKey; /* The integer ROWID or key for the record to be inserted */ - int i; - VdbeCursor *pC; - int nZero; - int seekResult; - const char *zDb; - const char *zTbl; - int op; -#endif /* local variables moved into u.bi */ - - u.bi.pData = &p->aMem[pOp->p2]; - u.bi.pKey = &p->aMem[pOp->p3]; - u.bi.i = pOp->p1; - assert( u.bi.i>=0 && u.bi.inCursor ); - u.bi.pC = p->apCsr[u.bi.i]; - assert( u.bi.pC!=0 ); - assert( u.bi.pC->pCursor!=0 || u.bi.pC->pseudoTable ); - assert( u.bi.pKey->flags & MEM_Int ); - assert( u.bi.pC->isTable ); - REGISTER_TRACE(pOp->p2, u.bi.pData); - REGISTER_TRACE(pOp->p3, u.bi.pKey); +#if 0 /* local variables moved into u.bf */ + Mem *pData; /* MEM cell holding data for the record to be inserted */ + Mem *pKey; /* MEM cell holding key for the record */ + i64 iKey; /* The integer ROWID or key for the record to be inserted */ + VdbeCursor *pC; /* Cursor to table into which insert is written */ + int nZero; /* Number of zero-bytes to append */ + int seekResult; /* Result of prior seek or 0 if no USESEEKRESULT flag */ + const char *zDb; /* database name - used by the update hook */ + const char *zTbl; /* Table name - used by the opdate hook */ + int op; /* Opcode for update hook: SQLITE_UPDATE or SQLITE_INSERT */ +#endif /* local variables moved into u.bf */ - u.bi.iKey = intToKey(u.bi.pKey->u.i); + u.bf.pData = &p->aMem[pOp->p2]; + u.bf.pKey = &p->aMem[pOp->p3]; + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bf.pC = p->apCsr[pOp->p1]; + assert( u.bf.pC!=0 ); + assert( u.bf.pC->pCursor!=0 ); + assert( u.bf.pC->pseudoTableReg==0 ); + assert( u.bf.pKey->flags & MEM_Int ); + assert( u.bf.pC->isTable ); + REGISTER_TRACE(pOp->p2, u.bf.pData); + REGISTER_TRACE(pOp->p3, u.bf.pKey); + + u.bf.iKey = u.bf.pKey->u.i; if( pOp->p5 & OPFLAG_NCHANGE ) p->nChange++; - if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = u.bi.pKey->u.i; - if( u.bi.pData->flags & MEM_Null ){ - u.bi.pData->z = 0; - u.bi.pData->n = 0; + if( pOp->p5 & OPFLAG_LASTROWID ) db->lastRowid = u.bf.pKey->u.i; + if( u.bf.pData->flags & MEM_Null ){ + u.bf.pData->z = 0; + u.bf.pData->n = 0; }else{ - assert( u.bi.pData->flags & (MEM_Blob|MEM_Str) ); + assert( u.bf.pData->flags & (MEM_Blob|MEM_Str) ); } - if( u.bi.pC->pseudoTable ){ - if( !u.bi.pC->ephemPseudoTable ){ - sqlite3DbFree(db, u.bi.pC->pData); - } - u.bi.pC->iKey = u.bi.iKey; - u.bi.pC->nData = u.bi.pData->n; - if( u.bi.pData->z==u.bi.pData->zMalloc || u.bi.pC->ephemPseudoTable ){ - u.bi.pC->pData = u.bi.pData->z; - if( !u.bi.pC->ephemPseudoTable ){ - u.bi.pData->flags &= ~MEM_Dyn; - u.bi.pData->flags |= MEM_Ephem; - u.bi.pData->zMalloc = 0; - } - }else{ - u.bi.pC->pData = sqlite3Malloc( u.bi.pC->nData+2 ); - if( !u.bi.pC->pData ) goto no_mem; - memcpy(u.bi.pC->pData, u.bi.pData->z, u.bi.pC->nData); - u.bi.pC->pData[u.bi.pC->nData] = 0; - u.bi.pC->pData[u.bi.pC->nData+1] = 0; - } - u.bi.pC->nullRow = 0; + u.bf.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bf.pC->seekResult : 0); + if( u.bf.pData->flags & MEM_Zero ){ + u.bf.nZero = u.bf.pData->u.nZero; }else{ - u.bi.seekResult = ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bi.pC->seekResult : 0); - if( u.bi.pData->flags & MEM_Zero ){ - u.bi.nZero = u.bi.pData->u.nZero; - }else{ - u.bi.nZero = 0; - } - sqlite3BtreeSetCachedRowid(u.bi.pC->pCursor, 0); - rc = sqlite3BtreeInsert(u.bi.pC->pCursor, 0, u.bi.iKey, - u.bi.pData->z, u.bi.pData->n, u.bi.nZero, - pOp->p5 & OPFLAG_APPEND, u.bi.seekResult - ); + u.bf.nZero = 0; } - - u.bi.pC->rowidIsValid = 0; - u.bi.pC->deferredMoveto = 0; - u.bi.pC->cacheStatus = CACHE_STALE; + sqlite3BtreeSetCachedRowid(u.bf.pC->pCursor, 0); + rc = sqlite3BtreeInsert(u.bf.pC->pCursor, 0, u.bf.iKey, + u.bf.pData->z, u.bf.pData->n, u.bf.nZero, + pOp->p5 & OPFLAG_APPEND, u.bf.seekResult + ); + u.bf.pC->rowidIsValid = 0; + u.bf.pC->deferredMoveto = 0; + u.bf.pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ - u.bi.zDb = db->aDb[u.bi.pC->iDb].zName; - u.bi.zTbl = pOp->p4.z; - u.bi.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); - assert( u.bi.pC->isTable ); - db->xUpdateCallback(db->pUpdateArg, u.bi.op, u.bi.zDb, u.bi.zTbl, u.bi.iKey); - assert( u.bi.pC->iDb>=0 ); + u.bf.zDb = db->aDb[u.bf.pC->iDb].zName; + u.bf.zTbl = pOp->p4.z; + u.bf.op = ((pOp->p5 & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_INSERT); + assert( u.bf.pC->isTable ); + db->xUpdateCallback(db->pUpdateArg, u.bf.op, u.bf.zDb, u.bf.zTbl, u.bf.iKey); + assert( u.bf.pC->iDb>=0 ); } break; } @@ -54780,56 +55782,60 @@ case OP_Insert: { ** using OP_NotFound prior to invoking this opcode. */ case OP_Delete: { -#if 0 /* local variables moved into u.bj */ - int i; +#if 0 /* local variables moved into u.bg */ i64 iKey; VdbeCursor *pC; -#endif /* local variables moved into u.bj */ +#endif /* local variables moved into u.bg */ - u.bj.i = pOp->p1; - u.bj.iKey = 0; - assert( u.bj.i>=0 && u.bj.inCursor ); - u.bj.pC = p->apCsr[u.bj.i]; - assert( u.bj.pC!=0 ); - assert( u.bj.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ + u.bg.iKey = 0; + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bg.pC = p->apCsr[pOp->p1]; + assert( u.bg.pC!=0 ); + assert( u.bg.pC->pCursor!=0 ); /* Only valid for real tables, no pseudotables */ - /* If the update-hook will be invoked, set u.bj.iKey to the rowid of the + /* If the update-hook will be invoked, set u.bg.iKey to the rowid of the ** row being deleted. */ if( db->xUpdateCallback && pOp->p4.z ){ - assert( u.bj.pC->isTable ); - assert( u.bj.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ - u.bj.iKey = u.bj.pC->lastRowid; + assert( u.bg.pC->isTable ); + assert( u.bg.pC->rowidIsValid ); /* lastRowid set by previous OP_NotFound */ + u.bg.iKey = u.bg.pC->lastRowid; } - rc = sqlite3VdbeCursorMoveto(u.bj.pC); - if( rc ) goto abort_due_to_error; - sqlite3BtreeSetCachedRowid(u.bj.pC->pCursor, 0); - rc = sqlite3BtreeDelete(u.bj.pC->pCursor); - u.bj.pC->cacheStatus = CACHE_STALE; + /* The OP_Delete opcode always follows an OP_NotExists or OP_Last or + ** OP_Column on the same table without any intervening operations that + ** might move or invalidate the cursor. Hence cursor u.bg.pC is always pointing + ** to the row to be deleted and the sqlite3VdbeCursorMoveto() operation + ** below is always a no-op and cannot fail. We will run it anyhow, though, + ** to guard against future changes to the code generator. + **/ + assert( u.bg.pC->deferredMoveto==0 ); + rc = sqlite3VdbeCursorMoveto(u.bg.pC); + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; + + sqlite3BtreeSetCachedRowid(u.bg.pC->pCursor, 0); + rc = sqlite3BtreeDelete(u.bg.pC->pCursor); + u.bg.pC->cacheStatus = CACHE_STALE; /* Invoke the update-hook if required. */ if( rc==SQLITE_OK && db->xUpdateCallback && pOp->p4.z ){ - const char *zDb = db->aDb[u.bj.pC->iDb].zName; + const char *zDb = db->aDb[u.bg.pC->iDb].zName; const char *zTbl = pOp->p4.z; - db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bj.iKey); - assert( u.bj.pC->iDb>=0 ); + db->xUpdateCallback(db->pUpdateArg, SQLITE_DELETE, zDb, zTbl, u.bg.iKey); + assert( u.bg.pC->iDb>=0 ); } if( pOp->p2 & OPFLAG_NCHANGE ) p->nChange++; break; } - -/* Opcode: ResetCount P1 * * +/* Opcode: ResetCount * * * * * ** -** This opcode resets the VMs internal change counter to 0. If P1 is true, -** then the value of the change counter is copied to the database handle -** change counter (returned by subsequent calls to sqlite3_changes()) -** before it is reset. This is used by trigger programs. +** The value of the change counter is copied to the database handle +** change counter (returned by subsequent calls to sqlite3_changes()). +** Then the VMs internal change counter resets to 0. +** This is used by trigger programs. */ case OP_ResetCount: { - if( pOp->p1 ){ - sqlite3VdbeSetChanges(db, p->nChange); - } + sqlite3VdbeSetChanges(db, p->nChange); p->nChange = 0; break; } @@ -54856,51 +55862,60 @@ case OP_ResetCount: { */ case OP_RowKey: case OP_RowData: { -#if 0 /* local variables moved into u.bk */ - int i; +#if 0 /* local variables moved into u.bh */ VdbeCursor *pC; BtCursor *pCrsr; u32 n; i64 n64; -#endif /* local variables moved into u.bk */ +#endif /* local variables moved into u.bh */ - u.bk.i = pOp->p1; pOut = &p->aMem[pOp->p2]; /* Note that RowKey and RowData are really exactly the same instruction */ - assert( u.bk.i>=0 && u.bk.inCursor ); - u.bk.pC = p->apCsr[u.bk.i]; - assert( u.bk.pC->isTable || pOp->opcode==OP_RowKey ); - assert( u.bk.pC->isIndex || pOp->opcode==OP_RowData ); - assert( u.bk.pC!=0 ); - assert( u.bk.pC->nullRow==0 ); - assert( u.bk.pC->pseudoTable==0 ); - assert( u.bk.pC->pCursor!=0 ); - u.bk.pCrsr = u.bk.pC->pCursor; - rc = sqlite3VdbeCursorMoveto(u.bk.pC); - if( rc ) goto abort_due_to_error; - if( u.bk.pC->isIndex ){ - assert( !u.bk.pC->isTable ); - sqlite3BtreeKeySize(u.bk.pCrsr, &u.bk.n64); - if( u.bk.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bh.pC = p->apCsr[pOp->p1]; + assert( u.bh.pC->isTable || pOp->opcode==OP_RowKey ); + assert( u.bh.pC->isIndex || pOp->opcode==OP_RowData ); + assert( u.bh.pC!=0 ); + assert( u.bh.pC->nullRow==0 ); + assert( u.bh.pC->pseudoTableReg==0 ); + assert( u.bh.pC->pCursor!=0 ); + u.bh.pCrsr = u.bh.pC->pCursor; + assert( sqlite3BtreeCursorIsValid(u.bh.pCrsr) ); + + /* The OP_RowKey and OP_RowData opcodes always follow OP_NotExists or + ** OP_Rewind/Op_Next with no intervening instructions that might invalidate + ** the cursor. Hence the following sqlite3VdbeCursorMoveto() call is always + ** a no-op and can never fail. But we leave it in place as a safety. + */ + assert( u.bh.pC->deferredMoveto==0 ); + rc = sqlite3VdbeCursorMoveto(u.bh.pC); + if( NEVER(rc!=SQLITE_OK) ) goto abort_due_to_error; + + if( u.bh.pC->isIndex ){ + assert( !u.bh.pC->isTable ); + rc = sqlite3BtreeKeySize(u.bh.pCrsr, &u.bh.n64); + assert( rc==SQLITE_OK ); /* True because of CursorMoveto() call above */ + if( u.bh.n64>db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } - u.bk.n = (u32)u.bk.n64; + u.bh.n = (u32)u.bh.n64; }else{ - sqlite3BtreeDataSize(u.bk.pCrsr, &u.bk.n); - if( u.bk.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ + rc = sqlite3BtreeDataSize(u.bh.pCrsr, &u.bh.n); + assert( rc==SQLITE_OK ); /* DataSize() cannot fail */ + if( u.bh.n>(u32)db->aLimit[SQLITE_LIMIT_LENGTH] ){ goto too_big; } } - if( sqlite3VdbeMemGrow(pOut, u.bk.n, 0) ){ + if( sqlite3VdbeMemGrow(pOut, u.bh.n, 0) ){ goto no_mem; } - pOut->n = u.bk.n; + pOut->n = u.bh.n; MemSetTypeFlag(pOut, MEM_Blob); - if( u.bk.pC->isIndex ){ - rc = sqlite3BtreeKey(u.bk.pCrsr, 0, u.bk.n, pOut->z); + if( u.bh.pC->isIndex ){ + rc = sqlite3BtreeKey(u.bh.pCrsr, 0, u.bh.n, pOut->z); }else{ - rc = sqlite3BtreeData(u.bk.pCrsr, 0, u.bk.n, pOut->z); + rc = sqlite3BtreeData(u.bh.pCrsr, 0, u.bh.n, pOut->z); } pOut->enc = SQLITE_UTF8; /* In case the blob is ever cast to text */ UPDATE_MAX_BLOBSIZE(pOut); @@ -54917,49 +55932,46 @@ case OP_RowData: { ** one opcode now works for both table types. */ case OP_Rowid: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bl */ - int i; +#if 0 /* local variables moved into u.bi */ VdbeCursor *pC; i64 v; sqlite3_vtab *pVtab; const sqlite3_module *pModule; -#endif /* local variables moved into u.bl */ +#endif /* local variables moved into u.bi */ - u.bl.i = pOp->p1; - assert( u.bl.i>=0 && u.bl.inCursor ); - u.bl.pC = p->apCsr[u.bl.i]; - assert( u.bl.pC!=0 ); - if( u.bl.pC->nullRow ){ + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bi.pC = p->apCsr[pOp->p1]; + assert( u.bi.pC!=0 ); + assert( u.bi.pC->pseudoTableReg==0 ); + if( u.bi.pC->nullRow ){ /* Do nothing so that reg[P2] remains NULL */ break; - }else if( u.bl.pC->deferredMoveto ){ - u.bl.v = u.bl.pC->movetoTarget; - }else if( u.bl.pC->pseudoTable ){ - u.bl.v = keyToInt(u.bl.pC->iKey); + }else if( u.bi.pC->deferredMoveto ){ + u.bi.v = u.bi.pC->movetoTarget; #ifndef SQLITE_OMIT_VIRTUALTABLE - }else if( u.bl.pC->pVtabCursor ){ - u.bl.pVtab = u.bl.pC->pVtabCursor->pVtab; - u.bl.pModule = u.bl.pVtab->pModule; - assert( u.bl.pModule->xRowid ); + }else if( u.bi.pC->pVtabCursor ){ + u.bi.pVtab = u.bi.pC->pVtabCursor->pVtab; + u.bi.pModule = u.bi.pVtab->pModule; + assert( u.bi.pModule->xRowid ); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - rc = u.bl.pModule->xRowid(u.bl.pC->pVtabCursor, &u.bl.v); + rc = u.bi.pModule->xRowid(u.bi.pC->pVtabCursor, &u.bi.v); sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.bl.pVtab->zErrMsg; - u.bl.pVtab->zErrMsg = 0; + p->zErrMsg = u.bi.pVtab->zErrMsg; + u.bi.pVtab->zErrMsg = 0; if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; #endif /* SQLITE_OMIT_VIRTUALTABLE */ }else{ - rc = sqlite3VdbeCursorMoveto(u.bl.pC); + assert( u.bi.pC->pCursor!=0 ); + rc = sqlite3VdbeCursorMoveto(u.bi.pC); if( rc ) goto abort_due_to_error; - if( u.bl.pC->rowidIsValid ){ - u.bl.v = u.bl.pC->lastRowid; + if( u.bi.pC->rowidIsValid ){ + u.bi.v = u.bi.pC->lastRowid; }else{ - assert( u.bl.pC->pCursor!=0 ); - sqlite3BtreeKeySize(u.bl.pC->pCursor, &u.bl.v); - u.bl.v = keyToInt(u.bl.v); + rc = sqlite3BtreeKeySize(u.bi.pC->pCursor, &u.bi.v); + assert( rc==SQLITE_OK ); /* Always so because of CursorMoveto() above */ } } - pOut->u.i = u.bl.v; + pOut->u.i = u.bi.v; MemSetTypeFlag(pOut, MEM_Int); break; } @@ -54971,19 +55983,17 @@ case OP_Rowid: { /* out2-prerelease */ ** write a NULL. */ case OP_NullRow: { -#if 0 /* local variables moved into u.bm */ - int i; +#if 0 /* local variables moved into u.bj */ VdbeCursor *pC; -#endif /* local variables moved into u.bm */ +#endif /* local variables moved into u.bj */ - u.bm.i = pOp->p1; - assert( u.bm.i>=0 && u.bm.inCursor ); - u.bm.pC = p->apCsr[u.bm.i]; - assert( u.bm.pC!=0 ); - u.bm.pC->nullRow = 1; - u.bm.pC->rowidIsValid = 0; - if( u.bm.pC->pCursor ){ - sqlite3BtreeClearCursor(u.bm.pC->pCursor); + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bj.pC = p->apCsr[pOp->p1]; + assert( u.bj.pC!=0 ); + u.bj.pC->nullRow = 1; + u.bj.pC->rowidIsValid = 0; + if( u.bj.pC->pCursor ){ + sqlite3BtreeClearCursor(u.bj.pC->pCursor); } break; } @@ -54997,25 +56007,26 @@ case OP_NullRow: { ** to the following instruction. */ case OP_Last: { /* jump */ -#if 0 /* local variables moved into u.bn */ - int i; +#if 0 /* local variables moved into u.bk */ VdbeCursor *pC; BtCursor *pCrsr; int res; -#endif /* local variables moved into u.bn */ +#endif /* local variables moved into u.bk */ - u.bn.i = pOp->p1; - assert( u.bn.i>=0 && u.bn.inCursor ); - u.bn.pC = p->apCsr[u.bn.i]; - assert( u.bn.pC!=0 ); - u.bn.pCrsr = u.bn.pC->pCursor; - assert( u.bn.pCrsr!=0 ); - rc = sqlite3BtreeLast(u.bn.pCrsr, &u.bn.res); - u.bn.pC->nullRow = (u8)u.bn.res; - u.bn.pC->deferredMoveto = 0; - u.bn.pC->rowidIsValid = 0; - u.bn.pC->cacheStatus = CACHE_STALE; - if( u.bn.res && pOp->p2>0 ){ + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bk.pC = p->apCsr[pOp->p1]; + assert( u.bk.pC!=0 ); + u.bk.pCrsr = u.bk.pC->pCursor; + if( u.bk.pCrsr==0 ){ + u.bk.res = 1; + }else{ + rc = sqlite3BtreeLast(u.bk.pCrsr, &u.bk.res); + } + u.bk.pC->nullRow = (u8)u.bk.res; + u.bk.pC->deferredMoveto = 0; + u.bk.pC->rowidIsValid = 0; + u.bk.pC->cacheStatus = CACHE_STALE; + if( pOp->p2>0 && u.bk.res ){ pc = pOp->p2 - 1; } break; @@ -55051,29 +56062,27 @@ case OP_Sort: { /* jump */ ** to the following instruction. */ case OP_Rewind: { /* jump */ -#if 0 /* local variables moved into u.bo */ - int i; +#if 0 /* local variables moved into u.bl */ VdbeCursor *pC; BtCursor *pCrsr; int res; -#endif /* local variables moved into u.bo */ +#endif /* local variables moved into u.bl */ - u.bo.i = pOp->p1; - assert( u.bo.i>=0 && u.bo.inCursor ); - u.bo.pC = p->apCsr[u.bo.i]; - assert( u.bo.pC!=0 ); - if( (u.bo.pCrsr = u.bo.pC->pCursor)!=0 ){ - rc = sqlite3BtreeFirst(u.bo.pCrsr, &u.bo.res); - u.bo.pC->atFirst = u.bo.res==0 ?1:0; - u.bo.pC->deferredMoveto = 0; - u.bo.pC->cacheStatus = CACHE_STALE; - u.bo.pC->rowidIsValid = 0; + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bl.pC = p->apCsr[pOp->p1]; + assert( u.bl.pC!=0 ); + if( (u.bl.pCrsr = u.bl.pC->pCursor)!=0 ){ + rc = sqlite3BtreeFirst(u.bl.pCrsr, &u.bl.res); + u.bl.pC->atFirst = u.bl.res==0 ?1:0; + u.bl.pC->deferredMoveto = 0; + u.bl.pC->cacheStatus = CACHE_STALE; + u.bl.pC->rowidIsValid = 0; }else{ - u.bo.res = 1; + u.bl.res = 1; } - u.bo.pC->nullRow = (u8)u.bo.res; + u.bl.pC->nullRow = (u8)u.bl.res; assert( pOp->p2>0 && pOp->p2nOp ); - if( u.bo.res ){ + if( u.bl.res ){ pc = pOp->p2 - 1; } break; @@ -55101,34 +56110,37 @@ case OP_Rewind: { /* jump */ */ case OP_Prev: /* jump */ case OP_Next: { /* jump */ -#if 0 /* local variables moved into u.bp */ +#if 0 /* local variables moved into u.bm */ VdbeCursor *pC; BtCursor *pCrsr; int res; -#endif /* local variables moved into u.bp */ +#endif /* local variables moved into u.bm */ CHECK_FOR_INTERRUPT; assert( pOp->p1>=0 && pOp->p1nCursor ); - u.bp.pC = p->apCsr[pOp->p1]; - if( u.bp.pC==0 ){ + u.bm.pC = p->apCsr[pOp->p1]; + if( u.bm.pC==0 ){ break; /* See ticket #2273 */ } - u.bp.pCrsr = u.bp.pC->pCursor; - assert( u.bp.pCrsr ); - u.bp.res = 1; - assert( u.bp.pC->deferredMoveto==0 ); - rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(u.bp.pCrsr, &u.bp.res) : - sqlite3BtreePrevious(u.bp.pCrsr, &u.bp.res); - u.bp.pC->nullRow = (u8)u.bp.res; - u.bp.pC->cacheStatus = CACHE_STALE; - if( u.bp.res==0 ){ + u.bm.pCrsr = u.bm.pC->pCursor; + if( u.bm.pCrsr==0 ){ + u.bm.pC->nullRow = 1; + break; + } + u.bm.res = 1; + assert( u.bm.pC->deferredMoveto==0 ); + rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(u.bm.pCrsr, &u.bm.res) : + sqlite3BtreePrevious(u.bm.pCrsr, &u.bm.res); + u.bm.pC->nullRow = (u8)u.bm.res; + u.bm.pC->cacheStatus = CACHE_STALE; + if( u.bm.res==0 ){ pc = pOp->p2 - 1; if( pOp->p5 ) p->aCounter[pOp->p5-1]++; #ifdef SQLITE_TEST sqlite3_search_count++; #endif } - u.bp.pC->rowidIsValid = 0; + u.bm.pC->rowidIsValid = 0; break; } @@ -55145,29 +56157,29 @@ case OP_Next: { /* jump */ ** for tables is OP_Insert. */ case OP_IdxInsert: { /* in2 */ -#if 0 /* local variables moved into u.bq */ - int i; +#if 0 /* local variables moved into u.bn */ VdbeCursor *pC; BtCursor *pCrsr; int nKey; const char *zKey; -#endif /* local variables moved into u.bq */ +#endif /* local variables moved into u.bn */ - u.bq.i = pOp->p1; - assert( u.bq.i>=0 && u.bq.inCursor ); - assert( p->apCsr[u.bq.i]!=0 ); + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bn.pC = p->apCsr[pOp->p1]; + assert( u.bn.pC!=0 ); assert( pIn2->flags & MEM_Blob ); - if( (u.bq.pCrsr = (u.bq.pC = p->apCsr[u.bq.i])->pCursor)!=0 ){ - assert( u.bq.pC->isTable==0 ); + u.bn.pCrsr = u.bn.pC->pCursor; + if( ALWAYS(u.bn.pCrsr!=0) ){ + assert( u.bn.pC->isTable==0 ); rc = ExpandBlob(pIn2); if( rc==SQLITE_OK ){ - u.bq.nKey = pIn2->n; - u.bq.zKey = pIn2->z; - rc = sqlite3BtreeInsert(u.bq.pCrsr, u.bq.zKey, u.bq.nKey, "", 0, 0, pOp->p3, - ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bq.pC->seekResult : 0) + u.bn.nKey = pIn2->n; + u.bn.zKey = pIn2->z; + rc = sqlite3BtreeInsert(u.bn.pCrsr, u.bn.zKey, u.bn.nKey, "", 0, 0, pOp->p3, + ((pOp->p5 & OPFLAG_USESEEKRESULT) ? u.bn.pC->seekResult : 0) ); - assert( u.bq.pC->deferredMoveto==0 ); - u.bq.pC->cacheStatus = CACHE_STALE; + assert( u.bn.pC->deferredMoveto==0 ); + u.bn.pC->cacheStatus = CACHE_STALE; } } break; @@ -55180,30 +56192,30 @@ case OP_IdxInsert: { /* in2 */ ** index opened by cursor P1. */ case OP_IdxDelete: { -#if 0 /* local variables moved into u.br */ - int i; +#if 0 /* local variables moved into u.bo */ VdbeCursor *pC; BtCursor *pCrsr; -#endif /* local variables moved into u.br */ + int res; + UnpackedRecord r; +#endif /* local variables moved into u.bo */ - u.br.i = pOp->p1; assert( pOp->p3>0 ); assert( pOp->p2>0 && pOp->p2+pOp->p3<=p->nMem+1 ); - assert( u.br.i>=0 && u.br.inCursor ); - assert( p->apCsr[u.br.i]!=0 ); - if( (u.br.pCrsr = (u.br.pC = p->apCsr[u.br.i])->pCursor)!=0 ){ - int res; - UnpackedRecord r; - r.pKeyInfo = u.br.pC->pKeyInfo; - r.nField = (u16)pOp->p3; - r.flags = 0; - r.aMem = &p->aMem[pOp->p2]; - rc = sqlite3BtreeMovetoUnpacked(u.br.pCrsr, &r, 0, 0, &res); - if( rc==SQLITE_OK && res==0 ){ - rc = sqlite3BtreeDelete(u.br.pCrsr); - } - assert( u.br.pC->deferredMoveto==0 ); - u.br.pC->cacheStatus = CACHE_STALE; + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bo.pC = p->apCsr[pOp->p1]; + assert( u.bo.pC!=0 ); + u.bo.pCrsr = u.bo.pC->pCursor; + if( ALWAYS(u.bo.pCrsr!=0) ){ + u.bo.r.pKeyInfo = u.bo.pC->pKeyInfo; + u.bo.r.nField = (u16)pOp->p3; + u.bo.r.flags = 0; + u.bo.r.aMem = &p->aMem[pOp->p2]; + rc = sqlite3BtreeMovetoUnpacked(u.bo.pCrsr, &u.bo.r, 0, 0, &u.bo.res); + if( rc==SQLITE_OK && u.bo.res==0 ){ + rc = sqlite3BtreeDelete(u.bo.pCrsr); + } + assert( u.bo.pC->deferredMoveto==0 ); + u.bo.pC->cacheStatus = CACHE_STALE; } break; } @@ -55217,28 +56229,28 @@ case OP_IdxDelete: { ** See also: Rowid, MakeRecord. */ case OP_IdxRowid: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bs */ - int i; +#if 0 /* local variables moved into u.bp */ BtCursor *pCrsr; VdbeCursor *pC; i64 rowid; -#endif /* local variables moved into u.bs */ +#endif /* local variables moved into u.bp */ - u.bs.i = pOp->p1; - assert( u.bs.i>=0 && u.bs.inCursor ); - assert( p->apCsr[u.bs.i]!=0 ); - if( (u.bs.pCrsr = (u.bs.pC = p->apCsr[u.bs.i])->pCursor)!=0 ){ - rc = sqlite3VdbeCursorMoveto(u.bs.pC); - if( rc ) goto abort_due_to_error; - assert( u.bs.pC->deferredMoveto==0 ); - assert( u.bs.pC->isTable==0 ); - if( !u.bs.pC->nullRow ){ - rc = sqlite3VdbeIdxRowid(u.bs.pCrsr, &u.bs.rowid); + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bp.pC = p->apCsr[pOp->p1]; + assert( u.bp.pC!=0 ); + u.bp.pCrsr = u.bp.pC->pCursor; + if( ALWAYS(u.bp.pCrsr!=0) ){ + rc = sqlite3VdbeCursorMoveto(u.bp.pC); + if( NEVER(rc) ) goto abort_due_to_error; + assert( u.bp.pC->deferredMoveto==0 ); + assert( u.bp.pC->isTable==0 ); + if( !u.bp.pC->nullRow ){ + rc = sqlite3VdbeIdxRowid(db, u.bp.pCrsr, &u.bp.rowid); if( rc!=SQLITE_OK ){ goto abort_due_to_error; } MemSetTypeFlag(pOut, MEM_Int); - pOut->u.i = u.bs.rowid; + pOut->u.i = u.bp.rowid; } } break; @@ -55272,36 +56284,35 @@ case OP_IdxRowid: { /* out2-prerelease */ */ case OP_IdxLT: /* jump, in3 */ case OP_IdxGE: { /* jump, in3 */ -#if 0 /* local variables moved into u.bt */ - int i; +#if 0 /* local variables moved into u.bq */ VdbeCursor *pC; int res; UnpackedRecord r; -#endif /* local variables moved into u.bt */ +#endif /* local variables moved into u.bq */ - u.bt.i = pOp->p1; - assert( u.bt.i>=0 && u.bt.inCursor ); - assert( p->apCsr[u.bt.i]!=0 ); - if( (u.bt.pC = p->apCsr[u.bt.i])->pCursor!=0 ){ - assert( u.bt.pC->deferredMoveto==0 ); + assert( pOp->p1>=0 && pOp->p1nCursor ); + u.bq.pC = p->apCsr[pOp->p1]; + assert( u.bq.pC!=0 ); + if( ALWAYS(u.bq.pC->pCursor!=0) ){ + assert( u.bq.pC->deferredMoveto==0 ); assert( pOp->p5==0 || pOp->p5==1 ); assert( pOp->p4type==P4_INT32 ); - u.bt.r.pKeyInfo = u.bt.pC->pKeyInfo; - u.bt.r.nField = (u16)pOp->p4.i; + u.bq.r.pKeyInfo = u.bq.pC->pKeyInfo; + u.bq.r.nField = (u16)pOp->p4.i; if( pOp->p5 ){ - u.bt.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; + u.bq.r.flags = UNPACKED_INCRKEY | UNPACKED_IGNORE_ROWID; }else{ - u.bt.r.flags = UNPACKED_IGNORE_ROWID; + u.bq.r.flags = UNPACKED_IGNORE_ROWID; } - u.bt.r.aMem = &p->aMem[pOp->p3]; - rc = sqlite3VdbeIdxKeyCompare(u.bt.pC, &u.bt.r, &u.bt.res); + u.bq.r.aMem = &p->aMem[pOp->p3]; + rc = sqlite3VdbeIdxKeyCompare(u.bq.pC, &u.bq.r, &u.bq.res); if( pOp->opcode==OP_IdxLT ){ - u.bt.res = -u.bt.res; + u.bq.res = -u.bq.res; }else{ assert( pOp->opcode==OP_IdxGE ); - u.bt.res++; + u.bq.res++; } - if( u.bt.res>0 ){ + if( u.bq.res>0 ){ pc = pOp->p2 - 1 ; } } @@ -55329,35 +56340,35 @@ case OP_IdxGE: { /* jump, in3 */ ** See also: Clear */ case OP_Destroy: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bu */ +#if 0 /* local variables moved into u.br */ int iMoved; int iCnt; Vdbe *pVdbe; int iDb; -#endif /* local variables moved into u.bu */ +#endif /* local variables moved into u.br */ #ifndef SQLITE_OMIT_VIRTUALTABLE - u.bu.iCnt = 0; - for(u.bu.pVdbe=db->pVdbe; u.bu.pVdbe; u.bu.pVdbe = u.bu.pVdbe->pNext){ - if( u.bu.pVdbe->magic==VDBE_MAGIC_RUN && u.bu.pVdbe->inVtabMethod<2 && u.bu.pVdbe->pc>=0 ){ - u.bu.iCnt++; + u.br.iCnt = 0; + for(u.br.pVdbe=db->pVdbe; u.br.pVdbe; u.br.pVdbe = u.br.pVdbe->pNext){ + if( u.br.pVdbe->magic==VDBE_MAGIC_RUN && u.br.pVdbe->inVtabMethod<2 && u.br.pVdbe->pc>=0 ){ + u.br.iCnt++; } } #else - u.bu.iCnt = db->activeVdbeCnt; + u.br.iCnt = db->activeVdbeCnt; #endif - if( u.bu.iCnt>1 ){ + if( u.br.iCnt>1 ){ rc = SQLITE_LOCKED; p->errorAction = OE_Abort; }else{ - u.bu.iDb = pOp->p3; - assert( u.bu.iCnt==1 ); - assert( (p->btreeMask & (1<aDb[u.bu.iDb].pBt, pOp->p1, &u.bu.iMoved); + u.br.iDb = pOp->p3; + assert( u.br.iCnt==1 ); + assert( (p->btreeMask & (1<aDb[u.br.iDb].pBt, pOp->p1, &u.br.iMoved); MemSetTypeFlag(pOut, MEM_Int); - pOut->u.i = u.bu.iMoved; + pOut->u.i = u.br.iMoved; #ifndef SQLITE_OMIT_AUTOVACUUM - if( rc==SQLITE_OK && u.bu.iMoved!=0 ){ - sqlite3RootPageMoved(&db->aDb[u.bu.iDb], u.bu.iMoved, pOp->p1); + if( rc==SQLITE_OK && u.br.iMoved!=0 ){ + sqlite3RootPageMoved(&db->aDb[u.br.iDb], u.br.iMoved, pOp->p1); } #endif } @@ -55383,19 +56394,19 @@ case OP_Destroy: { /* out2-prerelease */ ** See also: Destroy */ case OP_Clear: { -#if 0 /* local variables moved into u.bv */ +#if 0 /* local variables moved into u.bs */ int nChange; -#endif /* local variables moved into u.bv */ +#endif /* local variables moved into u.bs */ - u.bv.nChange = 0; + u.bs.nChange = 0; assert( (p->btreeMask & (1<p2))!=0 ); rc = sqlite3BtreeClearTable( - db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bv.nChange : 0) + db->aDb[pOp->p2].pBt, pOp->p1, (pOp->p3 ? &u.bs.nChange : 0) ); if( pOp->p3 ){ - p->nChange += u.bv.nChange; + p->nChange += u.bs.nChange; if( pOp->p3>0 ){ - p->aMem[pOp->p3].u.i += u.bv.nChange; + p->aMem[pOp->p3].u.i += u.bs.nChange; } } break; @@ -55425,25 +56436,25 @@ case OP_Clear: { */ case OP_CreateIndex: /* out2-prerelease */ case OP_CreateTable: { /* out2-prerelease */ -#if 0 /* local variables moved into u.bw */ +#if 0 /* local variables moved into u.bt */ int pgno; int flags; Db *pDb; -#endif /* local variables moved into u.bw */ +#endif /* local variables moved into u.bt */ - u.bw.pgno = 0; + u.bt.pgno = 0; assert( pOp->p1>=0 && pOp->p1nDb ); assert( (p->btreeMask & (1<p1))!=0 ); - u.bw.pDb = &db->aDb[pOp->p1]; - assert( u.bw.pDb->pBt!=0 ); + u.bt.pDb = &db->aDb[pOp->p1]; + assert( u.bt.pDb->pBt!=0 ); if( pOp->opcode==OP_CreateTable ){ - /* u.bw.flags = BTREE_INTKEY; */ - u.bw.flags = BTREE_LEAFDATA|BTREE_INTKEY; + /* u.bt.flags = BTREE_INTKEY; */ + u.bt.flags = BTREE_LEAFDATA|BTREE_INTKEY; }else{ - u.bw.flags = BTREE_ZERODATA; + u.bt.flags = BTREE_ZERODATA; } - rc = sqlite3BtreeCreateTable(u.bw.pDb->pBt, &u.bw.pgno, u.bw.flags); - pOut->u.i = u.bw.pgno; + rc = sqlite3BtreeCreateTable(u.bt.pDb->pBt, &u.bt.pgno, u.bt.flags); + pOut->u.i = u.bt.pgno; MemSetTypeFlag(pOut, MEM_Int); break; } @@ -55461,15 +56472,15 @@ case OP_CreateTable: { /* out2-prerelease */ ** then runs the new virtual machine. It is thus a re-entrant opcode. */ case OP_ParseSchema: { -#if 0 /* local variables moved into u.bx */ +#if 0 /* local variables moved into u.bu */ int iDb; const char *zMaster; char *zSql; InitData initData; -#endif /* local variables moved into u.bx */ +#endif /* local variables moved into u.bu */ - u.bx.iDb = pOp->p1; - assert( u.bx.iDb>=0 && u.bx.iDbnDb ); + u.bu.iDb = pOp->p1; + assert( u.bu.iDb>=0 && u.bu.iDbnDb ); /* If pOp->p2 is 0, then this opcode is being executed to read a ** single row, for example the row corresponding to a new index @@ -55479,40 +56490,40 @@ case OP_ParseSchema: { ** with the rest of the schema when it is required. ** ** Although the mutex on the BtShared object that corresponds to - ** database u.bx.iDb (the database containing the sqlite_master table + ** database u.bu.iDb (the database containing the sqlite_master table ** read by this instruction) is currently held, it is necessary to ** obtain the mutexes on all attached databases before checking if - ** the schema of u.bx.iDb is loaded. This is because, at the start of + ** the schema of u.bu.iDb is loaded. This is because, at the start of ** the sqlite3_exec() call below, SQLite will invoke ** sqlite3BtreeEnterAll(). If all mutexes are not already held, the - ** u.bx.iDb mutex may be temporarily released to avoid deadlock. If + ** u.bu.iDb mutex may be temporarily released to avoid deadlock. If ** this happens, then some other thread may delete the in-memory - ** schema of database u.bx.iDb before the SQL statement runs. The schema + ** schema of database u.bu.iDb before the SQL statement runs. The schema ** will not be reloaded becuase the db->init.busy flag is set. This ** can result in a "no such table: sqlite_master" or "malformed ** database schema" error being returned to the user. */ - assert( sqlite3BtreeHoldsMutex(db->aDb[u.bx.iDb].pBt) ); + assert( sqlite3BtreeHoldsMutex(db->aDb[u.bu.iDb].pBt) ); sqlite3BtreeEnterAll(db); - if( pOp->p2 || DbHasProperty(db, u.bx.iDb, DB_SchemaLoaded) ){ - u.bx.zMaster = SCHEMA_TABLE(u.bx.iDb); - u.bx.initData.db = db; - u.bx.initData.iDb = pOp->p1; - u.bx.initData.pzErrMsg = &p->zErrMsg; - u.bx.zSql = sqlite3MPrintf(db, + if( pOp->p2 || DbHasProperty(db, u.bu.iDb, DB_SchemaLoaded) ){ + u.bu.zMaster = SCHEMA_TABLE(u.bu.iDb); + u.bu.initData.db = db; + u.bu.initData.iDb = pOp->p1; + u.bu.initData.pzErrMsg = &p->zErrMsg; + u.bu.zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s WHERE %s", - db->aDb[u.bx.iDb].zName, u.bx.zMaster, pOp->p4.z); - if( u.bx.zSql==0 ){ + db->aDb[u.bu.iDb].zName, u.bu.zMaster, pOp->p4.z); + if( u.bu.zSql==0 ){ rc = SQLITE_NOMEM; }else{ (void)sqlite3SafetyOff(db); assert( db->init.busy==0 ); db->init.busy = 1; - u.bx.initData.rc = SQLITE_OK; + u.bu.initData.rc = SQLITE_OK; assert( !db->mallocFailed ); - rc = sqlite3_exec(db, u.bx.zSql, sqlite3InitCallback, &u.bx.initData, 0); - if( rc==SQLITE_OK ) rc = u.bx.initData.rc; - sqlite3DbFree(db, u.bx.zSql); + rc = sqlite3_exec(db, u.bu.zSql, sqlite3InitCallback, &u.bu.initData, 0); + if( rc==SQLITE_OK ) rc = u.bu.initData.rc; + sqlite3DbFree(db, u.bu.zSql); db->init.busy = 0; (void)sqlite3SafetyOn(db); } @@ -55524,7 +56535,7 @@ case OP_ParseSchema: { break; } -#if !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) +#if !defined(SQLITE_OMIT_ANALYZE) /* Opcode: LoadAnalysis P1 * * * * ** ** Read the sqlite_stat1 table for database P1 and load the content @@ -55536,7 +56547,7 @@ case OP_LoadAnalysis: { rc = sqlite3AnalysisLoad(db, pOp->p1); break; } -#endif /* !defined(SQLITE_OMIT_ANALYZE) && !defined(SQLITE_OMIT_PARSER) */ +#endif /* !defined(SQLITE_OMIT_ANALYZE) */ /* Opcode: DropTable P1 * * P4 * ** @@ -55597,41 +56608,41 @@ case OP_DropTrigger: { ** This opcode is used to implement the integrity_check pragma. */ case OP_IntegrityCk: { -#if 0 /* local variables moved into u.by */ +#if 0 /* local variables moved into u.bv */ int nRoot; /* Number of tables to check. (Number of root pages.) */ int *aRoot; /* Array of rootpage numbers for tables to be checked */ int j; /* Loop counter */ int nErr; /* Number of errors reported */ char *z; /* Text of the error report */ Mem *pnErr; /* Register keeping track of errors remaining */ -#endif /* local variables moved into u.by */ +#endif /* local variables moved into u.bv */ - u.by.nRoot = pOp->p2; - assert( u.by.nRoot>0 ); - u.by.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.by.nRoot+1) ); - if( u.by.aRoot==0 ) goto no_mem; + u.bv.nRoot = pOp->p2; + assert( u.bv.nRoot>0 ); + u.bv.aRoot = sqlite3DbMallocRaw(db, sizeof(int)*(u.bv.nRoot+1) ); + if( u.bv.aRoot==0 ) goto no_mem; assert( pOp->p3>0 && pOp->p3<=p->nMem ); - u.by.pnErr = &p->aMem[pOp->p3]; - assert( (u.by.pnErr->flags & MEM_Int)!=0 ); - assert( (u.by.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); + u.bv.pnErr = &p->aMem[pOp->p3]; + assert( (u.bv.pnErr->flags & MEM_Int)!=0 ); + assert( (u.bv.pnErr->flags & (MEM_Str|MEM_Blob))==0 ); pIn1 = &p->aMem[pOp->p1]; - for(u.by.j=0; u.by.jp5nDb ); assert( (p->btreeMask & (1<p5))!=0 ); - u.by.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.by.aRoot, u.by.nRoot, - (int)u.by.pnErr->u.i, &u.by.nErr); - sqlite3DbFree(db, u.by.aRoot); - u.by.pnErr->u.i -= u.by.nErr; + u.bv.z = sqlite3BtreeIntegrityCheck(db->aDb[pOp->p5].pBt, u.bv.aRoot, u.bv.nRoot, + (int)u.bv.pnErr->u.i, &u.bv.nErr); + sqlite3DbFree(db, u.bv.aRoot); + u.bv.pnErr->u.i -= u.bv.nErr; sqlite3VdbeMemSetNull(pIn1); - if( u.by.nErr==0 ){ - assert( u.by.z==0 ); - }else if( u.by.z==0 ){ + if( u.bv.nErr==0 ){ + assert( u.bv.z==0 ); + }else if( u.bv.z==0 ){ goto no_mem; }else{ - sqlite3VdbeMemSetStr(pIn1, u.by.z, -1, SQLITE_UTF8, sqlite3_free); + sqlite3VdbeMemSetStr(pIn1, u.bv.z, -1, SQLITE_UTF8, sqlite3_free); } UPDATE_MAX_BLOBSIZE(pIn1); sqlite3VdbeChangeEncoding(pIn1, encoding); @@ -55647,20 +56658,20 @@ case OP_IntegrityCk: { ** An assertion fails if P2 is not an integer. */ case OP_RowSetAdd: { /* in2 */ -#if 0 /* local variables moved into u.bz */ +#if 0 /* local variables moved into u.bw */ Mem *pIdx; Mem *pVal; -#endif /* local variables moved into u.bz */ +#endif /* local variables moved into u.bw */ assert( pOp->p1>0 && pOp->p1<=p->nMem ); - u.bz.pIdx = &p->aMem[pOp->p1]; + u.bw.pIdx = &p->aMem[pOp->p1]; assert( pOp->p2>0 && pOp->p2<=p->nMem ); - u.bz.pVal = &p->aMem[pOp->p2]; - assert( (u.bz.pVal->flags & MEM_Int)!=0 ); - if( (u.bz.pIdx->flags & MEM_RowSet)==0 ){ - sqlite3VdbeMemSetRowSet(u.bz.pIdx); - if( (u.bz.pIdx->flags & MEM_RowSet)==0 ) goto no_mem; + u.bw.pVal = &p->aMem[pOp->p2]; + assert( (u.bw.pVal->flags & MEM_Int)!=0 ); + if( (u.bw.pIdx->flags & MEM_RowSet)==0 ){ + sqlite3VdbeMemSetRowSet(u.bw.pIdx); + if( (u.bw.pIdx->flags & MEM_RowSet)==0 ) goto no_mem; } - sqlite3RowSetInsert(u.bz.pIdx->u.pRowSet, u.bz.pVal->u.i); + sqlite3RowSetInsert(u.bw.pIdx->u.pRowSet, u.bw.pVal->u.i); break; } @@ -55671,24 +56682,24 @@ case OP_RowSetAdd: { /* in2 */ ** unchanged and jump to instruction P2. */ case OP_RowSetRead: { /* jump, out3 */ -#if 0 /* local variables moved into u.ca */ +#if 0 /* local variables moved into u.bx */ Mem *pIdx; i64 val; -#endif /* local variables moved into u.ca */ +#endif /* local variables moved into u.bx */ assert( pOp->p1>0 && pOp->p1<=p->nMem ); CHECK_FOR_INTERRUPT; - u.ca.pIdx = &p->aMem[pOp->p1]; + u.bx.pIdx = &p->aMem[pOp->p1]; pOut = &p->aMem[pOp->p3]; - if( (u.ca.pIdx->flags & MEM_RowSet)==0 - || sqlite3RowSetNext(u.ca.pIdx->u.pRowSet, &u.ca.val)==0 + if( (u.bx.pIdx->flags & MEM_RowSet)==0 + || sqlite3RowSetNext(u.bx.pIdx->u.pRowSet, &u.bx.val)==0 ){ /* The boolean index is empty */ - sqlite3VdbeMemSetNull(u.ca.pIdx); + sqlite3VdbeMemSetNull(u.bx.pIdx); pc = pOp->p2 - 1; }else{ /* A value was pulled from the index */ assert( pOp->p3>0 && pOp->p3<=p->nMem ); - sqlite3VdbeMemSetInt64(pOut, u.ca.val); + sqlite3VdbeMemSetInt64(pOut, u.bx.val); } break; } @@ -55717,12 +56728,12 @@ case OP_RowSetRead: { /* jump, out3 */ ** inserted as part of some other set). */ case OP_RowSetTest: { /* jump, in1, in3 */ -#if 0 /* local variables moved into u.cb */ +#if 0 /* local variables moved into u.by */ int iSet; int exists; -#endif /* local variables moved into u.cb */ +#endif /* local variables moved into u.by */ - u.cb.iSet = pOp->p4.i; + u.by.iSet = pOp->p4.i; assert( pIn3->flags&MEM_Int ); /* If there is anything other than a rowset object in memory cell P1, @@ -55734,17 +56745,17 @@ case OP_RowSetTest: { /* jump, in1, in3 */ } assert( pOp->p4type==P4_INT32 ); - assert( u.cb.iSet==-1 || u.cb.iSet>=0 ); - if( u.cb.iSet ){ - u.cb.exists = sqlite3RowSetTest(pIn1->u.pRowSet, - (u8)(u.cb.iSet>=0 ? u.cb.iSet & 0xf : 0xff), + assert( u.by.iSet==-1 || u.by.iSet>=0 ); + if( u.by.iSet ){ + u.by.exists = sqlite3RowSetTest(pIn1->u.pRowSet, + (u8)(u.by.iSet>=0 ? u.by.iSet & 0xf : 0xff), pIn3->u.i); - if( u.cb.exists ){ + if( u.by.exists ){ pc = pOp->p2 - 1; break; } } - if( u.cb.iSet>=0 ){ + if( u.by.iSet>=0 ){ sqlite3RowSetInsert(pIn1->u.pRowSet, pIn3->u.i); } break; @@ -55752,65 +56763,211 @@ case OP_RowSetTest: { /* jump, in1, in3 */ #ifndef SQLITE_OMIT_TRIGGER -/* Opcode: ContextPush * * * + +/* Opcode: Program P1 P2 P3 P4 * ** -** Save the current Vdbe context such that it can be restored by a ContextPop -** opcode. The context stores the last insert row id, the last statement change -** count, and the current statement change count. +** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). +** +** P1 contains the address of the memory cell that contains the first memory +** cell in an array of values used as arguments to the sub-program. P2 +** contains the address to jump to if the sub-program throws an IGNORE +** exception using the RAISE() function. Register P3 contains the address +** of a memory cell in this (the parent) VM that is used to allocate the +** memory required by the sub-vdbe at runtime. +** +** P4 is a pointer to the VM containing the trigger program. */ -case OP_ContextPush: { -#if 0 /* local variables moved into u.cc */ - int i; - Context *pContext; -#endif /* local variables moved into u.cc */ +case OP_Program: { /* jump */ +#if 0 /* local variables moved into u.bz */ + int nMem; /* Number of memory registers for sub-program */ + int nByte; /* Bytes of runtime space required for sub-program */ + Mem *pRt; /* Register to allocate runtime space */ + Mem *pMem; /* Used to iterate through memory cells */ + Mem *pEnd; /* Last memory cell in new array */ + VdbeFrame *pFrame; /* New vdbe frame to execute in */ + SubProgram *pProgram; /* Sub-program to execute */ + void *t; /* Token identifying trigger */ +#endif /* local variables moved into u.bz */ + + u.bz.pProgram = pOp->p4.pProgram; + u.bz.pRt = &p->aMem[pOp->p3]; + assert( u.bz.pProgram->nOp>0 ); + + /* If the p5 flag is clear, then recursive invocation of triggers is + ** disabled for backwards compatibility (p5 is set if this sub-program + ** is really a trigger, not a foreign key action, and the flag set + ** and cleared by the "PRAGMA recursive_triggers" command is clear). + ** + ** It is recursive invocation of triggers, at the SQL level, that is + ** disabled. In some cases a single trigger may generate more than one + ** SubProgram (if the trigger may be executed with more than one different + ** ON CONFLICT algorithm). SubProgram structures associated with a + ** single trigger all have the same value for the SubProgram.token + ** variable. */ + if( pOp->p5 ){ + u.bz.t = u.bz.pProgram->token; + for(u.bz.pFrame=p->pFrame; u.bz.pFrame && u.bz.pFrame->token!=u.bz.t; u.bz.pFrame=u.bz.pFrame->pParent); + if( u.bz.pFrame ) break; + } + + if( p->nFrame>=db->aLimit[SQLITE_LIMIT_TRIGGER_DEPTH] ){ + rc = SQLITE_ERROR; + sqlite3SetString(&p->zErrMsg, db, "too many levels of trigger recursion"); + break; + } + + /* Register u.bz.pRt is used to store the memory required to save the state + ** of the current program, and the memory required at runtime to execute + ** the trigger program. If this trigger has been fired before, then u.bz.pRt + ** is already allocated. Otherwise, it must be initialized. */ + if( (u.bz.pRt->flags&MEM_Frame)==0 ){ + /* SubProgram.nMem is set to the number of memory cells used by the + ** program stored in SubProgram.aOp. As well as these, one memory + ** cell is required for each cursor used by the program. Set local + ** variable u.bz.nMem (and later, VdbeFrame.nChildMem) to this value. + */ + u.bz.nMem = u.bz.pProgram->nMem + u.bz.pProgram->nCsr; + u.bz.nByte = ROUND8(sizeof(VdbeFrame)) + + u.bz.nMem * sizeof(Mem) + + u.bz.pProgram->nCsr * sizeof(VdbeCursor *); + u.bz.pFrame = sqlite3DbMallocZero(db, u.bz.nByte); + if( !u.bz.pFrame ){ + goto no_mem; + } + sqlite3VdbeMemRelease(u.bz.pRt); + u.bz.pRt->flags = MEM_Frame; + u.bz.pRt->u.pFrame = u.bz.pFrame; + + u.bz.pFrame->v = p; + u.bz.pFrame->nChildMem = u.bz.nMem; + u.bz.pFrame->nChildCsr = u.bz.pProgram->nCsr; + u.bz.pFrame->pc = pc; + u.bz.pFrame->aMem = p->aMem; + u.bz.pFrame->nMem = p->nMem; + u.bz.pFrame->apCsr = p->apCsr; + u.bz.pFrame->nCursor = p->nCursor; + u.bz.pFrame->aOp = p->aOp; + u.bz.pFrame->nOp = p->nOp; + u.bz.pFrame->token = u.bz.pProgram->token; + + u.bz.pEnd = &VdbeFrameMem(u.bz.pFrame)[u.bz.pFrame->nChildMem]; + for(u.bz.pMem=VdbeFrameMem(u.bz.pFrame); u.bz.pMem!=u.bz.pEnd; u.bz.pMem++){ + u.bz.pMem->flags = MEM_Null; + u.bz.pMem->db = db; + } + }else{ + u.bz.pFrame = u.bz.pRt->u.pFrame; + assert( u.bz.pProgram->nMem+u.bz.pProgram->nCsr==u.bz.pFrame->nChildMem ); + assert( u.bz.pProgram->nCsr==u.bz.pFrame->nChildCsr ); + assert( pc==u.bz.pFrame->pc ); + } + + p->nFrame++; + u.bz.pFrame->pParent = p->pFrame; + u.bz.pFrame->lastRowid = db->lastRowid; + u.bz.pFrame->nChange = p->nChange; + p->nChange = 0; + p->pFrame = u.bz.pFrame; + p->aMem = &VdbeFrameMem(u.bz.pFrame)[-1]; + p->nMem = u.bz.pFrame->nChildMem; + p->nCursor = (u16)u.bz.pFrame->nChildCsr; + p->apCsr = (VdbeCursor **)&p->aMem[p->nMem+1]; + p->aOp = u.bz.pProgram->aOp; + p->nOp = u.bz.pProgram->nOp; + pc = -1; - u.cc.i = p->contextStackTop++; - assert( u.cc.i>=0 ); - /* FIX ME: This should be allocated as part of the vdbe at compile-time */ - if( u.cc.i>=p->contextStackDepth ){ - p->contextStackDepth = u.cc.i+1; - p->contextStack = sqlite3DbReallocOrFree(db, p->contextStack, - sizeof(Context)*(u.cc.i+1)); - if( p->contextStack==0 ) goto no_mem; - } - u.cc.pContext = &p->contextStack[u.cc.i]; - u.cc.pContext->lastRowid = db->lastRowid; - u.cc.pContext->nChange = p->nChange; break; } -/* Opcode: ContextPop * * * +/* Opcode: Param P1 P2 * * * +** +** This opcode is only ever present in sub-programs called via the +** OP_Program instruction. Copy a value currently stored in a memory +** cell of the calling (parent) frame to cell P2 in the current frames +** address space. This is used by trigger programs to access the new.* +** and old.* values. ** -** Restore the Vdbe context to the state it was in when contextPush was last -** executed. The context stores the last insert row id, the last statement -** change count, and the current statement change count. +** The address of the cell in the parent frame is determined by adding +** the value of the P1 argument to the value of the P1 argument to the +** calling OP_Program instruction. */ -case OP_ContextPop: { -#if 0 /* local variables moved into u.cd */ - Context *pContext; -#endif /* local variables moved into u.cd */ - u.cd.pContext = &p->contextStack[--p->contextStackTop]; - assert( p->contextStackTop>=0 ); - db->lastRowid = u.cd.pContext->lastRowid; - p->nChange = u.cd.pContext->nChange; +case OP_Param: { /* out2-prerelease */ +#if 0 /* local variables moved into u.ca */ + VdbeFrame *pFrame; + Mem *pIn; +#endif /* local variables moved into u.ca */ + u.ca.pFrame = p->pFrame; + u.ca.pIn = &u.ca.pFrame->aMem[pOp->p1 + u.ca.pFrame->aOp[u.ca.pFrame->pc].p1]; + sqlite3VdbeMemShallowCopy(pOut, u.ca.pIn, MEM_Ephem); break; } + #endif /* #ifndef SQLITE_OMIT_TRIGGER */ +#ifndef SQLITE_OMIT_FOREIGN_KEY +/* Opcode: FkCounter P1 P2 * * * +** +** Increment a "constraint counter" by P2 (P2 may be negative or positive). +** If P1 is non-zero, the database constraint counter is incremented +** (deferred foreign key constraints). Otherwise, if P1 is zero, the +** statement counter is incremented (immediate foreign key constraints). +*/ +case OP_FkCounter: { + if( pOp->p1 ){ + db->nDeferredCons += pOp->p2; + }else{ + p->nFkConstraint += pOp->p2; + } + break; +} + +/* Opcode: FkIfZero P1 P2 * * * +** +** This opcode tests if a foreign key constraint-counter is currently zero. +** If so, jump to instruction P2. Otherwise, fall through to the next +** instruction. +** +** If P1 is non-zero, then the jump is taken if the database constraint-counter +** is zero (the one that counts deferred constraint violations). If P1 is +** zero, the jump is taken if the statement constraint-counter is zero +** (immediate foreign key constraint violations). +*/ +case OP_FkIfZero: { /* jump */ + if( pOp->p1 ){ + if( db->nDeferredCons==0 ) pc = pOp->p2-1; + }else{ + if( p->nFkConstraint==0 ) pc = pOp->p2-1; + } + break; +} +#endif /* #ifndef SQLITE_OMIT_FOREIGN_KEY */ + #ifndef SQLITE_OMIT_AUTOINCREMENT /* Opcode: MemMax P1 P2 * * * ** -** Set the value of register P1 to the maximum of its current value -** and the value in register P2. +** P1 is a register in the root frame of this VM (the root frame is +** different from the current frame if this instruction is being executed +** within a sub-program). Set the value of register P1 to the maximum of +** its current value and the value in register P2. ** ** This instruction throws an error if the memory cell is not initially ** an integer. */ -case OP_MemMax: { /* in1, in2 */ - sqlite3VdbeMemIntegerify(pIn1); +case OP_MemMax: { /* in2 */ +#if 0 /* local variables moved into u.cb */ + Mem *pIn1; + VdbeFrame *pFrame; +#endif /* local variables moved into u.cb */ + if( p->pFrame ){ + for(u.cb.pFrame=p->pFrame; u.cb.pFrame->pParent; u.cb.pFrame=u.cb.pFrame->pParent); + u.cb.pIn1 = &u.cb.pFrame->aMem[pOp->p1]; + }else{ + u.cb.pIn1 = &p->aMem[pOp->p1]; + } + sqlite3VdbeMemIntegerify(u.cb.pIn1); sqlite3VdbeMemIntegerify(pIn2); - if( pIn1->u.iu.i){ - pIn1->u.i = pIn2->u.i; + if( u.cb.pIn1->u.iu.i){ + u.cb.pIn1->u.i = pIn2->u.i; } break; } @@ -55872,47 +57029,47 @@ case OP_IfZero: { /* jump, in1 */ ** successors. */ case OP_AggStep: { -#if 0 /* local variables moved into u.ce */ +#if 0 /* local variables moved into u.cc */ int n; int i; Mem *pMem; Mem *pRec; sqlite3_context ctx; sqlite3_value **apVal; -#endif /* local variables moved into u.ce */ +#endif /* local variables moved into u.cc */ - u.ce.n = pOp->p5; - assert( u.ce.n>=0 ); - u.ce.pRec = &p->aMem[pOp->p2]; - u.ce.apVal = p->apArg; - assert( u.ce.apVal || u.ce.n==0 ); - for(u.ce.i=0; u.ce.ip5; + assert( u.cc.n>=0 ); + u.cc.pRec = &p->aMem[pOp->p2]; + u.cc.apVal = p->apArg; + assert( u.cc.apVal || u.cc.n==0 ); + for(u.cc.i=0; u.cc.ip4.pFunc; + u.cc.ctx.pFunc = pOp->p4.pFunc; assert( pOp->p3>0 && pOp->p3<=p->nMem ); - u.ce.ctx.pMem = u.ce.pMem = &p->aMem[pOp->p3]; - u.ce.pMem->n++; - u.ce.ctx.s.flags = MEM_Null; - u.ce.ctx.s.z = 0; - u.ce.ctx.s.zMalloc = 0; - u.ce.ctx.s.xDel = 0; - u.ce.ctx.s.db = db; - u.ce.ctx.isError = 0; - u.ce.ctx.pColl = 0; - if( u.ce.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ + u.cc.ctx.pMem = u.cc.pMem = &p->aMem[pOp->p3]; + u.cc.pMem->n++; + u.cc.ctx.s.flags = MEM_Null; + u.cc.ctx.s.z = 0; + u.cc.ctx.s.zMalloc = 0; + u.cc.ctx.s.xDel = 0; + u.cc.ctx.s.db = db; + u.cc.ctx.isError = 0; + u.cc.ctx.pColl = 0; + if( u.cc.ctx.pFunc->flags & SQLITE_FUNC_NEEDCOLL ){ assert( pOp>p->aOp ); assert( pOp[-1].p4type==P4_COLLSEQ ); assert( pOp[-1].opcode==OP_CollSeq ); - u.ce.ctx.pColl = pOp[-1].p4.pColl; + u.cc.ctx.pColl = pOp[-1].p4.pColl; } - (u.ce.ctx.pFunc->xStep)(&u.ce.ctx, u.ce.n, u.ce.apVal); - if( u.ce.ctx.isError ){ - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.ce.ctx.s)); - rc = u.ce.ctx.isError; + (u.cc.ctx.pFunc->xStep)(&u.cc.ctx, u.cc.n, u.cc.apVal); + if( u.cc.ctx.isError ){ + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&u.cc.ctx.s)); + rc = u.cc.ctx.isError; } - sqlite3VdbeMemRelease(&u.ce.ctx.s); + sqlite3VdbeMemRelease(&u.cc.ctx.s); break; } @@ -55929,19 +57086,19 @@ case OP_AggStep: { ** the step function was not previously called. */ case OP_AggFinal: { -#if 0 /* local variables moved into u.cf */ +#if 0 /* local variables moved into u.cd */ Mem *pMem; -#endif /* local variables moved into u.cf */ +#endif /* local variables moved into u.cd */ assert( pOp->p1>0 && pOp->p1<=p->nMem ); - u.cf.pMem = &p->aMem[pOp->p1]; - assert( (u.cf.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); - rc = sqlite3VdbeMemFinalize(u.cf.pMem, pOp->p4.pFunc); - if( rc==SQLITE_ERROR ){ - sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cf.pMem)); - } - sqlite3VdbeChangeEncoding(u.cf.pMem, encoding); - UPDATE_MAX_BLOBSIZE(u.cf.pMem); - if( sqlite3VdbeMemTooBig(u.cf.pMem) ){ + u.cd.pMem = &p->aMem[pOp->p1]; + assert( (u.cd.pMem->flags & ~(MEM_Null|MEM_Agg))==0 ); + rc = sqlite3VdbeMemFinalize(u.cd.pMem, pOp->p4.pFunc); + if( rc ){ + sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(u.cd.pMem)); + } + sqlite3VdbeChangeEncoding(u.cd.pMem, encoding); + UPDATE_MAX_BLOBSIZE(u.cd.pMem); + if( sqlite3VdbeMemTooBig(u.cd.pMem) ){ goto too_big; } break; @@ -55971,14 +57128,14 @@ case OP_Vacuum: { ** P2. Otherwise, fall through to the next instruction. */ case OP_IncrVacuum: { /* jump */ -#if 0 /* local variables moved into u.cg */ +#if 0 /* local variables moved into u.ce */ Btree *pBt; -#endif /* local variables moved into u.cg */ +#endif /* local variables moved into u.ce */ assert( pOp->p1>=0 && pOp->p1nDb ); assert( (p->btreeMask & (1<p1))!=0 ); - u.cg.pBt = db->aDb[pOp->p1].pBt; - rc = sqlite3BtreeIncrVacuum(u.cg.pBt); + u.ce.pBt = db->aDb[pOp->p1].pBt; + rc = sqlite3BtreeIncrVacuum(u.ce.pBt); if( rc==SQLITE_DONE ){ pc = pOp->p2 - 1; rc = SQLITE_OK; @@ -56011,7 +57168,7 @@ case OP_Expire: { ** Obtain a lock on a particular table. This instruction is only used when ** the shared-cache feature is enabled. ** -** If P1 is the index of the database in sqlite3.aDb[] of the database +** P1 is the index of the database in sqlite3.aDb[] of the database ** on which the lock is acquired. A readlock is obtained if P3==0 or ** a write lock if P3==1. ** @@ -56021,20 +57178,17 @@ case OP_Expire: { ** used to generate an error message if the lock cannot be obtained. */ case OP_TableLock: { -#if 0 /* local variables moved into u.ch */ - int p1; - u8 isWriteLock; -#endif /* local variables moved into u.ch */ - - u.ch.p1 = pOp->p1; - u.ch.isWriteLock = (u8)pOp->p3; - assert( u.ch.p1>=0 && u.ch.p1nDb ); - assert( (p->btreeMask & (1<aDb[u.ch.p1].pBt, pOp->p2, u.ch.isWriteLock); - if( (rc&0xFF)==SQLITE_LOCKED ){ - const char *z = pOp->p4.z; - sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z); + u8 isWriteLock = (u8)pOp->p3; + if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommitted) ){ + int p1 = pOp->p1; + assert( p1>=0 && p1nDb ); + assert( (p->btreeMask & (1<aDb[p1].pBt, pOp->p2, isWriteLock); + if( (rc&0xFF)==SQLITE_LOCKED ){ + const char *z = pOp->p4.z; + sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z); + } } break; } @@ -56051,15 +57205,15 @@ case OP_TableLock: { ** code will be set to SQLITE_LOCKED. */ case OP_VBegin: { -#if 0 /* local variables moved into u.ci */ - sqlite3_vtab *pVtab; -#endif /* local variables moved into u.ci */ - u.ci.pVtab = pOp->p4.pVtab; - rc = sqlite3VtabBegin(db, u.ci.pVtab); - if( u.ci.pVtab ){ +#if 0 /* local variables moved into u.cf */ + VTable *pVTab; +#endif /* local variables moved into u.cf */ + u.cf.pVTab = pOp->p4.pVtab; + rc = sqlite3VtabBegin(db, u.cf.pVTab); + if( u.cf.pVTab ){ sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.ci.pVtab->zErrMsg; - u.ci.pVtab->zErrMsg = 0; + p->zErrMsg = u.cf.pVTab->pVtab->zErrMsg; + u.cf.pVTab->pVtab->zErrMsg = 0; } break; } @@ -56099,36 +57253,36 @@ case OP_VDestroy: { ** table and stores that cursor in P1. */ case OP_VOpen: { -#if 0 /* local variables moved into u.cj */ +#if 0 /* local variables moved into u.cg */ VdbeCursor *pCur; sqlite3_vtab_cursor *pVtabCursor; sqlite3_vtab *pVtab; sqlite3_module *pModule; -#endif /* local variables moved into u.cj */ +#endif /* local variables moved into u.cg */ - u.cj.pCur = 0; - u.cj.pVtabCursor = 0; - u.cj.pVtab = pOp->p4.pVtab; - u.cj.pModule = (sqlite3_module *)u.cj.pVtab->pModule; - assert(u.cj.pVtab && u.cj.pModule); + u.cg.pCur = 0; + u.cg.pVtabCursor = 0; + u.cg.pVtab = pOp->p4.pVtab->pVtab; + u.cg.pModule = (sqlite3_module *)u.cg.pVtab->pModule; + assert(u.cg.pVtab && u.cg.pModule); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - rc = u.cj.pModule->xOpen(u.cj.pVtab, &u.cj.pVtabCursor); + rc = u.cg.pModule->xOpen(u.cg.pVtab, &u.cg.pVtabCursor); sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.cj.pVtab->zErrMsg; - u.cj.pVtab->zErrMsg = 0; + p->zErrMsg = u.cg.pVtab->zErrMsg; + u.cg.pVtab->zErrMsg = 0; if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; if( SQLITE_OK==rc ){ /* Initialize sqlite3_vtab_cursor base class */ - u.cj.pVtabCursor->pVtab = u.cj.pVtab; + u.cg.pVtabCursor->pVtab = u.cg.pVtab; /* Initialise vdbe cursor object */ - u.cj.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); - if( u.cj.pCur ){ - u.cj.pCur->pVtabCursor = u.cj.pVtabCursor; - u.cj.pCur->pModule = u.cj.pVtabCursor->pVtab->pModule; + u.cg.pCur = allocateCursor(p, pOp->p1, 0, -1, 0); + if( u.cg.pCur ){ + u.cg.pCur->pVtabCursor = u.cg.pVtabCursor; + u.cg.pCur->pModule = u.cg.pVtabCursor->pVtab->pModule; }else{ db->mallocFailed = 1; - u.cj.pModule->xClose(u.cj.pVtabCursor); + u.cg.pModule->xClose(u.cg.pVtabCursor); } } break; @@ -56155,7 +57309,7 @@ case OP_VOpen: { ** A jump is made to P2 if the result set after filtering would be empty. */ case OP_VFilter: { /* jump */ -#if 0 /* local variables moved into u.ck */ +#if 0 /* local variables moved into u.ch */ int nArg; int iQuery; const sqlite3_module *pModule; @@ -56167,50 +57321,48 @@ case OP_VFilter: { /* jump */ int res; int i; Mem **apArg; -#endif /* local variables moved into u.ck */ +#endif /* local variables moved into u.ch */ - u.ck.pQuery = &p->aMem[pOp->p3]; - u.ck.pArgc = &u.ck.pQuery[1]; - u.ck.pCur = p->apCsr[pOp->p1]; - REGISTER_TRACE(pOp->p3, u.ck.pQuery); - assert( u.ck.pCur->pVtabCursor ); - u.ck.pVtabCursor = u.ck.pCur->pVtabCursor; - u.ck.pVtab = u.ck.pVtabCursor->pVtab; - u.ck.pModule = u.ck.pVtab->pModule; + u.ch.pQuery = &p->aMem[pOp->p3]; + u.ch.pArgc = &u.ch.pQuery[1]; + u.ch.pCur = p->apCsr[pOp->p1]; + REGISTER_TRACE(pOp->p3, u.ch.pQuery); + assert( u.ch.pCur->pVtabCursor ); + u.ch.pVtabCursor = u.ch.pCur->pVtabCursor; + u.ch.pVtab = u.ch.pVtabCursor->pVtab; + u.ch.pModule = u.ch.pVtab->pModule; /* Grab the index number and argc parameters */ - assert( (u.ck.pQuery->flags&MEM_Int)!=0 && u.ck.pArgc->flags==MEM_Int ); - u.ck.nArg = (int)u.ck.pArgc->u.i; - u.ck.iQuery = (int)u.ck.pQuery->u.i; + assert( (u.ch.pQuery->flags&MEM_Int)!=0 && u.ch.pArgc->flags==MEM_Int ); + u.ch.nArg = (int)u.ch.pArgc->u.i; + u.ch.iQuery = (int)u.ch.pQuery->u.i; /* Invoke the xFilter method */ { - u.ck.res = 0; - u.ck.apArg = p->apArg; - for(u.ck.i = 0; u.ck.iapArg; + for(u.ch.i = 0; u.ch.iinVtabMethod = 1; - rc = u.ck.pModule->xFilter(u.ck.pVtabCursor, u.ck.iQuery, pOp->p4.z, u.ck.nArg, u.ck.apArg); + rc = u.ch.pModule->xFilter(u.ch.pVtabCursor, u.ch.iQuery, pOp->p4.z, u.ch.nArg, u.ch.apArg); p->inVtabMethod = 0; sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.ck.pVtab->zErrMsg; - u.ck.pVtab->zErrMsg = 0; - sqlite3VtabUnlock(db, u.ck.pVtab); + p->zErrMsg = u.ch.pVtab->zErrMsg; + u.ch.pVtab->zErrMsg = 0; if( rc==SQLITE_OK ){ - u.ck.res = u.ck.pModule->xEof(u.ck.pVtabCursor); + u.ch.res = u.ch.pModule->xEof(u.ch.pVtabCursor); } if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; - if( u.ck.res ){ + if( u.ch.res ){ pc = pOp->p2 - 1; } } - u.ck.pCur->nullRow = 0; + u.ch.pCur->nullRow = 0; break; } @@ -56224,53 +57376,56 @@ case OP_VFilter: { /* jump */ ** P1 cursor is pointing to into register P3. */ case OP_VColumn: { -#if 0 /* local variables moved into u.cl */ +#if 0 /* local variables moved into u.ci */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; Mem *pDest; sqlite3_context sContext; -#endif /* local variables moved into u.cl */ +#endif /* local variables moved into u.ci */ VdbeCursor *pCur = p->apCsr[pOp->p1]; assert( pCur->pVtabCursor ); assert( pOp->p3>0 && pOp->p3<=p->nMem ); - u.cl.pDest = &p->aMem[pOp->p3]; + u.ci.pDest = &p->aMem[pOp->p3]; if( pCur->nullRow ){ - sqlite3VdbeMemSetNull(u.cl.pDest); + sqlite3VdbeMemSetNull(u.ci.pDest); break; } - u.cl.pVtab = pCur->pVtabCursor->pVtab; - u.cl.pModule = u.cl.pVtab->pModule; - assert( u.cl.pModule->xColumn ); - memset(&u.cl.sContext, 0, sizeof(u.cl.sContext)); + u.ci.pVtab = pCur->pVtabCursor->pVtab; + u.ci.pModule = u.ci.pVtab->pModule; + assert( u.ci.pModule->xColumn ); + memset(&u.ci.sContext, 0, sizeof(u.ci.sContext)); /* The output cell may already have a buffer allocated. Move - ** the current contents to u.cl.sContext.s so in case the user-function + ** the current contents to u.ci.sContext.s so in case the user-function ** can use the already allocated buffer instead of allocating a ** new one. */ - sqlite3VdbeMemMove(&u.cl.sContext.s, u.cl.pDest); - MemSetTypeFlag(&u.cl.sContext.s, MEM_Null); + sqlite3VdbeMemMove(&u.ci.sContext.s, u.ci.pDest); + MemSetTypeFlag(&u.ci.sContext.s, MEM_Null); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - rc = u.cl.pModule->xColumn(pCur->pVtabCursor, &u.cl.sContext, pOp->p2); + rc = u.ci.pModule->xColumn(pCur->pVtabCursor, &u.ci.sContext, pOp->p2); sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.cl.pVtab->zErrMsg; - u.cl.pVtab->zErrMsg = 0; + p->zErrMsg = u.ci.pVtab->zErrMsg; + u.ci.pVtab->zErrMsg = 0; + if( u.ci.sContext.isError ){ + rc = u.ci.sContext.isError; + } /* Copy the result of the function to the P3 register. We ** do this regardless of whether or not an error occurred to ensure any - ** dynamic allocation in u.cl.sContext.s (a Mem struct) is released. + ** dynamic allocation in u.ci.sContext.s (a Mem struct) is released. */ - sqlite3VdbeChangeEncoding(&u.cl.sContext.s, encoding); - REGISTER_TRACE(pOp->p3, u.cl.pDest); - sqlite3VdbeMemMove(u.cl.pDest, &u.cl.sContext.s); - UPDATE_MAX_BLOBSIZE(u.cl.pDest); + sqlite3VdbeChangeEncoding(&u.ci.sContext.s, encoding); + REGISTER_TRACE(pOp->p3, u.ci.pDest); + sqlite3VdbeMemMove(u.ci.pDest, &u.ci.sContext.s); + UPDATE_MAX_BLOBSIZE(u.ci.pDest); if( sqlite3SafetyOn(db) ){ goto abort_due_to_misuse; } - if( sqlite3VdbeMemTooBig(u.cl.pDest) ){ + if( sqlite3VdbeMemTooBig(u.ci.pDest) ){ goto too_big; } break; @@ -56285,22 +57440,22 @@ case OP_VColumn: { ** the end of its result set, then fall through to the next instruction. */ case OP_VNext: { /* jump */ -#if 0 /* local variables moved into u.cm */ +#if 0 /* local variables moved into u.cj */ sqlite3_vtab *pVtab; const sqlite3_module *pModule; int res; VdbeCursor *pCur; -#endif /* local variables moved into u.cm */ +#endif /* local variables moved into u.cj */ - u.cm.res = 0; - u.cm.pCur = p->apCsr[pOp->p1]; - assert( u.cm.pCur->pVtabCursor ); - if( u.cm.pCur->nullRow ){ + u.cj.res = 0; + u.cj.pCur = p->apCsr[pOp->p1]; + assert( u.cj.pCur->pVtabCursor ); + if( u.cj.pCur->nullRow ){ break; } - u.cm.pVtab = u.cm.pCur->pVtabCursor->pVtab; - u.cm.pModule = u.cm.pVtab->pModule; - assert( u.cm.pModule->xNext ); + u.cj.pVtab = u.cj.pCur->pVtabCursor->pVtab; + u.cj.pModule = u.cj.pVtab->pModule; + assert( u.cj.pModule->xNext ); /* Invoke the xNext() method of the module. There is no way for the ** underlying implementation to return an error if one occurs during @@ -56309,20 +57464,18 @@ case OP_VNext: { /* jump */ ** some other method is next invoked on the save virtual table cursor. */ if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - sqlite3VtabLock(u.cm.pVtab); p->inVtabMethod = 1; - rc = u.cm.pModule->xNext(u.cm.pCur->pVtabCursor); + rc = u.cj.pModule->xNext(u.cj.pCur->pVtabCursor); p->inVtabMethod = 0; sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.cm.pVtab->zErrMsg; - u.cm.pVtab->zErrMsg = 0; - sqlite3VtabUnlock(db, u.cm.pVtab); + p->zErrMsg = u.cj.pVtab->zErrMsg; + u.cj.pVtab->zErrMsg = 0; if( rc==SQLITE_OK ){ - u.cm.res = u.cm.pModule->xEof(u.cm.pCur->pVtabCursor); + u.cj.res = u.cj.pModule->xEof(u.cj.pCur->pVtabCursor); } if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; - if( !u.cm.res ){ + if( !u.cj.res ){ /* If there is data, jump to P2 */ pc = pOp->p2 - 1; } @@ -56338,25 +57491,21 @@ case OP_VNext: { /* jump */ ** in register P1 is passed as the zName argument to the xRename method. */ case OP_VRename: { -#if 0 /* local variables moved into u.cn */ +#if 0 /* local variables moved into u.ck */ sqlite3_vtab *pVtab; Mem *pName; -#endif /* local variables moved into u.cn */ - - u.cn.pVtab = pOp->p4.pVtab; - u.cn.pName = &p->aMem[pOp->p1]; - assert( u.cn.pVtab->pModule->xRename ); - REGISTER_TRACE(pOp->p1, u.cn.pName); - - Stringify(u.cn.pName, encoding); +#endif /* local variables moved into u.ck */ + u.ck.pVtab = pOp->p4.pVtab->pVtab; + u.ck.pName = &p->aMem[pOp->p1]; + assert( u.ck.pVtab->pModule->xRename ); + REGISTER_TRACE(pOp->p1, u.ck.pName); + assert( u.ck.pName->flags & MEM_Str ); if( sqlite3SafetyOff(db) ) goto abort_due_to_misuse; - sqlite3VtabLock(u.cn.pVtab); - rc = u.cn.pVtab->pModule->xRename(u.cn.pVtab, u.cn.pName->z); + rc = u.ck.pVtab->pModule->xRename(u.ck.pVtab, u.ck.pName->z); sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.cn.pVtab->zErrMsg; - u.cn.pVtab->zErrMsg = 0; - sqlite3VtabUnlock(db, u.cn.pVtab); + p->zErrMsg = u.ck.pVtab->zErrMsg; + u.ck.pVtab->zErrMsg = 0; if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; break; @@ -56388,7 +57537,7 @@ case OP_VRename: { ** is set to the value of the rowid for the row just inserted. */ case OP_VUpdate: { -#if 0 /* local variables moved into u.co */ +#if 0 /* local variables moved into u.cl */ sqlite3_vtab *pVtab; sqlite3_module *pModule; int nArg; @@ -56396,34 +57545,29 @@ case OP_VUpdate: { sqlite_int64 rowid; Mem **apArg; Mem *pX; -#endif /* local variables moved into u.co */ +#endif /* local variables moved into u.cl */ - u.co.pVtab = pOp->p4.pVtab; - u.co.pModule = (sqlite3_module *)u.co.pVtab->pModule; - u.co.nArg = pOp->p2; + u.cl.pVtab = pOp->p4.pVtab->pVtab; + u.cl.pModule = (sqlite3_module *)u.cl.pVtab->pModule; + u.cl.nArg = pOp->p2; assert( pOp->p4type==P4_VTAB ); - if( u.co.pModule->xUpdate==0 ){ - sqlite3SetString(&p->zErrMsg, db, "read-only table"); - rc = SQLITE_ERROR; - }else{ - u.co.apArg = p->apArg; - u.co.pX = &p->aMem[pOp->p3]; - for(u.co.i=0; u.co.ixUpdate) ){ + u.cl.apArg = p->apArg; + u.cl.pX = &p->aMem[pOp->p3]; + for(u.cl.i=0; u.cl.ixUpdate(u.co.pVtab, u.co.nArg, u.co.apArg, &u.co.rowid); + rc = u.cl.pModule->xUpdate(u.cl.pVtab, u.cl.nArg, u.cl.apArg, &u.cl.rowid); sqlite3DbFree(db, p->zErrMsg); - p->zErrMsg = u.co.pVtab->zErrMsg; - u.co.pVtab->zErrMsg = 0; - sqlite3VtabUnlock(db, u.co.pVtab); + p->zErrMsg = u.cl.pVtab->zErrMsg; + u.cl.pVtab->zErrMsg = 0; if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse; - if( pOp->p1 && rc==SQLITE_OK ){ - assert( u.co.nArg>1 && u.co.apArg[0] && (u.co.apArg[0]->flags&MEM_Null) ); - db->lastRowid = u.co.rowid; + if( rc==SQLITE_OK && pOp->p1 ){ + assert( u.cl.nArg>1 && u.cl.apArg[0] && (u.cl.apArg[0]->flags&MEM_Null) ); + db->lastRowid = u.cl.rowid; } p->nChange++; } @@ -56437,18 +57581,21 @@ case OP_VUpdate: { ** Write the current number of pages in database P1 to memory cell P2. */ case OP_Pagecount: { /* out2-prerelease */ -#if 0 /* local variables moved into u.cp */ +#if 0 /* local variables moved into u.cm */ int p1; int nPage; Pager *pPager; -#endif /* local variables moved into u.cp */ +#endif /* local variables moved into u.cm */ - u.cp.p1 = pOp->p1; - u.cp.pPager = sqlite3BtreePager(db->aDb[u.cp.p1].pBt); - rc = sqlite3PagerPagecount(u.cp.pPager, &u.cp.nPage); - if( rc==SQLITE_OK ){ + u.cm.p1 = pOp->p1; + u.cm.pPager = sqlite3BtreePager(db->aDb[u.cm.p1].pBt); + rc = sqlite3PagerPagecount(u.cm.pPager, &u.cm.nPage); + /* OP_Pagecount is always called from within a read transaction. The + ** page count has already been successfully read and cached. So the + ** sqlite3PagerPagecount() call above cannot fail. */ + if( ALWAYS(rc==SQLITE_OK) ){ pOut->flags = MEM_Int; - pOut->u.i = u.cp.nPage; + pOut->u.i = u.cm.nPage; } break; } @@ -56461,18 +57608,18 @@ case OP_Pagecount: { /* out2-prerelease */ ** the UTF-8 string contained in P4 is emitted on the trace callback. */ case OP_Trace: { -#if 0 /* local variables moved into u.cq */ +#if 0 /* local variables moved into u.cn */ char *zTrace; -#endif /* local variables moved into u.cq */ +#endif /* local variables moved into u.cn */ - u.cq.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); - if( u.cq.zTrace ){ + u.cn.zTrace = (pOp->p4.z ? pOp->p4.z : p->zSql); + if( u.cn.zTrace ){ if( db->xTrace ){ - db->xTrace(db->pTraceArg, u.cq.zTrace); + db->xTrace(db->pTraceArg, u.cn.zTrace); } #ifdef SQLITE_DEBUG if( (db->flags & SQLITE_SqlTrace)!=0 ){ - sqlite3DebugPrintf("SQL-trace: %s\n", u.cq.zTrace); + sqlite3DebugPrintf("SQL-trace: %s\n", u.cn.zTrace); } #endif /* SQLITE_DEBUG */ } @@ -56615,7 +57762,7 @@ abort_due_to_interrupt: ** ** This file contains code used to implement incremental BLOB I/O. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ @@ -56667,19 +57814,18 @@ SQLITE_API int sqlite3_blob_open( static const VdbeOpList openBlob[] = { {OP_Transaction, 0, 0, 0}, /* 0: Start a transaction */ {OP_VerifyCookie, 0, 0, 0}, /* 1: Check the schema cookie */ - - /* One of the following two instructions is replaced by an - ** OP_Noop before exection. - */ - {OP_OpenRead, 0, 0, 0}, /* 2: Open cursor 0 for reading */ - {OP_OpenWrite, 0, 0, 0}, /* 3: Open cursor 0 for read/write */ - - {OP_Variable, 1, 1, 1}, /* 4: Push the rowid to the stack */ - {OP_NotExists, 0, 8, 1}, /* 5: Seek the cursor */ - {OP_Column, 0, 0, 1}, /* 6 */ - {OP_ResultRow, 1, 0, 0}, /* 7 */ - {OP_Close, 0, 0, 0}, /* 8 */ - {OP_Halt, 0, 0, 0}, /* 9 */ + {OP_TableLock, 0, 0, 0}, /* 2: Acquire a read or write lock */ + + /* One of the following two instructions is replaced by an OP_Noop. */ + {OP_OpenRead, 0, 0, 0}, /* 3: Open cursor 0 for reading */ + {OP_OpenWrite, 0, 0, 0}, /* 4: Open cursor 0 for read/write */ + + {OP_Variable, 1, 1, 1}, /* 5: Push the rowid to the stack */ + {OP_NotExists, 0, 9, 1}, /* 6: Seek the cursor */ + {OP_Column, 0, 0, 1}, /* 7 */ + {OP_ResultRow, 1, 0, 0}, /* 8 */ + {OP_Close, 0, 0, 0}, /* 9 */ + {OP_Halt, 0, 0, 0}, /* 10 */ }; Vdbe *v = 0; @@ -56746,35 +57892,56 @@ SQLITE_API int sqlite3_blob_open( } /* If the value is being opened for writing, check that the - ** column is not indexed. It is against the rules to open an - ** indexed column for writing. - */ + ** column is not indexed, and that it is not part of a foreign key. + ** It is against the rules to open a column to which either of these + ** descriptions applies for writing. */ if( flags ){ + const char *zFault = 0; Index *pIdx; +#ifndef SQLITE_OMIT_FOREIGN_KEY + if( db->flags&SQLITE_ForeignKeys ){ + /* Check that the column is not part of an FK child key definition. It + ** is not necessary to check if it is part of a parent key, as parent + ** key columns must be indexed. The check below will pick up this + ** case. */ + FKey *pFKey; + for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + int j; + for(j=0; jnCol; j++){ + if( pFKey->aCol[j].iFrom==iCol ){ + zFault = "foreign key"; + } + } + } + } +#endif for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ int j; for(j=0; jnColumn; j++){ if( pIdx->aiColumn[j]==iCol ){ - sqlite3DbFree(db, zErr); - zErr = sqlite3MPrintf(db, - "cannot open indexed column for writing"); - rc = SQLITE_ERROR; - (void)sqlite3SafetyOff(db); - sqlite3BtreeLeaveAll(db); - goto blob_open_out; + zFault = "indexed"; } } } + if( zFault ){ + sqlite3DbFree(db, zErr); + zErr = sqlite3MPrintf(db, "cannot open %s column for writing", zFault); + rc = SQLITE_ERROR; + (void)sqlite3SafetyOff(db); + sqlite3BtreeLeaveAll(db); + goto blob_open_out; + } } v = sqlite3VdbeCreate(db); if( v ){ int iDb = sqlite3SchemaToIndex(db, pTab->pSchema); sqlite3VdbeAddOpList(v, sizeof(openBlob)/sizeof(VdbeOpList), openBlob); + flags = !!flags; /* flags = (flags ? 1 : 0); */ /* Configure the OP_Transaction */ sqlite3VdbeChangeP1(v, 0, iDb); - sqlite3VdbeChangeP2(v, 0, (flags ? 1 : 0)); + sqlite3VdbeChangeP2(v, 0, flags); /* Configure the OP_VerifyCookie */ sqlite3VdbeChangeP1(v, 1, iDb); @@ -56783,13 +57950,17 @@ SQLITE_API int sqlite3_blob_open( /* Make sure a mutex is held on the table to be accessed */ sqlite3VdbeUsesBtree(v, iDb); + /* Configure the OP_TableLock instruction */ + sqlite3VdbeChangeP1(v, 2, iDb); + sqlite3VdbeChangeP2(v, 2, pTab->tnum); + sqlite3VdbeChangeP3(v, 2, flags); + sqlite3VdbeChangeP4(v, 2, pTab->zName, P4_TRANSIENT); + /* Remove either the OP_OpenWrite or OpenRead. Set the P2 - ** parameter of the other to pTab->tnum. - */ - flags = !!flags; - sqlite3VdbeChangeToNoop(v, 3 - flags, 1); - sqlite3VdbeChangeP2(v, 2 + flags, pTab->tnum); - sqlite3VdbeChangeP3(v, 2 + flags, iDb); + ** parameter of the other to pTab->tnum. */ + sqlite3VdbeChangeToNoop(v, 4 - flags, 1); + sqlite3VdbeChangeP2(v, 3 + flags, pTab->tnum); + sqlite3VdbeChangeP3(v, 3 + flags, iDb); /* Configure the number of columns. Configure the cursor to ** think that the table has one more column than it really @@ -56798,10 +57969,10 @@ SQLITE_API int sqlite3_blob_open( ** we can invoke OP_Column to fill in the vdbe cursors type ** and offset cache without causing any IO. */ - sqlite3VdbeChangeP4(v, 2+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); - sqlite3VdbeChangeP2(v, 6, pTab->nCol); + sqlite3VdbeChangeP4(v, 3+flags, SQLITE_INT_TO_PTR(pTab->nCol+1),P4_INT32); + sqlite3VdbeChangeP2(v, 7, pTab->nCol); if( !db->mallocFailed ){ - sqlite3VdbeMakeReady(v, 1, 1, 1, 0); + sqlite3VdbeMakeReady(v, 1, 1, 1, 0, 0, 0); } } @@ -56984,7 +58155,7 @@ SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *pBlob){ ** ************************************************************************* ** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** @(#) $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifdef SQLITE_ENABLE_ATOMIC_WRITE @@ -57230,7 +58401,7 @@ SQLITE_PRIVATE int sqlite3JournalSize(sqlite3_vfs *pVfs){ ** The in-memory rollback journal is used to journal transactions for ** ":memory:" databases and when the journal_mode=MEMORY pragma is used. ** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** @(#) $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* Forward references to internal structures */ @@ -57489,7 +58660,7 @@ SQLITE_PRIVATE int sqlite3MemJournalSize(void){ ** This file contains routines used for walking the parser tree for ** an SQL statement. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ @@ -57536,14 +58707,14 @@ SQLITE_PRIVATE int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ ** an abort request is seen. */ SQLITE_PRIVATE int sqlite3WalkExprList(Walker *pWalker, ExprList *p){ - int i, rc = WRC_Continue; + int i; struct ExprList_item *pItem; if( p ){ for(i=p->nExpr, pItem=p->a; i>0; i--, pItem++){ if( sqlite3WalkExpr(pWalker, pItem->pExpr) ) return WRC_Abort; } } - return rc & WRC_Continue; + return WRC_Continue; } /* @@ -57576,7 +58747,7 @@ SQLITE_PRIVATE int sqlite3WalkSelectFrom(Walker *pWalker, Select *p){ struct SrcList_item *pItem; pSrc = p->pSrc; - if( pSrc ){ + if( ALWAYS(pSrc) ){ for(i=pSrc->nSrc, pItem=pSrc->a; i>0; i--, pItem++){ if( sqlite3WalkSelect(pWalker, pItem->pSelect) ){ return WRC_Abort; @@ -57629,7 +58800,7 @@ SQLITE_PRIVATE int sqlite3WalkSelect(Walker *pWalker, Select *p){ ** resolve all identifiers by associating them with a particular ** table and column. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -57688,15 +58859,14 @@ static void resolveAlias( if( pDup==0 ) return; }else{ char *zToken = pOrig->u.zToken; + assert( zToken!=0 ); pOrig->u.zToken = 0; pDup = sqlite3ExprDup(db, pOrig, 0); pOrig->u.zToken = zToken; if( pDup==0 ) return; - if( zToken ){ - assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 ); - pDup->flags2 |= EP2_MallocedToken; - pDup->u.zToken = sqlite3DbStrDup(db, zToken); - } + assert( (pDup->flags & (EP_Reduced|EP_TokenOnly))==0 ); + pDup->flags2 |= EP2_MallocedToken; + pDup->u.zToken = sqlite3DbStrDup(db, zToken); } if( pExpr->flags & EP_ExpCollate ){ pDup->pColl = pExpr->pColl; @@ -57732,7 +58902,7 @@ static void resolveAlias( ** can be used. ** ** If the name cannot be resolved unambiguously, leave an error message -** in pParse and return non-zero. Return zero on success. +** in pParse and return WRC_Abort. Return WRC_Prune on success. */ static int lookupName( Parse *pParse, /* The parsing context */ @@ -57750,6 +58920,7 @@ static int lookupName( struct SrcList_item *pMatch = 0; /* The matching pSrcList item */ NameContext *pTopNC = pNC; /* First namecontext in the list */ Schema *pSchema = 0; /* Schema of the expression */ + int isTrigger = 0; assert( pNC ); /* the name context cannot be NULL. */ assert( zCol ); /* The Z in X.Y.Z cannot be NULL */ @@ -57781,7 +58952,9 @@ static int lookupName( if( sqlite3StrICmp(zTabName, zTab)!=0 ) continue; }else{ char *zTabName = pTab->zName; - if( zTabName==0 || sqlite3StrICmp(zTabName, zTab)!=0 ) continue; + if( NEVER(zTabName==0) || sqlite3StrICmp(zTabName, zTab)!=0 ){ + continue; + } if( zDb!=0 && sqlite3StrICmp(db->aDb[iDb].zName, zDb)!=0 ){ continue; } @@ -57833,45 +59006,48 @@ static int lookupName( /* If we have not already resolved the name, then maybe ** it is a new.* or old.* trigger argument reference */ - if( zDb==0 && zTab!=0 && cnt==0 && pParse->trigStack!=0 ){ - TriggerStack *pTriggerStack = pParse->trigStack; + if( zDb==0 && zTab!=0 && cnt==0 && pParse->pTriggerTab!=0 ){ + int op = pParse->eTriggerOp; Table *pTab = 0; - u32 *piColMask = 0; - if( pTriggerStack->newIdx != -1 && sqlite3StrICmp("new", zTab) == 0 ){ - pExpr->iTable = pTriggerStack->newIdx; - assert( pTriggerStack->pTab ); - pTab = pTriggerStack->pTab; - piColMask = &(pTriggerStack->newColMask); - }else if( pTriggerStack->oldIdx != -1 && sqlite3StrICmp("old", zTab)==0 ){ - pExpr->iTable = pTriggerStack->oldIdx; - assert( pTriggerStack->pTab ); - pTab = pTriggerStack->pTab; - piColMask = &(pTriggerStack->oldColMask); + assert( op==TK_DELETE || op==TK_UPDATE || op==TK_INSERT ); + if( op!=TK_DELETE && sqlite3StrICmp("new",zTab) == 0 ){ + pExpr->iTable = 1; + pTab = pParse->pTriggerTab; + }else if( op!=TK_INSERT && sqlite3StrICmp("old",zTab)==0 ){ + pExpr->iTable = 0; + pTab = pParse->pTriggerTab; } if( pTab ){ int iCol; - Column *pCol = pTab->aCol; - pSchema = pTab->pSchema; cntTab++; - for(iCol=0; iCol < pTab->nCol; iCol++, pCol++) { - if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ - cnt++; - pExpr->iColumn = iCol==pTab->iPKey ? -1 : (i16)iCol; - pExpr->pTab = pTab; - if( iCol>=0 ){ - testcase( iCol==31 ); - testcase( iCol==32 ); - if( iCol>=32 ){ - *piColMask = 0xffffffff; - }else{ - *piColMask |= ((u32)1)<nCol; iCol++){ + Column *pCol = &pTab->aCol[iCol]; + if( sqlite3StrICmp(pCol->zName, zCol)==0 ){ + if( iCol==pTab->iPKey ){ + iCol = -1; } + break; } - break; } } + if( iColnCol ){ + cnt++; + if( iCol<0 ){ + pExpr->affinity = SQLITE_AFF_INTEGER; + }else if( pExpr->iTable==0 ){ + testcase( iCol==31 ); + testcase( iCol==32 ); + pParse->oldmask |= (iCol>=32 ? 0xffffffff : (((u32)1)<iColumn = (i16)iCol; + pExpr->pTab = pTab; + isTrigger = 1; + } } } #endif /* !defined(SQLITE_OMIT_TRIGGER) */ @@ -57908,7 +59084,7 @@ static int lookupName( pOrig = pEList->a[j].pExpr; if( !pNC->allowAgg && ExprHasProperty(pOrig, EP_Agg) ){ sqlite3ErrorMsg(pParse, "misuse of aliased aggregate %s", zAs); - return 2; + return WRC_Abort; } resolveAlias(pParse, pEList, j, pExpr, ""); cnt = 1; @@ -57940,7 +59116,7 @@ static int lookupName( if( cnt==0 && zTab==0 && ExprHasProperty(pExpr,EP_DblQuoted) ){ pExpr->op = TK_STRING; pExpr->pTab = 0; - return 0; + return WRC_Prune; } /* @@ -57982,7 +59158,7 @@ static int lookupName( pExpr->pLeft = 0; sqlite3ExprDelete(db, pExpr->pRight); pExpr->pRight = 0; - pExpr->op = TK_COLUMN; + pExpr->op = (isTrigger ? TK_TRIGGER : TK_COLUMN); lookupname_end: if( cnt==1 ){ assert( pNC!=0 ); @@ -57995,9 +59171,9 @@ lookupname_end: if( pTopNC==pNC ) break; pTopNC = pTopNC->pNext; } - return 0; + return WRC_Prune; } else { - return 1; + return WRC_Abort; } } @@ -58056,8 +59232,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ /* A lone identifier is the name of a column. */ case TK_ID: { - lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr); - return WRC_Prune; + return lookupName(pParse, 0, 0, pExpr->u.zToken, pNC, pExpr); } /* A table name and column name: ID.ID @@ -58081,8 +59256,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ zTable = pRight->pLeft->u.zToken; zColumn = pRight->pRight->u.zToken; } - lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); - return WRC_Prune; + return lookupName(pParse, zDb, zTable, zColumn, pNC, pExpr); } /* Resolve function names @@ -58100,6 +59274,7 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ FuncDef *pDef; /* Information about the function */ u8 enc = ENC(pParse->db); /* The database encoding */ + testcase( pExpr->op==TK_CONST_FUNC ); assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); zId = pExpr->u.zToken; nId = sqlite3Strlen30(zId); @@ -58154,9 +59329,10 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){ } #ifndef SQLITE_OMIT_SUBQUERY case TK_SELECT: - case TK_EXISTS: + case TK_EXISTS: testcase( pExpr->op==TK_EXISTS ); #endif case TK_IN: { + testcase( pExpr->op==TK_IN ); if( ExprHasProperty(pExpr, EP_xIsSelect) ){ int nRef = pNC->nRef; #ifndef SQLITE_OMIT_CHECK @@ -58205,7 +59381,7 @@ static int resolveAsName( UNUSED_PARAMETER(pParse); - if( pE->op==TK_ID || (pE->op==TK_STRING && pE->u.zToken[0]!='\'') ){ + if( pE->op==TK_ID ){ char *zCol = pE->u.zToken; for(i=0; inExpr; i++){ char *zAs = pEList->a[i].zName; @@ -58341,7 +59517,7 @@ static int resolveCompoundOrderBy( if( pItem->done ) continue; pE = pItem->pExpr; if( sqlite3ExprIsInteger(pE, &iCol) ){ - if( iCol<0 || iCol>pEList->nExpr ){ + if( iCol<=0 || iCol>pEList->nExpr ){ resolveOutOfRangeError(pParse, "ORDER", i+1, pEList->nExpr); return 1; } @@ -58355,9 +59531,6 @@ static int resolveCompoundOrderBy( } sqlite3ExprDelete(db, pDup); } - if( iCol<0 ){ - return 1; - } } if( iCol>0 ){ CollSeq *pColl = pE->pColl; @@ -58464,9 +59637,6 @@ static int resolveOrderGroupBy( for(i=0, pItem=pOrderBy->a; inExpr; i++, pItem++){ Expr *pE = pItem->pExpr; iCol = resolveAsName(pParse, pSelect->pEList, pE); - if( iCol<0 ){ - return 1; /* OOM error */ - } if( iCol>0 ){ /* If an AS-name match is found, mark this ORDER BY column as being ** a copy of the iCol-th result-set column. The subsequent call to @@ -58795,8 +59965,6 @@ SQLITE_PRIVATE void sqlite3ResolveSelectNames( ************************************************************************* ** This file contains routines used for analyzing expressions and ** for generating VDBE code that evaluates expressions in SQLite. -** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ */ /* @@ -58875,7 +60043,9 @@ SQLITE_PRIVATE CollSeq *sqlite3ExprCollSeq(Parse *pParse, Expr *pExpr){ pColl = p->pColl; if( pColl ) break; op = p->op; - if( (op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER) && p->pTab!=0 ){ + if( p->pTab!=0 && ( + op==TK_AGG_COLUMN || op==TK_COLUMN || op==TK_REGISTER || op==TK_TRIGGER + )){ /* op==TK_REGISTER && p->pTab!=0 happens when pExpr was originally ** a TK_COLUMN but was previously evaluated and cached in a register */ const char *zColl; @@ -58935,7 +60105,7 @@ static char comparisonAffinity(Expr *pExpr){ char aff; assert( pExpr->op==TK_EQ || pExpr->op==TK_IN || pExpr->op==TK_LT || pExpr->op==TK_GT || pExpr->op==TK_GE || pExpr->op==TK_LE || - pExpr->op==TK_NE ); + pExpr->op==TK_NE || pExpr->op==TK_IS || pExpr->op==TK_ISNOT ); assert( pExpr->pLeft ); aff = sqlite3ExprAffinity(pExpr->pLeft); if( pExpr->pRight ){ @@ -59273,11 +60443,11 @@ SQLITE_PRIVATE void sqlite3ExprAttachSubtrees( } /* -** Allocate a Expr node which joins up to two subtrees. +** Allocate a Expr node which joins as many as two subtrees. ** -** The -** Works like sqlite3Expr() except that it takes an extra Parse* -** argument and notifies the associated connection object if malloc fails. +** One or both of the subtrees can be NULL. Return a pointer to the new +** Expr node. Or, if an OOM error occurs, set pParse->db->mallocFailed, +** free the subtrees and return NULL. */ SQLITE_PRIVATE Expr *sqlite3PExpr( Parse *pParse, /* Parsing context */ @@ -59669,9 +60839,8 @@ SQLITE_PRIVATE ExprList *sqlite3ExprListDup(sqlite3 *db, ExprList *p, int flags) } pOldItem = p->a; for(i=0; inExpr; i++, pItem++, pOldItem++){ - Expr *pNewExpr; Expr *pOldExpr = pOldItem->pExpr; - pItem->pExpr = pNewExpr = sqlite3ExprDup(db, pOldExpr, flags); + pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); pItem->zName = sqlite3DbStrDup(db, pOldItem->zName); pItem->zSpan = sqlite3DbStrDup(db, pOldItem->zSpan); pItem->sortOrder = pOldItem->sortOrder; @@ -60182,7 +61351,6 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ if( iCol<0 ){ int iMem = ++pParse->nMem; int iAddr; - sqlite3VdbeUsesBtree(v, iDb); iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem); sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); @@ -60216,9 +61384,6 @@ SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){ char *pKey; pKey = (char *)sqlite3IndexKeyinfo(pParse, pIdx); - iDb = sqlite3SchemaToIndex(db, pIdx->pSchema); - sqlite3VdbeUsesBtree(v, iDb); - iAddr = sqlite3VdbeAddOp1(v, OP_If, iMem); sqlite3VdbeAddOp2(v, OP_Integer, 1, iMem); @@ -60307,7 +61472,7 @@ SQLITE_PRIVATE void sqlite3CodeSubselect( ** If all of the above are false, then we can run this code just once ** save the results, and reuse the same result on subsequent invocations. */ - if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->trigStack ){ + if( !ExprHasAnyProperty(pExpr, EP_VarSelect) && !pParse->pTriggerTab ){ int mem = ++pParse->nMem; sqlite3VdbeAddOp1(v, OP_If, mem); testAddr = sqlite3VdbeAddOp2(v, OP_Integer, 1, mem); @@ -60494,13 +61659,10 @@ static void codeReal(Vdbe *v, const char *z, int negateFlag, int iMem){ double value; char *zV; sqlite3AtoF(z, &value); - if( sqlite3IsNaN(value) ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, iMem); - }else{ - if( negateFlag ) value = -value; - zV = dup8bytes(v, (char*)&value); - sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL); - } + assert( !sqlite3IsNaN(value) ); /* The new AtoF never returns NaN */ + if( negateFlag ) value = -value; + zV = dup8bytes(v, (char*)&value); + sqlite3VdbeAddOp4(v, OP_Real, 0, iMem, 0, zV, P4_REAL); } } @@ -60708,12 +61870,7 @@ SQLITE_PRIVATE int sqlite3ExprCodeGetColumn( }else if( ALWAYS(pTab!=0) ){ int op = IsVirtual(pTab) ? OP_VColumn : OP_Column; sqlite3VdbeAddOp3(v, op, iTable, iColumn, iReg); - sqlite3ColumnDefault(v, pTab, iColumn); -#ifndef SQLITE_OMIT_FLOATING_POINT - if( pTab->aCol[iColumn].affinity==SQLITE_AFF_REAL ){ - sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); - } -#endif + sqlite3ColumnDefault(v, pTab, iColumn, iReg); } sqlite3ExprCacheStore(pParse, iTable, iColumn, iReg); return iReg; @@ -61040,6 +62197,19 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) testcase( regFree2==0 ); break; } + case TK_IS: + case TK_ISNOT: { + testcase( op==TK_IS ); + testcase( op==TK_ISNOT ); + codeCompareOperands(pParse, pExpr->pLeft, &r1, ®Free1, + pExpr->pRight, &r2, ®Free2); + op = (op==TK_IS) ? TK_EQ : TK_NE; + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, inReg, SQLITE_STOREP2 | SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } case TK_AND: case TK_OR: case TK_PLUS: @@ -61161,10 +62331,15 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) zId = pExpr->u.zToken; nId = sqlite3Strlen30(zId); pDef = sqlite3FindFunction(db, zId, nId, nFarg, enc, 0); - assert( pDef!=0 ); + if( pDef==0 ){ + sqlite3ErrorMsg(pParse, "unknown function: %.*s()", nId, zId); + break; + } if( pFarg ){ r1 = sqlite3GetTempRange(pParse, nFarg); + sqlite3ExprCachePush(pParse); /* Ticket 2ea2425d34be */ sqlite3ExprCodeExprList(pParse, pFarg, r1, 1); + sqlite3ExprCachePop(pParse, 1); /* Ticket 2ea2425d34be */ }else{ r1 = 0; } @@ -61347,6 +62522,58 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) break; } + case TK_TRIGGER: { + /* If the opcode is TK_TRIGGER, then the expression is a reference + ** to a column in the new.* or old.* pseudo-tables available to + ** trigger programs. In this case Expr.iTable is set to 1 for the + ** new.* pseudo-table, or 0 for the old.* pseudo-table. Expr.iColumn + ** is set to the column of the pseudo-table to read, or to -1 to + ** read the rowid field. + ** + ** The expression is implemented using an OP_Param opcode. The p1 + ** parameter is set to 0 for an old.rowid reference, or to (i+1) + ** to reference another column of the old.* pseudo-table, where + ** i is the index of the column. For a new.rowid reference, p1 is + ** set to (n+1), where n is the number of columns in each pseudo-table. + ** For a reference to any other column in the new.* pseudo-table, p1 + ** is set to (n+2+i), where n and i are as defined previously. For + ** example, if the table on which triggers are being fired is + ** declared as: + ** + ** CREATE TABLE t1(a, b); + ** + ** Then p1 is interpreted as follows: + ** + ** p1==0 -> old.rowid p1==3 -> new.rowid + ** p1==1 -> old.a p1==4 -> new.a + ** p1==2 -> old.b p1==5 -> new.b + */ + Table *pTab = pExpr->pTab; + int p1 = pExpr->iTable * (pTab->nCol+1) + 1 + pExpr->iColumn; + + assert( pExpr->iTable==0 || pExpr->iTable==1 ); + assert( pExpr->iColumn>=-1 && pExpr->iColumnnCol ); + assert( pTab->iPKey<0 || pExpr->iColumn!=pTab->iPKey ); + assert( p1>=0 && p1<(pTab->nCol*2+2) ); + + sqlite3VdbeAddOp2(v, OP_Param, p1, target); + VdbeComment((v, "%s.%s -> $%d", + (pExpr->iTable ? "new" : "old"), + (pExpr->iColumn<0 ? "rowid" : pExpr->pTab->aCol[pExpr->iColumn].zName), + target + )); + + /* If the column has REAL affinity, it may currently be stored as an + ** integer. Use OP_RealAffinity to make sure it is really real. */ + if( pExpr->iColumn>=0 + && pTab->aCol[pExpr->iColumn].affinity==SQLITE_AFF_REAL + ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, target); + } + break; + } + + /* ** Form A: ** CASE x WHEN e1 THEN r1 WHEN e2 THEN r2 ... WHEN eN THEN rN ELSE y END @@ -61431,24 +62658,27 @@ SQLITE_PRIVATE int sqlite3ExprCodeTarget(Parse *pParse, Expr *pExpr, int target) } #ifndef SQLITE_OMIT_TRIGGER case TK_RAISE: { - if( !pParse->trigStack ){ + assert( pExpr->affinity==OE_Rollback + || pExpr->affinity==OE_Abort + || pExpr->affinity==OE_Fail + || pExpr->affinity==OE_Ignore + ); + if( !pParse->pTriggerTab ){ sqlite3ErrorMsg(pParse, "RAISE() may only be used within a trigger-program"); return 0; } - if( pExpr->affinity!=OE_Ignore ){ - assert( pExpr->affinity==OE_Rollback || - pExpr->affinity == OE_Abort || - pExpr->affinity == OE_Fail ); - assert( !ExprHasProperty(pExpr, EP_IntValue) ); - sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, pExpr->affinity, 0, - pExpr->u.zToken, 0); - } else { - assert( pExpr->affinity == OE_Ignore ); - sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0); - sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->trigStack->ignoreJump); - VdbeComment((v, "raise(IGNORE)")); + if( pExpr->affinity==OE_Abort ){ + sqlite3MayAbort(pParse); } + assert( !ExprHasProperty(pExpr, EP_IntValue) ); + if( pExpr->affinity==OE_Ignore ){ + sqlite3VdbeAddOp4( + v, OP_Halt, SQLITE_OK, OE_Ignore, 0, pExpr->u.zToken,0); + }else{ + sqlite3HaltConstraint(pParse, pExpr->affinity, pExpr->u.zToken, 0); + } + break; } #endif @@ -61624,6 +62854,7 @@ static int evalConstExpr(Walker *pWalker, Expr *pExpr){ int r2; r2 = sqlite3ExprCodeTarget(pParse, pExpr, r1); if( NEVER(r1!=r2) ) sqlite3ReleaseTempReg(pParse, r1); + pExpr->op2 = pExpr->op; pExpr->op = TK_REGISTER; pExpr->iTable = r2; return WRC_Prune; @@ -61753,6 +62984,19 @@ SQLITE_PRIVATE void sqlite3ExprIfTrue(Parse *pParse, Expr *pExpr, int dest, int testcase( regFree2==0 ); break; } + case TK_IS: + case TK_ISNOT: { + testcase( op==TK_IS ); + testcase( op==TK_ISNOT ); + codeCompareOperands(pParse, pExpr->pLeft, &r1, ®Free1, + pExpr->pRight, &r2, ®Free2); + op = (op==TK_IS) ? TK_EQ : TK_NE; + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } case TK_ISNULL: case TK_NOTNULL: { assert( TK_ISNULL==OP_IsNull ); @@ -61902,6 +63146,19 @@ SQLITE_PRIVATE void sqlite3ExprIfFalse(Parse *pParse, Expr *pExpr, int dest, int testcase( regFree2==0 ); break; } + case TK_IS: + case TK_ISNOT: { + testcase( pExpr->op==TK_IS ); + testcase( pExpr->op==TK_ISNOT ); + codeCompareOperands(pParse, pExpr->pLeft, &r1, ®Free1, + pExpr->pRight, &r2, ®Free2); + op = (pExpr->op==TK_IS) ? TK_NE : TK_EQ; + codeCompare(pParse, pExpr->pLeft, pExpr->pRight, op, + r1, r2, dest, SQLITE_NULLEQ); + testcase( regFree1==0 ); + testcase( regFree2==0 ); + break; + } case TK_ISNULL: case TK_NOTNULL: { testcase( op==TK_ISNULL ); @@ -62291,7 +63548,7 @@ SQLITE_PRIVATE void sqlite3ReleaseTempRange(Parse *pParse, int iReg, int nReg){ ** This file contains C code routines that used to generate VDBE code ** that implements the ALTER TABLE command. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -62363,6 +63620,69 @@ static void renameTableFunc( } } +/* +** This C function implements an SQL user function that is used by SQL code +** generated by the ALTER TABLE ... RENAME command to modify the definition +** of any foreign key constraints that use the table being renamed as the +** parent table. It is passed three arguments: +** +** 1) The complete text of the CREATE TABLE statement being modified, +** 2) The old name of the table being renamed, and +** 3) The new name of the table being renamed. +** +** It returns the new CREATE TABLE statement. For example: +** +** sqlite_rename_parent('CREATE TABLE t1(a REFERENCES t2)', 't2', 't3') +** -> 'CREATE TABLE t1(a REFERENCES t3)' +*/ +#ifndef SQLITE_OMIT_FOREIGN_KEY +static void renameParentFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **argv +){ + sqlite3 *db = sqlite3_context_db_handle(context); + char *zOutput = 0; + char *zResult; + unsigned char const *zInput = sqlite3_value_text(argv[0]); + unsigned char const *zOld = sqlite3_value_text(argv[1]); + unsigned char const *zNew = sqlite3_value_text(argv[2]); + + unsigned const char *z; /* Pointer to token */ + int n; /* Length of token z */ + int token; /* Type of token */ + + UNUSED_PARAMETER(NotUsed); + for(z=zInput; *z; z=z+n){ + n = sqlite3GetToken(z, &token); + if( token==TK_REFERENCES ){ + char *zParent; + do { + z += n; + n = sqlite3GetToken(z, &token); + }while( token==TK_SPACE ); + + zParent = sqlite3DbStrNDup(db, (const char *)z, n); + if( zParent==0 ) break; + sqlite3Dequote(zParent); + if( 0==sqlite3StrICmp((const char *)zOld, zParent) ){ + char *zOut = sqlite3MPrintf(db, "%s%.*s\"%w\"", + (zOutput?zOutput:""), z-zInput, zInput, (const char *)zNew + ); + sqlite3DbFree(db, zOutput); + zOutput = zOut; + zInput = &z[n]; + } + sqlite3DbFree(db, zParent); + } + } + + zResult = sqlite3MPrintf(db, "%s%s", (zOutput?zOutput:""), zInput), + sqlite3_result_text(context, zResult, -1, SQLITE_DYNAMIC); + sqlite3DbFree(db, zOutput); +} +#endif + #ifndef SQLITE_OMIT_TRIGGER /* This function is used by SQL generated to implement the ** ALTER TABLE command. The first argument is the text of a CREATE TRIGGER @@ -62450,8 +63770,56 @@ SQLITE_PRIVATE void sqlite3AlterFunctions(sqlite3 *db){ sqlite3CreateFunc(db, "sqlite_rename_trigger", 2, SQLITE_UTF8, 0, renameTriggerFunc, 0, 0); #endif +#ifndef SQLITE_OMIT_FOREIGN_KEY + sqlite3CreateFunc(db, "sqlite_rename_parent", 3, SQLITE_UTF8, 0, + renameParentFunc, 0, 0); +#endif } +/* +** This function is used to create the text of expressions of the form: +** +** name= OR name= OR ... +** +** If argument zWhere is NULL, then a pointer string containing the text +** "name=" is returned, where is the quoted version +** of the string passed as argument zConstant. The returned buffer is +** allocated using sqlite3DbMalloc(). It is the responsibility of the +** caller to ensure that it is eventually freed. +** +** If argument zWhere is not NULL, then the string returned is +** " OR name=", where is the contents of zWhere. +** In this case zWhere is passed to sqlite3DbFree() before returning. +** +*/ +static char *whereOrName(sqlite3 *db, char *zWhere, char *zConstant){ + char *zNew; + if( !zWhere ){ + zNew = sqlite3MPrintf(db, "name=%Q", zConstant); + }else{ + zNew = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, zConstant); + sqlite3DbFree(db, zWhere); + } + return zNew; +} + +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) +/* +** Generate the text of a WHERE expression which can be used to select all +** tables that have foreign key constraints that refer to table pTab (i.e. +** constraints for which pTab is the parent table) from the sqlite_master +** table. +*/ +static char *whereForeignKeys(Parse *pParse, Table *pTab){ + FKey *p; + char *zWhere = 0; + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + zWhere = whereOrName(pParse->db, zWhere, p->pFrom->zName); + } + return zWhere; +} +#endif + /* ** Generate the text of a WHERE expression which can be used to select all ** temporary triggers on table pTab from the sqlite_temp_master table. If @@ -62461,7 +63829,6 @@ SQLITE_PRIVATE void sqlite3AlterFunctions(sqlite3 *db){ static char *whereTempTriggers(Parse *pParse, Table *pTab){ Trigger *pTrig; char *zWhere = 0; - char *tmp = 0; const Schema *pTempSchema = pParse->db->aDb[1].pSchema; /* Temp db schema */ /* If the table is not located in the temp-db (in which case NULL is @@ -62473,13 +63840,7 @@ static char *whereTempTriggers(Parse *pParse, Table *pTab){ sqlite3 *db = pParse->db; for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ if( pTrig->pSchema==pTempSchema ){ - if( !zWhere ){ - zWhere = sqlite3MPrintf(db, "name=%Q", pTrig->name); - }else{ - tmp = zWhere; - zWhere = sqlite3MPrintf(db, "%s OR name=%Q", zWhere, pTrig->name); - sqlite3DbFree(db, tmp); - } + zWhere = whereOrName(db, zWhere, pTrig->zName); } } } @@ -62513,11 +63874,11 @@ static void reloadTableSchema(Parse *pParse, Table *pTab, const char *zName){ for(pTrig=sqlite3TriggerList(pParse, pTab); pTrig; pTrig=pTrig->pNext){ int iTrigDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); assert( iTrigDb==iDb || iTrigDb==1 ); - sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->name, 0); + sqlite3VdbeAddOp4(v, OP_DropTrigger, iTrigDb, 0, 0, pTrig->zName, 0); } #endif - /* Drop the table and index from the internal schema */ + /* Drop the table and index from the internal schema. */ sqlite3VdbeAddOp4(v, OP_DropTable, iDb, 0, 0, pTab->zName, 0); /* Reload the table, index and permanent trigger schemas. */ @@ -62555,7 +63916,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( #ifndef SQLITE_OMIT_TRIGGER char *zWhere = 0; /* Where clause to locate temp triggers */ #endif - int isVirtualRename = 0; /* True if this is a v-table with an xRename() */ + VTable *pVTab = 0; /* Non-zero if this is a v-tab with an xRename() */ if( NEVER(db->mallocFailed) ) goto exit_rename_table; assert( pSrc->nSrc==1 ); @@ -62610,8 +63971,11 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto exit_rename_table; } - if( IsVirtual(pTab) && pTab->pMod->pModule->xRename ){ - isVirtualRename = 1; + if( IsVirtual(pTab) ){ + pVTab = sqlite3GetVTable(db, pTab); + if( pVTab->pVtab->pModule->xRename==0 ){ + pVTab = 0; + } } #endif @@ -62624,7 +63988,7 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( if( v==0 ){ goto exit_rename_table; } - sqlite3BeginWriteOperation(pParse, isVirtualRename, iDb); + sqlite3BeginWriteOperation(pParse, pVTab!=0, iDb); sqlite3ChangeCookie(pParse, iDb); /* If this is a virtual table, invoke the xRename() function if @@ -62633,10 +63997,11 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( ** SQLite tables) that are identified by the name of the virtual table. */ #ifndef SQLITE_OMIT_VIRTUALTABLE - if( isVirtualRename ){ + if( pVTab ){ int i = ++pParse->nMem; sqlite3VdbeAddOp4(v, OP_String8, 0, i, 0, zName, 0); - sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pTab->pVtab, P4_VTAB); + sqlite3VdbeAddOp4(v, OP_VRename, i, 0, 0,(const char*)pVTab, P4_VTAB); + sqlite3MayAbort(pParse); } #endif @@ -62644,6 +64009,21 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( zTabName = pTab->zName; nTabName = sqlite3Utf8CharLen(zTabName, -1); +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + if( db->flags&SQLITE_ForeignKeys ){ + /* If foreign-key support is enabled, rewrite the CREATE TABLE + ** statements corresponding to all child tables of foreign key constraints + ** for which the renamed table is the parent table. */ + if( (zWhere=whereForeignKeys(pParse, pTab))!=0 ){ + sqlite3NestedParse(pParse, + "UPDATE sqlite_master SET " + "sql = sqlite_rename_parent(sql, %Q, %Q) " + "WHERE %s;", zTabName, zName, zWhere); + sqlite3DbFree(db, zWhere); + } + } +#endif + /* Modify the sqlite_master table to use the new table name. */ sqlite3NestedParse(pParse, "UPDATE %Q.%s SET " @@ -62695,6 +64075,18 @@ SQLITE_PRIVATE void sqlite3AlterRenameTable( } #endif +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + if( db->flags&SQLITE_ForeignKeys ){ + FKey *p; + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + Table *pFrom = p->pFrom; + if( pFrom!=pTab ){ + reloadTableSchema(pParse, p->pFrom, pFrom->zName); + } + } + } +#endif + /* Drop and reload the internal table schema. */ reloadTableSchema(pParse, pTab, zName); @@ -62789,6 +64181,11 @@ SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *pParse, Token *pColDef){ sqlite3ErrorMsg(pParse, "Cannot add a UNIQUE column"); return; } + if( (db->flags&SQLITE_ForeignKeys) && pNew->pFKey && pDflt ){ + sqlite3ErrorMsg(pParse, + "Cannot add a REFERENCES column with non-NULL default value"); + return; + } if( pCol->notNull && !pDflt ){ sqlite3ErrorMsg(pParse, "Cannot add a NOT NULL column with default value NULL"); @@ -62947,17 +64344,25 @@ exit_begin_add_column: ************************************************************************* ** This file contains code associated with the ANALYZE command. ** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** @(#) $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef SQLITE_OMIT_ANALYZE /* -** This routine generates code that opens the sqlite_stat1 table on cursor -** iStatCur. +** This routine generates code that opens the sqlite_stat1 table for +** writing with cursor iStatCur. If the library was built with the +** SQLITE_ENABLE_STAT2 macro defined, then the sqlite_stat2 table is +** opened for writing using cursor (iStatCur+1) ** ** If the sqlite_stat1 tables does not previously exist, it is created. -** If it does previously exist, all entires associated with table zWhere -** are removed. If zWhere==0 then all entries are removed. +** Similarly, if the sqlite_stat2 table does not exist and the library +** is compiled with SQLITE_ENABLE_STAT2 defined, it is created. +** +** Argument zWhere may be a pointer to a buffer containing a table name, +** or it may be a NULL pointer. If it is not NULL, then all entries in +** the sqlite_stat1 and (if applicable) sqlite_stat2 tables associated +** with the named table are deleted. If zWhere==0, then code is generated +** to delete all stat table entries. */ static void openStatTable( Parse *pParse, /* Parsing context */ @@ -62965,53 +64370,64 @@ static void openStatTable( int iStatCur, /* Open the sqlite_stat1 table on this cursor */ const char *zWhere /* Delete entries associated with this table */ ){ + static struct { + const char *zName; + const char *zCols; + } aTable[] = { + { "sqlite_stat1", "tbl,idx,stat" }, +#ifdef SQLITE_ENABLE_STAT2 + { "sqlite_stat2", "tbl,idx,sampleno,sample" }, +#endif + }; + + int aRoot[] = {0, 0}; + u8 aCreateTbl[] = {0, 0}; + + int i; sqlite3 *db = pParse->db; Db *pDb; - int iRootPage; - u8 createStat1 = 0; - Table *pStat; Vdbe *v = sqlite3GetVdbe(pParse); - if( v==0 ) return; assert( sqlite3BtreeHoldsAllMutexes(db) ); assert( sqlite3VdbeDb(v)==db ); pDb = &db->aDb[iDb]; - if( (pStat = sqlite3FindTable(db, "sqlite_stat1", pDb->zName))==0 ){ - /* The sqlite_stat1 tables does not exist. Create it. - ** Note that a side-effect of the CREATE TABLE statement is to leave - ** the rootpage of the new table in register pParse->regRoot. This is - ** important because the OpenWrite opcode below will be needing it. */ - sqlite3NestedParse(pParse, - "CREATE TABLE %Q.sqlite_stat1(tbl,idx,stat)", - pDb->zName - ); - iRootPage = pParse->regRoot; - createStat1 = 1; /* Cause rootpage to be taken from top of stack */ - }else if( zWhere ){ - /* The sqlite_stat1 table exists. Delete all entries associated with - ** the table zWhere. */ - sqlite3NestedParse(pParse, - "DELETE FROM %Q.sqlite_stat1 WHERE tbl=%Q", - pDb->zName, zWhere - ); - iRootPage = pStat->tnum; - }else{ - /* The sqlite_stat1 table already exists. Delete all rows. */ - iRootPage = pStat->tnum; - sqlite3VdbeAddOp2(v, OP_Clear, pStat->tnum, iDb); + + for(i=0; izName))==0 ){ + /* The sqlite_stat[12] table does not exist. Create it. Note that a + ** side-effect of the CREATE TABLE statement is to leave the rootpage + ** of the new table in register pParse->regRoot. This is important + ** because the OpenWrite opcode below will be needing it. */ + sqlite3NestedParse(pParse, + "CREATE TABLE %Q.%s(%s)", pDb->zName, zTab, aTable[i].zCols + ); + aRoot[i] = pParse->regRoot; + aCreateTbl[i] = 1; + }else{ + /* The table already exists. If zWhere is not NULL, delete all entries + ** associated with the table zWhere. If zWhere is NULL, delete the + ** entire contents of the table. */ + aRoot[i] = pStat->tnum; + sqlite3TableLock(pParse, iDb, aRoot[i], 1, zTab); + if( zWhere ){ + sqlite3NestedParse(pParse, + "DELETE FROM %Q.%s WHERE tbl=%Q", pDb->zName, zTab, zWhere + ); + }else{ + /* The sqlite_stat[12] table already exists. Delete all rows. */ + sqlite3VdbeAddOp2(v, OP_Clear, aRoot[i], iDb); + } + } } - /* Open the sqlite_stat1 table for writing. Unless it was created - ** by this vdbe program, lock it for writing at the shared-cache level. - ** If this vdbe did create the sqlite_stat1 table, then it must have - ** already obtained a schema-lock, making the write-lock redundant. - */ - if( !createStat1 ){ - sqlite3TableLock(pParse, iDb, iRootPage, 1, "sqlite_stat1"); + /* Open the sqlite_stat[12] tables for writing. */ + for(i=0; idb; /* Database handle */ + Index *pIdx; /* An index to being analyzed */ + int iIdxCur; /* Cursor open on index being analyzed */ + Vdbe *v; /* The virtual machine being built up */ + int i; /* Loop counter */ + int topOfLoop; /* The top of the loop */ + int endOfLoop; /* The end of the loop */ + int addr; /* The address of an instruction */ + int iDb; /* Index of database containing pTab */ + int regTabname = iMem++; /* Register containing table name */ + int regIdxname = iMem++; /* Register containing index name */ + int regSampleno = iMem++; /* Register containing next sample number */ + int regCol = iMem++; /* Content of a column analyzed table */ + int regRec = iMem++; /* Register holding completed record */ + int regTemp = iMem++; /* Temporary use register */ + int regRowid = iMem++; /* Rowid for the inserted record */ + +#ifdef SQLITE_ENABLE_STAT2 + int regTemp2 = iMem++; /* Temporary use register */ + int regSamplerecno = iMem++; /* Index of next sample to record */ + int regRecno = iMem++; /* Current sample index */ + int regLast = iMem++; /* Index of last sample to record */ + int regFirst = iMem++; /* Index of first sample to record */ +#endif v = sqlite3GetVdbe(pParse); if( v==0 || NEVER(pTab==0) || pTab->pIndex==0 ){ /* Do no analysis for tables that have no indices */ return; } - assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + assert( sqlite3BtreeHoldsAllMutexes(db) ); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDb>=0 ); #ifndef SQLITE_OMIT_AUTHORIZATION if( sqlite3AuthCheck(pParse, SQLITE_ANALYZE, pTab->zName, 0, - pParse->db->aDb[iDb].zName ) ){ + db->aDb[iDb].zName ) ){ return; } #endif @@ -63054,40 +64485,66 @@ static void analyzeOneTable( iIdxCur = pParse->nTab++; for(pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext){ + int nCol = pIdx->nColumn; KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); - int regFields; /* Register block for building records */ - int regRec; /* Register holding completed record */ - int regTemp; /* Temporary use register */ - int regCol; /* Content of a column from the table being analyzed */ - int regRowid; /* Rowid for the inserted record */ - int regF2; - - /* Open a cursor to the index to be analyzed - */ - assert( iDb==sqlite3SchemaToIndex(pParse->db, pIdx->pSchema) ); - nCol = pIdx->nColumn; + + if( iMem+1+(nCol*2)>pParse->nMem ){ + pParse->nMem = iMem+1+(nCol*2); + } + + /* Open a cursor to the index to be analyzed. */ + assert( iDb==sqlite3SchemaToIndex(db, pIdx->pSchema) ); sqlite3VdbeAddOp4(v, OP_OpenRead, iIdxCur, pIdx->tnum, iDb, (char *)pKey, P4_KEYINFO_HANDOFF); VdbeComment((v, "%s", pIdx->zName)); - regFields = iMem+nCol*2; - regTemp = regRowid = regCol = regFields+3; - regRec = regCol+1; - if( regRec>pParse->nMem ){ - pParse->nMem = regRec; + + /* Populate the registers containing the table and index names. */ + if( pTab->pIndex==pIdx ){ + sqlite3VdbeAddOp4(v, OP_String8, 0, regTabname, 0, pTab->zName, 0); + } + sqlite3VdbeAddOp4(v, OP_String8, 0, regIdxname, 0, pIdx->zName, 0); + +#ifdef SQLITE_ENABLE_STAT2 + + /* If this iteration of the loop is generating code to analyze the + ** first index in the pTab->pIndex list, then register regLast has + ** not been populated. In this case populate it now. */ + if( pTab->pIndex==pIdx ){ + sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES, regSamplerecno); + sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2-1, regTemp); + sqlite3VdbeAddOp2(v, OP_Integer, SQLITE_INDEX_SAMPLES*2, regTemp2); + + sqlite3VdbeAddOp2(v, OP_Count, iIdxCur, regLast); + sqlite3VdbeAddOp2(v, OP_Null, 0, regFirst); + addr = sqlite3VdbeAddOp3(v, OP_Lt, regSamplerecno, 0, regLast); + sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regFirst); + sqlite3VdbeAddOp3(v, OP_Multiply, regLast, regTemp, regLast); + sqlite3VdbeAddOp2(v, OP_AddImm, regLast, SQLITE_INDEX_SAMPLES*2-2); + sqlite3VdbeAddOp3(v, OP_Divide, regTemp2, regLast, regLast); + sqlite3VdbeJumpHere(v, addr); } - /* Memory cells are used as follows: + /* Zero the regSampleno and regRecno registers. */ + sqlite3VdbeAddOp2(v, OP_Integer, 0, regSampleno); + sqlite3VdbeAddOp2(v, OP_Integer, 0, regRecno); + sqlite3VdbeAddOp2(v, OP_Copy, regFirst, regSamplerecno); +#endif + + /* The block of memory cells initialized here is used as follows. ** - ** mem[iMem]: The total number of rows in the table. - ** mem[iMem+1]: Number of distinct values in column 1 - ** ... - ** mem[iMem+nCol]: Number of distinct values in column N - ** mem[iMem+nCol+1] Last observed value of column 1 - ** ... - ** mem[iMem+nCol+nCol]: Last observed value of column N + ** iMem: + ** The total number of rows in the table. ** - ** Cells iMem through iMem+nCol are initialized to 0. The others - ** are initialized to NULL. + ** iMem+1 .. iMem+nCol: + ** Number of distinct entries in index considering the + ** left-most N columns only, where N is between 1 and nCol, + ** inclusive. + ** + ** iMem+nCol+1 .. Mem+2*nCol: + ** Previous value of indexed columns, from left to right. + ** + ** Cells iMem through iMem+nCol are initialized to 0. The others are + ** initialized to contain an SQL NULL. */ for(i=0; i<=nCol; i++){ sqlite3VdbeAddOp2(v, OP_Integer, 0, iMem+i); @@ -63096,29 +64553,72 @@ static void analyzeOneTable( sqlite3VdbeAddOp2(v, OP_Null, 0, iMem+nCol+i+1); } - /* Do the analysis. - */ + /* Start the analysis loop. This loop runs through all the entries in + ** the index b-tree. */ endOfLoop = sqlite3VdbeMakeLabel(v); sqlite3VdbeAddOp2(v, OP_Rewind, iIdxCur, endOfLoop); topOfLoop = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp2(v, OP_AddImm, iMem, 1); + for(i=0; imallocFailed ){ + /* If a malloc failure has occurred, then the result of the expression + ** passed as the second argument to the call to sqlite3VdbeJumpHere() + ** below may be negative. Which causes an assert() to fail (or an + ** out-of-bounds write if SQLITE_DEBUG is not defined). */ + return; + } sqlite3VdbeAddOp2(v, OP_Goto, 0, endOfLoop); for(i=0; izName, 0); - sqlite3VdbeAddOp4(v, OP_String8, 0, regFields+1, 0, pIdx->zName, 0); - regF2 = regFields+2; - sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regF2); + sqlite3VdbeAddOp2(v, OP_SCopy, iMem, regSampleno); for(i=0; inTab++; + iStatCur = pParse->nTab; + pParse->nTab += 2; openStatTable(pParse, iDb, iStatCur, 0); iMem = pParse->nMem+1; for(k=sqliteHashFirst(&pSchema->tblHash); k; k=sqliteHashNext(k)){ @@ -63202,7 +64700,8 @@ static void analyzeTable(Parse *pParse, Table *pTab){ assert( sqlite3BtreeHoldsAllMutexes(pParse->db) ); iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); sqlite3BeginWriteOperation(pParse, 0, iDb); - iStatCur = pParse->nTab++; + iStatCur = pParse->nTab; + pParse->nTab += 2; openStatTable(pParse, iDb, iStatCur, pTab->zName); analyzeOneTable(pParse, pTab, iStatCur, pParse->nMem+1); loadAnalysis(pParse, iDb); @@ -63322,7 +64821,47 @@ static int analysisLoader(void *pData, int argc, char **argv, char **NotUsed){ } /* -** Load the content of the sqlite_stat1 table into the index hash tables. +** If the Index.aSample variable is not NULL, delete the aSample[] array +** and its contents. +*/ +SQLITE_PRIVATE void sqlite3DeleteIndexSamples(Index *pIdx){ +#ifdef SQLITE_ENABLE_STAT2 + if( pIdx->aSample ){ + int j; + sqlite3 *dbMem = pIdx->pTable->dbMem; + for(j=0; jaSample[j]; + if( p->eType==SQLITE_TEXT || p->eType==SQLITE_BLOB ){ + sqlite3DbFree(pIdx->pTable->dbMem, p->u.z); + } + } + sqlite3DbFree(dbMem, pIdx->aSample); + pIdx->aSample = 0; + } +#else + UNUSED_PARAMETER(pIdx); +#endif +} + +/* +** Load the content of the sqlite_stat1 and sqlite_stat2 tables. The +** contents of sqlite_stat1 are used to populate the Index.aiRowEst[] +** arrays. The contents of sqlite_stat2 are used to populate the +** Index.aSample[] arrays. +** +** If the sqlite_stat1 table is not present in the database, SQLITE_ERROR +** is returned. In this case, even if SQLITE_ENABLE_STAT2 was defined +** during compilation and the sqlite_stat2 table is present, no data is +** read from it. +** +** If SQLITE_ENABLE_STAT2 was defined during compilation and the +** sqlite_stat2 table is not present in the database, SQLITE_ERROR is +** returned. However, in this case, data is read from the sqlite_stat1 +** table (if it is present) before returning. +** +** If an OOM error occurs, this function always sets db->mallocFailed. +** This means if the caller does not care about other errors, the return +** code may be ignored. */ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ analysisInfo sInfo; @@ -63338,19 +64877,19 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ for(i=sqliteHashFirst(&db->aDb[iDb].pSchema->idxHash);i;i=sqliteHashNext(i)){ Index *pIdx = sqliteHashData(i); sqlite3DefaultRowEst(pIdx); + sqlite3DeleteIndexSamples(pIdx); } - /* Check to make sure the sqlite_stat1 table existss */ + /* Check to make sure the sqlite_stat1 table exists */ sInfo.db = db; sInfo.zDatabase = db->aDb[iDb].zName; if( sqlite3FindTable(db, "sqlite_stat1", sInfo.zDatabase)==0 ){ - return SQLITE_ERROR; + return SQLITE_ERROR; } - /* Load new statistics out of the sqlite_stat1 table */ - zSql = sqlite3MPrintf(db, "SELECT idx, stat FROM %Q.sqlite_stat1", - sInfo.zDatabase); + zSql = sqlite3MPrintf(db, + "SELECT idx, stat FROM %Q.sqlite_stat1", sInfo.zDatabase); if( zSql==0 ){ rc = SQLITE_NOMEM; }else{ @@ -63358,7 +64897,86 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ rc = sqlite3_exec(db, zSql, analysisLoader, &sInfo, 0); (void)sqlite3SafetyOn(db); sqlite3DbFree(db, zSql); - if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; + } + + + /* Load the statistics from the sqlite_stat2 table. */ +#ifdef SQLITE_ENABLE_STAT2 + if( rc==SQLITE_OK && !sqlite3FindTable(db, "sqlite_stat2", sInfo.zDatabase) ){ + rc = SQLITE_ERROR; + } + if( rc==SQLITE_OK ){ + sqlite3_stmt *pStmt = 0; + + zSql = sqlite3MPrintf(db, + "SELECT idx,sampleno,sample FROM %Q.sqlite_stat2", sInfo.zDatabase); + if( !zSql ){ + rc = SQLITE_NOMEM; + }else{ + (void)sqlite3SafetyOff(db); + rc = sqlite3_prepare(db, zSql, -1, &pStmt, 0); + (void)sqlite3SafetyOn(db); + sqlite3DbFree(db, zSql); + } + + if( rc==SQLITE_OK ){ + (void)sqlite3SafetyOff(db); + while( sqlite3_step(pStmt)==SQLITE_ROW ){ + char *zIndex = (char *)sqlite3_column_text(pStmt, 0); + Index *pIdx = sqlite3FindIndex(db, zIndex, sInfo.zDatabase); + if( pIdx ){ + int iSample = sqlite3_column_int(pStmt, 1); + sqlite3 *dbMem = pIdx->pTable->dbMem; + assert( dbMem==db || dbMem==0 ); + if( iSample=0 ){ + int eType = sqlite3_column_type(pStmt, 2); + + if( pIdx->aSample==0 ){ + static const int sz = sizeof(IndexSample)*SQLITE_INDEX_SAMPLES; + pIdx->aSample = (IndexSample *)sqlite3DbMallocZero(dbMem, sz); + if( pIdx->aSample==0 ){ + db->mallocFailed = 1; + break; + } + } + + assert( pIdx->aSample ); + { + IndexSample *pSample = &pIdx->aSample[iSample]; + pSample->eType = (u8)eType; + if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + pSample->u.r = sqlite3_column_double(pStmt, 2); + }else if( eType==SQLITE_TEXT || eType==SQLITE_BLOB ){ + const char *z = (const char *)( + (eType==SQLITE_BLOB) ? + sqlite3_column_blob(pStmt, 2): + sqlite3_column_text(pStmt, 2) + ); + int n = sqlite3_column_bytes(pStmt, 2); + if( n>24 ){ + n = 24; + } + pSample->nByte = (u8)n; + pSample->u.z = sqlite3DbMallocRaw(dbMem, n); + if( pSample->u.z ){ + memcpy(pSample->u.z, z, n); + }else{ + db->mallocFailed = 1; + break; + } + } + } + } + } + } + rc = sqlite3_finalize(pStmt); + (void)sqlite3SafetyOn(db); + } + } +#endif + + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; } return rc; } @@ -63381,7 +64999,7 @@ SQLITE_PRIVATE int sqlite3AnalysisLoad(sqlite3 *db, int iDb){ ************************************************************************* ** This file contains code used to implement the ATTACH and DETACH commands. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef SQLITE_OMIT_ATTACH @@ -63923,7 +65541,7 @@ SQLITE_PRIVATE int sqlite3FixTriggerStep( ** systems that do not need this facility may omit it by recompiling ** the library with -DSQLITE_OMIT_AUTHORIZATION=1 ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -63999,6 +65617,39 @@ static void sqliteAuthBadReturnCode(Parse *pParse){ pParse->rc = SQLITE_ERROR; } +/* +** Invoke the authorization callback for permission to read column zCol from +** table zTab in database zDb. This function assumes that an authorization +** callback has been registered (i.e. that sqlite3.xAuth is not NULL). +** +** If SQLITE_IGNORE is returned and pExpr is not NULL, then pExpr is changed +** to an SQL NULL expression. Otherwise, if pExpr is NULL, then SQLITE_IGNORE +** is treated as SQLITE_DENY. In this case an error is left in pParse. +*/ +SQLITE_PRIVATE int sqlite3AuthReadCol( + Parse *pParse, /* The parser context */ + const char *zTab, /* Table name */ + const char *zCol, /* Column name */ + int iDb /* Index of containing database. */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + char *zDb = db->aDb[iDb].zName; /* Name of attached database */ + int rc; /* Auth callback return code */ + + rc = db->xAuth(db->pAuthArg, SQLITE_READ, zTab,zCol,zDb,pParse->zAuthContext); + if( rc==SQLITE_DENY ){ + if( db->nDb>2 || iDb!=0 ){ + sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited",zDb,zTab,zCol); + }else{ + sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited", zTab, zCol); + } + pParse->rc = SQLITE_AUTH; + }else if( rc!=SQLITE_IGNORE && rc!=SQLITE_OK ){ + sqliteAuthBadReturnCode(pParse); + } + return rc; +} + /* ** The pExpr should be a TK_COLUMN expression. The table referred to ** is in pTabList or else it is the NEW or OLD table of a trigger. @@ -64015,42 +65666,38 @@ SQLITE_PRIVATE void sqlite3AuthRead( SrcList *pTabList /* All table that pExpr might refer to */ ){ sqlite3 *db = pParse->db; - int rc; Table *pTab = 0; /* The table being read */ const char *zCol; /* Name of the column of the table */ int iSrc; /* Index in pTabList->a[] of table being read */ - const char *zDBase; /* Name of database being accessed */ - TriggerStack *pStack; /* The stack of current triggers */ int iDb; /* The index of the database the expression refers to */ + int iCol; /* Index of column in table */ if( db->xAuth==0 ) return; - assert( pExpr->op==TK_COLUMN ); iDb = sqlite3SchemaToIndex(pParse->db, pSchema); if( iDb<0 ){ /* An attempt to read a column out of a subquery or other ** temporary table. */ return; } - if( pTabList ){ - for(iSrc=0; ALWAYS(iSrcnSrc); iSrc++){ - if( pExpr->iTable==pTabList->a[iSrc].iCursor ) break; - } - assert( iSrcnSrc ); - pTab = pTabList->a[iSrc].pTab; + + assert( pExpr->op==TK_COLUMN || pExpr->op==TK_TRIGGER ); + if( pExpr->op==TK_TRIGGER ){ + pTab = pParse->pTriggerTab; }else{ - pStack = pParse->trigStack; - if( ALWAYS(pStack) ){ - /* This must be an attempt to read the NEW or OLD pseudo-tables - ** of a trigger. - */ - assert( pExpr->iTable==pStack->newIdx || pExpr->iTable==pStack->oldIdx ); - pTab = pStack->pTab; + assert( pTabList ); + for(iSrc=0; ALWAYS(iSrcnSrc); iSrc++){ + if( pExpr->iTable==pTabList->a[iSrc].iCursor ){ + pTab = pTabList->a[iSrc].pTab; + break; + } } } + iCol = pExpr->iColumn; if( NEVER(pTab==0) ) return; - if( pExpr->iColumn>=0 ){ - assert( pExpr->iColumnnCol ); - zCol = pTab->aCol[pExpr->iColumn].zName; + + if( iCol>=0 ){ + assert( iColnCol ); + zCol = pTab->aCol[iCol].zName; }else if( pTab->iPKey>=0 ){ assert( pTab->iPKeynCol ); zCol = pTab->aCol[pTab->iPKey].zName; @@ -64058,21 +65705,8 @@ SQLITE_PRIVATE void sqlite3AuthRead( zCol = "ROWID"; } assert( iDb>=0 && iDbnDb ); - zDBase = db->aDb[iDb].zName; - rc = db->xAuth(db->pAuthArg, SQLITE_READ, pTab->zName, zCol, zDBase, - pParse->zAuthContext); - if( rc==SQLITE_IGNORE ){ + if( SQLITE_IGNORE==sqlite3AuthReadCol(pParse, pTab->zName, zCol, iDb) ){ pExpr->op = TK_NULL; - }else if( rc==SQLITE_DENY ){ - if( db->nDb>2 || iDb!=0 ){ - sqlite3ErrorMsg(pParse, "access to %s.%s.%s is prohibited", - zDBase, pTab->zName, zCol); - }else{ - sqlite3ErrorMsg(pParse, "access to %s.%s is prohibited",pTab->zName,zCol); - } - pParse->rc = SQLITE_AUTH; - }else if( rc!=SQLITE_OK ){ - sqliteAuthBadReturnCode(pParse); } } @@ -64168,7 +65802,7 @@ SQLITE_PRIVATE void sqlite3AuthContextPop(AuthContext *pContext){ ** COMMIT ** ROLLBACK ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -64209,31 +65843,32 @@ SQLITE_PRIVATE void sqlite3TableLock( u8 isWriteLock, /* True for a write lock */ const char *zName /* Name of the table to be locked */ ){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); int i; int nBytes; TableLock *p; - assert( iDb>=0 ); - for(i=0; inTableLock; i++){ - p = &pParse->aTableLock[i]; + + for(i=0; inTableLock; i++){ + p = &pToplevel->aTableLock[i]; if( p->iDb==iDb && p->iTab==iTab ){ p->isWriteLock = (p->isWriteLock || isWriteLock); return; } } - nBytes = sizeof(TableLock) * (pParse->nTableLock+1); - pParse->aTableLock = - sqlite3DbReallocOrFree(pParse->db, pParse->aTableLock, nBytes); - if( pParse->aTableLock ){ - p = &pParse->aTableLock[pParse->nTableLock++]; + nBytes = sizeof(TableLock) * (pToplevel->nTableLock+1); + pToplevel->aTableLock = + sqlite3DbReallocOrFree(pToplevel->db, pToplevel->aTableLock, nBytes); + if( pToplevel->aTableLock ){ + p = &pToplevel->aTableLock[pToplevel->nTableLock++]; p->iDb = iDb; p->iTab = iTab; p->isWriteLock = isWriteLock; p->zName = zName; }else{ - pParse->nTableLock = 0; - pParse->db->mallocFailed = 1; + pToplevel->nTableLock = 0; + pToplevel->db->mallocFailed = 1; } } @@ -64282,6 +65917,8 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ ** vdbe program */ v = sqlite3GetVdbe(pParse); + assert( !pParse->isMultiWrite + || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ sqlite3VdbeAddOp0(v, OP_Halt); @@ -64307,7 +65944,7 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ { int i; for(i=0; inVtabLock; i++){ - char *vtab = (char *)pParse->apVtabLock[i]->pVtab; + char *vtab = (char *)sqlite3GetVTable(db, pParse->apVtabLock[i]); sqlite3VdbeAddOp4(v, OP_VBegin, 0, 0, 0, vtab, P4_VTAB); } pParse->nVtabLock = 0; @@ -64319,6 +65956,12 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ ** shared-cache feature is enabled. */ codeTableLocks(pParse); + + /* Initialize any AUTOINCREMENT data structures required. + */ + sqlite3AutoincrementBegin(pParse); + + /* Finally, jump back to the beginning of the executable code. */ sqlite3VdbeAddOp2(v, OP_Goto, 0, pParse->cookieGoto); } } @@ -64332,8 +65975,12 @@ SQLITE_PRIVATE void sqlite3FinishCoding(Parse *pParse){ sqlite3VdbeTrace(v, trace); #endif assert( pParse->iCacheLevel==0 ); /* Disables and re-enables match */ + /* A minimum of one cursor is required if autoincrement is used + * See ticket [a696379c1f08866] */ + if( pParse->pAinc!=0 && pParse->nTab==0 ) pParse->nTab = 1; sqlite3VdbeMakeReady(v, pParse->nVar, pParse->nMem, - pParse->nTab, pParse->explain); + pParse->nTab, pParse->nMaxArg, pParse->explain, + pParse->isMultiWrite && pParse->mayAbort); pParse->rc = SQLITE_DONE; pParse->colNamesSet = 0; }else if( pParse->rc==SQLITE_OK ){ @@ -64481,7 +66128,9 @@ SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const cha */ static void freeIndex(Index *p){ sqlite3 *db = p->pTable->dbMem; - /* testcase( db==0 ); */ +#ifndef SQLITE_OMIT_ANALYZE + sqlite3DeleteIndexSamples(p); +#endif sqlite3DbFree(db, p->zColAff); sqlite3DbFree(db, p); } @@ -64517,10 +66166,7 @@ SQLITE_PRIVATE void sqlite3UnlinkAndDeleteIndex(sqlite3 *db, int iDb, const char len = sqlite3Strlen30(zIdxName); pIndex = sqlite3HashInsert(pHash, zIdxName, len, 0); - /* Justification of ALWAYS(): This routine is only called from the - ** OP_DropIndex opcode. And there is no way that opcode will ever run - ** unless the corresponding index is in the symbol table. */ - if( ALWAYS(pIndex) ){ + if( pIndex ){ if( pIndex->pTable->pIndex==pIndex ){ pIndex->pTable->pIndex = pIndex->pNext; }else{ @@ -64566,6 +66212,7 @@ SQLITE_PRIVATE void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ } assert( iDb==0 ); db->flags &= ~SQLITE_InternChanges; + sqlite3VtabUnlockList(db); sqlite3BtreeLeaveAll(db); /* If one or more of the auxiliary database files has been closed, @@ -64574,15 +66221,6 @@ SQLITE_PRIVATE void sqlite3ResetInternalSchema(sqlite3 *db, int iDb){ ** schema hash tables and therefore do not have to make any changes ** to any of those tables. */ -#ifdef SQLITE_HAS_CODEC - for(i=0; inDb; i++){ - struct Db *pDb = &db->aDb[i]; - if( pDb->pBt==0 ){ - if( pDb->pAux && pDb->xFreeAux ) pDb->xFreeAux(pDb->pAux); - pDb->pAux = 0; - } - } -#endif for(i=j=2; inDb; i++){ struct Db *pDb = &db->aDb[i]; if( pDb->pBt==0 ){ @@ -64645,7 +66283,6 @@ static void sqliteResetColumnNames(Table *pTable){ */ SQLITE_PRIVATE void sqlite3DeleteTable(Table *pTable){ Index *pIndex, *pNext; - FKey *pFKey, *pNextFKey; sqlite3 *db; if( pTable==0 ) return; @@ -64667,13 +66304,8 @@ SQLITE_PRIVATE void sqlite3DeleteTable(Table *pTable){ sqlite3DeleteIndex(pIndex); } -#ifndef SQLITE_OMIT_FOREIGN_KEY - /* Delete all foreign keys associated with this table. */ - for(pFKey=pTable->pFKey; pFKey; pFKey=pNextFKey){ - pNextFKey = pFKey->pNextFrom; - sqlite3DbFree(db, pFKey); - } -#endif + /* Delete any foreign keys attached to this table. */ + sqlite3FkDelete(pTable); /* Delete the Table structure itself. */ @@ -65315,7 +66947,11 @@ SQLITE_PRIVATE void sqlite3AddPrimaryKey( "INTEGER PRIMARY KEY"); #endif }else{ - sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0); + Index *p; + p = sqlite3CreateIndex(pParse, 0, 0, 0, pList, onError, 0, 0, sortOrder, 0); + if( p ){ + p->autoIndex = 2; + } pList = 0; } @@ -65406,10 +67042,9 @@ SQLITE_PRIVATE CollSeq *sqlite3LocateCollSeq(Parse *pParse, const char *zName){ pColl = sqlite3FindCollSeq(db, enc, zName, initbusy); if( !initbusy && (!pColl || !pColl->xCmp) ){ - pColl = sqlite3GetCollSeq(db, pColl, zName); + pColl = sqlite3GetCollSeq(db, enc, pColl, zName); if( !pColl ){ sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); - pColl = 0; } } @@ -66027,6 +67662,7 @@ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ Vdbe *v = sqlite3GetVdbe(pParse); int r1 = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_Destroy, iTable, r1, iDb); + sqlite3MayAbort(pParse); #ifndef SQLITE_OMIT_AUTOVACUUM /* OP_Destroy stores an in integer r1. If this integer ** is non-zero, then it is the root page number of a table moved to @@ -66154,7 +67790,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, #ifndef SQLITE_OMIT_VIRTUALTABLE }else if( IsVirtual(pTab) ){ code = SQLITE_DROP_VTABLE; - zArg2 = pTab->pMod->zName; + zArg2 = sqlite3GetVTable(db, pTab)->pMod->zName; #endif }else{ if( !OMIT_TEMPDB && iDb==1 ){ @@ -66204,6 +67840,7 @@ SQLITE_PRIVATE void sqlite3DropTable(Parse *pParse, SrcList *pName, int isView, sqlite3VdbeAddOp0(v, OP_VBegin); } #endif + sqlite3FkDropTable(pParse, pName, pTab); /* Drop all triggers associated with the table being dropped. Code ** is generated to remove entries from sqlite_master and/or @@ -66294,6 +67931,7 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( sqlite3 *db = pParse->db; #ifndef SQLITE_OMIT_FOREIGN_KEY FKey *pFKey = 0; + FKey *pNextTo; Table *p = pParse->pNewTable; int nByte; int i; @@ -66368,9 +68006,21 @@ SQLITE_PRIVATE void sqlite3CreateForeignKey( } } pFKey->isDeferred = 0; - pFKey->deleteConf = (u8)(flags & 0xff); - pFKey->updateConf = (u8)((flags >> 8 ) & 0xff); - pFKey->insertConf = (u8)((flags >> 16 ) & 0xff); + pFKey->aAction[0] = (u8)(flags & 0xff); /* ON DELETE action */ + pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ + + pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, + pFKey->zTo, sqlite3Strlen30(pFKey->zTo), (void *)pFKey + ); + if( pNextTo==pFKey ){ + db->mallocFailed = 1; + goto fk_end; + } + if( pNextTo ){ + assert( pNextTo->pPrevTo==0 ); + pFKey->pNextTo = pNextTo; + pNextTo->pPrevTo = pFKey; + } /* Link the foreign key to the table as the last step. */ @@ -66396,7 +68046,7 @@ SQLITE_PRIVATE void sqlite3DeferForeignKey(Parse *pParse, int isDeferred){ Table *pTab; FKey *pFKey; if( (pTab = pParse->pNewTable)==0 || (pFKey = pTab->pFKey)==0 ) return; - assert( isDeferred==0 || isDeferred==1 ); + assert( isDeferred==0 || isDeferred==1 ); /* EV: R-30323-21917 */ pFKey->isDeferred = (u8)isDeferred; #endif } @@ -66468,8 +68118,8 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ ** since sqlite3ReleaseTempRange() was called, it is safe to do so. */ sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx, j2, regRowid, pRegKey, P4_INT32); - sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort, 0, - "indexed columns are not unique", P4_STATIC); + sqlite3HaltConstraint( + pParse, OE_Abort, "indexed columns are not unique", P4_STATIC); } sqlite3VdbeAddOp2(v, OP_IdxInsert, iIdx, regRecord); sqlite3VdbeChangeP5(v, OPFLAG_USESEEKRESULT); @@ -66491,8 +68141,12 @@ static void sqlite3RefillIndex(Parse *pParse, Index *pIndex, int memRootPage){ ** pList is a list of columns to be indexed. pList will be NULL if this ** is a primary key or unique-constraint on the most recent column added ** to the table currently under construction. +** +** If the index is created successfully, return a pointer to the new Index +** structure. This is used by sqlite3AddPrimaryKey() to mark the index +** as the tables primary key (Index.autoIndex==2). */ -SQLITE_PRIVATE void sqlite3CreateIndex( +SQLITE_PRIVATE Index *sqlite3CreateIndex( Parse *pParse, /* All information about this parse */ Token *pName1, /* First part of index name. May be NULL */ Token *pName2, /* Second part of index name. May be NULL */ @@ -66504,6 +68158,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( int sortOrder, /* Sort order of primary key when pList==NULL */ int ifNotExist /* Omit error if index already exists */ ){ + Index *pRet = 0; /* Pointer to return */ Table *pTab = 0; /* Table to be indexed */ Index *pIndex = 0; /* The index to be created */ char *zName = 0; /* Name of the index */ @@ -66939,6 +68594,7 @@ SQLITE_PRIVATE void sqlite3CreateIndex( pIndex->pNext = pOther->pNext; pOther->pNext = pIndex; } + pRet = pIndex; pIndex = 0; } @@ -66951,7 +68607,7 @@ exit_create_index: sqlite3ExprListDelete(db, pList); sqlite3SrcListDelete(db, pTblName); sqlite3DbFree(db, zName); - return; + return pRet; } /* @@ -67360,12 +69016,15 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( ){ struct SrcList_item *pItem; sqlite3 *db = pParse->db; + if( !p && (pOn || pUsing) ){ + sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", + (pOn ? "ON" : "USING") + ); + goto append_from_error; + } p = sqlite3SrcListAppend(db, p, pTable, pDatabase); if( p==0 || NEVER(p->nSrc==0) ){ - sqlite3ExprDelete(db, pOn); - sqlite3IdListDelete(db, pUsing); - sqlite3SelectDelete(db, pSubquery); - return p; + goto append_from_error; } pItem = &p->a[p->nSrc-1]; assert( pAlias!=0 ); @@ -67376,6 +69035,13 @@ SQLITE_PRIVATE SrcList *sqlite3SrcListAppendFromTerm( pItem->pOn = pOn; pItem->pUsing = pUsing; return p; + + append_from_error: + assert( p==0 ); + sqlite3ExprDelete(db, pOn); + sqlite3IdListDelete(db, pUsing); + sqlite3SelectDelete(db, pSubquery); + return 0; } /* @@ -67562,26 +69228,26 @@ SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *pParse){ ** early in the code, before we know if any database tables will be used. */ SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ - sqlite3 *db; - Vdbe *v; - int mask; + Parse *pToplevel = sqlite3ParseToplevel(pParse); - v = sqlite3GetVdbe(pParse); - if( v==0 ) return; /* This only happens if there was a prior error */ - db = pParse->db; - if( pParse->cookieGoto==0 ){ - pParse->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1; + if( pToplevel->cookieGoto==0 ){ + Vdbe *v = sqlite3GetVdbe(pToplevel); + if( v==0 ) return; /* This only happens if there was a prior error */ + pToplevel->cookieGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0)+1; } if( iDb>=0 ){ + sqlite3 *db = pToplevel->db; + int mask; + assert( iDbnDb ); assert( db->aDb[iDb].pBt!=0 || iDb==1 ); assert( iDbcookieMask & mask)==0 ){ - pParse->cookieMask |= mask; - pParse->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; + if( (pToplevel->cookieMask & mask)==0 ){ + pToplevel->cookieMask |= mask; + pToplevel->cookieValue[iDb] = db->aDb[iDb].pSchema->schema_cookie; if( !OMIT_TEMPDB && iDb==1 ){ - sqlite3OpenTempDatabase(pParse); + sqlite3OpenTempDatabase(pToplevel); } } } @@ -67601,14 +69267,56 @@ SQLITE_PRIVATE void sqlite3CodeVerifySchema(Parse *pParse, int iDb){ ** necessary to undo a write and the checkpoint should not be set. */ SQLITE_PRIVATE void sqlite3BeginWriteOperation(Parse *pParse, int setStatement, int iDb){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); sqlite3CodeVerifySchema(pParse, iDb); - pParse->writeMask |= 1<nested==0 ){ - /* Every place where this routine is called with setStatement!=0 has - ** already successfully created a VDBE. */ - assert( pParse->pVdbe ); - sqlite3VdbeAddOp1(pParse->pVdbe, OP_Statement, iDb); + pToplevel->writeMask |= 1<isMultiWrite |= setStatement; +} + +/* +** Indicate that the statement currently under construction might write +** more than one entry (example: deleting one row then inserting another, +** inserting multiple rows in a table, or inserting a row and index entries.) +** If an abort occurs after some of these writes have completed, then it will +** be necessary to undo the completed writes. +*/ +SQLITE_PRIVATE void sqlite3MultiWrite(Parse *pParse){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pToplevel->isMultiWrite = 1; +} + +/* +** The code generator calls this routine if is discovers that it is +** possible to abort a statement prior to completion. In order to +** perform this abort without corrupting the database, we need to make +** sure that the statement is protected by a statement transaction. +** +** Technically, we only need to set the mayAbort flag if the +** isMultiWrite flag was previously set. There is a time dependency +** such that the abort must occur after the multiwrite. This makes +** some statements involving the REPLACE conflict resolution algorithm +** go a little faster. But taking advantage of this time dependency +** makes it more difficult to prove that the code is correct (in +** particular, it prevents us from writing an effective +** implementation of sqlite3AssertMayAbort()) and so we have chosen +** to take the safe route and skip the optimization. +*/ +SQLITE_PRIVATE void sqlite3MayAbort(Parse *pParse){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pToplevel->mayAbort = 1; +} + +/* +** Code an OP_Halt that causes the vdbe to return an SQLITE_CONSTRAINT +** error. The onError parameter determines which (if any) of the statement +** and/or current transaction is rolled back. +*/ +SQLITE_PRIVATE void sqlite3HaltConstraint(Parse *pParse, int onError, char *p4, int p4type){ + Vdbe *v = sqlite3GetVdbe(pParse); + if( onError==OE_Abort ){ + sqlite3MayAbort(pParse); } + sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, p4, p4type); } /* @@ -67793,21 +69501,20 @@ SQLITE_PRIVATE KeyInfo *sqlite3IndexKeyinfo(Parse *pParse, Index *pIdx){ ** This file contains functions used to access the internal hash tables ** of user defined functions and collation sequences. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* ** Invoke the 'collation needed' callback to request a collation sequence -** in the database text encoding of name zName, length nName. -** If the collation sequence +** in the encoding enc of name zName, length nName. */ -static void callCollNeeded(sqlite3 *db, const char *zName){ +static void callCollNeeded(sqlite3 *db, int enc, const char *zName){ assert( !db->xCollNeeded || !db->xCollNeeded16 ); if( db->xCollNeeded ){ char *zExternal = sqlite3DbStrDup(db, zName); if( !zExternal ) return; - db->xCollNeeded(db->pCollNeededArg, db, (int)ENC(db), zExternal); + db->xCollNeeded(db->pCollNeededArg, db, enc, zExternal); sqlite3DbFree(db, zExternal); } #ifndef SQLITE_OMIT_UTF16 @@ -67850,8 +69557,7 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ /* ** This function is responsible for invoking the collation factory callback ** or substituting a collation sequence of a different encoding when the -** requested collation sequence is not available in the database native -** encoding. +** requested collation sequence is not available in the desired encoding. ** ** If it is not NULL, then pColl must point to the database native encoding ** collation sequence with name zName, length nName. @@ -67864,6 +69570,7 @@ static int synthCollSeq(sqlite3 *db, CollSeq *pColl){ */ SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq( sqlite3* db, /* The database connection */ + u8 enc, /* The desired encoding for the collating sequence */ CollSeq *pColl, /* Collating sequence with native encoding, or NULL */ const char *zName /* Collating sequence name */ ){ @@ -67871,14 +69578,14 @@ SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq( p = pColl; if( !p ){ - p = sqlite3FindCollSeq(db, ENC(db), zName, 0); + p = sqlite3FindCollSeq(db, enc, zName, 0); } if( !p || !p->xCmp ){ /* No collation sequence of this type for this encoding is registered. ** Call the collation factory to see if it can supply us with one. */ - callCollNeeded(db, zName); - p = sqlite3FindCollSeq(db, ENC(db), zName, 0); + callCollNeeded(db, enc, zName); + p = sqlite3FindCollSeq(db, enc, zName, 0); } if( p && !p->xCmp && synthCollSeq(db, p) ){ p = 0; @@ -67901,11 +69608,10 @@ SQLITE_PRIVATE CollSeq *sqlite3GetCollSeq( SQLITE_PRIVATE int sqlite3CheckCollSeq(Parse *pParse, CollSeq *pColl){ if( pColl ){ const char *zName = pColl->zName; - CollSeq *p = sqlite3GetCollSeq(pParse->db, pColl, zName); + sqlite3 *db = pParse->db; + CollSeq *p = sqlite3GetCollSeq(db, ENC(db), pColl, zName); if( !p ){ - if( pParse->nErr==0 ){ - sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); - } + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", zName); pParse->nErr++; return SQLITE_ERROR; } @@ -68120,7 +69826,6 @@ SQLITE_PRIVATE FuncDef *sqlite3FindFunction( assert( enc==SQLITE_UTF8 || enc==SQLITE_UTF16LE || enc==SQLITE_UTF16BE ); - if( nArg<-1 ) nArg = -1; h = (sqlite3UpperToLower[(u8)zName[0]] + nName) % ArraySize(db->aFunc.a); /* First search for a match amongst the application-defined functions. @@ -68205,6 +69910,7 @@ SQLITE_PRIVATE void sqlite3SchemaFree(void *p){ sqlite3DeleteTable(pTab); } sqlite3HashClear(&temp1); + sqlite3HashClear(&pSchema->fkeyHash); pSchema->pSeqTab = 0; pSchema->flags &= ~DB_SchemaLoaded; } @@ -68226,6 +69932,7 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ sqlite3HashInit(&p->tblHash); sqlite3HashInit(&p->idxHash); sqlite3HashInit(&p->trigHash); + sqlite3HashInit(&p->fkeyHash); p->enc = SQLITE_UTF8; } return p; @@ -68247,7 +69954,7 @@ SQLITE_PRIVATE Schema *sqlite3SchemaGet(sqlite3 *db, Btree *pBt){ ** This file contains C code routines that are called by the parser ** in order to generate code for DELETE FROM statements. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -68277,16 +69984,26 @@ SQLITE_PRIVATE Table *sqlite3SrcListLookup(Parse *pParse, SrcList *pSrc){ ** writable return 0; */ SQLITE_PRIVATE int sqlite3IsReadOnly(Parse *pParse, Table *pTab, int viewOk){ - if( ((pTab->tabFlags & TF_Readonly)!=0 - && (pParse->db->flags & SQLITE_WriteSchema)==0 - && pParse->nested==0) -#ifndef SQLITE_OMIT_VIRTUALTABLE - || (pTab->pMod && pTab->pMod->pModule->xUpdate==0) -#endif + /* A table is not writable under the following circumstances: + ** + ** 1) It is a virtual table and no implementation of the xUpdate method + ** has been provided, or + ** 2) It is a system table (i.e. sqlite_master), this call is not + ** part of a nested parse and writable_schema pragma has not + ** been specified. + ** + ** In either case leave an error message in pParse and return non-zero. + */ + if( ( IsVirtual(pTab) + && sqlite3GetVTable(pParse->db, pTab)->pMod->pModule->xUpdate==0 ) + || ( (pTab->tabFlags & TF_Readonly)!=0 + && (pParse->db->flags & SQLITE_WriteSchema)==0 + && pParse->nested==0 ) ){ sqlite3ErrorMsg(pParse, "table %s may not be modified", pTab->zName); return 1; } + #ifndef SQLITE_OMIT_VIEW if( !viewOk && pTab->pSelect ){ sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); @@ -68452,7 +70169,6 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( int iCur; /* VDBE Cursor number for pTab */ sqlite3 *db; /* Main database structure */ AuthContext sContext; /* Authorization context */ - int oldIdx = -1; /* Cursor for the OLD table of AFTER triggers */ NameContext sNC; /* Name context to resolve expressions in */ int iDb; /* Database number */ int memCnt = -1; /* Memory cell used for change counting */ @@ -68462,13 +70178,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( int isView; /* True if attempting to delete from a view */ Trigger *pTrigger; /* List of table triggers, if required */ #endif - int iBeginAfterTrigger = 0; /* Address of after trigger program */ - int iEndAfterTrigger = 0; /* Exit of after trigger program */ - int iBeginBeforeTrigger = 0; /* Address of before trigger program */ - int iEndBeforeTrigger = 0; /* Exit of before trigger program */ - u32 old_col_mask = 0; /* Mask of OLD.* columns in use */ - sContext.pParse = 0; + memset(&sContext, 0, sizeof(sContext)); db = pParse->db; if( pParse->nErr || db->mallocFailed ){ goto delete_from_cleanup; @@ -68498,6 +70209,12 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( # define isView 0 #endif + /* If pTab is really a view, make sure it has been initialized. + */ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + goto delete_from_cleanup; + } + if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){ goto delete_from_cleanup; } @@ -68511,18 +70228,6 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( } assert(!isView || pTrigger); - /* If pTab is really a view, make sure it has been initialized. - */ - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ - goto delete_from_cleanup; - } - - /* Allocate a cursor used to store the old.* data for a trigger. - */ - if( pTrigger ){ - oldIdx = pParse->nTab++; - } - /* Assign cursor number to the table and all its indices. */ assert( pTabList->nSrc==1 ); @@ -68544,25 +70249,7 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( goto delete_from_cleanup; } if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); - sqlite3BeginWriteOperation(pParse, (pTrigger?1:0), iDb); - - if( pTrigger ){ - int orconf = ((pParse->trigStack)?pParse->trigStack->orconf:OE_Default); - int iGoto = sqlite3VdbeAddOp0(v, OP_Goto); - addr = sqlite3VdbeMakeLabel(v); - - iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v); - (void)sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0, - TRIGGER_BEFORE, pTab, -1, oldIdx, orconf, addr, &old_col_mask, 0); - iEndBeforeTrigger = sqlite3VdbeAddOp0(v, OP_Goto); - - iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v); - (void)sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0, - TRIGGER_AFTER, pTab, -1, oldIdx, orconf, addr, &old_col_mask, 0); - iEndAfterTrigger = sqlite3VdbeAddOp0(v, OP_Goto); - - sqlite3VdbeJumpHere(v, iGoto); - } + sqlite3BeginWriteOperation(pParse, 1, iDb); /* If we are trying to delete from a view, realize that view into ** a ephemeral table. @@ -68592,10 +70279,12 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( #ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION /* Special case: A DELETE without a WHERE clause deletes everything. - ** It is easier just to erase the whole table. Note, however, that - ** this means that the row change count will be incorrect. - */ - if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) ){ + ** It is easier just to erase the whole table. Prior to version 3.6.5, + ** this optimization caused the row change count (the value returned by + ** API function sqlite3_count_changes) to be set incorrectly. */ + if( rcauth==SQLITE_OK && pWhere==0 && !pTrigger && !IsVirtual(pTab) + && 0==sqlite3FkRequired(pParse, pTab, 0, 0) + ){ assert( !isView ); sqlite3VdbeAddOp4(v, OP_Clear, pTab->tnum, iDb, memCnt, pTab->zName, P4_STATIC); @@ -68609,8 +70298,8 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( ** the table and pick which records to delete. */ { - int iRowid = ++pParse->nMem; /* Used for storing rowid values. */ int iRowSet = ++pParse->nMem; /* Register for rowset of rows to delete */ + int iRowid = ++pParse->nMem; /* Used for storing rowid values. */ int regRowid; /* Actual register containing rowids */ /* Collect rowids of every row to be deleted. @@ -68625,83 +70314,41 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( } sqlite3WhereEnd(pWInfo); - /* Open the pseudo-table used to store OLD if there are triggers. - */ - if( pTrigger ){ - sqlite3VdbeAddOp3(v, OP_OpenPseudo, oldIdx, 0, pTab->nCol); - } - /* Delete every item whose key was written to the list during the ** database scan. We have to delete items after the scan is complete - ** because deleting an item can change the scan order. - */ + ** because deleting an item can change the scan order. */ end = sqlite3VdbeMakeLabel(v); + /* Unless this is a view, open cursors for the table we are + ** deleting from and all its indices. If this is a view, then the + ** only effect this statement has is to fire the INSTEAD OF + ** triggers. */ if( !isView ){ - /* Open cursors for the table we are deleting from and - ** all its indices. - */ sqlite3OpenTableAndIndices(pParse, pTab, iCur, OP_OpenWrite); } - /* This is the beginning of the delete loop. If a trigger encounters - ** an IGNORE constraint, it jumps back to here. - */ - if( pTrigger ){ - sqlite3VdbeResolveLabel(v, addr); - } addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, end, iRowid); - if( pTrigger ){ - int iData = ++pParse->nMem; /* For storing row data of OLD table */ - - /* If the record is no longer present in the table, jump to the - ** next iteration of the loop through the contents of the fifo. - */ - sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, iRowid); - - /* Populate the OLD.* pseudo-table */ - if( old_col_mask ){ - sqlite3VdbeAddOp2(v, OP_RowData, iCur, iData); - }else{ - sqlite3VdbeAddOp2(v, OP_Null, 0, iData); - } - sqlite3VdbeAddOp3(v, OP_Insert, oldIdx, iData, iRowid); - - /* Jump back and run the BEFORE triggers */ - sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger); - sqlite3VdbeJumpHere(v, iEndBeforeTrigger); - } - - if( !isView ){ - /* Delete the row */ + /* Delete the row */ #ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTab) ){ - const char *pVtab = (const char *)pTab->pVtab; - sqlite3VtabMakeWritable(pParse, pTab); - sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVtab, P4_VTAB); - }else + if( IsVirtual(pTab) ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); + sqlite3VtabMakeWritable(pParse, pTab); + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, 1, iRowid, pVTab, P4_VTAB); + sqlite3MayAbort(pParse); + }else #endif - { - sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, pParse->nested==0); - } - } - - /* If there are row triggers, close all cursors then invoke - ** the AFTER triggers - */ - if( pTrigger ){ - /* Jump back and run the AFTER triggers */ - sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginAfterTrigger); - sqlite3VdbeJumpHere(v, iEndAfterTrigger); + { + int count = (pParse->nested==0); /* True to count changes */ + sqlite3GenerateRowDelete(pParse, pTab, iCur, iRowid, count, pTrigger, OE_Default); } /* End of the delete loop */ sqlite3VdbeAddOp2(v, OP_Goto, 0, addr); sqlite3VdbeResolveLabel(v, end); - /* Close the cursors after the loop if there are no row triggers */ - if( !isView && !IsVirtual(pTab) ){ + /* Close the cursors open on the table and its indexes. */ + if( !isView && !IsVirtual(pTab) ){ for(i=1, pIdx=pTab->pIndex; pIdx; i++, pIdx=pIdx->pNext){ sqlite3VdbeAddOp2(v, OP_Close, iCur + i, pIdx->tnum); } @@ -68709,12 +70356,19 @@ SQLITE_PRIVATE void sqlite3DeleteFrom( } } - /* - ** Return the number of rows that were deleted. If this routine is + /* Update the sqlite_sequence table by storing the content of the + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. + */ + if( pParse->nested==0 && pParse->pTriggerTab==0 ){ + sqlite3AutoincrementEnd(pParse); + } + + /* Return the number of rows that were deleted. If this routine is ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ - if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){ + if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){ sqlite3VdbeAddOp2(v, OP_ResultRow, memCnt, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows deleted", SQLITE_STATIC); @@ -68726,6 +70380,15 @@ delete_from_cleanup: sqlite3ExprDelete(db, pWhere); return; } +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** thely may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif /* ** This routine generates VDBE code that causes a single row of a @@ -68735,7 +70398,7 @@ delete_from_cleanup: ** These are the requirements: ** ** 1. A read/write cursor pointing to pTab, the table containing the row -** to be deleted, must be opened as cursor number "base". +** to be deleted, must be opened as cursor number $iCur. ** ** 2. Read/write cursors for all indices of pTab must be open as ** cursor number base+i for the i-th index. @@ -68743,28 +70406,97 @@ delete_from_cleanup: ** 3. The record number of the row to be deleted must be stored in ** memory cell iRowid. ** -** This routine pops the top of the stack to remove the record number -** and then generates code to remove both the table record and all index -** entries that point to that record. +** This routine generates code to remove both the table record and all +** index entries that point to that record. */ SQLITE_PRIVATE void sqlite3GenerateRowDelete( Parse *pParse, /* Parsing context */ Table *pTab, /* Table containing the row to be deleted */ int iCur, /* Cursor number for the table */ int iRowid, /* Memory cell that contains the rowid to delete */ - int count /* Increment the row change counter */ + int count, /* If non-zero, increment the row change counter */ + Trigger *pTrigger, /* List of triggers to (potentially) fire */ + int onconf /* Default ON CONFLICT policy for triggers */ ){ - int addr; - Vdbe *v; + Vdbe *v = pParse->pVdbe; /* Vdbe */ + int iOld = 0; /* First register in OLD.* array */ + int iLabel; /* Label resolved to end of generated code */ - v = pParse->pVdbe; - addr = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, iRowid); - sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0); - sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0)); - if( count ){ - sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); + /* Vdbe is guaranteed to have been allocated by this stage. */ + assert( v ); + + /* Seek cursor iCur to the row to delete. If this row no longer exists + ** (this can happen if a trigger program has already deleted it), do + ** not attempt to delete it or fire any DELETE triggers. */ + iLabel = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, iLabel, iRowid); + + /* If there are any triggers to fire, allocate a range of registers to + ** use for the old.* references in the triggers. */ + if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ + u32 mask; /* Mask of OLD.* columns in use */ + int iCol; /* Iterator used while populating OLD.* */ + + /* TODO: Could use temporary registers here. Also could attempt to + ** avoid copying the contents of the rowid register. */ + mask = sqlite3TriggerOldmask(pParse, pTrigger, 0, pTab, onconf); + mask |= sqlite3FkOldmask(pParse, pTab); + iOld = pParse->nMem+1; + pParse->nMem += (1 + pTab->nCol); + + /* Populate the OLD.* pseudo-table register array. These values will be + ** used by any BEFORE and AFTER triggers that exist. */ + sqlite3VdbeAddOp2(v, OP_Copy, iRowid, iOld); + for(iCol=0; iColnCol; iCol++){ + if( mask==0xffffffff || mask&(1<pSelect==0 ){ + sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, 0); + sqlite3VdbeAddOp2(v, OP_Delete, iCur, (count?OPFLAG_NCHANGE:0)); + if( count ){ + sqlite3VdbeChangeP4(v, -1, pTab->zName, P4_STATIC); + } + } + + /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to + ** handle rows (possibly in other tables) that refer via a foreign key + ** to the row just deleted. */ + sqlite3FkActions(pParse, pTab, 0, iOld); + + /* Invoke AFTER DELETE trigger programs. */ + sqlite3CodeRowTrigger(pParse, pTrigger, + TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel + ); + + /* Jump here if the row had already been deleted before any BEFORE + ** trigger programs were invoked. Or if a trigger program throws a + ** RAISE(IGNORE) exception. */ + sqlite3VdbeResolveLabel(v, iLabel); } /* @@ -68833,22 +70565,18 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey( sqlite3VdbeAddOp2(v, OP_SCopy, regBase+nCol, regBase+j); }else{ sqlite3VdbeAddOp3(v, OP_Column, iCur, idx, regBase+j); - sqlite3ColumnDefault(v, pTab, idx); + sqlite3ColumnDefault(v, pTab, idx, -1); } } if( doMakeRec ){ sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol+1, regOut); - sqlite3IndexAffinityStr(v, pIdx); + sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0); sqlite3ExprCacheAffinityChange(pParse, regBase, nCol+1); } sqlite3ReleaseTempRange(pParse, regBase, nCol+1); return regBase; } -/* Make sure "isView" gets undefined in case this file becomes part of -** the amalgamation - so that subsequent files do not see isView as a -** macro. */ -#undef isView /************** End of delete.c **********************************************/ /************** Begin file func.c ********************************************/ @@ -68869,8 +70597,6 @@ SQLITE_PRIVATE int sqlite3GenerateIndexKey( ** There is only one exported symbol in this file - the function ** sqliteRegisterBuildinFunctions() found at the bottom of the file. ** All other code has file scope. -** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ */ /* @@ -69552,7 +71278,7 @@ static void nullifFunc( } /* -** Implementation of the VERSION(*) function. The result is the version +** Implementation of the sqlite_version() function. The result is the version ** of the SQLite library that is running. */ static void versionFunc( @@ -69564,6 +71290,20 @@ static void versionFunc( sqlite3_result_text(context, sqlite3_version, -1, SQLITE_STATIC); } +/* +** Implementation of the sqlite_source_id() function. The result is a string +** that identifies the particular version of the source code used to build +** SQLite. +*/ +static void sourceidFunc( + sqlite3_context *context, + int NotUsed, + sqlite3_value **NotUsed2 +){ + UNUSED_PARAMETER2(NotUsed, NotUsed2); + sqlite3_result_text(context, SQLITE_SOURCE_ID, -1, SQLITE_STATIC); +} + /* Array for converting from half-bytes (nybbles) into ASCII hex ** digits. */ static const char hexdigits[] = { @@ -70115,15 +71855,10 @@ static void groupConcatStep( if( pAccum ){ sqlite3 *db = sqlite3_context_db_handle(context); - int n; + int firstTerm = pAccum->useMalloc==0; pAccum->useMalloc = 1; pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH]; -#ifdef SQLITE_OMIT_DEPRECATED - n = context->pMem->n; -#else - n = sqlite3_aggregate_count(context); -#endif - if( n>1 ){ + if( !firstTerm ){ if( argc==2 ){ zSep = (char*)sqlite3_value_text(argv[1]); nSep = sqlite3_value_bytes(argv[1]); @@ -70169,9 +71904,6 @@ SQLITE_PRIVATE void sqlite3RegisterBuiltinFunctions(sqlite3 *db){ db->mallocFailed = 1; } } -#ifdef SQLITE_SSE - (void)sqlite3SseFunctions(db); -#endif } /* @@ -70291,6 +72023,7 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ FUNCTION(randomblob, 1, 0, 0, randomBlob ), FUNCTION(nullif, 2, 0, 1, nullifFunc ), FUNCTION(sqlite_version, 0, 0, 0, versionFunc ), + FUNCTION(sqlite_source_id, 0, 0, 0, sourceidFunc ), FUNCTION(quote, 1, 0, 0, quoteFunc ), FUNCTION(last_insert_rowid, 0, 0, 0, last_insert_rowid), FUNCTION(changes, 0, 0, 0, changes ), @@ -70334,6 +72067,1199 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ } /************** End of func.c ************************************************/ +/************** Begin file fkey.c ********************************************/ +/* +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains code used by the compiler to add foreign key +** support to compiled SQL statements. +*/ + +#ifndef SQLITE_OMIT_FOREIGN_KEY +#ifndef SQLITE_OMIT_TRIGGER + +/* +** Deferred and Immediate FKs +** -------------------------- +** +** Foreign keys in SQLite come in two flavours: deferred and immediate. +** If an immediate foreign key constraint is violated, SQLITE_CONSTRAINT +** is returned and the current statement transaction rolled back. If a +** deferred foreign key constraint is violated, no action is taken +** immediately. However if the application attempts to commit the +** transaction before fixing the constraint violation, the attempt fails. +** +** Deferred constraints are implemented using a simple counter associated +** with the database handle. The counter is set to zero each time a +** database transaction is opened. Each time a statement is executed +** that causes a foreign key violation, the counter is incremented. Each +** time a statement is executed that removes an existing violation from +** the database, the counter is decremented. When the transaction is +** committed, the commit fails if the current value of the counter is +** greater than zero. This scheme has two big drawbacks: +** +** * When a commit fails due to a deferred foreign key constraint, +** there is no way to tell which foreign constraint is not satisfied, +** or which row it is not satisfied for. +** +** * If the database contains foreign key violations when the +** transaction is opened, this may cause the mechanism to malfunction. +** +** Despite these problems, this approach is adopted as it seems simpler +** than the alternatives. +** +** INSERT operations: +** +** I.1) For each FK for which the table is the child table, search +** the parent table for a match. If none is found increment the +** constraint counter. +** +** I.2) For each FK for which the table is the parent table, +** search the child table for rows that correspond to the new +** row in the parent table. Decrement the counter for each row +** found (as the constraint is now satisfied). +** +** DELETE operations: +** +** D.1) For each FK for which the table is the child table, +** search the parent table for a row that corresponds to the +** deleted row in the child table. If such a row is not found, +** decrement the counter. +** +** D.2) For each FK for which the table is the parent table, search +** the child table for rows that correspond to the deleted row +** in the parent table. For each found increment the counter. +** +** UPDATE operations: +** +** An UPDATE command requires that all 4 steps above are taken, but only +** for FK constraints for which the affected columns are actually +** modified (values must be compared at runtime). +** +** Note that I.1 and D.1 are very similar operations, as are I.2 and D.2. +** This simplifies the implementation a bit. +** +** For the purposes of immediate FK constraints, the OR REPLACE conflict +** resolution is considered to delete rows before the new row is inserted. +** If a delete caused by OR REPLACE violates an FK constraint, an exception +** is thrown, even if the FK constraint would be satisfied after the new +** row is inserted. +** +** Immediate constraints are usually handled similarly. The only difference +** is that the counter used is stored as part of each individual statement +** object (struct Vdbe). If, after the statement has run, its immediate +** constraint counter is greater than zero, it returns SQLITE_CONSTRAINT +** and the statement transaction is rolled back. An exception is an INSERT +** statement that inserts a single row only (no triggers). In this case, +** instead of using a counter, an exception is thrown immediately if the +** INSERT violates a foreign key constraint. This is necessary as such +** an INSERT does not open a statement transaction. +** +** TODO: How should dropping a table be handled? How should renaming a +** table be handled? +** +** +** Query API Notes +** --------------- +** +** Before coding an UPDATE or DELETE row operation, the code-generator +** for those two operations needs to know whether or not the operation +** requires any FK processing and, if so, which columns of the original +** row are required by the FK processing VDBE code (i.e. if FKs were +** implemented using triggers, which of the old.* columns would be +** accessed). No information is required by the code-generator before +** coding an INSERT operation. The functions used by the UPDATE/DELETE +** generation code to query for this information are: +** +** sqlite3FkRequired() - Test to see if FK processing is required. +** sqlite3FkOldmask() - Query for the set of required old.* columns. +** +** +** Externally accessible module functions +** -------------------------------------- +** +** sqlite3FkCheck() - Check for foreign key violations. +** sqlite3FkActions() - Code triggers for ON UPDATE/ON DELETE actions. +** sqlite3FkDelete() - Delete an FKey structure. +*/ + +/* +** VDBE Calling Convention +** ----------------------- +** +** Example: +** +** For the following INSERT statement: +** +** CREATE TABLE t1(a, b INTEGER PRIMARY KEY, c); +** INSERT INTO t1 VALUES(1, 2, 3.1); +** +** Register (x): 2 (type integer) +** Register (x+1): 1 (type integer) +** Register (x+2): NULL (type NULL) +** Register (x+3): 3.1 (type real) +*/ + +/* +** A foreign key constraint requires that the key columns in the parent +** table are collectively subject to a UNIQUE or PRIMARY KEY constraint. +** Given that pParent is the parent table for foreign key constraint pFKey, +** search the schema a unique index on the parent key columns. +** +** If successful, zero is returned. If the parent key is an INTEGER PRIMARY +** KEY column, then output variable *ppIdx is set to NULL. Otherwise, *ppIdx +** is set to point to the unique index. +** +** If the parent key consists of a single column (the foreign key constraint +** is not a composite foreign key), output variable *paiCol is set to NULL. +** Otherwise, it is set to point to an allocated array of size N, where +** N is the number of columns in the parent key. The first element of the +** array is the index of the child table column that is mapped by the FK +** constraint to the parent table column stored in the left-most column +** of index *ppIdx. The second element of the array is the index of the +** child table column that corresponds to the second left-most column of +** *ppIdx, and so on. +** +** If the required index cannot be found, either because: +** +** 1) The named parent key columns do not exist, or +** +** 2) The named parent key columns do exist, but are not subject to a +** UNIQUE or PRIMARY KEY constraint, or +** +** 3) No parent key columns were provided explicitly as part of the +** foreign key definition, and the parent table does not have a +** PRIMARY KEY, or +** +** 4) No parent key columns were provided explicitly as part of the +** foreign key definition, and the PRIMARY KEY of the parent table +** consists of a a different number of columns to the child key in +** the child table. +** +** then non-zero is returned, and a "foreign key mismatch" error loaded +** into pParse. If an OOM error occurs, non-zero is returned and the +** pParse->db->mallocFailed flag is set. +*/ +static int locateFkeyIndex( + Parse *pParse, /* Parse context to store any error in */ + Table *pParent, /* Parent table of FK constraint pFKey */ + FKey *pFKey, /* Foreign key to find index for */ + Index **ppIdx, /* OUT: Unique index on parent table */ + int **paiCol /* OUT: Map of index columns in pFKey */ +){ + Index *pIdx = 0; /* Value to return via *ppIdx */ + int *aiCol = 0; /* Value to return via *paiCol */ + int nCol = pFKey->nCol; /* Number of columns in parent key */ + char *zKey = pFKey->aCol[0].zCol; /* Name of left-most parent key column */ + + /* The caller is responsible for zeroing output parameters. */ + assert( ppIdx && *ppIdx==0 ); + assert( !paiCol || *paiCol==0 ); + assert( pParse ); + + /* If this is a non-composite (single column) foreign key, check if it + ** maps to the INTEGER PRIMARY KEY of table pParent. If so, leave *ppIdx + ** and *paiCol set to zero and return early. + ** + ** Otherwise, for a composite foreign key (more than one column), allocate + ** space for the aiCol array (returned via output parameter *paiCol). + ** Non-composite foreign keys do not require the aiCol array. + */ + if( nCol==1 ){ + /* The FK maps to the IPK if any of the following are true: + ** + ** 1) There is an INTEGER PRIMARY KEY column and the FK is implicitly + ** mapped to the primary key of table pParent, or + ** 2) The FK is explicitly mapped to a column declared as INTEGER + ** PRIMARY KEY. + */ + if( pParent->iPKey>=0 ){ + if( !zKey ) return 0; + if( !sqlite3StrICmp(pParent->aCol[pParent->iPKey].zName, zKey) ) return 0; + } + }else if( paiCol ){ + assert( nCol>1 ); + aiCol = (int *)sqlite3DbMallocRaw(pParse->db, nCol*sizeof(int)); + if( !aiCol ) return 1; + *paiCol = aiCol; + } + + for(pIdx=pParent->pIndex; pIdx; pIdx=pIdx->pNext){ + if( pIdx->nColumn==nCol && pIdx->onError!=OE_None ){ + /* pIdx is a UNIQUE index (or a PRIMARY KEY) and has the right number + ** of columns. If each indexed column corresponds to a foreign key + ** column of pFKey, then this index is a winner. */ + + if( zKey==0 ){ + /* If zKey is NULL, then this foreign key is implicitly mapped to + ** the PRIMARY KEY of table pParent. The PRIMARY KEY index may be + ** identified by the test (Index.autoIndex==2). */ + if( pIdx->autoIndex==2 ){ + if( aiCol ){ + int i; + for(i=0; iaCol[i].iFrom; + } + break; + } + }else{ + /* If zKey is non-NULL, then this foreign key was declared to + ** map to an explicit list of columns in table pParent. Check if this + ** index matches those columns. Also, check that the index uses + ** the default collation sequences for each column. */ + int i, j; + for(i=0; iaiColumn[i]; /* Index of column in parent tbl */ + char *zDfltColl; /* Def. collation for column */ + char *zIdxCol; /* Name of indexed column */ + + /* If the index uses a collation sequence that is different from + ** the default collation sequence for the column, this index is + ** unusable. Bail out early in this case. */ + zDfltColl = pParent->aCol[iCol].zColl; + if( !zDfltColl ){ + zDfltColl = "BINARY"; + } + if( sqlite3StrICmp(pIdx->azColl[i], zDfltColl) ) break; + + zIdxCol = pParent->aCol[iCol].zName; + for(j=0; jaCol[j].zCol, zIdxCol)==0 ){ + if( aiCol ) aiCol[i] = pFKey->aCol[j].iFrom; + break; + } + } + if( j==nCol ) break; + } + if( i==nCol ) break; /* pIdx is usable */ + } + } + } + + if( !pIdx ){ + if( !pParse->disableTriggers ){ + sqlite3ErrorMsg(pParse, "foreign key mismatch"); + } + sqlite3DbFree(pParse->db, aiCol); + return 1; + } + + *ppIdx = pIdx; + return 0; +} + +/* +** This function is called when a row is inserted into or deleted from the +** child table of foreign key constraint pFKey. If an SQL UPDATE is executed +** on the child table of pFKey, this function is invoked twice for each row +** affected - once to "delete" the old row, and then again to "insert" the +** new row. +** +** Each time it is called, this function generates VDBE code to locate the +** row in the parent table that corresponds to the row being inserted into +** or deleted from the child table. If the parent row can be found, no +** special action is taken. Otherwise, if the parent row can *not* be +** found in the parent table: +** +** Operation | FK type | Action taken +** -------------------------------------------------------------------------- +** INSERT immediate Increment the "immediate constraint counter". +** +** DELETE immediate Decrement the "immediate constraint counter". +** +** INSERT deferred Increment the "deferred constraint counter". +** +** DELETE deferred Decrement the "deferred constraint counter". +** +** These operations are identified in the comment at the top of this file +** (fkey.c) as "I.1" and "D.1". +*/ +static void fkLookupParent( + Parse *pParse, /* Parse context */ + int iDb, /* Index of database housing pTab */ + Table *pTab, /* Parent table of FK pFKey */ + Index *pIdx, /* Unique index on parent key columns in pTab */ + FKey *pFKey, /* Foreign key constraint */ + int *aiCol, /* Map from parent key columns to child table columns */ + int regData, /* Address of array containing child table row */ + int nIncr, /* Increment constraint counter by this */ + int isIgnore /* If true, pretend pTab contains all NULL values */ +){ + int i; /* Iterator variable */ + Vdbe *v = sqlite3GetVdbe(pParse); /* Vdbe to add code to */ + int iCur = pParse->nTab - 1; /* Cursor number to use */ + int iOk = sqlite3VdbeMakeLabel(v); /* jump here if parent key found */ + + /* If nIncr is less than zero, then check at runtime if there are any + ** outstanding constraints to resolve. If there are not, there is no need + ** to check if deleting this row resolves any outstanding violations. + ** + ** Check if any of the key columns in the child table row are NULL. If + ** any are, then the constraint is considered satisfied. No need to + ** search for a matching row in the parent table. */ + if( nIncr<0 ){ + sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, iOk); + } + for(i=0; inCol; i++){ + int iReg = aiCol[i] + regData + 1; + sqlite3VdbeAddOp2(v, OP_IsNull, iReg, iOk); + } + + if( isIgnore==0 ){ + if( pIdx==0 ){ + /* If pIdx is NULL, then the parent key is the INTEGER PRIMARY KEY + ** column of the parent table (table pTab). */ + int iMustBeInt; /* Address of MustBeInt instruction */ + int regTemp = sqlite3GetTempReg(pParse); + + /* Invoke MustBeInt to coerce the child key value to an integer (i.e. + ** apply the affinity of the parent key). If this fails, then there + ** is no matching parent key. Before using MustBeInt, make a copy of + ** the value. Otherwise, the value inserted into the child key column + ** will have INTEGER affinity applied to it, which may not be correct. */ + sqlite3VdbeAddOp2(v, OP_SCopy, aiCol[0]+1+regData, regTemp); + iMustBeInt = sqlite3VdbeAddOp2(v, OP_MustBeInt, regTemp, 0); + + /* If the parent table is the same as the child table, and we are about + ** to increment the constraint-counter (i.e. this is an INSERT operation), + ** then check if the row being inserted matches itself. If so, do not + ** increment the constraint-counter. */ + if( pTab==pFKey->pFrom && nIncr==1 ){ + sqlite3VdbeAddOp3(v, OP_Eq, regData, iOk, regTemp); + } + + sqlite3OpenTable(pParse, iCur, iDb, pTab, OP_OpenRead); + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regTemp); + sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); + sqlite3VdbeJumpHere(v, sqlite3VdbeCurrentAddr(v)-2); + sqlite3VdbeJumpHere(v, iMustBeInt); + sqlite3ReleaseTempReg(pParse, regTemp); + }else{ + int nCol = pFKey->nCol; + int regTemp = sqlite3GetTempRange(pParse, nCol); + int regRec = sqlite3GetTempReg(pParse); + KeyInfo *pKey = sqlite3IndexKeyinfo(pParse, pIdx); + + sqlite3VdbeAddOp3(v, OP_OpenRead, iCur, pIdx->tnum, iDb); + sqlite3VdbeChangeP4(v, -1, (char*)pKey, P4_KEYINFO_HANDOFF); + for(i=0; ipFrom && nIncr==1 ){ + int iJump = sqlite3VdbeCurrentAddr(v) + nCol + 1; + for(i=0; iaiColumn[i]+1+regData; + sqlite3VdbeAddOp3(v, OP_Ne, iChild, iJump, iParent); + } + sqlite3VdbeAddOp2(v, OP_Goto, 0, iOk); + } + + sqlite3VdbeAddOp3(v, OP_MakeRecord, regTemp, nCol, regRec); + sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0); + sqlite3VdbeAddOp3(v, OP_Found, iCur, iOk, regRec); + + sqlite3ReleaseTempReg(pParse, regRec); + sqlite3ReleaseTempRange(pParse, regTemp, nCol); + } + } + + if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){ + /* Special case: If this is an INSERT statement that will insert exactly + ** one row into the table, raise a constraint immediately instead of + ** incrementing a counter. This is necessary as the VM code is being + ** generated for will not open a statement transaction. */ + assert( nIncr==1 ); + sqlite3HaltConstraint( + pParse, OE_Abort, "foreign key constraint failed", P4_STATIC + ); + }else{ + if( nIncr>0 && pFKey->isDeferred==0 ){ + sqlite3ParseToplevel(pParse)->mayAbort = 1; + } + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); + } + + sqlite3VdbeResolveLabel(v, iOk); + sqlite3VdbeAddOp1(v, OP_Close, iCur); +} + +/* +** This function is called to generate code executed when a row is deleted +** from the parent table of foreign key constraint pFKey and, if pFKey is +** deferred, when a row is inserted into the same table. When generating +** code for an SQL UPDATE operation, this function may be called twice - +** once to "delete" the old row and once to "insert" the new row. +** +** The code generated by this function scans through the rows in the child +** table that correspond to the parent table row being deleted or inserted. +** For each child row found, one of the following actions is taken: +** +** Operation | FK type | Action taken +** -------------------------------------------------------------------------- +** DELETE immediate Increment the "immediate constraint counter". +** Or, if the ON (UPDATE|DELETE) action is RESTRICT, +** throw a "foreign key constraint failed" exception. +** +** INSERT immediate Decrement the "immediate constraint counter". +** +** DELETE deferred Increment the "deferred constraint counter". +** Or, if the ON (UPDATE|DELETE) action is RESTRICT, +** throw a "foreign key constraint failed" exception. +** +** INSERT deferred Decrement the "deferred constraint counter". +** +** These operations are identified in the comment at the top of this file +** (fkey.c) as "I.2" and "D.2". +*/ +static void fkScanChildren( + Parse *pParse, /* Parse context */ + SrcList *pSrc, /* SrcList containing the table to scan */ + Table *pTab, + Index *pIdx, /* Foreign key index */ + FKey *pFKey, /* Foreign key relationship */ + int *aiCol, /* Map from pIdx cols to child table cols */ + int regData, /* Referenced table data starts here */ + int nIncr /* Amount to increment deferred counter by */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + int i; /* Iterator variable */ + Expr *pWhere = 0; /* WHERE clause to scan with */ + NameContext sNameContext; /* Context used to resolve WHERE clause */ + WhereInfo *pWInfo; /* Context used by sqlite3WhereXXX() */ + int iFkIfZero = 0; /* Address of OP_FkIfZero */ + Vdbe *v = sqlite3GetVdbe(pParse); + + assert( !pIdx || pIdx->pTable==pTab ); + + if( nIncr<0 ){ + iFkIfZero = sqlite3VdbeAddOp2(v, OP_FkIfZero, pFKey->isDeferred, 0); + } + + /* Create an Expr object representing an SQL expression like: + ** + ** = AND = ... + ** + ** The collation sequence used for the comparison should be that of + ** the parent key columns. The affinity of the parent key column should + ** be applied to each child key value before the comparison takes place. + */ + for(i=0; inCol; i++){ + Expr *pLeft; /* Value from parent table row */ + Expr *pRight; /* Column ref to child table */ + Expr *pEq; /* Expression (pLeft = pRight) */ + int iCol; /* Index of column in child table */ + const char *zCol; /* Name of column in child table */ + + pLeft = sqlite3Expr(db, TK_REGISTER, 0); + if( pLeft ){ + /* Set the collation sequence and affinity of the LHS of each TK_EQ + ** expression to the parent key column defaults. */ + if( pIdx ){ + Column *pCol; + iCol = pIdx->aiColumn[i]; + pCol = &pIdx->pTable->aCol[iCol]; + pLeft->iTable = regData+iCol+1; + pLeft->affinity = pCol->affinity; + pLeft->pColl = sqlite3LocateCollSeq(pParse, pCol->zColl); + }else{ + pLeft->iTable = regData; + pLeft->affinity = SQLITE_AFF_INTEGER; + } + } + iCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; + assert( iCol>=0 ); + zCol = pFKey->pFrom->aCol[iCol].zName; + pRight = sqlite3Expr(db, TK_ID, zCol); + pEq = sqlite3PExpr(pParse, TK_EQ, pLeft, pRight, 0); + pWhere = sqlite3ExprAnd(db, pWhere, pEq); + } + + /* If the child table is the same as the parent table, and this scan + ** is taking place as part of a DELETE operation (operation D.2), omit the + ** row being deleted from the scan by adding ($rowid != rowid) to the WHERE + ** clause, where $rowid is the rowid of the row being deleted. */ + if( pTab==pFKey->pFrom && nIncr>0 ){ + Expr *pEq; /* Expression (pLeft = pRight) */ + Expr *pLeft; /* Value from parent table row */ + Expr *pRight; /* Column ref to child table */ + pLeft = sqlite3Expr(db, TK_REGISTER, 0); + pRight = sqlite3Expr(db, TK_COLUMN, 0); + if( pLeft && pRight ){ + pLeft->iTable = regData; + pLeft->affinity = SQLITE_AFF_INTEGER; + pRight->iTable = pSrc->a[0].iCursor; + pRight->iColumn = -1; + } + pEq = sqlite3PExpr(pParse, TK_NE, pLeft, pRight, 0); + pWhere = sqlite3ExprAnd(db, pWhere, pEq); + } + + /* Resolve the references in the WHERE clause. */ + memset(&sNameContext, 0, sizeof(NameContext)); + sNameContext.pSrcList = pSrc; + sNameContext.pParse = pParse; + sqlite3ResolveExprNames(&sNameContext, pWhere); + + /* Create VDBE to loop through the entries in pSrc that match the WHERE + ** clause. If the constraint is not deferred, throw an exception for + ** each row found. Otherwise, for deferred constraints, increment the + ** deferred constraint counter by nIncr for each row selected. */ + pWInfo = sqlite3WhereBegin(pParse, pSrc, pWhere, 0, 0); + if( nIncr>0 && pFKey->isDeferred==0 ){ + sqlite3ParseToplevel(pParse)->mayAbort = 1; + } + sqlite3VdbeAddOp2(v, OP_FkCounter, pFKey->isDeferred, nIncr); + if( pWInfo ){ + sqlite3WhereEnd(pWInfo); + } + + /* Clean up the WHERE clause constructed above. */ + sqlite3ExprDelete(db, pWhere); + if( iFkIfZero ){ + sqlite3VdbeJumpHere(v, iFkIfZero); + } +} + +/* +** This function returns a pointer to the head of a linked list of FK +** constraints for which table pTab is the parent table. For example, +** given the following schema: +** +** CREATE TABLE t1(a PRIMARY KEY); +** CREATE TABLE t2(b REFERENCES t1(a); +** +** Calling this function with table "t1" as an argument returns a pointer +** to the FKey structure representing the foreign key constraint on table +** "t2". Calling this function with "t2" as the argument would return a +** NULL pointer (as there are no FK constraints for which t2 is the parent +** table). +*/ +SQLITE_PRIVATE FKey *sqlite3FkReferences(Table *pTab){ + int nName = sqlite3Strlen30(pTab->zName); + return (FKey *)sqlite3HashFind(&pTab->pSchema->fkeyHash, pTab->zName, nName); +} + +/* +** The second argument is a Trigger structure allocated by the +** fkActionTrigger() routine. This function deletes the Trigger structure +** and all of its sub-components. +** +** The Trigger structure or any of its sub-components may be allocated from +** the lookaside buffer belonging to database handle dbMem. +*/ +static void fkTriggerDelete(sqlite3 *dbMem, Trigger *p){ + if( p ){ + TriggerStep *pStep = p->step_list; + sqlite3ExprDelete(dbMem, pStep->pWhere); + sqlite3ExprListDelete(dbMem, pStep->pExprList); + sqlite3SelectDelete(dbMem, pStep->pSelect); + sqlite3ExprDelete(dbMem, p->pWhen); + sqlite3DbFree(dbMem, p); + } +} + +/* +** This function is called to generate code that runs when table pTab is +** being dropped from the database. The SrcList passed as the second argument +** to this function contains a single entry guaranteed to resolve to +** table pTab. +** +** Normally, no code is required. However, if either +** +** (a) The table is the parent table of a FK constraint, or +** (b) The table is the child table of a deferred FK constraint and it is +** determined at runtime that there are outstanding deferred FK +** constraint violations in the database, +** +** then the equivalent of "DELETE FROM " is executed before dropping +** the table from the database. Triggers are disabled while running this +** DELETE, but foreign key actions are not. +*/ +SQLITE_PRIVATE void sqlite3FkDropTable(Parse *pParse, SrcList *pName, Table *pTab){ + sqlite3 *db = pParse->db; + if( (db->flags&SQLITE_ForeignKeys) && !IsVirtual(pTab) && !pTab->pSelect ){ + int iSkip = 0; + Vdbe *v = sqlite3GetVdbe(pParse); + + assert( v ); /* VDBE has already been allocated */ + if( sqlite3FkReferences(pTab)==0 ){ + /* Search for a deferred foreign key constraint for which this table + ** is the child table. If one cannot be found, return without + ** generating any VDBE code. If one can be found, then jump over + ** the entire DELETE if there are no outstanding deferred constraints + ** when this statement is run. */ + FKey *p; + for(p=pTab->pFKey; p; p=p->pNextFrom){ + if( p->isDeferred ) break; + } + if( !p ) return; + iSkip = sqlite3VdbeMakeLabel(v); + sqlite3VdbeAddOp2(v, OP_FkIfZero, 1, iSkip); + } + + pParse->disableTriggers = 1; + sqlite3DeleteFrom(pParse, sqlite3SrcListDup(db, pName, 0), 0); + pParse->disableTriggers = 0; + + /* If the DELETE has generated immediate foreign key constraint + ** violations, halt the VDBE and return an error at this point, before + ** any modifications to the schema are made. This is because statement + ** transactions are not able to rollback schema changes. */ + sqlite3VdbeAddOp2(v, OP_FkIfZero, 0, sqlite3VdbeCurrentAddr(v)+2); + sqlite3HaltConstraint( + pParse, OE_Abort, "foreign key constraint failed", P4_STATIC + ); + + if( iSkip ){ + sqlite3VdbeResolveLabel(v, iSkip); + } + } +} + +/* +** This function is called when inserting, deleting or updating a row of +** table pTab to generate VDBE code to perform foreign key constraint +** processing for the operation. +** +** For a DELETE operation, parameter regOld is passed the index of the +** first register in an array of (pTab->nCol+1) registers containing the +** rowid of the row being deleted, followed by each of the column values +** of the row being deleted, from left to right. Parameter regNew is passed +** zero in this case. +** +** For an INSERT operation, regOld is passed zero and regNew is passed the +** first register of an array of (pTab->nCol+1) registers containing the new +** row data. +** +** For an UPDATE operation, this function is called twice. Once before +** the original record is deleted from the table using the calling convention +** described for DELETE. Then again after the original record is deleted +** but before the new record is inserted using the INSERT convention. +*/ +SQLITE_PRIVATE void sqlite3FkCheck( + Parse *pParse, /* Parse context */ + Table *pTab, /* Row is being deleted from this table */ + int regOld, /* Previous row data is stored here */ + int regNew /* New row data is stored here */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + Vdbe *v; /* VM to write code to */ + FKey *pFKey; /* Used to iterate through FKs */ + int iDb; /* Index of database containing pTab */ + const char *zDb; /* Name of database containing pTab */ + int isIgnoreErrors = pParse->disableTriggers; + + /* Exactly one of regOld and regNew should be non-zero. */ + assert( (regOld==0)!=(regNew==0) ); + + /* If foreign-keys are disabled, this function is a no-op. */ + if( (db->flags&SQLITE_ForeignKeys)==0 ) return; + + v = sqlite3GetVdbe(pParse); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); + zDb = db->aDb[iDb].zName; + + /* Loop through all the foreign key constraints for which pTab is the + ** child table (the table that the foreign key definition is part of). */ + for(pFKey=pTab->pFKey; pFKey; pFKey=pFKey->pNextFrom){ + Table *pTo; /* Parent table of foreign key pFKey */ + Index *pIdx = 0; /* Index on key columns in pTo */ + int *aiFree = 0; + int *aiCol; + int iCol; + int i; + int isIgnore = 0; + + /* Find the parent table of this foreign key. Also find a unique index + ** on the parent key columns in the parent table. If either of these + ** schema items cannot be located, set an error in pParse and return + ** early. */ + if( pParse->disableTriggers ){ + pTo = sqlite3FindTable(db, pFKey->zTo, zDb); + }else{ + pTo = sqlite3LocateTable(pParse, 0, pFKey->zTo, zDb); + } + if( !pTo || locateFkeyIndex(pParse, pTo, pFKey, &pIdx, &aiFree) ){ + if( !isIgnoreErrors || db->mallocFailed ) return; + continue; + } + assert( pFKey->nCol==1 || (aiFree && pIdx) ); + + if( aiFree ){ + aiCol = aiFree; + }else{ + iCol = pFKey->aCol[0].iFrom; + aiCol = &iCol; + } + for(i=0; inCol; i++){ + if( aiCol[i]==pTab->iPKey ){ + aiCol[i] = -1; + } +#ifndef SQLITE_OMIT_AUTHORIZATION + /* Request permission to read the parent key columns. If the + ** authorization callback returns SQLITE_IGNORE, behave as if any + ** values read from the parent table are NULL. */ + if( db->xAuth ){ + int rcauth; + char *zCol = pTo->aCol[pIdx ? pIdx->aiColumn[i] : pTo->iPKey].zName; + rcauth = sqlite3AuthReadCol(pParse, pTo->zName, zCol, iDb); + isIgnore = (rcauth==SQLITE_IGNORE); + } +#endif + } + + /* Take a shared-cache advisory read-lock on the parent table. Allocate + ** a cursor to use to search the unique index on the parent key columns + ** in the parent table. */ + sqlite3TableLock(pParse, iDb, pTo->tnum, 0, pTo->zName); + pParse->nTab++; + + if( regOld!=0 ){ + /* A row is being removed from the child table. Search for the parent. + ** If the parent does not exist, removing the child row resolves an + ** outstanding foreign key constraint violation. */ + fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regOld, -1,isIgnore); + } + if( regNew!=0 ){ + /* A row is being added to the child table. If a parent row cannot + ** be found, adding the child row has violated the FK constraint. */ + fkLookupParent(pParse, iDb, pTo, pIdx, pFKey, aiCol, regNew, +1,isIgnore); + } + + sqlite3DbFree(db, aiFree); + } + + /* Loop through all the foreign key constraints that refer to this table */ + for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ + Index *pIdx = 0; /* Foreign key index for pFKey */ + SrcList *pSrc; + int *aiCol = 0; + + if( !pFKey->isDeferred && !pParse->pToplevel && !pParse->isMultiWrite ){ + assert( regOld==0 && regNew!=0 ); + /* Inserting a single row into a parent table cannot cause an immediate + ** foreign key violation. So do nothing in this case. */ + continue; + } + + if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ){ + if( !isIgnoreErrors || db->mallocFailed ) return; + continue; + } + assert( aiCol || pFKey->nCol==1 ); + + /* Create a SrcList structure containing a single table (the table + ** the foreign key that refers to this table is attached to). This + ** is required for the sqlite3WhereXXX() interface. */ + pSrc = sqlite3SrcListAppend(db, 0, 0, 0); + if( pSrc ){ + struct SrcList_item *pItem = pSrc->a; + pItem->pTab = pFKey->pFrom; + pItem->zName = pFKey->pFrom->zName; + pItem->pTab->nRef++; + pItem->iCursor = pParse->nTab++; + + if( regNew!=0 ){ + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regNew, -1); + } + if( regOld!=0 ){ + /* If there is a RESTRICT action configured for the current operation + ** on the parent table of this FK, then throw an exception + ** immediately if the FK constraint is violated, even if this is a + ** deferred trigger. That's what RESTRICT means. To defer checking + ** the constraint, the FK should specify NO ACTION (represented + ** using OE_None). NO ACTION is the default. */ + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); + } + pItem->zName = 0; + sqlite3SrcListDelete(db, pSrc); + } + sqlite3DbFree(db, aiCol); + } +} + +#define COLUMN_MASK(x) (((x)>31) ? 0xffffffff : ((u32)1<<(x))) + +/* +** This function is called before generating code to update or delete a +** row contained in table pTab. +*/ +SQLITE_PRIVATE u32 sqlite3FkOldmask( + Parse *pParse, /* Parse context */ + Table *pTab /* Table being modified */ +){ + u32 mask = 0; + if( pParse->db->flags&SQLITE_ForeignKeys ){ + FKey *p; + int i; + for(p=pTab->pFKey; p; p=p->pNextFrom){ + for(i=0; inCol; i++) mask |= COLUMN_MASK(p->aCol[i].iFrom); + } + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + Index *pIdx = 0; + locateFkeyIndex(pParse, pTab, p, &pIdx, 0); + if( pIdx ){ + for(i=0; inColumn; i++) mask |= COLUMN_MASK(pIdx->aiColumn[i]); + } + } + } + return mask; +} + +/* +** This function is called before generating code to update or delete a +** row contained in table pTab. If the operation is a DELETE, then +** parameter aChange is passed a NULL value. For an UPDATE, aChange points +** to an array of size N, where N is the number of columns in table pTab. +** If the i'th column is not modified by the UPDATE, then the corresponding +** entry in the aChange[] array is set to -1. If the column is modified, +** the value is 0 or greater. Parameter chngRowid is set to true if the +** UPDATE statement modifies the rowid fields of the table. +** +** If any foreign key processing will be required, this function returns +** true. If there is no foreign key related processing, this function +** returns false. +*/ +SQLITE_PRIVATE int sqlite3FkRequired( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being modified */ + int *aChange, /* Non-NULL for UPDATE operations */ + int chngRowid /* True for UPDATE that affects rowid */ +){ + if( pParse->db->flags&SQLITE_ForeignKeys ){ + if( !aChange ){ + /* A DELETE operation. Foreign key processing is required if the + ** table in question is either the child or parent table for any + ** foreign key constraint. */ + return (sqlite3FkReferences(pTab) || pTab->pFKey); + }else{ + /* This is an UPDATE. Foreign key processing is only required if the + ** operation modifies one or more child or parent key columns. */ + int i; + FKey *p; + + /* Check if any child key columns are being modified. */ + for(p=pTab->pFKey; p; p=p->pNextFrom){ + for(i=0; inCol; i++){ + int iChildKey = p->aCol[i].iFrom; + if( aChange[iChildKey]>=0 ) return 1; + if( iChildKey==pTab->iPKey && chngRowid ) return 1; + } + } + + /* Check if any parent key columns are being modified. */ + for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ + for(i=0; inCol; i++){ + char *zKey = p->aCol[i].zCol; + int iKey; + for(iKey=0; iKeynCol; iKey++){ + Column *pCol = &pTab->aCol[iKey]; + if( (zKey ? !sqlite3StrICmp(pCol->zName, zKey) : pCol->isPrimKey) ){ + if( aChange[iKey]>=0 ) return 1; + if( iKey==pTab->iPKey && chngRowid ) return 1; + } + } + } + } + } + } + return 0; +} + +/* +** This function is called when an UPDATE or DELETE operation is being +** compiled on table pTab, which is the parent table of foreign-key pFKey. +** If the current operation is an UPDATE, then the pChanges parameter is +** passed a pointer to the list of columns being modified. If it is a +** DELETE, pChanges is passed a NULL pointer. +** +** It returns a pointer to a Trigger structure containing a trigger +** equivalent to the ON UPDATE or ON DELETE action specified by pFKey. +** If the action is "NO ACTION" or "RESTRICT", then a NULL pointer is +** returned (these actions require no special handling by the triggers +** sub-system, code for them is created by fkScanChildren()). +** +** For example, if pFKey is the foreign key and pTab is table "p" in +** the following schema: +** +** CREATE TABLE p(pk PRIMARY KEY); +** CREATE TABLE c(ck REFERENCES p ON DELETE CASCADE); +** +** then the returned trigger structure is equivalent to: +** +** CREATE TRIGGER ... DELETE ON p BEGIN +** DELETE FROM c WHERE ck = old.pk; +** END; +** +** The returned pointer is cached as part of the foreign key object. It +** is eventually freed along with the rest of the foreign key object by +** sqlite3FkDelete(). +*/ +static Trigger *fkActionTrigger( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated or deleted from */ + FKey *pFKey, /* Foreign key to get action for */ + ExprList *pChanges /* Change-list for UPDATE, NULL for DELETE */ +){ + sqlite3 *db = pParse->db; /* Database handle */ + int action; /* One of OE_None, OE_Cascade etc. */ + Trigger *pTrigger; /* Trigger definition to return */ + int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ + + action = pFKey->aAction[iAction]; + pTrigger = pFKey->apTrigger[iAction]; + + if( action!=OE_None && !pTrigger ){ + u8 enableLookaside; /* Copy of db->lookaside.bEnabled */ + char const *zFrom; /* Name of child table */ + int nFrom; /* Length in bytes of zFrom */ + Index *pIdx = 0; /* Parent key index for this FK */ + int *aiCol = 0; /* child table cols -> parent key cols */ + TriggerStep *pStep = 0; /* First (only) step of trigger program */ + Expr *pWhere = 0; /* WHERE clause of trigger step */ + ExprList *pList = 0; /* Changes list if ON UPDATE CASCADE */ + Select *pSelect = 0; /* If RESTRICT, "SELECT RAISE(...)" */ + int i; /* Iterator variable */ + Expr *pWhen = 0; /* WHEN clause for the trigger */ + + if( locateFkeyIndex(pParse, pTab, pFKey, &pIdx, &aiCol) ) return 0; + assert( aiCol || pFKey->nCol==1 ); + + for(i=0; inCol; i++){ + Token tOld = { "old", 3 }; /* Literal "old" token */ + Token tNew = { "new", 3 }; /* Literal "new" token */ + Token tFromCol; /* Name of column in child table */ + Token tToCol; /* Name of column in parent table */ + int iFromCol; /* Idx of column in child table */ + Expr *pEq; /* tFromCol = OLD.tToCol */ + + iFromCol = aiCol ? aiCol[i] : pFKey->aCol[0].iFrom; + assert( iFromCol>=0 ); + tToCol.z = pIdx ? pTab->aCol[pIdx->aiColumn[i]].zName : "oid"; + tFromCol.z = pFKey->pFrom->aCol[iFromCol].zName; + + tToCol.n = sqlite3Strlen30(tToCol.z); + tFromCol.n = sqlite3Strlen30(tFromCol.z); + + /* Create the expression "OLD.zToCol = zFromCol". It is important + ** that the "OLD.zToCol" term is on the LHS of the = operator, so + ** that the affinity and collation sequence associated with the + ** parent table are used for the comparison. */ + pEq = sqlite3PExpr(pParse, TK_EQ, + sqlite3PExpr(pParse, TK_DOT, + sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld), + sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol) + , 0), + sqlite3PExpr(pParse, TK_ID, 0, 0, &tFromCol) + , 0); + pWhere = sqlite3ExprAnd(db, pWhere, pEq); + + /* For ON UPDATE, construct the next term of the WHEN clause. + ** The final WHEN clause will be like this: + ** + ** WHEN NOT(old.col1 IS new.col1 AND ... AND old.colN IS new.colN) + */ + if( pChanges ){ + pEq = sqlite3PExpr(pParse, TK_IS, + sqlite3PExpr(pParse, TK_DOT, + sqlite3PExpr(pParse, TK_ID, 0, 0, &tOld), + sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol), + 0), + sqlite3PExpr(pParse, TK_DOT, + sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew), + sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol), + 0), + 0); + pWhen = sqlite3ExprAnd(db, pWhen, pEq); + } + + if( action!=OE_Restrict && (action!=OE_Cascade || pChanges) ){ + Expr *pNew; + if( action==OE_Cascade ){ + pNew = sqlite3PExpr(pParse, TK_DOT, + sqlite3PExpr(pParse, TK_ID, 0, 0, &tNew), + sqlite3PExpr(pParse, TK_ID, 0, 0, &tToCol) + , 0); + }else if( action==OE_SetDflt ){ + Expr *pDflt = pFKey->pFrom->aCol[iFromCol].pDflt; + if( pDflt ){ + pNew = sqlite3ExprDup(db, pDflt, 0); + }else{ + pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); + } + }else{ + pNew = sqlite3PExpr(pParse, TK_NULL, 0, 0, 0); + } + pList = sqlite3ExprListAppend(pParse, pList, pNew); + sqlite3ExprListSetName(pParse, pList, &tFromCol, 0); + } + } + sqlite3DbFree(db, aiCol); + + zFrom = pFKey->pFrom->zName; + nFrom = sqlite3Strlen30(zFrom); + + if( action==OE_Restrict ){ + Token tFrom; + Expr *pRaise; + + tFrom.z = zFrom; + tFrom.n = nFrom; + pRaise = sqlite3Expr(db, TK_RAISE, "foreign key constraint failed"); + if( pRaise ){ + pRaise->affinity = OE_Abort; + } + pSelect = sqlite3SelectNew(pParse, + sqlite3ExprListAppend(pParse, 0, pRaise), + sqlite3SrcListAppend(db, 0, &tFrom, 0), + pWhere, + 0, 0, 0, 0, 0, 0 + ); + pWhere = 0; + } + + /* In the current implementation, pTab->dbMem==0 for all tables except + ** for temporary tables used to describe subqueries. And temporary + ** tables do not have foreign key constraints. Hence, pTab->dbMem + ** should always be 0 there. + */ + enableLookaside = db->lookaside.bEnabled; + db->lookaside.bEnabled = 0; + + pTrigger = (Trigger *)sqlite3DbMallocZero(db, + sizeof(Trigger) + /* struct Trigger */ + sizeof(TriggerStep) + /* Single step in trigger program */ + nFrom + 1 /* Space for pStep->target.z */ + ); + if( pTrigger ){ + pStep = pTrigger->step_list = (TriggerStep *)&pTrigger[1]; + pStep->target.z = (char *)&pStep[1]; + pStep->target.n = nFrom; + memcpy((char *)pStep->target.z, zFrom, nFrom); + + pStep->pWhere = sqlite3ExprDup(db, pWhere, EXPRDUP_REDUCE); + pStep->pExprList = sqlite3ExprListDup(db, pList, EXPRDUP_REDUCE); + pStep->pSelect = sqlite3SelectDup(db, pSelect, EXPRDUP_REDUCE); + if( pWhen ){ + pWhen = sqlite3PExpr(pParse, TK_NOT, pWhen, 0, 0); + pTrigger->pWhen = sqlite3ExprDup(db, pWhen, EXPRDUP_REDUCE); + } + } + + /* Re-enable the lookaside buffer, if it was disabled earlier. */ + db->lookaside.bEnabled = enableLookaside; + + sqlite3ExprDelete(db, pWhere); + sqlite3ExprDelete(db, pWhen); + sqlite3ExprListDelete(db, pList); + sqlite3SelectDelete(db, pSelect); + if( db->mallocFailed==1 ){ + fkTriggerDelete(db, pTrigger); + return 0; + } + + switch( action ){ + case OE_Restrict: + pStep->op = TK_SELECT; + break; + case OE_Cascade: + if( !pChanges ){ + pStep->op = TK_DELETE; + break; + } + default: + pStep->op = TK_UPDATE; + } + pStep->pTrig = pTrigger; + pTrigger->pSchema = pTab->pSchema; + pTrigger->pTabSchema = pTab->pSchema; + pFKey->apTrigger[iAction] = pTrigger; + pTrigger->op = (pChanges ? TK_UPDATE : TK_DELETE); + } + + return pTrigger; +} + +/* +** This function is called when deleting or updating a row to implement +** any required CASCADE, SET NULL or SET DEFAULT actions. +*/ +SQLITE_PRIVATE void sqlite3FkActions( + Parse *pParse, /* Parse context */ + Table *pTab, /* Table being updated or deleted from */ + ExprList *pChanges, /* Change-list for UPDATE, NULL for DELETE */ + int regOld /* Address of array containing old row */ +){ + /* If foreign-key support is enabled, iterate through all FKs that + ** refer to table pTab. If there is an action associated with the FK + ** for this operation (either update or delete), invoke the associated + ** trigger sub-program. */ + if( pParse->db->flags&SQLITE_ForeignKeys ){ + FKey *pFKey; /* Iterator variable */ + for(pFKey = sqlite3FkReferences(pTab); pFKey; pFKey=pFKey->pNextTo){ + Trigger *pAction = fkActionTrigger(pParse, pTab, pFKey, pChanges); + if( pAction ){ + sqlite3CodeRowTriggerDirect(pParse, pAction, pTab, regOld, OE_Abort, 0); + } + } + } +} + +#endif /* ifndef SQLITE_OMIT_TRIGGER */ + +/* +** Free all memory associated with foreign key definitions attached to +** table pTab. Remove the deleted foreign keys from the Schema.fkeyHash +** hash table. +*/ +SQLITE_PRIVATE void sqlite3FkDelete(Table *pTab){ + FKey *pFKey; /* Iterator variable */ + FKey *pNext; /* Copy of pFKey->pNextFrom */ + + for(pFKey=pTab->pFKey; pFKey; pFKey=pNext){ + + /* Remove the FK from the fkeyHash hash table. */ + if( pFKey->pPrevTo ){ + pFKey->pPrevTo->pNextTo = pFKey->pNextTo; + }else{ + void *data = (void *)pFKey->pNextTo; + const char *z = (data ? pFKey->pNextTo->zTo : pFKey->zTo); + sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, sqlite3Strlen30(z), data); + } + if( pFKey->pNextTo ){ + pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; + } + + /* Delete any triggers created to implement actions for this FK. */ +#ifndef SQLITE_OMIT_TRIGGER + fkTriggerDelete(pTab->dbMem, pFKey->apTrigger[0]); + fkTriggerDelete(pTab->dbMem, pFKey->apTrigger[1]); +#endif + + /* EV: R-30323-21917 Each foreign key constraint in SQLite is + ** classified as either immediate or deferred. + */ + assert( pFKey->isDeferred==0 || pFKey->isDeferred==1 ); + + pNext = pFKey->pNextFrom; + sqlite3DbFree(pTab->dbMem, pFKey); + } +} +#endif /* ifndef SQLITE_OMIT_FOREIGN_KEY */ + +/************** End of fkey.c ************************************************/ /************** Begin file insert.c ******************************************/ /* ** 2001 September 15 @@ -70349,7 +73275,7 @@ SQLITE_PRIVATE void sqlite3RegisterGlobalFunctions(void){ ** This file contains C code routines that are called by the parser ** to handle INSERT statements in SQLite. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -70373,9 +73299,9 @@ SQLITE_PRIVATE void sqlite3OpenTable( } /* -** Set P4 of the most recently inserted opcode to a column affinity -** string for index pIdx. A column affinity string has one character -** for each column in the table, according to the affinity of the column: +** Return a pointer to the column affinity string associated with index +** pIdx. A column affinity string has one character for each column in +** the table, according to the affinity of the column: ** ** Character Column affinity ** ------------------------------ @@ -70387,8 +73313,12 @@ SQLITE_PRIVATE void sqlite3OpenTable( ** ** An extra 'b' is appended to the end of the string to cover the ** rowid that appears as the last column in every index. +** +** Memory for the buffer containing the column index affinity string +** is managed along with the rest of the Index structure. It will be +** released when sqlite3DeleteIndex() is called. */ -SQLITE_PRIVATE void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ +SQLITE_PRIVATE const char *sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ if( !pIdx->zColAff ){ /* The first time a column affinity string for a particular index is ** required, it is allocated and populated here. It is then stored as @@ -70404,7 +73334,7 @@ SQLITE_PRIVATE void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ pIdx->zColAff = (char *)sqlite3Malloc(pIdx->nColumn+2); if( !pIdx->zColAff ){ db->mallocFailed = 1; - return; + return 0; } for(n=0; nnColumn; n++){ pIdx->zColAff[n] = pTab->aCol[pIdx->aiColumn[n]].affinity; @@ -70413,7 +73343,7 @@ SQLITE_PRIVATE void sqlite3IndexAffinityStr(Vdbe *v, Index *pIdx){ pIdx->zColAff[n] = 0; } - sqlite3VdbeChangeP4(v, -1, pIdx->zColAff, 0); + return pIdx->zColAff; } /* @@ -70467,9 +73397,14 @@ SQLITE_PRIVATE void sqlite3TableAffinityStr(Vdbe *v, Table *pTab){ ** a statement of the form "INSERT INTO SELECT ..." can ** run without using temporary table for the results of the SELECT. */ -static int readsTable(Vdbe *v, int iStartAddr, int iDb, Table *pTab){ +static int readsTable(Parse *p, int iStartAddr, int iDb, Table *pTab){ + Vdbe *v = sqlite3GetVdbe(p); int i; int iEnd = sqlite3VdbeCurrentAddr(v); +#ifndef SQLITE_OMIT_VIRTUALTABLE + VTable *pVTab = IsVirtual(pTab) ? sqlite3GetVTable(p->db, pTab) : 0; +#endif + for(i=iStartAddr; iopcode==OP_VOpen && pOp->p4.pVtab==pTab->pVtab ){ + if( pOp->opcode==OP_VOpen && pOp->p4.pVtab==pVTab ){ assert( pOp->p4.pVtab!=0 ); assert( pOp->p4type==P4_VTAB ); return 1; @@ -70498,22 +73433,24 @@ static int readsTable(Vdbe *v, int iStartAddr, int iDb, Table *pTab){ #ifndef SQLITE_OMIT_AUTOINCREMENT /* -** Write out code to initialize the autoincrement logic. This code -** looks up the current autoincrement value in the sqlite_sequence -** table and stores that value in a register. Code generated by -** autoIncStep() will keep that register holding the largest -** rowid value. Code generated by autoIncEnd() will write the new -** largest value of the counter back into the sqlite_sequence table. +** Locate or create an AutoincInfo structure associated with table pTab +** which is in database iDb. Return the register number for the register +** that holds the maximum rowid. +** +** There is at most one AutoincInfo structure per table even if the +** same table is autoincremented multiple times due to inserts within +** triggers. A new AutoincInfo structure is created if this is the +** first use of table pTab. On 2nd and subsequent uses, the original +** AutoincInfo structure is used. +** +** Three memory locations are allocated: ** -** This routine returns the index of the mem[] cell that contains -** the maximum rowid counter. +** (1) Register to hold the name of the pTab table. +** (2) Register to hold the maximum ROWID of pTab. +** (3) Register to hold the rowid in sqlite_sequence of pTab ** -** Three consecutive registers are allocated by this routine. The -** first two hold the name of the target table and the maximum rowid -** inserted into the target table, respectively. -** The third holds the rowid in sqlite_sequence where we will -** write back the revised maximum rowid. This routine returns the -** index of the second of these three registers. +** The 2nd register is the one that is returned. That is all the +** insert routine needs to know about. */ static int autoIncBegin( Parse *pParse, /* Parsing context */ @@ -70522,29 +73459,62 @@ static int autoIncBegin( ){ int memId = 0; /* Register holding maximum rowid */ if( pTab->tabFlags & TF_Autoincrement ){ - Vdbe *v = pParse->pVdbe; - Db *pDb = &pParse->db->aDb[iDb]; - int iCur = pParse->nTab++; - int addr; /* Address of the top of the loop */ - assert( v ); - pParse->nMem++; /* Holds name of table */ - memId = ++pParse->nMem; - pParse->nMem++; - sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead); + Parse *pToplevel = sqlite3ParseToplevel(pParse); + AutoincInfo *pInfo; + + pInfo = pToplevel->pAinc; + while( pInfo && pInfo->pTab!=pTab ){ pInfo = pInfo->pNext; } + if( pInfo==0 ){ + pInfo = sqlite3DbMallocRaw(pParse->db, sizeof(*pInfo)); + if( pInfo==0 ) return 0; + pInfo->pNext = pToplevel->pAinc; + pToplevel->pAinc = pInfo; + pInfo->pTab = pTab; + pInfo->iDb = iDb; + pToplevel->nMem++; /* Register to hold name of table */ + pInfo->regCtr = ++pToplevel->nMem; /* Max rowid register */ + pToplevel->nMem++; /* Rowid in sqlite_sequence */ + } + memId = pInfo->regCtr; + } + return memId; +} + +/* +** This routine generates code that will initialize all of the +** register used by the autoincrement tracker. +*/ +SQLITE_PRIVATE void sqlite3AutoincrementBegin(Parse *pParse){ + AutoincInfo *p; /* Information about an AUTOINCREMENT */ + sqlite3 *db = pParse->db; /* The database connection */ + Db *pDb; /* Database only autoinc table */ + int memId; /* Register holding max rowid */ + int addr; /* A VDBE address */ + Vdbe *v = pParse->pVdbe; /* VDBE under construction */ + + /* This routine is never called during trigger-generation. It is + ** only called from the top-level */ + assert( pParse->pTriggerTab==0 ); + assert( pParse==sqlite3ParseToplevel(pParse) ); + + assert( v ); /* We failed long ago if this is not so */ + for(p = pParse->pAinc; p; p = p->pNext){ + pDb = &db->aDb[p->iDb]; + memId = p->regCtr; + sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenRead); addr = sqlite3VdbeCurrentAddr(v); - sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, pTab->zName, 0); - sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addr+9); - sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, memId); + sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, p->pTab->zName, 0); + sqlite3VdbeAddOp2(v, OP_Rewind, 0, addr+9); + sqlite3VdbeAddOp3(v, OP_Column, 0, 0, memId); sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId); sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL); - sqlite3VdbeAddOp2(v, OP_Rowid, iCur, memId+1); - sqlite3VdbeAddOp3(v, OP_Column, iCur, 1, memId); + sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1); + sqlite3VdbeAddOp3(v, OP_Column, 0, 1, memId); sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9); - sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+2); + sqlite3VdbeAddOp2(v, OP_Next, 0, addr+2); sqlite3VdbeAddOp2(v, OP_Integer, 0, memId); - sqlite3VdbeAddOp2(v, OP_Close, iCur, 0); + sqlite3VdbeAddOp0(v, OP_Close); } - return memId; } /* @@ -70562,32 +73532,43 @@ static void autoIncStep(Parse *pParse, int memId, int regRowid){ } /* -** After doing one or more inserts, the maximum rowid is stored -** in reg[memId]. Generate code to write this value back into the -** the sqlite_sequence table. +** This routine generates the code needed to write autoincrement +** maximum rowid values back into the sqlite_sequence register. +** Every statement that might do an INSERT into an autoincrement +** table (either directly or through triggers) needs to call this +** routine just before the "exit" code. */ -static void autoIncEnd( - Parse *pParse, /* The parsing context */ - int iDb, /* Index of the database holding pTab */ - Table *pTab, /* Table we are inserting into */ - int memId /* Memory cell holding the maximum rowid */ -){ - if( pTab->tabFlags & TF_Autoincrement ){ - int iCur = pParse->nTab++; - Vdbe *v = pParse->pVdbe; - Db *pDb = &pParse->db->aDb[iDb]; - int j1; - int iRec = ++pParse->nMem; /* Memory cell used for record */ +SQLITE_PRIVATE void sqlite3AutoincrementEnd(Parse *pParse){ + AutoincInfo *p; + Vdbe *v = pParse->pVdbe; + sqlite3 *db = pParse->db; - assert( v ); - sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); + assert( v ); + for(p = pParse->pAinc; p; p = p->pNext){ + Db *pDb = &db->aDb[p->iDb]; + int j1, j2, j3, j4, j5; + int iRec; + int memId = p->regCtr; + + iRec = sqlite3GetTempReg(pParse); + sqlite3OpenTable(pParse, 0, p->iDb, pDb->pSchema->pSeqTab, OP_OpenWrite); j1 = sqlite3VdbeAddOp1(v, OP_NotNull, memId+1); - sqlite3VdbeAddOp2(v, OP_NewRowid, iCur, memId+1); + j2 = sqlite3VdbeAddOp0(v, OP_Rewind); + j3 = sqlite3VdbeAddOp3(v, OP_Column, 0, 0, iRec); + j4 = sqlite3VdbeAddOp3(v, OP_Eq, memId-1, 0, iRec); + sqlite3VdbeAddOp2(v, OP_Next, 0, j3); + sqlite3VdbeJumpHere(v, j2); + sqlite3VdbeAddOp2(v, OP_NewRowid, 0, memId+1); + j5 = sqlite3VdbeAddOp0(v, OP_Goto); + sqlite3VdbeJumpHere(v, j4); + sqlite3VdbeAddOp2(v, OP_Rowid, 0, memId+1); sqlite3VdbeJumpHere(v, j1); + sqlite3VdbeJumpHere(v, j5); sqlite3VdbeAddOp3(v, OP_MakeRecord, memId-1, 2, iRec); - sqlite3VdbeAddOp3(v, OP_Insert, iCur, iRec, memId+1); + sqlite3VdbeAddOp3(v, OP_Insert, 0, iRec, memId+1); sqlite3VdbeChangeP5(v, OPFLAG_APPEND); - sqlite3VdbeAddOp1(v, OP_Close, iCur); + sqlite3VdbeAddOp0(v, OP_Close); + sqlite3ReleaseTempReg(pParse, iRec); } } #else @@ -70597,7 +73578,6 @@ static void autoIncEnd( */ # define autoIncBegin(A,B,C) (0) # define autoIncStep(A,B,C) -# define autoIncEnd(A,B,C,D) #endif /* SQLITE_OMIT_AUTOINCREMENT */ @@ -70738,7 +73718,6 @@ SQLITE_PRIVATE void sqlite3Insert( int addrCont = 0; /* Top of insert loop. Label "C" in templates 3 and 4 */ int addrSelect = 0; /* Address of coroutine that implements the SELECT */ SelectDest dest; /* Destination for SELECT on rhs of INSERT */ - int newIdx = -1; /* Cursor for the NEW pseudo-table */ int iDb; /* Index of database holding TABLE */ Db *pDb; /* The database containing table being inserted into */ int appendFlag = 0; /* True if the insert is likely to be an append */ @@ -70754,7 +73733,6 @@ SQLITE_PRIVATE void sqlite3Insert( int regEof = 0; /* Register recording end of SELECT data */ int *aRegIdx = 0; /* One register allocated to each index */ - #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to insert into a view */ Trigger *pTrigger; /* List of triggers on pTab, if required */ @@ -70801,15 +73779,6 @@ SQLITE_PRIVATE void sqlite3Insert( #endif assert( (pTrigger && tmask) || (pTrigger==0 && tmask==0) ); - /* Ensure that: - * (a) the table is not read-only, - * (b) that if it is a view then ON INSERT triggers exist - */ - if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ - goto insert_cleanup; - } - assert( pTab!=0 ); - /* If pTab is really a view, make sure it has been initialized. ** ViewGetColumnNames() is a no-op if pTab is not a view (or virtual ** module table). @@ -70818,6 +73787,14 @@ SQLITE_PRIVATE void sqlite3Insert( goto insert_cleanup; } + /* Ensure that: + * (a) the table is not read-only, + * (b) that if it is a view then ON INSERT triggers exist + */ + if( sqlite3IsReadOnly(pParse, pTab, tmask) ){ + goto insert_cleanup; + } + /* Allocate a VDBE */ v = sqlite3GetVdbe(pParse); @@ -70825,11 +73802,6 @@ SQLITE_PRIVATE void sqlite3Insert( if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); sqlite3BeginWriteOperation(pParse, pSelect || pTrigger, iDb); - /* if there are row triggers, allocate a temp table for new.* references. */ - if( pTrigger ){ - newIdx = pParse->nTab++; - } - #ifndef SQLITE_OMIT_XFER_OPT /* If the statement is of the form ** @@ -70843,7 +73815,7 @@ SQLITE_PRIVATE void sqlite3Insert( if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){ assert( !pTrigger ); assert( pList==0 ); - goto insert_cleanup; + goto insert_end; } #endif /* SQLITE_OMIT_XFER_OPT */ @@ -70917,7 +73889,7 @@ SQLITE_PRIVATE void sqlite3Insert( ** of the tables being read by the SELECT statement. Also use a ** temp table in the case of row triggers. */ - if( pTrigger || readsTable(v, addrSelect, iDb, pTab) ){ + if( pTrigger || readsTable(pParse, addrSelect, iDb, pTab) ){ useTempTable = 1; } @@ -71033,12 +74005,6 @@ SQLITE_PRIVATE void sqlite3Insert( if( pColumn==0 && nColumn>0 ){ keyColumn = pTab->iPKey; } - - /* Open the temp table for FOR EACH ROW triggers - */ - if( pTrigger ){ - sqlite3VdbeAddOp3(v, OP_OpenPseudo, newIdx, 0, pTab->nCol); - } /* Initialize the count of rows to be inserted */ @@ -71105,9 +74071,7 @@ SQLITE_PRIVATE void sqlite3Insert( */ endOfLoop = sqlite3VdbeMakeLabel(v); if( tmask & TRIGGER_BEFORE ){ - int regTrigRowid; - int regCols; - int regRec; + int regCols = sqlite3GetTempRange(pParse, pTab->nCol+1); /* build the NEW.* reference row. Note that if there is an INTEGER ** PRIMARY KEY into which a NULL is being inserted, that NULL will be @@ -71115,31 +74079,29 @@ SQLITE_PRIVATE void sqlite3Insert( ** we do not know what the unique ID will be (because the insert has ** not happened yet) so we substitute a rowid of -1 */ - regTrigRowid = sqlite3GetTempReg(pParse); if( keyColumn<0 ){ - sqlite3VdbeAddOp2(v, OP_Integer, -1, regTrigRowid); + sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); }else{ int j1; if( useTempTable ){ - sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regTrigRowid); + sqlite3VdbeAddOp3(v, OP_Column, srcTab, keyColumn, regCols); }else{ assert( pSelect==0 ); /* Otherwise useTempTable is true */ - sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regTrigRowid); + sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regCols); } - j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regTrigRowid); - sqlite3VdbeAddOp2(v, OP_Integer, -1, regTrigRowid); + j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regCols); + sqlite3VdbeAddOp2(v, OP_Integer, -1, regCols); sqlite3VdbeJumpHere(v, j1); - sqlite3VdbeAddOp1(v, OP_MustBeInt, regTrigRowid); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regCols); } /* Cannot have triggers on a virtual table. If it were possible, ** this block would have to account for hidden column. */ - assert(!IsVirtual(pTab)); + assert( !IsVirtual(pTab) ); /* Create the new column data */ - regCols = sqlite3GetTempRange(pParse, pTab->nCol); for(i=0; inCol; i++){ if( pColumn==0 ){ j = i; @@ -71149,16 +74111,14 @@ SQLITE_PRIVATE void sqlite3Insert( } } if( pColumn && j>=pColumn->nId ){ - sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i); + sqlite3ExprCode(pParse, pTab->aCol[i].pDflt, regCols+i+1); }else if( useTempTable ){ - sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i); + sqlite3VdbeAddOp3(v, OP_Column, srcTab, j, regCols+i+1); }else{ assert( pSelect==0 ); /* Otherwise useTempTable is true */ - sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i); + sqlite3ExprCodeAndCache(pParse, pList->a[j].pExpr, regCols+i+1); } } - regRec = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp3(v, OP_MakeRecord, regCols, pTab->nCol, regRec); /* If this is an INSERT on a view with an INSTEAD OF INSERT trigger, ** do not attempt any conversions before assembling the record. @@ -71166,18 +74126,15 @@ SQLITE_PRIVATE void sqlite3Insert( ** table column affinities. */ if( !isView ){ + sqlite3VdbeAddOp2(v, OP_Affinity, regCols+1, pTab->nCol); sqlite3TableAffinityStr(v, pTab); } - sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRec, regTrigRowid); - sqlite3ReleaseTempReg(pParse, regRec); - sqlite3ReleaseTempReg(pParse, regTrigRowid); - sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol); /* Fire BEFORE or INSTEAD OF triggers */ - if( sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, - pTab, newIdx, -1, onError, endOfLoop, 0, 0) ){ - goto insert_cleanup; - } + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, + pTab, regCols-pTab->nCol-1, onError, endOfLoop); + + sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1); } /* Push the record number for the new entry onto the stack. The @@ -71273,9 +74230,10 @@ SQLITE_PRIVATE void sqlite3Insert( */ #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); sqlite3VtabMakeWritable(pParse, pTab); - sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, - (const char*)pTab->pVtab, P4_VTAB); + sqlite3VdbeAddOp4(v, OP_VUpdate, 1, pTab->nCol+2, regIns, pVTab, P4_VTAB); + sqlite3MayAbort(pParse); }else #endif { @@ -71283,9 +74241,9 @@ SQLITE_PRIVATE void sqlite3Insert( sqlite3GenerateConstraintChecks(pParse, pTab, baseCur, regIns, aRegIdx, keyColumn>=0, 0, onError, endOfLoop, &isReplace ); + sqlite3FkCheck(pParse, pTab, 0, regIns); sqlite3CompleteInsertion( - pParse, pTab, baseCur, regIns, aRegIdx, 0, - (tmask&TRIGGER_AFTER) ? newIdx : -1, appendFlag, isReplace==0 + pParse, pTab, baseCur, regIns, aRegIdx, 0, appendFlag, isReplace==0 ); } } @@ -71298,10 +74256,8 @@ SQLITE_PRIVATE void sqlite3Insert( if( pTrigger ){ /* Code AFTER triggers */ - if( sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, - pTab, newIdx, -1, onError, endOfLoop, 0, 0) ){ - goto insert_cleanup; - } + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, + pTab, regData-2-pTab->nCol, onError, endOfLoop); } /* The bottom of the main insertion loop, if the data source @@ -71325,18 +74281,21 @@ SQLITE_PRIVATE void sqlite3Insert( } } +insert_end: /* Update the sqlite_sequence table by storing the content of the - ** counter value in memory regAutoinc back into the sqlite_sequence - ** table. + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. */ - autoIncEnd(pParse, iDb, pTab, regAutoinc); + if( pParse->nested==0 && pParse->pTriggerTab==0 ){ + sqlite3AutoincrementEnd(pParse); + } /* ** Return the number of rows inserted. If this routine is ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ - if( db->flags & SQLITE_CountRows && pParse->nested==0 && !pParse->trigStack ){ + if( (db->flags&SQLITE_CountRows) && !pParse->nested && !pParse->pTriggerTab ){ sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows inserted", SQLITE_STATIC); @@ -71350,31 +74309,43 @@ insert_cleanup: sqlite3DbFree(db, aRegIdx); } +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** thely may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif +#ifdef tmask + #undef tmask +#endif + + /* ** Generate code to do constraint checks prior to an INSERT or an UPDATE. ** ** The input is a range of consecutive registers as follows: ** -** 1. The rowid of the row to be updated before the update. This -** value is omitted unless we are doing an UPDATE that involves a -** change to the record number or writing to a virtual table. +** 1. The rowid of the row after the update. ** -** 2. The rowid of the row after the update. -** -** 3. The data in the first column of the entry after the update. +** 2. The data in the first column of the entry after the update. ** ** i. Data from middle columns... ** ** N. The data in the last column of the entry after the update. ** -** The regRowid parameter is the index of the register containing (2). +** The regRowid parameter is the index of the register containing (1). ** -** The old rowid shown as entry (1) above is omitted unless both isUpdate -** and rowidChng are 1. isUpdate is true for UPDATEs and false for -** INSERTs. RowidChng means that the new rowid is explicitly specified by -** the update or insert statement. If rowidChng is false, it means that -** the rowid is computed automatically in an insert or that the rowid value -** is not modified by the update. +** If isUpdate is true and rowidChng is non-zero, then rowidChng contains +** the address of a register containing the rowid before the update takes +** place. isUpdate is true for UPDATEs and false for INSERTs. If isUpdate +** is false, indicating an INSERT statement, then a non-zero rowidChng +** indicates that the rowid was explicitly specified as part of the +** INSERT statement. If rowidChng is false, it means that the rowid is +** computed automatically in an insert or that the rowid value is not +** modified by an update. ** ** The code generated by this routine store new index entries into ** registers identified by aRegIdx[]. No index entry is created for @@ -71449,7 +74420,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( int iCur; /* Table cursor number */ Index *pIdx; /* Pointer to one of the indices */ int seenReplace = 0; /* True if REPLACE is used to resolve INT PK conflict */ - int hasTwoRowids = (isUpdate && rowidChng); + int regOldRowid = (rowidChng && isUpdate) ? rowidChng : regRowid; v = sqlite3GetVdbe(pParse); assert( v!=0 ); @@ -71457,7 +74428,6 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( nCol = pTab->nCol; regData = regRowid + 1; - /* Test all NOT NULL constraints. */ for(i=0; ipIndex ){ - if( isUpdate ){ - j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, regRowid-1); - } - j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid); - switch( onError ){ - default: { - onError = OE_Abort; - /* Fall thru into the next case */ - } - case OE_Rollback: - case OE_Abort: - case OE_Fail: { - sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, - "PRIMARY KEY must be unique", P4_STATIC); - break; + if( isUpdate ){ + j2 = sqlite3VdbeAddOp3(v, OP_Eq, regRowid, 0, rowidChng); + } + j3 = sqlite3VdbeAddOp3(v, OP_NotExists, baseCur, 0, regRowid); + switch( onError ){ + default: { + onError = OE_Abort; + /* Fall thru into the next case */ + } + case OE_Rollback: + case OE_Abort: + case OE_Fail: { + sqlite3HaltConstraint( + pParse, onError, "PRIMARY KEY must be unique", P4_STATIC); + break; + } + case OE_Replace: { + /* If there are DELETE triggers on this table and the + ** recursive-triggers flag is set, call GenerateRowDelete() to + ** remove the conflicting row from the the table. This will fire + ** the triggers and remove both the table and index b-tree entries. + ** + ** Otherwise, if there are no triggers or the recursive-triggers + ** flag is not set, call GenerateRowIndexDelete(). This removes + ** the index b-tree entries only. The table b-tree entry will be + ** replaced by the new entry when it is inserted. */ + Trigger *pTrigger = 0; + if( pParse->db->flags&SQLITE_RecTriggers ){ + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); } - case OE_Replace: { + sqlite3MultiWrite(pParse); + if( pTrigger || sqlite3FkRequired(pParse, pTab, 0, 0) ){ + sqlite3GenerateRowDelete( + pParse, pTab, baseCur, regRowid, 0, pTrigger, OE_Replace + ); + }else{ sqlite3GenerateRowIndexDelete(pParse, pTab, baseCur, 0); - seenReplace = 1; - break; - } - case OE_Ignore: { - assert( seenReplace==0 ); - sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); - break; } + seenReplace = 1; + break; } - sqlite3VdbeJumpHere(v, j3); - if( isUpdate ){ - sqlite3VdbeJumpHere(v, j2); + case OE_Ignore: { + assert( seenReplace==0 ); + sqlite3VdbeAddOp2(v, OP_Goto, 0, ignoreDest); + break; } } + sqlite3VdbeJumpHere(v, j3); + if( isUpdate ){ + sqlite3VdbeJumpHere(v, j2); + } } /* Test all UNIQUE constraints by creating entries for each UNIQUE @@ -71588,7 +74577,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( } sqlite3VdbeAddOp2(v, OP_SCopy, regRowid, regIdx+i); sqlite3VdbeAddOp3(v, OP_MakeRecord, regIdx, pIdx->nColumn+1, aRegIdx[iCur]); - sqlite3IndexAffinityStr(v, pIdx); + sqlite3VdbeChangeP4(v, -1, sqlite3IndexAffinityStr(v, pIdx), 0); sqlite3ExprCacheAffinityChange(pParse, regIdx, pIdx->nColumn+1); /* Find out what action to take in case there is an indexing conflict */ @@ -71607,10 +74596,9 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( else if( onError==OE_Fail ) onError = OE_Abort; } - /* Check to see if the new index entry will be unique */ regR = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp2(v, OP_SCopy, regRowid-hasTwoRowids, regR); + sqlite3VdbeAddOp2(v, OP_SCopy, regOldRowid, regR); j3 = sqlite3VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0, regR, SQLITE_INT_TO_PTR(regIdx), P4_INT32); @@ -71640,7 +74628,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( sqlite3StrAccumAppend(&errMsg, pIdx->nColumn>1 ? " are not unique" : " is not unique", -1); zErr = sqlite3StrAccumFinish(&errMsg); - sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, zErr, 0); + sqlite3HaltConstraint(pParse, onError, zErr, 0); sqlite3DbFree(errMsg.db, zErr); break; } @@ -71650,8 +74638,15 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( break; } default: { + Trigger *pTrigger = 0; assert( onError==OE_Replace ); - sqlite3GenerateRowDelete(pParse, pTab, baseCur, regR, 0); + sqlite3MultiWrite(pParse); + if( pParse->db->flags&SQLITE_RecTriggers ){ + pTrigger = sqlite3TriggersExist(pParse, pTab, TK_DELETE, 0, 0); + } + sqlite3GenerateRowDelete( + pParse, pTab, baseCur, regR, 0, pTrigger, OE_Replace + ); seenReplace = 1; break; } @@ -71659,7 +74654,7 @@ SQLITE_PRIVATE void sqlite3GenerateConstraintChecks( sqlite3VdbeJumpHere(v, j3); sqlite3ReleaseTempReg(pParse, regR); } - + if( pbMayReplace ){ *pbMayReplace = seenReplace; } @@ -71681,7 +74676,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( int regRowid, /* Range of content */ int *aRegIdx, /* Register used by each index. 0 for unused indices */ int isUpdate, /* True for UPDATE, False for INSERT */ - int newIdx, /* Index of NEW table for triggers. -1 if none */ int appendBias, /* True if this is likely to be an append */ int useSeekResult /* True to set the USESEEKRESULT flag on OP_[Idx]Insert */ ){ @@ -71709,11 +74703,6 @@ SQLITE_PRIVATE void sqlite3CompleteInsertion( sqlite3VdbeAddOp3(v, OP_MakeRecord, regData, pTab->nCol, regRec); sqlite3TableAffinityStr(v, pTab); sqlite3ExprCacheAffinityChange(pParse, regData, pTab->nCol); -#ifndef SQLITE_OMIT_TRIGGER - if( newIdx>=0 ){ - sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRec, regRowid); - } -#endif if( pParse->nested ){ pik_flags = 0; }else{ @@ -72037,8 +75026,8 @@ static int xferOptimization( if( pDest->iPKey>=0 ){ addr1 = sqlite3VdbeAddOp2(v, OP_Rowid, iSrc, regRowid); addr2 = sqlite3VdbeAddOp3(v, OP_NotExists, iDest, 0, regRowid); - sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, onError, 0, - "PRIMARY KEY must be unique", P4_STATIC); + sqlite3HaltConstraint( + pParse, onError, "PRIMARY KEY must be unique", P4_STATIC); sqlite3VdbeJumpHere(v, addr2); autoIncStep(pParse, regAutoinc, regRowid); }else if( pDest->pIndex==0 ){ @@ -72052,7 +75041,6 @@ static int xferOptimization( sqlite3VdbeChangeP5(v, OPFLAG_NCHANGE|OPFLAG_LASTROWID|OPFLAG_APPEND); sqlite3VdbeChangeP4(v, -1, pDest->zName, 0); sqlite3VdbeAddOp2(v, OP_Next, iSrc, addr1); - autoIncEnd(pParse, iDbDest, pDest, regAutoinc); for(pDestIdx=pDest->pIndex; pDestIdx; pDestIdx=pDestIdx->pNext){ for(pSrcIdx=pSrc->pIndex; ALWAYS(pSrcIdx); pSrcIdx=pSrcIdx->pNext){ if( xferCompatibleIndex(pDestIdx, pSrcIdx) ) break; @@ -72090,11 +75078,6 @@ static int xferOptimization( } #endif /* SQLITE_OMIT_XFER_OPT */ -/* Make sure "isView" gets undefined in case this file becomes part of -** the amalgamation - so that subsequent files do not see isView as a -** macro. */ -#undef isView - /************** End of insert.c **********************************************/ /************** Begin file legacy.c ******************************************/ /* @@ -72113,7 +75096,7 @@ static int xferOptimization( ** other files are for internal use by SQLite and should not be ** accessed by users of the library. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ @@ -72230,6 +75213,9 @@ exec_out: *pzErrMsg = sqlite3Malloc(nErrMsg); if( *pzErrMsg ){ memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg); + }else{ + rc = SQLITE_NOMEM; + sqlite3Error(db, SQLITE_NOMEM, 0); } }else if( pzErrMsg ){ *pzErrMsg = 0; @@ -72256,7 +75242,7 @@ exec_out: ** This file contains code used to dynamically load extensions into ** the SQLite library. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef SQLITE_CORE @@ -72281,7 +75267,7 @@ exec_out: ** as extensions by SQLite should #include this file instead of ** sqlite3.h. ** -** @(#) $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** @(#) $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef _SQLITE3EXT_H_ #define _SQLITE3EXT_H_ @@ -73250,12 +76236,12 @@ SQLITE_PRIVATE void sqlite3AutoLoadExtensions(sqlite3 *db){ ************************************************************************* ** This file contains code used to implement the PRAGMA command. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* Ignore this whole file if pragmas are disabled */ -#if !defined(SQLITE_OMIT_PRAGMA) && !defined(SQLITE_OMIT_PARSER) +#if !defined(SQLITE_OMIT_PRAGMA) /* ** Interpret the given string as a safety level. Return 0 for OFF, @@ -73428,6 +76414,13 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ /* TODO: Maybe it shouldn't be possible to change the ReadUncommitted ** flag if there are any active statements. */ { "read_uncommitted", SQLITE_ReadUncommitted }, + { "recursive_triggers", SQLITE_RecTriggers }, + + /* This flag may only be set if both foreign-key and trigger support + ** are present in the build. */ +#if !defined(SQLITE_OMIT_FOREIGN_KEY) && !defined(SQLITE_OMIT_TRIGGER) + { "foreign_keys", SQLITE_ForeignKeys }, +#endif }; int i; const struct sPragmaType *p; @@ -73441,10 +76434,17 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ if( zRight==0 ){ returnSingleInt(pParse, p->zName, (db->flags & p->mask)!=0 ); }else{ + int mask = p->mask; /* Mask of bits to set or clear. */ + if( db->autoCommit==0 ){ + /* Foreign key support may not be enabled or disabled while not + ** in auto-commit mode. */ + mask &= ~(SQLITE_ForeignKeys); + } + if( getBoolean(zRight) ){ - db->flags |= p->mask; + db->flags |= mask; }else{ - db->flags &= ~p->mask; + db->flags &= ~mask; } /* Many of the flag-pragmas modify the code generated by the SQL @@ -73465,17 +76465,20 @@ static int flagPragma(Parse *pParse, const char *zLeft, const char *zRight){ /* ** Return a human-readable name for a constraint resolution action. */ +#ifndef SQLITE_OMIT_FOREIGN_KEY static const char *actionName(u8 action){ const char *zName; switch( action ){ - case OE_SetNull: zName = "SET NULL"; break; - case OE_SetDflt: zName = "SET DEFAULT"; break; - case OE_Cascade: zName = "CASCADE"; break; - default: zName = "RESTRICT"; - assert( action==OE_Restrict ); break; + case OE_SetNull: zName = "SET NULL"; break; + case OE_SetDflt: zName = "SET DEFAULT"; break; + case OE_Cascade: zName = "CASCADE"; break; + case OE_Restrict: zName = "RESTRICT"; break; + default: zName = "NO ACTION"; + assert( action==OE_None ); break; } return zName; } +#endif /* ** Process a pragma statement. @@ -73556,12 +76559,13 @@ SQLITE_PRIVATE void sqlite3Pragma( */ if( sqlite3StrICmp(zLeft,"default_cache_size")==0 ){ static const VdbeOpList getCacheSize[] = { - { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 0 */ - { OP_IfPos, 1, 6, 0}, + { OP_Transaction, 0, 0, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, BTREE_DEFAULT_CACHE_SIZE}, /* 1 */ + { OP_IfPos, 1, 7, 0}, { OP_Integer, 0, 2, 0}, { OP_Subtract, 1, 2, 1}, - { OP_IfPos, 1, 6, 0}, - { OP_Integer, 0, 1, 0}, /* 5 */ + { OP_IfPos, 1, 7, 0}, + { OP_Integer, 0, 1, 0}, /* 6 */ { OP_ResultRow, 1, 1, 0}, }; int addr; @@ -73573,7 +76577,8 @@ SQLITE_PRIVATE void sqlite3Pragma( pParse->nMem += 2; addr = sqlite3VdbeAddOpList(v, ArraySize(getCacheSize), getCacheSize); sqlite3VdbeChangeP1(v, addr, iDb); - sqlite3VdbeChangeP1(v, addr+5, SQLITE_DEFAULT_CACHE_SIZE); + sqlite3VdbeChangeP1(v, addr+1, iDb); + sqlite3VdbeChangeP1(v, addr+6, SQLITE_DEFAULT_CACHE_SIZE); }else{ int size = atoi(zRight); if( size<0 ) size = -size; @@ -74200,8 +77205,8 @@ SQLITE_PRIVATE void sqlite3Pragma( int j; for(j=0; jnCol; j++){ char *zCol = pFK->aCol[j].zCol; - char *zOnUpdate = (char *)actionName(pFK->updateConf); - char *zOnDelete = (char *)actionName(pFK->deleteConf); + char *zOnDelete = (char *)actionName(pFK->aAction[0]); + char *zOnUpdate = (char *)actionName(pFK->aAction[1]); sqlite3VdbeAddOp2(v, OP_Integer, i, 1); sqlite3VdbeAddOp2(v, OP_Integer, j, 2); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, pFK->zTo, 0); @@ -74540,12 +77545,14 @@ SQLITE_PRIVATE void sqlite3Pragma( }else{ /* Read the specified cookie value */ static const VdbeOpList readCookie[] = { - { OP_ReadCookie, 0, 1, 0}, /* 0 */ + { OP_Transaction, 0, 0, 0}, /* 0 */ + { OP_ReadCookie, 0, 1, 0}, /* 1 */ { OP_ResultRow, 1, 1, 0} }; int addr = sqlite3VdbeAddOpList(v, ArraySize(readCookie), readCookie); sqlite3VdbeChangeP1(v, addr, iDb); - sqlite3VdbeChangeP3(v, addr, iCookie); + sqlite3VdbeChangeP1(v, addr+1, iDb); + sqlite3VdbeChangeP3(v, addr+1, iCookie); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, zLeft, SQLITE_TRANSIENT); } @@ -74586,17 +77593,6 @@ SQLITE_PRIVATE void sqlite3Pragma( }else #endif -#ifdef SQLITE_SSE - /* - ** Check to see if the sqlite_statements table exists. Create it - ** if it does not. - */ - if( sqlite3StrICmp(zLeft, "create_sqlite_statement_table")==0 ){ - extern int sqlite3CreateStatementsTable(Parse*); - sqlite3CreateStatementsTable(pParse); - }else -#endif - #if SQLITE_HAS_CODEC if( sqlite3StrICmp(zLeft, "key")==0 && zRight ){ sqlite3_key(db, zRight, sqlite3Strlen30(zRight)); @@ -74661,7 +77657,7 @@ pragma_out: sqlite3DbFree(db, zRight); } -#endif /* SQLITE_OMIT_PRAGMA || SQLITE_OMIT_PARSER */ +#endif /* SQLITE_OMIT_PRAGMA */ /************** End of pragma.c **********************************************/ /************** Begin file prepare.c *****************************************/ @@ -74680,7 +77676,7 @@ pragma_out: ** interface, and routines that contribute to loading the database schema ** from disk. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -74695,14 +77691,14 @@ static void corruptSchema( sqlite3 *db = pData->db; if( !db->mallocFailed && (db->flags & SQLITE_RecoveryMode)==0 ){ if( zObj==0 ) zObj = "?"; - sqlite3SetString(pData->pzErrMsg, pData->db, - "malformed database schema (%s)", zObj); - if( zExtra && zExtra[0] ){ - *pData->pzErrMsg = sqlite3MAppendf(pData->db, *pData->pzErrMsg, "%s - %s", - *pData->pzErrMsg, zExtra); + sqlite3SetString(pData->pzErrMsg, db, + "malformed database schema (%s)", zObj); + if( zExtra ){ + *pData->pzErrMsg = sqlite3MAppendf(db, *pData->pzErrMsg, + "%s - %s", *pData->pzErrMsg, zExtra); } } - pData->rc = SQLITE_CORRUPT; + pData->rc = db->mallocFailed ? SQLITE_NOMEM : SQLITE_CORRUPT; } /* @@ -74728,7 +77724,7 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char DbClearProperty(db, iDb, DB_Empty); if( db->mallocFailed ){ corruptSchema(pData, argv[0], 0); - return SQLITE_NOMEM; + return 1; } assert( iDb>=0 && iDbnDb ); @@ -74746,15 +77742,20 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char assert( db->init.busy ); db->init.iDb = iDb; db->init.newTnum = atoi(argv[1]); + db->init.orphanTrigger = 0; rc = sqlite3_exec(db, argv[2], 0, 0, &zErr); db->init.iDb = 0; assert( rc!=SQLITE_OK || zErr==0 ); if( SQLITE_OK!=rc ){ - pData->rc = rc; - if( rc==SQLITE_NOMEM ){ - db->mallocFailed = 1; - }else if( rc!=SQLITE_INTERRUPT && (rc&0xff)!=SQLITE_LOCKED ){ - corruptSchema(pData, argv[0], zErr); + if( db->init.orphanTrigger ){ + assert( iDb==1 ); + }else{ + pData->rc = rc; + if( rc==SQLITE_NOMEM ){ + db->mallocFailed = 1; + }else if( rc!=SQLITE_INTERRUPT && rc!=SQLITE_LOCKED ){ + corruptSchema(pData, argv[0], zErr); + } } sqlite3DbFree(db, zErr); } @@ -74769,15 +77770,15 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char */ Index *pIndex; pIndex = sqlite3FindIndex(db, argv[0], db->aDb[iDb].zName); - if( pIndex==0 || pIndex->tnum!=0 ){ + if( pIndex==0 ){ /* This can occur if there exists an index on a TEMP table which ** has the same name as another index on a permanent index. Since ** the permanent table is hidden by the TEMP table, we can also ** safely ignore the index on the permanent table. */ /* Do Nothing */; - }else{ - pIndex->tnum = atoi(argv[1]); + }else if( sqlite3GetInt32(argv[1], &pIndex->tnum)==0 ){ + corruptSchema(pData, argv[0], "invalid rootpage"); } } return 0; @@ -74794,7 +77795,6 @@ SQLITE_PRIVATE int sqlite3InitCallback(void *pInit, int argc, char **argv, char static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ int rc; int i; - BtCursor *curMain; int size; Table *pTab; Db *pDb; @@ -74803,6 +77803,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ InitData initData; char const *zMasterSchema; char const *zMasterName = SCHEMA_TABLE(iDb); + int openedTransaction = 0; /* ** The master database table has a structure like this @@ -74863,7 +77864,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ goto error_out; } pTab = sqlite3FindTable(db, zMasterName, db->aDb[iDb].zName); - if( pTab ){ + if( ALWAYS(pTab) ){ pTab->tabFlags |= TF_Readonly; } @@ -74871,19 +77872,24 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ */ pDb = &db->aDb[iDb]; if( pDb->pBt==0 ){ - if( !OMIT_TEMPDB && iDb==1 ){ + if( !OMIT_TEMPDB && ALWAYS(iDb==1) ){ DbSetProperty(db, 1, DB_SchemaLoaded); } return SQLITE_OK; } - curMain = sqlite3MallocZero(sqlite3BtreeCursorSize()); - if( !curMain ){ - rc = SQLITE_NOMEM; - goto error_out; - } + + /* If there is not already a read-only (or read-write) transaction opened + ** on the b-tree database, open one now. If a transaction is opened, it + ** will be closed before this function returns. */ sqlite3BtreeEnter(pDb->pBt); - rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, curMain); - if( rc==SQLITE_EMPTY ) rc = SQLITE_OK; + if( !sqlite3BtreeIsInReadTrans(pDb->pBt) ){ + rc = sqlite3BtreeBeginTrans(pDb->pBt, 0); + if( rc!=SQLITE_OK ){ + sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc)); + goto initone_error_out; + } + openedTransaction = 1; + } /* Get the database meta information. ** @@ -74891,18 +77897,19 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ ** meta[0] Schema cookie. Changes with each schema change. ** meta[1] File format of schema layer. ** meta[2] Size of the page cache. - ** meta[3] Use freelist if 0. Autovacuum if greater than zero. + ** meta[3] Largest rootpage (auto/incr_vacuum mode) ** meta[4] Db text encoding. 1:UTF-8 2:UTF-16LE 3:UTF-16BE + ** meta[5] User version + ** meta[6] Incremental vacuum mode + ** meta[7] unused + ** meta[8] unused + ** meta[9] unused ** ** Note: The #defined SQLITE_UTF* symbols in sqliteInt.h correspond to ** the possible values of meta[4]. */ - for(i=0; rc==SQLITE_OK && ipBt, i+1, (u32 *)&meta[i]); - } - if( rc ){ - sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc)); - goto initone_error_out; + for(i=0; ipBt, i+1, (u32 *)&meta[i]); } pDb->pSchema->schema_cookie = meta[BTREE_SCHEMA_VERSION-1]; @@ -74969,10 +77976,7 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ /* Read the schema information out of the schema tables */ assert( db->init.busy ); - if( rc==SQLITE_EMPTY ){ - /* For an empty database, there is nothing to read */ - rc = SQLITE_OK; - }else{ + { char *zSql; zSql = sqlite3MPrintf(db, "SELECT name, rootpage, sql FROM '%q'.%s", @@ -75020,8 +78024,9 @@ static int sqlite3InitOne(sqlite3 *db, int iDb, char **pzErrMsg){ ** before that point, jump to error_out. */ initone_error_out: - sqlite3BtreeCloseCursor(curMain); - sqlite3_free(curMain); + if( openedTransaction ){ + sqlite3BtreeCommit(pDb->pBt); + } sqlite3BtreeLeave(pDb->pBt); error_out: @@ -75046,7 +78051,6 @@ SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){ int commit_internal = !(db->flags&SQLITE_InternChanges); assert( sqlite3_mutex_held(db->mutex) ); - if( db->init.busy ) return SQLITE_OK; rc = SQLITE_OK; db->init.busy = 1; for(i=0; rc==SQLITE_OK && inDb; i++){ @@ -75062,7 +78066,8 @@ SQLITE_PRIVATE int sqlite3Init(sqlite3 *db, char **pzErrMsg){ ** schema may contain references to objects in other databases. */ #ifndef SQLITE_OMIT_TEMPDB - if( rc==SQLITE_OK && db->nDb>1 && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ + if( rc==SQLITE_OK && ALWAYS(db->nDb>1) + && !DbHasProperty(db, 1, DB_SchemaLoaded) ){ rc = sqlite3InitOne(db, 1, pzErrMsg); if( rc ){ sqlite3ResetInternalSchema(db, 1); @@ -75099,42 +78104,47 @@ SQLITE_PRIVATE int sqlite3ReadSchema(Parse *pParse){ /* ** Check schema cookies in all databases. If any cookie is out -** of date, return 0. If all schema cookies are current, return 1. +** of date set pParse->rc to SQLITE_SCHEMA. If all schema cookies +** make no changes to pParse->rc. */ -static int schemaIsValid(sqlite3 *db){ +static void schemaIsValid(Parse *pParse){ + sqlite3 *db = pParse->db; int iDb; int rc; - BtCursor *curTemp; int cookie; - int allOk = 1; - curTemp = (BtCursor *)sqlite3Malloc(sqlite3BtreeCursorSize()); - if( curTemp ){ - assert( sqlite3_mutex_held(db->mutex) ); - for(iDb=0; allOk && iDbnDb; iDb++){ - Btree *pBt; - pBt = db->aDb[iDb].pBt; - if( pBt==0 ) continue; - memset(curTemp, 0, sqlite3BtreeCursorSize()); - rc = sqlite3BtreeCursor(pBt, MASTER_ROOT, 0, 0, curTemp); - if( rc==SQLITE_OK ){ - rc = sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); - if( rc==SQLITE_OK && cookie!=db->aDb[iDb].pSchema->schema_cookie ){ - allOk = 0; - } - sqlite3BtreeCloseCursor(curTemp); - } + assert( pParse->checkSchema ); + assert( sqlite3_mutex_held(db->mutex) ); + for(iDb=0; iDbnDb; iDb++){ + int openedTransaction = 0; /* True if a transaction is opened */ + Btree *pBt = db->aDb[iDb].pBt; /* Btree database to read cookie from */ + if( pBt==0 ) continue; + + /* If there is not already a read-only (or read-write) transaction opened + ** on the b-tree database, open one now. If a transaction is opened, it + ** will be closed immediately after reading the meta-value. */ + if( !sqlite3BtreeIsInReadTrans(pBt) ){ + rc = sqlite3BtreeBeginTrans(pBt, 0); if( rc==SQLITE_NOMEM || rc==SQLITE_IOERR_NOMEM ){ db->mallocFailed = 1; } + if( rc!=SQLITE_OK ) return; + openedTransaction = 1; + } + + /* Read the schema cookie from the database. If it does not match the + ** value stored as part of the in the in-memory schema representation, + ** set Parse.rc to SQLITE_SCHEMA. */ + sqlite3BtreeGetMeta(pBt, BTREE_SCHEMA_VERSION, (u32 *)&cookie); + if( cookie!=db->aDb[iDb].pSchema->schema_cookie ){ + pParse->rc = SQLITE_SCHEMA; } - sqlite3_free(curTemp); - }else{ - allOk = 0; - db->mallocFailed = 1; - } - return allOk; + /* Close the transaction, if one was opened. */ + if( openedTransaction ){ + sqlite3BtreeCommit(pBt); + } + } } /* @@ -75238,11 +78248,14 @@ static int sqlite3Prepare( } } + sqlite3VtabUnlockList(db); pParse->db = db; if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){ char *zSqlCopy; int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH]; + testcase( nBytes==mxLen ); + testcase( nBytes==mxLen+1 ); if( nBytes>mxLen ){ sqlite3Error(db, SQLITE_TOOBIG, "statement too long"); (void)sqlite3SafetyOff(db); @@ -75265,8 +78278,8 @@ static int sqlite3Prepare( pParse->rc = SQLITE_NOMEM; } if( pParse->rc==SQLITE_DONE ) pParse->rc = SQLITE_OK; - if( pParse->checkSchema && !schemaIsValid(db) ){ - pParse->rc = SQLITE_SCHEMA; + if( pParse->checkSchema ){ + schemaIsValid(pParse); } if( pParse->rc==SQLITE_SCHEMA ){ sqlite3ResetInternalSchema(db, 0); @@ -75325,6 +78338,14 @@ static int sqlite3Prepare( sqlite3Error(db, rc, 0); } + /* Delete any TriggerPrg structures allocated while parsing this statement. */ + while( pParse->pTriggerPrg ){ + TriggerPrg *pT = pParse->pTriggerPrg; + pParse->pTriggerPrg = pT->pNext; + sqlite3VdbeProgramDelete(db, pT->pProgram, 0); + sqlite3DbFree(db, pT); + } + end_prepare: sqlite3StackFree(db, pParse); @@ -75349,6 +78370,10 @@ static int sqlite3LockAndPrepare( sqlite3_mutex_enter(db->mutex); sqlite3BtreeEnterAll(db); rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail); + if( rc==SQLITE_SCHEMA ){ + sqlite3_finalize(*ppStmt); + rc = sqlite3Prepare(db, zSql, nBytes, saveSqlFlag, ppStmt, pzTail); + } sqlite3BtreeLeaveAll(db); sqlite3_mutex_leave(db->mutex); return rc; @@ -75522,7 +78547,7 @@ SQLITE_API int sqlite3_prepare16_v2( ** This file contains C code routines that are called by the parser ** to handle SELECT statements in SQLite. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ @@ -76275,14 +79300,16 @@ static void generateSortTail( int regRowid; iTab = pOrderBy->iECursor; + regRow = sqlite3GetTempReg(pParse); if( eDest==SRT_Output || eDest==SRT_Coroutine ){ pseudoTab = pParse->nTab++; - sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, eDest==SRT_Output, nColumn); + sqlite3VdbeAddOp3(v, OP_OpenPseudo, pseudoTab, regRow, nColumn); + regRowid = 0; + }else{ + regRowid = sqlite3GetTempReg(pParse); } addr = 1 + sqlite3VdbeAddOp2(v, OP_Sort, iTab, addrBreak); codeOffset(v, p, addrContinue); - regRow = sqlite3GetTempReg(pParse); - regRowid = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp3(v, OP_Column, iTab, pOrderBy->nExpr + 1, regRow); switch( eDest ){ case SRT_Table: @@ -76314,11 +79341,12 @@ static void generateSortTail( assert( eDest==SRT_Output || eDest==SRT_Coroutine ); testcase( eDest==SRT_Output ); testcase( eDest==SRT_Coroutine ); - sqlite3VdbeAddOp2(v, OP_Integer, 1, regRowid); - sqlite3VdbeAddOp3(v, OP_Insert, pseudoTab, regRow, regRowid); for(i=0; iiMem+i ); sqlite3VdbeAddOp3(v, OP_Column, pseudoTab, i, pDest->iMem+i); + if( i==0 ){ + sqlite3VdbeChangeP5(v, OPFLAG_CLEARCACHE); + } } if( eDest==SRT_Output ){ sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn); @@ -76402,21 +79430,27 @@ static const char *columnType( } if( pTab==0 ){ - /* FIX ME: - ** This can occurs if you have something like "SELECT new.x;" inside - ** a trigger. In other words, if you reference the special "new" - ** table in the result set of a select. We do not have a good way - ** to find the actual table type, so call it "TEXT". This is really - ** something of a bug, but I do not know how to fix it. + /* At one time, code such as "SELECT new.x" within a trigger would + ** cause this condition to run. Since then, we have restructured how + ** trigger code is generated and so this condition is no longer + ** possible. However, it can still be true for statements like + ** the following: ** - ** This code does not produce the correct answer - it just prevents - ** a segfault. See ticket #1229. - */ - zType = "TEXT"; + ** CREATE TABLE t1(col INTEGER); + ** SELECT (SELECT t1.col) FROM FROM t1; + ** + ** when columnType() is called on the expression "t1.col" in the + ** sub-select. In this case, set the column type to NULL, even + ** though it should really be "INTEGER". + ** + ** This is not a problem, as the column type of "t1.col" is never + ** used. When columnType() is called on the expression + ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT + ** branch below. */ break; } - assert( pTab ); + assert( pTab && pExpr->pTab==pTab ); if( pS ){ /* The "table" is actually a sub-select or a view in the FROM clause ** of the SELECT statement. Return the declaration type and origin @@ -76430,7 +79464,7 @@ static const char *columnType( NameContext sNC; Expr *p = pS->pEList->a[iCol].pExpr; sNC.pSrcList = pS->pSrc; - sNC.pNext = 0; + sNC.pNext = pNC; sNC.pParse = pNC->pParse; zType = columnType(&sNC, p, &zOriginDb, &zOriginTab, &zOriginCol); } @@ -77864,6 +80898,9 @@ static Expr *substExpr( assert( pEList!=0 && pExpr->iColumnnExpr ); assert( pExpr->pLeft==0 && pExpr->pRight==0 ); pNew = sqlite3ExprDup(db, pEList->a[pExpr->iColumn].pExpr, 0); + if( pNew && pExpr->pColl ){ + pNew->pColl = pExpr->pColl; + } sqlite3ExprDelete(db, pExpr); pExpr = pNew; } @@ -78240,8 +81277,9 @@ static int flattenSubquery( if( ALWAYS(pSubitem->pTab!=0) ){ Table *pTabToDel = pSubitem->pTab; if( pTabToDel->nRef==1 ){ - pTabToDel->pNextZombie = pParse->pZombieTab; - pParse->pZombieTab = pTabToDel; + Parse *pToplevel = sqlite3ParseToplevel(pParse); + pTabToDel->pNextZombie = pToplevel->pZombieTab; + pToplevel->pZombieTab = pTabToDel; }else{ pTabToDel->nRef--; } @@ -79757,7 +82795,7 @@ SQLITE_PRIVATE void sqlite3PrintSelect(Select *p, int indent){ ** These routines are in a separate files so that they will not be linked ** if they are not used. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef SQLITE_OMIT_GET_TABLE @@ -79950,7 +82988,7 @@ SQLITE_API void sqlite3_free_table( ************************************************************************* ** ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef SQLITE_OMIT_TRIGGER @@ -79989,6 +83027,10 @@ SQLITE_PRIVATE Trigger *sqlite3TriggerList(Parse *pParse, Table *pTab){ Schema * const pTmpSchema = pParse->db->aDb[1].pSchema; Trigger *pList = 0; /* List of triggers to return */ + if( pParse->disableTriggers ){ + return 0; + } + if( pTmpSchema!=pTab->pSchema ){ HashElem *p; for(p=sqliteHashFirst(&pTmpSchema->trigHash); p; p=sqliteHashNext(p)){ @@ -80025,14 +83067,14 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( int isTemp, /* True if the TEMPORARY keyword is present */ int noErr /* Suppress errors if the trigger already exists */ ){ - Trigger *pTrigger = 0; - Table *pTab; + Trigger *pTrigger = 0; /* The new trigger */ + Table *pTab; /* Table that the trigger fires off of */ char *zName = 0; /* Name of the trigger */ - sqlite3 *db = pParse->db; + sqlite3 *db = pParse->db; /* The database connection */ int iDb; /* The database to store the trigger in */ Token *pName; /* The unqualified db name */ - DbFixer sFix; - int iTabDb; + DbFixer sFix; /* State vector for the DB fixer */ + int iTabDb; /* Index of the database holding pTab */ assert( pName1!=0 ); /* pName1->z might be NULL, but not pName1 itself */ assert( pName2!=0 ); @@ -80077,6 +83119,17 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( pTab = sqlite3SrcListLookup(pParse, pTableName); if( !pTab ){ /* The table does not exist. */ + if( db->init.iDb==1 ){ + /* Ticket #3810. + ** Normally, whenever a table is dropped, all associated triggers are + ** dropped too. But if a TEMP trigger is created on a non-TEMP table + ** and the table is dropped by a different database connection, the + ** trigger is not visible to the database connection that does the + ** drop so the trigger cannot be dropped. This results in an + ** "orphaned trigger" - a trigger whose associated table is missing. + */ + db->init.orphanTrigger = 1; + } goto trigger_cleanup; } if( IsVirtual(pTab) ){ @@ -80147,7 +83200,7 @@ SQLITE_PRIVATE void sqlite3BeginTrigger( /* Build the Trigger object */ pTrigger = (Trigger*)sqlite3DbMallocZero(db, sizeof(Trigger)); if( pTrigger==0 ) goto trigger_cleanup; - pTrigger->name = zName; + pTrigger->zName = zName; zName = 0; pTrigger->table = sqlite3DbStrDup(db, pTableName->a[0].zName); pTrigger->pSchema = db->aDb[iDb].pSchema; @@ -80190,14 +83243,14 @@ SQLITE_PRIVATE void sqlite3FinishTrigger( pTrig = pParse->pNewTrigger; pParse->pNewTrigger = 0; if( NEVER(pParse->nErr) || !pTrig ) goto triggerfinish_cleanup; - zName = pTrig->name; + zName = pTrig->zName; iDb = sqlite3SchemaToIndex(pParse->db, pTrig->pSchema); pTrig->step_list = pStepList; while( pStepList ){ pStepList->pTrig = pTrig; pStepList = pStepList->pNext; } - nameToken.z = pTrig->name; + nameToken.z = pTrig->zName; nameToken.n = sqlite3Strlen30(nameToken.z); if( sqlite3FixInit(&sFix, pParse, iDb, "trigger", &nameToken) && sqlite3FixTriggerStep(&sFix, pTrig->step_list) ){ @@ -80276,7 +83329,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerSelectStep(sqlite3 *db, Select *pSelec */ static TriggerStep *triggerStepAllocate( sqlite3 *db, /* Database connection */ - int op, /* Trigger opcode */ + u8 op, /* Trigger opcode */ Token *pName /* The target name */ ){ TriggerStep *pTriggerStep; @@ -80305,7 +83358,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerInsertStep( IdList *pColumn, /* List of columns in pTableName to insert into */ ExprList *pEList, /* The VALUE clause: a list of values to be inserted */ Select *pSelect, /* A SELECT statement that supplies values */ - int orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ + u8 orconf /* The conflict algorithm (OE_Abort, OE_Replace, etc.) */ ){ TriggerStep *pTriggerStep; @@ -80337,7 +83390,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerUpdateStep( Token *pTableName, /* Name of the table to be updated */ ExprList *pEList, /* The SET clause: list of column and new values */ Expr *pWhere, /* The WHERE clause */ - int orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ + u8 orconf /* The conflict algorithm. (OE_Abort, OE_Ignore, etc) */ ){ TriggerStep *pTriggerStep; @@ -80379,7 +83432,7 @@ SQLITE_PRIVATE TriggerStep *sqlite3TriggerDeleteStep( SQLITE_PRIVATE void sqlite3DeleteTrigger(sqlite3 *db, Trigger *pTrigger){ if( pTrigger==0 ) return; sqlite3DeleteTriggerStep(db, pTrigger->step_list); - sqlite3DbFree(db, pTrigger->name); + sqlite3DbFree(db, pTrigger->zName); sqlite3DbFree(db, pTrigger->table); sqlite3ExprDelete(db, pTrigger->pWhen); sqlite3IdListDelete(db, pTrigger->pColumns); @@ -80459,7 +83512,7 @@ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ const char *zDb = db->aDb[iDb].zName; const char *zTab = SCHEMA_TABLE(iDb); if( iDb==1 ) code = SQLITE_DROP_TEMP_TRIGGER; - if( sqlite3AuthCheck(pParse, code, pTrigger->name, pTable->zName, zDb) || + if( sqlite3AuthCheck(pParse, code, pTrigger->zName, pTable->zName, zDb) || sqlite3AuthCheck(pParse, SQLITE_DELETE, zTab, 0, zDb) ){ return; } @@ -80486,11 +83539,11 @@ SQLITE_PRIVATE void sqlite3DropTriggerPtr(Parse *pParse, Trigger *pTrigger){ sqlite3BeginWriteOperation(pParse, 0, iDb); sqlite3OpenMasterTable(pParse, iDb); base = sqlite3VdbeAddOpList(v, ArraySize(dropTrigger), dropTrigger); - sqlite3VdbeChangeP4(v, base+1, pTrigger->name, 0); + sqlite3VdbeChangeP4(v, base+1, pTrigger->zName, 0); sqlite3VdbeChangeP4(v, base+4, "trigger", P4_STATIC); sqlite3ChangeCookie(pParse, iDb); sqlite3VdbeAddOp2(v, OP_Close, 0, 0); - sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->name, 0); + sqlite3VdbeAddOp4(v, OP_DropTrigger, iDb, 0, 0, pTrigger->zName, 0); if( pParse->nMem<3 ){ pParse->nMem = 3; } @@ -80594,209 +83647,412 @@ static SrcList *targetSrcList( } /* -** Generate VDBE code for zero or more statements inside the body of a -** trigger. +** Generate VDBE code for the statements inside the body of a single +** trigger. */ static int codeTriggerProgram( Parse *pParse, /* The parser context */ TriggerStep *pStepList, /* List of statements inside the trigger body */ - int orconfin /* Conflict algorithm. (OE_Abort, etc) */ + int orconf /* Conflict algorithm. (OE_Abort, etc) */ ){ - TriggerStep * pTriggerStep = pStepList; - int orconf; + TriggerStep *pStep; Vdbe *v = pParse->pVdbe; sqlite3 *db = pParse->db; - assert( pTriggerStep!=0 ); + assert( pParse->pTriggerTab && pParse->pToplevel ); + assert( pStepList ); assert( v!=0 ); - sqlite3VdbeAddOp2(v, OP_ContextPush, 0, 0); - VdbeComment((v, "begin trigger %s", pStepList->pTrig->name)); - while( pTriggerStep ){ - sqlite3ExprCacheClear(pParse); - orconf = (orconfin == OE_Default)?pTriggerStep->orconf:orconfin; - pParse->trigStack->orconf = orconf; - switch( pTriggerStep->op ){ + for(pStep=pStepList; pStep; pStep=pStep->pNext){ + /* Figure out the ON CONFLICT policy that will be used for this step + ** of the trigger program. If the statement that caused this trigger + ** to fire had an explicit ON CONFLICT, then use it. Otherwise, use + ** the ON CONFLICT policy that was specified as part of the trigger + ** step statement. Example: + ** + ** CREATE TRIGGER AFTER INSERT ON t1 BEGIN; + ** INSERT OR REPLACE INTO t2 VALUES(new.a, new.b); + ** END; + ** + ** INSERT INTO t1 ... ; -- insert into t2 uses REPLACE policy + ** INSERT OR IGNORE INTO t1 ... ; -- insert into t2 uses IGNORE policy + */ + pParse->eOrconf = (orconf==OE_Default)?pStep->orconf:(u8)orconf; + + switch( pStep->op ){ case TK_UPDATE: { - SrcList *pSrc; - pSrc = targetSrcList(pParse, pTriggerStep); - sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0); - sqlite3Update(pParse, pSrc, - sqlite3ExprListDup(db, pTriggerStep->pExprList, 0), - sqlite3ExprDup(db, pTriggerStep->pWhere, 0), orconf); - sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0); + sqlite3Update(pParse, + targetSrcList(pParse, pStep), + sqlite3ExprListDup(db, pStep->pExprList, 0), + sqlite3ExprDup(db, pStep->pWhere, 0), + pParse->eOrconf + ); break; } case TK_INSERT: { - SrcList *pSrc; - pSrc = targetSrcList(pParse, pTriggerStep); - sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0); - sqlite3Insert(pParse, pSrc, - sqlite3ExprListDup(db, pTriggerStep->pExprList, 0), - sqlite3SelectDup(db, pTriggerStep->pSelect, 0), - sqlite3IdListDup(db, pTriggerStep->pIdList), orconf); - sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0); + sqlite3Insert(pParse, + targetSrcList(pParse, pStep), + sqlite3ExprListDup(db, pStep->pExprList, 0), + sqlite3SelectDup(db, pStep->pSelect, 0), + sqlite3IdListDup(db, pStep->pIdList), + pParse->eOrconf + ); break; } case TK_DELETE: { - SrcList *pSrc; - sqlite3VdbeAddOp2(v, OP_ResetCount, 0, 0); - pSrc = targetSrcList(pParse, pTriggerStep); - sqlite3DeleteFrom(pParse, pSrc, - sqlite3ExprDup(db, pTriggerStep->pWhere, 0)); - sqlite3VdbeAddOp2(v, OP_ResetCount, 1, 0); + sqlite3DeleteFrom(pParse, + targetSrcList(pParse, pStep), + sqlite3ExprDup(db, pStep->pWhere, 0) + ); break; } - default: assert( pTriggerStep->op==TK_SELECT ); { - Select *ss = sqlite3SelectDup(db, pTriggerStep->pSelect, 0); - if( ss ){ - SelectDest dest; - - sqlite3SelectDestInit(&dest, SRT_Discard, 0); - sqlite3Select(pParse, ss, &dest); - sqlite3SelectDelete(db, ss); - } + default: assert( pStep->op==TK_SELECT ); { + SelectDest sDest; + Select *pSelect = sqlite3SelectDup(db, pStep->pSelect, 0); + sqlite3SelectDestInit(&sDest, SRT_Discard, 0); + sqlite3Select(pParse, pSelect, &sDest); + sqlite3SelectDelete(db, pSelect); break; } } - pTriggerStep = pTriggerStep->pNext; + if( pStep->op!=TK_SELECT ){ + sqlite3VdbeAddOp0(v, OP_ResetCount); + } } - sqlite3VdbeAddOp2(v, OP_ContextPop, 0, 0); - VdbeComment((v, "end trigger %s", pStepList->pTrig->name)); return 0; } +#ifdef SQLITE_DEBUG /* -** This is called to code FOR EACH ROW triggers. -** -** When the code that this function generates is executed, the following -** must be true: -** -** 1. No cursors may be open in the main database. (But newIdx and oldIdx -** can be indices of cursors in temporary tables. See below.) -** -** 2. If the triggers being coded are ON INSERT or ON UPDATE triggers, then -** a temporary vdbe cursor (index newIdx) must be open and pointing at -** a row containing values to be substituted for new.* expressions in the -** trigger program(s). -** -** 3. If the triggers being coded are ON DELETE or ON UPDATE triggers, then -** a temporary vdbe cursor (index oldIdx) must be open and pointing at -** a row containing values to be substituted for old.* expressions in the -** trigger program(s). -** -** If they are not NULL, the piOldColMask and piNewColMask output variables -** are set to values that describe the columns used by the trigger program -** in the OLD.* and NEW.* tables respectively. If column N of the -** pseudo-table is read at least once, the corresponding bit of the output -** mask is set. If a column with an index greater than 32 is read, the -** output mask is set to the special value 0xffffffff. -** +** This function is used to add VdbeComment() annotations to a VDBE +** program. It is not used in production code, only for debugging. */ -SQLITE_PRIVATE int sqlite3CodeRowTrigger( +static const char *onErrorText(int onError){ + switch( onError ){ + case OE_Abort: return "abort"; + case OE_Rollback: return "rollback"; + case OE_Fail: return "fail"; + case OE_Replace: return "replace"; + case OE_Ignore: return "ignore"; + case OE_Default: return "default"; + } + return "n/a"; +} +#endif + +/* +** Parse context structure pFrom has just been used to create a sub-vdbe +** (trigger program). If an error has occurred, transfer error information +** from pFrom to pTo. +*/ +static void transferParseError(Parse *pTo, Parse *pFrom){ + assert( pFrom->zErrMsg==0 || pFrom->nErr ); + assert( pTo->zErrMsg==0 || pTo->nErr ); + if( pTo->nErr==0 ){ + pTo->zErrMsg = pFrom->zErrMsg; + pTo->nErr = pFrom->nErr; + }else{ + sqlite3DbFree(pFrom->db, pFrom->zErrMsg); + } +} + +/* +** Create and populate a new TriggerPrg object with a sub-program +** implementing trigger pTrigger with ON CONFLICT policy orconf. +*/ +static TriggerPrg *codeRowTrigger( + Parse *pParse, /* Current parse context */ + Trigger *pTrigger, /* Trigger to code */ + Table *pTab, /* The table pTrigger is attached to */ + int orconf /* ON CONFLICT policy to code trigger program with */ +){ + Parse *pTop = sqlite3ParseToplevel(pParse); + sqlite3 *db = pParse->db; /* Database handle */ + TriggerPrg *pPrg; /* Value to return */ + Expr *pWhen = 0; /* Duplicate of trigger WHEN expression */ + Vdbe *v; /* Temporary VM */ + NameContext sNC; /* Name context for sub-vdbe */ + SubProgram *pProgram = 0; /* Sub-vdbe for trigger program */ + Parse *pSubParse; /* Parse context for sub-vdbe */ + int iEndTrigger = 0; /* Label to jump to if WHEN is false */ + + assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); + + /* Allocate the TriggerPrg and SubProgram objects. To ensure that they + ** are freed if an error occurs, link them into the Parse.pTriggerPrg + ** list of the top-level Parse object sooner rather than later. */ + pPrg = sqlite3DbMallocZero(db, sizeof(TriggerPrg)); + if( !pPrg ) return 0; + pPrg->pNext = pTop->pTriggerPrg; + pTop->pTriggerPrg = pPrg; + pPrg->pProgram = pProgram = sqlite3DbMallocZero(db, sizeof(SubProgram)); + if( !pProgram ) return 0; + pProgram->nRef = 1; + pPrg->pTrigger = pTrigger; + pPrg->orconf = orconf; + pPrg->oldmask = 0xffffffff; + + /* Allocate and populate a new Parse context to use for coding the + ** trigger sub-program. */ + pSubParse = sqlite3StackAllocZero(db, sizeof(Parse)); + if( !pSubParse ) return 0; + memset(&sNC, 0, sizeof(sNC)); + sNC.pParse = pSubParse; + pSubParse->db = db; + pSubParse->pTriggerTab = pTab; + pSubParse->pToplevel = pTop; + pSubParse->zAuthContext = pTrigger->zName; + pSubParse->eTriggerOp = pTrigger->op; + + v = sqlite3GetVdbe(pSubParse); + if( v ){ + VdbeComment((v, "Start: %s.%s (%s %s%s%s ON %s)", + pTrigger->zName, onErrorText(orconf), + (pTrigger->tr_tm==TRIGGER_BEFORE ? "BEFORE" : "AFTER"), + (pTrigger->op==TK_UPDATE ? "UPDATE" : ""), + (pTrigger->op==TK_INSERT ? "INSERT" : ""), + (pTrigger->op==TK_DELETE ? "DELETE" : ""), + pTab->zName + )); +#ifndef SQLITE_OMIT_TRACE + sqlite3VdbeChangeP4(v, -1, + sqlite3MPrintf(db, "-- TRIGGER %s", pTrigger->zName), P4_DYNAMIC + ); +#endif + + /* If one was specified, code the WHEN clause. If it evaluates to false + ** (or NULL) the sub-vdbe is immediately halted by jumping to the + ** OP_Halt inserted at the end of the program. */ + if( pTrigger->pWhen ){ + pWhen = sqlite3ExprDup(db, pTrigger->pWhen, 0); + if( SQLITE_OK==sqlite3ResolveExprNames(&sNC, pWhen) + && db->mallocFailed==0 + ){ + iEndTrigger = sqlite3VdbeMakeLabel(v); + sqlite3ExprIfFalse(pSubParse, pWhen, iEndTrigger, SQLITE_JUMPIFNULL); + } + sqlite3ExprDelete(db, pWhen); + } + + /* Code the trigger program into the sub-vdbe. */ + codeTriggerProgram(pSubParse, pTrigger->step_list, orconf); + + /* Insert an OP_Halt at the end of the sub-program. */ + if( iEndTrigger ){ + sqlite3VdbeResolveLabel(v, iEndTrigger); + } + sqlite3VdbeAddOp0(v, OP_Halt); + VdbeComment((v, "End: %s.%s", pTrigger->zName, onErrorText(orconf))); + + transferParseError(pParse, pSubParse); + if( db->mallocFailed==0 ){ + pProgram->aOp = sqlite3VdbeTakeOpArray(v, &pProgram->nOp, &pTop->nMaxArg); + } + pProgram->nMem = pSubParse->nMem; + pProgram->nCsr = pSubParse->nTab; + pProgram->token = (void *)pTrigger; + pPrg->oldmask = pSubParse->oldmask; + sqlite3VdbeDelete(v); + } + + assert( !pSubParse->pAinc && !pSubParse->pZombieTab ); + assert( !pSubParse->pTriggerPrg && !pSubParse->nMaxArg ); + sqlite3StackFree(db, pSubParse); + + return pPrg; +} + +/* +** Return a pointer to a TriggerPrg object containing the sub-program for +** trigger pTrigger with default ON CONFLICT algorithm orconf. If no such +** TriggerPrg object exists, a new object is allocated and populated before +** being returned. +*/ +static TriggerPrg *getRowTrigger( + Parse *pParse, /* Current parse context */ + Trigger *pTrigger, /* Trigger to code */ + Table *pTab, /* The table trigger pTrigger is attached to */ + int orconf /* ON CONFLICT algorithm. */ +){ + Parse *pRoot = sqlite3ParseToplevel(pParse); + TriggerPrg *pPrg; + + assert( pTrigger->zName==0 || pTab==tableOfTrigger(pTrigger) ); + + /* It may be that this trigger has already been coded (or is in the + ** process of being coded). If this is the case, then an entry with + ** a matching TriggerPrg.pTrigger field will be present somewhere + ** in the Parse.pTriggerPrg list. Search for such an entry. */ + for(pPrg=pRoot->pTriggerPrg; + pPrg && (pPrg->pTrigger!=pTrigger || pPrg->orconf!=orconf); + pPrg=pPrg->pNext + ); + + /* If an existing TriggerPrg could not be located, create a new one. */ + if( !pPrg ){ + pPrg = codeRowTrigger(pParse, pTrigger, pTab, orconf); + } + + return pPrg; +} + +/* +** Generate code for the trigger program associated with trigger p on +** table pTab. The reg, orconf and ignoreJump parameters passed to this +** function are the same as those described in the header function for +** sqlite3CodeRowTrigger() +*/ +SQLITE_PRIVATE void sqlite3CodeRowTriggerDirect( + Parse *pParse, /* Parse context */ + Trigger *p, /* Trigger to code */ + Table *pTab, /* The table to code triggers from */ + int reg, /* Reg array containing OLD.* and NEW.* values */ + int orconf, /* ON CONFLICT policy */ + int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ +){ + Vdbe *v = sqlite3GetVdbe(pParse); /* Main VM */ + TriggerPrg *pPrg; + pPrg = getRowTrigger(pParse, p, pTab, orconf); + assert( pPrg || pParse->nErr || pParse->db->mallocFailed ); + + /* Code the OP_Program opcode in the parent VDBE. P4 of the OP_Program + ** is a pointer to the sub-vdbe containing the trigger program. */ + if( pPrg ){ + sqlite3VdbeAddOp3(v, OP_Program, reg, ignoreJump, ++pParse->nMem); + pPrg->pProgram->nRef++; + sqlite3VdbeChangeP4(v, -1, (const char *)pPrg->pProgram, P4_SUBPROGRAM); + VdbeComment( + (v, "Call: %s.%s", (p->zName?p->zName:"fkey"), onErrorText(orconf))); + + /* Set the P5 operand of the OP_Program instruction to non-zero if + ** recursive invocation of this trigger program is disallowed. Recursive + ** invocation is disallowed if (a) the sub-program is really a trigger, + ** not a foreign key action, and (b) the flag to enable recursive triggers + ** is clear. */ + sqlite3VdbeChangeP5(v, (u8)(p->zName && !(pParse->db->flags&SQLITE_RecTriggers))); + } +} + +/* +** This is called to code the required FOR EACH ROW triggers for an operation +** on table pTab. The operation to code triggers for (INSERT, UPDATE or DELETE) +** is given by the op paramater. The tr_tm parameter determines whether the +** BEFORE or AFTER triggers are coded. If the operation is an UPDATE, then +** parameter pChanges is passed the list of columns being modified. +** +** If there are no triggers that fire at the specified time for the specified +** operation on pTab, this function is a no-op. +** +** The reg argument is the address of the first in an array of registers +** that contain the values substituted for the new.* and old.* references +** in the trigger program. If N is the number of columns in table pTab +** (a copy of pTab->nCol), then registers are populated as follows: +** +** Register Contains +** ------------------------------------------------------ +** reg+0 OLD.rowid +** reg+1 OLD.* value of left-most column of pTab +** ... ... +** reg+N OLD.* value of right-most column of pTab +** reg+N+1 NEW.rowid +** reg+N+2 OLD.* value of left-most column of pTab +** ... ... +** reg+N+N+1 NEW.* value of right-most column of pTab +** +** For ON DELETE triggers, the registers containing the NEW.* values will +** never be accessed by the trigger program, so they are not allocated or +** populated by the caller (there is no data to populate them with anyway). +** Similarly, for ON INSERT triggers the values stored in the OLD.* registers +** are never accessed, and so are not allocated by the caller. So, for an +** ON INSERT trigger, the value passed to this function as parameter reg +** is not a readable register, although registers (reg+N) through +** (reg+N+N+1) are. +** +** Parameter orconf is the default conflict resolution algorithm for the +** trigger program to use (REPLACE, IGNORE etc.). Parameter ignoreJump +** is the instruction that control should jump to if a trigger program +** raises an IGNORE exception. +*/ +SQLITE_PRIVATE void sqlite3CodeRowTrigger( Parse *pParse, /* Parse context */ Trigger *pTrigger, /* List of triggers on table pTab */ int op, /* One of TK_UPDATE, TK_INSERT, TK_DELETE */ ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ int tr_tm, /* One of TRIGGER_BEFORE, TRIGGER_AFTER */ Table *pTab, /* The table to code triggers from */ - int newIdx, /* The indice of the "new" row to access */ - int oldIdx, /* The indice of the "old" row to access */ + int reg, /* The first in an array of registers (see above) */ int orconf, /* ON CONFLICT policy */ - int ignoreJump, /* Instruction to jump to for RAISE(IGNORE) */ - u32 *piOldColMask, /* OUT: Mask of columns used from the OLD.* table */ - u32 *piNewColMask /* OUT: Mask of columns used from the NEW.* table */ + int ignoreJump /* Instruction to jump to for RAISE(IGNORE) */ ){ - Trigger *p; - sqlite3 *db = pParse->db; - TriggerStack trigStackEntry; + Trigger *p; /* Used to iterate through pTrigger list */ - trigStackEntry.oldColMask = 0; - trigStackEntry.newColMask = 0; - - assert(op == TK_UPDATE || op == TK_INSERT || op == TK_DELETE); - assert(tr_tm == TRIGGER_BEFORE || tr_tm == TRIGGER_AFTER ); - - assert(newIdx != -1 || oldIdx != -1); + assert( op==TK_UPDATE || op==TK_INSERT || op==TK_DELETE ); + assert( tr_tm==TRIGGER_BEFORE || tr_tm==TRIGGER_AFTER ); + assert( (op==TK_UPDATE)==(pChanges!=0) ); for(p=pTrigger; p; p=p->pNext){ - int fire_this = 0; /* Sanity checking: The schema for the trigger and for the table are ** always defined. The trigger must be in the same schema as the table ** or else it must be a TEMP trigger. */ assert( p->pSchema!=0 ); assert( p->pTabSchema!=0 ); - assert( p->pSchema==p->pTabSchema || p->pSchema==db->aDb[1].pSchema ); + assert( p->pSchema==p->pTabSchema + || p->pSchema==pParse->db->aDb[1].pSchema ); /* Determine whether we should code this trigger */ - if( - p->op==op && - p->tr_tm==tr_tm && - checkColumnOverlap(p->pColumns,pChanges) + if( p->op==op + && p->tr_tm==tr_tm + && checkColumnOverlap(p->pColumns, pChanges) ){ - TriggerStack *pS; /* Pointer to trigger-stack entry */ - for(pS=pParse->trigStack; pS && p!=pS->pTrigger; pS=pS->pNext){} - if( !pS ){ - fire_this = 1; - } -#if 0 /* Give no warning for recursive triggers. Just do not do them */ - else{ - sqlite3ErrorMsg(pParse, "recursive triggers not supported (%s)", - p->name); - return SQLITE_ERROR; - } -#endif + sqlite3CodeRowTriggerDirect(pParse, p, pTab, reg, orconf, ignoreJump); } - - if( fire_this ){ - int endTrigger; - Expr * whenExpr; - AuthContext sContext; - NameContext sNC; - -#ifndef SQLITE_OMIT_TRACE - sqlite3VdbeAddOp4(pParse->pVdbe, OP_Trace, 0, 0, 0, - sqlite3MPrintf(db, "-- TRIGGER %s", p->name), - P4_DYNAMIC); -#endif - memset(&sNC, 0, sizeof(sNC)); - sNC.pParse = pParse; - - /* Push an entry on to the trigger stack */ - trigStackEntry.pTrigger = p; - trigStackEntry.newIdx = newIdx; - trigStackEntry.oldIdx = oldIdx; - trigStackEntry.pTab = pTab; - trigStackEntry.pNext = pParse->trigStack; - trigStackEntry.ignoreJump = ignoreJump; - pParse->trigStack = &trigStackEntry; - sqlite3AuthContextPush(pParse, &sContext, p->name); - - /* code the WHEN clause */ - endTrigger = sqlite3VdbeMakeLabel(pParse->pVdbe); - whenExpr = sqlite3ExprDup(db, p->pWhen, 0); - if( db->mallocFailed || sqlite3ResolveExprNames(&sNC, whenExpr) ){ - pParse->trigStack = trigStackEntry.pNext; - sqlite3ExprDelete(db, whenExpr); - return 1; - } - sqlite3ExprIfFalse(pParse, whenExpr, endTrigger, SQLITE_JUMPIFNULL); - sqlite3ExprDelete(db, whenExpr); - - codeTriggerProgram(pParse, p->step_list, orconf); + } +} - /* Pop the entry off the trigger stack */ - pParse->trigStack = trigStackEntry.pNext; - sqlite3AuthContextPop(&sContext); +/* +** Triggers fired by UPDATE or DELETE statements may access values stored +** in the old.* pseudo-table. This function returns a 32-bit bitmask +** indicating which columns of the old.* table actually are used by +** triggers. This information may be used by the caller to avoid having +** to load the entire old.* record into memory when executing an UPDATE +** or DELETE command. +** +** Bit 0 of the returned mask is set if the left-most column of the +** table may be accessed using an old. reference. Bit 1 is set if +** the second leftmost column value is required, and so on. If there +** are more than 32 columns in the table, and at least one of the columns +** with an index greater than 32 may be accessed, 0xffffffff is returned. +** +** It is not possible to determine if the old.rowid column is accessed +** by triggers. The caller must always assume that it is. +** +** There is no equivalent function for new.* references. +*/ +SQLITE_PRIVATE u32 sqlite3TriggerOldmask( + Parse *pParse, /* Parse context */ + Trigger *pTrigger, /* List of triggers on table pTab */ + ExprList *pChanges, /* Changes list for any UPDATE OF triggers */ + Table *pTab, /* The table to code triggers from */ + int orconf /* Default ON CONFLICT policy for trigger steps */ +){ + const int op = pChanges ? TK_UPDATE : TK_DELETE; + u32 mask = 0; + Trigger *p; - sqlite3VdbeResolveLabel(pParse->pVdbe, endTrigger); + for(p=pTrigger; p; p=p->pNext){ + if( p->op==op && checkColumnOverlap(p->pColumns,pChanges) ){ + TriggerPrg *pPrg; + pPrg = getRowTrigger(pParse, p, pTab, orconf); + if( pPrg ){ + mask |= pPrg->oldmask; + } } } - if( piOldColMask ) *piOldColMask |= trigStackEntry.oldColMask; - if( piNewColMask ) *piNewColMask |= trigStackEntry.newColMask; - return 0; + + return mask; } + #endif /* !defined(SQLITE_OMIT_TRIGGER) */ /************** End of trigger.c *********************************************/ @@ -80815,7 +84071,7 @@ SQLITE_PRIVATE int sqlite3CodeRowTrigger( ** This file contains C code routines that are called by the parser ** to handle UPDATE statements. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef SQLITE_OMIT_VIRTUALTABLE @@ -80855,8 +84111,13 @@ static void updateVirtualTable( ** the column is a literal number, string or null. The sqlite3ValueFromExpr() ** function is capable of transforming these types of expressions into ** sqlite3_value objects. +** +** If parameter iReg is not negative, code an OP_RealAffinity instruction +** on register iReg. This is used when an equivalent integer value is +** stored in place of an 8-byte floating point value in order to save +** space. */ -SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){ +SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i, int iReg){ assert( pTab!=0 ); if( !pTab->pSelect ){ sqlite3_value *pValue; @@ -80869,6 +84130,11 @@ SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *v, Table *pTab, int i){ if( pValue ){ sqlite3VdbeChangeP4(v, -1, (const char *)pValue, P4_MEM); } +#ifndef SQLITE_OMIT_FLOATING_POINT + if( iReg>=0 && pTab->aCol[i].affinity==SQLITE_AFF_REAL ){ + sqlite3VdbeAddOp1(v, OP_RealAffinity, iReg); + } +#endif } } @@ -80907,29 +84173,23 @@ SQLITE_PRIVATE void sqlite3Update( int iDb; /* Database containing the table being updated */ int j1; /* Addresses of jump instructions */ int okOnePass; /* True for one-pass algorithm without the FIFO */ + int hasFK; /* True if foreign key processing is required */ #ifndef SQLITE_OMIT_TRIGGER int isView; /* Trying to update a view */ Trigger *pTrigger; /* List of triggers on pTab, if required */ #endif - int iBeginAfterTrigger = 0; /* Address of after trigger program */ - int iEndAfterTrigger = 0; /* Exit of after trigger program */ - int iBeginBeforeTrigger = 0; /* Address of before trigger program */ - int iEndBeforeTrigger = 0; /* Exit of before trigger program */ - u32 old_col_mask = 0; /* Mask of OLD.* columns in use */ - u32 new_col_mask = 0; /* Mask of NEW.* columns in use */ - - int newIdx = -1; /* index of trigger "new" temp table */ - int oldIdx = -1; /* index of trigger "old" temp table */ /* Register Allocations */ int regRowCount = 0; /* A count of rows changed */ int regOldRowid; /* The old rowid */ int regNewRowid; /* The new rowid */ - int regData; /* New data for the row */ + int regNew; + int regOld = 0; int regRowSet = 0; /* Rowset of rows to be updated */ + int regRec; /* Register used for new table record to insert */ - sContext.pParse = 0; + memset(&sContext, 0, sizeof(sContext)); db = pParse->db; if( pParse->nErr || db->mallocFailed ){ goto update_cleanup; @@ -80943,7 +84203,7 @@ SQLITE_PRIVATE void sqlite3Update( iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); /* Figure out if we have any triggers and if the table being - ** updated is a view + ** updated is a view. */ #ifndef SQLITE_OMIT_TRIGGER pTrigger = sqlite3TriggersExist(pParse, pTab, TK_UPDATE, pChanges, 0); @@ -80957,24 +84217,16 @@ SQLITE_PRIVATE void sqlite3Update( # define isView 0 #endif - if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){ + if( sqlite3ViewGetColumnNames(pParse, pTab) ){ goto update_cleanup; } - if( sqlite3ViewGetColumnNames(pParse, pTab) ){ + if( sqlite3IsReadOnly(pParse, pTab, (pTrigger?1:0)) ){ goto update_cleanup; } aXRef = sqlite3DbMallocRaw(db, sizeof(int) * pTab->nCol ); if( aXRef==0 ) goto update_cleanup; for(i=0; inCol; i++) aXRef[i] = -1; - /* If there are FOR EACH ROW triggers, allocate cursors for the - ** special OLD and NEW tables - */ - if( pTrigger ){ - newIdx = pParse->nTab++; - oldIdx = pParse->nTab++; - } - /* Allocate a cursors for the main database table and for all indices. ** The index cursors might not be used, but if they are used they ** need to occur right after the database cursor. So go ahead and @@ -81034,6 +84286,8 @@ SQLITE_PRIVATE void sqlite3Update( #endif } + hasFK = sqlite3FkRequired(pParse, pTab, aXRef, chngRowid); + /* Allocate memory for the array aRegIdx[]. There is one entry in the ** array for each index associated with table being updated. Fill in ** the value with a register number for indices that are to be used @@ -81060,24 +84314,7 @@ SQLITE_PRIVATE void sqlite3Update( aRegIdx[j] = reg; } - /* Allocate a block of register used to store the change record - ** sent to sqlite3GenerateConstraintChecks(). There are either - ** one or two registers for holding the rowid. One rowid register - ** is used if chngRowid is false and two are used if chngRowid is - ** true. Following these are pTab->nCol register holding column - ** data. - */ - regOldRowid = regNewRowid = pParse->nMem + 1; - pParse->nMem += pTab->nCol + 1; - if( chngRowid ){ - regNewRowid++; - pParse->nMem++; - } - regData = regNewRowid+1; - - - /* Begin generating code. - */ + /* Begin generating code. */ v = sqlite3GetVdbe(pParse); if( v==0 ) goto update_cleanup; if( pParse->nested==0 ) sqlite3VdbeCountChanges(v); @@ -81094,39 +84331,22 @@ SQLITE_PRIVATE void sqlite3Update( } #endif - /* Start the view context - */ - if( isView ){ - sqlite3AuthContextPush(pParse, &sContext, pTab->zName); + /* Allocate required registers. */ + regOldRowid = regNewRowid = ++pParse->nMem; + if( pTrigger || hasFK ){ + regOld = pParse->nMem + 1; + pParse->nMem += pTab->nCol; } + if( chngRowid || pTrigger || hasFK ){ + regNewRowid = ++pParse->nMem; + } + regNew = pParse->nMem + 1; + pParse->nMem += pTab->nCol; + regRec = ++pParse->nMem; - /* Generate the code for triggers. - */ - if( pTrigger ){ - int iGoto; - - /* Create pseudo-tables for NEW and OLD - */ - sqlite3VdbeAddOp3(v, OP_OpenPseudo, oldIdx, 0, pTab->nCol); - sqlite3VdbeAddOp3(v, OP_OpenPseudo, newIdx, 0, pTab->nCol); - - iGoto = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); - addr = sqlite3VdbeMakeLabel(v); - iBeginBeforeTrigger = sqlite3VdbeCurrentAddr(v); - if( sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, - TRIGGER_BEFORE, pTab, newIdx, oldIdx, onError, addr, - &old_col_mask, &new_col_mask) ){ - goto update_cleanup; - } - iEndBeforeTrigger = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); - iBeginAfterTrigger = sqlite3VdbeCurrentAddr(v); - if( sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, - TRIGGER_AFTER, pTab, newIdx, oldIdx, onError, addr, - &old_col_mask, &new_col_mask) ){ - goto update_cleanup; - } - iEndAfterTrigger = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0); - sqlite3VdbeJumpHere(v, iGoto); + /* Start the view context. */ + if( isView ){ + sqlite3AuthContextPush(pParse, &sContext, pTab->zName); } /* If we are trying to update a view, realize that view into @@ -81166,7 +84386,7 @@ SQLITE_PRIVATE void sqlite3Update( /* Initialize the count of updated rows */ - if( db->flags & SQLITE_CountRows && !pParse->trigStack ){ + if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab ){ regRowCount = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Integer, 0, regRowCount); } @@ -81199,11 +84419,6 @@ SQLITE_PRIVATE void sqlite3Update( } } } - - /* Jump back to this point if a trigger encounters an IGNORE constraint. */ - if( pTrigger ){ - sqlite3VdbeResolveLabel(v, addr); - } /* Top of the update loop */ if( okOnePass ){ @@ -81214,139 +84429,117 @@ SQLITE_PRIVATE void sqlite3Update( addr = sqlite3VdbeAddOp3(v, OP_RowSetRead, regRowSet, 0, regOldRowid); } - if( pTrigger ){ - int regRowid; - int regRow; - int regCols; - - /* Make cursor iCur point to the record that is being updated. - */ - sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid); + /* Make cursor iCur point to the record that is being updated. If + ** this record does not exist for some reason (deleted by a trigger, + ** for example, then jump to the next iteration of the RowSet loop. */ + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid); - /* Generate the OLD table - */ - regRowid = sqlite3GetTempReg(pParse); - regRow = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regRowid); - if( !old_col_mask ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, regRow); - }else{ - sqlite3VdbeAddOp2(v, OP_RowData, iCur, regRow); - } - sqlite3VdbeAddOp3(v, OP_Insert, oldIdx, regRow, regRowid); + /* If the record number will change, set register regNewRowid to + ** contain the new value. If the record number is not being modified, + ** then regNewRowid is the same register as regOldRowid, which is + ** already populated. */ + assert( chngRowid || pTrigger || hasFK || regOldRowid==regNewRowid ); + if( chngRowid ){ + sqlite3ExprCode(pParse, pRowidExpr, regNewRowid); + sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); + } - /* Generate the NEW table - */ - if( chngRowid ){ - sqlite3ExprCodeAndCache(pParse, pRowidExpr, regRowid); - sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid); - }else{ - sqlite3VdbeAddOp2(v, OP_Rowid, iCur, regRowid); - } - regCols = sqlite3GetTempRange(pParse, pTab->nCol); + /* If there are triggers on this table, populate an array of registers + ** with the required old.* column data. */ + if( hasFK || pTrigger ){ + u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0); + oldmask |= sqlite3TriggerOldmask(pParse, pTrigger, pChanges, pTab, onError); for(i=0; inCol; i++){ - if( i==pTab->iPKey ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, regCols+i); - continue; - } - j = aXRef[i]; - if( (i<32 && (new_col_mask&((u32)1<a[j].pExpr, regCols+i); - } + if( aXRef[i]<0 || oldmask==0xffffffff || (oldmask & (1<nCol, regRow); - if( !isView ){ - sqlite3TableAffinityStr(v, pTab); - sqlite3ExprCacheAffinityChange(pParse, regCols, pTab->nCol); + if( chngRowid==0 ){ + sqlite3VdbeAddOp2(v, OP_Copy, regOldRowid, regNewRowid); } - sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol); - /* if( pParse->nErr ) goto update_cleanup; */ - sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRow, regRowid); - sqlite3ReleaseTempReg(pParse, regRowid); - sqlite3ReleaseTempReg(pParse, regRow); - - sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginBeforeTrigger); - sqlite3VdbeJumpHere(v, iEndBeforeTrigger); } - if( !isView ){ - /* Loop over every record that needs updating. We have to load - ** the old data for each record to be updated because some columns - ** might not change and we will need to copy the old value. - ** Also, the old data is needed to delete the old index entries. - ** So make the cursor point at the old record. - */ - sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid); - - /* If the record number will change, push the record number as it - ** will be after the update. (The old record number is currently - ** on top of the stack.) - */ - if( chngRowid ){ - sqlite3ExprCode(pParse, pRowidExpr, regNewRowid); - sqlite3VdbeAddOp1(v, OP_MustBeInt, regNewRowid); - } - - /* Compute new data for this record. - */ - for(i=0; inCol; i++){ - if( i==pTab->iPKey ){ - sqlite3VdbeAddOp2(v, OP_Null, 0, regData+i); - continue; - } + /* Populate the array of registers beginning at regNew with the new + ** row data. This array is used to check constaints, create the new + ** table and index records, and as the values for any new.* references + ** made by triggers. */ + for(i=0; inCol; i++){ + if( i==pTab->iPKey ){ + sqlite3VdbeAddOp2(v, OP_Null, 0, regNew+i); + }else{ j = aXRef[i]; if( j<0 ){ - sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regData+i); - sqlite3ColumnDefault(v, pTab, i); + sqlite3VdbeAddOp3(v, OP_Column, iCur, i, regNew+i); + sqlite3ColumnDefault(v, pTab, i, regNew+i); }else{ - sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regData+i); + sqlite3ExprCode(pParse, pChanges->a[j].pExpr, regNew+i); } } + } - /* Do constraint checks - */ + /* Fire any BEFORE UPDATE triggers. This happens before constraints are + ** verified. One could argue that this is wrong. */ + if( pTrigger ){ + sqlite3VdbeAddOp2(v, OP_Affinity, regNew, pTab->nCol); + sqlite3TableAffinityStr(v, pTab); + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + TRIGGER_BEFORE, pTab, regOldRowid, onError, addr); + + /* The row-trigger may have deleted the row being updated. In this + ** case, jump to the next row. No updates or AFTER triggers are + ** required. This behaviour - what happens when the row being updated + ** is deleted or renamed by a BEFORE trigger - is left undefined in the + ** documentation. */ + sqlite3VdbeAddOp3(v, OP_NotExists, iCur, addr, regOldRowid); + } + + if( !isView ){ + + /* Do constraint checks. */ sqlite3GenerateConstraintChecks(pParse, pTab, iCur, regNewRowid, - aRegIdx, chngRowid, 1, - onError, addr, 0); + aRegIdx, (chngRowid?regOldRowid:0), 1, onError, addr, 0); - /* Delete the old indices for the current record. - */ + /* Do FK constraint checks. */ + if( hasFK ){ + sqlite3FkCheck(pParse, pTab, regOldRowid, 0); + } + + /* Delete the index entries associated with the current record. */ j1 = sqlite3VdbeAddOp3(v, OP_NotExists, iCur, 0, regOldRowid); sqlite3GenerateRowIndexDelete(pParse, pTab, iCur, aRegIdx); - - /* If changing the record number, delete the old record. - */ - if( chngRowid ){ + + /* If changing the record number, delete the old record. */ + if( hasFK || chngRowid ){ sqlite3VdbeAddOp2(v, OP_Delete, iCur, 0); } sqlite3VdbeJumpHere(v, j1); - /* Create the new index entries and the new record. - */ - sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, - aRegIdx, 1, -1, 0, 0); + if( hasFK ){ + sqlite3FkCheck(pParse, pTab, 0, regNewRowid); + } + + /* Insert the new index entries and the new record. */ + sqlite3CompleteInsertion(pParse, pTab, iCur, regNewRowid, aRegIdx, 1, 0, 0); + + /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to + ** handle rows (possibly in other tables) that refer via a foreign key + ** to the row just updated. */ + if( hasFK ){ + sqlite3FkActions(pParse, pTab, pChanges, regOldRowid); + } } /* Increment the row counter */ - if( db->flags & SQLITE_CountRows && !pParse->trigStack){ + if( (db->flags & SQLITE_CountRows) && !pParse->pTriggerTab){ sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); } - /* If there are triggers, close all the cursors after each iteration - ** through the loop. The fire the after triggers. - */ - if( pTrigger ){ - sqlite3VdbeAddOp2(v, OP_Goto, 0, iBeginAfterTrigger); - sqlite3VdbeJumpHere(v, iEndAfterTrigger); - } + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + TRIGGER_AFTER, pTab, regOldRowid, onError, addr); /* Repeat the above with the next record to be updated, until ** all record selected by the WHERE clause have been updated. @@ -81361,9 +84554,13 @@ SQLITE_PRIVATE void sqlite3Update( } } sqlite3VdbeAddOp2(v, OP_Close, iCur, 0); - if( pTrigger ){ - sqlite3VdbeAddOp2(v, OP_Close, newIdx, 0); - sqlite3VdbeAddOp2(v, OP_Close, oldIdx, 0); + + /* Update the sqlite_sequence table by storing the content of the + ** maximum rowid counter values recorded while inserting into + ** autoincrement tables. + */ + if( pParse->nested==0 && pParse->pTriggerTab==0 ){ + sqlite3AutoincrementEnd(pParse); } /* @@ -81371,7 +84568,7 @@ SQLITE_PRIVATE void sqlite3Update( ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ - if( db->flags & SQLITE_CountRows && !pParse->trigStack && pParse->nested==0 ){ + if( (db->flags&SQLITE_CountRows) && !pParse->pTriggerTab && !pParse->nested ){ sqlite3VdbeAddOp2(v, OP_ResultRow, regRowCount, 1); sqlite3VdbeSetNumCols(v, 1); sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "rows updated", SQLITE_STATIC); @@ -81386,6 +84583,15 @@ update_cleanup: sqlite3ExprDelete(db, pWhere); return; } +/* Make sure "isView" and other macros defined above are undefined. Otherwise +** thely may interfere with compilation of other functions in this file +** (or in another file, if this file becomes part of the amalgamation). */ +#ifdef isView + #undef isView +#endif +#ifdef pTrigger + #undef pTrigger +#endif #ifndef SQLITE_OMIT_VIRTUALTABLE /* @@ -81425,7 +84631,7 @@ static void updateVirtualTable( int addr; /* Address of top of loop */ int iReg; /* First register in set passed to OP_VUpdate */ sqlite3 *db = pParse->db; /* Database connection */ - const char *pVtab = (const char*)pTab->pVtab; + const char *pVTab = (const char*)sqlite3GetVTable(db, pTab); SelectDest dest; /* Construct the SELECT statement that will find the new values for @@ -81463,17 +84669,17 @@ static void updateVirtualTable( /* Generate code to scan the ephemeral table and call VUpdate. */ iReg = ++pParse->nMem; pParse->nMem += pTab->nCol+1; - sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); - addr = sqlite3VdbeCurrentAddr(v); + addr = sqlite3VdbeAddOp2(v, OP_Rewind, ephemTab, 0); sqlite3VdbeAddOp3(v, OP_Column, ephemTab, 0, iReg); sqlite3VdbeAddOp3(v, OP_Column, ephemTab, (pRowid?1:0), iReg+1); for(i=0; inCol; i++){ sqlite3VdbeAddOp3(v, OP_Column, ephemTab, i+1+(pRowid!=0), iReg+2+i); } sqlite3VtabMakeWritable(pParse, pTab); - sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVtab, P4_VTAB); - sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr); - sqlite3VdbeJumpHere(v, addr-1); + sqlite3VdbeAddOp4(v, OP_VUpdate, 0, pTab->nCol+2, iReg, pVTab, P4_VTAB); + sqlite3MayAbort(pParse); + sqlite3VdbeAddOp2(v, OP_Next, ephemTab, addr+1); + sqlite3VdbeJumpHere(v, addr); sqlite3VdbeAddOp2(v, OP_Close, ephemTab, 0); /* Cleanup */ @@ -81481,11 +84687,6 @@ static void updateVirtualTable( } #endif /* SQLITE_OMIT_VIRTUALTABLE */ -/* Make sure "isView" gets undefined in case this file becomes part of -** the amalgamation - so that subsequent files do not see isView as a -** macro. */ -#undef isView - /************** End of update.c **********************************************/ /************** Begin file vacuum.c ******************************************/ /* @@ -81504,7 +84705,7 @@ static void updateVirtualTable( ** Most of the code in this file may be omitted by defining the ** SQLITE_OMIT_VACUUM macro. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH) @@ -81585,11 +84786,14 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ return SQLITE_ERROR; } - /* Save the current value of the write-schema flag before setting it. */ + /* Save the current value of the database flags so that it can be + ** restored before returning. Then set the writable-schema flag, and + ** disable CHECK and foreign key constraints. */ saved_flags = db->flags; saved_nChange = db->nChange; saved_nTotalChange = db->nTotalChange; db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks; + db->flags &= ~SQLITE_ForeignKeys; pMain = db->aDb[0].pBt; isMemDb = sqlite3PagerIsMemdb(sqlite3BtreePager(pMain)); @@ -81742,8 +84946,7 @@ SQLITE_PRIVATE int sqlite3RunVacuum(char **pzErrMsg, sqlite3 *db){ for(i=0; inRef++; +SQLITE_PRIVATE void sqlite3VtabLock(VTable *pVTab){ + pVTab->nRef++; } + /* -** Unlock a virtual table. When the last lock is removed, -** disconnect the virtual table. +** pTab is a pointer to a Table structure representing a virtual-table. +** Return a pointer to the VTable object used by connection db to access +** this virtual-table, if one has been created, or NULL otherwise. */ -SQLITE_PRIVATE void sqlite3VtabUnlock(sqlite3 *db, sqlite3_vtab *pVtab){ - assert( pVtab->nRef>0 ); - pVtab->nRef--; - assert(db); +SQLITE_PRIVATE VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){ + VTable *pVtab; + assert( IsVirtual(pTab) ); + for(pVtab=pTab->pVTable; pVtab && pVtab->db!=db; pVtab=pVtab->pNext); + return pVtab; +} + +/* +** Decrement the ref-count on a virtual table object. When the ref-count +** reaches zero, call the xDisconnect() method to delete the object. +*/ +SQLITE_PRIVATE void sqlite3VtabUnlock(VTable *pVTab){ + sqlite3 *db = pVTab->db; + + assert( db ); + assert( pVTab->nRef>0 ); assert( sqlite3SafetyCheckOk(db) ); - if( pVtab->nRef==0 ){ + + pVTab->nRef--; + if( pVTab->nRef==0 ){ + sqlite3_vtab *p = pVTab->pVtab; + if( p ){ #ifdef SQLITE_DEBUG - if( db->magic==SQLITE_MAGIC_BUSY ){ - (void)sqlite3SafetyOff(db); - pVtab->pModule->xDisconnect(pVtab); - (void)sqlite3SafetyOn(db); - } else + if( pVTab->db->magic==SQLITE_MAGIC_BUSY ){ + (void)sqlite3SafetyOff(db); + p->pModule->xDisconnect(p); + (void)sqlite3SafetyOn(db); + } else #endif - { - pVtab->pModule->xDisconnect(pVtab); + { + p->pModule->xDisconnect(p); + } + } + sqlite3DbFree(db, pVTab); + } +} + +/* +** Table p is a virtual table. This function moves all elements in the +** p->pVTable list to the sqlite3.pDisconnect lists of their associated +** database connections to be disconnected at the next opportunity. +** Except, if argument db is not NULL, then the entry associated with +** connection db is left in the p->pVTable list. +*/ +static VTable *vtabDisconnectAll(sqlite3 *db, Table *p){ + VTable *pRet = 0; + VTable *pVTable = p->pVTable; + p->pVTable = 0; + + /* Assert that the mutex (if any) associated with the BtShared database + ** that contains table p is held by the caller. See header comments + ** above function sqlite3VtabUnlockList() for an explanation of why + ** this makes it safe to access the sqlite3.pDisconnect list of any + ** database connection that may have an entry in the p->pVTable list. */ + assert( db==0 || + sqlite3BtreeHoldsMutex(db->aDb[sqlite3SchemaToIndex(db, p->pSchema)].pBt) + ); + + while( pVTable ){ + sqlite3 *db2 = pVTable->db; + VTable *pNext = pVTable->pNext; + assert( db2 ); + if( db2==db ){ + pRet = pVTable; + p->pVTable = pRet; + pRet->pNext = 0; + }else{ + pVTable->pNext = db2->pDisconnect; + db2->pDisconnect = pVTable; } + pVTable = pNext; + } + + assert( !db || pRet ); + return pRet; +} + + +/* +** Disconnect all the virtual table objects in the sqlite3.pDisconnect list. +** +** This function may only be called when the mutexes associated with all +** shared b-tree databases opened using connection db are held by the +** caller. This is done to protect the sqlite3.pDisconnect list. The +** sqlite3.pDisconnect list is accessed only as follows: +** +** 1) By this function. In this case, all BtShared mutexes and the mutex +** associated with the database handle itself must be held. +** +** 2) By function vtabDisconnectAll(), when it adds a VTable entry to +** the sqlite3.pDisconnect list. In this case either the BtShared mutex +** associated with the database the virtual table is stored in is held +** or, if the virtual table is stored in a non-sharable database, then +** the database handle mutex is held. +** +** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously +** by multiple threads. It is thread-safe. +*/ +SQLITE_PRIVATE void sqlite3VtabUnlockList(sqlite3 *db){ + VTable *p = db->pDisconnect; + db->pDisconnect = 0; + + assert( sqlite3BtreeHoldsAllMutexes(db) ); + assert( sqlite3_mutex_held(db->mutex) ); + + if( p ){ + sqlite3ExpirePreparedStatements(db); + do { + VTable *pNext = p->pNext; + sqlite3VtabUnlock(p); + p = pNext; + }while( p ); } } @@ -81914,22 +85215,24 @@ SQLITE_PRIVATE void sqlite3VtabUnlock(sqlite3 *db, sqlite3_vtab *pVtab){ ** Clear any and all virtual-table information from the Table record. ** This routine is called, for example, just before deleting the Table ** record. +** +** Since it is a virtual-table, the Table structure contains a pointer +** to the head of a linked list of VTable structures. Each VTable +** structure is associated with a single sqlite3* user of the schema. +** The reference count of the VTable structure associated with database +** connection db is decremented immediately (which may lead to the +** structure being xDisconnected and free). Any other VTable structures +** in the list are moved to the sqlite3.pDisconnect list of the associated +** database connection. */ SQLITE_PRIVATE void sqlite3VtabClear(Table *p){ - sqlite3_vtab *pVtab = p->pVtab; - Schema *pSchema = p->pSchema; - sqlite3 *db = pSchema ? pSchema->db : 0; - if( pVtab ){ - assert( p->pMod && p->pMod->pModule ); - sqlite3VtabUnlock(db, pVtab); - p->pVtab = 0; - } + vtabDisconnectAll(0, p); if( p->azModuleArg ){ int i; for(i=0; inModuleArg; i++){ - sqlite3DbFree(db, p->azModuleArg[i]); + sqlite3DbFree(p->dbMem, p->azModuleArg[i]); } - sqlite3DbFree(db, p->azModuleArg); + sqlite3DbFree(p->dbMem, p->azModuleArg); } } @@ -81974,11 +85277,6 @@ SQLITE_PRIVATE void sqlite3VtabBeginParse( Table *pTable; /* The new virtual table */ sqlite3 *db; /* Database connection */ - if( pParse->db->flags & SQLITE_SharedCache ){ - sqlite3ErrorMsg(pParse, "Cannot use virtual tables in shared-cache mode"); - return; - } - sqlite3StartTable(pParse, pName1, pName2, 0, 0, 1, 0); pTable = pParse->pNewTable; if( pTable==0 ) return; @@ -82027,23 +85325,13 @@ static void addArgumentToVtab(Parse *pParse){ ** has been completely parsed. */ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ - Table *pTab; /* The table being constructed */ - sqlite3 *db; /* The database connection */ - char *zModule; /* The module name of the table: USING modulename */ - Module *pMod = 0; + Table *pTab = pParse->pNewTable; /* The table being constructed */ + sqlite3 *db = pParse->db; /* The database connection */ + if( pTab==0 ) return; addArgumentToVtab(pParse); pParse->sArg.z = 0; - - /* Lookup the module name. */ - pTab = pParse->pNewTable; - if( pTab==0 ) return; - db = pParse->db; if( pTab->nModuleArg<1 ) return; - zModule = pTab->azModuleArg[0]; - pMod = (Module*)sqlite3HashFind(&db->aModule, zModule, - sqlite3Strlen30(zModule)); - pTab->pMod = pMod; /* If the CREATE VIRTUAL TABLE statement is being entered for the ** first time (in other words if the virtual table is actually being @@ -82094,9 +85382,10 @@ SQLITE_PRIVATE void sqlite3VtabFinishParse(Parse *pParse, Token *pEnd){ } /* If we are rereading the sqlite_master table create the in-memory - ** record of the table. If the module has already been registered, - ** also call the xConnect method here. - */ + ** record of the table. The xConnect() method is not called until + ** the first time the virtual table is used in an SQL statement. This + ** allows a schema that contains virtual tables to be loaded before + ** the required virtual table implementations are registered. */ else { Table *pOld; Schema *pSchema = pTab->pSchema; @@ -82150,9 +85439,8 @@ static int vtabCallConstructor( int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), char **pzErr ){ + VTable *pVTable; int rc; - int rc2; - sqlite3_vtab *pVtab = 0; const char *const*azArg = (const char *const*)pTab->azModuleArg; int nArg = pTab->nModuleArg; char *zErr = 0; @@ -82162,22 +85450,23 @@ static int vtabCallConstructor( return SQLITE_NOMEM; } + pVTable = sqlite3DbMallocZero(db, sizeof(VTable)); + if( !pVTable ){ + sqlite3DbFree(db, zModuleName); + return SQLITE_NOMEM; + } + pVTable->db = db; + pVTable->pMod = pMod; + assert( !db->pVTab ); assert( xConstruct ); - db->pVTab = pTab; - rc = sqlite3SafetyOff(db); - assert( rc==SQLITE_OK ); - rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVtab, &zErr); - rc2 = sqlite3SafetyOn(db); + + /* Invoke the virtual table constructor */ + (void)sqlite3SafetyOff(db); + rc = xConstruct(db, pMod->pAux, nArg, azArg, &pVTable->pVtab, &zErr); + (void)sqlite3SafetyOn(db); if( rc==SQLITE_NOMEM ) db->mallocFailed = 1; - /* Justification of ALWAYS(): A correct vtab constructor must allocate - ** the sqlite3_vtab object if successful. */ - if( rc==SQLITE_OK && ALWAYS(pVtab) ){ - pVtab->pModule = pMod->pModule; - pVtab->nRef = 1; - pTab->pVtab = pVtab; - } if( SQLITE_OK!=rc ){ if( zErr==0 ){ @@ -82186,54 +85475,61 @@ static int vtabCallConstructor( *pzErr = sqlite3MPrintf(db, "%s", zErr); sqlite3DbFree(db, zErr); } - }else if( db->pVTab ){ - const char *zFormat = "vtable constructor did not declare schema: %s"; - *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); - rc = SQLITE_ERROR; - } - if( rc==SQLITE_OK ){ - rc = rc2; - } - db->pVTab = 0; - sqlite3DbFree(db, zModuleName); + sqlite3DbFree(db, pVTable); + }else if( ALWAYS(pVTable->pVtab) ){ + /* Justification of ALWAYS(): A correct vtab constructor must allocate + ** the sqlite3_vtab object if successful. */ + pVTable->pVtab->pModule = pMod->pModule; + pVTable->nRef = 1; + if( db->pVTab ){ + const char *zFormat = "vtable constructor did not declare schema: %s"; + *pzErr = sqlite3MPrintf(db, zFormat, pTab->zName); + sqlite3VtabUnlock(pVTable); + rc = SQLITE_ERROR; + }else{ + int iCol; + /* If everything went according to plan, link the new VTable structure + ** into the linked list headed by pTab->pVTable. Then loop through the + ** columns of the table to see if any of them contain the token "hidden". + ** If so, set the Column.isHidden flag and remove the token from + ** the type string. */ + pVTable->pNext = pTab->pVTable; + pTab->pVTable = pVTable; - /* If everything went according to plan, loop through the columns - ** of the table to see if any of them contain the token "hidden". - ** If so, set the Column.isHidden flag and remove the token from - ** the type string. - */ - if( rc==SQLITE_OK ){ - int iCol; - for(iCol=0; iColnCol; iCol++){ - char *zType = pTab->aCol[iCol].zType; - int nType; - int i = 0; - if( !zType ) continue; - nType = sqlite3Strlen30(zType); - if( sqlite3StrNICmp("hidden", zType, 6) || (zType[6] && zType[6]!=' ') ){ - for(i=0; inCol; iCol++){ + char *zType = pTab->aCol[iCol].zType; + int nType; + int i = 0; + if( !zType ) continue; + nType = sqlite3Strlen30(zType); + if( sqlite3StrNICmp("hidden", zType, 6)||(zType[6] && zType[6]!=' ') ){ + for(i=0; i0 ){ - assert(zType[i-1]==' '); - zType[i-1] = '\0'; + if( i0 ){ + assert(zType[i-1]==' '); + zType[i-1] = '\0'; + } + pTab->aCol[iCol].isHidden = 1; } - pTab->aCol[iCol].isHidden = 1; } } } + + sqlite3DbFree(db, zModuleName); + db->pVTab = 0; return rc; } @@ -82245,22 +85541,26 @@ static int vtabCallConstructor( ** This call is a no-op if table pTab is not a virtual table. */ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ + sqlite3 *db = pParse->db; + const char *zMod; Module *pMod; - int rc = SQLITE_OK; + int rc; assert( pTab ); - if( (pTab->tabFlags & TF_Virtual)==0 || pTab->pVtab ){ + if( (pTab->tabFlags & TF_Virtual)==0 || sqlite3GetVTable(db, pTab) ){ return SQLITE_OK; } - pMod = pTab->pMod; + /* Locate the required virtual table module */ + zMod = pTab->azModuleArg[0]; + pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod)); + if( !pMod ){ const char *zModule = pTab->azModuleArg[0]; sqlite3ErrorMsg(pParse, "no such module: %s", zModule); rc = SQLITE_ERROR; - } else { + }else{ char *zErr = 0; - sqlite3 *db = pParse->db; rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xConnect, &zErr); if( rc!=SQLITE_OK ){ sqlite3ErrorMsg(pParse, "%s", zErr); @@ -82272,14 +85572,14 @@ SQLITE_PRIVATE int sqlite3VtabCallConnect(Parse *pParse, Table *pTab){ } /* -** Add the virtual table pVtab to the array sqlite3.aVTrans[]. +** Add the virtual table pVTab to the array sqlite3.aVTrans[]. */ -static int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){ +static int addToVTrans(sqlite3 *db, VTable *pVTab){ const int ARRAY_INCR = 5; /* Grow the sqlite3.aVTrans array if required */ if( (db->nVTrans%ARRAY_INCR)==0 ){ - sqlite3_vtab **aVTrans; + VTable **aVTrans; int nBytes = sizeof(sqlite3_vtab *) * (db->nVTrans + ARRAY_INCR); aVTrans = sqlite3DbRealloc(db, (void *)db->aVTrans, nBytes); if( !aVTrans ){ @@ -82290,8 +85590,8 @@ static int addToVTrans(sqlite3 *db, sqlite3_vtab *pVtab){ } /* Add pVtab to the end of sqlite3.aVTrans */ - db->aVTrans[db->nVTrans++] = pVtab; - sqlite3VtabLock(pVtab); + db->aVTrans[db->nVTrans++] = pVTab; + sqlite3VtabLock(pVTab); return SQLITE_OK; } @@ -82307,19 +85607,21 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, int rc = SQLITE_OK; Table *pTab; Module *pMod; - const char *zModule; + const char *zMod; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); - assert(pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVtab); - pMod = pTab->pMod; - zModule = pTab->azModuleArg[0]; + assert( pTab && (pTab->tabFlags & TF_Virtual)!=0 && !pTab->pVTable ); + + /* Locate the required virtual table module */ + zMod = pTab->azModuleArg[0]; + pMod = (Module*)sqlite3HashFind(&db->aModule, zMod, sqlite3Strlen30(zMod)); /* If the module has been registered and includes a Create method, ** invoke it now. If the module has not been registered, return an ** error. Otherwise, do nothing. */ if( !pMod ){ - *pzErr = sqlite3MPrintf(db, "no such module: %s", zModule); + *pzErr = sqlite3MPrintf(db, "no such module: %s", zMod); rc = SQLITE_ERROR; }else{ rc = vtabCallConstructor(db, pTab, pMod, pMod->pModule->xCreate, pzErr); @@ -82327,8 +85629,8 @@ SQLITE_PRIVATE int sqlite3VtabCallCreate(sqlite3 *db, int iDb, const char *zTab, /* Justification of ALWAYS(): The xConstructor method is required to ** create a valid sqlite3_vtab if it returns SQLITE_OK. */ - if( rc==SQLITE_OK && ALWAYS(pTab->pVtab) ){ - rc = addToVTrans(db, pTab->pVtab); + if( rc==SQLITE_OK && ALWAYS(sqlite3GetVTable(db, pTab)) ){ + rc = addToVTrans(db, sqlite3GetVTable(db, pTab)); } return rc; @@ -82353,7 +85655,7 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ sqlite3_mutex_leave(db->mutex); return SQLITE_MISUSE; } - assert((pTab->tabFlags & TF_Virtual)!=0 && pTab->nCol==0 && pTab->aCol==0); + assert( (pTab->tabFlags & TF_Virtual)!=0 ); pParse = sqlite3StackAllocZero(db, sizeof(*pParse)); if( pParse==0 ){ @@ -82368,10 +85670,12 @@ SQLITE_API int sqlite3_declare_vtab(sqlite3 *db, const char *zCreateTable){ !pParse->pNewTable->pSelect && (pParse->pNewTable->tabFlags & TF_Virtual)==0 ){ - pTab->aCol = pParse->pNewTable->aCol; - pTab->nCol = pParse->pNewTable->nCol; - pParse->pNewTable->nCol = 0; - pParse->pNewTable->aCol = 0; + if( !pTab->aCol ){ + pTab->aCol = pParse->pNewTable->aCol; + pTab->nCol = pParse->pNewTable->nCol; + pParse->pNewTable->nCol = 0; + pParse->pNewTable->aCol = 0; + } db->pVTab = 0; } else { sqlite3Error(db, SQLITE_ERROR, zErr); @@ -82405,21 +85709,20 @@ SQLITE_PRIVATE int sqlite3VtabCallDestroy(sqlite3 *db, int iDb, const char *zTab Table *pTab; pTab = sqlite3FindTable(db, zTab, db->aDb[iDb].zName); - if( ALWAYS(pTab!=0 && pTab->pVtab!=0) ){ - int (*xDestroy)(sqlite3_vtab *pVTab) = pTab->pMod->pModule->xDestroy; + if( ALWAYS(pTab!=0 && pTab->pVTable!=0) ){ + VTable *p = vtabDisconnectAll(db, pTab); + rc = sqlite3SafetyOff(db); assert( rc==SQLITE_OK ); - rc = xDestroy(pTab->pVtab); + rc = p->pMod->pModule->xDestroy(p->pVtab); (void)sqlite3SafetyOn(db); + + /* Remove the sqlite3_vtab* from the aVTrans[] array, if applicable */ if( rc==SQLITE_OK ){ - int i; - for(i=0; inVTrans; i++){ - if( db->aVTrans[i]==pTab->pVtab ){ - db->aVTrans[i] = db->aVTrans[--db->nVTrans]; - break; - } - } - pTab->pVtab = 0; + assert( pTab->pVTable==p && p->pNext==0 ); + p->pVtab = 0; + pTab->pVTable = 0; + sqlite3VtabUnlock(p); } } @@ -82438,13 +85741,14 @@ static void callFinaliser(sqlite3 *db, int offset){ int i; if( db->aVTrans ){ for(i=0; inVTrans; i++){ - sqlite3_vtab *pVtab = db->aVTrans[i]; - int (*x)(sqlite3_vtab *); - - assert( pVtab!=0 ); - x = *(int (**)(sqlite3_vtab *))((char *)pVtab->pModule + offset); - if( x ) x(pVtab); - sqlite3VtabUnlock(db, pVtab); + VTable *pVTab = db->aVTrans[i]; + sqlite3_vtab *p = pVTab->pVtab; + if( p ){ + int (*x)(sqlite3_vtab *); + x = *(int (**)(sqlite3_vtab *))((char *)p->pModule + offset); + if( x ) x(p); + } + sqlite3VtabUnlock(pVTab); } sqlite3DbFree(db, db->aVTrans); db->nVTrans = 0; @@ -82464,16 +85768,14 @@ SQLITE_PRIVATE int sqlite3VtabSync(sqlite3 *db, char **pzErrmsg){ int i; int rc = SQLITE_OK; int rcsafety; - sqlite3_vtab **aVTrans = db->aVTrans; + VTable **aVTrans = db->aVTrans; rc = sqlite3SafetyOff(db); db->aVTrans = 0; for(i=0; rc==SQLITE_OK && inVTrans; i++){ - sqlite3_vtab *pVtab = aVTrans[i]; int (*x)(sqlite3_vtab *); - assert( pVtab!=0 ); - x = pVtab->pModule->xSync; - if( x ){ + sqlite3_vtab *pVtab = aVTrans[i]->pVtab; + if( pVtab && (x = pVtab->pModule->xSync)!=0 ){ rc = x(pVtab); sqlite3DbFree(db, *pzErrmsg); *pzErrmsg = pVtab->zErrMsg; @@ -82515,7 +85817,7 @@ SQLITE_PRIVATE int sqlite3VtabCommit(sqlite3 *db){ ** If the xBegin call is successful, place the sqlite3_vtab pointer ** in the sqlite3.aVTrans array. */ -SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){ +SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, VTable *pVTab){ int rc = SQLITE_OK; const sqlite3_module *pModule; @@ -82527,10 +85829,10 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){ if( sqlite3VtabInSync(db) ){ return SQLITE_LOCKED; } - if( !pVtab ){ + if( !pVTab ){ return SQLITE_OK; } - pModule = pVtab->pModule; + pModule = pVTab->pVtab->pModule; if( pModule->xBegin ){ int i; @@ -82538,15 +85840,15 @@ SQLITE_PRIVATE int sqlite3VtabBegin(sqlite3 *db, sqlite3_vtab *pVtab){ /* If pVtab is already in the aVTrans array, return early */ for(i=0; inVTrans; i++){ - if( db->aVTrans[i]==pVtab ){ + if( db->aVTrans[i]==pVTab ){ return SQLITE_OK; } } /* Invoke the xBegin method */ - rc = pModule->xBegin(pVtab); + rc = pModule->xBegin(pVTab->pVtab); if( rc==SQLITE_OK ){ - rc = addToVTrans(db, pVtab); + rc = addToVTrans(db, pVTab); } } return rc; @@ -82588,7 +85890,7 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( pTab = pExpr->pTab; if( NEVER(pTab==0) ) return pDef; if( (pTab->tabFlags & TF_Virtual)==0 ) return pDef; - pVtab = pTab->pVtab; + pVtab = sqlite3GetVTable(db, pTab)->pVtab; assert( pVtab!=0 ); assert( pVtab->pModule!=0 ); pMod = (sqlite3_module *)pVtab->pModule; @@ -82612,7 +85914,7 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( /* Create a new ephemeral function definition for the overloaded ** function */ pNew = sqlite3DbMallocZero(db, sizeof(*pNew) - + sqlite3Strlen30(pDef->zName) ); + + sqlite3Strlen30(pDef->zName) + 1); if( pNew==0 ){ return pDef; } @@ -82632,20 +85934,21 @@ SQLITE_PRIVATE FuncDef *sqlite3VtabOverloadFunction( ** is a no-op. */ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ + Parse *pToplevel = sqlite3ParseToplevel(pParse); int i, n; Table **apVtabLock; assert( IsVirtual(pTab) ); - for(i=0; inVtabLock; i++){ - if( pTab==pParse->apVtabLock[i] ) return; + for(i=0; inVtabLock; i++){ + if( pTab==pToplevel->apVtabLock[i] ) return; } - n = (pParse->nVtabLock+1)*sizeof(pParse->apVtabLock[0]); - apVtabLock = sqlite3_realloc(pParse->apVtabLock, n); + n = (pToplevel->nVtabLock+1)*sizeof(pToplevel->apVtabLock[0]); + apVtabLock = sqlite3_realloc(pToplevel->apVtabLock, n); if( apVtabLock ){ - pParse->apVtabLock = apVtabLock; - pParse->apVtabLock[pParse->nVtabLock++] = pTab; + pToplevel->apVtabLock = apVtabLock; + pToplevel->apVtabLock[pToplevel->nVtabLock++] = pTab; }else{ - pParse->db->mallocFailed = 1; + pToplevel->db->mallocFailed = 1; } } @@ -82671,7 +85974,7 @@ SQLITE_PRIVATE void sqlite3VtabMakeWritable(Parse *pParse, Table *pTab){ ** so is applicable. Because this module is responsible for selecting ** indices, you might also think of this module as the "query optimizer". ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -82849,6 +86152,7 @@ struct WhereCost { WherePlan plan; /* The lookup strategy */ double rCost; /* Overall cost of pursuing this search strategy */ double nRow; /* Estimated number of output rows */ + Bitmask used; /* Bitmask of cursors used by this plan */ }; /* @@ -83315,18 +86619,18 @@ static int isLikeOrGlob( } if( sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT ) return 0; z = pRight->u.zToken; - cnt = 0; if( ALWAYS(z) ){ + cnt = 0; while( (c=z[cnt])!=0 && c!=wc[0] && c!=wc[1] && c!=wc[2] ){ cnt++; } + if( cnt!=0 && c!=0 && 255!=(u8)z[cnt-1] ){ + *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0; + *pnPattern = cnt; + return 1; + } } - if( cnt==0 || c==0 || 255==(u8)z[cnt-1] ){ - return 0; - } - *pisComplete = z[cnt]==wc[0] && z[cnt+1]==0; - *pnPattern = cnt; - return 1; + return 0; } #endif /* SQLITE_OMIT_LIKE_OPTIMIZATION */ @@ -83830,6 +87134,7 @@ static void exprAnalyze( else if( pExpr->op==TK_OR ){ assert( pWC->op==TK_AND ); exprAnalyzeOrTerm(pSrc, pWC, idxTerm); + pTerm = &pWC->a[idxTerm]; } #endif /* SQLITE_OMIT_OR_OPTIMIZATION */ @@ -83991,6 +87296,11 @@ static int isSortingIndex( nTerm = pOrderBy->nExpr; assert( nTerm>0 ); + /* Argument pIdx must either point to a 'real' named index structure, + ** or an index structure allocated on the stack by bestBtreeIndex() to + ** represent the rowid index that is part of every table. */ + assert( pIdx->zName || (pIdx->nColumn==1 && pIdx->aiColumn[0]==-1) ); + /* Match terms of the ORDER BY clause against columns of ** the index. ** @@ -84017,7 +87327,7 @@ static int isSortingIndex( if( !pColl ){ pColl = db->pDfltColl; } - if( inColumn ){ + if( pIdx->zName && inColumn ){ iColumn = pIdx->aiColumn[i]; if( iColumn==pIdx->pTable->iPKey ){ iColumn = -1; @@ -84046,7 +87356,7 @@ static int isSortingIndex( return 0; } } - assert( pIdx->aSortOrder!=0 ); + assert( pIdx->aSortOrder!=0 || iColumn==-1 ); assert( pTerm->sortOrder==0 || pTerm->sortOrder==1 ); assert( iSortOrder==0 || iSortOrder==1 ); termSortOrder = iSortOrder ^ pTerm->sortOrder; @@ -84089,30 +87399,6 @@ static int isSortingIndex( return 0; } -/* -** Check table to see if the ORDER BY clause in pOrderBy can be satisfied -** by sorting in order of ROWID. Return true if so and set *pbRev to be -** true for reverse ROWID and false for forward ROWID order. -*/ -static int sortableByRowid( - int base, /* Cursor number for table to be sorted */ - ExprList *pOrderBy, /* The ORDER BY clause */ - WhereMaskSet *pMaskSet, /* Mapping from table cursors to bitmaps */ - int *pbRev /* Set to 1 if ORDER BY is DESC */ -){ - Expr *p; - - assert( pOrderBy!=0 ); - assert( pOrderBy->nExpr>0 ); - p = pOrderBy->a[0].pExpr; - if( p->op==TK_COLUMN && p->iTable==base && p->iColumn==-1 - && !referencesOtherTables(pOrderBy, pMaskSet, 1, base) ){ - *pbRev = pOrderBy->a[0].sortOrder; - return 1; - } - return 0; -} - /* ** Prepare a crude estimate of the logarithm of the input value. ** The results need not be exact. This is only used for estimating @@ -84213,6 +87499,7 @@ static void bestOrClauseIndex( int flags = WHERE_MULTI_OR; double rTotal = 0; double nRow = 0; + Bitmask used = 0; for(pOrTerm=pOrWC->a; pOrTerm=pCost->rCost ) break; } @@ -84252,6 +87540,7 @@ static void bestOrClauseIndex( if( rTotalrCost ){ pCost->rCost = rTotal; pCost->nRow = nRow; + pCost->used = used; pCost->plan.wsFlags = flags; pCost->plan.u.pTerm = pTerm; } @@ -84380,7 +87669,7 @@ static sqlite3_index_info *allocateIndexInfo( ** that this is required. */ static int vtabBestIndex(Parse *pParse, Table *pTab, sqlite3_index_info *p){ - sqlite3_vtab *pVtab = pTab->pVtab; + sqlite3_vtab *pVtab = sqlite3GetVTable(pParse->db, pTab)->pVtab; int i; int rc; @@ -84477,7 +87766,7 @@ static void bestVirtualIndex( ** sqlite3ViewGetColumnNames() would have picked up the error. */ assert( pTab->azModuleArg && pTab->azModuleArg[0] ); - assert( pTab->pVtab ); + assert( sqlite3GetVTable(pParse->db, pTab) ); /* Set the aConstraint[].usable fields and initialize all ** output variables to zero. @@ -84504,7 +87793,7 @@ static void bestVirtualIndex( for(i=0; inConstraint; i++, pIdxCons++){ j = pIdxCons->iTermOffset; pTerm = &pWC->a[j]; - pIdxCons->usable = (pTerm->prereqRight & notReady)==0 ?1:0; + pIdxCons->usable = (pTerm->prereqRight¬Ready) ? 0 : 1; } memset(pUsage, 0, sizeof(pUsage[0])*pIdxInfo->nConstraint); if( pIdxInfo->needToFreeIdxStr ){ @@ -84525,6 +87814,13 @@ static void bestVirtualIndex( return; } + pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; + for(i=0; inConstraint; i++){ + if( pUsage[i].argvIndex>0 ){ + pCost->used |= pWC->a[pIdxCons[i].iTermOffset].prereqRight; + } + } + /* The cost is not allowed to be larger than SQLITE_BIG_DBL (the ** inital value of lowestCost in this loop. If it is, then the ** (costaSample; + int i = 0; + int eType = sqlite3_value_type(pVal); + + if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + double r = sqlite3_value_double(pVal); + for(i=0; i=SQLITE_TEXT || aSample[i].u.r>r ) break; + } + }else{ + sqlite3 *db = pParse->db; + CollSeq *pColl; + const u8 *z; + int n; + + /* pVal comes from sqlite3ValueFromExpr() so the type cannot be NULL */ + assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); + + if( eType==SQLITE_BLOB ){ + z = (const u8 *)sqlite3_value_blob(pVal); + pColl = db->pDfltColl; + assert( pColl->enc==SQLITE_UTF8 ); + }else{ + pColl = sqlite3GetCollSeq(db, SQLITE_UTF8, 0, *pIdx->azColl); + if( pColl==0 ){ + sqlite3ErrorMsg(pParse, "no such collation sequence: %s", + *pIdx->azColl); + return SQLITE_ERROR; + } + z = (const u8 *)sqlite3ValueText(pVal, pColl->enc); + if( !z ){ + return SQLITE_NOMEM; + } + assert( z && pColl && pColl->xCmp ); + } + n = sqlite3ValueBytes(pVal, pColl->enc); + + for(i=0; ienc!=SQLITE_UTF8 ){ + int nSample; + char *zSample = sqlite3Utf8to16( + db, pColl->enc, aSample[i].u.z, aSample[i].nByte, &nSample + ); + if( !zSample ){ + assert( db->mallocFailed ); + return SQLITE_NOMEM; + } + r = pColl->xCmp(pColl->pUser, nSample, zSample, n, z); + sqlite3DbFree(db, zSample); + }else +#endif + { + r = pColl->xCmp(pColl->pUser, aSample[i].nByte, aSample[i].u.z, n, z); + } + if( r>0 ) break; + } + } + + assert( i>=0 && i<=SQLITE_INDEX_SAMPLES ); + *piRegion = i; + } + return SQLITE_OK; +} +#endif /* #ifdef SQLITE_ENABLE_STAT2 */ + +/* +** This function is used to estimate the number of rows that will be visited +** by scanning an index for a range of values. The range may have an upper +** bound, a lower bound, or both. The WHERE clause terms that set the upper +** and lower bounds are represented by pLower and pUpper respectively. For +** example, assuming that index p is on t1(a): +** +** ... FROM t1 WHERE a > ? AND a < ? ... +** |_____| |_____| +** | | +** pLower pUpper +** +** If either of the upper or lower bound is not present, then NULL is passed in +** place of the corresponding WhereTerm. +** +** The nEq parameter is passed the index of the index column subject to the +** range constraint. Or, equivalently, the number of equality constraints +** optimized by the proposed index scan. For example, assuming index p is +** on t1(a, b), and the SQL query is: +** +** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... +** +** then nEq should be passed the value 1 (as the range restricted column, +** b, is the second left-most column of the index). Or, if the query is: +** +** ... FROM t1 WHERE a > ? AND a < ? ... +** +** then nEq should be passed 0. +** +** The returned value is an integer between 1 and 100, inclusive. A return +** value of 1 indicates that the proposed range scan is expected to visit +** approximately 1/100th (1%) of the rows selected by the nEq equality +** constraints (if any). A return value of 100 indicates that it is expected +** that the range scan will visit every row (100%) selected by the equality +** constraints. +** +** In the absence of sqlite_stat2 ANALYZE data, each range inequality +** reduces the search space by 2/3rds. Hence a single constraint (x>?) +** results in a return of 33 and a range constraint (x>? AND xaCol[] of the range-compared column */ + WhereTerm *pLower, /* Lower bound on the range. ex: "x>123" Might be NULL */ + WhereTerm *pUpper, /* Upper bound on the range. ex: "x<455" Might be NULL */ + int *piEst /* OUT: Return value */ +){ + int rc = SQLITE_OK; + +#ifdef SQLITE_ENABLE_STAT2 + sqlite3 *db = pParse->db; + sqlite3_value *pLowerVal = 0; + sqlite3_value *pUpperVal = 0; + + if( nEq==0 && p->aSample ){ + int iEst; + int iLower = 0; + int iUpper = SQLITE_INDEX_SAMPLES; + u8 aff = p->pTable->aCol[0].affinity; + + if( pLower ){ + Expr *pExpr = pLower->pExpr->pRight; + rc = sqlite3ValueFromExpr(db, pExpr, SQLITE_UTF8, aff, &pLowerVal); + } + if( rc==SQLITE_OK && pUpper ){ + Expr *pExpr = pUpper->pExpr->pRight; + rc = sqlite3ValueFromExpr(db, pExpr, SQLITE_UTF8, aff, &pUpperVal); + } + + if( rc!=SQLITE_OK || (pLowerVal==0 && pUpperVal==0) ){ + sqlite3ValueFree(pLowerVal); + sqlite3ValueFree(pUpperVal); + goto range_est_fallback; + }else if( pLowerVal==0 ){ + rc = whereRangeRegion(pParse, p, pUpperVal, &iUpper); + if( pLower ) iLower = iUpper/2; + }else if( pUpperVal==0 ){ + rc = whereRangeRegion(pParse, p, pLowerVal, &iLower); + if( pUpper ) iUpper = (iLower + SQLITE_INDEX_SAMPLES + 1)/2; + }else{ + rc = whereRangeRegion(pParse, p, pUpperVal, &iUpper); + if( rc==SQLITE_OK ){ + rc = whereRangeRegion(pParse, p, pLowerVal, &iLower); + } + } + + iEst = iUpper - iLower; + testcase( iEst==SQLITE_INDEX_SAMPLES ); + assert( iEst<=SQLITE_INDEX_SAMPLES ); + if( iEst<1 ){ + iEst = 1; + } + + sqlite3ValueFree(pLowerVal); + sqlite3ValueFree(pUpperVal); + *piEst = (iEst * 100)/SQLITE_INDEX_SAMPLES; + return rc; + } +range_est_fallback: +#else + UNUSED_PARAMETER(pParse); + UNUSED_PARAMETER(p); + UNUSED_PARAMETER(nEq); +#endif + assert( pLower || pUpper ); + if( pLower && pUpper ){ + *piEst = 11; + }else{ + *piEst = 33; + } + return rc; +} + + /* ** Find the query plan for accessing a particular table. Write the ** best query plan and its cost into the WhereCost object supplied as the @@ -84587,290 +88093,314 @@ static void bestBtreeIndex( ExprList *pOrderBy, /* The ORDER BY clause */ WhereCost *pCost /* Lowest cost query plan */ ){ - WhereTerm *pTerm; /* A single term of the WHERE clause */ int iCur = pSrc->iCursor; /* The cursor of the table to be accessed */ Index *pProbe; /* An index we are evaluating */ - int rev; /* True to scan in reverse order */ - int wsFlags; /* Flags associated with pProbe */ - int nEq; /* Number of == or IN constraints */ - int eqTermMask; /* Mask of valid equality operators */ - double cost; /* Cost of using pProbe */ - double nRow; /* Estimated number of rows in result set */ - int i; /* Loop counter */ - - WHERETRACE(("bestIndex: tbl=%s notReady=%llx\n", pSrc->pTab->zName,notReady)); - pProbe = pSrc->pTab->pIndex; - if( pSrc->notIndexed ){ - pProbe = 0; - } - - /* If the table has no indices and there are no terms in the where - ** clause that refer to the ROWID, then we will never be able to do - ** anything other than a full table scan on this table. We might as - ** well put it first in the join order. That way, perhaps it can be - ** referenced by other tables in the join. - */ + Index *pIdx; /* Copy of pProbe, or zero for IPK index */ + int eqTermMask; /* Current mask of valid equality operators */ + int idxEqTermMask; /* Index mask of valid equality operators */ + Index sPk; /* A fake index object for the primary key */ + unsigned int aiRowEstPk[2]; /* The aiRowEst[] value for the sPk index */ + int aiColumnPk = -1; /* The aColumn[] value for the sPk index */ + int wsFlagMask; /* Allowed flags in pCost->plan.wsFlag */ + + /* Initialize the cost to a worst-case value */ memset(pCost, 0, sizeof(*pCost)); - if( pProbe==0 && - findTerm(pWC, iCur, -1, 0, WO_EQ|WO_IN|WO_LT|WO_LE|WO_GT|WO_GE,0)==0 && - (pOrderBy==0 || !sortableByRowid(iCur, pOrderBy, pWC->pMaskSet, &rev)) ){ - if( pParse->db->flags & SQLITE_ReverseOrder ){ - /* For application testing, randomly reverse the output order for - ** SELECT statements that omit the ORDER BY clause. This will help - ** to find cases where - */ - pCost->plan.wsFlags |= WHERE_REVERSE; - } - return; - } pCost->rCost = SQLITE_BIG_DBL; - /* Check for a rowid=EXPR or rowid IN (...) constraints. If there was - ** an INDEXED BY clause attached to this table, skip this step. - */ - if( !pSrc->pIndex ){ - pTerm = findTerm(pWC, iCur, -1, notReady, WO_EQ|WO_IN, 0); - if( pTerm ){ - Expr *pExpr; - pCost->plan.wsFlags = WHERE_ROWID_EQ; - if( pTerm->eOperator & WO_EQ ){ - /* Rowid== is always the best pick. Look no further. Because only - ** a single row is generated, output is always in sorted order */ - pCost->plan.wsFlags = WHERE_ROWID_EQ | WHERE_UNIQUE; - pCost->plan.nEq = 1; - WHERETRACE(("... best is rowid\n")); - pCost->rCost = 0; - pCost->nRow = 1; - return; - }else if( !ExprHasProperty((pExpr = pTerm->pExpr), EP_xIsSelect) - && pExpr->x.pList - ){ - /* Rowid IN (LIST): cost is NlogN where N is the number of list - ** elements. */ - pCost->rCost = pCost->nRow = pExpr->x.pList->nExpr; - pCost->rCost *= estLog(pCost->rCost); - }else{ - /* Rowid IN (SELECT): cost is NlogN where N is the number of rows - ** in the result of the inner select. We have no way to estimate - ** that value so make a wild guess. */ - pCost->nRow = 100; - pCost->rCost = 200; - } - WHERETRACE(("... rowid IN cost: %.9g\n", pCost->rCost)); - } - - /* Estimate the cost of a table scan. If we do not know how many - ** entries are in the table, use 1 million as a guess. - */ - cost = pProbe ? pProbe->aiRowEst[0] : 1000000; - WHERETRACE(("... table scan base cost: %.9g\n", cost)); - wsFlags = WHERE_ROWID_RANGE; - - /* Check for constraints on a range of rowids in a table scan. - */ - pTerm = findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE|WO_GT|WO_GE, 0); - if( pTerm ){ - if( findTerm(pWC, iCur, -1, notReady, WO_LT|WO_LE, 0) ){ - wsFlags |= WHERE_TOP_LIMIT; - cost /= 3; /* Guess that rowidEXPR eliminates two-thirds of rows */ - } - WHERETRACE(("... rowid range reduces cost to %.9g\n", cost)); - }else{ - wsFlags = 0; - } - nRow = cost; - - /* If the table scan does not satisfy the ORDER BY clause, increase - ** the cost by NlogN to cover the expense of sorting. */ - if( pOrderBy ){ - if( sortableByRowid(iCur, pOrderBy, pWC->pMaskSet, &rev) ){ - wsFlags |= WHERE_ORDERBY|WHERE_ROWID_RANGE; - if( rev ){ - wsFlags |= WHERE_REVERSE; - } - }else{ - cost += cost*estLog(cost); - WHERETRACE(("... sorting increases cost to %.9g\n", cost)); - } - }else if( pParse->db->flags & SQLITE_ReverseOrder ){ - /* For application testing, randomly reverse the output order for - ** SELECT statements that omit the ORDER BY clause. This will help - ** to find cases where - */ - wsFlags |= WHERE_REVERSE; - } - - /* Remember this case if it is the best so far */ - if( costrCost ){ - pCost->rCost = cost; - pCost->nRow = nRow; - pCost->plan.wsFlags = wsFlags; - } - } - - bestOrClauseIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost); - /* If the pSrc table is the right table of a LEFT JOIN then we may not ** use an index to satisfy IS NULL constraints on that table. This is ** because columns might end up being NULL if the table does not match - ** a circumstance which the index cannot help us discover. Ticket #2177. */ - if( (pSrc->jointype & JT_LEFT)!=0 ){ - eqTermMask = WO_EQ|WO_IN; + if( pSrc->jointype & JT_LEFT ){ + idxEqTermMask = WO_EQ|WO_IN; }else{ - eqTermMask = WO_EQ|WO_IN|WO_ISNULL; + idxEqTermMask = WO_EQ|WO_IN|WO_ISNULL; } - /* Look at each index. - */ if( pSrc->pIndex ){ - pProbe = pSrc->pIndex; - } - for(; pProbe; pProbe=(pSrc->pIndex ? 0 : pProbe->pNext)){ - double inMultiplier = 1; /* Number of equality look-ups needed */ - int inMultIsEst = 0; /* True if inMultiplier is an estimate */ - - WHERETRACE(("... index %s:\n", pProbe->zName)); - - /* Count the number of columns in the index that are satisfied - ** by x=EXPR or x IS NULL constraints or x IN (...) constraints. - ** For a term of the form x=EXPR or x IS NULL we only have to do - ** a single binary search. But for x IN (...) we have to do a - ** number of binary searched - ** equal to the number of entries on the RHS of the IN operator. - ** The inMultipler variable with try to estimate the number of - ** binary searches needed. + /* An INDEXED BY clause specifies a particular index to use */ + pIdx = pProbe = pSrc->pIndex; + wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE); + eqTermMask = idxEqTermMask; + }else{ + /* There is no INDEXED BY clause. Create a fake Index object to + ** represent the primary key */ + Index *pFirst; /* Any other index on the table */ + memset(&sPk, 0, sizeof(Index)); + sPk.nColumn = 1; + sPk.aiColumn = &aiColumnPk; + sPk.aiRowEst = aiRowEstPk; + aiRowEstPk[1] = 1; + sPk.onError = OE_Replace; + sPk.pTable = pSrc->pTab; + pFirst = pSrc->pTab->pIndex; + if( pSrc->notIndexed==0 ){ + sPk.pNext = pFirst; + } + /* The aiRowEstPk[0] is an estimate of the total number of rows in the + ** table. Get this information from the ANALYZE information if it is + ** available. If not available, assume the table 1 million rows in size. */ - wsFlags = 0; - for(i=0; inColumn; i++){ - int j = pProbe->aiColumn[i]; - pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pProbe); + if( pFirst ){ + assert( pFirst->aiRowEst!=0 ); /* Allocated together with pFirst */ + aiRowEstPk[0] = pFirst->aiRowEst[0]; + }else{ + aiRowEstPk[0] = 1000000; + } + pProbe = &sPk; + wsFlagMask = ~( + WHERE_COLUMN_IN|WHERE_COLUMN_EQ|WHERE_COLUMN_NULL|WHERE_COLUMN_RANGE + ); + eqTermMask = WO_EQ|WO_IN; + pIdx = 0; + } + + /* Loop over all indices looking for the best one to use + */ + for(; pProbe; pIdx=pProbe=pProbe->pNext){ + const unsigned int * const aiRowEst = pProbe->aiRowEst; + double cost; /* Cost of using pProbe */ + double nRow; /* Estimated number of rows in result set */ + int rev; /* True to scan in reverse order */ + int wsFlags = 0; + Bitmask used = 0; + + /* The following variables are populated based on the properties of + ** scan being evaluated. They are then used to determine the expected + ** cost and number of rows returned. + ** + ** nEq: + ** Number of equality terms that can be implemented using the index. + ** + ** nInMul: + ** The "in-multiplier". This is an estimate of how many seek operations + ** SQLite must perform on the index in question. For example, if the + ** WHERE clause is: + ** + ** WHERE a IN (1, 2, 3) AND b IN (4, 5, 6) + ** + ** SQLite must perform 9 lookups on an index on (a, b), so nInMul is + ** set to 9. Given the same schema and either of the following WHERE + ** clauses: + ** + ** WHERE a = 1 + ** WHERE a >= 2 + ** + ** nInMul is set to 1. + ** + ** If there exists a WHERE term of the form "x IN (SELECT ...)", then + ** the sub-select is assumed to return 25 rows for the purposes of + ** determining nInMul. + ** + ** bInEst: + ** Set to true if there was at least one "x IN (SELECT ...)" term used + ** in determining the value of nInMul. + ** + ** nBound: + ** An estimate on the amount of the table that must be searched. A + ** value of 100 means the entire table is searched. Range constraints + ** might reduce this to a value less than 100 to indicate that only + ** a fraction of the table needs searching. In the absence of + ** sqlite_stat2 ANALYZE data, a single inequality reduces the search + ** space to 1/3rd its original size. So an x>? constraint reduces + ** nBound to 33. Two constraints (x>? AND xnColumn; nEq++){ + WhereTerm *pTerm; /* A single term of the WHERE clause */ + int j = pProbe->aiColumn[nEq]; + pTerm = findTerm(pWC, iCur, j, notReady, eqTermMask, pIdx); if( pTerm==0 ) break; - wsFlags |= WHERE_COLUMN_EQ; + wsFlags |= (WHERE_COLUMN_EQ|WHERE_ROWID_EQ); if( pTerm->eOperator & WO_IN ){ Expr *pExpr = pTerm->pExpr; wsFlags |= WHERE_COLUMN_IN; if( ExprHasProperty(pExpr, EP_xIsSelect) ){ - inMultiplier *= 25; - inMultIsEst = 1; + nInMul *= 25; + bInEst = 1; }else if( pExpr->x.pList ){ - inMultiplier *= pExpr->x.pList->nExpr + 1; + nInMul *= pExpr->x.pList->nExpr + 1; } }else if( pTerm->eOperator & WO_ISNULL ){ wsFlags |= WHERE_COLUMN_NULL; } + used |= pTerm->prereqRight; } - nRow = pProbe->aiRowEst[i] * inMultiplier; - /* If inMultiplier is an estimate and that estimate results in an - ** nRow it that is more than half number of rows in the table, - ** then reduce inMultipler */ - if( inMultIsEst && nRow*2 > pProbe->aiRowEst[0] ){ - nRow = pProbe->aiRowEst[0]/2; - inMultiplier = nRow/pProbe->aiRowEst[i]; - } - cost = nRow + inMultiplier*estLog(pProbe->aiRowEst[0]); - nEq = i; - if( pProbe->onError!=OE_None && nEq==pProbe->nColumn ){ - testcase( wsFlags & WHERE_COLUMN_IN ); - testcase( wsFlags & WHERE_COLUMN_NULL ); - if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){ - wsFlags |= WHERE_UNIQUE; - } - } - WHERETRACE(("...... nEq=%d inMult=%.9g nRow=%.9g cost=%.9g\n", - nEq, inMultiplier, nRow, cost)); - /* Look for range constraints. Assume that each range constraint - ** makes the search space 1/3rd smaller. - */ + /* Determine the value of nBound. */ if( nEqnColumn ){ int j = pProbe->aiColumn[nEq]; - pTerm = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pProbe); - if( pTerm ){ - wsFlags |= WHERE_COLUMN_RANGE; - if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pProbe) ){ + if( findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE|WO_GT|WO_GE, pIdx) ){ + WhereTerm *pTop = findTerm(pWC, iCur, j, notReady, WO_LT|WO_LE, pIdx); + WhereTerm *pBtm = findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pIdx); + whereRangeScanEst(pParse, pProbe, nEq, pBtm, pTop, &nBound); + if( pTop ){ wsFlags |= WHERE_TOP_LIMIT; - cost /= 3; - nRow /= 3; + used |= pTop->prereqRight; } - if( findTerm(pWC, iCur, j, notReady, WO_GT|WO_GE, pProbe) ){ + if( pBtm ){ wsFlags |= WHERE_BTM_LIMIT; - cost /= 3; - nRow /= 3; + used |= pBtm->prereqRight; } - WHERETRACE(("...... range reduces nRow to %.9g and cost to %.9g\n", - nRow, cost)); + wsFlags |= (WHERE_COLUMN_RANGE|WHERE_ROWID_RANGE); + } + }else if( pProbe->onError!=OE_None ){ + testcase( wsFlags & WHERE_COLUMN_IN ); + testcase( wsFlags & WHERE_COLUMN_NULL ); + if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 ){ + wsFlags |= WHERE_UNIQUE; } } - /* Add the additional cost of sorting if that is a factor. - */ + /* If there is an ORDER BY clause and the index being considered will + ** naturally scan rows in the required order, set the appropriate flags + ** in wsFlags. Otherwise, if there is an ORDER BY clause but the index + ** will scan rows in a different order, set the bSort variable. */ if( pOrderBy ){ if( (wsFlags & (WHERE_COLUMN_IN|WHERE_COLUMN_NULL))==0 - && isSortingIndex(pParse,pWC->pMaskSet,pProbe,iCur,pOrderBy,nEq,&rev) + && isSortingIndex(pParse,pWC->pMaskSet,pProbe,iCur,pOrderBy,nEq,&rev) ){ - if( wsFlags==0 ){ - wsFlags = WHERE_COLUMN_RANGE; - } - wsFlags |= WHERE_ORDERBY; - if( rev ){ - wsFlags |= WHERE_REVERSE; - } + wsFlags |= WHERE_ROWID_RANGE|WHERE_COLUMN_RANGE|WHERE_ORDERBY; + wsFlags |= (rev ? WHERE_REVERSE : 0); }else{ - cost += cost*estLog(cost); - WHERETRACE(("...... orderby increases cost to %.9g\n", cost)); + bSort = 1; } - }else if( wsFlags!=0 && (pParse->db->flags & SQLITE_ReverseOrder)!=0 ){ - /* For application testing, randomly reverse the output order for - ** SELECT statements that omit the ORDER BY clause. This will help - ** to find cases where - */ - wsFlags |= WHERE_REVERSE; } - /* Check to see if we can get away with using just the index without - ** ever reading the table. If that is the case, then halve the - ** cost of this index. - */ - if( wsFlags && pSrc->colUsed < (((Bitmask)1)<<(BMS-1)) ){ + /* If currently calculating the cost of using an index (not the IPK + ** index), determine if all required column data may be obtained without + ** seeking to entries in the main table (i.e. if the index is a covering + ** index for this query). If it is, set the WHERE_IDX_ONLY flag in + ** wsFlags. Otherwise, set the bLookup variable to true. */ + if( pIdx && wsFlags ){ Bitmask m = pSrc->colUsed; int j; - for(j=0; jnColumn; j++){ - int x = pProbe->aiColumn[j]; + for(j=0; jnColumn; j++){ + int x = pIdx->aiColumn[j]; if( xaiRowEst[0] ){ + nRow = aiRowEst[0]/2; + nInMul = (int)(nRow / aiRowEst[nEq]); + } + + /* Assume constant cost to access a row and logarithmic cost to + ** do a binary search. Hence, the initial cost is the number of output + ** rows plus log2(table-size) times the number of binary searches. */ - if( wsFlags!=0 && cost < pCost->rCost ){ + cost = nRow + nInMul*estLog(aiRowEst[0]); + + /* Adjust the number of rows and the cost downward to reflect rows + ** that are excluded by range constraints. + */ + nRow = (nRow * (double)nBound) / (double)100; + cost = (cost * (double)nBound) / (double)100; + + /* Add in the estimated cost of sorting the result + */ + if( bSort ){ + cost += cost*estLog(cost); + } + + /* If all information can be taken directly from the index, we avoid + ** doing table lookups. This reduces the cost by half. (Not really - + ** this needs to be fixed.) + */ + if( pIdx && bLookup==0 ){ + cost /= (double)2; + } + /**** Cost of using this index has now been computed ****/ + + WHERETRACE(( + "tbl=%s idx=%s nEq=%d nInMul=%d nBound=%d bSort=%d bLookup=%d" + " wsFlags=%d (nRow=%.2f cost=%.2f)\n", + pSrc->pTab->zName, (pIdx ? pIdx->zName : "ipk"), + nEq, nInMul, nBound, bSort, bLookup, wsFlags, nRow, cost + )); + + /* If this index is the best we have seen so far, then record this + ** index and its cost in the pCost structure. + */ + if( (!pIdx || wsFlags) && costrCost ){ pCost->rCost = cost; pCost->nRow = nRow; - pCost->plan.wsFlags = wsFlags; + pCost->used = used; + pCost->plan.wsFlags = (wsFlags&wsFlagMask); pCost->plan.nEq = nEq; - assert( pCost->plan.wsFlags & WHERE_INDEXED ); - pCost->plan.u.pIdx = pProbe; + pCost->plan.u.pIdx = pIdx; } + + /* If there was an INDEXED BY clause, then only that one index is + ** considered. */ + if( pSrc->pIndex ) break; + + /* Reset masks for the next index in the loop */ + wsFlagMask = ~(WHERE_ROWID_EQ|WHERE_ROWID_RANGE); + eqTermMask = idxEqTermMask; } - /* Report the best result - */ + /* If there is no ORDER BY clause and the SQLITE_ReverseOrder flag + ** is set, then reverse the order that the index will be scanned + ** in. This is used for application testing, to help find cases + ** where application behaviour depends on the (undefined) order that + ** SQLite outputs rows in in the absence of an ORDER BY clause. */ + if( !pOrderBy && pParse->db->flags & SQLITE_ReverseOrder ){ + pCost->plan.wsFlags |= WHERE_REVERSE; + } + + assert( pOrderBy || (pCost->plan.wsFlags&WHERE_ORDERBY)==0 ); + assert( pCost->plan.u.pIdx==0 || (pCost->plan.wsFlags&WHERE_ROWID_EQ)==0 ); + assert( pSrc->pIndex==0 + || pCost->plan.u.pIdx==0 + || pCost->plan.u.pIdx==pSrc->pIndex + ); + + WHERETRACE(("best index is: %s\n", + (pCost->plan.u.pIdx ? pCost->plan.u.pIdx->zName : "ipk") + )); + + bestOrClauseIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost); pCost->plan.wsFlags |= eqTermMask; - WHERETRACE(("best index is %s, cost=%.9g, nrow=%.9g, wsFlags=%x, nEq=%d\n", - (pCost->plan.wsFlags & WHERE_INDEXED)!=0 ? - pCost->plan.u.pIdx->zName : "(none)", pCost->nRow, - pCost->rCost, pCost->plan.wsFlags, pCost->plan.nEq)); } /* @@ -84887,6 +88417,7 @@ static void bestIndex( ExprList *pOrderBy, /* The ORDER BY clause */ WhereCost *pCost /* Lowest cost query plan */ ){ +#ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pSrc->pTab) ){ sqlite3_index_info *p = 0; bestVirtualIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost, &p); @@ -84894,7 +88425,9 @@ static void bestIndex( sqlite3_free(p->idxStr); } sqlite3DbFree(pParse->db, p); - }else{ + }else +#endif + { bestBtreeIndex(pParse, pWC, pSrc, notReady, pOrderBy, pCost); } } @@ -84938,17 +88471,19 @@ static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){ } /* -** Apply the affinities associated with the first n columns of index -** pIdx to the values in the n registers starting at base. +** Code an OP_Affinity opcode to apply the column affinity string zAff +** to the n registers starting at base. +** +** Buffer zAff was allocated using sqlite3DbMalloc(). It is the +** responsibility of this function to arrange for it to be eventually +** freed using sqlite3DbFree(). */ -static void codeApplyAffinity(Parse *pParse, int base, int n, Index *pIdx){ - if( n>0 ){ - Vdbe *v = pParse->pVdbe; - assert( v!=0 ); - sqlite3VdbeAddOp2(v, OP_Affinity, base, n); - sqlite3IndexAffinityStr(v, pIdx); - sqlite3ExprCacheAffinityChange(pParse, base, n); - } +static void codeApplyAffinity(Parse *pParse, int base, int n, char *zAff){ + Vdbe *v = pParse->pVdbe; + assert( v!=0 ); + sqlite3VdbeAddOp2(v, OP_Affinity, base, n); + sqlite3VdbeChangeP4(v, -1, zAff, P4_DYNAMIC); + sqlite3ExprCacheAffinityChange(pParse, base, n); } @@ -85039,13 +88574,29 @@ static int codeEqualityTerm( ** key value of the loop. If one or more IN operators appear, then ** this routine allocates an additional nEq memory cells for internal ** use. +** +** Before returning, *pzAff is set to point to a buffer containing a +** copy of the column affinity string of the index allocated using +** sqlite3DbMalloc(). Except, entries in the copy of the string associated +** with equality constraints that use NONE affinity are set to +** SQLITE_AFF_NONE. This is to deal with SQL such as the following: +** +** CREATE TABLE t1(a TEXT PRIMARY KEY, b); +** SELECT ... FROM t1 AS t2, t1 WHERE t1.a = t2.b; +** +** In the example above, the index on t1(a) has TEXT affinity. But since +** the right hand side of the equality constraint (t2.b) has NONE affinity, +** no conversion should be attempted before using a t2.b value as part of +** a key to search the index. Hence the first byte in the returned affinity +** string in this example would be set to SQLITE_AFF_NONE. */ static int codeAllEqualityTerms( Parse *pParse, /* Parsing context */ WhereLevel *pLevel, /* Which nested loop of the FROM we are coding */ WhereClause *pWC, /* The WHERE clause */ Bitmask notReady, /* Which parts of FROM have not yet been coded */ - int nExtraReg /* Number of extra registers to allocate */ + int nExtraReg, /* Number of extra registers to allocate */ + char **pzAff /* OUT: Set to point to affinity string */ ){ int nEq = pLevel->plan.nEq; /* The number of == or IN constraints to code */ Vdbe *v = pParse->pVdbe; /* The vm under construction */ @@ -85055,6 +88606,7 @@ static int codeAllEqualityTerms( int j; /* Loop counter */ int regBase; /* Base register */ int nReg; /* Number of registers to allocate */ + char *zAff; /* Affinity string to return */ /* This module is only called on query plans that use an index. */ assert( pLevel->plan.wsFlags & WHERE_INDEXED ); @@ -85066,6 +88618,11 @@ static int codeAllEqualityTerms( nReg = pLevel->plan.nEq + nExtraReg; pParse->nMem += nReg; + zAff = sqlite3DbStrDup(pParse->db, sqlite3IndexAffinityStr(v, pIdx)); + if( !zAff ){ + pParse->db->mallocFailed = 1; + } + /* Evaluate the equality constraints */ assert( pIdx->nColumn>=nEq ); @@ -85088,8 +88645,14 @@ static int codeAllEqualityTerms( testcase( pTerm->eOperator & WO_IN ); if( (pTerm->eOperator & (WO_ISNULL|WO_IN))==0 ){ sqlite3VdbeAddOp2(v, OP_IsNull, regBase+j, pLevel->addrBrk); + if( zAff + && sqlite3CompareAffinity(pTerm->pExpr->pRight, zAff[j])==SQLITE_AFF_NONE + ){ + zAff[j] = SQLITE_AFF_NONE; + } } } + *pzAff = zAff; return regBase; } @@ -85345,6 +88908,7 @@ static Bitmask codeOneLoopStart( int iIdxCur; /* The VDBE cursor for the index */ int nExtraReg = 0; /* Number of extra registers needed */ int op; /* Instruction opcode */ + char *zAff; pIdx = pLevel->plan.u.pIdx; iIdxCur = pLevel->iIdxCur; @@ -85384,10 +88948,11 @@ static Bitmask codeOneLoopStart( ** and store the values of those terms in an array of registers ** starting at regBase. */ - regBase = codeAllEqualityTerms(pParse, pLevel, pWC, notReady, nExtraReg); + regBase = codeAllEqualityTerms( + pParse, pLevel, pWC, notReady, nExtraReg, &zAff + ); addrNxt = pLevel->addrNxt; - /* If we are doing a reverse order scan on an ascending index, or ** a forward order scan on a descending index, interchange the ** start and end terms (pRangeStart and pRangeEnd). @@ -85407,8 +88972,17 @@ static Bitmask codeOneLoopStart( /* Seek the index cursor to the start of the range. */ nConstraint = nEq; if( pRangeStart ){ - sqlite3ExprCode(pParse, pRangeStart->pExpr->pRight, regBase+nEq); + Expr *pRight = pRangeStart->pExpr->pRight; + sqlite3ExprCode(pParse, pRight, regBase+nEq); sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); + if( zAff + && sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE + ){ + /* Since the comparison is to be performed with no conversions applied + ** to the operands, set the affinity to apply to pRight to + ** SQLITE_AFF_NONE. */ + zAff[nConstraint] = SQLITE_AFF_NONE; + } nConstraint++; }else if( isMinQuery ){ sqlite3VdbeAddOp2(v, OP_Null, 0, regBase+nEq); @@ -85416,7 +88990,7 @@ static Bitmask codeOneLoopStart( startEq = 0; start_constraints = 1; } - codeApplyAffinity(pParse, regBase, nConstraint, pIdx); + codeApplyAffinity(pParse, regBase, nConstraint, zAff); op = aStartOp[(start_constraints<<2) + (startEq<<1) + bRev]; assert( op!=0 ); testcase( op==OP_Rewind ); @@ -85433,10 +89007,20 @@ static Bitmask codeOneLoopStart( */ nConstraint = nEq; if( pRangeEnd ){ + Expr *pRight = pRangeEnd->pExpr->pRight; sqlite3ExprCacheRemove(pParse, regBase+nEq); - sqlite3ExprCode(pParse, pRangeEnd->pExpr->pRight, regBase+nEq); + sqlite3ExprCode(pParse, pRight, regBase+nEq); sqlite3VdbeAddOp2(v, OP_IsNull, regBase+nEq, addrNxt); - codeApplyAffinity(pParse, regBase, nEq+1, pIdx); + zAff = sqlite3DbStrDup(pParse->db, zAff); + if( zAff + && sqlite3CompareAffinity(pRight, zAff[nConstraint])==SQLITE_AFF_NONE + ){ + /* Since the comparison is to be performed with no conversions applied + ** to the operands, set the affinity to apply to pRight to + ** SQLITE_AFF_NONE. */ + zAff[nConstraint] = SQLITE_AFF_NONE; + } + codeApplyAffinity(pParse, regBase, nEq+1, zAff); nConstraint++; } @@ -85530,8 +89114,8 @@ static Bitmask codeOneLoopStart( SrcList oneTab; /* Shortened table list */ int regReturn = ++pParse->nMem; /* Register used with OP_Gosub */ - int regRowset; /* Register for RowSet object */ - int regRowid; /* Register holding rowid */ + int regRowset = 0; /* Register for RowSet object */ + int regRowid = 0; /* Register holding rowid */ int iLoopBody = sqlite3VdbeMakeLabel(v); /* Start of loop body */ int iRetInit; /* Address of regReturn init */ int ii; @@ -85579,7 +89163,7 @@ static Bitmask codeOneLoopStart( int r; r = sqlite3ExprCodeGetColumn(pParse, pTabItem->pTab, -1, iCur, regRowid, 0); - sqlite3VdbeAddOp4(v, OP_RowSetTest, regRowset, + sqlite3VdbeAddOp4(v, OP_RowSetTest, regRowset, sqlite3VdbeCurrentAddr(v)+2, r, SQLITE_INT_TO_PTR(iSet), P4_INT32); } @@ -85870,9 +89454,11 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( assert( pWC->vmask==0 && pMaskSet->n==0 ); for(i=0; inSrc; i++){ createMask(pMaskSet, pTabList->a[i].iCursor); +#ifndef SQLITE_OMIT_VIRTUALTABLE if( ALWAYS(pTabList->a[i].pTab) && IsVirtual(pTabList->a[i].pTab) ){ pWC->vmask |= ((Bitmask)1 << i); } +#endif } #ifndef NDEBUG { @@ -85919,44 +89505,84 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( WhereCost bestPlan; /* Most efficient plan seen so far */ Index *pIdx; /* Index for FROM table at pTabItem */ int j; /* For looping over FROM tables */ - int bestJ = 0; /* The value of j */ + int bestJ = -1; /* The value of j */ Bitmask m; /* Bitmask value for j or bestJ */ - int once = 0; /* True when first table is seen */ + int isOptimal; /* Iterator for optimal/non-optimal search */ memset(&bestPlan, 0, sizeof(bestPlan)); bestPlan.rCost = SQLITE_BIG_DBL; - for(j=iFrom, pTabItem=&pTabList->a[j]; jnSrc; j++, pTabItem++){ - int doNotReorder; /* True if this table should not be reordered */ - WhereCost sCost; /* Cost information from best[Virtual]Index() */ - ExprList *pOrderBy; /* ORDER BY clause for index to optimize */ - - doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0; - if( once && doNotReorder ) break; - m = getMask(pMaskSet, pTabItem->iCursor); - if( (m & notReady)==0 ){ - if( j==iFrom ) iFrom++; - continue; - } - pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0); - assert( pTabItem->pTab ); + /* Loop through the remaining entries in the FROM clause to find the + ** next nested loop. The FROM clause entries may be iterated through + ** either once or twice. + ** + ** The first iteration, which is always performed, searches for the + ** FROM clause entry that permits the lowest-cost, "optimal" scan. In + ** this context an optimal scan is one that uses the same strategy + ** for the given FROM clause entry as would be selected if the entry + ** were used as the innermost nested loop. In other words, a table + ** is chosen such that the cost of running that table cannot be reduced + ** by waiting for other tables to run first. + ** + ** The second iteration is only performed if no optimal scan strategies + ** were found by the first. This iteration is used to search for the + ** lowest cost scan overall. + ** + ** Previous versions of SQLite performed only the second iteration - + ** the next outermost loop was always that with the lowest overall + ** cost. However, this meant that SQLite could select the wrong plan + ** for scripts such as the following: + ** + ** CREATE TABLE t1(a, b); + ** CREATE TABLE t2(c, d); + ** SELECT * FROM t2, t1 WHERE t2.rowid = t1.a; + ** + ** The best strategy is to iterate through table t1 first. However it + ** is not possible to determine this with a simple greedy algorithm. + ** However, since the cost of a linear scan through table t2 is the same + ** as the cost of a linear scan through table t1, a simple greedy + ** algorithm may choose to use t2 for the outer loop, which is a much + ** costlier approach. + */ + for(isOptimal=1; isOptimal>=0 && bestJ<0; isOptimal--){ + Bitmask mask = (isOptimal ? 0 : notReady); + assert( (pTabList->nSrc-iFrom)>1 || isOptimal ); + for(j=iFrom, pTabItem=&pTabList->a[j]; jnSrc; j++, pTabItem++){ + int doNotReorder; /* True if this table should not be reordered */ + WhereCost sCost; /* Cost information from best[Virtual]Index() */ + ExprList *pOrderBy; /* ORDER BY clause for index to optimize */ + + doNotReorder = (pTabItem->jointype & (JT_LEFT|JT_CROSS))!=0; + if( j!=iFrom && doNotReorder ) break; + m = getMask(pMaskSet, pTabItem->iCursor); + if( (m & notReady)==0 ){ + if( j==iFrom ) iFrom++; + continue; + } + pOrderBy = ((i==0 && ppOrderBy )?*ppOrderBy:0); + + assert( pTabItem->pTab ); #ifndef SQLITE_OMIT_VIRTUALTABLE - if( IsVirtual(pTabItem->pTab) ){ - sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo; - bestVirtualIndex(pParse, pWC, pTabItem, notReady, pOrderBy, &sCost, pp); - }else + if( IsVirtual(pTabItem->pTab) ){ + sqlite3_index_info **pp = &pWInfo->a[j].pIdxInfo; + bestVirtualIndex(pParse, pWC, pTabItem, mask, pOrderBy, &sCost, pp); + }else #endif - { - bestBtreeIndex(pParse, pWC, pTabItem, notReady, pOrderBy, &sCost); - } - if( once==0 || sCost.rCost=0 ); assert( notReady & getMask(pMaskSet, pTabList->a[bestJ].iCursor) ); WHERETRACE(("*** Optimizer selects table %d for loop %d\n", bestJ, pLevel-pWInfo->a)); @@ -86053,13 +89679,13 @@ SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin( #endif /* SQLITE_OMIT_EXPLAIN */ pTabItem = &pTabList->a[pLevel->iFrom]; pTab = pTabItem->pTab; - iDb = sqlite3SchemaToIndex(pParse->db, pTab->pSchema); + iDb = sqlite3SchemaToIndex(db, pTab->pSchema); if( (pTab->tabFlags & TF_Ephemeral)!=0 || pTab->pSelect ) continue; #ifndef SQLITE_OMIT_VIRTUALTABLE if( (pLevel->plan.wsFlags & WHERE_VIRTUALTABLE)!=0 ){ + const char *pVTab = (const char *)sqlite3GetVTable(db, pTab); int iCur = pTabItem->iCursor; - sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, - (const char*)pTab->pVtab, P4_VTAB); + sqlite3VdbeAddOp4(v, OP_VOpen, iCur, 0, 0, pVTab, P4_VTAB); }else #endif if( (pLevel->plan.wsFlags & WHERE_IDX_ONLY)==0 @@ -86285,6 +89911,12 @@ SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo *pWInfo){ /************** Begin file parse.c *******************************************/ /* Driver template for the LEMON parser generator. ** The author disclaims copyright to this source code. +** +** This version of "lempar.c" is modified, slightly, for use by SQLite. +** The only modifications are the addition of a couple of NEVER() +** macros to disable tests that are needed in the case of a general +** LALR(1) grammar but which are always false in the +** specific grammar used by SQLite. */ /* First off, code is included that follows the "include" declaration ** in the input grammar file. */ @@ -86447,25 +90079,26 @@ struct AttachKey { int type; Token key; }; ** defined, then do no error processing. */ #define YYCODETYPE unsigned char -#define YYNOCODE 252 +#define YYNOCODE 254 #define YYACTIONTYPE unsigned short int -#define YYWILDCARD 65 +#define YYWILDCARD 67 #define sqlite3ParserTOKENTYPE Token typedef union { int yyinit; sqlite3ParserTOKENTYPE yy0; - Expr* yy72; - TriggerStep* yy145; - ExprList* yy148; - SrcList* yy185; - ExprSpan yy190; - int yy194; - Select* yy243; - IdList* yy254; - struct TrigEvent yy332; - struct LimitVal yy354; - struct LikeOp yy392; - struct {int value; int mask;} yy497; + Select* yy3; + ExprList* yy14; + SrcList* yy65; + struct LikeOp yy96; + Expr* yy132; + u8 yy186; + int yy328; + ExprSpan yy346; + struct TrigEvent yy378; + IdList* yy408; + struct {int value; int mask;} yy429; + TriggerStep* yy473; + struct LimitVal yy476; } YYMINORTYPE; #ifndef YYSTACKDEPTH #define YYSTACKDEPTH 100 @@ -86474,8 +90107,8 @@ typedef union { #define sqlite3ParserARG_PDECL ,Parse *pParse #define sqlite3ParserARG_FETCH Parse *pParse = yypParser->pParse #define sqlite3ParserARG_STORE yypParser->pParse = pParse -#define YYNSTATE 619 -#define YYNRULE 324 +#define YYNSTATE 629 +#define YYNRULE 329 #define YYFALLBACK 1 #define YY_NO_ACTION (YYNSTATE+YYNRULE+2) #define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) @@ -86546,454 +90179,465 @@ static const YYMINORTYPE yyzerominor = { 0 }; ** yy_default[] Default action for each state. */ static const YYACTIONTYPE yy_action[] = { - /* 0 */ 305, 944, 176, 618, 2, 150, 214, 441, 24, 24, - /* 10 */ 24, 24, 490, 26, 26, 26, 26, 27, 27, 28, - /* 20 */ 28, 28, 29, 216, 415, 416, 212, 415, 416, 448, - /* 30 */ 454, 31, 26, 26, 26, 26, 27, 27, 28, 28, - /* 40 */ 28, 29, 216, 30, 485, 32, 134, 23, 22, 311, - /* 50 */ 458, 459, 455, 455, 25, 25, 24, 24, 24, 24, - /* 60 */ 438, 26, 26, 26, 26, 27, 27, 28, 28, 28, - /* 70 */ 29, 216, 305, 216, 314, 441, 514, 492, 45, 26, - /* 80 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216, - /* 90 */ 415, 416, 418, 419, 156, 418, 419, 362, 365, 366, - /* 100 */ 314, 448, 454, 387, 516, 21, 186, 497, 367, 27, - /* 110 */ 27, 28, 28, 28, 29, 216, 415, 416, 417, 23, - /* 120 */ 22, 311, 458, 459, 455, 455, 25, 25, 24, 24, - /* 130 */ 24, 24, 557, 26, 26, 26, 26, 27, 27, 28, - /* 140 */ 28, 28, 29, 216, 305, 228, 506, 135, 470, 218, - /* 150 */ 550, 145, 132, 256, 360, 261, 361, 153, 418, 419, - /* 160 */ 241, 600, 333, 30, 265, 32, 134, 441, 598, 599, - /* 170 */ 230, 228, 492, 448, 454, 57, 508, 330, 132, 256, - /* 180 */ 360, 261, 361, 153, 418, 419, 437, 78, 410, 407, - /* 190 */ 265, 23, 22, 311, 458, 459, 455, 455, 25, 25, - /* 200 */ 24, 24, 24, 24, 344, 26, 26, 26, 26, 27, - /* 210 */ 27, 28, 28, 28, 29, 216, 305, 214, 536, 549, - /* 220 */ 308, 127, 491, 597, 30, 333, 32, 134, 347, 389, - /* 230 */ 431, 63, 333, 357, 417, 441, 509, 333, 417, 537, - /* 240 */ 330, 215, 193, 596, 595, 448, 454, 330, 18, 437, - /* 250 */ 85, 16, 330, 183, 190, 558, 437, 78, 312, 465, - /* 260 */ 466, 437, 85, 23, 22, 311, 458, 459, 455, 455, - /* 270 */ 25, 25, 24, 24, 24, 24, 438, 26, 26, 26, - /* 280 */ 26, 27, 27, 28, 28, 28, 29, 216, 305, 349, - /* 290 */ 221, 316, 597, 191, 380, 333, 474, 234, 347, 383, - /* 300 */ 326, 412, 220, 346, 594, 217, 213, 417, 112, 333, - /* 310 */ 330, 4, 596, 401, 211, 556, 531, 448, 454, 437, - /* 320 */ 79, 217, 555, 517, 330, 336, 515, 461, 461, 471, - /* 330 */ 443, 574, 434, 437, 78, 23, 22, 311, 458, 459, - /* 340 */ 455, 455, 25, 25, 24, 24, 24, 24, 438, 26, - /* 350 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216, - /* 360 */ 305, 445, 445, 445, 156, 470, 218, 362, 365, 366, - /* 370 */ 333, 247, 397, 400, 217, 351, 333, 30, 367, 32, - /* 380 */ 134, 390, 282, 281, 39, 330, 41, 432, 547, 448, - /* 390 */ 454, 330, 214, 533, 437, 93, 544, 603, 1, 406, - /* 400 */ 437, 93, 415, 416, 497, 40, 538, 23, 22, 311, - /* 410 */ 458, 459, 455, 455, 25, 25, 24, 24, 24, 24, - /* 420 */ 575, 26, 26, 26, 26, 27, 27, 28, 28, 28, - /* 430 */ 29, 216, 305, 276, 333, 179, 510, 492, 210, 549, - /* 440 */ 322, 415, 416, 222, 192, 387, 323, 240, 417, 330, - /* 450 */ 559, 63, 415, 416, 417, 619, 410, 407, 437, 71, - /* 460 */ 417, 448, 454, 539, 574, 28, 28, 28, 29, 216, - /* 470 */ 418, 419, 438, 338, 465, 466, 403, 43, 438, 23, - /* 480 */ 22, 311, 458, 459, 455, 455, 25, 25, 24, 24, - /* 490 */ 24, 24, 497, 26, 26, 26, 26, 27, 27, 28, - /* 500 */ 28, 28, 29, 216, 305, 429, 209, 135, 513, 418, - /* 510 */ 419, 433, 233, 64, 390, 282, 281, 441, 66, 544, - /* 520 */ 418, 419, 415, 416, 156, 214, 405, 362, 365, 366, - /* 530 */ 549, 252, 492, 448, 454, 493, 217, 8, 367, 497, - /* 540 */ 438, 608, 63, 208, 299, 417, 494, 472, 548, 200, - /* 550 */ 196, 23, 22, 311, 458, 459, 455, 455, 25, 25, - /* 560 */ 24, 24, 24, 24, 388, 26, 26, 26, 26, 27, - /* 570 */ 27, 28, 28, 28, 29, 216, 305, 479, 254, 356, - /* 580 */ 530, 60, 519, 520, 438, 441, 391, 333, 358, 7, - /* 590 */ 418, 419, 333, 480, 330, 374, 197, 137, 462, 501, - /* 600 */ 449, 450, 330, 437, 9, 448, 454, 330, 481, 487, - /* 610 */ 521, 437, 72, 569, 417, 436, 437, 67, 488, 435, - /* 620 */ 522, 452, 453, 23, 22, 311, 458, 459, 455, 455, - /* 630 */ 25, 25, 24, 24, 24, 24, 333, 26, 26, 26, - /* 640 */ 26, 27, 27, 28, 28, 28, 29, 216, 305, 333, - /* 650 */ 451, 330, 268, 392, 463, 333, 65, 333, 370, 436, - /* 660 */ 437, 76, 313, 435, 330, 150, 185, 441, 475, 333, - /* 670 */ 330, 501, 330, 437, 97, 29, 216, 448, 454, 437, - /* 680 */ 96, 437, 101, 355, 330, 242, 417, 336, 154, 461, - /* 690 */ 461, 354, 571, 437, 99, 23, 22, 311, 458, 459, - /* 700 */ 455, 455, 25, 25, 24, 24, 24, 24, 333, 26, - /* 710 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216, - /* 720 */ 305, 333, 248, 330, 264, 56, 336, 333, 461, 461, - /* 730 */ 864, 335, 437, 104, 378, 441, 330, 417, 333, 417, - /* 740 */ 567, 333, 330, 307, 566, 437, 105, 442, 265, 448, - /* 750 */ 454, 437, 126, 330, 572, 520, 330, 336, 379, 461, - /* 760 */ 461, 317, 437, 128, 194, 437, 59, 23, 22, 311, - /* 770 */ 458, 459, 455, 455, 25, 25, 24, 24, 24, 24, - /* 780 */ 333, 26, 26, 26, 26, 27, 27, 28, 28, 28, - /* 790 */ 29, 216, 305, 333, 136, 330, 467, 479, 438, 333, - /* 800 */ 352, 333, 611, 303, 437, 102, 201, 137, 330, 417, - /* 810 */ 456, 178, 333, 480, 330, 417, 330, 437, 77, 486, - /* 820 */ 249, 448, 454, 437, 100, 437, 68, 330, 481, 469, - /* 830 */ 343, 616, 934, 341, 934, 417, 437, 98, 489, 23, - /* 840 */ 22, 311, 458, 459, 455, 455, 25, 25, 24, 24, - /* 850 */ 24, 24, 333, 26, 26, 26, 26, 27, 27, 28, - /* 860 */ 28, 28, 29, 216, 305, 333, 399, 330, 164, 264, - /* 870 */ 205, 333, 264, 334, 612, 250, 437, 129, 409, 2, - /* 880 */ 330, 325, 175, 333, 417, 214, 330, 417, 417, 437, - /* 890 */ 130, 468, 468, 448, 454, 437, 131, 398, 330, 257, - /* 900 */ 336, 259, 461, 461, 438, 154, 229, 437, 69, 318, - /* 910 */ 258, 23, 33, 311, 458, 459, 455, 455, 25, 25, - /* 920 */ 24, 24, 24, 24, 333, 26, 26, 26, 26, 27, - /* 930 */ 27, 28, 28, 28, 29, 216, 305, 333, 155, 330, - /* 940 */ 531, 264, 414, 333, 264, 472, 339, 200, 437, 80, - /* 950 */ 542, 499, 330, 151, 541, 333, 417, 417, 330, 417, - /* 960 */ 307, 437, 81, 535, 534, 448, 454, 437, 70, 47, - /* 970 */ 330, 616, 933, 543, 933, 420, 421, 422, 319, 437, - /* 980 */ 82, 320, 304, 613, 22, 311, 458, 459, 455, 455, - /* 990 */ 25, 25, 24, 24, 24, 24, 333, 26, 26, 26, - /* 1000 */ 26, 27, 27, 28, 28, 28, 29, 216, 305, 333, - /* 1010 */ 209, 330, 364, 206, 612, 333, 528, 565, 377, 565, - /* 1020 */ 437, 83, 525, 526, 330, 615, 545, 333, 501, 577, - /* 1030 */ 330, 333, 290, 437, 84, 426, 396, 448, 454, 437, - /* 1040 */ 86, 590, 330, 417, 438, 141, 330, 438, 413, 423, - /* 1050 */ 417, 437, 87, 424, 327, 437, 88, 311, 458, 459, - /* 1060 */ 455, 455, 25, 25, 24, 24, 24, 24, 388, 26, - /* 1070 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 216, - /* 1080 */ 35, 340, 286, 3, 333, 270, 333, 329, 416, 142, - /* 1090 */ 384, 321, 276, 425, 144, 35, 340, 337, 3, 330, - /* 1100 */ 6, 330, 329, 416, 304, 614, 276, 417, 437, 73, - /* 1110 */ 437, 74, 337, 333, 328, 342, 427, 333, 439, 333, - /* 1120 */ 540, 417, 155, 47, 289, 474, 287, 274, 330, 272, - /* 1130 */ 342, 417, 330, 350, 330, 277, 276, 437, 89, 243, - /* 1140 */ 474, 437, 90, 437, 91, 38, 37, 615, 333, 584, - /* 1150 */ 244, 417, 428, 276, 36, 331, 332, 46, 245, 443, - /* 1160 */ 38, 37, 507, 330, 202, 203, 204, 417, 417, 36, - /* 1170 */ 331, 332, 437, 92, 443, 198, 267, 214, 155, 586, - /* 1180 */ 235, 236, 237, 143, 239, 348, 133, 583, 440, 246, - /* 1190 */ 445, 445, 445, 446, 447, 10, 587, 276, 20, 42, - /* 1200 */ 172, 417, 294, 333, 288, 445, 445, 445, 446, 447, - /* 1210 */ 10, 295, 417, 35, 340, 219, 3, 149, 330, 484, - /* 1220 */ 329, 416, 333, 170, 276, 574, 48, 437, 75, 169, - /* 1230 */ 337, 19, 171, 251, 444, 415, 416, 330, 333, 417, - /* 1240 */ 588, 345, 276, 177, 353, 498, 437, 17, 342, 417, - /* 1250 */ 483, 253, 255, 330, 276, 496, 417, 417, 474, 333, - /* 1260 */ 504, 505, 437, 94, 369, 417, 155, 231, 359, 417, - /* 1270 */ 417, 518, 523, 474, 330, 395, 291, 281, 38, 37, - /* 1280 */ 500, 306, 315, 437, 95, 232, 214, 36, 331, 332, - /* 1290 */ 524, 502, 443, 188, 189, 417, 262, 292, 532, 263, - /* 1300 */ 551, 260, 269, 515, 271, 273, 417, 443, 570, 402, - /* 1310 */ 155, 417, 527, 417, 417, 417, 275, 417, 280, 417, - /* 1320 */ 417, 382, 385, 445, 445, 445, 446, 447, 10, 528, - /* 1330 */ 386, 417, 283, 417, 284, 285, 417, 417, 445, 445, - /* 1340 */ 445, 582, 593, 293, 107, 417, 296, 417, 297, 417, - /* 1350 */ 417, 607, 578, 529, 151, 300, 417, 417, 417, 226, - /* 1360 */ 579, 417, 54, 417, 158, 591, 417, 54, 225, 610, - /* 1370 */ 227, 302, 546, 552, 301, 553, 554, 371, 560, 159, - /* 1380 */ 375, 373, 207, 160, 51, 562, 563, 161, 117, 278, - /* 1390 */ 381, 140, 573, 163, 181, 393, 394, 118, 119, 120, - /* 1400 */ 180, 580, 121, 123, 324, 605, 604, 606, 55, 609, - /* 1410 */ 589, 309, 224, 62, 58, 103, 411, 111, 238, 430, - /* 1420 */ 199, 174, 660, 661, 662, 146, 147, 460, 310, 457, - /* 1430 */ 34, 476, 464, 473, 182, 195, 148, 477, 5, 478, - /* 1440 */ 482, 12, 138, 44, 11, 106, 495, 511, 512, 503, - /* 1450 */ 223, 49, 363, 108, 109, 152, 266, 50, 110, 157, - /* 1460 */ 258, 372, 184, 561, 139, 113, 151, 162, 279, 115, - /* 1470 */ 376, 15, 576, 116, 165, 52, 13, 368, 581, 53, - /* 1480 */ 167, 166, 585, 122, 124, 114, 592, 564, 568, 168, - /* 1490 */ 14, 61, 601, 602, 173, 298, 125, 408, 187, 617, - /* 1500 */ 945, 945, 404, + /* 0 */ 312, 959, 182, 628, 2, 157, 219, 450, 24, 24, + /* 10 */ 24, 24, 221, 26, 26, 26, 26, 27, 27, 28, + /* 20 */ 28, 28, 29, 221, 424, 425, 30, 492, 33, 141, + /* 30 */ 457, 463, 31, 26, 26, 26, 26, 27, 27, 28, + /* 40 */ 28, 28, 29, 221, 28, 28, 28, 29, 221, 23, + /* 50 */ 22, 32, 465, 466, 464, 464, 25, 25, 24, 24, + /* 60 */ 24, 24, 293, 26, 26, 26, 26, 27, 27, 28, + /* 70 */ 28, 28, 29, 221, 312, 450, 319, 479, 344, 208, + /* 80 */ 47, 26, 26, 26, 26, 27, 27, 28, 28, 28, + /* 90 */ 29, 221, 427, 428, 163, 339, 543, 368, 371, 372, + /* 100 */ 521, 317, 472, 473, 457, 463, 296, 373, 294, 21, + /* 110 */ 336, 367, 419, 416, 424, 425, 523, 1, 544, 446, + /* 120 */ 80, 424, 425, 23, 22, 32, 465, 466, 464, 464, + /* 130 */ 25, 25, 24, 24, 24, 24, 564, 26, 26, 26, + /* 140 */ 26, 27, 27, 28, 28, 28, 29, 221, 312, 233, + /* 150 */ 319, 441, 554, 152, 139, 263, 365, 268, 366, 160, + /* 160 */ 551, 352, 332, 421, 222, 272, 362, 322, 218, 557, + /* 170 */ 116, 339, 248, 574, 477, 223, 216, 573, 457, 463, + /* 180 */ 450, 59, 427, 428, 295, 610, 336, 563, 538, 427, + /* 190 */ 428, 385, 608, 609, 562, 446, 87, 23, 22, 32, + /* 200 */ 465, 466, 464, 464, 25, 25, 24, 24, 24, 24, + /* 210 */ 447, 26, 26, 26, 26, 27, 27, 28, 28, 28, + /* 220 */ 29, 221, 312, 233, 477, 223, 576, 134, 139, 263, + /* 230 */ 365, 268, 366, 160, 406, 354, 226, 498, 481, 272, + /* 240 */ 339, 27, 27, 28, 28, 28, 29, 221, 450, 442, + /* 250 */ 199, 540, 457, 463, 349, 336, 163, 551, 66, 368, + /* 260 */ 371, 372, 450, 415, 446, 80, 522, 581, 401, 373, + /* 270 */ 452, 23, 22, 32, 465, 466, 464, 464, 25, 25, + /* 280 */ 24, 24, 24, 24, 447, 26, 26, 26, 26, 27, + /* 290 */ 27, 28, 28, 28, 29, 221, 312, 339, 556, 607, + /* 300 */ 197, 454, 454, 454, 546, 578, 352, 198, 607, 440, + /* 310 */ 65, 351, 336, 426, 426, 399, 289, 424, 425, 606, + /* 320 */ 605, 446, 73, 426, 214, 219, 457, 463, 606, 410, + /* 330 */ 450, 241, 306, 196, 565, 479, 555, 208, 288, 29, + /* 340 */ 221, 447, 4, 874, 504, 23, 22, 32, 465, 466, + /* 350 */ 464, 464, 25, 25, 24, 24, 24, 24, 447, 26, + /* 360 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 221, + /* 370 */ 312, 163, 582, 339, 368, 371, 372, 314, 424, 425, + /* 380 */ 604, 222, 397, 227, 373, 427, 428, 339, 336, 409, + /* 390 */ 222, 478, 339, 30, 396, 33, 141, 446, 81, 62, + /* 400 */ 457, 463, 336, 157, 400, 450, 504, 336, 438, 426, + /* 410 */ 500, 446, 87, 41, 380, 613, 446, 80, 581, 23, + /* 420 */ 22, 32, 465, 466, 464, 464, 25, 25, 24, 24, + /* 430 */ 24, 24, 213, 26, 26, 26, 26, 27, 27, 28, + /* 440 */ 28, 28, 29, 221, 312, 513, 427, 428, 517, 254, + /* 450 */ 524, 386, 225, 339, 486, 363, 389, 339, 356, 443, + /* 460 */ 494, 236, 30, 497, 33, 141, 399, 289, 336, 495, + /* 470 */ 487, 501, 336, 450, 457, 463, 219, 446, 95, 445, + /* 480 */ 68, 446, 95, 444, 424, 425, 488, 44, 348, 288, + /* 490 */ 504, 424, 425, 23, 22, 32, 465, 466, 464, 464, + /* 500 */ 25, 25, 24, 24, 24, 24, 391, 26, 26, 26, + /* 510 */ 26, 27, 27, 28, 28, 28, 29, 221, 312, 361, + /* 520 */ 556, 426, 520, 328, 191, 271, 339, 329, 247, 259, + /* 530 */ 339, 566, 65, 249, 336, 426, 424, 425, 445, 516, + /* 540 */ 426, 336, 444, 446, 9, 336, 556, 451, 457, 463, + /* 550 */ 446, 74, 427, 428, 446, 69, 192, 618, 65, 427, + /* 560 */ 428, 426, 323, 277, 16, 202, 189, 23, 22, 32, + /* 570 */ 465, 466, 464, 464, 25, 25, 24, 24, 24, 24, + /* 580 */ 255, 26, 26, 26, 26, 27, 27, 28, 28, 28, + /* 590 */ 29, 221, 312, 339, 486, 426, 537, 235, 515, 447, + /* 600 */ 339, 629, 419, 416, 427, 428, 217, 281, 336, 279, + /* 610 */ 487, 203, 144, 526, 527, 336, 391, 446, 78, 429, + /* 620 */ 430, 431, 457, 463, 446, 99, 488, 341, 528, 468, + /* 630 */ 468, 426, 343, 472, 473, 626, 949, 474, 949, 529, + /* 640 */ 447, 23, 22, 32, 465, 466, 464, 464, 25, 25, + /* 650 */ 24, 24, 24, 24, 339, 26, 26, 26, 26, 27, + /* 660 */ 27, 28, 28, 28, 29, 221, 312, 339, 162, 336, + /* 670 */ 275, 283, 476, 376, 339, 579, 527, 346, 446, 98, + /* 680 */ 622, 30, 336, 33, 141, 339, 426, 339, 508, 336, + /* 690 */ 469, 446, 105, 418, 2, 222, 457, 463, 446, 101, + /* 700 */ 336, 219, 336, 426, 161, 626, 948, 290, 948, 446, + /* 710 */ 108, 446, 109, 398, 284, 23, 22, 32, 465, 466, + /* 720 */ 464, 464, 25, 25, 24, 24, 24, 24, 339, 26, + /* 730 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 221, + /* 740 */ 312, 339, 271, 336, 339, 58, 535, 482, 143, 339, + /* 750 */ 622, 318, 446, 133, 408, 257, 336, 426, 321, 336, + /* 760 */ 357, 339, 272, 426, 336, 446, 135, 184, 446, 61, + /* 770 */ 457, 463, 219, 446, 106, 426, 336, 493, 341, 234, + /* 780 */ 468, 468, 621, 310, 407, 446, 102, 209, 144, 23, + /* 790 */ 22, 32, 465, 466, 464, 464, 25, 25, 24, 24, + /* 800 */ 24, 24, 339, 26, 26, 26, 26, 27, 27, 28, + /* 810 */ 28, 28, 29, 221, 312, 339, 271, 336, 339, 341, + /* 820 */ 538, 468, 468, 572, 383, 496, 446, 79, 499, 549, + /* 830 */ 336, 426, 508, 336, 508, 341, 339, 468, 468, 446, + /* 840 */ 103, 391, 446, 70, 457, 463, 572, 426, 40, 426, + /* 850 */ 42, 336, 220, 324, 504, 341, 426, 468, 468, 18, + /* 860 */ 446, 100, 266, 23, 22, 32, 465, 466, 464, 464, + /* 870 */ 25, 25, 24, 24, 24, 24, 339, 26, 26, 26, + /* 880 */ 26, 27, 27, 28, 28, 28, 29, 221, 312, 339, + /* 890 */ 283, 336, 339, 261, 548, 384, 339, 327, 142, 550, + /* 900 */ 446, 136, 475, 475, 336, 426, 185, 336, 499, 396, + /* 910 */ 339, 336, 370, 446, 137, 256, 446, 138, 457, 463, + /* 920 */ 446, 71, 499, 360, 426, 336, 161, 311, 623, 215, + /* 930 */ 426, 359, 237, 412, 446, 82, 200, 23, 34, 32, + /* 940 */ 465, 466, 464, 464, 25, 25, 24, 24, 24, 24, + /* 950 */ 339, 26, 26, 26, 26, 27, 27, 28, 28, 28, + /* 960 */ 29, 221, 312, 447, 271, 336, 339, 271, 340, 210, + /* 970 */ 447, 172, 625, 211, 446, 83, 240, 552, 142, 426, + /* 980 */ 321, 336, 426, 426, 339, 414, 331, 181, 458, 459, + /* 990 */ 446, 72, 457, 463, 470, 506, 67, 158, 394, 336, + /* 1000 */ 587, 325, 499, 447, 326, 311, 624, 447, 446, 84, + /* 1010 */ 461, 462, 22, 32, 465, 466, 464, 464, 25, 25, + /* 1020 */ 24, 24, 24, 24, 339, 26, 26, 26, 26, 27, + /* 1030 */ 27, 28, 28, 28, 29, 221, 312, 460, 339, 336, + /* 1040 */ 339, 283, 423, 393, 532, 533, 204, 205, 446, 85, + /* 1050 */ 625, 392, 547, 336, 162, 336, 426, 426, 339, 435, + /* 1060 */ 436, 339, 446, 104, 446, 86, 457, 463, 264, 291, + /* 1070 */ 274, 49, 162, 336, 426, 426, 336, 297, 265, 542, + /* 1080 */ 541, 405, 446, 88, 594, 446, 89, 32, 465, 466, + /* 1090 */ 464, 464, 25, 25, 24, 24, 24, 24, 600, 26, + /* 1100 */ 26, 26, 26, 27, 27, 28, 28, 28, 29, 221, + /* 1110 */ 36, 345, 339, 3, 214, 8, 422, 335, 425, 437, + /* 1120 */ 375, 148, 162, 36, 345, 339, 3, 336, 342, 432, + /* 1130 */ 335, 425, 149, 577, 426, 162, 446, 90, 151, 339, + /* 1140 */ 336, 342, 434, 339, 283, 433, 333, 347, 447, 446, + /* 1150 */ 75, 588, 6, 158, 336, 448, 140, 481, 336, 426, + /* 1160 */ 347, 453, 334, 446, 76, 49, 350, 446, 91, 7, + /* 1170 */ 481, 426, 397, 283, 355, 250, 426, 39, 38, 251, + /* 1180 */ 339, 426, 48, 353, 37, 337, 338, 596, 426, 452, + /* 1190 */ 39, 38, 514, 252, 390, 336, 20, 37, 337, 338, + /* 1200 */ 253, 43, 452, 206, 446, 92, 219, 449, 242, 243, + /* 1210 */ 244, 150, 246, 283, 491, 593, 597, 490, 224, 258, + /* 1220 */ 454, 454, 454, 455, 456, 10, 503, 183, 426, 178, + /* 1230 */ 156, 301, 426, 454, 454, 454, 455, 456, 10, 339, + /* 1240 */ 302, 426, 36, 345, 50, 3, 339, 505, 260, 335, + /* 1250 */ 425, 262, 339, 176, 336, 581, 598, 358, 364, 175, + /* 1260 */ 342, 336, 177, 446, 93, 46, 345, 336, 3, 339, + /* 1270 */ 446, 94, 335, 425, 525, 339, 446, 77, 320, 347, + /* 1280 */ 511, 339, 507, 342, 336, 589, 601, 56, 56, 481, + /* 1290 */ 336, 512, 283, 446, 17, 531, 336, 426, 530, 446, + /* 1300 */ 96, 534, 347, 404, 298, 446, 97, 426, 313, 39, + /* 1310 */ 38, 267, 481, 219, 535, 536, 37, 337, 338, 283, + /* 1320 */ 620, 452, 309, 283, 111, 19, 288, 509, 269, 424, + /* 1330 */ 425, 539, 39, 38, 426, 238, 270, 411, 426, 37, + /* 1340 */ 337, 338, 426, 426, 452, 558, 426, 307, 231, 276, + /* 1350 */ 278, 426, 454, 454, 454, 455, 456, 10, 553, 280, + /* 1360 */ 426, 559, 239, 230, 426, 426, 299, 282, 287, 481, + /* 1370 */ 560, 388, 584, 232, 426, 454, 454, 454, 455, 456, + /* 1380 */ 10, 561, 426, 426, 585, 395, 426, 426, 292, 194, + /* 1390 */ 195, 592, 603, 300, 303, 308, 377, 522, 381, 426, + /* 1400 */ 426, 452, 567, 426, 304, 617, 426, 426, 426, 426, + /* 1410 */ 379, 53, 147, 165, 166, 167, 580, 212, 569, 426, + /* 1420 */ 426, 285, 168, 570, 387, 120, 123, 187, 590, 402, + /* 1430 */ 403, 125, 454, 454, 454, 330, 599, 614, 186, 126, + /* 1440 */ 127, 128, 615, 616, 57, 60, 619, 107, 229, 64, + /* 1450 */ 115, 420, 245, 130, 439, 180, 315, 207, 670, 316, + /* 1460 */ 671, 467, 672, 153, 154, 35, 483, 471, 480, 188, + /* 1470 */ 201, 155, 484, 5, 485, 489, 12, 502, 45, 11, + /* 1480 */ 110, 145, 518, 519, 510, 228, 51, 112, 369, 273, + /* 1490 */ 113, 159, 545, 52, 374, 114, 164, 265, 378, 190, + /* 1500 */ 146, 568, 117, 158, 286, 382, 169, 119, 15, 583, + /* 1510 */ 170, 171, 121, 586, 122, 54, 55, 13, 124, 591, + /* 1520 */ 173, 174, 118, 575, 129, 595, 571, 131, 14, 132, + /* 1530 */ 611, 63, 612, 193, 602, 179, 305, 413, 417, 960, + /* 1540 */ 627, }; static const YYCODETYPE yy_lookahead[] = { - /* 0 */ 19, 142, 143, 144, 145, 24, 116, 26, 75, 76, - /* 10 */ 77, 78, 25, 80, 81, 82, 83, 84, 85, 86, - /* 20 */ 87, 88, 89, 90, 26, 27, 160, 26, 27, 48, - /* 30 */ 49, 79, 80, 81, 82, 83, 84, 85, 86, 87, - /* 40 */ 88, 89, 90, 222, 223, 224, 225, 66, 67, 68, + /* 0 */ 19, 142, 143, 144, 145, 24, 115, 26, 77, 78, + /* 10 */ 79, 80, 92, 82, 83, 84, 85, 86, 87, 88, + /* 20 */ 89, 90, 91, 92, 26, 27, 222, 223, 224, 225, + /* 30 */ 49, 50, 81, 82, 83, 84, 85, 86, 87, 88, + /* 40 */ 89, 90, 91, 92, 88, 89, 90, 91, 92, 68, /* 50 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - /* 60 */ 194, 80, 81, 82, 83, 84, 85, 86, 87, 88, - /* 70 */ 89, 90, 19, 90, 19, 94, 174, 25, 25, 80, - /* 80 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 90 */ 26, 27, 94, 95, 96, 94, 95, 99, 100, 101, - /* 100 */ 19, 48, 49, 150, 174, 52, 119, 166, 110, 84, - /* 110 */ 85, 86, 87, 88, 89, 90, 26, 27, 165, 66, - /* 120 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 130 */ 77, 78, 186, 80, 81, 82, 83, 84, 85, 86, - /* 140 */ 87, 88, 89, 90, 19, 90, 205, 95, 84, 85, - /* 150 */ 186, 96, 97, 98, 99, 100, 101, 102, 94, 95, - /* 160 */ 195, 97, 150, 222, 109, 224, 225, 26, 104, 105, - /* 170 */ 217, 90, 120, 48, 49, 50, 86, 165, 97, 98, - /* 180 */ 99, 100, 101, 102, 94, 95, 174, 175, 1, 2, - /* 190 */ 109, 66, 67, 68, 69, 70, 71, 72, 73, 74, - /* 200 */ 75, 76, 77, 78, 191, 80, 81, 82, 83, 84, - /* 210 */ 85, 86, 87, 88, 89, 90, 19, 116, 35, 150, - /* 220 */ 155, 24, 208, 150, 222, 150, 224, 225, 216, 128, - /* 230 */ 161, 162, 150, 221, 165, 94, 23, 150, 165, 56, - /* 240 */ 165, 197, 160, 170, 171, 48, 49, 165, 204, 174, - /* 250 */ 175, 22, 165, 24, 185, 186, 174, 175, 169, 170, - /* 260 */ 171, 174, 175, 66, 67, 68, 69, 70, 71, 72, - /* 270 */ 73, 74, 75, 76, 77, 78, 194, 80, 81, 82, - /* 280 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 214, - /* 290 */ 215, 108, 150, 25, 229, 150, 64, 148, 216, 234, - /* 300 */ 146, 147, 215, 221, 231, 232, 152, 165, 154, 150, - /* 310 */ 165, 196, 170, 171, 160, 181, 182, 48, 49, 174, - /* 320 */ 175, 232, 188, 165, 165, 112, 94, 114, 115, 166, - /* 330 */ 98, 55, 174, 174, 175, 66, 67, 68, 69, 70, - /* 340 */ 71, 72, 73, 74, 75, 76, 77, 78, 194, 80, - /* 350 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 360 */ 19, 129, 130, 131, 96, 84, 85, 99, 100, 101, - /* 370 */ 150, 226, 218, 231, 232, 216, 150, 222, 110, 224, - /* 380 */ 225, 105, 106, 107, 135, 165, 137, 172, 173, 48, - /* 390 */ 49, 165, 116, 183, 174, 175, 181, 242, 22, 245, - /* 400 */ 174, 175, 26, 27, 166, 136, 183, 66, 67, 68, - /* 410 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - /* 420 */ 11, 80, 81, 82, 83, 84, 85, 86, 87, 88, - /* 430 */ 89, 90, 19, 150, 150, 23, 23, 25, 160, 150, - /* 440 */ 220, 26, 27, 205, 160, 150, 220, 158, 165, 165, - /* 450 */ 161, 162, 26, 27, 165, 0, 1, 2, 174, 175, - /* 460 */ 165, 48, 49, 183, 55, 86, 87, 88, 89, 90, - /* 470 */ 94, 95, 194, 169, 170, 171, 193, 136, 194, 66, - /* 480 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 490 */ 77, 78, 166, 80, 81, 82, 83, 84, 85, 86, - /* 500 */ 87, 88, 89, 90, 19, 153, 160, 95, 23, 94, - /* 510 */ 95, 173, 217, 22, 105, 106, 107, 26, 22, 181, - /* 520 */ 94, 95, 26, 27, 96, 116, 243, 99, 100, 101, - /* 530 */ 150, 205, 120, 48, 49, 120, 232, 22, 110, 166, - /* 540 */ 194, 161, 162, 236, 163, 165, 120, 166, 167, 168, - /* 550 */ 160, 66, 67, 68, 69, 70, 71, 72, 73, 74, - /* 560 */ 75, 76, 77, 78, 218, 80, 81, 82, 83, 84, - /* 570 */ 85, 86, 87, 88, 89, 90, 19, 12, 205, 150, - /* 580 */ 23, 235, 190, 191, 194, 94, 240, 150, 86, 74, - /* 590 */ 94, 95, 150, 28, 165, 237, 206, 207, 23, 150, - /* 600 */ 48, 49, 165, 174, 175, 48, 49, 165, 43, 31, - /* 610 */ 45, 174, 175, 21, 165, 113, 174, 175, 40, 117, - /* 620 */ 55, 69, 70, 66, 67, 68, 69, 70, 71, 72, - /* 630 */ 73, 74, 75, 76, 77, 78, 150, 80, 81, 82, - /* 640 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 150, - /* 650 */ 98, 165, 23, 61, 23, 150, 25, 150, 19, 113, - /* 660 */ 174, 175, 213, 117, 165, 24, 196, 26, 23, 150, - /* 670 */ 165, 150, 165, 174, 175, 89, 90, 48, 49, 174, - /* 680 */ 175, 174, 175, 19, 165, 198, 165, 112, 49, 114, - /* 690 */ 115, 27, 100, 174, 175, 66, 67, 68, 69, 70, - /* 700 */ 71, 72, 73, 74, 75, 76, 77, 78, 150, 80, - /* 710 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 720 */ 19, 150, 150, 165, 150, 24, 112, 150, 114, 115, - /* 730 */ 138, 19, 174, 175, 213, 94, 165, 165, 150, 165, - /* 740 */ 29, 150, 165, 104, 33, 174, 175, 166, 109, 48, - /* 750 */ 49, 174, 175, 165, 190, 191, 165, 112, 47, 114, - /* 760 */ 115, 187, 174, 175, 160, 174, 175, 66, 67, 68, - /* 770 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, - /* 780 */ 150, 80, 81, 82, 83, 84, 85, 86, 87, 88, - /* 790 */ 89, 90, 19, 150, 150, 165, 233, 12, 194, 150, - /* 800 */ 150, 150, 248, 249, 174, 175, 206, 207, 165, 165, - /* 810 */ 98, 23, 150, 28, 165, 165, 165, 174, 175, 177, - /* 820 */ 150, 48, 49, 174, 175, 174, 175, 165, 43, 233, - /* 830 */ 45, 22, 23, 228, 25, 165, 174, 175, 177, 66, - /* 840 */ 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - /* 850 */ 77, 78, 150, 80, 81, 82, 83, 84, 85, 86, - /* 860 */ 87, 88, 89, 90, 19, 150, 97, 165, 25, 150, - /* 870 */ 160, 150, 150, 150, 65, 209, 174, 175, 144, 145, - /* 880 */ 165, 246, 247, 150, 165, 116, 165, 165, 165, 174, - /* 890 */ 175, 129, 130, 48, 49, 174, 175, 128, 165, 98, - /* 900 */ 112, 177, 114, 115, 194, 49, 187, 174, 175, 187, - /* 910 */ 109, 66, 67, 68, 69, 70, 71, 72, 73, 74, - /* 920 */ 75, 76, 77, 78, 150, 80, 81, 82, 83, 84, - /* 930 */ 85, 86, 87, 88, 89, 90, 19, 150, 25, 165, - /* 940 */ 182, 150, 150, 150, 150, 166, 167, 168, 174, 175, - /* 950 */ 166, 23, 165, 25, 177, 150, 165, 165, 165, 165, - /* 960 */ 104, 174, 175, 97, 98, 48, 49, 174, 175, 126, - /* 970 */ 165, 22, 23, 177, 25, 7, 8, 9, 187, 174, - /* 980 */ 175, 187, 22, 23, 67, 68, 69, 70, 71, 72, - /* 990 */ 73, 74, 75, 76, 77, 78, 150, 80, 81, 82, - /* 1000 */ 83, 84, 85, 86, 87, 88, 89, 90, 19, 150, - /* 1010 */ 160, 165, 178, 160, 65, 150, 103, 105, 106, 107, - /* 1020 */ 174, 175, 7, 8, 165, 65, 166, 150, 150, 199, - /* 1030 */ 165, 150, 209, 174, 175, 150, 209, 48, 49, 174, - /* 1040 */ 175, 199, 165, 165, 194, 6, 165, 194, 149, 149, - /* 1050 */ 165, 174, 175, 149, 149, 174, 175, 68, 69, 70, - /* 1060 */ 71, 72, 73, 74, 75, 76, 77, 78, 218, 80, - /* 1070 */ 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, - /* 1080 */ 19, 20, 16, 22, 150, 16, 150, 26, 27, 151, - /* 1090 */ 240, 213, 150, 13, 151, 19, 20, 36, 22, 165, - /* 1100 */ 25, 165, 26, 27, 22, 23, 150, 165, 174, 175, - /* 1110 */ 174, 175, 36, 150, 159, 54, 150, 150, 194, 150, - /* 1120 */ 23, 165, 25, 126, 58, 64, 60, 58, 165, 60, - /* 1130 */ 54, 165, 165, 123, 165, 193, 150, 174, 175, 199, - /* 1140 */ 64, 174, 175, 174, 175, 84, 85, 65, 150, 193, - /* 1150 */ 200, 165, 150, 150, 93, 94, 95, 124, 201, 98, - /* 1160 */ 84, 85, 86, 165, 105, 106, 107, 165, 165, 93, - /* 1170 */ 94, 95, 174, 175, 98, 5, 23, 116, 25, 193, - /* 1180 */ 10, 11, 12, 13, 14, 122, 150, 17, 203, 202, - /* 1190 */ 129, 130, 131, 132, 133, 134, 193, 150, 125, 135, - /* 1200 */ 30, 165, 32, 150, 138, 129, 130, 131, 132, 133, - /* 1210 */ 134, 41, 165, 19, 20, 227, 22, 118, 165, 157, - /* 1220 */ 26, 27, 150, 53, 150, 55, 104, 174, 175, 59, - /* 1230 */ 36, 22, 62, 210, 150, 26, 27, 165, 150, 165, - /* 1240 */ 193, 150, 150, 157, 121, 211, 174, 175, 54, 165, - /* 1250 */ 150, 210, 210, 165, 150, 150, 165, 165, 64, 150, - /* 1260 */ 211, 211, 174, 175, 23, 165, 25, 193, 104, 165, - /* 1270 */ 165, 176, 176, 64, 165, 105, 106, 107, 84, 85, - /* 1280 */ 150, 111, 46, 174, 175, 193, 116, 93, 94, 95, - /* 1290 */ 184, 150, 98, 84, 85, 165, 150, 193, 150, 150, - /* 1300 */ 150, 176, 150, 94, 150, 150, 165, 98, 23, 139, - /* 1310 */ 25, 165, 178, 165, 165, 165, 150, 165, 150, 165, - /* 1320 */ 165, 150, 150, 129, 130, 131, 132, 133, 134, 103, - /* 1330 */ 150, 165, 150, 165, 150, 150, 165, 165, 129, 130, - /* 1340 */ 131, 150, 150, 150, 22, 165, 150, 165, 150, 165, - /* 1350 */ 165, 150, 23, 176, 25, 179, 165, 165, 165, 90, - /* 1360 */ 23, 165, 25, 165, 156, 23, 165, 25, 230, 23, - /* 1370 */ 230, 25, 184, 176, 179, 176, 176, 18, 157, 156, - /* 1380 */ 44, 157, 157, 156, 135, 157, 239, 156, 22, 238, - /* 1390 */ 157, 66, 189, 189, 219, 157, 18, 192, 192, 192, - /* 1400 */ 219, 199, 192, 189, 157, 157, 39, 157, 241, 37, - /* 1410 */ 199, 250, 180, 244, 241, 164, 1, 180, 15, 23, - /* 1420 */ 22, 247, 118, 118, 118, 118, 118, 113, 250, 98, - /* 1430 */ 22, 11, 23, 23, 22, 22, 25, 23, 34, 23, - /* 1440 */ 23, 34, 118, 25, 25, 22, 120, 23, 23, 27, - /* 1450 */ 50, 22, 50, 22, 22, 34, 23, 22, 22, 102, - /* 1460 */ 109, 19, 24, 20, 38, 104, 25, 104, 138, 22, - /* 1470 */ 42, 5, 1, 108, 127, 74, 22, 50, 1, 74, - /* 1480 */ 16, 119, 20, 119, 108, 51, 128, 57, 51, 121, - /* 1490 */ 22, 16, 23, 23, 15, 140, 127, 3, 22, 4, - /* 1500 */ 251, 251, 63, + /* 60 */ 79, 80, 16, 82, 83, 84, 85, 86, 87, 88, + /* 70 */ 89, 90, 91, 92, 19, 94, 19, 166, 167, 168, + /* 80 */ 25, 82, 83, 84, 85, 86, 87, 88, 89, 90, + /* 90 */ 91, 92, 94, 95, 96, 150, 36, 99, 100, 101, + /* 100 */ 174, 169, 170, 171, 49, 50, 60, 109, 62, 54, + /* 110 */ 165, 51, 1, 2, 26, 27, 174, 22, 58, 174, + /* 120 */ 175, 26, 27, 68, 69, 70, 71, 72, 73, 74, + /* 130 */ 75, 76, 77, 78, 79, 80, 186, 82, 83, 84, + /* 140 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 92, + /* 150 */ 19, 172, 173, 96, 97, 98, 99, 100, 101, 102, + /* 160 */ 181, 216, 146, 147, 232, 108, 221, 107, 152, 186, + /* 170 */ 154, 150, 195, 30, 86, 87, 160, 34, 49, 50, + /* 180 */ 26, 52, 94, 95, 138, 97, 165, 181, 182, 94, + /* 190 */ 95, 48, 104, 105, 188, 174, 175, 68, 69, 70, + /* 200 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + /* 210 */ 194, 82, 83, 84, 85, 86, 87, 88, 89, 90, + /* 220 */ 91, 92, 19, 92, 86, 87, 21, 24, 97, 98, + /* 230 */ 99, 100, 101, 102, 218, 214, 215, 208, 66, 108, + /* 240 */ 150, 86, 87, 88, 89, 90, 91, 92, 94, 173, + /* 250 */ 160, 183, 49, 50, 191, 165, 96, 181, 22, 99, + /* 260 */ 100, 101, 26, 247, 174, 175, 94, 57, 63, 109, + /* 270 */ 98, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 280 */ 77, 78, 79, 80, 194, 82, 83, 84, 85, 86, + /* 290 */ 87, 88, 89, 90, 91, 92, 19, 150, 150, 150, + /* 300 */ 25, 129, 130, 131, 183, 100, 216, 160, 150, 161, + /* 310 */ 162, 221, 165, 165, 165, 105, 106, 26, 27, 170, + /* 320 */ 171, 174, 175, 165, 160, 115, 49, 50, 170, 171, + /* 330 */ 94, 148, 163, 185, 186, 166, 167, 168, 128, 91, + /* 340 */ 92, 194, 196, 138, 166, 68, 69, 70, 71, 72, + /* 350 */ 73, 74, 75, 76, 77, 78, 79, 80, 194, 82, + /* 360 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + /* 370 */ 19, 96, 11, 150, 99, 100, 101, 155, 26, 27, + /* 380 */ 231, 232, 218, 205, 109, 94, 95, 150, 165, 231, + /* 390 */ 232, 166, 150, 222, 150, 224, 225, 174, 175, 235, + /* 400 */ 49, 50, 165, 24, 240, 26, 166, 165, 153, 165, + /* 410 */ 119, 174, 175, 136, 237, 244, 174, 175, 57, 68, + /* 420 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + /* 430 */ 79, 80, 236, 82, 83, 84, 85, 86, 87, 88, + /* 440 */ 89, 90, 91, 92, 19, 205, 94, 95, 23, 226, + /* 450 */ 165, 229, 215, 150, 12, 88, 234, 150, 216, 174, + /* 460 */ 32, 217, 222, 25, 224, 225, 105, 106, 165, 41, + /* 470 */ 28, 119, 165, 94, 49, 50, 115, 174, 175, 112, + /* 480 */ 22, 174, 175, 116, 26, 27, 44, 136, 46, 128, + /* 490 */ 166, 26, 27, 68, 69, 70, 71, 72, 73, 74, + /* 500 */ 75, 76, 77, 78, 79, 80, 150, 82, 83, 84, + /* 510 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 150, + /* 520 */ 150, 165, 23, 220, 196, 150, 150, 220, 158, 205, + /* 530 */ 150, 161, 162, 198, 165, 165, 26, 27, 112, 23, + /* 540 */ 165, 165, 116, 174, 175, 165, 150, 166, 49, 50, + /* 550 */ 174, 175, 94, 95, 174, 175, 118, 161, 162, 94, + /* 560 */ 95, 165, 187, 16, 22, 160, 24, 68, 69, 70, + /* 570 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + /* 580 */ 150, 82, 83, 84, 85, 86, 87, 88, 89, 90, + /* 590 */ 91, 92, 19, 150, 12, 165, 23, 241, 88, 194, + /* 600 */ 150, 0, 1, 2, 94, 95, 160, 60, 165, 62, + /* 610 */ 28, 206, 207, 190, 191, 165, 150, 174, 175, 7, + /* 620 */ 8, 9, 49, 50, 174, 175, 44, 111, 46, 113, + /* 630 */ 114, 165, 169, 170, 171, 22, 23, 233, 25, 57, + /* 640 */ 194, 68, 69, 70, 71, 72, 73, 74, 75, 76, + /* 650 */ 77, 78, 79, 80, 150, 82, 83, 84, 85, 86, + /* 660 */ 87, 88, 89, 90, 91, 92, 19, 150, 25, 165, + /* 670 */ 23, 150, 233, 19, 150, 190, 191, 228, 174, 175, + /* 680 */ 67, 222, 165, 224, 225, 150, 165, 150, 150, 165, + /* 690 */ 23, 174, 175, 144, 145, 232, 49, 50, 174, 175, + /* 700 */ 165, 115, 165, 165, 50, 22, 23, 241, 25, 174, + /* 710 */ 175, 174, 175, 127, 193, 68, 69, 70, 71, 72, + /* 720 */ 73, 74, 75, 76, 77, 78, 79, 80, 150, 82, + /* 730 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + /* 740 */ 19, 150, 150, 165, 150, 24, 103, 23, 150, 150, + /* 750 */ 67, 213, 174, 175, 97, 209, 165, 165, 104, 165, + /* 760 */ 150, 150, 108, 165, 165, 174, 175, 23, 174, 175, + /* 770 */ 49, 50, 115, 174, 175, 165, 165, 177, 111, 187, + /* 780 */ 113, 114, 250, 251, 127, 174, 175, 206, 207, 68, + /* 790 */ 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, + /* 800 */ 79, 80, 150, 82, 83, 84, 85, 86, 87, 88, + /* 810 */ 89, 90, 91, 92, 19, 150, 150, 165, 150, 111, + /* 820 */ 182, 113, 114, 105, 106, 177, 174, 175, 25, 166, + /* 830 */ 165, 165, 150, 165, 150, 111, 150, 113, 114, 174, + /* 840 */ 175, 150, 174, 175, 49, 50, 128, 165, 135, 165, + /* 850 */ 137, 165, 197, 187, 166, 111, 165, 113, 114, 204, + /* 860 */ 174, 175, 177, 68, 69, 70, 71, 72, 73, 74, + /* 870 */ 75, 76, 77, 78, 79, 80, 150, 82, 83, 84, + /* 880 */ 85, 86, 87, 88, 89, 90, 91, 92, 19, 150, + /* 890 */ 150, 165, 150, 205, 177, 213, 150, 213, 95, 177, + /* 900 */ 174, 175, 129, 130, 165, 165, 23, 165, 25, 150, + /* 910 */ 150, 165, 178, 174, 175, 150, 174, 175, 49, 50, + /* 920 */ 174, 175, 119, 19, 165, 165, 50, 22, 23, 160, + /* 930 */ 165, 27, 241, 193, 174, 175, 160, 68, 69, 70, + /* 940 */ 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, + /* 950 */ 150, 82, 83, 84, 85, 86, 87, 88, 89, 90, + /* 960 */ 91, 92, 19, 194, 150, 165, 150, 150, 150, 160, + /* 970 */ 194, 25, 67, 160, 174, 175, 217, 166, 95, 165, + /* 980 */ 104, 165, 165, 165, 150, 245, 248, 249, 49, 50, + /* 990 */ 174, 175, 49, 50, 23, 23, 25, 25, 242, 165, + /* 1000 */ 199, 187, 119, 194, 187, 22, 23, 194, 174, 175, + /* 1010 */ 71, 72, 69, 70, 71, 72, 73, 74, 75, 76, + /* 1020 */ 77, 78, 79, 80, 150, 82, 83, 84, 85, 86, + /* 1030 */ 87, 88, 89, 90, 91, 92, 19, 98, 150, 165, + /* 1040 */ 150, 150, 150, 19, 7, 8, 105, 106, 174, 175, + /* 1050 */ 67, 27, 23, 165, 25, 165, 165, 165, 150, 150, + /* 1060 */ 150, 150, 174, 175, 174, 175, 49, 50, 98, 242, + /* 1070 */ 23, 125, 25, 165, 165, 165, 165, 209, 108, 97, + /* 1080 */ 98, 209, 174, 175, 193, 174, 175, 70, 71, 72, + /* 1090 */ 73, 74, 75, 76, 77, 78, 79, 80, 199, 82, + /* 1100 */ 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, + /* 1110 */ 19, 20, 150, 22, 160, 22, 149, 26, 27, 150, + /* 1120 */ 23, 6, 25, 19, 20, 150, 22, 165, 37, 149, + /* 1130 */ 26, 27, 151, 23, 165, 25, 174, 175, 151, 150, + /* 1140 */ 165, 37, 13, 150, 150, 149, 149, 56, 194, 174, + /* 1150 */ 175, 23, 25, 25, 165, 194, 150, 66, 165, 165, + /* 1160 */ 56, 150, 159, 174, 175, 125, 150, 174, 175, 76, + /* 1170 */ 66, 165, 218, 150, 122, 199, 165, 86, 87, 200, + /* 1180 */ 150, 165, 123, 121, 93, 94, 95, 193, 165, 98, + /* 1190 */ 86, 87, 88, 201, 240, 165, 124, 93, 94, 95, + /* 1200 */ 202, 135, 98, 5, 174, 175, 115, 203, 10, 11, + /* 1210 */ 12, 13, 14, 150, 157, 17, 193, 150, 227, 210, + /* 1220 */ 129, 130, 131, 132, 133, 134, 150, 157, 165, 31, + /* 1230 */ 117, 33, 165, 129, 130, 131, 132, 133, 134, 150, + /* 1240 */ 42, 165, 19, 20, 104, 22, 150, 211, 210, 26, + /* 1250 */ 27, 210, 150, 55, 165, 57, 193, 120, 104, 61, + /* 1260 */ 37, 165, 64, 174, 175, 19, 20, 165, 22, 150, + /* 1270 */ 174, 175, 26, 27, 176, 150, 174, 175, 47, 56, + /* 1280 */ 211, 150, 150, 37, 165, 23, 23, 25, 25, 66, + /* 1290 */ 165, 211, 150, 174, 175, 184, 165, 165, 176, 174, + /* 1300 */ 175, 178, 56, 105, 106, 174, 175, 165, 110, 86, + /* 1310 */ 87, 176, 66, 115, 103, 176, 93, 94, 95, 150, + /* 1320 */ 23, 98, 25, 150, 22, 22, 128, 150, 150, 26, + /* 1330 */ 27, 150, 86, 87, 165, 193, 150, 139, 165, 93, + /* 1340 */ 94, 95, 165, 165, 98, 150, 165, 179, 92, 150, + /* 1350 */ 150, 165, 129, 130, 131, 132, 133, 134, 184, 150, + /* 1360 */ 165, 176, 193, 230, 165, 165, 193, 150, 150, 66, + /* 1370 */ 176, 150, 150, 230, 165, 129, 130, 131, 132, 133, + /* 1380 */ 134, 176, 165, 165, 150, 150, 165, 165, 150, 86, + /* 1390 */ 87, 150, 150, 150, 150, 179, 18, 94, 45, 165, + /* 1400 */ 165, 98, 157, 165, 150, 150, 165, 165, 165, 165, + /* 1410 */ 157, 135, 68, 156, 156, 156, 189, 157, 157, 165, + /* 1420 */ 165, 238, 156, 239, 157, 189, 22, 219, 199, 157, + /* 1430 */ 18, 192, 129, 130, 131, 157, 199, 40, 219, 192, + /* 1440 */ 192, 192, 157, 157, 243, 243, 38, 164, 180, 246, + /* 1450 */ 180, 1, 15, 189, 23, 249, 252, 22, 117, 252, + /* 1460 */ 117, 112, 117, 117, 117, 22, 11, 23, 23, 22, + /* 1470 */ 22, 25, 23, 35, 23, 23, 35, 119, 25, 25, + /* 1480 */ 22, 117, 23, 23, 27, 52, 22, 22, 52, 23, + /* 1490 */ 22, 35, 29, 22, 52, 22, 102, 108, 19, 24, + /* 1500 */ 39, 20, 104, 25, 138, 43, 104, 22, 5, 1, + /* 1510 */ 117, 35, 107, 27, 126, 76, 76, 22, 118, 1, + /* 1520 */ 16, 120, 53, 53, 118, 20, 59, 107, 22, 126, + /* 1530 */ 23, 16, 23, 22, 127, 15, 140, 65, 3, 253, + /* 1540 */ 4, }; -#define YY_SHIFT_USE_DFLT (-111) -#define YY_SHIFT_MAX 408 +#define YY_SHIFT_USE_DFLT (-110) +#define YY_SHIFT_MAX 417 static const short yy_shift_ofst[] = { - /* 0 */ 187, 1061, 1170, 1061, 1194, 1194, -2, 64, 64, -19, - /* 10 */ 1194, 1194, 1194, 1194, 1194, 276, 1, 125, 1076, 1194, - /* 20 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, - /* 30 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, - /* 40 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, - /* 50 */ 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, 1194, -48, - /* 60 */ 409, 1, 1, 141, 281, 281, -110, 53, 197, 269, - /* 70 */ 341, 413, 485, 557, 629, 701, 773, 845, 773, 773, - /* 80 */ 773, 773, 773, 773, 773, 773, 773, 773, 773, 773, - /* 90 */ 773, 773, 773, 773, 773, 773, 917, 989, 989, -67, - /* 100 */ -67, -1, -1, 55, 25, 379, 1, 1, 1, 1, - /* 110 */ 1, 639, 592, 1, 1, 1, 1, 1, 1, 1, - /* 120 */ 1, 1, 1, 1, 1, 1, 586, 141, -17, -111, - /* 130 */ -111, -111, 1209, 81, 376, 415, 426, 496, 90, 565, - /* 140 */ 565, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 150 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 160 */ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - /* 170 */ 1, 1, 1, 1, 809, 949, 455, 641, 641, 641, - /* 180 */ 769, 101, -110, -110, -110, -111, -111, -111, 232, 232, - /* 190 */ 268, 428, 213, 575, 645, 785, 788, 412, 968, 502, - /* 200 */ 491, 52, 183, 183, 183, 614, 614, 711, 912, 614, - /* 210 */ 614, 614, 614, 229, 546, -13, 141, 762, 762, 249, - /* 220 */ 578, 578, 664, 578, 856, 578, 141, 578, 141, 913, - /* 230 */ 843, 664, 664, 843, 1039, 1039, 1039, 1039, 1080, 1080, - /* 240 */ 1075, -110, 997, 1010, 1033, 1063, 1073, 1064, 1099, 1099, - /* 250 */ 1122, 1123, 1122, 1123, 1122, 1123, 1164, 1164, 1236, 1164, - /* 260 */ 1226, 1164, 1322, 1269, 1269, 1236, 1164, 1164, 1164, 1322, - /* 270 */ 1359, 1099, 1359, 1099, 1359, 1099, 1099, 1336, 1249, 1359, - /* 280 */ 1099, 1325, 1325, 1366, 997, 1099, 1378, 1378, 1378, 1378, - /* 290 */ 997, 1325, 1366, 1099, 1367, 1367, 1099, 1099, 1372, -111, - /* 300 */ -111, -111, -111, -111, -111, 552, 1066, 1059, 1069, 960, - /* 310 */ 1082, 712, 631, 928, 801, 1015, 866, 1097, 1153, 1241, - /* 320 */ 1285, 1329, 1337, 1342, 515, 1346, 1415, 1403, 1396, 1398, - /* 330 */ 1304, 1305, 1306, 1307, 1308, 1331, 1314, 1408, 1409, 1410, - /* 340 */ 1412, 1420, 1413, 1414, 1411, 1416, 1417, 1418, 1404, 1419, - /* 350 */ 1407, 1418, 1326, 1423, 1421, 1422, 1324, 1424, 1425, 1426, - /* 360 */ 1400, 1429, 1402, 1431, 1433, 1432, 1435, 1427, 1436, 1357, - /* 370 */ 1351, 1442, 1443, 1438, 1361, 1428, 1430, 1434, 1441, 1437, - /* 380 */ 1330, 1363, 1447, 1466, 1471, 1365, 1401, 1405, 1347, 1454, - /* 390 */ 1362, 1477, 1464, 1368, 1462, 1364, 1376, 1369, 1468, 1358, - /* 400 */ 1469, 1470, 1475, 1439, 1479, 1355, 1476, 1494, 1495, + /* 0 */ 111, 1091, 1198, 1091, 1223, 1223, -2, 88, 88, -19, + /* 10 */ 1223, 1223, 1223, 1223, 1223, 210, 465, 129, 1104, 1223, + /* 20 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 30 */ 1223, 1223, 1246, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 40 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 50 */ 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, 1223, + /* 60 */ 1223, -49, 361, 465, 465, 154, 138, 138, -109, 55, + /* 70 */ 203, 277, 351, 425, 499, 573, 647, 721, 795, 869, + /* 80 */ 795, 795, 795, 795, 795, 795, 795, 795, 795, 795, + /* 90 */ 795, 795, 795, 795, 795, 795, 795, 795, 943, 1017, + /* 100 */ 1017, -69, -69, -69, -69, -1, -1, 57, 155, -44, + /* 110 */ 465, 465, 465, 465, 465, 654, 205, 465, 465, 465, + /* 120 */ 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, + /* 130 */ 465, 465, 465, 248, 154, -80, -110, -110, -110, 1303, + /* 140 */ 131, 95, 291, 352, 458, 510, 582, 582, 465, 465, + /* 150 */ 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, + /* 160 */ 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, + /* 170 */ 465, 465, 465, 465, 465, 465, 465, 465, 465, 465, + /* 180 */ 613, 683, 601, 379, 379, 379, 657, 586, -109, -109, + /* 190 */ -109, -110, -110, -110, 172, 172, 275, 160, 516, 667, + /* 200 */ 724, 442, 744, 883, 60, 60, 612, 367, 236, 803, + /* 210 */ 708, 708, 143, 718, 708, 708, 708, 708, 542, 426, + /* 220 */ 438, 154, 773, 773, 713, 428, 428, 904, 428, 876, + /* 230 */ 428, 154, 428, 154, 643, 1024, 946, 1024, 904, 904, + /* 240 */ 946, 1115, 1115, 1115, 1115, 1129, 1129, 1127, -109, 1040, + /* 250 */ 1052, 1059, 1062, 1072, 1066, 1113, 1113, 1140, 1137, 1140, + /* 260 */ 1137, 1140, 1137, 1154, 1154, 1231, 1154, 1211, 1154, 1302, + /* 270 */ 1256, 1256, 1231, 1154, 1154, 1154, 1302, 1378, 1113, 1378, + /* 280 */ 1113, 1378, 1113, 1113, 1353, 1276, 1378, 1113, 1344, 1344, + /* 290 */ 1404, 1040, 1113, 1412, 1412, 1412, 1412, 1040, 1344, 1404, + /* 300 */ 1113, 1397, 1397, 1113, 1113, 1408, -110, -110, -110, -110, + /* 310 */ -110, -110, 939, 46, 547, 905, 983, 971, 972, 970, + /* 320 */ 1037, 941, 982, 1029, 1047, 1097, 1110, 1128, 1262, 1263, + /* 330 */ 1093, 1297, 1450, 1437, 1431, 1435, 1341, 1343, 1345, 1346, + /* 340 */ 1347, 1349, 1443, 1444, 1445, 1447, 1455, 1448, 1449, 1446, + /* 350 */ 1451, 1452, 1453, 1438, 1454, 1441, 1453, 1358, 1458, 1456, + /* 360 */ 1457, 1364, 1459, 1460, 1461, 1433, 1464, 1463, 1436, 1465, + /* 370 */ 1466, 1468, 1471, 1442, 1473, 1394, 1389, 1479, 1481, 1475, + /* 380 */ 1398, 1462, 1467, 1469, 1478, 1470, 1366, 1402, 1485, 1503, + /* 390 */ 1508, 1393, 1476, 1486, 1405, 1439, 1440, 1388, 1495, 1400, + /* 400 */ 1518, 1504, 1401, 1505, 1406, 1420, 1403, 1506, 1407, 1507, + /* 410 */ 1509, 1515, 1472, 1520, 1396, 1511, 1535, 1536, }; -#define YY_REDUCE_USE_DFLT (-180) -#define YY_REDUCE_MAX 304 +#define YY_REDUCE_USE_DFLT (-197) +#define YY_REDUCE_MAX 311 static const short yy_reduce_ofst[] = { - /* 0 */ -141, 82, 154, 284, 12, 75, 69, 73, 142, -59, - /* 10 */ 145, 87, 159, 220, 226, 346, 289, 155, 429, 437, - /* 20 */ 442, 486, 499, 505, 507, 519, 558, 571, 577, 588, - /* 30 */ 591, 630, 643, 649, 651, 662, 702, 715, 721, 733, - /* 40 */ 774, 787, 793, 805, 846, 859, 865, 877, 881, 934, - /* 50 */ 936, 963, 967, 969, 998, 1053, 1072, 1088, 1109, -179, - /* 60 */ 850, 283, 380, 381, 89, 304, 390, 2, 2, 2, - /* 70 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - /* 80 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - /* 90 */ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - /* 100 */ 2, 2, 2, 215, 2, 2, 449, 574, 719, 722, - /* 110 */ 791, 134, 65, 942, 521, 794, -47, 878, 956, 986, - /* 120 */ 1003, 1047, 1074, 1092, 295, 1104, 2, 779, 2, 2, - /* 130 */ 2, 2, 158, 338, 572, 644, 650, 670, 723, 392, - /* 140 */ 564, 792, 885, 966, 1002, 1036, 723, 1084, 1091, 1100, - /* 150 */ 1105, 1130, 1141, 1146, 1148, 1149, 1150, 1152, 1154, 1155, - /* 160 */ 1166, 1168, 1171, 1172, 1180, 1182, 1184, 1185, 1191, 1192, - /* 170 */ 1193, 1196, 1198, 1201, 554, 554, 734, 238, 326, 373, - /* 180 */ -134, 278, 604, 710, 853, 44, 600, 635, -98, -70, - /* 190 */ -54, -36, -35, -35, -35, 13, -35, 14, 149, 115, - /* 200 */ 163, 14, 210, 223, 280, -35, -35, 307, 358, -35, - /* 210 */ -35, -35, -35, 352, 470, 487, 581, 563, 596, 605, - /* 220 */ 642, 661, 666, 724, 758, 777, 784, 796, 860, 834, - /* 230 */ 830, 823, 827, 842, 899, 900, 904, 905, 938, 943, - /* 240 */ 955, 924, 940, 950, 957, 987, 985, 988, 1062, 1086, - /* 250 */ 1023, 1034, 1041, 1049, 1042, 1050, 1095, 1096, 1106, 1125, - /* 260 */ 1134, 1177, 1176, 1138, 1140, 1188, 1197, 1199, 1200, 1195, - /* 270 */ 1208, 1221, 1223, 1224, 1227, 1225, 1228, 1151, 1147, 1231, - /* 280 */ 1233, 1203, 1204, 1175, 1202, 1238, 1205, 1206, 1207, 1210, - /* 290 */ 1211, 1214, 1181, 1247, 1167, 1173, 1248, 1250, 1169, 1251, - /* 300 */ 1232, 1237, 1174, 1161, 1178, + /* 0 */ -141, 90, 16, 147, -55, 21, 148, 149, 158, 240, + /* 10 */ 223, 237, 242, 303, 307, 164, 370, 171, 369, 376, + /* 20 */ 380, 443, 450, 504, 517, 524, 535, 537, 578, 591, + /* 30 */ 594, 599, 611, 652, 665, 668, 686, 726, 739, 742, + /* 40 */ 746, 760, 800, 816, 834, 874, 888, 890, 908, 911, + /* 50 */ 962, 975, 989, 993, 1030, 1089, 1096, 1102, 1119, 1125, + /* 60 */ 1131, -196, 954, 740, 396, 169, -68, 463, 405, 459, + /* 70 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, + /* 80 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, + /* 90 */ 459, 459, 459, 459, 459, 459, 459, 459, 459, 459, + /* 100 */ 459, 459, 459, 459, 459, 459, 459, -21, 459, 459, + /* 110 */ 538, 375, 592, 666, 814, 6, 222, 521, 682, 817, + /* 120 */ 356, 244, 466, 684, 691, 891, 994, 1023, 1063, 1142, + /* 130 */ 1169, 759, 1173, 459, -89, 459, 459, 459, 459, 285, + /* 140 */ 76, 430, 598, 610, 765, 818, 423, 485, 892, 909, + /* 150 */ 910, 969, 1006, 818, 1011, 1016, 1067, 1076, 1132, 1177, + /* 160 */ 1178, 1181, 1186, 1195, 1199, 1200, 1209, 1217, 1218, 1221, + /* 170 */ 1222, 1234, 1235, 1238, 1241, 1242, 1243, 1244, 1254, 1255, + /* 180 */ 532, 532, 549, 178, 324, 688, 446, 769, 776, 809, + /* 190 */ 813, 655, 581, 738, -74, -58, -50, -17, -23, -23, + /* 200 */ -23, 63, -23, 29, 68, 121, 183, 146, 225, 29, + /* 210 */ -23, -23, 196, 177, -23, -23, -23, -23, 255, 328, + /* 220 */ 335, 381, 404, 439, 449, 600, 648, 546, 685, 638, + /* 230 */ 717, 663, 722, 811, 734, 756, 801, 827, 868, 872, + /* 240 */ 899, 967, 980, 996, 997, 981, 987, 1003, 961, 976, + /* 250 */ 979, 992, 998, 1004, 991, 1057, 1070, 1009, 1036, 1038, + /* 260 */ 1069, 1041, 1080, 1098, 1122, 1111, 1135, 1123, 1139, 1168, + /* 270 */ 1133, 1143, 1174, 1185, 1194, 1205, 1216, 1257, 1245, 1258, + /* 280 */ 1253, 1259, 1260, 1261, 1183, 1184, 1266, 1267, 1227, 1236, + /* 290 */ 1208, 1229, 1272, 1239, 1247, 1248, 1249, 1237, 1264, 1219, + /* 300 */ 1278, 1201, 1202, 1285, 1286, 1203, 1283, 1268, 1270, 1206, + /* 310 */ 1204, 1207, }; static const YYACTIONTYPE yy_default[] = { - /* 0 */ 624, 859, 943, 943, 859, 943, 943, 888, 888, 747, - /* 10 */ 857, 943, 943, 943, 943, 943, 943, 917, 943, 943, - /* 20 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943, - /* 30 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943, - /* 40 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943, - /* 50 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 831, - /* 60 */ 943, 943, 943, 663, 888, 888, 751, 782, 943, 943, - /* 70 */ 943, 943, 943, 943, 943, 943, 783, 943, 861, 856, - /* 80 */ 852, 854, 853, 860, 784, 773, 780, 787, 762, 901, - /* 90 */ 789, 790, 796, 797, 918, 916, 819, 818, 837, 821, - /* 100 */ 843, 820, 830, 655, 822, 823, 943, 943, 943, 943, - /* 110 */ 943, 716, 650, 943, 943, 943, 943, 943, 943, 943, - /* 120 */ 943, 943, 943, 943, 943, 943, 824, 943, 825, 838, - /* 130 */ 839, 840, 943, 943, 943, 943, 943, 943, 943, 943, - /* 140 */ 943, 630, 943, 943, 943, 943, 943, 943, 943, 943, - /* 150 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943, - /* 160 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 872, - /* 170 */ 943, 921, 923, 943, 943, 943, 624, 747, 747, 747, - /* 180 */ 943, 943, 943, 943, 943, 741, 751, 935, 943, 943, - /* 190 */ 707, 943, 943, 943, 943, 943, 943, 943, 632, 739, - /* 200 */ 665, 749, 943, 943, 943, 652, 728, 894, 943, 908, - /* 210 */ 906, 730, 792, 943, 739, 748, 943, 943, 943, 855, - /* 220 */ 776, 776, 764, 776, 686, 776, 943, 776, 943, 689, - /* 230 */ 786, 764, 764, 786, 629, 629, 629, 629, 640, 640, - /* 240 */ 706, 943, 786, 777, 779, 769, 781, 943, 755, 755, - /* 250 */ 763, 768, 763, 768, 763, 768, 718, 718, 703, 718, - /* 260 */ 689, 718, 865, 869, 869, 703, 718, 718, 718, 865, - /* 270 */ 647, 755, 647, 755, 647, 755, 755, 898, 900, 647, - /* 280 */ 755, 720, 720, 798, 786, 755, 727, 727, 727, 727, - /* 290 */ 786, 720, 798, 755, 920, 920, 755, 755, 928, 673, - /* 300 */ 691, 691, 935, 940, 940, 943, 943, 943, 943, 943, - /* 310 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943, - /* 320 */ 943, 943, 943, 943, 874, 943, 943, 638, 943, 657, - /* 330 */ 805, 810, 806, 943, 807, 943, 733, 943, 943, 943, - /* 340 */ 943, 943, 943, 943, 943, 943, 943, 858, 943, 770, - /* 350 */ 943, 778, 943, 943, 943, 943, 943, 943, 943, 943, - /* 360 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943, - /* 370 */ 943, 943, 943, 943, 943, 943, 943, 896, 897, 943, - /* 380 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943, - /* 390 */ 943, 943, 943, 943, 943, 943, 943, 943, 943, 943, - /* 400 */ 943, 943, 943, 927, 943, 943, 930, 625, 943, 620, - /* 410 */ 622, 623, 627, 628, 631, 657, 658, 660, 661, 662, - /* 420 */ 633, 634, 635, 636, 637, 639, 643, 641, 642, 644, - /* 430 */ 651, 653, 672, 674, 676, 737, 738, 802, 731, 732, - /* 440 */ 736, 659, 813, 804, 808, 809, 811, 812, 826, 827, - /* 450 */ 829, 835, 842, 845, 828, 833, 834, 836, 841, 844, - /* 460 */ 734, 735, 848, 666, 667, 670, 671, 884, 886, 885, - /* 470 */ 887, 669, 668, 814, 817, 850, 851, 909, 910, 911, - /* 480 */ 912, 913, 846, 756, 849, 832, 771, 774, 775, 772, - /* 490 */ 740, 750, 758, 759, 760, 761, 745, 746, 752, 767, - /* 500 */ 800, 801, 765, 766, 753, 754, 742, 743, 744, 847, - /* 510 */ 803, 815, 816, 677, 678, 810, 679, 680, 681, 719, - /* 520 */ 722, 723, 724, 682, 701, 704, 705, 683, 690, 684, - /* 530 */ 685, 692, 693, 694, 697, 698, 699, 700, 695, 696, - /* 540 */ 866, 867, 870, 868, 687, 688, 702, 675, 664, 656, - /* 550 */ 708, 711, 712, 713, 714, 715, 717, 709, 710, 654, - /* 560 */ 645, 648, 757, 890, 899, 895, 891, 892, 893, 649, - /* 570 */ 862, 863, 721, 794, 795, 889, 902, 904, 799, 905, - /* 580 */ 907, 903, 932, 646, 725, 726, 729, 871, 914, 785, - /* 590 */ 788, 791, 793, 873, 875, 877, 879, 880, 881, 882, - /* 600 */ 883, 876, 878, 915, 919, 922, 924, 925, 926, 929, - /* 610 */ 931, 936, 937, 938, 941, 942, 939, 626, 621, + /* 0 */ 634, 869, 958, 958, 869, 958, 958, 898, 898, 757, + /* 10 */ 867, 958, 958, 958, 958, 958, 958, 932, 958, 958, + /* 20 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, + /* 30 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, + /* 40 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, + /* 50 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, + /* 60 */ 958, 841, 958, 958, 958, 673, 898, 898, 761, 792, + /* 70 */ 958, 958, 958, 958, 958, 958, 958, 958, 793, 958, + /* 80 */ 871, 866, 862, 864, 863, 870, 794, 783, 790, 797, + /* 90 */ 772, 911, 799, 800, 806, 807, 933, 931, 829, 828, + /* 100 */ 847, 831, 845, 853, 846, 830, 840, 665, 832, 833, + /* 110 */ 958, 958, 958, 958, 958, 726, 660, 958, 958, 958, + /* 120 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, + /* 130 */ 958, 958, 958, 834, 958, 835, 848, 849, 850, 958, + /* 140 */ 958, 958, 958, 958, 958, 958, 958, 958, 640, 958, + /* 150 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, + /* 160 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, + /* 170 */ 958, 958, 958, 958, 958, 882, 958, 936, 938, 958, + /* 180 */ 958, 958, 634, 757, 757, 757, 958, 958, 958, 958, + /* 190 */ 958, 751, 761, 950, 958, 958, 717, 958, 958, 958, + /* 200 */ 958, 958, 958, 958, 958, 958, 642, 749, 675, 759, + /* 210 */ 662, 738, 904, 958, 923, 921, 740, 802, 958, 749, + /* 220 */ 758, 958, 958, 958, 865, 786, 786, 774, 786, 696, + /* 230 */ 786, 958, 786, 958, 699, 916, 796, 916, 774, 774, + /* 240 */ 796, 639, 639, 639, 639, 650, 650, 716, 958, 796, + /* 250 */ 787, 789, 779, 791, 958, 765, 765, 773, 778, 773, + /* 260 */ 778, 773, 778, 728, 728, 713, 728, 699, 728, 875, + /* 270 */ 879, 879, 713, 728, 728, 728, 875, 657, 765, 657, + /* 280 */ 765, 657, 765, 765, 908, 910, 657, 765, 730, 730, + /* 290 */ 808, 796, 765, 737, 737, 737, 737, 796, 730, 808, + /* 300 */ 765, 935, 935, 765, 765, 943, 683, 701, 701, 950, + /* 310 */ 955, 955, 958, 958, 958, 958, 958, 958, 958, 958, + /* 320 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, + /* 330 */ 884, 958, 958, 648, 958, 667, 815, 820, 816, 958, + /* 340 */ 817, 743, 958, 958, 958, 958, 958, 958, 958, 958, + /* 350 */ 958, 958, 868, 958, 780, 958, 788, 958, 958, 958, + /* 360 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, + /* 370 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, + /* 380 */ 958, 958, 958, 906, 907, 958, 958, 958, 958, 958, + /* 390 */ 958, 914, 958, 958, 958, 958, 958, 958, 958, 958, + /* 400 */ 958, 958, 958, 958, 958, 958, 958, 958, 958, 958, + /* 410 */ 958, 958, 942, 958, 958, 945, 635, 958, 630, 632, + /* 420 */ 633, 637, 638, 641, 667, 668, 670, 671, 672, 643, + /* 430 */ 644, 645, 646, 647, 649, 653, 651, 652, 654, 661, + /* 440 */ 663, 682, 684, 686, 747, 748, 812, 741, 742, 746, + /* 450 */ 669, 823, 814, 818, 819, 821, 822, 836, 837, 839, + /* 460 */ 844, 852, 855, 838, 843, 851, 854, 744, 745, 858, + /* 470 */ 676, 677, 680, 681, 894, 896, 895, 897, 679, 678, + /* 480 */ 824, 827, 860, 861, 924, 925, 926, 927, 928, 856, + /* 490 */ 766, 859, 842, 781, 784, 785, 782, 750, 760, 768, + /* 500 */ 769, 770, 771, 755, 756, 762, 777, 810, 811, 775, + /* 510 */ 776, 763, 764, 752, 753, 754, 857, 813, 825, 826, + /* 520 */ 687, 688, 820, 689, 690, 691, 729, 732, 733, 734, + /* 530 */ 692, 711, 714, 715, 693, 700, 694, 695, 702, 703, + /* 540 */ 704, 706, 707, 708, 709, 710, 705, 876, 877, 880, + /* 550 */ 878, 697, 698, 712, 685, 674, 666, 718, 721, 722, + /* 560 */ 723, 724, 725, 727, 719, 720, 664, 655, 658, 767, + /* 570 */ 900, 909, 905, 901, 902, 903, 659, 872, 873, 731, + /* 580 */ 804, 805, 899, 912, 915, 917, 918, 919, 809, 920, + /* 590 */ 922, 913, 947, 656, 735, 736, 739, 881, 929, 795, + /* 600 */ 798, 801, 803, 883, 885, 887, 889, 890, 891, 892, + /* 610 */ 893, 886, 888, 930, 934, 937, 939, 940, 941, 944, + /* 620 */ 946, 951, 952, 953, 956, 957, 954, 636, 631, }; #define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) @@ -87038,6 +90682,7 @@ static const YYCODETYPE yyFallback[] = { 0, /* ID => nothing */ 0, /* INDEXED => nothing */ 26, /* ABORT => ID */ + 26, /* ACTION => ID */ 26, /* AFTER => ID */ 26, /* ANALYZE => ID */ 26, /* ASC => ID */ @@ -87059,6 +90704,7 @@ static const YYCODETYPE yyFallback[] = { 26, /* INSTEAD => ID */ 26, /* LIKE_KW => ID */ 26, /* MATCH => ID */ + 26, /* NO => ID */ 26, /* KEY => ID */ 26, /* OF => ID */ 26, /* OFFSET => ID */ @@ -87158,32 +90804,32 @@ static const char *const yyTokenName[] = { "TABLE", "CREATE", "IF", "NOT", "EXISTS", "TEMP", "LP", "RP", "AS", "COMMA", "ID", "INDEXED", - "ABORT", "AFTER", "ANALYZE", "ASC", - "ATTACH", "BEFORE", "BY", "CASCADE", - "CAST", "COLUMNKW", "CONFLICT", "DATABASE", - "DESC", "DETACH", "EACH", "FAIL", - "FOR", "IGNORE", "INITIALLY", "INSTEAD", - "LIKE_KW", "MATCH", "KEY", "OF", - "OFFSET", "PRAGMA", "RAISE", "REPLACE", - "RESTRICT", "ROW", "TRIGGER", "VACUUM", - "VIEW", "VIRTUAL", "REINDEX", "RENAME", - "CTIME_KW", "ANY", "OR", "AND", - "IS", "BETWEEN", "IN", "ISNULL", - "NOTNULL", "NE", "EQ", "GT", - "LE", "LT", "GE", "ESCAPE", - "BITAND", "BITOR", "LSHIFT", "RSHIFT", - "PLUS", "MINUS", "STAR", "SLASH", - "REM", "CONCAT", "COLLATE", "UMINUS", - "UPLUS", "BITNOT", "STRING", "JOIN_KW", + "ABORT", "ACTION", "AFTER", "ANALYZE", + "ASC", "ATTACH", "BEFORE", "BY", + "CASCADE", "CAST", "COLUMNKW", "CONFLICT", + "DATABASE", "DESC", "DETACH", "EACH", + "FAIL", "FOR", "IGNORE", "INITIALLY", + "INSTEAD", "LIKE_KW", "MATCH", "NO", + "KEY", "OF", "OFFSET", "PRAGMA", + "RAISE", "REPLACE", "RESTRICT", "ROW", + "TRIGGER", "VACUUM", "VIEW", "VIRTUAL", + "REINDEX", "RENAME", "CTIME_KW", "ANY", + "OR", "AND", "IS", "BETWEEN", + "IN", "ISNULL", "NOTNULL", "NE", + "EQ", "GT", "LE", "LT", + "GE", "ESCAPE", "BITAND", "BITOR", + "LSHIFT", "RSHIFT", "PLUS", "MINUS", + "STAR", "SLASH", "REM", "CONCAT", + "COLLATE", "BITNOT", "STRING", "JOIN_KW", "CONSTRAINT", "DEFAULT", "NULL", "PRIMARY", "UNIQUE", "CHECK", "REFERENCES", "AUTOINCR", - "ON", "DELETE", "UPDATE", "INSERT", - "SET", "DEFERRABLE", "FOREIGN", "DROP", - "UNION", "ALL", "EXCEPT", "INTERSECT", - "SELECT", "DISTINCT", "DOT", "FROM", - "JOIN", "USING", "ORDER", "GROUP", - "HAVING", "LIMIT", "WHERE", "INTO", - "VALUES", "INTEGER", "FLOAT", "BLOB", + "ON", "DELETE", "UPDATE", "SET", + "DEFERRABLE", "FOREIGN", "DROP", "UNION", + "ALL", "EXCEPT", "INTERSECT", "SELECT", + "DISTINCT", "DOT", "FROM", "JOIN", + "USING", "ORDER", "GROUP", "HAVING", + "LIMIT", "WHERE", "INTO", "VALUES", + "INSERT", "INTEGER", "FLOAT", "BLOB", "REGISTER", "VARIABLE", "CASE", "WHEN", "THEN", "ELSE", "INDEX", "ALTER", "ADD", "error", "input", "cmdlist", @@ -87211,9 +90857,10 @@ static const char *const yyTokenName[] = { "case_else", "uniqueflag", "collate", "nmnum", "plus_opt", "number", "trigger_decl", "trigger_cmd_list", "trigger_time", "trigger_event", "foreach_clause", "when_clause", - "trigger_cmd", "database_kw_opt", "key_opt", "add_column_fullname", - "kwcolumn_opt", "create_vtab", "vtabarglist", "vtabarg", - "vtabargtoken", "lp", "anylist", + "trigger_cmd", "trnm", "tridxby", "database_kw_opt", + "key_opt", "add_column_fullname", "kwcolumn_opt", "create_vtab", + "vtabarglist", "vtabarg", "vtabargtoken", "lp", + "anylist", }; #endif /* NDEBUG */ @@ -87298,11 +90945,11 @@ static const char *const yyRuleName[] = { /* 74 */ "refarg ::= MATCH nm", /* 75 */ "refarg ::= ON DELETE refact", /* 76 */ "refarg ::= ON UPDATE refact", - /* 77 */ "refarg ::= ON INSERT refact", - /* 78 */ "refact ::= SET NULL", - /* 79 */ "refact ::= SET DEFAULT", - /* 80 */ "refact ::= CASCADE", - /* 81 */ "refact ::= RESTRICT", + /* 77 */ "refact ::= SET NULL", + /* 78 */ "refact ::= SET DEFAULT", + /* 79 */ "refact ::= CASCADE", + /* 80 */ "refact ::= RESTRICT", + /* 81 */ "refact ::= NO ACTION", /* 82 */ "defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt", /* 83 */ "defer_subclause ::= DEFERRABLE init_deferred_pred_opt", /* 84 */ "init_deferred_pred_opt ::=", @@ -87436,9 +91083,9 @@ static const char *const yyRuleName[] = { /* 212 */ "escape ::=", /* 213 */ "expr ::= expr likeop expr escape", /* 214 */ "expr ::= expr ISNULL|NOTNULL", - /* 215 */ "expr ::= expr IS NULL", - /* 216 */ "expr ::= expr NOT NULL", - /* 217 */ "expr ::= expr IS NOT NULL", + /* 215 */ "expr ::= expr NOT NULL", + /* 216 */ "expr ::= expr IS expr", + /* 217 */ "expr ::= expr IS NOT expr", /* 218 */ "expr ::= NOT expr", /* 219 */ "expr ::= BITNOT expr", /* 220 */ "expr ::= MINUS expr", @@ -87506,45 +91153,50 @@ static const char *const yyRuleName[] = { /* 282 */ "when_clause ::= WHEN expr", /* 283 */ "trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI", /* 284 */ "trigger_cmd_list ::= trigger_cmd SEMI", - /* 285 */ "trigger_cmd ::= UPDATE orconf nm SET setlist where_opt", - /* 286 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP", - /* 287 */ "trigger_cmd ::= insert_cmd INTO nm inscollist_opt select", - /* 288 */ "trigger_cmd ::= DELETE FROM nm where_opt", - /* 289 */ "trigger_cmd ::= select", - /* 290 */ "expr ::= RAISE LP IGNORE RP", - /* 291 */ "expr ::= RAISE LP raisetype COMMA nm RP", - /* 292 */ "raisetype ::= ROLLBACK", - /* 293 */ "raisetype ::= ABORT", - /* 294 */ "raisetype ::= FAIL", - /* 295 */ "cmd ::= DROP TRIGGER ifexists fullname", - /* 296 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", - /* 297 */ "cmd ::= DETACH database_kw_opt expr", - /* 298 */ "key_opt ::=", - /* 299 */ "key_opt ::= KEY expr", - /* 300 */ "database_kw_opt ::= DATABASE", - /* 301 */ "database_kw_opt ::=", - /* 302 */ "cmd ::= REINDEX", - /* 303 */ "cmd ::= REINDEX nm dbnm", - /* 304 */ "cmd ::= ANALYZE", - /* 305 */ "cmd ::= ANALYZE nm dbnm", - /* 306 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", - /* 307 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", - /* 308 */ "add_column_fullname ::= fullname", - /* 309 */ "kwcolumn_opt ::=", - /* 310 */ "kwcolumn_opt ::= COLUMNKW", - /* 311 */ "cmd ::= create_vtab", - /* 312 */ "cmd ::= create_vtab LP vtabarglist RP", - /* 313 */ "create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm", - /* 314 */ "vtabarglist ::= vtabarg", - /* 315 */ "vtabarglist ::= vtabarglist COMMA vtabarg", - /* 316 */ "vtabarg ::=", - /* 317 */ "vtabarg ::= vtabarg vtabargtoken", - /* 318 */ "vtabargtoken ::= ANY", - /* 319 */ "vtabargtoken ::= lp anylist RP", - /* 320 */ "lp ::= LP", - /* 321 */ "anylist ::=", - /* 322 */ "anylist ::= anylist LP anylist RP", - /* 323 */ "anylist ::= anylist ANY", + /* 285 */ "trnm ::= nm", + /* 286 */ "trnm ::= nm DOT nm", + /* 287 */ "tridxby ::=", + /* 288 */ "tridxby ::= INDEXED BY nm", + /* 289 */ "tridxby ::= NOT INDEXED", + /* 290 */ "trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt", + /* 291 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP", + /* 292 */ "trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select", + /* 293 */ "trigger_cmd ::= DELETE FROM trnm tridxby where_opt", + /* 294 */ "trigger_cmd ::= select", + /* 295 */ "expr ::= RAISE LP IGNORE RP", + /* 296 */ "expr ::= RAISE LP raisetype COMMA nm RP", + /* 297 */ "raisetype ::= ROLLBACK", + /* 298 */ "raisetype ::= ABORT", + /* 299 */ "raisetype ::= FAIL", + /* 300 */ "cmd ::= DROP TRIGGER ifexists fullname", + /* 301 */ "cmd ::= ATTACH database_kw_opt expr AS expr key_opt", + /* 302 */ "cmd ::= DETACH database_kw_opt expr", + /* 303 */ "key_opt ::=", + /* 304 */ "key_opt ::= KEY expr", + /* 305 */ "database_kw_opt ::= DATABASE", + /* 306 */ "database_kw_opt ::=", + /* 307 */ "cmd ::= REINDEX", + /* 308 */ "cmd ::= REINDEX nm dbnm", + /* 309 */ "cmd ::= ANALYZE", + /* 310 */ "cmd ::= ANALYZE nm dbnm", + /* 311 */ "cmd ::= ALTER TABLE fullname RENAME TO nm", + /* 312 */ "cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column", + /* 313 */ "add_column_fullname ::= fullname", + /* 314 */ "kwcolumn_opt ::=", + /* 315 */ "kwcolumn_opt ::= COLUMNKW", + /* 316 */ "cmd ::= create_vtab", + /* 317 */ "cmd ::= create_vtab LP vtabarglist RP", + /* 318 */ "create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm", + /* 319 */ "vtabarglist ::= vtabarg", + /* 320 */ "vtabarglist ::= vtabarglist COMMA vtabarg", + /* 321 */ "vtabarg ::=", + /* 322 */ "vtabarg ::= vtabarg vtabargtoken", + /* 323 */ "vtabargtoken ::= ANY", + /* 324 */ "vtabargtoken ::= lp anylist RP", + /* 325 */ "lp ::= LP", + /* 326 */ "anylist ::=", + /* 327 */ "anylist ::= anylist LP anylist RP", + /* 328 */ "anylist ::= anylist ANY", }; #endif /* NDEBUG */ @@ -87626,14 +91278,14 @@ static void yy_destructor( case 160: /* select */ case 194: /* oneselect */ { -sqlite3SelectDelete(pParse->db, (yypminor->yy243)); +sqlite3SelectDelete(pParse->db, (yypminor->yy3)); } break; case 174: /* term */ case 175: /* expr */ case 223: /* escape */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy190).pExpr); +sqlite3ExprDelete(pParse->db, (yypminor->yy346).pExpr); } break; case 179: /* idxlist_opt */ @@ -87649,7 +91301,7 @@ sqlite3ExprDelete(pParse->db, (yypminor->yy190).pExpr); case 221: /* exprlist */ case 227: /* case_exprlist */ { -sqlite3ExprListDelete(pParse->db, (yypminor->yy148)); +sqlite3ExprListDelete(pParse->db, (yypminor->yy14)); } break; case 193: /* fullname */ @@ -87657,7 +91309,7 @@ sqlite3ExprListDelete(pParse->db, (yypminor->yy148)); case 206: /* seltablist */ case 207: /* stl_prefix */ { -sqlite3SrcListDelete(pParse->db, (yypminor->yy185)); +sqlite3SrcListDelete(pParse->db, (yypminor->yy65)); } break; case 199: /* where_opt */ @@ -87667,27 +91319,27 @@ sqlite3SrcListDelete(pParse->db, (yypminor->yy185)); case 226: /* case_operand */ case 228: /* case_else */ case 239: /* when_clause */ - case 242: /* key_opt */ + case 244: /* key_opt */ { -sqlite3ExprDelete(pParse->db, (yypminor->yy72)); +sqlite3ExprDelete(pParse->db, (yypminor->yy132)); } break; case 211: /* using_opt */ case 213: /* inscollist */ case 219: /* inscollist_opt */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy254)); +sqlite3IdListDelete(pParse->db, (yypminor->yy408)); } break; case 235: /* trigger_cmd_list */ case 240: /* trigger_cmd */ { -sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy145)); +sqlite3DeleteTriggerStep(pParse->db, (yypminor->yy473)); } break; case 237: /* trigger_event */ { -sqlite3IdListDelete(pParse->db, (yypminor->yy332).b); +sqlite3IdListDelete(pParse->db, (yypminor->yy378).b); } break; default: break; /* If no destructor action specified: do nothing */ @@ -87706,7 +91358,9 @@ static int yy_pop_parser_stack(yyParser *pParser){ YYCODETYPE yymajor; yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; - if( pParser->yyidx<0 ) return 0; + /* There is no mechanism by which the parser stack can be popped below + ** empty in SQLite. */ + if( NEVER(pParser->yyidx<0) ) return 0; #ifndef NDEBUG if( yyTraceFILE && pParser->yyidx>=0 ){ fprintf(yyTraceFILE,"%sPopping %s\n", @@ -87737,7 +91391,9 @@ SQLITE_PRIVATE void sqlite3ParserFree( void (*freeProc)(void*) /* Function used to reclaim memory */ ){ yyParser *pParser = (yyParser*)p; - if( pParser==0 ) return; + /* In SQLite, we never try to destroy a parser that was not successfully + ** created in the first place. */ + if( NEVER(pParser==0) ) return; while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); #if YYSTACKDEPTH<=0 free(pParser->yystack); @@ -87776,6 +91432,8 @@ static int yy_find_shift_action( assert( iLookAhead!=YYNOCODE ); i += iLookAhead; if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ + /* The user of ";" instead of "\000" as a statement terminator in SQLite + ** means that we always have a look-ahead token. */ if( iLookAhead>0 ){ #ifdef YYFALLBACK YYCODETYPE iFallback; /* Fallback token */ @@ -87997,11 +91655,11 @@ static const struct { { 182, 2 }, { 182, 3 }, { 182, 3 }, - { 182, 3 }, { 183, 2 }, { 183, 2 }, { 183, 1 }, { 183, 1 }, + { 183, 2 }, { 181, 3 }, { 181, 2 }, { 184, 0 }, @@ -88205,10 +91863,15 @@ static const struct { { 239, 2 }, { 235, 3 }, { 235, 2 }, - { 240, 6 }, + { 241, 1 }, + { 241, 3 }, + { 242, 0 }, + { 242, 3 }, + { 242, 2 }, + { 240, 7 }, { 240, 8 }, { 240, 5 }, - { 240, 4 }, + { 240, 5 }, { 240, 1 }, { 175, 4 }, { 175, 6 }, @@ -88218,32 +91881,32 @@ static const struct { { 147, 4 }, { 147, 6 }, { 147, 3 }, - { 242, 0 }, - { 242, 2 }, - { 241, 1 }, - { 241, 0 }, + { 244, 0 }, + { 244, 2 }, + { 243, 1 }, + { 243, 0 }, { 147, 1 }, { 147, 3 }, { 147, 1 }, { 147, 3 }, { 147, 6 }, { 147, 6 }, - { 243, 1 }, - { 244, 0 }, - { 244, 1 }, + { 245, 1 }, + { 246, 0 }, + { 246, 1 }, { 147, 1 }, { 147, 4 }, - { 245, 7 }, - { 246, 1 }, - { 246, 3 }, - { 247, 0 }, - { 247, 2 }, + { 247, 7 }, { 248, 1 }, { 248, 3 }, - { 249, 1 }, - { 250, 0 }, - { 250, 4 }, - { 250, 2 }, + { 249, 0 }, + { 249, 2 }, + { 250, 1 }, + { 250, 3 }, + { 251, 1 }, + { 252, 0 }, + { 252, 4 }, + { 252, 2 }, }; static void yy_accept(yyParser*); /* Forward Declaration */ @@ -88311,17 +91974,17 @@ static void yy_reduce( { sqlite3FinishCoding(pParse); } break; case 9: /* cmd ::= BEGIN transtype trans_opt */ -{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy194);} +{sqlite3BeginTransaction(pParse, yymsp[-1].minor.yy328);} break; case 13: /* transtype ::= */ -{yygotominor.yy194 = TK_DEFERRED;} +{yygotominor.yy328 = TK_DEFERRED;} break; case 14: /* transtype ::= DEFERRED */ case 15: /* transtype ::= IMMEDIATE */ yytestcase(yyruleno==15); case 16: /* transtype ::= EXCLUSIVE */ yytestcase(yyruleno==16); case 114: /* multiselect_op ::= UNION */ yytestcase(yyruleno==114); case 116: /* multiselect_op ::= EXCEPT|INTERSECT */ yytestcase(yyruleno==116); -{yygotominor.yy194 = yymsp[0].major;} +{yygotominor.yy328 = yymsp[0].major;} break; case 17: /* cmd ::= COMMIT trans_opt */ case 18: /* cmd ::= END trans_opt */ yytestcase(yyruleno==18); @@ -88347,7 +92010,7 @@ static void yy_reduce( break; case 26: /* create_table ::= createkw temp TABLE ifnotexists nm dbnm */ { - sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy194,0,0,yymsp[-2].minor.yy194); + sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy328,0,0,yymsp[-2].minor.yy328); } break; case 27: /* createkw ::= CREATE */ @@ -88359,6 +92022,7 @@ static void yy_reduce( case 28: /* ifnotexists ::= */ case 31: /* temp ::= */ yytestcase(yyruleno==31); case 70: /* autoinc ::= */ yytestcase(yyruleno==70); + case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==82); case 84: /* init_deferred_pred_opt ::= */ yytestcase(yyruleno==84); case 86: /* init_deferred_pred_opt ::= INITIALLY IMMEDIATE */ yytestcase(yyruleno==86); case 97: /* defer_subclause_opt ::= */ yytestcase(yyruleno==97); @@ -88367,7 +92031,7 @@ static void yy_reduce( case 120: /* distinct ::= */ yytestcase(yyruleno==120); case 222: /* between_op ::= BETWEEN */ yytestcase(yyruleno==222); case 225: /* in_op ::= IN */ yytestcase(yyruleno==225); -{yygotominor.yy194 = 0;} +{yygotominor.yy328 = 0;} break; case 29: /* ifnotexists ::= IF NOT EXISTS */ case 30: /* temp ::= TEMP */ yytestcase(yyruleno==30); @@ -88377,7 +92041,7 @@ static void yy_reduce( case 118: /* distinct ::= DISTINCT */ yytestcase(yyruleno==118); case 223: /* between_op ::= NOT BETWEEN */ yytestcase(yyruleno==223); case 226: /* in_op ::= NOT IN */ yytestcase(yyruleno==226); -{yygotominor.yy194 = 1;} +{yygotominor.yy328 = 1;} break; case 32: /* create_table_args ::= LP columnlist conslist_opt RP */ { @@ -88386,8 +92050,8 @@ static void yy_reduce( break; case 33: /* create_table_args ::= AS select */ { - sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy243); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243); + sqlite3EndTable(pParse,0,0,yymsp[0].minor.yy3); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3); } break; case 36: /* column ::= columnid type carglist */ @@ -88423,6 +92087,7 @@ static void yy_reduce( case 265: /* plus_num ::= plus_opt number */ yytestcase(yyruleno==265); case 266: /* minus_num ::= MINUS number */ yytestcase(yyruleno==266); case 267: /* number ::= INTEGER|FLOAT */ yytestcase(yyruleno==267); + case 285: /* trnm ::= nm */ yytestcase(yyruleno==285); {yygotominor.yy0 = yymsp[0].minor.yy0;} break; case 45: /* type ::= typetoken */ @@ -88445,17 +92110,17 @@ static void yy_reduce( break; case 57: /* ccons ::= DEFAULT term */ case 59: /* ccons ::= DEFAULT PLUS term */ yytestcase(yyruleno==59); -{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy190);} +{sqlite3AddDefaultValue(pParse,&yymsp[0].minor.yy346);} break; case 58: /* ccons ::= DEFAULT LP expr RP */ -{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy190);} +{sqlite3AddDefaultValue(pParse,&yymsp[-1].minor.yy346);} break; case 60: /* ccons ::= DEFAULT MINUS term */ { ExprSpan v; - v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy190.pExpr, 0, 0); + v.pExpr = sqlite3PExpr(pParse, TK_UMINUS, yymsp[0].minor.yy346.pExpr, 0, 0); v.zStart = yymsp[-1].minor.yy0.z; - v.zEnd = yymsp[0].minor.yy190.zEnd; + v.zEnd = yymsp[0].minor.yy346.zEnd; sqlite3AddDefaultValue(pParse,&v); } break; @@ -88467,64 +92132,61 @@ static void yy_reduce( } break; case 63: /* ccons ::= NOT NULL onconf */ -{sqlite3AddNotNull(pParse, yymsp[0].minor.yy194);} +{sqlite3AddNotNull(pParse, yymsp[0].minor.yy328);} break; case 64: /* ccons ::= PRIMARY KEY sortorder onconf autoinc */ -{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy194,yymsp[0].minor.yy194,yymsp[-2].minor.yy194);} +{sqlite3AddPrimaryKey(pParse,0,yymsp[-1].minor.yy328,yymsp[0].minor.yy328,yymsp[-2].minor.yy328);} break; case 65: /* ccons ::= UNIQUE onconf */ -{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy194,0,0,0,0);} +{sqlite3CreateIndex(pParse,0,0,0,0,yymsp[0].minor.yy328,0,0,0,0);} break; case 66: /* ccons ::= CHECK LP expr RP */ -{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy190.pExpr);} +{sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy346.pExpr);} break; case 67: /* ccons ::= REFERENCES nm idxlist_opt refargs */ -{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy148,yymsp[0].minor.yy194);} +{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy14,yymsp[0].minor.yy328);} break; case 68: /* ccons ::= defer_subclause */ -{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy194);} +{sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy328);} break; case 69: /* ccons ::= COLLATE ids */ {sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);} break; case 72: /* refargs ::= */ -{ yygotominor.yy194 = OE_Restrict * 0x010101; } +{ yygotominor.yy328 = OE_None * 0x000101; } break; case 73: /* refargs ::= refargs refarg */ -{ yygotominor.yy194 = (yymsp[-1].minor.yy194 & ~yymsp[0].minor.yy497.mask) | yymsp[0].minor.yy497.value; } +{ yygotominor.yy328 = (yymsp[-1].minor.yy328 & ~yymsp[0].minor.yy429.mask) | yymsp[0].minor.yy429.value; } break; case 74: /* refarg ::= MATCH nm */ -{ yygotominor.yy497.value = 0; yygotominor.yy497.mask = 0x000000; } +{ yygotominor.yy429.value = 0; yygotominor.yy429.mask = 0x000000; } break; case 75: /* refarg ::= ON DELETE refact */ -{ yygotominor.yy497.value = yymsp[0].minor.yy194; yygotominor.yy497.mask = 0x0000ff; } +{ yygotominor.yy429.value = yymsp[0].minor.yy328; yygotominor.yy429.mask = 0x0000ff; } break; case 76: /* refarg ::= ON UPDATE refact */ -{ yygotominor.yy497.value = yymsp[0].minor.yy194<<8; yygotominor.yy497.mask = 0x00ff00; } +{ yygotominor.yy429.value = yymsp[0].minor.yy328<<8; yygotominor.yy429.mask = 0x00ff00; } break; - case 77: /* refarg ::= ON INSERT refact */ -{ yygotominor.yy497.value = yymsp[0].minor.yy194<<16; yygotominor.yy497.mask = 0xff0000; } + case 77: /* refact ::= SET NULL */ +{ yygotominor.yy328 = OE_SetNull; } break; - case 78: /* refact ::= SET NULL */ -{ yygotominor.yy194 = OE_SetNull; } + case 78: /* refact ::= SET DEFAULT */ +{ yygotominor.yy328 = OE_SetDflt; } break; - case 79: /* refact ::= SET DEFAULT */ -{ yygotominor.yy194 = OE_SetDflt; } + case 79: /* refact ::= CASCADE */ +{ yygotominor.yy328 = OE_Cascade; } break; - case 80: /* refact ::= CASCADE */ -{ yygotominor.yy194 = OE_Cascade; } + case 80: /* refact ::= RESTRICT */ +{ yygotominor.yy328 = OE_Restrict; } break; - case 81: /* refact ::= RESTRICT */ -{ yygotominor.yy194 = OE_Restrict; } + case 81: /* refact ::= NO ACTION */ +{ yygotominor.yy328 = OE_None; } break; - case 82: /* defer_subclause ::= NOT DEFERRABLE init_deferred_pred_opt */ - case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ yytestcase(yyruleno==83); + case 83: /* defer_subclause ::= DEFERRABLE init_deferred_pred_opt */ case 98: /* defer_subclause_opt ::= defer_subclause */ yytestcase(yyruleno==98); case 100: /* onconf ::= ON CONFLICT resolvetype */ yytestcase(yyruleno==100); - case 102: /* orconf ::= OR resolvetype */ yytestcase(yyruleno==102); case 103: /* resolvetype ::= raisetype */ yytestcase(yyruleno==103); - case 175: /* insert_cmd ::= INSERT orconf */ yytestcase(yyruleno==175); -{yygotominor.yy194 = yymsp[0].minor.yy194;} +{yygotominor.yy328 = yymsp[0].minor.yy328;} break; case 87: /* conslist_opt ::= */ {yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;} @@ -88533,97 +92195,101 @@ static void yy_reduce( {yygotominor.yy0 = yymsp[-1].minor.yy0;} break; case 93: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */ -{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy148,yymsp[0].minor.yy194,yymsp[-2].minor.yy194,0);} +{sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy14,yymsp[0].minor.yy328,yymsp[-2].minor.yy328,0);} break; case 94: /* tcons ::= UNIQUE LP idxlist RP onconf */ -{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy148,yymsp[0].minor.yy194,0,0,0,0);} +{sqlite3CreateIndex(pParse,0,0,0,yymsp[-2].minor.yy14,yymsp[0].minor.yy328,0,0,0,0);} break; case 95: /* tcons ::= CHECK LP expr RP onconf */ -{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy190.pExpr);} +{sqlite3AddCheckConstraint(pParse,yymsp[-2].minor.yy346.pExpr);} break; case 96: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */ { - sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy148, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy148, yymsp[-1].minor.yy194); - sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy194); + sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy14, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy14, yymsp[-1].minor.yy328); + sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy328); } break; case 99: /* onconf ::= */ - case 101: /* orconf ::= */ yytestcase(yyruleno==101); -{yygotominor.yy194 = OE_Default;} +{yygotominor.yy328 = OE_Default;} + break; + case 101: /* orconf ::= */ +{yygotominor.yy186 = OE_Default;} + break; + case 102: /* orconf ::= OR resolvetype */ +{yygotominor.yy186 = (u8)yymsp[0].minor.yy328;} break; case 104: /* resolvetype ::= IGNORE */ -{yygotominor.yy194 = OE_Ignore;} +{yygotominor.yy328 = OE_Ignore;} break; case 105: /* resolvetype ::= REPLACE */ - case 176: /* insert_cmd ::= REPLACE */ yytestcase(yyruleno==176); -{yygotominor.yy194 = OE_Replace;} +{yygotominor.yy328 = OE_Replace;} break; case 106: /* cmd ::= DROP TABLE ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy185, 0, yymsp[-1].minor.yy194); + sqlite3DropTable(pParse, yymsp[0].minor.yy65, 0, yymsp[-1].minor.yy328); } break; case 109: /* cmd ::= createkw temp VIEW ifnotexists nm dbnm AS select */ { - sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy243, yymsp[-6].minor.yy194, yymsp[-4].minor.yy194); + sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy3, yymsp[-6].minor.yy328, yymsp[-4].minor.yy328); } break; case 110: /* cmd ::= DROP VIEW ifexists fullname */ { - sqlite3DropTable(pParse, yymsp[0].minor.yy185, 1, yymsp[-1].minor.yy194); + sqlite3DropTable(pParse, yymsp[0].minor.yy65, 1, yymsp[-1].minor.yy328); } break; case 111: /* cmd ::= select */ { SelectDest dest = {SRT_Output, 0, 0, 0, 0}; - sqlite3Select(pParse, yymsp[0].minor.yy243, &dest); - sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy243); + sqlite3Select(pParse, yymsp[0].minor.yy3, &dest); + sqlite3SelectDelete(pParse->db, yymsp[0].minor.yy3); } break; case 112: /* select ::= oneselect */ -{yygotominor.yy243 = yymsp[0].minor.yy243;} +{yygotominor.yy3 = yymsp[0].minor.yy3;} break; case 113: /* select ::= select multiselect_op oneselect */ { - if( yymsp[0].minor.yy243 ){ - yymsp[0].minor.yy243->op = (u8)yymsp[-1].minor.yy194; - yymsp[0].minor.yy243->pPrior = yymsp[-2].minor.yy243; + if( yymsp[0].minor.yy3 ){ + yymsp[0].minor.yy3->op = (u8)yymsp[-1].minor.yy328; + yymsp[0].minor.yy3->pPrior = yymsp[-2].minor.yy3; }else{ - sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy243); + sqlite3SelectDelete(pParse->db, yymsp[-2].minor.yy3); } - yygotominor.yy243 = yymsp[0].minor.yy243; + yygotominor.yy3 = yymsp[0].minor.yy3; } break; case 115: /* multiselect_op ::= UNION ALL */ -{yygotominor.yy194 = TK_ALL;} +{yygotominor.yy328 = TK_ALL;} break; case 117: /* oneselect ::= SELECT distinct selcollist from where_opt groupby_opt having_opt orderby_opt limit_opt */ { - yygotominor.yy243 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy148,yymsp[-5].minor.yy185,yymsp[-4].minor.yy72,yymsp[-3].minor.yy148,yymsp[-2].minor.yy72,yymsp[-1].minor.yy148,yymsp[-7].minor.yy194,yymsp[0].minor.yy354.pLimit,yymsp[0].minor.yy354.pOffset); + yygotominor.yy3 = sqlite3SelectNew(pParse,yymsp[-6].minor.yy14,yymsp[-5].minor.yy65,yymsp[-4].minor.yy132,yymsp[-3].minor.yy14,yymsp[-2].minor.yy132,yymsp[-1].minor.yy14,yymsp[-7].minor.yy328,yymsp[0].minor.yy476.pLimit,yymsp[0].minor.yy476.pOffset); } break; case 121: /* sclp ::= selcollist COMMA */ case 247: /* idxlist_opt ::= LP idxlist RP */ yytestcase(yyruleno==247); -{yygotominor.yy148 = yymsp[-1].minor.yy148;} +{yygotominor.yy14 = yymsp[-1].minor.yy14;} break; case 122: /* sclp ::= */ case 150: /* orderby_opt ::= */ yytestcase(yyruleno==150); case 158: /* groupby_opt ::= */ yytestcase(yyruleno==158); case 240: /* exprlist ::= */ yytestcase(yyruleno==240); case 246: /* idxlist_opt ::= */ yytestcase(yyruleno==246); -{yygotominor.yy148 = 0;} +{yygotominor.yy14 = 0;} break; case 123: /* selcollist ::= sclp expr as */ { - yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy148, yymsp[-1].minor.yy190.pExpr); - if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy148, &yymsp[0].minor.yy0, 1); - sqlite3ExprListSetSpan(pParse,yygotominor.yy148,&yymsp[-1].minor.yy190); + yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-2].minor.yy14, yymsp[-1].minor.yy346.pExpr); + if( yymsp[0].minor.yy0.n>0 ) sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[0].minor.yy0, 1); + sqlite3ExprListSetSpan(pParse,yygotominor.yy14,&yymsp[-1].minor.yy346); } break; case 124: /* selcollist ::= sclp STAR */ { Expr *p = sqlite3Expr(pParse->db, TK_ALL, 0); - yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy148, p); + yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-1].minor.yy14, p); } break; case 125: /* selcollist ::= sclp nm DOT STAR */ @@ -88631,52 +92297,50 @@ static void yy_reduce( Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, &yymsp[0].minor.yy0); Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0); - yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148, pDot); + yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14, pDot); } break; case 128: /* as ::= */ {yygotominor.yy0.n = 0;} break; case 129: /* from ::= */ -{yygotominor.yy185 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy185));} +{yygotominor.yy65 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy65));} break; case 130: /* from ::= FROM seltablist */ { - yygotominor.yy185 = yymsp[0].minor.yy185; - sqlite3SrcListShiftJoinType(yygotominor.yy185); + yygotominor.yy65 = yymsp[0].minor.yy65; + sqlite3SrcListShiftJoinType(yygotominor.yy65); } break; case 131: /* stl_prefix ::= seltablist joinop */ { - yygotominor.yy185 = yymsp[-1].minor.yy185; - if( ALWAYS(yygotominor.yy185 && yygotominor.yy185->nSrc>0) ) yygotominor.yy185->a[yygotominor.yy185->nSrc-1].jointype = (u8)yymsp[0].minor.yy194; + yygotominor.yy65 = yymsp[-1].minor.yy65; + if( ALWAYS(yygotominor.yy65 && yygotominor.yy65->nSrc>0) ) yygotominor.yy65->a[yygotominor.yy65->nSrc-1].jointype = (u8)yymsp[0].minor.yy328; } break; case 132: /* stl_prefix ::= */ -{yygotominor.yy185 = 0;} +{yygotominor.yy65 = 0;} break; case 133: /* seltablist ::= stl_prefix nm dbnm as indexed_opt on_opt using_opt */ { - yygotominor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); - sqlite3SrcListIndexedBy(pParse, yygotominor.yy185, &yymsp[-2].minor.yy0); + yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,&yymsp[-5].minor.yy0,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,0,yymsp[-1].minor.yy132,yymsp[0].minor.yy408); + sqlite3SrcListIndexedBy(pParse, yygotominor.yy65, &yymsp[-2].minor.yy0); } break; case 134: /* seltablist ::= stl_prefix LP select RP as on_opt using_opt */ { - yygotominor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy243,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); + yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy3,yymsp[-1].minor.yy132,yymsp[0].minor.yy408); } break; case 135: /* seltablist ::= stl_prefix LP seltablist RP as on_opt using_opt */ { - if( yymsp[-6].minor.yy185==0 ){ - sqlite3ExprDelete(pParse->db, yymsp[-1].minor.yy72); - sqlite3IdListDelete(pParse->db, yymsp[0].minor.yy254); - yygotominor.yy185 = yymsp[-4].minor.yy185; + if( yymsp[-6].minor.yy65==0 && yymsp[-2].minor.yy0.n==0 && yymsp[-1].minor.yy132==0 && yymsp[0].minor.yy408==0 ){ + yygotominor.yy65 = yymsp[-4].minor.yy65; }else{ Select *pSubquery; - sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy185); - pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy185,0,0,0,0,0,0,0); - yygotominor.yy185 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy185,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy72,yymsp[0].minor.yy254); + sqlite3SrcListShiftJoinType(yymsp[-4].minor.yy65); + pSubquery = sqlite3SelectNew(pParse,0,yymsp[-4].minor.yy65,0,0,0,0,0,0,0); + yygotominor.yy65 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy65,0,0,&yymsp[-2].minor.yy0,pSubquery,yymsp[-1].minor.yy132,yymsp[0].minor.yy408); } } break; @@ -88685,19 +92349,19 @@ static void yy_reduce( {yygotominor.yy0.z=0; yygotominor.yy0.n=0;} break; case 138: /* fullname ::= nm dbnm */ -{yygotominor.yy185 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} +{yygotominor.yy65 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);} break; case 139: /* joinop ::= COMMA|JOIN */ -{ yygotominor.yy194 = JT_INNER; } +{ yygotominor.yy328 = JT_INNER; } break; case 140: /* joinop ::= JOIN_KW JOIN */ -{ yygotominor.yy194 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } +{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); } break; case 141: /* joinop ::= JOIN_KW nm JOIN */ -{ yygotominor.yy194 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); } +{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); } break; case 142: /* joinop ::= JOIN_KW nm nm JOIN */ -{ yygotominor.yy194 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); } +{ yygotominor.yy328 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); } break; case 143: /* on_opt ::= ON expr */ case 154: /* sortitem ::= expr */ yytestcase(yyruleno==154); @@ -88705,132 +92369,138 @@ static void yy_reduce( case 168: /* where_opt ::= WHERE expr */ yytestcase(yyruleno==168); case 235: /* case_else ::= ELSE expr */ yytestcase(yyruleno==235); case 237: /* case_operand ::= expr */ yytestcase(yyruleno==237); -{yygotominor.yy72 = yymsp[0].minor.yy190.pExpr;} +{yygotominor.yy132 = yymsp[0].minor.yy346.pExpr;} break; case 144: /* on_opt ::= */ case 160: /* having_opt ::= */ yytestcase(yyruleno==160); case 167: /* where_opt ::= */ yytestcase(yyruleno==167); case 236: /* case_else ::= */ yytestcase(yyruleno==236); case 238: /* case_operand ::= */ yytestcase(yyruleno==238); -{yygotominor.yy72 = 0;} +{yygotominor.yy132 = 0;} break; case 147: /* indexed_opt ::= NOT INDEXED */ {yygotominor.yy0.z=0; yygotominor.yy0.n=1;} break; case 148: /* using_opt ::= USING LP inscollist RP */ case 180: /* inscollist_opt ::= LP inscollist RP */ yytestcase(yyruleno==180); -{yygotominor.yy254 = yymsp[-1].minor.yy254;} +{yygotominor.yy408 = yymsp[-1].minor.yy408;} break; case 149: /* using_opt ::= */ case 179: /* inscollist_opt ::= */ yytestcase(yyruleno==179); -{yygotominor.yy254 = 0;} +{yygotominor.yy408 = 0;} break; case 151: /* orderby_opt ::= ORDER BY sortlist */ case 159: /* groupby_opt ::= GROUP BY nexprlist */ yytestcase(yyruleno==159); case 239: /* exprlist ::= nexprlist */ yytestcase(yyruleno==239); -{yygotominor.yy148 = yymsp[0].minor.yy148;} +{yygotominor.yy14 = yymsp[0].minor.yy14;} break; case 152: /* sortlist ::= sortlist COMMA sortitem sortorder */ { - yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy148,yymsp[-1].minor.yy72); - if( yygotominor.yy148 ) yygotominor.yy148->a[yygotominor.yy148->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy194; + yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy14,yymsp[-1].minor.yy132); + if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328; } break; case 153: /* sortlist ::= sortitem sortorder */ { - yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy72); - if( yygotominor.yy148 && ALWAYS(yygotominor.yy148->a) ) yygotominor.yy148->a[0].sortOrder = (u8)yymsp[0].minor.yy194; + yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[-1].minor.yy132); + if( yygotominor.yy14 && ALWAYS(yygotominor.yy14->a) ) yygotominor.yy14->a[0].sortOrder = (u8)yymsp[0].minor.yy328; } break; case 155: /* sortorder ::= ASC */ case 157: /* sortorder ::= */ yytestcase(yyruleno==157); -{yygotominor.yy194 = SQLITE_SO_ASC;} +{yygotominor.yy328 = SQLITE_SO_ASC;} break; case 156: /* sortorder ::= DESC */ -{yygotominor.yy194 = SQLITE_SO_DESC;} +{yygotominor.yy328 = SQLITE_SO_DESC;} break; case 162: /* limit_opt ::= */ -{yygotominor.yy354.pLimit = 0; yygotominor.yy354.pOffset = 0;} +{yygotominor.yy476.pLimit = 0; yygotominor.yy476.pOffset = 0;} break; case 163: /* limit_opt ::= LIMIT expr */ -{yygotominor.yy354.pLimit = yymsp[0].minor.yy190.pExpr; yygotominor.yy354.pOffset = 0;} +{yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr; yygotominor.yy476.pOffset = 0;} break; case 164: /* limit_opt ::= LIMIT expr OFFSET expr */ -{yygotominor.yy354.pLimit = yymsp[-2].minor.yy190.pExpr; yygotominor.yy354.pOffset = yymsp[0].minor.yy190.pExpr;} +{yygotominor.yy476.pLimit = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pOffset = yymsp[0].minor.yy346.pExpr;} break; case 165: /* limit_opt ::= LIMIT expr COMMA expr */ -{yygotominor.yy354.pOffset = yymsp[-2].minor.yy190.pExpr; yygotominor.yy354.pLimit = yymsp[0].minor.yy190.pExpr;} +{yygotominor.yy476.pOffset = yymsp[-2].minor.yy346.pExpr; yygotominor.yy476.pLimit = yymsp[0].minor.yy346.pExpr;} break; case 166: /* cmd ::= DELETE FROM fullname indexed_opt where_opt */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy185, &yymsp[-1].minor.yy0); - sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy185,yymsp[0].minor.yy72); + sqlite3SrcListIndexedBy(pParse, yymsp[-2].minor.yy65, &yymsp[-1].minor.yy0); + sqlite3DeleteFrom(pParse,yymsp[-2].minor.yy65,yymsp[0].minor.yy132); } break; case 169: /* cmd ::= UPDATE orconf fullname indexed_opt SET setlist where_opt */ { - sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy185, &yymsp[-3].minor.yy0); - sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy148,"set list"); - sqlite3Update(pParse,yymsp[-4].minor.yy185,yymsp[-1].minor.yy148,yymsp[0].minor.yy72,yymsp[-5].minor.yy194); + sqlite3SrcListIndexedBy(pParse, yymsp[-4].minor.yy65, &yymsp[-3].minor.yy0); + sqlite3ExprListCheckLength(pParse,yymsp[-1].minor.yy14,"set list"); + sqlite3Update(pParse,yymsp[-4].minor.yy65,yymsp[-1].minor.yy14,yymsp[0].minor.yy132,yymsp[-5].minor.yy186); } break; case 170: /* setlist ::= setlist COMMA nm EQ expr */ { - yygotominor.yy148 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy148, yymsp[0].minor.yy190.pExpr); - sqlite3ExprListSetName(pParse, yygotominor.yy148, &yymsp[-2].minor.yy0, 1); + yygotominor.yy14 = sqlite3ExprListAppend(pParse, yymsp[-4].minor.yy14, yymsp[0].minor.yy346.pExpr); + sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1); } break; case 171: /* setlist ::= nm EQ expr */ { - yygotominor.yy148 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy190.pExpr); - sqlite3ExprListSetName(pParse, yygotominor.yy148, &yymsp[-2].minor.yy0, 1); + yygotominor.yy14 = sqlite3ExprListAppend(pParse, 0, yymsp[0].minor.yy346.pExpr); + sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1); } break; case 172: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */ -{sqlite3Insert(pParse, yymsp[-5].minor.yy185, yymsp[-1].minor.yy148, 0, yymsp[-4].minor.yy254, yymsp[-7].minor.yy194);} +{sqlite3Insert(pParse, yymsp[-5].minor.yy65, yymsp[-1].minor.yy14, 0, yymsp[-4].minor.yy408, yymsp[-7].minor.yy186);} break; case 173: /* cmd ::= insert_cmd INTO fullname inscollist_opt select */ -{sqlite3Insert(pParse, yymsp[-2].minor.yy185, 0, yymsp[0].minor.yy243, yymsp[-1].minor.yy254, yymsp[-4].minor.yy194);} +{sqlite3Insert(pParse, yymsp[-2].minor.yy65, 0, yymsp[0].minor.yy3, yymsp[-1].minor.yy408, yymsp[-4].minor.yy186);} break; case 174: /* cmd ::= insert_cmd INTO fullname inscollist_opt DEFAULT VALUES */ -{sqlite3Insert(pParse, yymsp[-3].minor.yy185, 0, 0, yymsp[-2].minor.yy254, yymsp[-5].minor.yy194);} +{sqlite3Insert(pParse, yymsp[-3].minor.yy65, 0, 0, yymsp[-2].minor.yy408, yymsp[-5].minor.yy186);} + break; + case 175: /* insert_cmd ::= INSERT orconf */ +{yygotominor.yy186 = yymsp[0].minor.yy186;} + break; + case 176: /* insert_cmd ::= REPLACE */ +{yygotominor.yy186 = OE_Replace;} break; case 177: /* itemlist ::= itemlist COMMA expr */ case 241: /* nexprlist ::= nexprlist COMMA expr */ yytestcase(yyruleno==241); -{yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy148,yymsp[0].minor.yy190.pExpr);} +{yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy14,yymsp[0].minor.yy346.pExpr);} break; case 178: /* itemlist ::= expr */ case 242: /* nexprlist ::= expr */ yytestcase(yyruleno==242); -{yygotominor.yy148 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy190.pExpr);} +{yygotominor.yy14 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy346.pExpr);} break; case 181: /* inscollist ::= inscollist COMMA nm */ -{yygotominor.yy254 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy254,&yymsp[0].minor.yy0);} +{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy408,&yymsp[0].minor.yy0);} break; case 182: /* inscollist ::= nm */ -{yygotominor.yy254 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);} +{yygotominor.yy408 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);} break; case 183: /* expr ::= term */ case 211: /* escape ::= ESCAPE expr */ yytestcase(yyruleno==211); -{yygotominor.yy190 = yymsp[0].minor.yy190;} +{yygotominor.yy346 = yymsp[0].minor.yy346;} break; case 184: /* expr ::= LP expr RP */ -{yygotominor.yy190.pExpr = yymsp[-1].minor.yy190.pExpr; spanSet(&yygotominor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);} +{yygotominor.yy346.pExpr = yymsp[-1].minor.yy346.pExpr; spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0);} break; case 185: /* term ::= NULL */ case 190: /* term ::= INTEGER|FLOAT|BLOB */ yytestcase(yyruleno==190); case 191: /* term ::= STRING */ yytestcase(yyruleno==191); -{spanExpr(&yygotominor.yy190, pParse, yymsp[0].major, &yymsp[0].minor.yy0);} +{spanExpr(&yygotominor.yy346, pParse, yymsp[0].major, &yymsp[0].minor.yy0);} break; case 186: /* expr ::= id */ case 187: /* expr ::= JOIN_KW */ yytestcase(yyruleno==187); -{spanExpr(&yygotominor.yy190, pParse, TK_ID, &yymsp[0].minor.yy0);} +{spanExpr(&yygotominor.yy346, pParse, TK_ID, &yymsp[0].minor.yy0);} break; case 188: /* expr ::= nm DOT nm */ { Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0); - yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); - spanSet(&yygotominor.yy190,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0); + spanSet(&yygotominor.yy346,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); } break; case 189: /* expr ::= nm DOT nm DOT nm */ @@ -88839,8 +92509,8 @@ static void yy_reduce( Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0); Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0); Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0); - yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); - spanSet(&yygotominor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0); + spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); } break; case 192: /* expr ::= REGISTER */ @@ -88850,61 +92520,61 @@ static void yy_reduce( ** in the virtual machine. #N is the N-th register. */ if( pParse->nested==0 ){ sqlite3ErrorMsg(pParse, "near \"%T\": syntax error", &yymsp[0].minor.yy0); - yygotominor.yy190.pExpr = 0; + yygotominor.yy346.pExpr = 0; }else{ - yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0); - if( yygotominor.yy190.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy190.pExpr->iTable); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_REGISTER, 0, 0, &yymsp[0].minor.yy0); + if( yygotominor.yy346.pExpr ) sqlite3GetInt32(&yymsp[0].minor.yy0.z[1], &yygotominor.yy346.pExpr->iTable); } - spanSet(&yygotominor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); + spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); } break; case 193: /* expr ::= VARIABLE */ { - spanExpr(&yygotominor.yy190, pParse, TK_VARIABLE, &yymsp[0].minor.yy0); - sqlite3ExprAssignVarNumber(pParse, yygotominor.yy190.pExpr); - spanSet(&yygotominor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); + spanExpr(&yygotominor.yy346, pParse, TK_VARIABLE, &yymsp[0].minor.yy0); + sqlite3ExprAssignVarNumber(pParse, yygotominor.yy346.pExpr); + spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); } break; case 194: /* expr ::= expr COLLATE ids */ { - yygotominor.yy190.pExpr = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy190.pExpr, &yymsp[0].minor.yy0); - yygotominor.yy190.zStart = yymsp[-2].minor.yy190.zStart; - yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy346.pExpr = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy346.pExpr, &yymsp[0].minor.yy0); + yygotominor.yy346.zStart = yymsp[-2].minor.yy346.zStart; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 195: /* expr ::= CAST LP expr AS typetoken RP */ { - yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy190.pExpr, 0, &yymsp[-1].minor.yy0); - spanSet(&yygotominor.yy190,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy346.pExpr, 0, &yymsp[-1].minor.yy0); + spanSet(&yygotominor.yy346,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0); } break; case 196: /* expr ::= ID LP distinct exprlist RP */ { - if( yymsp[-1].minor.yy148 && yymsp[-1].minor.yy148->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ + if( yymsp[-1].minor.yy14 && yymsp[-1].minor.yy14->nExpr>pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] ){ sqlite3ErrorMsg(pParse, "too many arguments on function %T", &yymsp[-4].minor.yy0); } - yygotominor.yy190.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy148, &yymsp[-4].minor.yy0); - spanSet(&yygotominor.yy190,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); - if( yymsp[-2].minor.yy194 && yygotominor.yy190.pExpr ){ - yygotominor.yy190.pExpr->flags |= EP_Distinct; + yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, yymsp[-1].minor.yy14, &yymsp[-4].minor.yy0); + spanSet(&yygotominor.yy346,&yymsp[-4].minor.yy0,&yymsp[0].minor.yy0); + if( yymsp[-2].minor.yy328 && yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->flags |= EP_Distinct; } } break; case 197: /* expr ::= ID LP STAR RP */ { - yygotominor.yy190.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); - spanSet(&yygotominor.yy190,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); + yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0, &yymsp[-3].minor.yy0); + spanSet(&yygotominor.yy346,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0); } break; case 198: /* term ::= CTIME_KW */ { /* The CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP values are ** treated as functions that return constants */ - yygotominor.yy190.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0); - if( yygotominor.yy190.pExpr ){ - yygotominor.yy190.pExpr->op = TK_CONST_FUNC; + yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, 0,&yymsp[0].minor.yy0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->op = TK_CONST_FUNC; } - spanSet(&yygotominor.yy190, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); + spanSet(&yygotominor.yy346, &yymsp[0].minor.yy0, &yymsp[0].minor.yy0); } break; case 199: /* expr ::= expr AND expr */ @@ -88915,182 +92585,192 @@ static void yy_reduce( case 204: /* expr ::= expr PLUS|MINUS expr */ yytestcase(yyruleno==204); case 205: /* expr ::= expr STAR|SLASH|REM expr */ yytestcase(yyruleno==205); case 206: /* expr ::= expr CONCAT expr */ yytestcase(yyruleno==206); -{spanBinaryExpr(&yygotominor.yy190,pParse,yymsp[-1].major,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy190);} +{spanBinaryExpr(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346);} break; case 207: /* likeop ::= LIKE_KW */ case 209: /* likeop ::= MATCH */ yytestcase(yyruleno==209); -{yygotominor.yy392.eOperator = yymsp[0].minor.yy0; yygotominor.yy392.not = 0;} +{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.not = 0;} break; case 208: /* likeop ::= NOT LIKE_KW */ case 210: /* likeop ::= NOT MATCH */ yytestcase(yyruleno==210); -{yygotominor.yy392.eOperator = yymsp[0].minor.yy0; yygotominor.yy392.not = 1;} +{yygotominor.yy96.eOperator = yymsp[0].minor.yy0; yygotominor.yy96.not = 1;} break; case 212: /* escape ::= */ -{memset(&yygotominor.yy190,0,sizeof(yygotominor.yy190));} +{memset(&yygotominor.yy346,0,sizeof(yygotominor.yy346));} break; case 213: /* expr ::= expr likeop expr escape */ { ExprList *pList; - pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy190.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy190.pExpr); - if( yymsp[0].minor.yy190.pExpr ){ - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr); + pList = sqlite3ExprListAppend(pParse,0, yymsp[-1].minor.yy346.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[-3].minor.yy346.pExpr); + if( yymsp[0].minor.yy346.pExpr ){ + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr); } - yygotominor.yy190.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy392.eOperator); - if( yymsp[-2].minor.yy392.not ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0); - yygotominor.yy190.zStart = yymsp[-3].minor.yy190.zStart; - yygotominor.yy190.zEnd = yymsp[-1].minor.yy190.zEnd; - if( yygotominor.yy190.pExpr ) yygotominor.yy190.pExpr->flags |= EP_InfixFunc; + yygotominor.yy346.pExpr = sqlite3ExprFunction(pParse, pList, &yymsp[-2].minor.yy96.eOperator); + if( yymsp[-2].minor.yy96.not ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); + yygotominor.yy346.zStart = yymsp[-3].minor.yy346.zStart; + yygotominor.yy346.zEnd = yymsp[-1].minor.yy346.zEnd; + if( yygotominor.yy346.pExpr ) yygotominor.yy346.pExpr->flags |= EP_InfixFunc; } break; case 214: /* expr ::= expr ISNULL|NOTNULL */ -{spanUnaryPostfix(&yygotominor.yy190,pParse,yymsp[0].major,&yymsp[-1].minor.yy190,&yymsp[0].minor.yy0);} +{spanUnaryPostfix(&yygotominor.yy346,pParse,yymsp[0].major,&yymsp[-1].minor.yy346,&yymsp[0].minor.yy0);} break; - case 215: /* expr ::= expr IS NULL */ -{spanUnaryPostfix(&yygotominor.yy190,pParse,TK_ISNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);} + case 215: /* expr ::= expr NOT NULL */ +{spanUnaryPostfix(&yygotominor.yy346,pParse,TK_NOTNULL,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy0);} break; - case 216: /* expr ::= expr NOT NULL */ -{spanUnaryPostfix(&yygotominor.yy190,pParse,TK_NOTNULL,&yymsp[-2].minor.yy190,&yymsp[0].minor.yy0);} + case 216: /* expr ::= expr IS expr */ +{ + spanBinaryExpr(&yygotominor.yy346,pParse,TK_IS,&yymsp[-2].minor.yy346,&yymsp[0].minor.yy346); + if( pParse->db->mallocFailed==0 && yymsp[0].minor.yy346.pExpr->op==TK_NULL ){ + yygotominor.yy346.pExpr->op = TK_ISNULL; + } +} break; - case 217: /* expr ::= expr IS NOT NULL */ -{spanUnaryPostfix(&yygotominor.yy190,pParse,TK_NOTNULL,&yymsp[-3].minor.yy190,&yymsp[0].minor.yy0);} + case 217: /* expr ::= expr IS NOT expr */ +{ + spanBinaryExpr(&yygotominor.yy346,pParse,TK_ISNOT,&yymsp[-3].minor.yy346,&yymsp[0].minor.yy346); + if( pParse->db->mallocFailed==0 && yymsp[0].minor.yy346.pExpr->op==TK_NULL ){ + yygotominor.yy346.pExpr->op = TK_NOTNULL; + } +} break; case 218: /* expr ::= NOT expr */ case 219: /* expr ::= BITNOT expr */ yytestcase(yyruleno==219); -{spanUnaryPrefix(&yygotominor.yy190,pParse,yymsp[-1].major,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);} +{spanUnaryPrefix(&yygotominor.yy346,pParse,yymsp[-1].major,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);} break; case 220: /* expr ::= MINUS expr */ -{spanUnaryPrefix(&yygotominor.yy190,pParse,TK_UMINUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);} +{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UMINUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);} break; case 221: /* expr ::= PLUS expr */ -{spanUnaryPrefix(&yygotominor.yy190,pParse,TK_UPLUS,&yymsp[0].minor.yy190,&yymsp[-1].minor.yy0);} +{spanUnaryPrefix(&yygotominor.yy346,pParse,TK_UPLUS,&yymsp[0].minor.yy346,&yymsp[-1].minor.yy0);} break; case 224: /* expr ::= expr between_op expr AND expr */ { - ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr); - pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy190.pExpr); - yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy190.pExpr, 0, 0); - if( yygotominor.yy190.pExpr ){ - yygotominor.yy190.pExpr->x.pList = pList; + ExprList *pList = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr); + pList = sqlite3ExprListAppend(pParse,pList, yymsp[0].minor.yy346.pExpr); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_BETWEEN, yymsp[-4].minor.yy346.pExpr, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->x.pList = pList; }else{ sqlite3ExprListDelete(pParse->db, pList); } - if( yymsp[-3].minor.yy194 ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0); - yygotominor.yy190.zStart = yymsp[-4].minor.yy190.zStart; - yygotominor.yy190.zEnd = yymsp[0].minor.yy190.zEnd; + if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); + yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart; + yygotominor.yy346.zEnd = yymsp[0].minor.yy346.zEnd; } break; case 227: /* expr ::= expr in_op LP exprlist RP */ { - yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0); - if( yygotominor.yy190.pExpr ){ - yygotominor.yy190.pExpr->x.pList = yymsp[-1].minor.yy148; - sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->x.pList = yymsp[-1].minor.yy14; + sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy148); + sqlite3ExprListDelete(pParse->db, yymsp[-1].minor.yy14); } - if( yymsp[-3].minor.yy194 ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0); - yygotominor.yy190.zStart = yymsp[-4].minor.yy190.zStart; - yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); + yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 228: /* expr ::= LP select RP */ { - yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); - if( yygotominor.yy190.pExpr ){ - yygotominor.yy190.pExpr->x.pSelect = yymsp[-1].minor.yy243; - ExprSetProperty(yygotominor.yy190.pExpr, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3; + ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); }else{ - sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy243); + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3); } - yygotominor.yy190.zStart = yymsp[-2].minor.yy0.z; - yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy346.zStart = yymsp[-2].minor.yy0.z; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 229: /* expr ::= expr in_op LP select RP */ { - yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy190.pExpr, 0, 0); - if( yygotominor.yy190.pExpr ){ - yygotominor.yy190.pExpr->x.pSelect = yymsp[-1].minor.yy243; - ExprSetProperty(yygotominor.yy190.pExpr, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy346.pExpr, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->x.pSelect = yymsp[-1].minor.yy3; + ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); }else{ - sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy243); + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3); } - if( yymsp[-3].minor.yy194 ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0); - yygotominor.yy190.zStart = yymsp[-4].minor.yy190.zStart; - yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + if( yymsp[-3].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); + yygotominor.yy346.zStart = yymsp[-4].minor.yy346.zStart; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 230: /* expr ::= expr in_op nm dbnm */ { SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0); - yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy190.pExpr, 0, 0); - if( yygotominor.yy190.pExpr ){ - yygotominor.yy190.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); - ExprSetProperty(yygotominor.yy190.pExpr, EP_xIsSelect); - sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy346.pExpr, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->x.pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0); + ExprSetProperty(yygotominor.yy346.pExpr, EP_xIsSelect); + sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); }else{ sqlite3SrcListDelete(pParse->db, pSrc); } - if( yymsp[-2].minor.yy194 ) yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy190.pExpr, 0, 0); - yygotominor.yy190.zStart = yymsp[-3].minor.yy190.zStart; - yygotominor.yy190.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]; + if( yymsp[-2].minor.yy328 ) yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy346.pExpr, 0, 0); + yygotominor.yy346.zStart = yymsp[-3].minor.yy346.zStart; + yygotominor.yy346.zEnd = yymsp[0].minor.yy0.z ? &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] : &yymsp[-1].minor.yy0.z[yymsp[-1].minor.yy0.n]; } break; case 231: /* expr ::= EXISTS LP select RP */ { - Expr *p = yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); + Expr *p = yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_EXISTS, 0, 0, 0); if( p ){ - p->x.pSelect = yymsp[-1].minor.yy243; + p->x.pSelect = yymsp[-1].minor.yy3; ExprSetProperty(p, EP_xIsSelect); sqlite3ExprSetHeight(pParse, p); }else{ - sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy243); + sqlite3SelectDelete(pParse->db, yymsp[-1].minor.yy3); } - yygotominor.yy190.zStart = yymsp[-3].minor.yy0.z; - yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 232: /* expr ::= CASE case_operand case_exprlist case_else END */ { - yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy72, yymsp[-1].minor.yy72, 0); - if( yygotominor.yy190.pExpr ){ - yygotominor.yy190.pExpr->x.pList = yymsp[-2].minor.yy148; - sqlite3ExprSetHeight(pParse, yygotominor.yy190.pExpr); + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy132, yymsp[-1].minor.yy132, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->x.pList = yymsp[-2].minor.yy14; + sqlite3ExprSetHeight(pParse, yygotominor.yy346.pExpr); }else{ - sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy148); + sqlite3ExprListDelete(pParse->db, yymsp[-2].minor.yy14); } - yygotominor.yy190.zStart = yymsp[-4].minor.yy0.z; - yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy346.zStart = yymsp[-4].minor.yy0.z; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; case 233: /* case_exprlist ::= case_exprlist WHEN expr THEN expr */ { - yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, yymsp[-2].minor.yy190.pExpr); - yygotominor.yy148 = sqlite3ExprListAppend(pParse,yygotominor.yy148, yymsp[0].minor.yy190.pExpr); + yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, yymsp[-2].minor.yy346.pExpr); + yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr); } break; case 234: /* case_exprlist ::= WHEN expr THEN expr */ { - yygotominor.yy148 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy190.pExpr); - yygotominor.yy148 = sqlite3ExprListAppend(pParse,yygotominor.yy148, yymsp[0].minor.yy190.pExpr); + yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, yymsp[-2].minor.yy346.pExpr); + yygotominor.yy14 = sqlite3ExprListAppend(pParse,yygotominor.yy14, yymsp[0].minor.yy346.pExpr); } break; case 243: /* cmd ::= createkw uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */ { sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, - sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy148, yymsp[-9].minor.yy194, - &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy194); + sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy14, yymsp[-9].minor.yy328, + &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy328); } break; case 244: /* uniqueflag ::= UNIQUE */ - case 293: /* raisetype ::= ABORT */ yytestcase(yyruleno==293); -{yygotominor.yy194 = OE_Abort;} + case 298: /* raisetype ::= ABORT */ yytestcase(yyruleno==298); +{yygotominor.yy328 = OE_Abort;} break; case 245: /* uniqueflag ::= */ -{yygotominor.yy194 = OE_None;} +{yygotominor.yy328 = OE_None;} break; case 248: /* idxlist ::= idxlist COMMA nm collate sortorder */ { @@ -89099,10 +92779,10 @@ static void yy_reduce( p = sqlite3Expr(pParse->db, TK_COLUMN, 0); sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0); } - yygotominor.yy148 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy148, p); - sqlite3ExprListSetName(pParse,yygotominor.yy148,&yymsp[-2].minor.yy0,1); - sqlite3ExprListCheckLength(pParse, yygotominor.yy148, "index"); - if( yygotominor.yy148 ) yygotominor.yy148->a[yygotominor.yy148->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy194; + yygotominor.yy14 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy14, p); + sqlite3ExprListSetName(pParse,yygotominor.yy14,&yymsp[-2].minor.yy0,1); + sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index"); + if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328; } break; case 249: /* idxlist ::= nm collate sortorder */ @@ -89112,17 +92792,17 @@ static void yy_reduce( p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0); sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0); } - yygotominor.yy148 = sqlite3ExprListAppend(pParse,0, p); - sqlite3ExprListSetName(pParse, yygotominor.yy148, &yymsp[-2].minor.yy0, 1); - sqlite3ExprListCheckLength(pParse, yygotominor.yy148, "index"); - if( yygotominor.yy148 ) yygotominor.yy148->a[yygotominor.yy148->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy194; + yygotominor.yy14 = sqlite3ExprListAppend(pParse,0, p); + sqlite3ExprListSetName(pParse, yygotominor.yy14, &yymsp[-2].minor.yy0, 1); + sqlite3ExprListCheckLength(pParse, yygotominor.yy14, "index"); + if( yygotominor.yy14 ) yygotominor.yy14->a[yygotominor.yy14->nExpr-1].sortOrder = (u8)yymsp[0].minor.yy328; } break; case 250: /* collate ::= */ {yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;} break; case 252: /* cmd ::= DROP INDEX ifexists fullname */ -{sqlite3DropIndex(pParse, yymsp[0].minor.yy185, yymsp[-1].minor.yy194);} +{sqlite3DropIndex(pParse, yymsp[0].minor.yy65, yymsp[-1].minor.yy328);} break; case 253: /* cmd ::= VACUUM */ case 254: /* cmd ::= VACUUM nm */ yytestcase(yyruleno==254); @@ -89148,156 +92828,178 @@ static void yy_reduce( Token all; all.z = yymsp[-3].minor.yy0.z; all.n = (int)(yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n; - sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy145, &all); + sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy473, &all); } break; case 271: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */ { - sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy194, yymsp[-4].minor.yy332.a, yymsp[-4].minor.yy332.b, yymsp[-2].minor.yy185, yymsp[0].minor.yy72, yymsp[-10].minor.yy194, yymsp[-8].minor.yy194); + sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy328, yymsp[-4].minor.yy378.a, yymsp[-4].minor.yy378.b, yymsp[-2].minor.yy65, yymsp[0].minor.yy132, yymsp[-10].minor.yy328, yymsp[-8].minor.yy328); yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0); } break; case 272: /* trigger_time ::= BEFORE */ case 275: /* trigger_time ::= */ yytestcase(yyruleno==275); -{ yygotominor.yy194 = TK_BEFORE; } +{ yygotominor.yy328 = TK_BEFORE; } break; case 273: /* trigger_time ::= AFTER */ -{ yygotominor.yy194 = TK_AFTER; } +{ yygotominor.yy328 = TK_AFTER; } break; case 274: /* trigger_time ::= INSTEAD OF */ -{ yygotominor.yy194 = TK_INSTEAD;} +{ yygotominor.yy328 = TK_INSTEAD;} break; case 276: /* trigger_event ::= DELETE|INSERT */ case 277: /* trigger_event ::= UPDATE */ yytestcase(yyruleno==277); -{yygotominor.yy332.a = yymsp[0].major; yygotominor.yy332.b = 0;} +{yygotominor.yy378.a = yymsp[0].major; yygotominor.yy378.b = 0;} break; case 278: /* trigger_event ::= UPDATE OF inscollist */ -{yygotominor.yy332.a = TK_UPDATE; yygotominor.yy332.b = yymsp[0].minor.yy254;} +{yygotominor.yy378.a = TK_UPDATE; yygotominor.yy378.b = yymsp[0].minor.yy408;} break; case 281: /* when_clause ::= */ - case 298: /* key_opt ::= */ yytestcase(yyruleno==298); -{ yygotominor.yy72 = 0; } + case 303: /* key_opt ::= */ yytestcase(yyruleno==303); +{ yygotominor.yy132 = 0; } break; case 282: /* when_clause ::= WHEN expr */ - case 299: /* key_opt ::= KEY expr */ yytestcase(yyruleno==299); -{ yygotominor.yy72 = yymsp[0].minor.yy190.pExpr; } + case 304: /* key_opt ::= KEY expr */ yytestcase(yyruleno==304); +{ yygotominor.yy132 = yymsp[0].minor.yy346.pExpr; } break; case 283: /* trigger_cmd_list ::= trigger_cmd_list trigger_cmd SEMI */ { - assert( yymsp[-2].minor.yy145!=0 ); - yymsp[-2].minor.yy145->pLast->pNext = yymsp[-1].minor.yy145; - yymsp[-2].minor.yy145->pLast = yymsp[-1].minor.yy145; - yygotominor.yy145 = yymsp[-2].minor.yy145; + assert( yymsp[-2].minor.yy473!=0 ); + yymsp[-2].minor.yy473->pLast->pNext = yymsp[-1].minor.yy473; + yymsp[-2].minor.yy473->pLast = yymsp[-1].minor.yy473; + yygotominor.yy473 = yymsp[-2].minor.yy473; } break; case 284: /* trigger_cmd_list ::= trigger_cmd SEMI */ { - assert( yymsp[-1].minor.yy145!=0 ); - yymsp[-1].minor.yy145->pLast = yymsp[-1].minor.yy145; - yygotominor.yy145 = yymsp[-1].minor.yy145; + assert( yymsp[-1].minor.yy473!=0 ); + yymsp[-1].minor.yy473->pLast = yymsp[-1].minor.yy473; + yygotominor.yy473 = yymsp[-1].minor.yy473; } break; - case 285: /* trigger_cmd ::= UPDATE orconf nm SET setlist where_opt */ -{ yygotominor.yy145 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy148, yymsp[0].minor.yy72, yymsp[-4].minor.yy194); } + case 286: /* trnm ::= nm DOT nm */ +{ + yygotominor.yy0 = yymsp[0].minor.yy0; + sqlite3ErrorMsg(pParse, + "qualified table names are not allowed on INSERT, UPDATE, and DELETE " + "statements within triggers"); +} + break; + case 288: /* tridxby ::= INDEXED BY nm */ +{ + sqlite3ErrorMsg(pParse, + "the INDEXED BY clause is not allowed on UPDATE or DELETE statements " + "within triggers"); +} + break; + case 289: /* tridxby ::= NOT INDEXED */ +{ + sqlite3ErrorMsg(pParse, + "the NOT INDEXED clause is not allowed on UPDATE or DELETE statements " + "within triggers"); +} + break; + case 290: /* trigger_cmd ::= UPDATE orconf trnm tridxby SET setlist where_opt */ +{ yygotominor.yy473 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-4].minor.yy0, yymsp[-1].minor.yy14, yymsp[0].minor.yy132, yymsp[-5].minor.yy186); } break; - case 286: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP */ -{yygotominor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy254, yymsp[-1].minor.yy148, 0, yymsp[-7].minor.yy194);} + case 291: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt VALUES LP itemlist RP */ +{yygotominor.yy473 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy408, yymsp[-1].minor.yy14, 0, yymsp[-7].minor.yy186);} break; - case 287: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt select */ -{yygotominor.yy145 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy254, 0, yymsp[0].minor.yy243, yymsp[-4].minor.yy194);} + case 292: /* trigger_cmd ::= insert_cmd INTO trnm inscollist_opt select */ +{yygotominor.yy473 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy408, 0, yymsp[0].minor.yy3, yymsp[-4].minor.yy186);} break; - case 288: /* trigger_cmd ::= DELETE FROM nm where_opt */ -{yygotominor.yy145 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-1].minor.yy0, yymsp[0].minor.yy72);} + case 293: /* trigger_cmd ::= DELETE FROM trnm tridxby where_opt */ +{yygotominor.yy473 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[0].minor.yy132);} break; - case 289: /* trigger_cmd ::= select */ -{yygotominor.yy145 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy243); } + case 294: /* trigger_cmd ::= select */ +{yygotominor.yy473 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy3); } break; - case 290: /* expr ::= RAISE LP IGNORE RP */ + case 295: /* expr ::= RAISE LP IGNORE RP */ { - yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); - if( yygotominor.yy190.pExpr ){ - yygotominor.yy190.pExpr->affinity = OE_Ignore; + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, 0); + if( yygotominor.yy346.pExpr ){ + yygotominor.yy346.pExpr->affinity = OE_Ignore; } - yygotominor.yy190.zStart = yymsp[-3].minor.yy0.z; - yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy346.zStart = yymsp[-3].minor.yy0.z; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; - case 291: /* expr ::= RAISE LP raisetype COMMA nm RP */ + case 296: /* expr ::= RAISE LP raisetype COMMA nm RP */ { - yygotominor.yy190.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); - if( yygotominor.yy190.pExpr ) { - yygotominor.yy190.pExpr->affinity = (char)yymsp[-3].minor.yy194; + yygotominor.yy346.pExpr = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); + if( yygotominor.yy346.pExpr ) { + yygotominor.yy346.pExpr->affinity = (char)yymsp[-3].minor.yy328; } - yygotominor.yy190.zStart = yymsp[-5].minor.yy0.z; - yygotominor.yy190.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; + yygotominor.yy346.zStart = yymsp[-5].minor.yy0.z; + yygotominor.yy346.zEnd = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n]; } break; - case 292: /* raisetype ::= ROLLBACK */ -{yygotominor.yy194 = OE_Rollback;} + case 297: /* raisetype ::= ROLLBACK */ +{yygotominor.yy328 = OE_Rollback;} break; - case 294: /* raisetype ::= FAIL */ -{yygotominor.yy194 = OE_Fail;} + case 299: /* raisetype ::= FAIL */ +{yygotominor.yy328 = OE_Fail;} break; - case 295: /* cmd ::= DROP TRIGGER ifexists fullname */ + case 300: /* cmd ::= DROP TRIGGER ifexists fullname */ { - sqlite3DropTrigger(pParse,yymsp[0].minor.yy185,yymsp[-1].minor.yy194); + sqlite3DropTrigger(pParse,yymsp[0].minor.yy65,yymsp[-1].minor.yy328); } break; - case 296: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ + case 301: /* cmd ::= ATTACH database_kw_opt expr AS expr key_opt */ { - sqlite3Attach(pParse, yymsp[-3].minor.yy190.pExpr, yymsp[-1].minor.yy190.pExpr, yymsp[0].minor.yy72); + sqlite3Attach(pParse, yymsp[-3].minor.yy346.pExpr, yymsp[-1].minor.yy346.pExpr, yymsp[0].minor.yy132); } break; - case 297: /* cmd ::= DETACH database_kw_opt expr */ + case 302: /* cmd ::= DETACH database_kw_opt expr */ { - sqlite3Detach(pParse, yymsp[0].minor.yy190.pExpr); + sqlite3Detach(pParse, yymsp[0].minor.yy346.pExpr); } break; - case 302: /* cmd ::= REINDEX */ + case 307: /* cmd ::= REINDEX */ {sqlite3Reindex(pParse, 0, 0);} break; - case 303: /* cmd ::= REINDEX nm dbnm */ + case 308: /* cmd ::= REINDEX nm dbnm */ {sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 304: /* cmd ::= ANALYZE */ + case 309: /* cmd ::= ANALYZE */ {sqlite3Analyze(pParse, 0, 0);} break; - case 305: /* cmd ::= ANALYZE nm dbnm */ + case 310: /* cmd ::= ANALYZE nm dbnm */ {sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);} break; - case 306: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ + case 311: /* cmd ::= ALTER TABLE fullname RENAME TO nm */ { - sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy185,&yymsp[0].minor.yy0); + sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy65,&yymsp[0].minor.yy0); } break; - case 307: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */ + case 312: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */ { sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0); } break; - case 308: /* add_column_fullname ::= fullname */ + case 313: /* add_column_fullname ::= fullname */ { pParse->db->lookaside.bEnabled = 0; - sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy185); + sqlite3AlterBeginAddColumn(pParse, yymsp[0].minor.yy65); } break; - case 311: /* cmd ::= create_vtab */ + case 316: /* cmd ::= create_vtab */ {sqlite3VtabFinishParse(pParse,0);} break; - case 312: /* cmd ::= create_vtab LP vtabarglist RP */ + case 317: /* cmd ::= create_vtab LP vtabarglist RP */ {sqlite3VtabFinishParse(pParse,&yymsp[0].minor.yy0);} break; - case 313: /* create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm */ + case 318: /* create_vtab ::= createkw VIRTUAL TABLE nm dbnm USING nm */ { sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0); } break; - case 316: /* vtabarg ::= */ + case 321: /* vtabarg ::= */ {sqlite3VtabArgInit(pParse);} break; - case 318: /* vtabargtoken ::= ANY */ - case 319: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==319); - case 320: /* lp ::= LP */ yytestcase(yyruleno==320); + case 323: /* vtabargtoken ::= ANY */ + case 324: /* vtabargtoken ::= lp anylist RP */ yytestcase(yyruleno==324); + case 325: /* lp ::= LP */ yytestcase(yyruleno==325); {sqlite3VtabArgExtend(pParse,&yymsp[0].minor.yy0);} break; default: @@ -89330,16 +93032,17 @@ static void yy_reduce( /* (269) plus_opt ::= */ yytestcase(yyruleno==269); /* (279) foreach_clause ::= */ yytestcase(yyruleno==279); /* (280) foreach_clause ::= FOR EACH ROW */ yytestcase(yyruleno==280); - /* (300) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==300); - /* (301) database_kw_opt ::= */ yytestcase(yyruleno==301); - /* (309) kwcolumn_opt ::= */ yytestcase(yyruleno==309); - /* (310) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==310); - /* (314) vtabarglist ::= vtabarg */ yytestcase(yyruleno==314); - /* (315) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==315); - /* (317) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==317); - /* (321) anylist ::= */ yytestcase(yyruleno==321); - /* (322) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==322); - /* (323) anylist ::= anylist ANY */ yytestcase(yyruleno==323); + /* (287) tridxby ::= */ yytestcase(yyruleno==287); + /* (305) database_kw_opt ::= DATABASE */ yytestcase(yyruleno==305); + /* (306) database_kw_opt ::= */ yytestcase(yyruleno==306); + /* (314) kwcolumn_opt ::= */ yytestcase(yyruleno==314); + /* (315) kwcolumn_opt ::= COLUMNKW */ yytestcase(yyruleno==315); + /* (319) vtabarglist ::= vtabarg */ yytestcase(yyruleno==319); + /* (320) vtabarglist ::= vtabarglist COMMA vtabarg */ yytestcase(yyruleno==320); + /* (322) vtabarg ::= vtabarg vtabargtoken */ yytestcase(yyruleno==322); + /* (326) anylist ::= */ yytestcase(yyruleno==326); + /* (327) anylist ::= anylist LP anylist RP */ yytestcase(yyruleno==327); + /* (328) anylist ::= anylist ANY */ yytestcase(yyruleno==328); break; }; yygoto = yyRuleInfo[yyruleno].lhs; @@ -89614,7 +93317,7 @@ SQLITE_PRIVATE void sqlite3Parser( ** individual tokens and sends those tokens one-by-one over to the ** parser for analysis. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* @@ -89667,7 +93370,7 @@ const unsigned char ebcdicToAscii[] = { ** ** The code in this file has been automatically generated by ** -** $Header: /repository/php-src/ext/sqlite3/libsqlite/sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Header: /home/drh/sqlite/trans/cvs/sqlite/sqlite/tool/mkkeywordhash.c,v 1.38 2009/06/09 14:27:41 drh Exp $ ** ** The code in this file implements a function that determines whether ** or not a given identifier is really an SQL keyword. The same thing @@ -89676,9 +93379,9 @@ const unsigned char ebcdicToAscii[] = { ** is substantially reduced. This is important for embedded applications ** on platforms with limited memory. */ -/* Hash score: 171 */ +/* Hash score: 175 */ static int keywordCode(const char *z, int n){ - /* zText[] encodes 801 bytes of keywords in 541 bytes */ + /* zText[] encodes 811 bytes of keywords in 541 bytes */ /* REINDEXEDESCAPEACHECKEYBEFOREIGNOREGEXPLAINSTEADDATABASELECT */ /* ABLEFTHENDEFERRABLELSEXCEPTRANSACTIONATURALTERAISEXCLUSIVE */ /* XISTSAVEPOINTERSECTRIGGEREFERENCESCONSTRAINTOFFSETEMPORARY */ @@ -89722,78 +93425,79 @@ static int keywordCode(const char *z, int n){ 'A','C','U','U','M','V','I','E','W','I','N','I','T','I','A','L','L','Y', }; static const unsigned char aHash[127] = { - 70, 99, 112, 68, 0, 43, 0, 0, 76, 0, 71, 0, 0, - 41, 12, 72, 15, 0, 111, 79, 49, 106, 0, 19, 0, 0, - 116, 0, 114, 109, 0, 22, 87, 0, 9, 0, 0, 64, 65, - 0, 63, 6, 0, 47, 84, 96, 0, 113, 95, 0, 0, 44, - 0, 97, 24, 0, 17, 0, 117, 48, 23, 0, 5, 104, 25, - 90, 0, 0, 119, 100, 55, 118, 52, 7, 50, 0, 85, 0, - 94, 26, 0, 93, 0, 0, 0, 89, 86, 91, 82, 103, 14, - 38, 102, 0, 75, 0, 18, 83, 105, 31, 0, 115, 74, 107, - 57, 45, 78, 0, 0, 88, 39, 0, 110, 0, 35, 0, 0, - 28, 0, 80, 53, 58, 0, 20, 56, 0, 51, + 72, 101, 114, 70, 0, 44, 0, 0, 78, 0, 73, 0, 0, + 42, 12, 74, 15, 0, 113, 81, 50, 108, 0, 19, 0, 0, + 118, 0, 116, 111, 0, 22, 89, 0, 9, 0, 0, 66, 67, + 0, 65, 6, 0, 48, 86, 98, 0, 115, 97, 0, 0, 45, + 0, 99, 24, 0, 17, 0, 119, 49, 23, 0, 5, 106, 25, + 92, 0, 0, 121, 102, 56, 120, 53, 28, 51, 0, 87, 0, + 96, 26, 0, 95, 0, 0, 0, 91, 88, 93, 84, 105, 14, + 39, 104, 0, 77, 0, 18, 85, 107, 32, 0, 117, 76, 109, + 59, 46, 80, 0, 0, 90, 40, 0, 112, 0, 36, 0, 0, + 29, 0, 82, 58, 60, 0, 20, 57, 0, 52, }; - static const unsigned char aNext[119] = { + static const unsigned char aNext[121] = { 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 13, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 32, 21, 0, 0, 0, 42, 3, 46, 0, - 0, 0, 0, 29, 0, 0, 37, 0, 0, 0, 1, 60, 0, - 0, 61, 0, 40, 0, 0, 0, 0, 0, 0, 0, 59, 0, - 0, 0, 0, 30, 54, 16, 33, 10, 0, 0, 0, 0, 0, - 0, 0, 11, 66, 73, 0, 8, 0, 98, 92, 0, 101, 0, - 81, 0, 69, 0, 0, 108, 27, 36, 67, 77, 0, 34, 62, - 0, 0, + 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 33, 21, 0, 0, 0, 43, 3, 47, + 0, 0, 0, 0, 30, 54, 0, 0, 38, 0, 0, 0, 1, + 62, 0, 0, 63, 0, 41, 0, 0, 0, 0, 0, 0, 0, + 61, 0, 0, 0, 0, 31, 55, 16, 34, 10, 0, 0, 0, + 0, 0, 0, 0, 11, 68, 75, 0, 8, 0, 100, 94, 0, + 103, 0, 83, 0, 71, 0, 0, 110, 27, 37, 69, 79, 0, + 35, 64, 0, 0, }; - static const unsigned char aLen[119] = { + static const unsigned char aLen[121] = { 7, 7, 5, 4, 6, 4, 5, 3, 6, 7, 3, 6, 6, 7, 7, 3, 8, 2, 6, 5, 4, 4, 3, 10, 4, 6, - 11, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10, 4, - 6, 2, 3, 4, 9, 2, 6, 5, 6, 6, 5, 6, 5, - 5, 7, 7, 7, 3, 4, 4, 7, 3, 6, 4, 7, 6, - 12, 6, 9, 4, 6, 5, 4, 7, 6, 5, 6, 7, 5, - 4, 5, 6, 5, 7, 3, 7, 13, 2, 2, 4, 6, 6, - 8, 5, 17, 12, 7, 8, 8, 2, 4, 4, 4, 4, 4, - 2, 2, 6, 5, 8, 5, 5, 8, 3, 5, 5, 6, 4, - 9, 3, + 11, 6, 2, 7, 5, 5, 9, 6, 9, 9, 7, 10, 10, + 4, 6, 2, 3, 4, 9, 2, 6, 5, 6, 6, 5, 6, + 5, 5, 7, 7, 7, 2, 3, 4, 4, 7, 3, 6, 4, + 7, 6, 12, 6, 9, 4, 6, 5, 4, 7, 6, 5, 6, + 7, 5, 4, 5, 6, 5, 7, 3, 7, 13, 2, 2, 4, + 6, 6, 8, 5, 17, 12, 7, 8, 8, 2, 4, 4, 4, + 4, 4, 2, 2, 6, 5, 8, 5, 5, 8, 3, 5, 5, + 6, 4, 9, 3, }; - static const unsigned short int aOffset[119] = { + static const unsigned short int aOffset[121] = { 0, 2, 2, 8, 9, 14, 16, 20, 23, 25, 25, 29, 33, 36, 41, 46, 48, 53, 54, 59, 62, 65, 67, 69, 78, 81, - 86, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152, 159, - 162, 162, 165, 167, 167, 171, 176, 179, 184, 189, 194, 197, 203, - 206, 210, 217, 223, 223, 226, 229, 233, 234, 238, 244, 248, 255, - 261, 273, 279, 288, 290, 296, 301, 303, 310, 315, 320, 326, 332, - 337, 341, 344, 350, 354, 361, 363, 370, 372, 374, 383, 387, 393, - 399, 407, 412, 412, 428, 435, 442, 443, 450, 454, 458, 462, 466, - 469, 471, 473, 479, 483, 491, 495, 500, 508, 511, 516, 521, 527, - 531, 536, + 86, 91, 95, 96, 101, 105, 109, 117, 122, 128, 136, 142, 152, + 159, 162, 162, 165, 167, 167, 171, 176, 179, 184, 189, 194, 197, + 203, 206, 210, 217, 223, 223, 223, 226, 229, 233, 234, 238, 244, + 248, 255, 261, 273, 279, 288, 290, 296, 301, 303, 310, 315, 320, + 326, 332, 337, 341, 344, 350, 354, 361, 363, 370, 372, 374, 383, + 387, 393, 399, 407, 412, 412, 428, 435, 442, 443, 450, 454, 458, + 462, 466, 469, 471, 473, 479, 483, 491, 495, 500, 508, 511, 516, + 521, 527, 531, 536, }; - static const unsigned char aCode[119] = { + static const unsigned char aCode[121] = { TK_REINDEX, TK_INDEXED, TK_INDEX, TK_DESC, TK_ESCAPE, TK_EACH, TK_CHECK, TK_KEY, TK_BEFORE, TK_FOREIGN, TK_FOR, TK_IGNORE, TK_LIKE_KW, TK_EXPLAIN, TK_INSTEAD, TK_ADD, TK_DATABASE, TK_AS, TK_SELECT, TK_TABLE, TK_JOIN_KW, TK_THEN, TK_END, TK_DEFERRABLE, TK_ELSE, - TK_EXCEPT, TK_TRANSACTION,TK_ON, TK_JOIN_KW, TK_ALTER, - TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT, TK_INTERSECT, - TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO, TK_OFFSET, - TK_OF, TK_SET, TK_TEMP, TK_TEMP, TK_OR, - TK_UNIQUE, TK_QUERY, TK_ATTACH, TK_HAVING, TK_GROUP, - TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RELEASE, TK_BETWEEN, - TK_NOTNULL, TK_NOT, TK_NULL, TK_LIKE_KW, TK_CASCADE, - TK_ASC, TK_DELETE, TK_CASE, TK_COLLATE, TK_CREATE, - TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, TK_JOIN, TK_INSERT, - TK_MATCH, TK_PLAN, TK_ANALYZE, TK_PRAGMA, TK_ABORT, - TK_VALUES, TK_VIRTUAL, TK_LIMIT, TK_WHEN, TK_WHERE, - TK_RENAME, TK_AFTER, TK_REPLACE, TK_AND, TK_DEFAULT, - TK_AUTOINCR, TK_TO, TK_IN, TK_CAST, TK_COLUMNKW, - TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, TK_CTIME_KW, TK_CTIME_KW, - TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, TK_IS, TK_DROP, - TK_FAIL, TK_FROM, TK_JOIN_KW, TK_LIKE_KW, TK_BY, - TK_IF, TK_ISNULL, TK_ORDER, TK_RESTRICT, TK_JOIN_KW, - TK_JOIN_KW, TK_ROLLBACK, TK_ROW, TK_UNION, TK_USING, - TK_VACUUM, TK_VIEW, TK_INITIALLY, TK_ALL, + TK_EXCEPT, TK_TRANSACTION,TK_ACTION, TK_ON, TK_JOIN_KW, + TK_ALTER, TK_RAISE, TK_EXCLUSIVE, TK_EXISTS, TK_SAVEPOINT, + TK_INTERSECT, TK_TRIGGER, TK_REFERENCES, TK_CONSTRAINT, TK_INTO, + TK_OFFSET, TK_OF, TK_SET, TK_TEMP, TK_TEMP, + TK_OR, TK_UNIQUE, TK_QUERY, TK_ATTACH, TK_HAVING, + TK_GROUP, TK_UPDATE, TK_BEGIN, TK_JOIN_KW, TK_RELEASE, + TK_BETWEEN, TK_NOTNULL, TK_NO, TK_NOT, TK_NULL, + TK_LIKE_KW, TK_CASCADE, TK_ASC, TK_DELETE, TK_CASE, + TK_COLLATE, TK_CREATE, TK_CTIME_KW, TK_DETACH, TK_IMMEDIATE, + TK_JOIN, TK_INSERT, TK_MATCH, TK_PLAN, TK_ANALYZE, + TK_PRAGMA, TK_ABORT, TK_VALUES, TK_VIRTUAL, TK_LIMIT, + TK_WHEN, TK_WHERE, TK_RENAME, TK_AFTER, TK_REPLACE, + TK_AND, TK_DEFAULT, TK_AUTOINCR, TK_TO, TK_IN, + TK_CAST, TK_COLUMNKW, TK_COMMIT, TK_CONFLICT, TK_JOIN_KW, + TK_CTIME_KW, TK_CTIME_KW, TK_PRIMARY, TK_DEFERRED, TK_DISTINCT, + TK_IS, TK_DROP, TK_FAIL, TK_FROM, TK_JOIN_KW, + TK_LIKE_KW, TK_BY, TK_IF, TK_ISNULL, TK_ORDER, + TK_RESTRICT, TK_JOIN_KW, TK_JOIN_KW, TK_ROLLBACK, TK_ROW, + TK_UNION, TK_USING, TK_VACUUM, TK_VIEW, TK_INITIALLY, + TK_ALL, }; int h, i; if( n<2 ) return TK_ID; @@ -89829,98 +93533,100 @@ static int keywordCode(const char *z, int n){ testcase( i==24 ); /* ELSE */ testcase( i==25 ); /* EXCEPT */ testcase( i==26 ); /* TRANSACTION */ - testcase( i==27 ); /* ON */ - testcase( i==28 ); /* NATURAL */ - testcase( i==29 ); /* ALTER */ - testcase( i==30 ); /* RAISE */ - testcase( i==31 ); /* EXCLUSIVE */ - testcase( i==32 ); /* EXISTS */ - testcase( i==33 ); /* SAVEPOINT */ - testcase( i==34 ); /* INTERSECT */ - testcase( i==35 ); /* TRIGGER */ - testcase( i==36 ); /* REFERENCES */ - testcase( i==37 ); /* CONSTRAINT */ - testcase( i==38 ); /* INTO */ - testcase( i==39 ); /* OFFSET */ - testcase( i==40 ); /* OF */ - testcase( i==41 ); /* SET */ - testcase( i==42 ); /* TEMP */ - testcase( i==43 ); /* TEMPORARY */ - testcase( i==44 ); /* OR */ - testcase( i==45 ); /* UNIQUE */ - testcase( i==46 ); /* QUERY */ - testcase( i==47 ); /* ATTACH */ - testcase( i==48 ); /* HAVING */ - testcase( i==49 ); /* GROUP */ - testcase( i==50 ); /* UPDATE */ - testcase( i==51 ); /* BEGIN */ - testcase( i==52 ); /* INNER */ - testcase( i==53 ); /* RELEASE */ - testcase( i==54 ); /* BETWEEN */ - testcase( i==55 ); /* NOTNULL */ - testcase( i==56 ); /* NOT */ - testcase( i==57 ); /* NULL */ - testcase( i==58 ); /* LIKE */ - testcase( i==59 ); /* CASCADE */ - testcase( i==60 ); /* ASC */ - testcase( i==61 ); /* DELETE */ - testcase( i==62 ); /* CASE */ - testcase( i==63 ); /* COLLATE */ - testcase( i==64 ); /* CREATE */ - testcase( i==65 ); /* CURRENT_DATE */ - testcase( i==66 ); /* DETACH */ - testcase( i==67 ); /* IMMEDIATE */ - testcase( i==68 ); /* JOIN */ - testcase( i==69 ); /* INSERT */ - testcase( i==70 ); /* MATCH */ - testcase( i==71 ); /* PLAN */ - testcase( i==72 ); /* ANALYZE */ - testcase( i==73 ); /* PRAGMA */ - testcase( i==74 ); /* ABORT */ - testcase( i==75 ); /* VALUES */ - testcase( i==76 ); /* VIRTUAL */ - testcase( i==77 ); /* LIMIT */ - testcase( i==78 ); /* WHEN */ - testcase( i==79 ); /* WHERE */ - testcase( i==80 ); /* RENAME */ - testcase( i==81 ); /* AFTER */ - testcase( i==82 ); /* REPLACE */ - testcase( i==83 ); /* AND */ - testcase( i==84 ); /* DEFAULT */ - testcase( i==85 ); /* AUTOINCREMENT */ - testcase( i==86 ); /* TO */ - testcase( i==87 ); /* IN */ - testcase( i==88 ); /* CAST */ - testcase( i==89 ); /* COLUMN */ - testcase( i==90 ); /* COMMIT */ - testcase( i==91 ); /* CONFLICT */ - testcase( i==92 ); /* CROSS */ - testcase( i==93 ); /* CURRENT_TIMESTAMP */ - testcase( i==94 ); /* CURRENT_TIME */ - testcase( i==95 ); /* PRIMARY */ - testcase( i==96 ); /* DEFERRED */ - testcase( i==97 ); /* DISTINCT */ - testcase( i==98 ); /* IS */ - testcase( i==99 ); /* DROP */ - testcase( i==100 ); /* FAIL */ - testcase( i==101 ); /* FROM */ - testcase( i==102 ); /* FULL */ - testcase( i==103 ); /* GLOB */ - testcase( i==104 ); /* BY */ - testcase( i==105 ); /* IF */ - testcase( i==106 ); /* ISNULL */ - testcase( i==107 ); /* ORDER */ - testcase( i==108 ); /* RESTRICT */ - testcase( i==109 ); /* OUTER */ - testcase( i==110 ); /* RIGHT */ - testcase( i==111 ); /* ROLLBACK */ - testcase( i==112 ); /* ROW */ - testcase( i==113 ); /* UNION */ - testcase( i==114 ); /* USING */ - testcase( i==115 ); /* VACUUM */ - testcase( i==116 ); /* VIEW */ - testcase( i==117 ); /* INITIALLY */ - testcase( i==118 ); /* ALL */ + testcase( i==27 ); /* ACTION */ + testcase( i==28 ); /* ON */ + testcase( i==29 ); /* NATURAL */ + testcase( i==30 ); /* ALTER */ + testcase( i==31 ); /* RAISE */ + testcase( i==32 ); /* EXCLUSIVE */ + testcase( i==33 ); /* EXISTS */ + testcase( i==34 ); /* SAVEPOINT */ + testcase( i==35 ); /* INTERSECT */ + testcase( i==36 ); /* TRIGGER */ + testcase( i==37 ); /* REFERENCES */ + testcase( i==38 ); /* CONSTRAINT */ + testcase( i==39 ); /* INTO */ + testcase( i==40 ); /* OFFSET */ + testcase( i==41 ); /* OF */ + testcase( i==42 ); /* SET */ + testcase( i==43 ); /* TEMP */ + testcase( i==44 ); /* TEMPORARY */ + testcase( i==45 ); /* OR */ + testcase( i==46 ); /* UNIQUE */ + testcase( i==47 ); /* QUERY */ + testcase( i==48 ); /* ATTACH */ + testcase( i==49 ); /* HAVING */ + testcase( i==50 ); /* GROUP */ + testcase( i==51 ); /* UPDATE */ + testcase( i==52 ); /* BEGIN */ + testcase( i==53 ); /* INNER */ + testcase( i==54 ); /* RELEASE */ + testcase( i==55 ); /* BETWEEN */ + testcase( i==56 ); /* NOTNULL */ + testcase( i==57 ); /* NO */ + testcase( i==58 ); /* NOT */ + testcase( i==59 ); /* NULL */ + testcase( i==60 ); /* LIKE */ + testcase( i==61 ); /* CASCADE */ + testcase( i==62 ); /* ASC */ + testcase( i==63 ); /* DELETE */ + testcase( i==64 ); /* CASE */ + testcase( i==65 ); /* COLLATE */ + testcase( i==66 ); /* CREATE */ + testcase( i==67 ); /* CURRENT_DATE */ + testcase( i==68 ); /* DETACH */ + testcase( i==69 ); /* IMMEDIATE */ + testcase( i==70 ); /* JOIN */ + testcase( i==71 ); /* INSERT */ + testcase( i==72 ); /* MATCH */ + testcase( i==73 ); /* PLAN */ + testcase( i==74 ); /* ANALYZE */ + testcase( i==75 ); /* PRAGMA */ + testcase( i==76 ); /* ABORT */ + testcase( i==77 ); /* VALUES */ + testcase( i==78 ); /* VIRTUAL */ + testcase( i==79 ); /* LIMIT */ + testcase( i==80 ); /* WHEN */ + testcase( i==81 ); /* WHERE */ + testcase( i==82 ); /* RENAME */ + testcase( i==83 ); /* AFTER */ + testcase( i==84 ); /* REPLACE */ + testcase( i==85 ); /* AND */ + testcase( i==86 ); /* DEFAULT */ + testcase( i==87 ); /* AUTOINCREMENT */ + testcase( i==88 ); /* TO */ + testcase( i==89 ); /* IN */ + testcase( i==90 ); /* CAST */ + testcase( i==91 ); /* COLUMN */ + testcase( i==92 ); /* COMMIT */ + testcase( i==93 ); /* CONFLICT */ + testcase( i==94 ); /* CROSS */ + testcase( i==95 ); /* CURRENT_TIMESTAMP */ + testcase( i==96 ); /* CURRENT_TIME */ + testcase( i==97 ); /* PRIMARY */ + testcase( i==98 ); /* DEFERRED */ + testcase( i==99 ); /* DISTINCT */ + testcase( i==100 ); /* IS */ + testcase( i==101 ); /* DROP */ + testcase( i==102 ); /* FAIL */ + testcase( i==103 ); /* FROM */ + testcase( i==104 ); /* FULL */ + testcase( i==105 ); /* GLOB */ + testcase( i==106 ); /* BY */ + testcase( i==107 ); /* IF */ + testcase( i==108 ); /* ISNULL */ + testcase( i==109 ); /* ORDER */ + testcase( i==110 ); /* RESTRICT */ + testcase( i==111 ); /* OUTER */ + testcase( i==112 ); /* RIGHT */ + testcase( i==113 ); /* ROLLBACK */ + testcase( i==114 ); /* ROW */ + testcase( i==115 ); /* UNION */ + testcase( i==116 ); /* USING */ + testcase( i==117 ); /* VACUUM */ + testcase( i==118 ); /* VIEW */ + testcase( i==119 ); /* INITIALLY */ + testcase( i==120 ); /* ALL */ return aCode[i]; } } @@ -90277,7 +93983,7 @@ SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzEr db->u1.isInterrupted = 0; } pParse->rc = SQLITE_OK; - pParse->zTail = pParse->zSql = zSql; + pParse->zTail = zSql; i = 0; assert( pzErrMsg!=0 ); pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc); @@ -90385,12 +94091,17 @@ abort_parse: sqlite3DeleteTrigger(db, pParse->pNewTrigger); sqlite3DbFree(db, pParse->apVarExpr); sqlite3DbFree(db, pParse->aAlias); + while( pParse->pAinc ){ + AutoincInfo *p = pParse->pAinc; + pParse->pAinc = p->pNext; + sqlite3DbFree(db, p); + } while( pParse->pZombieTab ){ Table *p = pParse->pZombieTab; pParse->pZombieTab = p->pNextZombie; sqlite3DeleteTable(p); } - if( nErr>0 && (pParse->rc==SQLITE_OK || pParse->rc==SQLITE_DONE) ){ + if( nErr>0 && pParse->rc==SQLITE_OK ){ pParse->rc = SQLITE_ERROR; } return nErr; @@ -90416,7 +94127,7 @@ abort_parse: ** separating it out, the code will be automatically omitted from ** static links that do not use it. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #ifndef SQLITE_OMIT_COMPLETE @@ -90692,8 +94403,6 @@ SQLITE_API int sqlite3_complete16(const void *zSql){ ** implement the programmer interface to the library. Routines in ** other files are for internal use by SQLite and should not be ** accessed by users of the library. -** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ */ #ifdef SQLITE_ENABLE_FTS3 @@ -90801,6 +94510,7 @@ SQLITE_PRIVATE int sqlite3IcuInit(sqlite3 *db); SQLITE_API const char sqlite3_version[] = SQLITE_VERSION; #endif SQLITE_API const char *sqlite3_libversion(void){ return sqlite3_version; } +SQLITE_API const char *sqlite3_sourceid(void){ return SQLITE_SOURCE_ID; } SQLITE_API int sqlite3_libversion_number(void){ return SQLITE_VERSION_NUMBER; } SQLITE_API int sqlite3_threadsafe(void){ return SQLITE_THREADSAFE; } @@ -90891,13 +94601,15 @@ SQLITE_API int sqlite3_initialize(void){ */ pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER); sqlite3_mutex_enter(pMaster); + sqlite3GlobalConfig.isMutexInit = 1; if( !sqlite3GlobalConfig.isMallocInit ){ rc = sqlite3MallocInit(); } if( rc==SQLITE_OK ){ sqlite3GlobalConfig.isMallocInit = 1; if( !sqlite3GlobalConfig.pInitMutex ){ - sqlite3GlobalConfig.pInitMutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); + sqlite3GlobalConfig.pInitMutex = + sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE); if( sqlite3GlobalConfig.bCoreMutex && !sqlite3GlobalConfig.pInitMutex ){ rc = SQLITE_NOMEM; } @@ -90908,10 +94620,9 @@ SQLITE_API int sqlite3_initialize(void){ } sqlite3_mutex_leave(pMaster); - /* If unable to initialize the malloc subsystem, then return early. - ** There is little hope of getting SQLite to run if the malloc - ** subsystem cannot be initialized. - */ + /* If rc is not SQLITE_OK at this point, then either the malloc + ** subsystem could not be initialized or the system failed to allocate + ** the pInitMutex mutex. Return an error in either case. */ if( rc!=SQLITE_OK ){ return rc; } @@ -90928,9 +94639,12 @@ SQLITE_API int sqlite3_initialize(void){ sqlite3GlobalConfig.inProgress = 1; memset(pHash, 0, sizeof(sqlite3GlobalFunctions)); sqlite3RegisterGlobalFunctions(); - rc = sqlite3PcacheInitialize(); + if( sqlite3GlobalConfig.isPCacheInit==0 ){ + rc = sqlite3PcacheInitialize(); + } if( rc==SQLITE_OK ){ - rc = sqlite3_os_init(); + sqlite3GlobalConfig.isPCacheInit = 1; + rc = sqlite3OsInit(); } if( rc==SQLITE_OK ){ sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, @@ -90985,14 +94699,23 @@ SQLITE_API int sqlite3_initialize(void){ */ SQLITE_API int sqlite3_shutdown(void){ if( sqlite3GlobalConfig.isInit ){ - sqlite3GlobalConfig.isMallocInit = 0; - sqlite3PcacheShutdown(); sqlite3_os_end(); sqlite3_reset_auto_extension(); + sqlite3GlobalConfig.isInit = 0; + } + if( sqlite3GlobalConfig.isPCacheInit ){ + sqlite3PcacheShutdown(); + sqlite3GlobalConfig.isPCacheInit = 0; + } + if( sqlite3GlobalConfig.isMallocInit ){ sqlite3MallocEnd(); + sqlite3GlobalConfig.isMallocInit = 0; + } + if( sqlite3GlobalConfig.isMutexInit ){ sqlite3MutexEnd(); - sqlite3GlobalConfig.isInit = 0; + sqlite3GlobalConfig.isMutexInit = 0; } + return SQLITE_OK; } @@ -91349,13 +95072,6 @@ SQLITE_API int sqlite3_close(sqlite3 *db){ } sqlite3_mutex_enter(db->mutex); -#ifdef SQLITE_SSE - { - extern void sqlite3SseCleanup(sqlite3*); - sqlite3SseCleanup(db); - } -#endif - sqlite3ResetInternalSchema(db, 0); /* If a transaction is open, the ResetInternalSchema() call above @@ -91492,6 +95208,9 @@ SQLITE_PRIVATE void sqlite3RollbackAll(sqlite3 *db){ sqlite3ResetInternalSchema(db, 0); } + /* Any deferred constraint violations have now been resolved. */ + db->nDeferredCons = 0; + /* If one has been configured, invoke the rollback-hook callback */ if( db->xRollbackCallback && (inTrans || !db->autoCommit) ){ db->xRollbackCallback(db->pRollbackArg); @@ -91522,7 +95241,7 @@ SQLITE_PRIVATE const char *sqlite3ErrStr(int rc){ /* SQLITE_PROTOCOL */ 0, /* SQLITE_EMPTY */ "table contains no data", /* SQLITE_SCHEMA */ "database schema has changed", - /* SQLITE_TOOBIG */ "String or BLOB exceeded size limit", + /* SQLITE_TOOBIG */ "string or blob too big", /* SQLITE_CONSTRAINT */ "constraint failed", /* SQLITE_MISMATCH */ "datatype mismatch", /* SQLITE_MISUSE */ "library routine called out of sequence", @@ -92118,9 +95837,10 @@ SQLITE_API int sqlite3_extended_errcode(sqlite3 *db){ ** and the encoding is enc. */ static int createCollation( - sqlite3* db, + sqlite3* db, const char *zName, - int enc, + u8 enc, + u8 collType, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDel)(void*) @@ -92185,6 +95905,7 @@ static int createCollation( pColl->pUser = pCtx; pColl->xDel = xDel; pColl->enc = (u8)(enc2 | (enc & SQLITE_UTF16_ALIGNED)); + pColl->type = collType; } sqlite3Error(db, SQLITE_OK, 0); return SQLITE_OK; @@ -92207,6 +95928,7 @@ static const int aHardLimit[] = { SQLITE_MAX_ATTACHED, SQLITE_MAX_LIKE_PATTERN_LENGTH, SQLITE_MAX_VARIABLE_NUMBER, + SQLITE_MAX_TRIGGER_DEPTH, }; /* @@ -92242,6 +95964,9 @@ static const int aHardLimit[] = { #if SQLITE_MAX_COLUMN>32767 # error SQLITE_MAX_COLUMN must not exceed 32767 #endif +#if SQLITE_MAX_TRIGGER_DEPTH<1 +# error SQLITE_MAX_TRIGGER_DEPTH must be at least 1 +#endif /* @@ -92282,7 +96007,6 @@ static int openDatabase( ){ sqlite3 *db; int rc; - CollSeq *pColl; int isThreadsafe; *ppDb = 0; @@ -92300,6 +96024,11 @@ static int openDatabase( }else{ isThreadsafe = sqlite3GlobalConfig.bFullMutex; } + if( flags & SQLITE_OPEN_PRIVATECACHE ){ + flags &= ~SQLITE_OPEN_SHAREDCACHE; + }else if( sqlite3GlobalConfig.sharedCacheEnabled ){ + flags |= SQLITE_OPEN_SHAREDCACHE; + } /* Remove harmful bits from the flags parameter ** @@ -92335,7 +96064,6 @@ static int openDatabase( } sqlite3_mutex_enter(db->mutex); db->errMask = 0xff; - db->priorNewRowid = 0; db->nDb = 2; db->magic = SQLITE_MAGIC_BUSY; db->aDb = db->aDbStatic; @@ -92351,6 +96079,9 @@ static int openDatabase( #endif #ifdef SQLITE_ENABLE_LOAD_EXTENSION | SQLITE_LoadExtension +#endif +#if SQLITE_DEFAULT_RECURSIVE_TRIGGERS + | SQLITE_RecTriggers #endif ; sqlite3HashInit(&db->aCollSeq); @@ -92369,10 +96100,14 @@ static int openDatabase( ** and UTF-16, so add a version for each to avoid any unnecessary ** conversions. The only error that can occur here is a malloc() failure. */ - createCollation(db, "BINARY", SQLITE_UTF8, 0, binCollFunc, 0); - createCollation(db, "BINARY", SQLITE_UTF16BE, 0, binCollFunc, 0); - createCollation(db, "BINARY", SQLITE_UTF16LE, 0, binCollFunc, 0); - createCollation(db, "RTRIM", SQLITE_UTF8, (void*)1, binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF8, SQLITE_COLL_BINARY, 0, + binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF16BE, SQLITE_COLL_BINARY, 0, + binCollFunc, 0); + createCollation(db, "BINARY", SQLITE_UTF16LE, SQLITE_COLL_BINARY, 0, + binCollFunc, 0); + createCollation(db, "RTRIM", SQLITE_UTF8, SQLITE_COLL_USER, (void*)1, + binCollFunc, 0); if( db->mallocFailed ){ goto opendb_out; } @@ -92380,14 +96115,8 @@ static int openDatabase( assert( db->pDfltColl!=0 ); /* Also add a UTF-8 case-insensitive collation sequence. */ - createCollation(db, "NOCASE", SQLITE_UTF8, 0, nocaseCollatingFunc, 0); - - /* Set flags on the built-in collating sequences */ - db->pDfltColl->type = SQLITE_COLL_BINARY; - pColl = sqlite3FindCollSeq(db, SQLITE_UTF8, "NOCASE", 0); - if( pColl ){ - pColl->type = SQLITE_COLL_NOCASE; - } + createCollation(db, "NOCASE", SQLITE_UTF8, SQLITE_COLL_NOCASE, 0, + nocaseCollatingFunc, 0); /* Open the backend database driver */ db->openFlags = flags; @@ -92410,10 +96139,8 @@ static int openDatabase( */ db->aDb[0].zName = "main"; db->aDb[0].safety_level = 3; -#ifndef SQLITE_OMIT_TEMPDB db->aDb[1].zName = "temp"; db->aDb[1].safety_level = 1; -#endif db->magic = SQLITE_MAGIC_OPEN; if( db->mallocFailed ){ @@ -92570,7 +96297,7 @@ SQLITE_API int sqlite3_create_collation( int rc; sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); - rc = createCollation(db, zName, enc, pCtx, xCompare, 0); + rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; @@ -92590,7 +96317,7 @@ SQLITE_API int sqlite3_create_collation_v2( int rc; sqlite3_mutex_enter(db->mutex); assert( !db->mallocFailed ); - rc = createCollation(db, zName, enc, pCtx, xCompare, xDel); + rc = createCollation(db, zName, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, xDel); rc = sqlite3ApiExit(db, rc); sqlite3_mutex_leave(db->mutex); return rc; @@ -92613,7 +96340,7 @@ SQLITE_API int sqlite3_create_collation16( assert( !db->mallocFailed ); zName8 = sqlite3Utf16to8(db, zName, -1); if( zName8 ){ - rc = createCollation(db, zName8, enc, pCtx, xCompare, 0); + rc = createCollation(db, zName8, (u8)enc, SQLITE_COLL_USER, pCtx, xCompare, 0); sqlite3DbFree(db, zName8); } rc = sqlite3ApiExit(db, rc); @@ -93019,6 +96746,21 @@ SQLITE_API int sqlite3_test_control(int op, ...){ rc = ALWAYS(x); break; } + + /* sqlite3_test_control(SQLITE_TESTCTRL_RESERVE, sqlite3 *db, int N) + ** + ** Set the nReserve size to N for the main database on the database + ** connection db. + */ + case SQLITE_TESTCTRL_RESERVE: { + sqlite3 *db = va_arg(ap, sqlite3*); + int x = va_arg(ap,int); + sqlite3_mutex_enter(db->mutex); + sqlite3BtreeSetPageSize(db->aDb[0].pBt, 0, x, 0); + sqlite3_mutex_leave(db->mutex); + break; + } + } va_end(ap); #endif /* SQLITE_OMIT_BUILTIN_TEST */ @@ -93042,7 +96784,7 @@ SQLITE_API int sqlite3_test_control(int op, ...){ ** This file contains the implementation of the sqlite3_unlock_notify() ** API method and its associated functionality. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ /* Omit this entire file if SQLITE_ENABLE_UNLOCK_NOTIFY is not defined. */ @@ -101162,7 +104904,9 @@ static int getNextNode( for(ii=0; iinCol; ii++){ const char *zStr = pParse->azCol[ii]; int nStr = strlen(zStr); - if( nInput>nStr && zInput[nStr]==':' && memcmp(zStr, zInput, nStr)==0 ){ + if( nInput>nStr && zInput[nStr]==':' + && sqlite3_strnicmp(zStr, zInput, nStr)==0 + ){ iCol = ii; iColLen = ((zInput - z) + nStr + 1); break; @@ -101279,10 +105023,10 @@ static int fts3ExprParse( pNot->eType = FTSQUERY_NOT; pNot->pRight = p; if( pNotBranch ){ - pNotBranch->pLeft = p; - pNot->pRight = pNotBranch; + pNot->pLeft = pNotBranch; } pNotBranch = pNot; + p = pPrev; }else{ int eType = p->eType; assert( eType!=FTSQUERY_PHRASE || !p->pPhrase->isNot ); @@ -101364,7 +105108,11 @@ static int fts3ExprParse( if( !pRet ){ rc = SQLITE_ERROR; }else{ - pNotBranch->pLeft = pRet; + Fts3Expr *pIter = pNotBranch; + while( pIter->pLeft ){ + pIter = pIter->pLeft; + } + pIter->pLeft = pRet; pRet = pNotBranch; } } @@ -103254,7 +107002,7 @@ SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule( ** This file contains code for implementations of the r-tree and r*-tree ** algorithms packaged as an SQLite virtual table module. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE) @@ -104724,8 +108472,8 @@ static void LinearPickSeeds( ** variables iLeftSeek and iRightSeed. */ for(i=0; inDim; i++){ - float x1 = aCell[0].aCoord[i*2]; - float x2 = aCell[0].aCoord[i*2+1]; + float x1 = DCOORD(aCell[0].aCoord[i*2]); + float x2 = DCOORD(aCell[0].aCoord[i*2+1]); float x3 = x1; float x4 = x2; int jj; @@ -104734,8 +108482,8 @@ static void LinearPickSeeds( int iCellRight = 0; for(jj=1; jjx4 ) x4 = right; @@ -105093,6 +108841,9 @@ static int splitNodeGuttman( int i; aiUsed = sqlite3_malloc(sizeof(int)*nCell); + if( !aiUsed ){ + return SQLITE_NOMEM; + } memset(aiUsed, 0, sizeof(int)*nCell); PickSeeds(pRtree, aCell, nCell, &iLeftSeed, &iRightSeed); @@ -105580,7 +109331,7 @@ static int hashIsEmpty(Rtree *pRtree){ /* ** The xUpdate method for rtree module virtual tables. */ -int rtreeUpdate( +static int rtreeUpdate( sqlite3_vtab *pVtab, int nData, sqlite3_value **azData, @@ -105975,8 +109726,10 @@ static int rtreeInit( zSql = sqlite3_mprintf("%s);", zTmp); sqlite3_free(zTmp); } - if( !zSql || sqlite3_declare_vtab(db, zSql) ){ + if( !zSql ){ rc = SQLITE_NOMEM; + }else if( SQLITE_OK!=(rc = sqlite3_declare_vtab(db, zSql)) ){ + *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db)); } sqlite3_free(zSql); } @@ -106109,7 +109862,7 @@ SQLITE_API int sqlite3_extension_init( ** May you share freely, never taking more than you give. ** ************************************************************************* -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ ** ** This file implements an integration between the ICU library ** ("International Components for Unicode", an open-source library @@ -106610,7 +110363,7 @@ SQLITE_API int sqlite3_extension_init( ************************************************************************* ** This file implements a tokenizer for fts3 based on the ICU library. ** -** $Id: sqlite3.c,v 1.1.2.25 2009/06/15 13:23:39 scottmac Exp $ +** $Id: sqlite3.c 289758 2009-10-19 17:11:05Z pajoye $ */ #if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) diff --git a/ext/sqlite3/libsqlite/sqlite3.h b/ext/sqlite3/libsqlite/sqlite3.h index 5c9a9dac0..5216154f6 100644 --- a/ext/sqlite3/libsqlite/sqlite3.h +++ b/ext/sqlite3/libsqlite/sqlite3.h @@ -18,8 +18,8 @@ ** Some of the definitions that are in this file are marked as ** "experimental". Experimental interfaces are normally new ** features recently added to SQLite. We do not anticipate changes -** to experimental interfaces but reserve to make minor changes if -** experience from use "in the wild" suggest such changes are prudent. +** to experimental interfaces but reserve the right to make minor changes +** if experience from use "in the wild" suggest such changes are prudent. ** ** The official C-language API documentation for SQLite is derived ** from comments in this file. This file is the authoritative source @@ -29,8 +29,6 @@ ** The makefile makes some minor changes to this file (such as inserting ** the version number) and changes its name to "sqlite3.h" as ** part of the build process. -** -** @(#) $Id: sqlite3.h,v 1.1.2.20 2009/06/15 13:23:58 scottmac Exp $ */ #ifndef _SQLITE3_H_ #define _SQLITE3_H_ @@ -51,10 +49,15 @@ extern "C" { # define SQLITE_EXTERN extern #endif +#ifndef SQLITE_API +# define SQLITE_API +#endif + + /* ** These no-op macros are used in front of interfaces to mark those ** interfaces as either deprecated or experimental. New applications -** should not use deprecated intrfaces - they are support for backwards +** should not use deprecated interfaces - they are support for backwards ** compatibility only. Application writers should be aware that ** experimental interfaces are subject to change in point releases. ** @@ -84,51 +87,81 @@ extern "C" { ** the sqlite3.h file specify the version of SQLite with which ** that header file is associated. ** -** The "version" of SQLite is a string of the form "X.Y.Z". -** The phrase "alpha" or "beta" might be appended after the Z. -** The X value is major version number always 3 in SQLite3. -** The X value only changes when backwards compatibility is +** The "version" of SQLite is a string of the form "W.X.Y" or "W.X.Y.Z". +** The W value is major version number and is always 3 in SQLite3. +** The W value only changes when backwards compatibility is ** broken and we intend to never break backwards compatibility. -** The Y value is the minor version number and only changes when +** The X value is the minor version number and only changes when ** there are major feature enhancements that are forwards compatible ** but not backwards compatible. -** The Z value is the release number and is incremented with -** each release but resets back to 0 whenever Y is incremented. +** The Y value is the release number and is incremented with +** each release but resets back to 0 whenever X is incremented. +** The Z value only appears on branch releases. +** +** The SQLITE_VERSION_NUMBER is an integer that is computed as +** follows: +** +**
    +** SQLITE_VERSION_NUMBER = W*1000000 + X*1000 + Y
    +** 
    +** +** Since version 3.6.18, SQLite source code has been stored in the +** fossil configuration management +** system. The SQLITE_SOURCE_ID +** macro is a string which identifies a particular check-in of SQLite +** within its configuration management system. The string contains the +** date and time of the check-in (UTC) and an SHA1 hash of the entire +** source tree. ** -** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()]. +** See also: [sqlite3_libversion()], +** [sqlite3_libversion_number()], [sqlite3_sourceid()], +** [sqlite_version()] and [sqlite_source_id()]. ** ** Requirements: [H10011] [H10014] */ -#define SQLITE_VERSION "3.6.15" -#define SQLITE_VERSION_NUMBER 3006015 +#define SQLITE_VERSION "3.6.19" +#define SQLITE_VERSION_NUMBER 3006019 +#define SQLITE_SOURCE_ID "2009-10-14 11:33:55 c1d499afc50d54b376945b4efb65c56c787a073d" /* ** CAPI3REF: Run-Time Library Version Numbers {H10020} ** KEYWORDS: sqlite3_version ** -** These features provide the same information as the [SQLITE_VERSION] -** and [SQLITE_VERSION_NUMBER] #defines in the header, but are associated -** with the library instead of the header file. Cautious programmers might -** include a check in their application to verify that -** sqlite3_libversion_number() always returns the value -** [SQLITE_VERSION_NUMBER]. +** These interfaces provide the same information as the [SQLITE_VERSION], +** [SQLITE_VERSION_NUMBER], and [SQLITE_SOURCE_ID] #defines in the header, +** but are associated with the library instead of the header file. Cautious +** programmers might include assert() statements in their application to +** verify that values returned by these interfaces match the macros in +** the header, and thus insure that the application is +** compiled with matching library and header files. +** +**
    +** assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER );
    +** assert( strcmp(sqlite3_sourceid(),SQLITE_SOURCE_ID)==0 );
    +** assert( strcmp(sqlite3_libversion,SQLITE_VERSION)==0 );
    +** 
    ** ** The sqlite3_libversion() function returns the same information as is ** in the sqlite3_version[] string constant. The function is provided ** for use in DLLs since DLL users usually do not have direct access to string -** constants within the DLL. +** constants within the DLL. Similarly, the sqlite3_sourceid() function +** returns the same information as is in the [SQLITE_SOURCE_ID] #define of +** the header file. +** +** See also: [sqlite_version()] and [sqlite_source_id()]. ** ** Requirements: [H10021] [H10022] [H10023] */ -SQLITE_EXTERN const char sqlite3_version[]; -const char *sqlite3_libversion(void); -int sqlite3_libversion_number(void); +SQLITE_API SQLITE_EXTERN const char sqlite3_version[]; +SQLITE_API const char *sqlite3_libversion(void); +SQLITE_API const char *sqlite3_sourceid(void); +SQLITE_API int sqlite3_libversion_number(void); /* ** CAPI3REF: Test To See If The Library Is Threadsafe {H10100} ** ** SQLite can be compiled with or without mutexes. When -** the [SQLITE_THREADSAFE] C preprocessor macro 1 or 2, mutexes +** the [SQLITE_THREADSAFE] C preprocessor macro is 1 or 2, mutexes ** are enabled and SQLite is threadsafe. When the ** [SQLITE_THREADSAFE] macro is 0, ** the mutexes are omitted. Without the mutexes, it is not safe @@ -139,7 +172,7 @@ int sqlite3_libversion_number(void); ** the mutexes. But for maximum safety, mutexes should be enabled. ** The default behavior is for mutexes to be enabled. ** -** This interface can be used by a program to make sure that the +** This interface can be used by an application to make sure that the ** version of SQLite that it is linking against was compiled with ** the desired setting of the [SQLITE_THREADSAFE] macro. ** @@ -156,7 +189,7 @@ int sqlite3_libversion_number(void); ** ** Requirements: [H10101] [H10102] */ -int sqlite3_threadsafe(void); +SQLITE_API int sqlite3_threadsafe(void); /* ** CAPI3REF: Database Connection Handle {H12000} @@ -237,7 +270,7 @@ typedef sqlite_uint64 sqlite3_uint64; ** Requirements: ** [H12011] [H12012] [H12013] [H12014] [H12015] [H12019] */ -int sqlite3_close(sqlite3 *); +SQLITE_API int sqlite3_close(sqlite3 *); /* ** The type for a callback function. @@ -290,7 +323,7 @@ typedef int (*sqlite3_callback)(void*,int,char**, char**); ** [H12101] [H12102] [H12104] [H12105] [H12107] [H12110] [H12113] [H12116] ** [H12119] [H12122] [H12125] [H12131] [H12134] [H12137] [H12138] */ -int sqlite3_exec( +SQLITE_API int sqlite3_exec( sqlite3*, /* An open database */ const char *sql, /* SQL to be evaluated */ int (*callback)(void*,int,char**,char**), /* Callback function */ @@ -406,6 +439,8 @@ int sqlite3_exec( #define SQLITE_OPEN_MASTER_JOURNAL 0x00004000 /* VFS only */ #define SQLITE_OPEN_NOMUTEX 0x00008000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_FULLMUTEX 0x00010000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_SHAREDCACHE 0x00020000 /* Ok for sqlite3_open_v2() */ +#define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ /* ** CAPI3REF: Device Characteristics {H10240} @@ -473,8 +508,9 @@ int sqlite3_exec( /* ** CAPI3REF: OS Interface Open File Handle {H11110} ** -** An [sqlite3_file] object represents an open file in the OS -** interface layer. Individual OS interface implementations will +** An [sqlite3_file] object represents an open file in the +** [sqlite3_vfs | OS interface layer]. Individual OS interface +** implementations will ** want to subclass this object by appending additional fields ** for their own use. The pMethods entry is a pointer to an ** [sqlite3_io_methods] object that defines methods for performing @@ -494,6 +530,12 @@ struct sqlite3_file { ** This object defines the methods used to perform various operations ** against the open file represented by the [sqlite3_file] object. ** +** If the xOpen method sets the sqlite3_file.pMethods element +** to a non-NULL pointer, then the sqlite3_io_methods.xClose method +** may be invoked even if the xOpen reported that it failed. The +** only way to prevent a call to xClose following a failed xOpen +** is for the xOpen to set the sqlite3_file.pMethods element to NULL. +** ** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or ** [SQLITE_SYNC_FULL]. The first choice is the normal fsync(). ** The second choice is a Mac OS X style fullsync. The [SQLITE_SYNC_DATAONLY] @@ -654,11 +696,11 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** is either a NULL pointer or string obtained ** from xFullPathname(). SQLite further guarantees that ** the string will be valid and unchanged until xClose() is -** called. Because of the previous sentense, +** called. Because of the previous sentence, ** the [sqlite3_file] can safely store a pointer to the ** filename if it needs to remember the filename for some reason. ** If the zFilename parameter is xOpen is a NULL pointer then xOpen -** must invite its own temporary name for the file. Whenever the +** must invent its own temporary name for the file. Whenever the ** xFilename parameter is NULL it will also be the case that the ** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE]. ** @@ -714,7 +756,12 @@ typedef struct sqlite3_mutex sqlite3_mutex; ** At least szOsFile bytes of memory are allocated by SQLite ** to hold the [sqlite3_file] structure passed as the third ** argument to xOpen. The xOpen method does not have to -** allocate the structure; it should just fill it in. +** allocate the structure; it should just fill it in. Note that +** the xOpen method must set the sqlite3_file.pMethods to either +** a valid [sqlite3_io_methods] object or to NULL. xOpen must do +** this even if the open fails. SQLite expects that the sqlite3_file.pMethods +** element will be valid after xOpen returns regardless of the success +** or failure of the xOpen call. ** ** The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] ** to test for the existence of a file, or [SQLITE_ACCESS_READWRITE] to @@ -839,18 +886,19 @@ struct sqlite3_vfs { ** interface is called automatically by sqlite3_initialize() and ** sqlite3_os_end() is called by sqlite3_shutdown(). Appropriate ** implementations for sqlite3_os_init() and sqlite3_os_end() -** are built into SQLite when it is compiled for unix, windows, or os/2. -** When built for other platforms (using the [SQLITE_OS_OTHER=1] compile-time +** are built into SQLite when it is compiled for Unix, Windows, or OS/2. +** When [custom builds | built for other platforms] +** (using the [SQLITE_OS_OTHER=1] compile-time ** option) the application must supply a suitable implementation for ** sqlite3_os_init() and sqlite3_os_end(). An application-supplied ** implementation of sqlite3_os_init() or sqlite3_os_end() ** must return [SQLITE_OK] on success and some other [error code] upon ** failure. */ -int sqlite3_initialize(void); -int sqlite3_shutdown(void); -int sqlite3_os_init(void); -int sqlite3_os_end(void); +SQLITE_API int sqlite3_initialize(void); +SQLITE_API int sqlite3_shutdown(void); +SQLITE_API int sqlite3_os_init(void); +SQLITE_API int sqlite3_os_end(void); /* ** CAPI3REF: Configuring The SQLite Library {H14100} @@ -885,7 +933,7 @@ int sqlite3_os_end(void); ** [H14138] [H14141] [H14144] [H14147] [H14150] [H14153] [H14156] [H14159] ** [H14162] [H14165] [H14168] */ -SQLITE_EXPERIMENTAL int sqlite3_config(int, ...); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_config(int, ...); /* ** CAPI3REF: Configure database connections {H14200} @@ -909,7 +957,7 @@ SQLITE_EXPERIMENTAL int sqlite3_config(int, ...); ** Requirements: ** [H14203] [H14206] [H14209] [H14212] [H14215] */ -SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); /* ** CAPI3REF: Memory Allocation Routines {H10155} @@ -921,13 +969,15 @@ SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); ** This object is used in only one place in the SQLite interface. ** A pointer to an instance of this object is the argument to ** [sqlite3_config()] when the configuration option is -** [SQLITE_CONFIG_MALLOC]. By creating an instance of this object -** and passing it to [sqlite3_config()] during configuration, an -** application can specify an alternative memory allocation subsystem -** for SQLite to use for all of its dynamic memory needs. -** -** Note that SQLite comes with a built-in memory allocator that is -** perfectly adequate for the overwhelming majority of applications +** [SQLITE_CONFIG_MALLOC] or [SQLITE_CONFIG_GETMALLOC]. +** By creating an instance of this object +** and passing it to [sqlite3_config]([SQLITE_CONFIG_MALLOC]) +** during configuration, an application can specify an alternative +** memory allocation subsystem for SQLite to use for all of its +** dynamic memory needs. +** +** Note that SQLite comes with several [built-in memory allocators] +** that are perfectly adequate for the overwhelming majority of applications ** and that this object is only useful to a tiny minority of applications ** with specialized memory allocation requirements. This object is ** also used during testing of SQLite in order to specify an alternative @@ -935,8 +985,16 @@ SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); ** order to verify that SQLite recovers gracefully from such ** conditions. ** -** The xMalloc, xFree, and xRealloc methods must work like the -** malloc(), free(), and realloc() functions from the standard library. +** The xMalloc and xFree methods must work like the +** malloc() and free() functions from the standard C library. +** The xRealloc method must work like realloc() from the standard C library +** with the exception that if the second argument to xRealloc is zero, +** xRealloc must be a no-op - it must not perform any allocation or +** deallocation. SQLite guaranteeds that the second argument to +** xRealloc is always a value returned by a prior call to xRoundup. +** And so in cases where xRoundup always returns a positive number, +** xRealloc can perform exactly as the standard library realloc() and +** still be in compliance with this specification. ** ** xSize should return the allocated size of a memory allocation ** previously obtained from xMalloc or xRealloc. The allocated size @@ -946,6 +1004,9 @@ SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); ** a memory allocation given a particular requested size. Most memory ** allocators round up memory allocations at least to the next multiple ** of 8. Some allocators round up to a larger multiple or to a power of 2. +** Every memory allocation request coming in through [sqlite3_malloc()] +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** that causes the corresponding memory allocation to fail. ** ** The xInit method initializes the memory allocator. (For example, ** it might allocate any require mutexes or initialize internal data @@ -953,6 +1014,20 @@ SQLITE_EXPERIMENTAL int sqlite3_db_config(sqlite3*, int op, ...); ** [sqlite3_shutdown()] and should deallocate any resources acquired ** by xInit. The pAppData pointer is used as the only parameter to ** xInit and xShutdown. +** +** SQLite holds the [SQLITE_MUTEX_STATIC_MASTER] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. For all other methods, SQLite +** holds the [SQLITE_MUTEX_STATIC_MEM] mutex as long as the +** [SQLITE_CONFIG_MEMSTATUS] configuration option is turned on (which +** it is by default) and so the methods are automatically serialized. +** However, if [SQLITE_CONFIG_MEMSTATUS] is disabled, then the other +** methods must be threadsafe or else make their own arrangements for +** serialization. +** +** SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). */ typedef struct sqlite3_mem_methods sqlite3_mem_methods; struct sqlite3_mem_methods { @@ -1106,9 +1181,12 @@ struct sqlite3_mem_methods { ** **
    SQLITE_CONFIG_LOOKASIDE
    **
    This option takes two arguments that determine the default -** memory allcation lookaside optimization. The first argument is the +** memory allocation lookaside optimization. The first argument is the ** size of each lookaside buffer slot and the second is the number of -** slots allocated to each database connection.
    +** slots allocated to each database connection. This option sets the +** default lookaside size. The [SQLITE_DBCONFIG_LOOKASIDE] +** verb to [sqlite3_db_config()] can be used to change the lookaside +** configuration on individual connections. ** **
    SQLITE_CONFIG_PCACHE
    **
    This option takes a single argument which is a pointer to @@ -1158,12 +1236,15 @@ struct sqlite3_mem_methods { **
    This option takes three additional arguments that determine the ** [lookaside memory allocator] configuration for the [database connection]. ** The first argument (the third parameter to [sqlite3_db_config()] is a -** pointer to an 8-byte aligned memory buffer to use for lookaside memory. +** pointer to an memory buffer to use for lookaside memory. ** The first argument may be NULL in which case SQLite will allocate the ** lookaside buffer itself using [sqlite3_malloc()]. The second argument is the ** size of each lookaside buffer slot and the third argument is the number of ** slots. The size of the buffer in the first argument must be greater than -** or equal to the product of the second and third arguments.
    +** or equal to the product of the second and third arguments. The buffer +** must be aligned to an 8-byte boundary. If the second argument is not +** a multiple of 8, it is internally rounded down to the next smaller +** multiple of 8. See also: [SQLITE_CONFIG_LOOKASIDE] ** **
  • */ @@ -1180,7 +1261,7 @@ struct sqlite3_mem_methods { ** Requirements: ** [H12201] [H12202] */ -int sqlite3_extended_result_codes(sqlite3*, int onoff); +SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff); /* ** CAPI3REF: Last Insert Rowid {H12220} @@ -1225,7 +1306,7 @@ int sqlite3_extended_result_codes(sqlite3*, int onoff); ** unpredictable and might not equal either the old or the new ** last insert [rowid]. */ -sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); +SQLITE_API sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); /* ** CAPI3REF: Count The Number Of Rows Modified {H12240} @@ -1235,8 +1316,9 @@ sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); ** on the [database connection] specified by the first parameter. ** Only changes that are directly specified by the [INSERT], [UPDATE], ** or [DELETE] statement are counted. Auxiliary changes caused by -** triggers are not counted. Use the [sqlite3_total_changes()] function -** to find the total number of changes including changes caused by triggers. +** triggers or [foreign key actions] are not counted. Use the +** [sqlite3_total_changes()] function to find the total number of changes +** including changes caused by triggers and foreign key actions. ** ** Changes to a view that are simulated by an [INSTEAD OF trigger] ** are not counted. Only real table changes are counted. @@ -1281,15 +1363,15 @@ sqlite3_int64 sqlite3_last_insert_rowid(sqlite3*); ** while [sqlite3_changes()] is running then the value returned ** is unpredictable and not meaningful. */ -int sqlite3_changes(sqlite3*); +SQLITE_API int sqlite3_changes(sqlite3*); /* ** CAPI3REF: Total Number Of Rows Modified {H12260} ** ** This function returns the number of row changes caused by [INSERT], ** [UPDATE] or [DELETE] statements since the [database connection] was opened. -** The count includes all changes from all -** [CREATE TRIGGER | trigger] contexts. However, +** The count includes all changes from all [CREATE TRIGGER | trigger] +** contexts and changes made by [foreign key actions]. However, ** the count does not include changes used to implement [REPLACE] constraints, ** do rollbacks or ABORT processing, or [DROP TABLE] processing. The ** count does not include rows of views that fire an [INSTEAD OF trigger], @@ -1309,7 +1391,7 @@ int sqlite3_changes(sqlite3*); ** while [sqlite3_total_changes()] is running then the value ** returned is unpredictable and not meaningful. */ -int sqlite3_total_changes(sqlite3*); +SQLITE_API int sqlite3_total_changes(sqlite3*); /* ** CAPI3REF: Interrupt A Long-Running Query {H12270} @@ -1351,7 +1433,7 @@ int sqlite3_total_changes(sqlite3*); ** If the database connection closes while [sqlite3_interrupt()] ** is running then bad things will likely happen. */ -void sqlite3_interrupt(sqlite3*); +SQLITE_API void sqlite3_interrupt(sqlite3*); /* ** CAPI3REF: Determine If An SQL Statement Is Complete {H10510} @@ -1388,8 +1470,8 @@ void sqlite3_interrupt(sqlite3*); ** The input to [sqlite3_complete16()] must be a zero-terminated ** UTF-16 string in native byte order. */ -int sqlite3_complete(const char *sql); -int sqlite3_complete16(const void *sql); +SQLITE_API int sqlite3_complete(const char *sql); +SQLITE_API int sqlite3_complete16(const void *sql); /* ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors {H12310} @@ -1458,7 +1540,7 @@ int sqlite3_complete16(const void *sql); ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ -int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); +SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); /* ** CAPI3REF: Set A Busy Timeout {H12340} @@ -1481,7 +1563,7 @@ int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*); ** Requirements: ** [H12341] [H12343] [H12344] */ -int sqlite3_busy_timeout(sqlite3*, int ms); +SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms); /* ** CAPI3REF: Convenience Routines For Running Queries {H12370} @@ -1554,7 +1636,7 @@ int sqlite3_busy_timeout(sqlite3*, int ms); ** Requirements: ** [H12371] [H12373] [H12374] [H12376] [H12379] [H12382] */ -int sqlite3_get_table( +SQLITE_API int sqlite3_get_table( sqlite3 *db, /* An open database */ const char *zSql, /* SQL to be evaluated */ char ***pazResult, /* Results of the query */ @@ -1562,12 +1644,12 @@ int sqlite3_get_table( int *pnColumn, /* Number of result columns written here */ char **pzErrmsg /* Error msg written here */ ); -void sqlite3_free_table(char **result); +SQLITE_API void sqlite3_free_table(char **result); /* ** CAPI3REF: Formatted String Printing Functions {H17400} ** -** These routines are workalikes of the "printf()" family of functions +** These routines are work-alikes of the "printf()" family of functions ** from the standard C library. ** ** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their @@ -1659,9 +1741,9 @@ void sqlite3_free_table(char **result); ** Requirements: ** [H17403] [H17406] [H17407] */ -char *sqlite3_mprintf(const char*,...); -char *sqlite3_vmprintf(const char*, va_list); -char *sqlite3_snprintf(int,char*,const char*, ...); +SQLITE_API char *sqlite3_mprintf(const char*,...); +SQLITE_API char *sqlite3_vmprintf(const char*, va_list); +SQLITE_API char *sqlite3_snprintf(int,char*,const char*, ...); /* ** CAPI3REF: Memory Allocation Subsystem {H17300} @@ -1744,9 +1826,9 @@ char *sqlite3_snprintf(int,char*,const char*, ...); ** a block of memory after it has been released using ** [sqlite3_free()] or [sqlite3_realloc()]. */ -void *sqlite3_malloc(int); -void *sqlite3_realloc(void*, int); -void sqlite3_free(void*); +SQLITE_API void *sqlite3_malloc(int); +SQLITE_API void *sqlite3_realloc(void*, int); +SQLITE_API void sqlite3_free(void*); /* ** CAPI3REF: Memory Allocator Statistics {H17370} @@ -1758,8 +1840,8 @@ void sqlite3_free(void*); ** Requirements: ** [H17371] [H17373] [H17374] [H17375] */ -sqlite3_int64 sqlite3_memory_used(void); -sqlite3_int64 sqlite3_memory_highwater(int resetFlag); +SQLITE_API sqlite3_int64 sqlite3_memory_used(void); +SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag); /* ** CAPI3REF: Pseudo-Random Number Generator {H17390} @@ -1782,7 +1864,7 @@ sqlite3_int64 sqlite3_memory_highwater(int resetFlag); ** Requirements: ** [H17392] */ -void sqlite3_randomness(int N, void *P); +SQLITE_API void sqlite3_randomness(int N, void *P); /* ** CAPI3REF: Compile-Time Authorization Callbacks {H12500} @@ -1854,7 +1936,7 @@ void sqlite3_randomness(int N, void *P); ** database connections for the meaning of "modify" in this paragraph. ** ** When [sqlite3_prepare_v2()] is used to prepare a statement, the -** statement might be reprepared during [sqlite3_step()] due to a +** statement might be re-prepared during [sqlite3_step()] due to a ** schema change. Hence, the application should ensure that the ** correct authorizer callback remains in place during the [sqlite3_step()]. ** @@ -1868,7 +1950,7 @@ void sqlite3_randomness(int N, void *P); ** [H12501] [H12502] [H12503] [H12504] [H12505] [H12506] [H12507] [H12510] ** [H12511] [H12512] [H12520] [H12521] [H12522] */ -int sqlite3_set_authorizer( +SQLITE_API int sqlite3_set_authorizer( sqlite3*, int (*xAuth)(void*,int,const char*,const char*,const char*,const char*), void *pUserData @@ -1966,8 +2048,8 @@ int sqlite3_set_authorizer( ** [H12281] [H12282] [H12283] [H12284] [H12285] [H12287] [H12288] [H12289] ** [H12290] */ -SQLITE_EXPERIMENTAL void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); -SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, +SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_trace(sqlite3*, void(*xTrace)(void*,const char*), void*); +SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, void(*xProfile)(void*,const char*,sqlite3_uint64), void*); /* @@ -1992,7 +2074,7 @@ SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*, ** [H12911] [H12912] [H12913] [H12914] [H12915] [H12916] [H12917] [H12918] ** */ -void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); +SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); /* ** CAPI3REF: Opening A New Database Connection {H12700} @@ -2021,7 +2103,8 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** except that it accepts two additional parameters for additional control ** over the new database connection. The flags parameter can take one of ** the following three values, optionally combined with the -** [SQLITE_OPEN_NOMUTEX] or [SQLITE_OPEN_FULLMUTEX] flags: +** [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], [SQLITE_OPEN_SHAREDCACHE], +** and/or [SQLITE_OPEN_PRIVATECACHE] flags: ** **
    **
    [SQLITE_OPEN_READONLY]
    @@ -2041,7 +2124,8 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** ** If the 3rd parameter to sqlite3_open_v2() is not one of the ** combinations shown above or one of the combinations shown above combined -** with the [SQLITE_OPEN_NOMUTEX] or [SQLITE_OPEN_FULLMUTEX] flags, +** with the [SQLITE_OPEN_NOMUTEX], [SQLITE_OPEN_FULLMUTEX], +** [SQLITE_OPEN_SHAREDCACHE] and/or [SQLITE_OPEN_SHAREDCACHE] flags, ** then the behavior is undefined. ** ** If the [SQLITE_OPEN_NOMUTEX] flag is set, then the database connection @@ -2050,6 +2134,11 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** [SQLITE_OPEN_FULLMUTEX] flag is set then the database connection opens ** in the serialized [threading mode] unless single-thread was ** previously selected at compile-time or start-time. +** The [SQLITE_OPEN_SHAREDCACHE] flag causes the database connection to be +** eligible to use [shared cache mode], regardless of whether or not shared +** cache is enabled using [sqlite3_enable_shared_cache()]. The +** [SQLITE_OPEN_PRIVATECACHE] flag causes the database connection to not +** participate in [shared cache mode] even if it is enabled. ** ** If the filename is ":memory:", then a private, temporary in-memory database ** is created for the connection. This in-memory database will vanish when @@ -2078,15 +2167,15 @@ void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*); ** [H12701] [H12702] [H12703] [H12704] [H12706] [H12707] [H12709] [H12711] ** [H12712] [H12713] [H12714] [H12717] [H12719] [H12721] [H12723] */ -int sqlite3_open( +SQLITE_API int sqlite3_open( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); -int sqlite3_open16( +SQLITE_API int sqlite3_open16( const void *filename, /* Database filename (UTF-16) */ sqlite3 **ppDb /* OUT: SQLite db handle */ ); -int sqlite3_open_v2( +SQLITE_API int sqlite3_open_v2( const char *filename, /* Database filename (UTF-8) */ sqlite3 **ppDb, /* OUT: SQLite db handle */ int flags, /* Flags */ @@ -2129,10 +2218,10 @@ int sqlite3_open_v2( ** Requirements: ** [H12801] [H12802] [H12803] [H12807] [H12808] [H12809] */ -int sqlite3_errcode(sqlite3 *db); -int sqlite3_extended_errcode(sqlite3 *db); -const char *sqlite3_errmsg(sqlite3*); -const void *sqlite3_errmsg16(sqlite3*); +SQLITE_API int sqlite3_errcode(sqlite3 *db); +SQLITE_API int sqlite3_extended_errcode(sqlite3 *db); +SQLITE_API const char *sqlite3_errmsg(sqlite3*); +SQLITE_API const void *sqlite3_errmsg16(sqlite3*); /* ** CAPI3REF: SQL Statement Object {H13000} @@ -2197,7 +2286,7 @@ typedef struct sqlite3_stmt sqlite3_stmt; ** Requirements: ** [H12762] [H12766] [H12769] */ -int sqlite3_limit(sqlite3*, int id, int newVal); +SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal); /* ** CAPI3REF: Run-Time Limit Categories {H12790} @@ -2243,6 +2332,9 @@ int sqlite3_limit(sqlite3*, int id, int newVal); **
    SQLITE_LIMIT_VARIABLE_NUMBER
    **
    The maximum number of variables in an SQL statement that can ** be bound.
    +** +**
    SQLITE_LIMIT_TRIGGER_DEPTH
    +**
    The maximum depth of recursion for triggers.
    **
    */ #define SQLITE_LIMIT_LENGTH 0 @@ -2255,6 +2347,7 @@ int sqlite3_limit(sqlite3*, int id, int newVal); #define SQLITE_LIMIT_ATTACHED 7 #define SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8 #define SQLITE_LIMIT_VARIABLE_NUMBER 9 +#define SQLITE_LIMIT_TRIGGER_DEPTH 10 /* ** CAPI3REF: Compiling An SQL Statement {H13010} @@ -2331,28 +2424,28 @@ int sqlite3_limit(sqlite3*, int id, int newVal); ** [H13011] [H13012] [H13013] [H13014] [H13015] [H13016] [H13019] [H13021] ** */ -int sqlite3_prepare( +SQLITE_API int sqlite3_prepare( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); -int sqlite3_prepare_v2( +SQLITE_API int sqlite3_prepare_v2( sqlite3 *db, /* Database handle */ const char *zSql, /* SQL statement, UTF-8 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const char **pzTail /* OUT: Pointer to unused portion of zSql */ ); -int sqlite3_prepare16( +SQLITE_API int sqlite3_prepare16( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ sqlite3_stmt **ppStmt, /* OUT: Statement handle */ const void **pzTail /* OUT: Pointer to unused portion of zSql */ ); -int sqlite3_prepare16_v2( +SQLITE_API int sqlite3_prepare16_v2( sqlite3 *db, /* Database handle */ const void *zSql, /* SQL statement, UTF-16 encoded */ int nByte, /* Maximum length of zSql in bytes. */ @@ -2370,7 +2463,7 @@ int sqlite3_prepare16_v2( ** Requirements: ** [H13101] [H13102] [H13103] */ -const char *sqlite3_sql(sqlite3_stmt *pStmt); +SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt); /* ** CAPI3REF: Dynamically Typed Value Object {H15000} @@ -2431,7 +2524,8 @@ typedef struct sqlite3_context sqlite3_context; ** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding} ** ** In the SQL strings input to [sqlite3_prepare_v2()] and its variants, -** literals may be replaced by a [parameter] in one of these forms: +** literals may be replaced by a [parameter] that matches one of following +** templates: ** **
      **
    • ? @@ -2441,8 +2535,8 @@ typedef struct sqlite3_context sqlite3_context; **
    • $VVV **
    ** -** In the parameter forms shown above NNN is an integer literal, -** and VVV is an alpha-numeric parameter name. The values of these +** In the templates above, NNN represents an integer literal, +** and VVV represents an alphanumeric identifer. The values of these ** parameters (also called "host parameter names" or "SQL parameters") ** can be set using the sqlite3_bind_*() routines defined here. ** @@ -2509,15 +2603,15 @@ typedef struct sqlite3_context sqlite3_context; ** [H13530] [H13533] [H13536] [H13539] [H13542] [H13545] [H13548] [H13551] ** */ -int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); -int sqlite3_bind_double(sqlite3_stmt*, int, double); -int sqlite3_bind_int(sqlite3_stmt*, int, int); -int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); -int sqlite3_bind_null(sqlite3_stmt*, int); -int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); -int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); -int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); -int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); +SQLITE_API int sqlite3_bind_blob(sqlite3_stmt*, int, const void*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_double(sqlite3_stmt*, int, double); +SQLITE_API int sqlite3_bind_int(sqlite3_stmt*, int, int); +SQLITE_API int sqlite3_bind_int64(sqlite3_stmt*, int, sqlite3_int64); +SQLITE_API int sqlite3_bind_null(sqlite3_stmt*, int); +SQLITE_API int sqlite3_bind_text(sqlite3_stmt*, int, const char*, int n, void(*)(void*)); +SQLITE_API int sqlite3_bind_text16(sqlite3_stmt*, int, const void*, int, void(*)(void*)); +SQLITE_API int sqlite3_bind_value(sqlite3_stmt*, int, const sqlite3_value*); +SQLITE_API int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); /* ** CAPI3REF: Number Of SQL Parameters {H13600} @@ -2540,7 +2634,7 @@ int sqlite3_bind_zeroblob(sqlite3_stmt*, int, int n); ** Requirements: ** [H13601] */ -int sqlite3_bind_parameter_count(sqlite3_stmt*); +SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*); /* ** CAPI3REF: Name Of A Host Parameter {H13620} @@ -2570,7 +2664,7 @@ int sqlite3_bind_parameter_count(sqlite3_stmt*); ** Requirements: ** [H13621] */ -const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); +SQLITE_API const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); /* ** CAPI3REF: Index Of A Parameter With A Given Name {H13640} @@ -2589,7 +2683,7 @@ const char *sqlite3_bind_parameter_name(sqlite3_stmt*, int); ** Requirements: ** [H13641] */ -int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); +SQLITE_API int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); /* ** CAPI3REF: Reset All Bindings On A Prepared Statement {H13660} @@ -2601,7 +2695,7 @@ int sqlite3_bind_parameter_index(sqlite3_stmt*, const char *zName); ** Requirements: ** [H13661] */ -int sqlite3_clear_bindings(sqlite3_stmt*); +SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*); /* ** CAPI3REF: Number Of Columns In A Result Set {H13710} @@ -2613,7 +2707,7 @@ int sqlite3_clear_bindings(sqlite3_stmt*); ** Requirements: ** [H13711] */ -int sqlite3_column_count(sqlite3_stmt *pStmt); +SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Column Names In A Result Set {H13720} @@ -2642,8 +2736,8 @@ int sqlite3_column_count(sqlite3_stmt *pStmt); ** Requirements: ** [H13721] [H13723] [H13724] [H13725] [H13726] [H13727] */ -const char *sqlite3_column_name(sqlite3_stmt*, int N); -const void *sqlite3_column_name16(sqlite3_stmt*, int N); +SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N); +SQLITE_API const void *sqlite3_column_name16(sqlite3_stmt*, int N); /* ** CAPI3REF: Source Of Data In A Query Result {H13740} @@ -2690,12 +2784,12 @@ const void *sqlite3_column_name16(sqlite3_stmt*, int N); ** for the same [prepared statement] and result column ** at the same time then the results are undefined. */ -const char *sqlite3_column_database_name(sqlite3_stmt*,int); -const void *sqlite3_column_database_name16(sqlite3_stmt*,int); -const char *sqlite3_column_table_name(sqlite3_stmt*,int); -const void *sqlite3_column_table_name16(sqlite3_stmt*,int); -const char *sqlite3_column_origin_name(sqlite3_stmt*,int); -const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_database_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_table_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_table_name16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_origin_name(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); /* ** CAPI3REF: Declared Datatype Of A Query Result {H13760} @@ -2729,8 +2823,8 @@ const void *sqlite3_column_origin_name16(sqlite3_stmt*,int); ** Requirements: ** [H13761] [H13762] [H13763] */ -const char *sqlite3_column_decltype(sqlite3_stmt*,int); -const void *sqlite3_column_decltype16(sqlite3_stmt*,int); +SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int); +SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int); /* ** CAPI3REF: Evaluate An SQL Statement {H13200} @@ -2800,7 +2894,7 @@ const void *sqlite3_column_decltype16(sqlite3_stmt*,int); ** Requirements: ** [H13202] [H15304] [H15306] [H15308] [H15310] */ -int sqlite3_step(sqlite3_stmt*); +SQLITE_API int sqlite3_step(sqlite3_stmt*); /* ** CAPI3REF: Number of columns in a result set {H13770} @@ -2810,7 +2904,7 @@ int sqlite3_step(sqlite3_stmt*); ** Requirements: ** [H13771] [H13772] */ -int sqlite3_data_count(sqlite3_stmt *pStmt); +SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt); /* ** CAPI3REF: Fundamental Datatypes {H10265} @@ -3000,16 +3094,16 @@ int sqlite3_data_count(sqlite3_stmt *pStmt); ** [H13803] [H13806] [H13809] [H13812] [H13815] [H13818] [H13821] [H13824] ** [H13827] [H13830] */ -const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); -int sqlite3_column_bytes(sqlite3_stmt*, int iCol); -int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); -double sqlite3_column_double(sqlite3_stmt*, int iCol); -int sqlite3_column_int(sqlite3_stmt*, int iCol); -sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); -const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); -const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); -int sqlite3_column_type(sqlite3_stmt*, int iCol); -sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); +SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_bytes16(sqlite3_stmt*, int iCol); +SQLITE_API double sqlite3_column_double(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_int(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_int64 sqlite3_column_int64(sqlite3_stmt*, int iCol); +SQLITE_API const unsigned char *sqlite3_column_text(sqlite3_stmt*, int iCol); +SQLITE_API const void *sqlite3_column_text16(sqlite3_stmt*, int iCol); +SQLITE_API int sqlite3_column_type(sqlite3_stmt*, int iCol); +SQLITE_API sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); /* ** CAPI3REF: Destroy A Prepared Statement Object {H13300} @@ -3030,7 +3124,7 @@ sqlite3_value *sqlite3_column_value(sqlite3_stmt*, int iCol); ** Requirements: ** [H11302] [H11304] */ -int sqlite3_finalize(sqlite3_stmt *pStmt); +SQLITE_API int sqlite3_finalize(sqlite3_stmt *pStmt); /* ** CAPI3REF: Reset A Prepared Statement Object {H13330} @@ -3056,7 +3150,7 @@ int sqlite3_finalize(sqlite3_stmt *pStmt); ** {H11338} The [sqlite3_reset(S)] interface does not change the values ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. */ -int sqlite3_reset(sqlite3_stmt *pStmt); +SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); /* ** CAPI3REF: Create Or Redefine SQL Functions {H16100} @@ -3094,7 +3188,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt); ** [SQLITE_UTF8 | text encoding] this SQL function prefers for ** its parameters. Any SQL function implementation should be able to work ** work with UTF-8, UTF-16le, or UTF-16be. But some implementations may be -** more efficient with one encoding than another. It is allowed to +** more efficient with one encoding than another. An application may ** invoke sqlite3_create_function() or sqlite3_create_function16() multiple ** times with the same function but with different values of eTextRep. ** When multiple implementations of the same function are available, SQLite @@ -3116,7 +3210,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt); ** It is permitted to register multiple implementations of the same ** functions with the same name but with either differing numbers of ** arguments or differing preferred text encodings. SQLite will use -** the implementation most closely matches the way in which the +** the implementation that most closely matches the way in which the ** SQL function is used. A function implementation with a non-negative ** nArg parameter is a better match than a function implementation with ** a negative nArg. A function where the preferred text encoding @@ -3142,7 +3236,7 @@ int sqlite3_reset(sqlite3_stmt *pStmt); ** [H16103] [H16106] [H16109] [H16112] [H16118] [H16121] [H16127] ** [H16130] [H16133] [H16136] [H16139] [H16142] */ -int sqlite3_create_function( +SQLITE_API int sqlite3_create_function( sqlite3 *db, const char *zFunctionName, int nArg, @@ -3152,7 +3246,7 @@ int sqlite3_create_function( void (*xStep)(sqlite3_context*,int,sqlite3_value**), void (*xFinal)(sqlite3_context*) ); -int sqlite3_create_function16( +SQLITE_API int sqlite3_create_function16( sqlite3 *db, const void *zFunctionName, int nArg, @@ -3187,12 +3281,12 @@ int sqlite3_create_function16( ** using these functions, we are not going to tell you what they do. */ #ifndef SQLITE_OMIT_DEPRECATED -SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); -SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); -SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); -SQLITE_DEPRECATED int sqlite3_global_recover(void); -SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); -SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); +SQLITE_API SQLITE_DEPRECATED int sqlite3_aggregate_count(sqlite3_context*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_expired(sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_transfer_bindings(sqlite3_stmt*, sqlite3_stmt*); +SQLITE_API SQLITE_DEPRECATED int sqlite3_global_recover(void); +SQLITE_API SQLITE_DEPRECATED void sqlite3_thread_cleanup(void); +SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void*,sqlite3_int64); #endif /* @@ -3244,18 +3338,18 @@ SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int64,int),void ** [H15103] [H15106] [H15109] [H15112] [H15115] [H15118] [H15121] [H15124] ** [H15127] [H15130] [H15133] [H15136] */ -const void *sqlite3_value_blob(sqlite3_value*); -int sqlite3_value_bytes(sqlite3_value*); -int sqlite3_value_bytes16(sqlite3_value*); -double sqlite3_value_double(sqlite3_value*); -int sqlite3_value_int(sqlite3_value*); -sqlite3_int64 sqlite3_value_int64(sqlite3_value*); -const unsigned char *sqlite3_value_text(sqlite3_value*); -const void *sqlite3_value_text16(sqlite3_value*); -const void *sqlite3_value_text16le(sqlite3_value*); -const void *sqlite3_value_text16be(sqlite3_value*); -int sqlite3_value_type(sqlite3_value*); -int sqlite3_value_numeric_type(sqlite3_value*); +SQLITE_API const void *sqlite3_value_blob(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes(sqlite3_value*); +SQLITE_API int sqlite3_value_bytes16(sqlite3_value*); +SQLITE_API double sqlite3_value_double(sqlite3_value*); +SQLITE_API int sqlite3_value_int(sqlite3_value*); +SQLITE_API sqlite3_int64 sqlite3_value_int64(sqlite3_value*); +SQLITE_API const unsigned char *sqlite3_value_text(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16le(sqlite3_value*); +SQLITE_API const void *sqlite3_value_text16be(sqlite3_value*); +SQLITE_API int sqlite3_value_type(sqlite3_value*); +SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*); /* ** CAPI3REF: Obtain Aggregate Function Context {H16210} @@ -3283,7 +3377,7 @@ int sqlite3_value_numeric_type(sqlite3_value*); ** Requirements: ** [H16211] [H16213] [H16215] [H16217] */ -void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); +SQLITE_API void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); /* ** CAPI3REF: User Data For Functions {H16240} @@ -3300,7 +3394,7 @@ void *sqlite3_aggregate_context(sqlite3_context*, int nBytes); ** Requirements: ** [H16243] */ -void *sqlite3_user_data(sqlite3_context*); +SQLITE_API void *sqlite3_user_data(sqlite3_context*); /* ** CAPI3REF: Database Connection For Functions {H16250} @@ -3314,7 +3408,7 @@ void *sqlite3_user_data(sqlite3_context*); ** Requirements: ** [H16253] */ -sqlite3 *sqlite3_context_db_handle(sqlite3_context*); +SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*); /* ** CAPI3REF: Function Auxiliary Data {H16270} @@ -3361,8 +3455,8 @@ sqlite3 *sqlite3_context_db_handle(sqlite3_context*); ** Requirements: ** [H16272] [H16274] [H16276] [H16277] [H16278] [H16279] */ -void *sqlite3_get_auxdata(sqlite3_context*, int N); -void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); +SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); +SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); /* @@ -3464,10 +3558,11 @@ typedef void (*sqlite3_destructor_type)(void*); ** or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that ** function as the destructor on the text or BLOB result when it has ** finished using that result. -** If the 4th parameter to the sqlite3_result_text* interfaces or +** If the 4th parameter to the sqlite3_result_text* interfaces or to ** sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite ** assumes that the text or BLOB result is in constant space and does not -** copy the it or call a destructor when it has finished using that result. +** copy the content of the parameter nor call a destructor on the content +** when it has finished using that result. ** If the 4th parameter to the sqlite3_result_text* interfaces ** or sqlite3_result_blob is the special constant SQLITE_TRANSIENT ** then SQLite makes a copy of the result into space obtained from @@ -3492,22 +3587,22 @@ typedef void (*sqlite3_destructor_type)(void*); ** [H16427] [H16430] [H16433] [H16436] [H16439] [H16442] [H16445] [H16448] ** [H16451] [H16454] [H16457] [H16460] [H16463] */ -void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); -void sqlite3_result_double(sqlite3_context*, double); -void sqlite3_result_error(sqlite3_context*, const char*, int); -void sqlite3_result_error16(sqlite3_context*, const void*, int); -void sqlite3_result_error_toobig(sqlite3_context*); -void sqlite3_result_error_nomem(sqlite3_context*); -void sqlite3_result_error_code(sqlite3_context*, int); -void sqlite3_result_int(sqlite3_context*, int); -void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); -void sqlite3_result_null(sqlite3_context*); -void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); -void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); -void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); -void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); -void sqlite3_result_value(sqlite3_context*, sqlite3_value*); -void sqlite3_result_zeroblob(sqlite3_context*, int n); +SQLITE_API void sqlite3_result_blob(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_double(sqlite3_context*, double); +SQLITE_API void sqlite3_result_error(sqlite3_context*, const char*, int); +SQLITE_API void sqlite3_result_error16(sqlite3_context*, const void*, int); +SQLITE_API void sqlite3_result_error_toobig(sqlite3_context*); +SQLITE_API void sqlite3_result_error_nomem(sqlite3_context*); +SQLITE_API void sqlite3_result_error_code(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int(sqlite3_context*, int); +SQLITE_API void sqlite3_result_int64(sqlite3_context*, sqlite3_int64); +SQLITE_API void sqlite3_result_null(sqlite3_context*); +SQLITE_API void sqlite3_result_text(sqlite3_context*, const char*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16(sqlite3_context*, const void*, int, void(*)(void*)); +SQLITE_API void sqlite3_result_text16le(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_text16be(sqlite3_context*, const void*, int,void(*)(void*)); +SQLITE_API void sqlite3_result_value(sqlite3_context*, sqlite3_value*); +SQLITE_API void sqlite3_result_zeroblob(sqlite3_context*, int n); /* ** CAPI3REF: Define New Collating Sequences {H16600} @@ -3559,14 +3654,14 @@ void sqlite3_result_zeroblob(sqlite3_context*, int n); ** [H16603] [H16604] [H16606] [H16609] [H16612] [H16615] [H16618] [H16621] ** [H16624] [H16627] [H16630] */ -int sqlite3_create_collation( +SQLITE_API int sqlite3_create_collation( sqlite3*, const char *zName, int eTextRep, void*, int(*xCompare)(void*,int,const void*,int,const void*) ); -int sqlite3_create_collation_v2( +SQLITE_API int sqlite3_create_collation_v2( sqlite3*, const char *zName, int eTextRep, @@ -3574,7 +3669,7 @@ int sqlite3_create_collation_v2( int(*xCompare)(void*,int,const void*,int,const void*), void(*xDestroy)(void*) ); -int sqlite3_create_collation16( +SQLITE_API int sqlite3_create_collation16( sqlite3*, const void *zName, int eTextRep, @@ -3611,12 +3706,12 @@ int sqlite3_create_collation16( ** Requirements: ** [H16702] [H16704] [H16706] */ -int sqlite3_collation_needed( +SQLITE_API int sqlite3_collation_needed( sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const char*) ); -int sqlite3_collation_needed16( +SQLITE_API int sqlite3_collation_needed16( sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const void*) @@ -3629,7 +3724,7 @@ int sqlite3_collation_needed16( ** The code to implement this API is not available in the public release ** of SQLite. */ -int sqlite3_key( +SQLITE_API int sqlite3_key( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The key */ ); @@ -3642,7 +3737,7 @@ int sqlite3_key( ** The code to implement this API is not available in the public release ** of SQLite. */ -int sqlite3_rekey( +SQLITE_API int sqlite3_rekey( sqlite3 *db, /* Database to be rekeyed */ const void *pKey, int nKey /* The new key */ ); @@ -3663,7 +3758,7 @@ int sqlite3_rekey( ** ** Requirements: [H10533] [H10536] */ -int sqlite3_sleep(int); +SQLITE_API int sqlite3_sleep(int); /* ** CAPI3REF: Name Of The Folder Holding Temporary Files {H10310} @@ -3693,7 +3788,7 @@ int sqlite3_sleep(int); ** made NULL or made to point to memory obtained from [sqlite3_malloc] ** or else the use of the [temp_store_directory pragma] should be avoided. */ -SQLITE_EXTERN char *sqlite3_temp_directory; +SQLITE_API SQLITE_EXTERN char *sqlite3_temp_directory; /* ** CAPI3REF: Test For Auto-Commit Mode {H12930} @@ -3718,7 +3813,7 @@ SQLITE_EXTERN char *sqlite3_temp_directory; ** ** Requirements: [H12931] [H12932] [H12933] [H12934] */ -int sqlite3_get_autocommit(sqlite3*); +SQLITE_API int sqlite3_get_autocommit(sqlite3*); /* ** CAPI3REF: Find The Database Handle Of A Prepared Statement {H13120} @@ -3731,7 +3826,7 @@ int sqlite3_get_autocommit(sqlite3*); ** ** Requirements: [H13123] */ -sqlite3 *sqlite3_db_handle(sqlite3_stmt*); +SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*); /* ** CAPI3REF: Find the next prepared statement {H13140} @@ -3748,7 +3843,7 @@ sqlite3 *sqlite3_db_handle(sqlite3_stmt*); ** ** Requirements: [H13143] [H13146] [H13149] [H13152] */ -sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); +SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); /* ** CAPI3REF: Commit And Rollback Notification Callbacks {H12950} @@ -3799,8 +3894,8 @@ sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt); ** [H12951] [H12952] [H12953] [H12954] [H12955] ** [H12961] [H12962] [H12963] [H12964] */ -void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); -void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); +SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*); +SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); /* ** CAPI3REF: Data Change Notification Callbacks {H12970} @@ -3849,7 +3944,7 @@ void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*); ** Requirements: ** [H12971] [H12973] [H12975] [H12977] [H12979] [H12981] [H12983] [H12986] */ -void *sqlite3_update_hook( +SQLITE_API void *sqlite3_update_hook( sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* @@ -3857,7 +3952,7 @@ void *sqlite3_update_hook( /* ** CAPI3REF: Enable Or Disable Shared Pager Cache {H10330} -** KEYWORDS: {shared cache} {shared cache mode} +** KEYWORDS: {shared cache} ** ** This routine enables or disables the sharing of the database cache ** and schema data structures between [database connection | connections] @@ -3888,7 +3983,7 @@ void *sqlite3_update_hook( ** ** Requirements: [H10331] [H10336] [H10337] [H10339] */ -int sqlite3_enable_shared_cache(int); +SQLITE_API int sqlite3_enable_shared_cache(int); /* ** CAPI3REF: Attempt To Free Heap Memory {H17340} @@ -3902,7 +3997,7 @@ int sqlite3_enable_shared_cache(int); ** ** Requirements: [H17341] [H17342] */ -int sqlite3_release_memory(int); +SQLITE_API int sqlite3_release_memory(int); /* ** CAPI3REF: Impose A Limit On Heap Size {H17350} @@ -3937,7 +4032,7 @@ int sqlite3_release_memory(int); ** Requirements: ** [H16351] [H16352] [H16353] [H16354] [H16355] [H16358] */ -void sqlite3_soft_heap_limit(int); +SQLITE_API void sqlite3_soft_heap_limit(int); /* ** CAPI3REF: Extract Metadata About A Column Of A Table {H12850} @@ -4001,7 +4096,7 @@ void sqlite3_soft_heap_limit(int); ** This API is only available if the library was compiled with the ** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined. */ -int sqlite3_table_column_metadata( +SQLITE_API int sqlite3_table_column_metadata( sqlite3 *db, /* Connection handle */ const char *zDbName, /* Database name or NULL */ const char *zTableName, /* Table name */ @@ -4039,7 +4134,7 @@ int sqlite3_table_column_metadata( ** [sqlite3_enable_load_extension()] prior to calling this API, ** otherwise an error will be returned. */ -int sqlite3_load_extension( +SQLITE_API int sqlite3_load_extension( sqlite3 *db, /* Load the extension into this database connection */ const char *zFile, /* Name of the shared library containing extension */ const char *zProc, /* Entry point. Derived from zFile if 0 */ @@ -4062,7 +4157,7 @@ int sqlite3_load_extension( ** ** {H12622} Extension loading is off by default. */ -int sqlite3_enable_load_extension(sqlite3 *db, int onoff); +SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff); /* ** CAPI3REF: Automatically Load An Extensions {H12640} @@ -4089,7 +4184,7 @@ int sqlite3_enable_load_extension(sqlite3 *db, int onoff); ** ** {H12644} Automatic extensions apply across all threads. */ -int sqlite3_auto_extension(void (*xEntryPoint)(void)); +SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void)); /* ** CAPI3REF: Reset Automatic Extension Loading {H12660} @@ -4103,7 +4198,7 @@ int sqlite3_auto_extension(void (*xEntryPoint)(void)); ** ** {H12662} This function disables automatic extensions in all threads. */ -void sqlite3_reset_auto_extension(void); +SQLITE_API void sqlite3_reset_auto_extension(void); /* ****** EXPERIMENTAL - subject to change without notice ************** @@ -4274,7 +4369,7 @@ struct sqlite3_index_info { ** This interface has exactly the same effect as calling ** [sqlite3_create_module_v2()] with a NULL client data destructor. */ -SQLITE_EXPERIMENTAL int sqlite3_create_module( +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ @@ -4291,7 +4386,7 @@ SQLITE_EXPERIMENTAL int sqlite3_create_module( ** invoke the destructor function (if it is not NULL) when SQLite ** no longer needs the pClientData pointer. */ -SQLITE_EXPERIMENTAL int sqlite3_create_module_v2( +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_create_module_v2( sqlite3 *db, /* SQLite connection to register module with */ const char *zName, /* Name of the module */ const sqlite3_module *p, /* Methods for the module */ @@ -4320,7 +4415,7 @@ SQLITE_EXPERIMENTAL int sqlite3_create_module_v2( */ struct sqlite3_vtab { const sqlite3_module *pModule; /* The module for this virtual table */ - int nRef; /* Used internally */ + int nRef; /* NO LONGER USED */ char *zErrMsg; /* Error message from sqlite3_mprintf() */ /* Virtual table implementations will typically add additional fields */ }; @@ -4357,7 +4452,7 @@ struct sqlite3_vtab_cursor { ** to declare the format (the names and datatypes of the columns) of ** the virtual tables they implement. */ -SQLITE_EXPERIMENTAL int sqlite3_declare_vtab(sqlite3*, const char *zSQL); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_declare_vtab(sqlite3*, const char *zSQL); /* ** CAPI3REF: Overload A Function For A Virtual Table {H18300} @@ -4376,7 +4471,7 @@ SQLITE_EXPERIMENTAL int sqlite3_declare_vtab(sqlite3*, const char *zSQL); ** purpose is to be a placeholder function that can be overloaded ** by a [virtual table]. */ -SQLITE_EXPERIMENTAL int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_overload_function(sqlite3*, const char *zFuncName, int nArg); /* ** The interface to the virtual-table mechanism defined above (back up @@ -4417,6 +4512,9 @@ typedef struct sqlite3_blob sqlite3_blob; ** ** If the flags parameter is non-zero, then the BLOB is opened for read ** and write access. If it is zero, the BLOB is opened for read access. +** It is not possible to open a column that is part of an index or primary +** key for writing. ^If [foreign key constraints] are enabled, it is +** not possible to open a column that is part of a [child key] for writing. ** ** Note that the database name is not the filename that contains ** the database but rather the symbolic name of the database that @@ -4446,7 +4544,7 @@ typedef struct sqlite3_blob sqlite3_blob; ** ** Use the [sqlite3_blob_bytes()] interface to determine the size of ** the opened blob. The size of a blob may not be changed by this -** underface. Use the [UPDATE] SQL command to change the size of a +** interface. Use the [UPDATE] SQL command to change the size of a ** blob. ** ** The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces @@ -4460,7 +4558,7 @@ typedef struct sqlite3_blob sqlite3_blob; ** Requirements: ** [H17813] [H17814] [H17816] [H17819] [H17821] [H17824] */ -int sqlite3_blob_open( +SQLITE_API int sqlite3_blob_open( sqlite3*, const char *zDb, const char *zTable, @@ -4495,7 +4593,7 @@ int sqlite3_blob_open( ** Requirements: ** [H17833] [H17836] [H17839] */ -int sqlite3_blob_close(sqlite3_blob *); +SQLITE_API int sqlite3_blob_close(sqlite3_blob *); /* ** CAPI3REF: Return The Size Of An Open BLOB {H17840} @@ -4513,7 +4611,7 @@ int sqlite3_blob_close(sqlite3_blob *); ** Requirements: ** [H17843] */ -int sqlite3_blob_bytes(sqlite3_blob *); +SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *); /* ** CAPI3REF: Read Data From A BLOB Incrementally {H17850} @@ -4544,7 +4642,7 @@ int sqlite3_blob_bytes(sqlite3_blob *); ** Requirements: ** [H17853] [H17856] [H17859] [H17862] [H17863] [H17865] [H17868] */ -int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); +SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); /* ** CAPI3REF: Write Data Into A BLOB Incrementally {H17870} @@ -4586,7 +4684,7 @@ int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset); ** [H17873] [H17874] [H17875] [H17876] [H17877] [H17879] [H17882] [H17885] ** [H17888] */ -int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); +SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); /* ** CAPI3REF: Virtual File System Objects {H11200} @@ -4620,9 +4718,9 @@ int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset); ** Requirements: ** [H11203] [H11206] [H11209] [H11212] [H11215] [H11218] */ -sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); -int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); -int sqlite3_vfs_unregister(sqlite3_vfs*); +SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfsName); +SQLITE_API int sqlite3_vfs_register(sqlite3_vfs*, int makeDflt); +SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs*); /* ** CAPI3REF: Mutexes {H17000} @@ -4686,7 +4784,7 @@ int sqlite3_vfs_unregister(sqlite3_vfs*); ** might return such a mutex in response to SQLITE_MUTEX_FAST. ** ** {H17017} The other allowed parameters to sqlite3_mutex_alloc() each return -** a pointer to a static preexisting mutex. {END} Four static mutexes are +** a pointer to a static preexisting mutex. {END} Six static mutexes are ** used by the current version of SQLite. Future versions of SQLite ** may add additional static mutexes. Static mutexes are for internal ** use by SQLite only. Applications that use SQLite mutexes should @@ -4736,11 +4834,11 @@ int sqlite3_vfs_unregister(sqlite3_vfs*); ** ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. */ -sqlite3_mutex *sqlite3_mutex_alloc(int); -void sqlite3_mutex_free(sqlite3_mutex*); -void sqlite3_mutex_enter(sqlite3_mutex*); -int sqlite3_mutex_try(sqlite3_mutex*); -void sqlite3_mutex_leave(sqlite3_mutex*); +SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int); +SQLITE_API void sqlite3_mutex_free(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_try(sqlite3_mutex*); +SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*); /* ** CAPI3REF: Mutex Methods Object {H17120} @@ -4792,6 +4890,21 @@ void sqlite3_mutex_leave(sqlite3_mutex*); ** of passing a NULL pointer instead of a valid mutex handle are undefined ** (i.e. it is acceptable to provide an implementation that segfaults if ** it is passed a NULL pointer). +** +** The xMutexInit() method must be threadsafe. It must be harmless to +** invoke xMutexInit() mutiple times within the same process and without +** intervening calls to xMutexEnd(). Second and subsequent calls to +** xMutexInit() must be no-ops. +** +** xMutexInit() must not use SQLite memory allocation ([sqlite3_malloc()] +** and its associates). Similarly, xMutexAlloc() must not use SQLite memory +** allocation for a static mutex. However xMutexAlloc() may use SQLite +** memory allocation for a fast or recursive mutex. +** +** SQLite will invoke the xMutexEnd() method when [sqlite3_shutdown()] is +** called, but only if the prior call to xMutexInit returned SQLITE_OK. +** If xMutexInit fails in any way, it is expected to clean up after itself +** prior to returning. */ typedef struct sqlite3_mutex_methods sqlite3_mutex_methods; struct sqlite3_mutex_methods { @@ -4835,8 +4948,8 @@ struct sqlite3_mutex_methods { ** the appropriate thing to do. {H17086} The sqlite3_mutex_notheld() ** interface should also return 1 when given a NULL pointer. */ -int sqlite3_mutex_held(sqlite3_mutex*); -int sqlite3_mutex_notheld(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*); +SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex*); /* ** CAPI3REF: Mutex Types {H17001} @@ -4867,7 +4980,7 @@ int sqlite3_mutex_notheld(sqlite3_mutex*); ** If the [threading mode] is Single-thread or Multi-thread then this ** routine returns a NULL pointer. */ -sqlite3_mutex *sqlite3_db_mutex(sqlite3*); +SQLITE_API sqlite3_mutex *sqlite3_db_mutex(sqlite3*); /* ** CAPI3REF: Low-Level Control Of Database Files {H11300} @@ -4893,7 +5006,7 @@ sqlite3_mutex *sqlite3_db_mutex(sqlite3*); ** ** See also: [SQLITE_FCNTL_LOCKSTATE] */ -int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); +SQLITE_API int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); /* ** CAPI3REF: Testing Interface {H11400} @@ -4912,7 +5025,7 @@ int sqlite3_file_control(sqlite3*, const char *zDbName, int op, void*); ** Unlike most of the SQLite API, this function is not guaranteed to ** operate consistently from one release to the next. */ -int sqlite3_test_control(int op, ...); +SQLITE_API int sqlite3_test_control(int op, ...); /* ** CAPI3REF: Testing Interface Operation Codes {H11410} @@ -4934,6 +5047,7 @@ int sqlite3_test_control(int op, ...); #define SQLITE_TESTCTRL_PENDING_BYTE 11 #define SQLITE_TESTCTRL_ASSERT 12 #define SQLITE_TESTCTRL_ALWAYS 13 +#define SQLITE_TESTCTRL_RESERVE 14 /* ** CAPI3REF: SQLite Runtime Status {H17200} @@ -4956,7 +5070,7 @@ int sqlite3_test_control(int op, ...); ** This routine returns SQLITE_OK on success and a non-zero ** [error code] on failure. ** -** This routine is threadsafe but is not atomic. This routine can +** This routine is threadsafe but is not atomic. This routine can be ** called while other threads are running the same or different SQLite ** interfaces. However the values returned in *pCurrent and ** *pHighwater reflect the status of SQLite at different points in time @@ -4965,7 +5079,7 @@ int sqlite3_test_control(int op, ...); ** ** See also: [sqlite3_db_status()] */ -SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag); /* @@ -5073,13 +5187,20 @@ SQLITE_EXPERIMENTAL int sqlite3_status(int op, int *pCurrent, int *pHighwater, i ** ** See also: [sqlite3_status()] and [sqlite3_stmt_status()]. */ -SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int resetFlg); /* ** CAPI3REF: Status Parameters for database connections {H17520} ** EXPERIMENTAL ** -** Status verbs for [sqlite3_db_status()]. +** These constants are the available integer "verbs" that can be passed as +** the second argument to the [sqlite3_db_status()] interface. +** +** New verbs may be added in future releases of SQLite. Existing verbs +** might be discontinued. Applications should check the return code from +** [sqlite3_db_status()] to make sure that the call worked. +** The [sqlite3_db_status()] interface will return a non-zero error code +** if a discontinued or unsupported verb is invoked. ** **
    **
    SQLITE_DBSTATUS_LOOKASIDE_USED
    @@ -5114,7 +5235,7 @@ SQLITE_EXPERIMENTAL int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiw ** ** See also: [sqlite3_status()] and [sqlite3_db_status()]. */ -SQLITE_EXPERIMENTAL int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); +SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg); /* ** CAPI3REF: Status Parameters for prepared statements {H17570} @@ -5157,95 +5278,109 @@ typedef struct sqlite3_pcache sqlite3_pcache; /* ** CAPI3REF: Application Defined Page Cache. +** KEYWORDS: {page cache} ** EXPERIMENTAL ** ** The [sqlite3_config]([SQLITE_CONFIG_PCACHE], ...) interface can ** register an alternative page cache implementation by passing in an ** instance of the sqlite3_pcache_methods structure. The majority of the -** heap memory used by sqlite is used by the page cache to cache data read +** heap memory used by SQLite is used by the page cache to cache data read ** from, or ready to be written to, the database file. By implementing a ** custom page cache using this API, an application can control more -** precisely the amount of memory consumed by sqlite, the way in which -** said memory is allocated and released, and the policies used to +** precisely the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to ** determine exactly which parts of a database file are cached and for ** how long. ** -** The contents of the structure are copied to an internal buffer by sqlite -** within the call to [sqlite3_config]. +** The contents of the sqlite3_pcache_methods structure are copied to an +** internal buffer by SQLite within the call to [sqlite3_config]. Hence +** the application may discard the parameter after the call to +** [sqlite3_config()] returns. ** ** The xInit() method is called once for each call to [sqlite3_initialize()] ** (usually only once during the lifetime of the process). It is passed ** a copy of the sqlite3_pcache_methods.pArg value. It can be used to set ** up global structures and mutexes required by the custom page cache -** implementation. The xShutdown() method is called from within -** [sqlite3_shutdown()], if the application invokes this API. It can be used -** to clean up any outstanding resources before process shutdown, if required. +** implementation. +** +** The xShutdown() method is called from within [sqlite3_shutdown()], +** if the application invokes this API. It can be used to clean up +** any outstanding resources before process shutdown, if required. +** +** SQLite holds a [SQLITE_MUTEX_RECURSIVE] mutex when it invokes +** the xInit method, so the xInit method need not be threadsafe. The +** xShutdown method is only called from [sqlite3_shutdown()] so it does +** not need to be threadsafe either. All other methods must be threadsafe +** in multithreaded applications. +** +** SQLite will never invoke xInit() more than once without an intervening +** call to xShutdown(). ** -** The xCreate() method is used to construct a new cache instance. The +** The xCreate() method is used to construct a new cache instance. SQLite +** will typically create one cache instance for each open database file, +** though this is not guaranteed. The ** first parameter, szPage, is the size in bytes of the pages that must -** be allocated by the cache. szPage will not be a power of two. The -** second argument, bPurgeable, is true if the cache being created will -** be used to cache database pages read from a file stored on disk, or +** be allocated by the cache. szPage will not be a power of two. szPage +** will the page size of the database file that is to be cached plus an +** increment (here called "R") of about 100 or 200. SQLite will use the +** extra R bytes on each page to store metadata about the underlying +** database page on disk. The value of R depends +** on the SQLite version, the target platform, and how SQLite was compiled. +** R is constant for a particular build of SQLite. The second argument to +** xCreate(), bPurgeable, is true if the cache being created will +** be used to cache database pages of a file stored on disk, or ** false if it is used for an in-memory database. The cache implementation -** does not have to do anything special based on the value of bPurgeable, -** it is purely advisory. +** does not have to do anything special based with the value of bPurgeable; +** it is purely advisory. On a cache where bPurgeable is false, SQLite will +** never invoke xUnpin() except to deliberately delete a page. +** In other words, a cache created with bPurgeable set to false will +** never contain any unpinned pages. ** ** The xCachesize() method may be called at any time by SQLite to set the ** suggested maximum cache-size (number of pages stored by) the cache ** instance passed as the first argument. This is the value configured using ** the SQLite "[PRAGMA cache_size]" command. As with the bPurgeable parameter, -** the implementation is not required to do anything special with this -** value, it is advisory only. +** the implementation is not required to do anything with this +** value; it is advisory only. ** ** The xPagecount() method should return the number of pages currently -** stored in the cache supplied as an argument. +** stored in the cache. ** ** The xFetch() method is used to fetch a page and return a pointer to it. ** A 'page', in this context, is a buffer of szPage bytes aligned at an ** 8-byte boundary. The page to be fetched is determined by the key. The ** mimimum key value is 1. After it has been retrieved using xFetch, the page -** is considered to be pinned. +** is considered to be "pinned". ** -** If the requested page is already in the page cache, then a pointer to -** the cached buffer should be returned with its contents intact. If the -** page is not already in the cache, then the expected behaviour of the -** cache is determined by the value of the createFlag parameter passed -** to xFetch, according to the following table: +** If the requested page is already in the page cache, then the page cache +** implementation must return a pointer to the page buffer with its content +** intact. If the requested page is not already in the cache, then the +** behavior of the cache implementation is determined by the value of the +** createFlag parameter passed to xFetch, according to the following table: ** ** -**
    createFlagExpected Behaviour -**
    0NULL should be returned. No new cache entry is created. -**
    1If createFlag is set to 1, this indicates that -** SQLite is holding pinned pages that can be unpinned -** by writing their contents to the database file (a -** relatively expensive operation). In this situation the -** cache implementation has two choices: it can return NULL, -** in which case SQLite will attempt to unpin one or more -** pages before re-requesting the same page, or it can -** allocate a new page and return a pointer to it. If a new -** page is allocated, then the first sizeof(void*) bytes of -** it (at least) must be zeroed before it is returned. -**
    2If createFlag is set to 2, then SQLite is not holding any -** pinned pages associated with the specific cache passed -** as the first argument to xFetch() that can be unpinned. The -** cache implementation should attempt to allocate a new -** cache entry and return a pointer to it. Again, the first -** sizeof(void*) bytes of the page should be zeroed before -** it is returned. If the xFetch() method returns NULL when -** createFlag==2, SQLite assumes that a memory allocation -** failed and returns SQLITE_NOMEM to the user. +**
    createFlag Behaviour when page is not already in cache +**
    0 Do not allocate a new page. Return NULL. +**
    1 Allocate a new page if it easy and convenient to do so. +** Otherwise return NULL. +**
    2 Make every effort to allocate a new page. Only return +** NULL if allocating a new page is effectively impossible. **
    ** +** SQLite will normally invoke xFetch() with a createFlag of 0 or 1. If +** a call to xFetch() with createFlag==1 returns NULL, then SQLite will +** attempt to unpin one or more cache pages by spilling the content of +** pinned pages to disk and synching the operating system disk cache. After +** attempting to unpin pages, the xFetch() method will be invoked again with +** a createFlag of 2. +** ** xUnpin() is called by SQLite with a pointer to a currently pinned page ** as its second argument. If the third parameter, discard, is non-zero, ** then the page should be evicted from the cache. In this case SQLite ** assumes that the next time the page is retrieved from the cache using ** the xFetch() method, it will be zeroed. If the discard parameter is ** zero, then the page is considered to be unpinned. The cache implementation -** may choose to reclaim (free or recycle) unpinned pages at any time. -** SQLite assumes that next time the page is retrieved from the cache -** it will either be zeroed, or contain the same data that it did when it -** was unpinned. +** may choose to evict unpinned pages at any time. ** ** The cache is not required to perform any reference counting. A single ** call to xUnpin() unpins the page regardless of the number of prior calls @@ -5469,16 +5604,16 @@ typedef struct sqlite3_backup sqlite3_backup; ** same time as another thread is invoking sqlite3_backup_step() it is ** possible that they return invalid values. */ -sqlite3_backup *sqlite3_backup_init( +SQLITE_API sqlite3_backup *sqlite3_backup_init( sqlite3 *pDest, /* Destination database handle */ const char *zDestName, /* Destination database name */ sqlite3 *pSource, /* Source database handle */ const char *zSourceName /* Source database name */ ); -int sqlite3_backup_step(sqlite3_backup *p, int nPage); -int sqlite3_backup_finish(sqlite3_backup *p); -int sqlite3_backup_remaining(sqlite3_backup *p); -int sqlite3_backup_pagecount(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_step(sqlite3_backup *p, int nPage); +SQLITE_API int sqlite3_backup_finish(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_remaining(sqlite3_backup *p); +SQLITE_API int sqlite3_backup_pagecount(sqlite3_backup *p); /* ** CAPI3REF: Unlock Notification @@ -5595,12 +5730,24 @@ int sqlite3_backup_pagecount(sqlite3_backup *p); ** the special "DROP TABLE/INDEX" case, the extended error code is just ** SQLITE_LOCKED. */ -int sqlite3_unlock_notify( +SQLITE_API int sqlite3_unlock_notify( sqlite3 *pBlocked, /* Waiting connection */ void (*xNotify)(void **apArg, int nArg), /* Callback function to invoke */ void *pNotifyArg /* Argument to pass to xNotify */ ); + +/* +** CAPI3REF: String Comparison +** EXPERIMENTAL +** +** The [sqlite3_strnicmp()] API allows applications and extensions to +** compare the contents of two buffers containing UTF-8 strings in a +** case-indendent fashion, using the same definition of case independence +** that SQLite uses internally when comparing identifiers. +*/ +SQLITE_API int sqlite3_strnicmp(const char *, const char *, int); + /* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. @@ -5613,3 +5760,4 @@ int sqlite3_unlock_notify( } /* End of the 'extern "C"' block */ #endif #endif + diff --git a/ext/sqlite3/libsqlite/sqlite3ext.h b/ext/sqlite3/libsqlite/sqlite3ext.h index a42f51d4f..102aaeac8 100644 --- a/ext/sqlite3/libsqlite/sqlite3ext.h +++ b/ext/sqlite3/libsqlite/sqlite3ext.h @@ -15,7 +15,7 @@ ** as extensions by SQLite should #include this file instead of ** sqlite3.h. ** -** @(#) $Id: sqlite3ext.h,v 1.1.2.18 2009/06/15 13:23:59 scottmac Exp $ +** @(#) $Id: sqlite3ext.h 283115 2009-06-30 11:17:14Z scottmac $ */ #ifndef _SQLITE3EXT_H_ #define _SQLITE3EXT_H_ diff --git a/ext/sqlite3/php_sqlite3.h b/ext/sqlite3/php_sqlite3.h index 234087cb4..48f2afdb6 100644 --- a/ext/sqlite3/php_sqlite3.h +++ b/ext/sqlite3/php_sqlite3.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_sqlite3.h,v 1.1.2.6 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: php_sqlite3.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SQLITE3_H #define PHP_SQLITE3_H diff --git a/ext/sqlite3/php_sqlite3_structs.h b/ext/sqlite3/php_sqlite3_structs.h index b3637c1b4..866871e75 100644 --- a/ext/sqlite3/php_sqlite3_structs.h +++ b/ext/sqlite3/php_sqlite3_structs.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_sqlite3_structs.h,v 1.1.2.8 2009/04/27 18:16:46 scottmac Exp $ */ +/* $Id: php_sqlite3_structs.h 279456 2009-04-27 18:16:46Z scottmac $ */ #ifndef PHP_SQLITE_STRUCTS_H #define PHP_SQLITE_STRUCTS_H diff --git a/ext/sqlite3/sqlite3.c b/ext/sqlite3/sqlite3.c index a85957cff..70fab57ce 100644 --- a/ext/sqlite3/sqlite3.c +++ b/ext/sqlite3/sqlite3.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sqlite3.c,v 1.1.2.39 2009/06/08 02:15:54 scottmac Exp $ */ +/* $Id: sqlite3.c 281793 2009-06-08 02:15:54Z scottmac $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/sqlite3/tests/sqlite3_32_createAggregate_paramCount.phpt b/ext/sqlite3/tests/sqlite3_32_createAggregate_paramCount.phpt index 47139cd7d..8a05c5753 100644 --- a/ext/sqlite3/tests/sqlite3_32_createAggregate_paramCount.phpt +++ b/ext/sqlite3/tests/sqlite3_32_createAggregate_paramCount.phpt @@ -1,6 +1,6 @@ --TEST-- SQLite3::createAggregate Test that an error is thrown when no parameters are present ---CREDIT-- +--CREDITS-- James Cauwelier # Belgium PHP TestFest --SKIPIF-- diff --git a/ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt b/ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt index 137b96977..7a1bb2831 100644 --- a/ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt +++ b/ext/sqlite3/tests/sqlite3_33_createAggregate_notcallable.phpt @@ -1,6 +1,6 @@ --TEST-- SQLite3::createAggregate() Test whether a supplied PHP function is valid when using in an aggregate function ---CREDIT-- +--CREDITS-- James Cauwelier # Belgium PHP TestFest (2009) --SKIPIF-- diff --git a/ext/standard/array.c b/ext/standard/array.c index 5bfc308e4..457f8b1ce 100644 --- a/ext/standard/array.c +++ b/ext/standard/array.c @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: array.c,v 1.308.2.21.2.37.2.56 2009/05/15 17:03:03 moriyoshi Exp $ */ +/* $Id: array.c 287275 2009-08-14 06:20:21Z dmitry $ */ #include "php.h" #include "php_ini.h" @@ -629,6 +629,7 @@ static int php_array_user_compare(const void *a, const void *b TSRMLS_DC) /* {{{ PHP_FUNCTION(usort) { zval *array; + int refcount; PHP_ARRAY_CMP_FUNC_VARS; PHP_ARRAY_CMP_FUNC_BACKUP(); @@ -638,12 +639,31 @@ PHP_FUNCTION(usort) return; } + /* Clear the is_ref flag, so the attemts to modify the array in user + * comaprison function will create a copy of array and won't affect the + * original array. The fact of modification is detected using refcount + * comparison. The result of sorting in such case is undefined and the + * function returns FALSE. + */ + Z_UNSET_ISREF_P(array); + refcount = Z_REFCOUNT_P(array); + if (zend_hash_sort(Z_ARRVAL_P(array), zend_qsort, php_array_user_compare, 1 TSRMLS_CC) == FAILURE) { - PHP_ARRAY_CMP_FUNC_RESTORE(); - RETURN_FALSE; + RETVAL_FALSE; + } else { + if (refcount > Z_REFCOUNT_P(array)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array was modified by the user comparison function"); + RETVAL_FALSE; + } else { + RETVAL_TRUE; + } + } + + if (Z_REFCOUNT_P(array) > 1) { + Z_SET_ISREF_P(array); } + PHP_ARRAY_CMP_FUNC_RESTORE(); - RETURN_TRUE; } /* }}} */ @@ -652,6 +672,7 @@ PHP_FUNCTION(usort) PHP_FUNCTION(uasort) { zval *array; + int refcount; PHP_ARRAY_CMP_FUNC_VARS; PHP_ARRAY_CMP_FUNC_BACKUP(); @@ -661,12 +682,31 @@ PHP_FUNCTION(uasort) return; } + /* Clear the is_ref flag, so the attemts to modify the array in user + * comaprison function will create a copy of array and won't affect the + * original array. The fact of modification is detected using refcount + * comparison. The result of sorting in such case is undefined and the + * function returns FALSE. + */ + Z_UNSET_ISREF_P(array); + refcount = Z_REFCOUNT_P(array); + if (zend_hash_sort(Z_ARRVAL_P(array), zend_qsort, php_array_user_compare, 0 TSRMLS_CC) == FAILURE) { - PHP_ARRAY_CMP_FUNC_RESTORE(); - RETURN_FALSE; + RETVAL_FALSE; + } else { + if (refcount > Z_REFCOUNT_P(array)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Array was modified by the user comparison function"); + RETVAL_FALSE; + } else { + RETVAL_TRUE; + } + } + + if (Z_REFCOUNT_P(array) > 1) { + Z_SET_ISREF_P(array); } + PHP_ARRAY_CMP_FUNC_RESTORE(); - RETURN_TRUE; } /* }}} */ @@ -2305,6 +2345,7 @@ static void php_array_merge_or_replace_wrapper(INTERNAL_FUNCTION_PARAMETERS, int array_init_size(return_value, init_size); for (i = 0; i < argc; i++) { + SEPARATE_ZVAL(args[i]); if (!replace) { php_array_merge(Z_ARRVAL_P(return_value), Z_ARRVAL_PP(args[i]), recursive TSRMLS_CC); } else if (recursive && i > 0) { /* First array will be copied directly instead */ diff --git a/ext/standard/assert.c b/ext/standard/assert.c index 200ffb5f4..af5ffff85 100644 --- a/ext/standard/assert.c +++ b/ext/standard/assert.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: assert.c,v 1.60.2.3.2.6.2.6 2009/06/05 18:50:32 mattwil Exp $ */ +/* $Id: assert.c 284153 2009-07-15 23:55:50Z stas $ */ /* {{{ includes */ #include "php.h" @@ -56,6 +56,7 @@ static PHP_INI_MH(OnChangeCallback) /* {{{ */ if (EG(in_execution)) { if (ASSERTG(callback)) { zval_ptr_dtor(&ASSERTG(callback)); + ASSERTG(callback) = NULL; } if (new_value && (ASSERTG(callback) || new_value_length)) { MAKE_STD_ZVAL(ASSERTG(callback)); diff --git a/ext/standard/base64.c b/ext/standard/base64.c index 84267af92..42f5c5302 100644 --- a/ext/standard/base64.c +++ b/ext/standard/base64.c @@ -15,7 +15,7 @@ | Author: Jim Winstead | +----------------------------------------------------------------------+ */ -/* $Id: base64.c,v 1.43.2.2.2.3.2.6 2009/01/25 18:27:11 iliaa Exp $ */ +/* $Id: base64.c 274569 2009-01-25 18:27:12Z iliaa $ */ #include diff --git a/ext/standard/base64.h b/ext/standard/base64.h index ef65b6ac6..4f43dbb69 100644 --- a/ext/standard/base64.h +++ b/ext/standard/base64.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: base64.h,v 1.14.2.1.2.2.2.2 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: base64.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef BASE64_H #define BASE64_H diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index d3364ed49..f7b394a04 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -1,4 +1,3 @@ - /* +----------------------------------------------------------------------+ | PHP Version 5 | @@ -18,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.c,v 1.725.2.31.2.64.2.92 2009/06/20 06:07:35 kalle Exp $ */ +/* $Id: basic_functions.c 289669 2009-10-15 14:10:03Z pajoye $ */ #include "php.h" #include "php_streams.h" @@ -33,7 +32,7 @@ #include "ext/standard/info.h" #include "ext/session/php_session.h" #include "zend_operators.h" -#include "ext/standard/dns.h" +#include "ext/standard/php_dns.h" #include "ext/standard/php_uuencode.h" #include "safe_mode.h" @@ -996,22 +995,20 @@ ZEND_BEGIN_ARG_INFO(arginfo_gethostname, 0) ZEND_END_ARG_INFO() #endif -#if defined(PHP_WIN32) || (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE))) +#if defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE))) ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_check_record, 0, 0, 1) ZEND_ARG_INFO(0, host) ZEND_ARG_INFO(0, type) ZEND_END_ARG_INFO() -# if defined(PHP_WIN32) || HAVE_DNS_FUNCS +# if defined(PHP_WIN32) || HAVE_FULL_DNS_FUNCS ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_record, 1, 0, 1) ZEND_ARG_INFO(0, hostname) ZEND_ARG_INFO(0, type) ZEND_ARG_INFO(1, authns) /* ARRAY_INFO(1, authns, 1) */ ZEND_ARG_INFO(1, addtl) /* ARRAY_INFO(1, addtl, 1) */ ZEND_END_ARG_INFO() -# endif -# if defined(PHP_WIN32) || (HAVE_DN_SKIPNAME && HAVE_DN_EXPAND) ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_mx, 0, 0, 2) ZEND_ARG_INFO(0, hostname) ZEND_ARG_INFO(1, mxhosts) /* ARRAY_INFO(1, mxhosts, 1) */ @@ -1019,7 +1016,7 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_mx, 0, 0, 2) ZEND_END_ARG_INFO() # endif -#endif /* defined(PHP_WIN32) || (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE))) */ +#endif /* defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE))) */ /* }}} */ /* {{{ exec.c */ @@ -3001,17 +2998,14 @@ const zend_function_entry basic_functions[] = { /* {{{ */ PHP_FE(gethostname, arginfo_gethostname) #endif -#if defined(PHP_WIN32) || (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE))) +#if defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE))) PHP_FE(dns_check_record, arginfo_dns_check_record) PHP_FALIAS(checkdnsrr, dns_check_record, arginfo_dns_check_record) -# if defined(PHP_WIN32) || (HAVE_DN_SKIPNAME && HAVE_DN_EXPAND) +# if defined(PHP_WIN32) || HAVE_FULL_DNS_FUNCS PHP_FE(dns_get_mx, arginfo_dns_get_mx) PHP_FALIAS(getmxrr, dns_get_mx, arginfo_dns_get_mx) -# endif - -# if defined(PHP_WIN32) || HAVE_DNS_FUNCS PHP_FE(dns_get_record, arginfo_dns_get_record) # endif #endif @@ -3462,7 +3456,6 @@ static void basic_globals_ctor(php_basic_globals *basic_globals_p TSRMLS_DC) /* zend_hash_init(&BG(sm_protected_env_vars), 5, NULL, NULL, 1); BG(sm_allowed_env_vars) = NULL; - memset(&BG(url_adapt_state), 0, sizeof(BG(url_adapt_state))); memset(&BG(url_adapt_state_ex), 0, sizeof(BG(url_adapt_state_ex))); #if defined(_REENTRANT) && defined(HAVE_MBRLEN) && defined(HAVE_MBSTATE_T) @@ -3641,8 +3634,8 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ php_register_url_stream_wrapper("ftp", &php_stream_ftp_wrapper TSRMLS_CC); #endif -#if defined(PHP_WIN32) || (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE))) -# if defined(PHP_WIN32) || HAVE_DNS_FUNCS +#if defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE))) +# if defined(PHP_WIN32) || HAVE_FULL_DNS_FUNCS PHP_MINIT(dns)(INIT_FUNC_ARGS_PASSTHRU); # endif #endif @@ -3685,7 +3678,9 @@ PHP_MSHUTDOWN_FUNCTION(basic) /* {{{ */ #if defined(HAVE_LOCALECONV) && defined(ZTS) PHP_MSHUTDOWN(localeconv)(SHUTDOWN_FUNC_ARGS_PASSTHRU); #endif +#if HAVE_CRYPT PHP_MSHUTDOWN(crypt)(SHUTDOWN_FUNC_ARGS_PASSTHRU); +#endif return SUCCESS; } @@ -3937,6 +3932,9 @@ PHP_FUNCTION(long2ip) int ip_len; unsigned long n; struct in_addr myaddr; +#ifdef HAVE_INET_PTON + char str[40]; +#endif if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &ip, &ip_len) == FAILURE) { return; @@ -3945,7 +3943,15 @@ PHP_FUNCTION(long2ip) n = strtoul(ip, NULL, 0); myaddr.s_addr = htonl(n); +#ifdef HAVE_INET_PTON + if (inet_ntop(AF_INET, &myaddr, str, sizeof(str))) { + RETURN_STRING(str, 1); + } else { + RETURN_FALSE; + } +#else RETURN_STRING(inet_ntoa(myaddr), 1); +#endif } /* }}} */ @@ -6042,6 +6048,7 @@ PHP_FUNCTION(import_request_variables) int types_len; zval *prefix = NULL; char *p; + zend_bool ok = 0; if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z/", &types, &types_len, &prefix) == FAILURE) { return; @@ -6064,17 +6071,20 @@ PHP_FUNCTION(import_request_variables) case 'g': case 'G': zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_GET]) TSRMLS_CC, (apply_func_args_t) copy_request_variable, 1, prefix); + ok = 1; break; case 'p': case 'P': zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_POST]) TSRMLS_CC, (apply_func_args_t) copy_request_variable, 1, prefix); zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_FILES]) TSRMLS_CC, (apply_func_args_t) copy_request_variable, 1, prefix); + ok = 1; break; case 'c': case 'C': zend_hash_apply_with_arguments(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_COOKIE]) TSRMLS_CC, (apply_func_args_t) copy_request_variable, 1, prefix); + ok = 1; break; } } @@ -6082,6 +6092,7 @@ PHP_FUNCTION(import_request_variables) if (ZEND_NUM_ARGS() < 2) { zval_ptr_dtor(&prefix); } + RETURN_BOOL(ok); } /* }}} */ diff --git a/ext/standard/basic_functions.h b/ext/standard/basic_functions.h index e821d5997..bc18f073b 100644 --- a/ext/standard/basic_functions.h +++ b/ext/standard/basic_functions.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: basic_functions.h,v 1.139.2.4.2.6.2.11 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: basic_functions.h 286378 2009-07-26 22:59:46Z jani $ */ #ifndef BASIC_FUNCTIONS_H #define BASIC_FUNCTIONS_H @@ -32,7 +32,6 @@ #include "zend_highlight.h" -#include "url_scanner.h" #include "url_scanner_ex.h" extern zend_module_entry basic_functions_module; @@ -207,8 +206,6 @@ typedef struct _php_basic_globals { /* var.c */ zend_class_entry *incomplete_class; - /* url_scanner.c */ - url_adapt_state_t url_adapt_state; /* url_scanner_ex.re */ url_adapt_state_ex_t url_adapt_state_ex; diff --git a/ext/standard/browscap.c b/ext/standard/browscap.c index 4b52ab5f2..c0b202979 100644 --- a/ext/standard/browscap.c +++ b/ext/standard/browscap.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: browscap.c,v 1.85.2.2.2.3.2.12 2009/06/06 02:40:48 mattwil Exp $ */ +/* $Id: browscap.c 281742 2009-06-06 02:40:49Z mattwil $ */ #include "php.h" #include "php_browscap.h" diff --git a/ext/standard/config.m4 b/ext/standard/config.m4 index faec8d855..7ccec319b 100644 --- a/ext/standard/config.m4 +++ b/ext/standard/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.80.2.3.2.3.2.8 2009/01/11 23:37:16 scottmac Exp $ -*- autoconf -*- +dnl $Id: config.m4 287120 2009-08-11 22:07:35Z scottmac $ -*- autoconf -*- divert(3)dnl @@ -247,21 +247,18 @@ fi dnl dnl Detect library functions needed by php dns_xxx functions -dnl ext/standard/dns.h will collect these in a single define: HAVE_DNS_FUNCS +dnl ext/standard/php_dns.h will collect these in a single define: HAVE_FULL_DNS_FUNCS dnl -PHP_CHECK_FUNC(res_nmkquery, resolv, bind, socket) -PHP_CHECK_FUNC(res_nsend, resolv, bind, socket) -PHP_CHECK_FUNC(res_search, resolv, bind, socket) +PHP_CHECK_FUNC(res_nsearch, resolv, bind, socket) +PHP_CHECK_FUNC(dns_search, resolv, bind, socket) PHP_CHECK_FUNC(dn_expand, resolv, bind, socket) PHP_CHECK_FUNC(dn_skipname, resolv, bind, socket) dnl -dnl These are old deprecated functions, a single define of HAVE_DEPRECATED_DNS_FUNCS -dnl will be set in ext/standard/dns.h +dnl These are old deprecated functions dnl -PHP_CHECK_FUNC(res_mkquery, resolv, bind, socket) -PHP_CHECK_FUNC(res_send, resolv, bind, socket) +PHP_CHECK_FUNC(res_search, resolv, bind, socket) dnl dnl Check if atof() accepts NAN @@ -457,7 +454,7 @@ PHP_NEW_EXTENSION(standard, array.c base64.c basic_functions.c browscap.c crc32. info.c iptc.c lcg.c link.c mail.c math.c md5.c metaphone.c \ microtime.c pack.c pageinfo.c quot_print.c rand.c \ soundex.c string.c scanf.c syslog.c type.c uniqid.c url.c \ - url_scanner.c var.c versioning.c assert.c strnatcmp.c levenshtein.c \ + var.c versioning.c assert.c strnatcmp.c levenshtein.c \ incomplete_class.c url_scanner_ex.c ftp_fopen_wrapper.c \ http_fopen_wrapper.c php_fopen_wrapper.c credits.c css.c \ var_unserializer.c ftok.c sha1.c user_filters.c uuencode.c \ diff --git a/ext/standard/config.w32 b/ext/standard/config.w32 index dee3e7c8d..c72a8aa85 100644 --- a/ext/standard/config.w32 +++ b/ext/standard/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.4.2.2.2.1.2.7 2009/06/23 06:56:45 kalle Exp $ +// $Id: config.w32 286378 2009-07-26 22:59:46Z jani $ ARG_WITH("config-file-scan-dir", "Dir to check for additional php ini files", ""); @@ -15,7 +15,7 @@ EXTENSION("standard", "array.c base64.c basic_functions.c browscap.c \ file.c filestat.c formatted_print.c fsock.c head.c html.c image.c \ info.c iptc.c lcg.c link_win32.c mail.c math.c md5.c metaphone.c microtime.c \ pack.c pageinfo.c quot_print.c rand.c soundex.c \ - string.c scanf.c syslog.c type.c uniqid.c url.c url_scanner.c var.c \ + string.c scanf.c syslog.c type.c uniqid.c url.c var.c \ versioning.c assert.c strnatcmp.c levenshtein.c incomplete_class.c \ url_scanner_ex.c ftp_fopen_wrapper.c http_fopen_wrapper.c \ php_fopen_wrapper.c credits.c css.c var_unserializer.c ftok.c sha1.c \ diff --git a/ext/standard/crc32.c b/ext/standard/crc32.c index a0ca2fd74..9afb56bf0 100644 --- a/ext/standard/crc32.c +++ b/ext/standard/crc32.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: crc32.c,v 1.16.2.4.2.1.2.2 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: crc32.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "basic_functions.h" diff --git a/ext/standard/crc32.h b/ext/standard/crc32.h index e6deb4b5f..140d04e9b 100644 --- a/ext/standard/crc32.h +++ b/ext/standard/crc32.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: crc32.h,v 1.6.2.1.2.1.2.2 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: crc32.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* * This code implements the AUTODIN II polynomial diff --git a/ext/standard/credits.c b/ext/standard/credits.c index 96535dd66..71998b8da 100644 --- a/ext/standard/credits.c +++ b/ext/standard/credits.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: credits.c,v 1.36.2.4.2.4.2.8 2009/03/17 15:37:34 pajoye Exp $ */ +/* $Id: credits.c 289420 2009-10-09 14:34:18Z pajoye $ */ #include "php.h" #include "info.h" @@ -109,10 +109,17 @@ PHPAPI void php_print_credits(int flag TSRMLS_DC) /* {{{ */ } if (flag & PHP_CREDITS_WEB) { - /* Website Team */ + /* Websites and infrastructure */ + php_info_print_table_start(); - php_info_print_table_header(1, "PHP Website Team"); - php_info_print_table_row(1, "Rasmus Lerdorf, Hannes Magnusson, Philip Olson"); + php_info_print_table_colspan_header(2, "Websites and Infrastructure team"); + /* www., wiki., windows., master., and others, I guess pecl. too? */ + CREDIT_LINE("PHP Websites Team", "Rasmus Lerdorf, Hannes Magnusson, Philip Olson, Lukas Kahwe Smith, Pierre-Alain Joye, Kalle Sommer Nielsen"); + CREDIT_LINE("Event Maintainers", "Damien Seguy, Daniel P. Brown"); + /* Mirroring */ + CREDIT_LINE("Network Infrastructure", "Daniel P. Brown"); + /* Windows build boxes and such things */ + CREDIT_LINE("Windows Infrastructure", "Alex Schoenmaker"); php_info_print_table_end(); } diff --git a/ext/standard/credits.h b/ext/standard/credits.h index 793a0853d..3fff960f1 100644 --- a/ext/standard/credits.h +++ b/ext/standard/credits.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: credits.h,v 1.11.2.1.2.1.2.2 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: credits.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef CREDITS_H #define CREDITS_H diff --git a/ext/standard/crypt.c b/ext/standard/crypt.c index d3f7dca48..3743e1eb9 100644 --- a/ext/standard/crypt.c +++ b/ext/standard/crypt.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: crypt.c,v 1.62.2.1.2.6.2.6 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: crypt.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include diff --git a/ext/standard/crypt_blowfish.c b/ext/standard/crypt_blowfish.c index 6451089bc..a345fc0d8 100644 --- a/ext/standard/crypt_blowfish.c +++ b/ext/standard/crypt_blowfish.c @@ -1,5 +1,5 @@ /* - $Id: crypt_blowfish.c,v 1.1.2.4 2009/06/08 08:44:15 pajoye Exp $ + $Id: crypt_blowfish.c 281805 2009-06-08 08:44:15Z pajoye $ */ /* * This code comes from John the Ripper password cracker, with reentrant diff --git a/ext/standard/crypt_freesec.c b/ext/standard/crypt_freesec.c index e853fcab2..0d70772ad 100644 --- a/ext/standard/crypt_freesec.c +++ b/ext/standard/crypt_freesec.c @@ -1,5 +1,5 @@ /* - $Id: crypt_freesec.c,v 1.1.2.6 2008/08/25 13:42:54 jani Exp $ + $Id: crypt_freesec.c 265468 2008-08-25 13:42:55Z jani $ */ /* * This version is derived from the original implementation of FreeSec @@ -40,7 +40,7 @@ * SUCH DAMAGE. * * $Owl: Owl/packages/glibc/crypt_freesec.c,v 1.4 2005/11/16 13:08:32 solar Exp $ - * $Id: crypt_freesec.c,v 1.1.2.6 2008/08/25 13:42:54 jani Exp $ + * $Id: crypt_freesec.c 265468 2008-08-25 13:42:55Z jani $ * * This is an original implementation of the DES and the crypt(3) interfaces * by David Burren . diff --git a/ext/standard/crypt_freesec.h b/ext/standard/crypt_freesec.h index 139b3afed..c1d876eaf 100644 --- a/ext/standard/crypt_freesec.h +++ b/ext/standard/crypt_freesec.h @@ -1,4 +1,4 @@ -/* $Id: crypt_freesec.h,v 1.1.2.9 2008/08/25 14:37:07 pajoye Exp $ */ +/* $Id: crypt_freesec.h 265472 2008-08-25 14:37:07Z pajoye $ */ #ifndef _CRYPT_FREESEC_H #define _CRYPT_FREESEC_H diff --git a/ext/standard/css.c b/ext/standard/css.c index 274ca1489..5a62621e5 100644 --- a/ext/standard/css.c +++ b/ext/standard/css.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: css.c,v 1.13.2.1.2.1.2.3 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: css.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "info.h" diff --git a/ext/standard/css.h b/ext/standard/css.h index 72ed5a5de..855c21eed 100644 --- a/ext/standard/css.h +++ b/ext/standard/css.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: css.h,v 1.6.2.1.2.1.2.2 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: css.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef CSS_H #define CSS_H diff --git a/ext/standard/cyr_convert.c b/ext/standard/cyr_convert.c index 39d139029..3a847be18 100644 --- a/ext/standard/cyr_convert.c +++ b/ext/standard/cyr_convert.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: cyr_convert.c,v 1.27.2.3.2.1.2.3 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: cyr_convert.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include diff --git a/ext/standard/cyr_convert.h b/ext/standard/cyr_convert.h index df67ce2ad..74a1a3628 100644 --- a/ext/standard/cyr_convert.h +++ b/ext/standard/cyr_convert.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: cyr_convert.h,v 1.11.2.1.2.1.2.2 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: cyr_convert.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef CYR_CONVERT_H #define CYR_CONVERT_H diff --git a/ext/standard/datetime.c b/ext/standard/datetime.c index f65fc9675..6afd94569 100644 --- a/ext/standard/datetime.c +++ b/ext/standard/datetime.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: datetime.c,v 1.134.2.2.2.4.2.3 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: datetime.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "zend_operators.h" diff --git a/ext/standard/datetime.h b/ext/standard/datetime.h index 85516431c..a944f270c 100644 --- a/ext/standard/datetime.h +++ b/ext/standard/datetime.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: datetime.h,v 1.23.2.2.2.1.2.2 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: datetime.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef DATETIME_H #define DATETIME_H diff --git a/ext/standard/dir.c b/ext/standard/dir.c index 48f010001..f2b8d24cb 100644 --- a/ext/standard/dir.c +++ b/ext/standard/dir.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dir.c,v 1.147.2.3.2.12.2.13 2008/12/31 11:15:44 sebastian Exp $ */ +/* $Id: dir.c 286555 2009-07-30 12:06:40Z felipe $ */ /* {{{ includes/startup/misc */ @@ -556,7 +556,9 @@ PHP_FUNCTION(scandir) RETURN_FALSE; } - context = php_stream_context_from_zval(zcontext, 0); + if (zcontext) { + context = php_stream_context_from_zval(zcontext, 0); + } if (!flags) { n = php_stream_scandir(dirn, &namelist, context, (void *) php_stream_dirent_alphasort); diff --git a/ext/standard/dl.c b/ext/standard/dl.c index b0a5ae9be..37eda68a5 100644 --- a/ext/standard/dl.c +++ b/ext/standard/dl.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dl.c,v 1.106.2.1.2.5.2.11 2009/01/17 02:05:13 stas Exp $ */ +/* $Id: dl.c 286859 2009-08-06 01:33:54Z scottmac $ */ #include "php.h" #include "dl.h" @@ -28,7 +28,7 @@ #include "SAPI.h" -#if defined(HAVE_LIBDL) || HAVE_MACH_O_DYLD_H +#if defined(HAVE_LIBDL) #include #include #ifdef HAVE_STRING_H @@ -47,7 +47,7 @@ #include #define GET_DL_ERROR() DL_ERROR() #endif -#endif /* defined(HAVE_LIBDL) || HAVE_MACH_O_DYLD_H */ +#endif /* defined(HAVE_LIBDL) */ /* {{{ proto int dl(string extension_filename) Load a PHP extension at runtime */ @@ -92,7 +92,7 @@ PHPAPI PHP_FUNCTION(dl) } /* }}} */ -#if defined(HAVE_LIBDL) || HAVE_MACH_O_DYLD_H +#if defined(HAVE_LIBDL) #ifdef ZTS #define USING_ZTS 1 diff --git a/ext/standard/dl.h b/ext/standard/dl.h index 6f823641c..8d9ce1e84 100644 --- a/ext/standard/dl.h +++ b/ext/standard/dl.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dl.h,v 1.23.2.1.2.1.2.5 2008/12/31 18:55:22 helly Exp $ */ +/* $Id: dl.h 272444 2008-12-31 18:55:22Z helly $ */ #ifndef DL_H #define DL_H diff --git a/ext/standard/dns.c b/ext/standard/dns.c index 9cb50a40b..7507884e6 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: dns.c,v 1.70.2.7.2.5.2.24 2009/05/20 12:44:19 jani Exp $ */ +/* $Id: dns.c 287120 2009-08-11 22:07:35Z scottmac $ */ /* {{{ includes */ #include "php.h" @@ -46,9 +46,15 @@ #if HAVE_ARPA_NAMESER_H #include #endif +#if HAVE_ARPA_NAMESER_COMPAT_H +#include +#endif #if HAVE_RESOLV_H #include #endif +#ifdef HAVE_DNS_H +#include +#endif #endif /* Borrowed from SYS/SOCKET.H */ @@ -56,7 +62,7 @@ #define AF_INET 2 /* internetwork: UDP, TCP, etc. */ #endif -#include "dns.h" +#include "php_dns.h" /* type compat */ #ifndef DNS_T_A @@ -258,7 +264,7 @@ static char *php_gethostbyname(char *name) } /* }}} */ -#if HAVE_DNS_FUNCS || defined(PHP_WIN32) +#if HAVE_FULL_DNS_FUNCS || defined(PHP_WIN32) # define PHP_DNS_NUM_TYPES 12 /* Number of DNS Types Supported by PHP currently */ # define PHP_DNS_A 0x00000001 @@ -275,10 +281,51 @@ static char *php_gethostbyname(char *name) # define PHP_DNS_AAAA 0x08000000 # define PHP_DNS_ANY 0x10000000 # define PHP_DNS_ALL (PHP_DNS_A|PHP_DNS_NS|PHP_DNS_CNAME|PHP_DNS_SOA|PHP_DNS_PTR|PHP_DNS_HINFO|PHP_DNS_MX|PHP_DNS_TXT|PHP_DNS_A6|PHP_DNS_SRV|PHP_DNS_NAPTR|PHP_DNS_AAAA) -#endif /* HAVE_DNS_FUNCS || defined(PHP_WIN32) */ +#endif /* HAVE_FULL_DNS_FUNCS || defined(PHP_WIN32) */ /* Note: These functions are defined in ext/standard/dns_win32.c for Windows! */ -#if !defined(PHP_WIN32) && (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE))) +#if !defined(PHP_WIN32) && (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE))) + +#ifndef HFIXEDSZ +#define HFIXEDSZ 12 /* fixed data in header */ +#endif /* HFIXEDSZ */ + +#ifndef QFIXEDSZ +#define QFIXEDSZ 4 /* fixed data in query */ +#endif /* QFIXEDSZ */ + +#undef MAXHOSTNAMELEN +#define MAXHOSTNAMELEN 1024 + +#ifndef MAXRESOURCERECORDS +#define MAXRESOURCERECORDS 64 +#endif /* MAXRESOURCERECORDS */ + +typedef union { + HEADER qb1; + u_char qb2[65536]; +} querybuf; + +/* just a hack to free resources allocated by glibc in __res_nsend() + * See also: + * res_thread_freeres() in glibc/resolv/res_init.c + * __libc_res_nsend() in resolv/res_send.c + * */ + +#if defined(__GLIBC__) && !defined(HAVE_DEPRECATED_DNS_FUNCS) +#define php_dns_free_res(__res__) _php_dns_free_res(__res__) +static void _php_dns_free_res(struct __res_state res) { /* {{{ */ + int ns; + for (ns = 0; ns < MAXNS; ns++) { + if (res._u._ext.nsaddrs[ns] != NULL) { + free (res._u._ext.nsaddrs[ns]); + res._u._ext.nsaddrs[ns] = NULL; + } + } +} /* }}} */ +#else +#define php_dns_free_res(__res__) +#endif /* {{{ proto bool dns_check_record(string host [, string type]) Check DNS records corresponding to a given Internet host name or IP address */ @@ -291,6 +338,14 @@ PHP_FUNCTION(dns_check_record) char *hostname, *rectype = NULL; int hostname_len, rectype_len = 0; int type = T_MX, i; +#if defined(HAVE_DNS_SEARCH) + struct sockaddr_storage from; + uint32_t fromsize = sizeof(from); + dns_handle_t handle; +#elif defined(HAVE_RES_NSEARCH) + struct __res_state state; + struct __res_state *handle = &state; +#endif if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &hostname, &hostname_len, &rectype, &rectype_len) == FAILURE) { return; @@ -320,58 +375,32 @@ PHP_FUNCTION(dns_check_record) } } - i = res_search(hostname, C_IN, type, ans, sizeof(ans)); +#if defined(HAVE_DNS_SEARCH) + handle = dns_open(NULL); + if (handle == NULL) { + RETURN_FALSE; + } +#elif defined(HAVE_RES_NSEARCH) + memset(&state, 0, sizeof(state)); + if (res_ninit(handle)) { + RETURN_FALSE; + } +#else + res_init(); +#endif + + RETVAL_TRUE; + i = php_dns_search(handle, hostname, C_IN, type, ans, sizeof(ans)); if (i < 0) { - RETURN_FALSE; + RETVAL_FALSE; } - RETURN_TRUE; + php_dns_free_handle(handle); } /* }}} */ -#if HAVE_DNS_FUNCS - -#ifndef HFIXEDSZ -#define HFIXEDSZ 12 /* fixed data in header */ -#endif /* HFIXEDSZ */ - -#ifndef QFIXEDSZ -#define QFIXEDSZ 4 /* fixed data in query */ -#endif /* QFIXEDSZ */ - -#undef MAXHOSTNAMELEN -#define MAXHOSTNAMELEN 1024 - -#ifndef MAXRESOURCERECORDS -#define MAXRESOURCERECORDS 64 -#endif /* MAXRESOURCERECORDS */ - -typedef union { - HEADER qb1; - u_char qb2[65536]; -} querybuf; - -/* just a hack to free resources allocated by glibc in __res_nsend() - * See also: - * res_thread_freeres() in glibc/resolv/res_init.c - * __libc_res_nsend() in resolv/res_send.c - * */ - -#if defined(__GLIBC__) && !defined(HAVE_DEPRECATED_DNS_FUNCS) -#define php_dns_free_res(__res__) _php_dns_free_res(__res__) -static void _php_dns_free_res(struct __res_state res) { /* {{{ */ - int ns; - for (ns = 0; ns < MAXNS; ns++) { - if (res._u._ext.nsaddrs[ns] != NULL) { - free (res._u._ext.nsaddrs[ns]); - res._u._ext.nsaddrs[ns] = NULL; - } - } -} /* }}} */ -#else -#define php_dns_free_res(__res__) -#endif +#if HAVE_FULL_DNS_FUNCS /* {{{ php_parserr */ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int store, zval **subarray) @@ -670,11 +699,16 @@ PHP_FUNCTION(dns_get_record) zval *authns = NULL, *addtl = NULL; int addtl_recs = 0; int type_to_fetch; -#if !defined(HAVE_DEPRECATED_DNS_FUNCS) - struct __res_state res; +#if defined(HAVE_DNS_SEARCH) + struct sockaddr_storage from; + uint32_t fromsize = sizeof(from); + dns_handle_t handle; +#elif defined(HAVE_RES_NSEARCH) + struct __res_state state; + struct __res_state *handle = &state; #endif HEADER *hp; - querybuf buf, answer; + querybuf answer; u_char *cp = NULL, *end = NULL; int n, qd, an, ns = 0, ar = 0; int type, first_query = 1, store_results = 1; @@ -757,29 +791,32 @@ PHP_FUNCTION(dns_get_record) type_to_fetch = DNS_T_ANY; break; } + if (type_to_fetch) { -#if defined(HAVE_DEPRECATED_DNS_FUNCS) - res_init(); -#else - memset(&res, 0, sizeof(res)); - res_ninit(&res); - res.retrans = 5; - res.options &= ~RES_DEFNAMES; -#endif - n = res_nmkquery(&res, QUERY, hostname, C_IN, type_to_fetch, NULL, 0, NULL, buf.qb2, sizeof buf); - if (n<0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "res_nmkquery() failed"); - zval_dtor(return_value); - res_nclose(&res); - php_dns_free_res(res); +#if defined(HAVE_DNS_SEARCH) + handle = dns_open(NULL); + if (handle == NULL) { RETURN_FALSE; } - n = res_nsend(&res, buf.qb2, n, answer.qb2, sizeof answer); - if (n<0) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "res_nsend() failed"); +#elif defined(HAVE_RES_NSEARCH) + memset(&state, 0, sizeof(state)); + if (res_ninit(handle)) { + RETURN_FALSE; + } +#else + res_init(); +#endif + + n = php_dns_search(handle, hostname, C_IN, type_to_fetch, answer.qb2, sizeof answer); + + if (n < 0) { + if (php_dns_errno(handle) == NO_DATA) { + php_dns_free_handle(handle); + continue; + } + + php_dns_free_handle(handle); zval_dtor(return_value); - res_nclose(&res); - php_dns_free_res(res); RETURN_FALSE; } @@ -797,8 +834,7 @@ PHP_FUNCTION(dns_get_record) if (n < 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to parse DNS data received"); zval_dtor(return_value); - res_nclose(&res); - php_dns_free_res(res); + php_dns_free_handle(handle); RETURN_FALSE; } cp += n + QFIXEDSZ; @@ -813,41 +849,38 @@ PHP_FUNCTION(dns_get_record) add_next_index_zval(return_value, retval); } } - res_nclose(&res); - php_dns_free_res(res); - } - } - if (authns || addtl) { - /* List of Authoritative Name Servers - * Process when only requesting addtl so that we can skip through the section - */ - while (ns-- > 0 && cp && cp < end) { - zval *retval = NULL; + if (authns || addtl) { + /* List of Authoritative Name Servers + * Process when only requesting addtl so that we can skip through the section + */ + while (ns-- > 0 && cp && cp < end) { + zval *retval = NULL; - cp = php_parserr(cp, &answer, DNS_T_ANY, authns != NULL, &retval); - if (retval != NULL) { - add_next_index_zval(authns, retval); + cp = php_parserr(cp, &answer, DNS_T_ANY, authns != NULL, &retval); + if (retval != NULL) { + add_next_index_zval(authns, retval); + } + } } - } - } - if (addtl_recs && addtl) { - /* Additional records associated with authoritative name servers */ - while (ar-- > 0 && cp && cp < end) { - zval *retval = NULL; + if (addtl_recs && addtl) { + /* Additional records associated with authoritative name servers */ + while (ar-- > 0 && cp && cp < end) { + zval *retval = NULL; - cp = php_parserr(cp, &answer, DNS_T_ANY, 1, &retval); - if (retval != NULL) { - add_next_index_zval(addtl, retval); + cp = php_parserr(cp, &answer, DNS_T_ANY, 1, &retval); + if (retval != NULL) { + add_next_index_zval(addtl, retval); + } + } } + php_dns_free_handle(handle); } } } /* }}} */ -#endif /* HAVE_DNS_FUNCS */ -#if HAVE_DN_SKIPNAME && HAVE_DN_EXPAND /* {{{ proto bool dns_get_mx(string hostname, array mxhosts [, array weight]) Get MX records corresponding to a given Internet host name */ PHP_FUNCTION(dns_get_mx) @@ -862,6 +895,14 @@ PHP_FUNCTION(dns_get_mx) HEADER *hp; u_char *cp, *end; int i; +#if defined(HAVE_DNS_SEARCH) + struct sockaddr_storage from; + uint32_t fromsize = sizeof(from); + dns_handle_t handle; +#elif defined(HAVE_RES_NSEARCH) + struct __res_state state; + struct __res_state *handle = &state; +#endif if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|z", &hostname, &hostname_len, &mx_list, &weight_list) == FAILURE) { return; @@ -875,7 +916,21 @@ PHP_FUNCTION(dns_get_mx) array_init(weight_list); } - i = res_search(hostname, C_IN, DNS_T_MX, (u_char *)&ans, sizeof(ans)); +#if defined(HAVE_DNS_SEARCH) + handle = dns_open(NULL); + if (handle == NULL) { + RETURN_FALSE; + } +#elif defined(HAVE_RES_NSEARCH) + memset(&state, 0, sizeof(state)); + if (res_ninit(handle)) { + RETURN_FALSE; + } +#else + res_init(); +#endif + + i = php_dns_search(handle, hostname, C_IN, DNS_T_MX, (u_char *)&ans, sizeof(ans)); if (i < 0) { RETURN_FALSE; } @@ -887,12 +942,14 @@ PHP_FUNCTION(dns_get_mx) end = (u_char *)&ans +i; for (qdc = ntohs((unsigned short)hp->qdcount); qdc--; cp += i + QFIXEDSZ) { if ((i = dn_skipname(cp, end)) < 0 ) { + php_dns_free_handle(handle); RETURN_FALSE; } } count = ntohs((unsigned short)hp->ancount); while (--count >= 0 && cp < end) { if ((i = dn_skipname(cp, end)) < 0 ) { + php_dns_free_handle(handle); RETURN_FALSE; } cp += i; @@ -905,6 +962,7 @@ PHP_FUNCTION(dns_get_mx) } GETSHORT(weight, cp); if ((i = dn_expand(ans, end, cp, buf, sizeof(buf)-1)) < 0) { + php_dns_free_handle(handle); RETURN_FALSE; } cp += i; @@ -913,13 +971,14 @@ PHP_FUNCTION(dns_get_mx) add_next_index_long(weight_list, weight); } } + php_dns_free_handle(handle); RETURN_TRUE; } /* }}} */ -#endif /* HAVE_DN_SKIPNAME && HAVE_DN_EXPAND */ -#endif /* !defined(PHP_WIN32) && (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE))) */ +#endif /* HAVE_FULL_DNS_FUNCS */ +#endif /* !defined(PHP_WIN32) && (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE))) */ -#if HAVE_DNS_FUNCS || defined(PHP_WIN32) +#if HAVE_FULL_DNS_FUNCS || defined(PHP_WIN32) PHP_MINIT_FUNCTION(dns) { REGISTER_LONG_CONSTANT("DNS_A", PHP_DNS_A, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("DNS_NS", PHP_DNS_NS, CONST_CS | CONST_PERSISTENT); @@ -937,7 +996,7 @@ PHP_MINIT_FUNCTION(dns) { REGISTER_LONG_CONSTANT("DNS_ALL", PHP_DNS_ALL, CONST_CS | CONST_PERSISTENT); return SUCCESS; } -#endif /* HAVE_DNS_FUNCS */ +#endif /* HAVE_FULL_DNS_FUNCS */ /* * Local variables: diff --git a/ext/standard/dns.h b/ext/standard/dns.h deleted file mode 100644 index 708b48233..000000000 --- a/ext/standard/dns.h +++ /dev/null @@ -1,71 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2008 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.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: The typical suspects | - | Marcus Boerger | - | Pollita | - +----------------------------------------------------------------------+ -*/ - -/* $Id: dns.h,v 1.19.2.1.2.1.2.6 2009/05/19 19:39:53 jani Exp $ */ - -#ifndef DNS_H -#define DNS_H - -#if HAVE_RES_MKQUERY && !defined(HAVE_RES_NMKQUERY) && HAVE_RES_SEND && !defined(HAVE_RES_NSEND) -#define HAVE_DEPRECATED_DNS_FUNCS 1 -#endif - -#if HAVE_DEPRECATED_DNS_FUNCS -#define res_nmkquery(res, op, dname, class, type, data, datalen, newrr, buf, buflen) \ - res_mkquery(op, dname, class, type, data, datalen, newrr, buf, buflen) -#define res_nsend(res, msg, msglen, answer, anslen) \ - res_send(msg, msglen, answer, anslen); -#define res_nclose(res) /* noop */ -#endif - -#if ((HAVE_RES_NMKQUERY && HAVE_RES_NSEND) || HAVE_DEPRECATED_DNS_FUNCS) && HAVE_DN_EXPAND && HAVE_DN_SKIPNAME -#define HAVE_DNS_FUNCS 1 -#endif - -PHP_FUNCTION(gethostbyaddr); -PHP_FUNCTION(gethostbyname); -PHP_FUNCTION(gethostbynamel); - -#ifdef HAVE_GETHOSTNAME -PHP_FUNCTION(gethostname); -#endif - -#if defined(PHP_WIN32) || (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE))) -PHP_FUNCTION(dns_check_record); -# if defined(PHP_WIN32) || (HAVE_DN_SKIPNAME && HAVE_DN_EXPAND) -PHP_FUNCTION(dns_get_mx); -# endif - -#if defined(PHP_WIN32) || HAVE_DNS_FUNCS -PHP_FUNCTION(dns_get_record); -PHP_MINIT_FUNCTION(dns); -# endif - -#endif /* defined(PHP_WIN32) || (HAVE_RES_SEARCH && !(defined(__BEOS__) || defined(NETWARE))) */ - -#ifndef INT16SZ -#define INT16SZ 2 -#endif - -#ifndef INT32SZ -#define INT32SZ 4 -#endif - -#endif /* DNS_H */ diff --git a/ext/standard/dns_win32.c b/ext/standard/dns_win32.c index a78405df6..8c94f27f4 100644 --- a/ext/standard/dns_win32.c +++ b/ext/standard/dns_win32.c @@ -22,7 +22,7 @@ #include #include -#include "dns.h" +#include "php_dns.h" #define PHP_DNS_NUM_TYPES 12 /* Number of DNS Types Supported by PHP currently */ @@ -132,7 +132,6 @@ PHP_FUNCTION(dns_check_record) } /* }}} */ -#if 1 /* {{{ php_parserr */ static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, zval **subarray) { @@ -237,20 +236,51 @@ static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, zval **s } break; - case DNS_TYPE_AAAA: -#if _WIN32_WINNT >= 0x0600 { - LPSTR str[MAXHOSTNAMELEN]; DNS_AAAA_DATA *data_aaaa = &pRec->Data.AAAA; + char buf[sizeof("AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA:AAAA")]; + char *tp = buf; + int i; + unsigned short out[8]; + int have_v6_break = 0, in_v6_break = 0; + + for (i = 0; i < 4; ++i) { + DWORD chunk = data_aaaa->Ip6Address.IP6Dword[i]; + out[i * 2] = htons(LOWORD(chunk)); + out[i * 2 + 1] = htons(HIWORD(chunk)); + } + + for(i=0; i < 8; i++) { + if (out[i] != 0) { + if (tp > (u_char *)buf) { + in_v6_break = 0; + tp[0] = ':'; + tp++; + } + tp += sprintf((char*)tp,"%x", out[i]); + } else { + if (!have_v6_break) { + have_v6_break = 1; + in_v6_break = 1; + tp[0] = ':'; + tp++; + } else if (!in_v6_break) { + tp[0] = ':'; + tp++; + tp[0] = '0'; + tp++; + } + } + } + add_assoc_string(*subarray, "type", "AAAA", 1); - add_assoc_string(*subarray, "ipv6", RtlIpv6AddressToString(data_aaaa->Ip6Address, str), 1); + add_assoc_string(*subarray, "ipv6", buf, 1); } -#endif break; #if 0 - /* Not supported yet */ + /* Won't be implemented. A6 is deprecated. (Pierre) */ case DNS_TYPE_A6: break; #endif @@ -269,7 +299,7 @@ static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, zval **s case DNS_TYPE_NAPTR: { -#ifdef DNS_NAPTR_DATA +#if _MSC_VER >= 1500 DNS_NAPTR_DATA * data_naptr = &pRec->Data.Naptr; add_assoc_string(*subarray, "type", "NAPTR", 1); @@ -291,7 +321,6 @@ static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, zval **s add_assoc_long(*subarray, "ttl", ttl); } /* }}} */ -#endif /* {{{ proto array|false dns_get_record(string hostname [, int type[, array authns, array addtl]]) Get any Resource Record corresponding to a given Internet host name */ diff --git a/ext/standard/exec.c b/ext/standard/exec.c index 3fcca46a6..6c2dd6000 100644 --- a/ext/standard/exec.c +++ b/ext/standard/exec.c @@ -16,7 +16,7 @@ | Ilia Alshanetsky | +----------------------------------------------------------------------+ */ -/* $Id: exec.c,v 1.113.2.3.2.1.2.17 2009/04/30 15:25:37 pajoye Exp $ */ +/* $Id: exec.c 289688 2009-10-15 21:36:42Z pajoye $ */ #include #include "php.h" @@ -62,7 +62,7 @@ PHPAPI int php_exec(int type, char *cmd, zval *array, zval *return_value TSRMLS_ { FILE *fp; char *buf, *tmp=NULL; - int l, pclose_return; + int l = 0, pclose_return; char *cmd_p, *b, *c, *d=NULL; php_stream *stream; size_t buflen, bufl = 0; @@ -157,13 +157,16 @@ PHPAPI int php_exec(int type, char *cmd, zval *array, zval *return_value TSRMLS_ } if (bufl) { /* strip trailing whitespaces if we have not done so already */ - if (type != 2) { + if ((type == 2 && bufl && !l) || type != 2) { l = bufl; while (l-- && isspace(((unsigned char *)buf)[l])); if (l != (int)(bufl - 1)) { bufl = l + 1; buf[bufl] = '\0'; } + if (type == 2) { + add_next_index_stringl(array, buf, bufl, 1); + } } /* Return last line from the shell command */ diff --git a/ext/standard/exec.h b/ext/standard/exec.h index 9893c1d78..669fa1b19 100644 --- a/ext/standard/exec.h +++ b/ext/standard/exec.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: exec.h,v 1.24.2.3.2.1.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: exec.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef EXEC_H #define EXEC_H diff --git a/ext/standard/file.c b/ext/standard/file.c index 22a1b1e38..61eb06c11 100644 --- a/ext/standard/file.c +++ b/ext/standard/file.c @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: file.c,v 1.409.2.6.2.28.2.36 2009/06/22 11:37:30 felipe Exp $ */ +/* $Id: file.c 289422 2009-10-09 14:37:45Z pajoye $ */ /* Synced with php 3.0 revision 1.218 1999-06-16 [ssb] */ @@ -846,6 +846,10 @@ PHP_FUNCTION(tempnam) return; } + if (PG(safe_mode) &&(!php_checkuid(dir, NULL, CHECKUID_ALLOW_ONLY_DIR))) { + RETURN_FALSE; + } + if (php_check_open_basedir(dir TSRMLS_CC)) { RETURN_FALSE; } @@ -854,6 +858,8 @@ PHP_FUNCTION(tempnam) if (p_len > 64) { p[63] = '\0'; } + + RETVAL_FALSE; if ((fd = php_open_temporary_fd(dir, p, &opened_path TSRMLS_CC)) >= 0) { close(fd); diff --git a/ext/standard/file.h b/ext/standard/file.h index b59aebdb3..d3720f9f1 100644 --- a/ext/standard/file.h +++ b/ext/standard/file.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: file.h,v 1.94.2.2.2.5.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: file.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* Synced with php 3.0 revision 1.30 1999-06-16 [ssb] */ diff --git a/ext/standard/filestat.c b/ext/standard/filestat.c index 0a6d5ac75..031422f7a 100644 --- a/ext/standard/filestat.c +++ b/ext/standard/filestat.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: filestat.c,v 1.136.2.8.2.14.2.9 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: filestat.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "safe_mode.h" diff --git a/ext/standard/filters.c b/ext/standard/filters.c index c2e1916bb..888b14e35 100644 --- a/ext/standard/filters.c +++ b/ext/standard/filters.c @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: filters.c,v 1.44.2.6.2.4.2.4 2009/04/16 10:16:27 dmitry Exp $ */ +/* $Id: filters.c 284646 2009-07-23 12:18:40Z iliaa $ */ #include "php.h" #include "php_globals.h" @@ -2007,6 +2007,7 @@ static int php_dechunk(char *buf, int len, php_chunked_filter_data *data) memmove(out, p, end - p); } data->chunk_size -= end - p; + data->state=CHUNK_BODY; out_len += end - p; return out_len; } diff --git a/ext/standard/flock_compat.c b/ext/standard/flock_compat.c index 908956633..a01423cc9 100644 --- a/ext/standard/flock_compat.c +++ b/ext/standard/flock_compat.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: flock_compat.c,v 1.29.2.1.2.1.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: flock_compat.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include diff --git a/ext/standard/flock_compat.h b/ext/standard/flock_compat.h index ad2cd95bc..a2d347fae 100644 --- a/ext/standard/flock_compat.h +++ b/ext/standard/flock_compat.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: flock_compat.h,v 1.20.2.1.2.1.2.5 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: flock_compat.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef FLOCK_COMPAT_H #define FLOCK_COMPAT_H diff --git a/ext/standard/formatted_print.c b/ext/standard/formatted_print.c index 22fa337e8..d44aae543 100644 --- a/ext/standard/formatted_print.c +++ b/ext/standard/formatted_print.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: formatted_print.c,v 1.82.2.1.2.16.2.10 2009/01/20 18:02:35 iliaa Exp $ */ +/* $Id: formatted_print.c 284649 2009-07-23 14:54:04Z jani $ */ #include /* modf() */ #include "php.h" @@ -697,14 +697,14 @@ PHP_FUNCTION(vsprintf) PHP_FUNCTION(user_printf) { char *result; - int len; + int len, rlen; if ((result=php_formatted_print(ht, &len, 0, 0 TSRMLS_CC))==NULL) { RETURN_FALSE; } - PHPWRITE(result, len); + rlen = PHPWRITE(result, len); efree(result); - RETURN_LONG(len); + RETURN_LONG(rlen); } /* }}} */ @@ -713,14 +713,14 @@ PHP_FUNCTION(user_printf) PHP_FUNCTION(vprintf) { char *result; - int len; + int len, rlen; if ((result=php_formatted_print(ht, &len, 1, 0 TSRMLS_CC))==NULL) { RETURN_FALSE; } - PHPWRITE(result, len); + rlen = PHPWRITE(result, len); efree(result); - RETURN_LONG(len); + RETURN_LONG(rlen); } /* }}} */ diff --git a/ext/standard/fsock.c b/ext/standard/fsock.c index 7030b50ae..270e4d529 100644 --- a/ext/standard/fsock.c +++ b/ext/standard/fsock.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: fsock.c,v 1.121.2.1.2.1.2.4 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: fsock.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "php_globals.h" diff --git a/ext/standard/fsock.h b/ext/standard/fsock.h index 545f6aba2..8c5db51d2 100644 --- a/ext/standard/fsock.h +++ b/ext/standard/fsock.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: fsock.h,v 1.50.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: fsock.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* Synced with php 3.0 revision 1.24 1999-06-18 [ssb] */ diff --git a/ext/standard/ftok.c b/ext/standard/ftok.c index 81bee6f52..3c768a8e0 100644 --- a/ext/standard/ftok.c +++ b/ext/standard/ftok.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: ftok.c,v 1.16.2.1.2.1.2.4 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: ftok.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" diff --git a/ext/standard/ftp_fopen_wrapper.c b/ext/standard/ftp_fopen_wrapper.c index 3f14ce676..b2175e8a2 100644 --- a/ext/standard/ftp_fopen_wrapper.c +++ b/ext/standard/ftp_fopen_wrapper.c @@ -18,7 +18,7 @@ | Sara Golemon | +----------------------------------------------------------------------+ */ -/* $Id: ftp_fopen_wrapper.c,v 1.85.2.4.2.4.2.7 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: ftp_fopen_wrapper.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "php_globals.h" diff --git a/ext/standard/head.c b/ext/standard/head.c index 69c022015..9e9d9d54e 100644 --- a/ext/standard/head.c +++ b/ext/standard/head.c @@ -15,7 +15,7 @@ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ */ -/* $Id: head.c,v 1.84.2.1.2.7.2.8 2009/06/06 02:40:48 mattwil Exp $ */ +/* $Id: head.c 286508 2009-07-29 13:44:16Z iliaa $ */ #include #include "php.h" @@ -124,8 +124,18 @@ PHPAPI int php_setcookie(char *name, int name_len, char *value, int value_len, t } else { snprintf(cookie, len + 100, "Set-Cookie: %s=%s", name, value ? encoded_value : ""); if (expires > 0) { + char *p; strlcat(cookie, "; expires=", len + 100); dt = php_format_date("D, d-M-Y H:i:s T", sizeof("D, d-M-Y H:i:s T")-1, expires, 0 TSRMLS_CC); + /* check to make sure that the year does not exceed 4 digits in length */ + p = zend_memrchr(dt, '-', strlen(dt)); + if (*(p + 5) != ' ') { + efree(dt); + efree(cookie); + efree(encoded_value); + zend_error(E_WARNING, "Expiry date cannot have a year greater then 9999"); + return FAILURE; + } strlcat(cookie, dt, len + 100); efree(dt); } diff --git a/ext/standard/head.h b/ext/standard/head.h index e9acd0580..1eef0f290 100644 --- a/ext/standard/head.h +++ b/ext/standard/head.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: head.h,v 1.28.2.1.2.2.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: head.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef HEAD_H #define HEAD_H diff --git a/ext/standard/html.c b/ext/standard/html.c index 7049b2061..6f1bab29a 100644 --- a/ext/standard/html.c +++ b/ext/standard/html.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: html.c,v 1.111.2.2.2.14.2.15 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: html.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* * HTML entity resources: diff --git a/ext/standard/html.h b/ext/standard/html.h index 31ce45a8d..9cd9e8b04 100644 --- a/ext/standard/html.h +++ b/ext/standard/html.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: html.h,v 1.20.2.1.2.3.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: html.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef HTML_H #define HTML_H diff --git a/ext/standard/http.c b/ext/standard/http.c index 0b25b5617..e3ee24ff0 100644 --- a/ext/standard/http.c +++ b/ext/standard/http.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: http.c,v 1.14.2.4.2.3.2.5 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: http.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_http.h" #include "php_ini.h" diff --git a/ext/standard/http_fopen_wrapper.c b/ext/standard/http_fopen_wrapper.c index d4592ab24..c1757d114 100644 --- a/ext/standard/http_fopen_wrapper.c +++ b/ext/standard/http_fopen_wrapper.c @@ -19,7 +19,7 @@ | Sara Golemon | +----------------------------------------------------------------------+ */ -/* $Id: http_fopen_wrapper.c,v 1.99.2.12.2.9.2.17 2009/05/16 20:34:48 lbarnaud Exp $ */ +/* $Id: http_fopen_wrapper.c 286790 2009-08-04 09:24:48Z tony2001 $ */ #include "php.h" #include "php_globals.h" @@ -326,7 +326,6 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, strlcat(scratch, " HTTP/1.0\r\n", scratch_len); } - /* send it */ php_stream_write(stream, scratch, strlen(scratch)); @@ -348,7 +347,11 @@ php_stream *php_stream_url_wrap_http_ex(php_stream_wrapper *wrapper, char *path, } } smart_str_0(&tmpstr); - tmp = tmpstr.c; + /* Remove newlines and spaces from start and end. there's at least one extra \r\n at the end that needs to go. */ + if (tmpstr.c) { + tmp = php_trim(tmpstr.c, strlen(tmpstr.c), NULL, 0, NULL, 3 TSRMLS_CC); + smart_str_free(&tmpstr); + } } if (Z_TYPE_PP(tmpzval) == IS_STRING && Z_STRLEN_PP(tmpzval)) { /* Remove newlines and spaces from start and end php_trim will estrndup() */ @@ -771,6 +774,7 @@ out: stream->wrapperdata = response_header; } php_stream_notify_progress_init(context, 0, file_size); + /* Restore original chunk size now that we're done with headers */ if (options & STREAM_WILL_CAST) php_stream_set_chunk_size(stream, chunk_size); @@ -782,6 +786,9 @@ out: * the stream */ stream->position = 0; + /* restore mode */ + strlcpy(stream->mode, mode, sizeof(stream->mode)); + if (transfer_encoding) { php_stream_filter_append(&stream->readfilters, transfer_encoding); } diff --git a/ext/standard/image.c b/ext/standard/image.c index d449622bd..b6d41f43b 100644 --- a/ext/standard/image.c +++ b/ext/standard/image.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: image.c,v 1.114.2.2.2.5.2.8 2009/03/17 03:25:57 scottmac Exp $ */ +/* $Id: image.c 277324 2009-03-17 03:25:57Z scottmac $ */ #include "php.h" #include diff --git a/ext/standard/incomplete_class.c b/ext/standard/incomplete_class.c index 6bd29522d..d66921e83 100644 --- a/ext/standard/incomplete_class.c +++ b/ext/standard/incomplete_class.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: incomplete_class.c,v 1.28.2.2.2.2.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: incomplete_class.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "basic_functions.h" diff --git a/ext/standard/info.c b/ext/standard/info.c index 29b1455ca..fd5eeacfd 100644 --- a/ext/standard/info.c +++ b/ext/standard/info.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: info.c,v 1.249.2.10.2.14.2.23 2009/01/17 02:05:13 stas Exp $ */ +/* $Id: info.c 289430 2009-10-09 17:15:46Z pajoye $ */ #include "php.h" #include "php_ini.h" @@ -527,6 +527,30 @@ PHPAPI char *php_get_uname(char mode) if (uname((struct utsname *)&buf) == -1) { php_uname = PHP_UNAME; } else { +#ifdef NETWARE + if (mode == 's') { + php_uname = buf.sysname; + } else if (mode == 'r') { + snprintf(tmp_uname, sizeof(tmp_uname), "%d.%d.%d", + buf.netware_major, buf.netware_minor, buf.netware_revision); + php_uname = tmp_uname; + } else if (mode == 'n') { + php_uname = buf.servername; + } else if (mode == 'v') { + snprintf(tmp_uname, sizeof(tmp_uname), "libc-%d.%d.%d #%d", + buf.libmajor, buf.libminor, buf.librevision, buf.libthreshold); + php_uname = tmp_uname; + } else if (mode == 'm') { + php_uname = buf.machine; + } else { /* assume mode == 'a' */ + snprintf(tmp_uname, sizeof(tmp_uname), "%s %s %d.%d.%d libc-%d.%d.%d #%d %s", + buf.sysname, buf.servername, + buf.netware_major, buf.netware_minor, buf.netware_revision, + buf.libmajor, buf.libminor, buf.librevision, buf.libthreshold, + buf.machine); + php_uname = tmp_uname; + } +#else if (mode == 's') { php_uname = buf.sysname; } else if (mode == 'r') { @@ -543,6 +567,7 @@ PHPAPI char *php_get_uname(char mode) buf.machine); php_uname = tmp_uname; } +#endif /* NETWARE */ } #else php_uname = PHP_UNAME; diff --git a/ext/standard/info.h b/ext/standard/info.h index c97f23207..173415b58 100644 --- a/ext/standard/info.h +++ b/ext/standard/info.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: info.h,v 1.38.2.1.2.5.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: info.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef INFO_H #define INFO_H diff --git a/ext/standard/iptc.c b/ext/standard/iptc.c index c2d931c13..93b144ce8 100644 --- a/ext/standard/iptc.c +++ b/ext/standard/iptc.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: iptc.c,v 1.50.2.2.2.5.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: iptc.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* * Functions to parse & compse IPTC data. diff --git a/ext/standard/lcg.c b/ext/standard/lcg.c index a702a12aa..385015191 100644 --- a/ext/standard/lcg.c +++ b/ext/standard/lcg.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: lcg.c,v 1.41.2.1.2.2.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: lcg.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "php_lcg.h" diff --git a/ext/standard/levenshtein.c b/ext/standard/levenshtein.c index 5eeb7ff9f..b02dcc5cb 100644 --- a/ext/standard/levenshtein.c +++ b/ext/standard/levenshtein.c @@ -15,7 +15,7 @@ | Author: Hartmut Holzgraefe | +----------------------------------------------------------------------+ */ -/* $Id: levenshtein.c,v 1.34.2.1.2.3.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: levenshtein.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include diff --git a/ext/standard/link.c b/ext/standard/link.c index 64c071ad1..923622147 100644 --- a/ext/standard/link.c +++ b/ext/standard/link.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: link.c,v 1.52.2.1.2.3.2.5 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: link.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "php_filestat.h" diff --git a/ext/standard/link_win32.c b/ext/standard/link_win32.c index 8df91e0a8..97c7cb718 100644 --- a/ext/standard/link_win32.c +++ b/ext/standard/link_win32.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: link_win32.c,v 1.1.2.5 2009/06/16 16:50:13 pajoye Exp $ */ +/* $Id: link_win32.c 287813 2009-08-27 14:45:41Z pajoye $ */ #ifdef PHP_WIN32 #include "php.h" @@ -55,6 +55,10 @@ TODO: #define VOLUME_NAME_NT 0x2 #endif +#ifndef VOLUME_NAME_DOS +#define VOLUME_NAME_DOS 0x0 +#endif + /* {{{ proto string readlink(string filename) Return the target of a symbolic link */ PHP_FUNCTION(readlink) @@ -107,7 +111,7 @@ PHP_FUNCTION(readlink) RETURN_FALSE; } - dwRet = pGetFinalPathNameByHandle(hFile, Path, MAXPATHLEN, VOLUME_NAME_NT); + dwRet = pGetFinalPathNameByHandle(hFile, Path, MAXPATHLEN, VOLUME_NAME_DOS); if(dwRet >= MAXPATHLEN) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't resolve the full path, the path exceeds the MAX_PATH_LEN (%d) limit", MAXPATHLEN); RETURN_FALSE; @@ -118,7 +122,14 @@ PHP_FUNCTION(readlink) /* Append NULL to the end of the string */ Path[dwRet] = '\0'; - RETURN_STRING(Path, 1); + if(dwRet > 4) { + /* Skip first 4 characters if they are "\??\" */ + if(Path[0] == '\\' && Path[1] == '\\' && Path[2] == '?' && Path[3] == '\\') { + RETURN_STRING(Path + 4, 1); + } + } else { + RETURN_STRING(Path, 1); + } } /* }}} */ diff --git a/ext/standard/mail.c b/ext/standard/mail.c index 600c17e67..2825881b4 100644 --- a/ext/standard/mail.c +++ b/ext/standard/mail.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mail.c,v 1.87.2.1.2.7.2.11 2009/06/21 15:29:16 iliaa Exp $ */ +/* $Id: mail.c 282504 2009-06-21 15:29:16Z iliaa $ */ #include #include diff --git a/ext/standard/math.c b/ext/standard/math.c index ba7f25745..89b7fcfb2 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: math.c,v 1.131.2.2.2.6.2.13 2009/03/18 10:18:10 dmitry Exp $ */ +/* $Id: math.c 277398 2009-03-18 10:18:10Z dmitry $ */ #include "php.h" #include "php_math.h" diff --git a/ext/standard/md5.c b/ext/standard/md5.c index c4a11c9ee..5ddd40f8a 100644 --- a/ext/standard/md5.c +++ b/ext/standard/md5.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: md5.c,v 1.39.2.1.2.4.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: md5.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "md5.h" diff --git a/ext/standard/md5.h b/ext/standard/md5.h index 768d7e92b..f9d55aba1 100644 --- a/ext/standard/md5.h +++ b/ext/standard/md5.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: md5.h,v 1.17.2.1.2.2.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: md5.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef MD5_H #define MD5_H diff --git a/ext/standard/metaphone.c b/ext/standard/metaphone.c index 24d39a6b0..06186d07f 100644 --- a/ext/standard/metaphone.c +++ b/ext/standard/metaphone.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: metaphone.c,v 1.28.2.1.2.4.2.5 2009/02/18 22:34:06 felipe Exp $ */ +/* $Id: metaphone.c 283127 2009-06-30 11:46:20Z felipe $ */ /* Based on CPANs "Text-Metaphone-1.96" by Michael G Schwern @@ -225,15 +225,14 @@ static int metaphone(unsigned char *word, int word_len, long max_phonemes, char w_idx += 2; } break; - /* WH becomes H, + /* WH becomes W, WR becomes R W if followed by a vowel */ case 'W': - if (Next_Letter == 'H' || - Next_Letter == 'R') { + if (Next_Letter == 'R') { Phonize(Next_Letter); w_idx += 2; - } else if (isvowel(Next_Letter)) { + } else if (Next_Letter == 'H' || isvowel(Next_Letter)) { Phonize('W'); w_idx += 2; } diff --git a/ext/standard/microtime.c b/ext/standard/microtime.c index fba6a0bd1..9a7c179f5 100644 --- a/ext/standard/microtime.c +++ b/ext/standard/microtime.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: microtime.c,v 1.53.2.2.2.3.2.3 2009/05/21 14:21:40 lbarnaud Exp $ */ +/* $Id: microtime.c 280906 2009-05-21 14:21:40Z lbarnaud $ */ #include "php.h" diff --git a/ext/standard/microtime.h b/ext/standard/microtime.h index e35f6c57f..8838d2ca2 100644 --- a/ext/standard/microtime.h +++ b/ext/standard/microtime.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: microtime.h,v 1.14.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: microtime.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef MICROTIME_H #define MICROTIME_H diff --git a/ext/standard/pack.c b/ext/standard/pack.c index c63517d7b..4aa4d5649 100644 --- a/ext/standard/pack.c +++ b/ext/standard/pack.c @@ -15,7 +15,7 @@ | Author: Chris Schneider | +----------------------------------------------------------------------+ */ -/* $Id: pack.c,v 1.57.2.5.2.6.2.6 2009/05/12 12:34:55 iliaa Exp $ */ +/* $Id: pack.c 287647 2009-08-24 18:40:13Z iliaa $ */ #include "php.h" @@ -693,15 +693,15 @@ PHP_FUNCTION(unpack) buf = emalloc(len + 1); for (ipos = opos = 0; opos < len; opos++) { - char c = (input[inputpos + ipos] >> nibbleshift) & 0xf; + char cc = (input[inputpos + ipos] >> nibbleshift) & 0xf; - if (c < 10) { - c += '0'; + if (cc < 10) { + cc += '0'; } else { - c += 'a' - 10; + cc += 'a' - 10; } - buf[opos] = c; + buf[opos] = cc; nibbleshift = (nibbleshift + 4) & 7; if (first-- == 0) { diff --git a/ext/standard/pack.h b/ext/standard/pack.h index 65912e6de..70d37151e 100644 --- a/ext/standard/pack.h +++ b/ext/standard/pack.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pack.h,v 1.16.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: pack.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PACK_H #define PACK_H diff --git a/ext/standard/pageinfo.c b/ext/standard/pageinfo.c index 375c45309..89022c7c1 100644 --- a/ext/standard/pageinfo.c +++ b/ext/standard/pageinfo.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pageinfo.c,v 1.40.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: pageinfo.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "pageinfo.h" diff --git a/ext/standard/pageinfo.h b/ext/standard/pageinfo.h index 71f09d6e3..5722beded 100644 --- a/ext/standard/pageinfo.h +++ b/ext/standard/pageinfo.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pageinfo.h,v 1.14.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: pageinfo.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PAGEINFO_H #define PAGEINFO_H diff --git a/ext/standard/php_array.h b/ext/standard/php_array.h index d63867548..76a5a66d0 100644 --- a/ext/standard/php_array.h +++ b/ext/standard/php_array.h @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_array.h,v 1.50.2.2.2.3.2.4 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_array.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_ARRAY_H #define PHP_ARRAY_H diff --git a/ext/standard/php_assert.h b/ext/standard/php_assert.h index 77e779cab..f8a634a16 100644 --- a/ext/standard/php_assert.h +++ b/ext/standard/php_assert.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_assert.h,v 1.15.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_assert.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_ASSERT_H #define PHP_ASSERT_H diff --git a/ext/standard/php_browscap.h b/ext/standard/php_browscap.h index a7f9defee..4107a4bd2 100644 --- a/ext/standard/php_browscap.h +++ b/ext/standard/php_browscap.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_browscap.h,v 1.13.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_browscap.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_BROWSCAP_H #define PHP_BROWSCAP_H diff --git a/ext/standard/php_crypt.h b/ext/standard/php_crypt.h index ef18989c6..8b06dadc3 100644 --- a/ext/standard/php_crypt.h +++ b/ext/standard/php_crypt.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_crypt.h,v 1.18.2.1.2.1.2.4 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_crypt.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_CRYPT_H #define PHP_CRYPT_H diff --git a/ext/standard/php_crypt_r.c b/ext/standard/php_crypt_r.c index e5c8bb74c..d1e0cda7f 100644 --- a/ext/standard/php_crypt_r.c +++ b/ext/standard/php_crypt_r.c @@ -1,4 +1,4 @@ -/* $Id: php_crypt_r.c,v 1.1.2.7 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_crypt_r.c 290154 2009-11-02 20:46:52Z pajoye $ */ /* +----------------------------------------------------------------------+ | PHP Version 5 | @@ -208,6 +208,7 @@ char * php_md5_crypt_r(const char *pw, const char *salt, char *out) { if (strncpy_s(passwd + MD5_MAGIC_LEN, MD5_HASH_MAX_LEN - MD5_MAGIC_LEN, sp, sl + 1) != 0) { goto _destroyCtx1; } + passwd[MD5_MAGIC_LEN + sl] = '\0'; strcat_s(passwd, MD5_HASH_MAX_LEN, "$"); #else /* VC6 version doesn't have strcat_s or strncpy_s */ diff --git a/ext/standard/php_crypt_r.h b/ext/standard/php_crypt_r.h index b100b7805..57143dbcc 100644 --- a/ext/standard/php_crypt_r.h +++ b/ext/standard/php_crypt_r.h @@ -1,4 +1,4 @@ -/* $Id: php_crypt_r.h,v 1.1.2.4 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_crypt_r.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* +----------------------------------------------------------------------+ | PHP Version 5 | diff --git a/ext/standard/php_dir.h b/ext/standard/php_dir.h index ab2465321..edc76158d 100644 --- a/ext/standard/php_dir.h +++ b/ext/standard/php_dir.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_dir.h,v 1.24.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_dir.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_DIR_H #define PHP_DIR_H diff --git a/ext/standard/php_dns.h b/ext/standard/php_dns.h new file mode 100644 index 000000000..2fa6746b0 --- /dev/null +++ b/ext/standard/php_dns.h @@ -0,0 +1,87 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2008 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.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: The typical suspects | + | Marcus Boerger | + | Pollita | + +----------------------------------------------------------------------+ +*/ + +/* $Id: php_dns.h 287120 2009-08-11 22:07:35Z scottmac $ */ + +#ifndef PHP_DNS_H +#define PHP_DNS_H + +#if defined(HAVE_DNS_SEARCH) +#define php_dns_search(res, dname, class, type, answer, anslen) \ + ((int)dns_search(res, dname, class, type, answer, anslen, (struct sockaddr *)&from, &fromsize)) +#define php_dns_free_handle(res) \ + dns_free(res) +#define php_dns_errno(_res) \ + (NO_DATA) + +#elif defined(HAVE_RES_NSEARCH) +#define php_dns_search(res, dname, class, type, answer, anslen) \ + res_nsearch(res, dname, class, type, answer, anslen); +#define php_dns_free_handle(res) \ + res_nclose(res); \ + php_dns_free_res(*res) +#define php_dns_errno(res) \ + (res->res_h_errno) + +#elif defined(HAVE_RES_SEARCH) +#define php_dns_search(res, dname, class, type, answer, anslen) \ + res_search(dname, class, type, answer, anslen) +#define php_dns_free_handle(res) /* noop */ +#define php_dns_errno(res) \ + (_res.res_h_errno) + +#endif + +#if defined(HAVE_DNS_SEARCH) || defined(HAVE_RES_NSEARCH) || defined(HAVE_RES_SEARCH) +#define HAVE_DNS_SEARCH_FUNC 1 +#endif + +#if HAVE_DNS_SEARCH_FUNC && HAVE_DN_EXPAND && HAVE_DN_SKIPNAME +#define HAVE_FULL_DNS_FUNCS 1 +#endif + +PHP_FUNCTION(gethostbyaddr); +PHP_FUNCTION(gethostbyname); +PHP_FUNCTION(gethostbynamel); + +#ifdef HAVE_GETHOSTNAME +PHP_FUNCTION(gethostname); +#endif + +#if defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE))) +PHP_FUNCTION(dns_check_record); + +# if defined(PHP_WIN32) || HAVE_FULL_DNS_FUNCS +PHP_FUNCTION(dns_get_mx); +PHP_FUNCTION(dns_get_record); +PHP_MINIT_FUNCTION(dns); +# endif + +#endif /* defined(PHP_WIN32) || (HAVE_DNS_SEARCH_FUNC && !(defined(__BEOS__) || defined(NETWARE))) */ + +#ifndef INT16SZ +#define INT16SZ 2 +#endif + +#ifndef INT32SZ +#define INT32SZ 4 +#endif + +#endif /* PHP_DNS_H */ diff --git a/ext/standard/php_ext_syslog.h b/ext/standard/php_ext_syslog.h index 4a94d2f11..0b6e3af03 100644 --- a/ext/standard/php_ext_syslog.h +++ b/ext/standard/php_ext_syslog.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ext_syslog.h,v 1.12.2.2.2.2.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_ext_syslog.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_EXT_SYSLOG_H #define PHP_EXT_SYSLOG_H diff --git a/ext/standard/php_filestat.h b/ext/standard/php_filestat.h index 980dc891b..49810550f 100644 --- a/ext/standard/php_filestat.h +++ b/ext/standard/php_filestat.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_filestat.h,v 1.24.2.4.2.1.2.5 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_filestat.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_FILESTAT_H #define PHP_FILESTAT_H diff --git a/ext/standard/php_fopen_wrapper.c b/ext/standard/php_fopen_wrapper.c index a807c93d5..f3dbf91ad 100644 --- a/ext/standard/php_fopen_wrapper.c +++ b/ext/standard/php_fopen_wrapper.c @@ -17,7 +17,7 @@ | Hartmut Holzgraefe | +----------------------------------------------------------------------+ */ -/* $Id: php_fopen_wrapper.c,v 1.45.2.4.2.7.2.7 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_fopen_wrapper.c 287507 2009-08-20 12:40:15Z jani $ */ #include #include @@ -31,22 +31,25 @@ #include "php_fopen_wrappers.h" #include "SAPI.h" -static size_t php_stream_output_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +static size_t php_stream_output_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) /* {{{ */ { PHPWRITE(buf, count); return count; } +/* }}} */ -static size_t php_stream_output_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) +static size_t php_stream_output_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) /* {{{ */ { stream->eof = 1; return 0; } +/* }}} */ -static int php_stream_output_close(php_stream *stream, int close_handle TSRMLS_DC) +static int php_stream_output_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{{ */ { return 0; } +/* }}} */ php_stream_ops php_stream_output_ops = { php_stream_output_write, @@ -60,54 +63,60 @@ php_stream_ops php_stream_output_ops = { NULL /* set_option */ }; -static size_t php_stream_input_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) +static size_t php_stream_input_write(php_stream *stream, const char *buf, size_t count TSRMLS_DC) /* {{{ */ { return -1; } +/* }}} */ -static size_t php_stream_input_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) +static size_t php_stream_input_read(php_stream *stream, char *buf, size_t count TSRMLS_DC) /* {{{ */ { off_t *position = (off_t*)stream->abstract; size_t read_bytes = 0; - if(!stream->eof) { - if(SG(request_info).raw_post_data) { /* data has already been read by a post handler */ + if (!stream->eof) { + if (SG(request_info).raw_post_data) { /* data has already been read by a post handler */ read_bytes = SG(request_info).raw_post_data_length - *position; - if(read_bytes <= count) { + if (read_bytes <= count) { stream->eof = 1; } else { read_bytes = count; } - if(read_bytes) { + if (read_bytes) { memcpy(buf, SG(request_info).raw_post_data + *position, read_bytes); } - } else if(sapi_module.read_post) { + } else if (sapi_module.read_post) { read_bytes = sapi_module.read_post(buf, count TSRMLS_CC); - if(read_bytes <= 0){ + if (read_bytes <= 0) { stream->eof = 1; read_bytes = 0; } + /* Increment SG(read_post_bytes) only when something was actually read. */ + SG(read_post_bytes) += read_bytes; } else { stream->eof = 1; } } *position += read_bytes; - SG(read_post_bytes) += read_bytes; - return read_bytes; + + return read_bytes; } +/* }}} */ -static int php_stream_input_close(php_stream *stream, int close_handle TSRMLS_DC) +static int php_stream_input_close(php_stream *stream, int close_handle TSRMLS_DC) /* {{{ */ { efree(stream->abstract); return 0; } +/* }}} */ -static int php_stream_input_flush(php_stream *stream TSRMLS_DC) +static int php_stream_input_flush(php_stream *stream TSRMLS_DC) /* {{{ */ { return -1; } +/* }}} */ php_stream_ops php_stream_input_ops = { php_stream_input_write, @@ -121,7 +130,8 @@ php_stream_ops php_stream_input_ops = { NULL /* set_option */ }; -static void php_stream_apply_filter_list(php_stream *stream, char *filterlist, int read_chain, int write_chain TSRMLS_DC) { +static void php_stream_apply_filter_list(php_stream *stream, char *filterlist, int read_chain, int write_chain TSRMLS_DC) /* {{{ */ +{ char *p, *token; php_stream_filter *temp_filter; @@ -145,9 +155,9 @@ static void php_stream_apply_filter_list(php_stream *stream, char *filterlist, i p = php_strtok_r(NULL, "|", &token); } } +/* }}} */ - -php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) +php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, char *mode, int options, char **opened_path, php_stream_context *context STREAMS_DC TSRMLS_DC) /* {{{ */ { int fd = -1; int mode_rw = 0; @@ -159,7 +169,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, ch if (!strncasecmp(path, "php://", 6)) { path += 6; } - + if (!strncasecmp(path, "temp", 4)) { path += 4; max_memory = PHP_STREAM_MAX_MEM; @@ -176,9 +186,9 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, ch } else { mode_rw = TEMP_STREAM_READONLY; } - return php_stream_temp_create(mode_rw, max_memory); + return php_stream_temp_create(mode_rw, max_memory); } - + if (!strcasecmp(path, "memory")) { if (strpbrk(mode, "wa+")) { mode_rw = TEMP_STREAM_DEFAULT; @@ -187,11 +197,11 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, ch } return php_stream_memory_create(mode_rw); } - + if (!strcasecmp(path, "output")) { return php_stream_alloc(&php_stream_output_ops, NULL, 0, "wb"); } - + if (!strcasecmp(path, "input")) { if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) { if (options & REPORT_ERRORS) { @@ -201,7 +211,7 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, ch } return php_stream_alloc(&php_stream_input_ops, ecalloc(1, sizeof(off_t)), 0, "rb"); } - + if (!strcasecmp(path, "stdin")) { if ((options & STREAM_OPEN_FOR_INCLUDE) && !PG(allow_url_include) ) { if (options & REPORT_ERRORS) { @@ -283,12 +293,12 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, ch efree(pathdup); return stream; - } else { + } else { /* invalid php://thingy */ php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid php:// URL specified"); return NULL; } - + /* must be stdin, stderr or stdout */ if (fd == -1) { /* failed to dup */ @@ -317,9 +327,10 @@ php_stream * php_stream_url_wrap_php(php_stream_wrapper *wrapper, char *path, ch close(fd); } } - + return stream; } +/* }}} */ static php_stream_wrapper_ops php_stdio_wops = { php_stream_url_wrap_php, diff --git a/ext/standard/php_fopen_wrappers.h b/ext/standard/php_fopen_wrappers.h index e3ea6b46a..7709e3e0b 100644 --- a/ext/standard/php_fopen_wrappers.h +++ b/ext/standard/php_fopen_wrappers.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_fopen_wrappers.h,v 1.21.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_fopen_wrappers.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_FOPEN_WRAPPERS_H #define PHP_FOPEN_WRAPPERS_H diff --git a/ext/standard/php_ftok.h b/ext/standard/php_ftok.h index 312260a0a..c7e4018d7 100644 --- a/ext/standard/php_ftok.h +++ b/ext/standard/php_ftok.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ftok.h,v 1.9.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_ftok.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_FTOK_H #define PHP_FTOK_H diff --git a/ext/standard/php_http.h b/ext/standard/php_http.h index a3023e752..6de68b4a1 100644 --- a/ext/standard/php_http.h +++ b/ext/standard/php_http.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_http.h,v 1.5.2.2.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_http.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_HTTP_H #define PHP_HTTP_H diff --git a/ext/standard/php_image.h b/ext/standard/php_image.h index ae7e4d5a0..f699dbbee 100644 --- a/ext/standard/php_image.h +++ b/ext/standard/php_image.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_image.h,v 1.29.2.1.2.1.2.4 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_image.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_IMAGE_H #define PHP_IMAGE_H diff --git a/ext/standard/php_incomplete_class.h b/ext/standard/php_incomplete_class.h index dfe614cb6..d84e7a530 100644 --- a/ext/standard/php_incomplete_class.h +++ b/ext/standard/php_incomplete_class.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_incomplete_class.h,v 1.17.2.2.2.1.2.4 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_incomplete_class.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_INCOMPLETE_CLASS_H #define PHP_INCOMPLETE_CLASS_H diff --git a/ext/standard/php_iptc.h b/ext/standard/php_iptc.h index 376248122..7a4e3cedc 100644 --- a/ext/standard/php_iptc.h +++ b/ext/standard/php_iptc.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_iptc.h,v 1.11.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_iptc.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_IPTC_H #define PHP_IPTC_H diff --git a/ext/standard/php_lcg.h b/ext/standard/php_lcg.h index 5f83a82fe..58b7d3347 100644 --- a/ext/standard/php_lcg.h +++ b/ext/standard/php_lcg.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_lcg.h,v 1.21.2.1.2.2.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_lcg.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_LCG_H #define PHP_LCG_H diff --git a/ext/standard/php_link.h b/ext/standard/php_link.h index bd427c779..8c63be632 100644 --- a/ext/standard/php_link.h +++ b/ext/standard/php_link.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_link.h,v 1.12.2.1.2.1.2.3 2009/01/16 01:00:22 pajoye Exp $ */ +/* $Id: php_link.h 273611 2009-01-16 01:00:22Z pajoye $ */ #ifndef PHP_LINK_H #define PHP_LINK_H diff --git a/ext/standard/php_mail.h b/ext/standard/php_mail.h index 9b0ec56e0..a3516dccb 100644 --- a/ext/standard/php_mail.h +++ b/ext/standard/php_mail.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_mail.h,v 1.18.2.1.2.2.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_mail.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_MAIL_H #define PHP_MAIL_H diff --git a/ext/standard/php_math.h b/ext/standard/php_math.h index d733144cb..f130e2f4e 100644 --- a/ext/standard/php_math.h +++ b/ext/standard/php_math.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_math.h,v 1.28.2.2.2.3.2.4 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_math.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_MATH_H #define PHP_MATH_H diff --git a/ext/standard/php_metaphone.h b/ext/standard/php_metaphone.h index 4dcb1c204..622aa31cc 100644 --- a/ext/standard/php_metaphone.h +++ b/ext/standard/php_metaphone.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_metaphone.h,v 1.16.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_metaphone.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_METAPHONE_H #define PHP_METAPHONE_H diff --git a/ext/standard/php_rand.h b/ext/standard/php_rand.h index ba57cfd79..220f436d5 100644 --- a/ext/standard/php_rand.h +++ b/ext/standard/php_rand.h @@ -20,7 +20,7 @@ | Based on code from: Shawn Cokus | +----------------------------------------------------------------------+ */ -/* $Id: php_rand.h,v 1.28.2.1.2.1.2.4 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_rand.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_RAND_H #define PHP_RAND_H diff --git a/ext/standard/php_smart_str.h b/ext/standard/php_smart_str.h index a2daa0c9d..298997873 100644 --- a/ext/standard/php_smart_str.h +++ b/ext/standard/php_smart_str.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_smart_str.h,v 1.30.2.3.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_smart_str.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SMART_STR_H #define PHP_SMART_STR_H diff --git a/ext/standard/php_smart_str_public.h b/ext/standard/php_smart_str_public.h index abdcefc04..e189549fd 100644 --- a/ext/standard/php_smart_str_public.h +++ b/ext/standard/php_smart_str_public.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_smart_str_public.h,v 1.10.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_smart_str_public.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SMART_STR_PUBLIC_H #define PHP_SMART_STR_PUBLIC_H diff --git a/ext/standard/php_standard.h b/ext/standard/php_standard.h index 10730cefe..005fa2972 100644 --- a/ext/standard/php_standard.h +++ b/ext/standard/php_standard.h @@ -16,14 +16,14 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_standard.h,v 1.24.2.2.2.1.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_standard.h 286857 2009-08-05 23:20:17Z scottmac $ */ #include "basic_functions.h" #include "php_math.h" #include "php_string.h" #include "base64.h" #include "php_dir.h" -#include "dns.h" +#include "php_dns.h" #include "php_mail.h" #include "md5.h" #include "sha1.h" diff --git a/ext/standard/php_string.h b/ext/standard/php_string.h index 1fb40e95e..4d85671a2 100644 --- a/ext/standard/php_string.h +++ b/ext/standard/php_string.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_string.h,v 1.87.2.2.2.3.2.5 2009/04/01 17:05:35 mattwil Exp $ */ +/* $Id: php_string.h 287198 2009-08-13 06:44:50Z stas $ */ /* Synced with php 3.0 revision 1.43 1999-06-16 [ssb] */ @@ -127,7 +127,7 @@ PHPAPI void php_stripslashes(char *str, int *len TSRMLS_DC); PHPAPI void php_stripcslashes(char *str, int *len); PHPAPI void php_basename(char *s, size_t len, char *suffix, size_t sufflen, char **p_ret, size_t *p_len TSRMLS_DC); PHPAPI size_t php_dirname(char *str, size_t len); -PHPAPI char *php_stristr(unsigned char *s, unsigned char *t, size_t s_len, size_t t_len); +PHPAPI char *php_stristr(char *s, char *t, size_t s_len, size_t t_len); PHPAPI char *php_str_to_str_ex(char *haystack, int length, char *needle, int needle_len, char *str, int str_len, int *_new_length, int case_sensitivity, int *replace_count); PHPAPI char *php_str_to_str(char *haystack, int length, char *needle, diff --git a/ext/standard/php_type.h b/ext/standard/php_type.h index 5c132e68e..9a8ae44fd 100644 --- a/ext/standard/php_type.h +++ b/ext/standard/php_type.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_type.h,v 1.6.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_type.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_TYPE_H #define PHP_TYPE_H diff --git a/ext/standard/php_uuencode.h b/ext/standard/php_uuencode.h index 253c76ce8..b722e1be3 100644 --- a/ext/standard/php_uuencode.h +++ b/ext/standard/php_uuencode.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_uuencode.h,v 1.4.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_uuencode.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_UUENCODE_H #define PHP_UUENCODE_H diff --git a/ext/standard/php_var.h b/ext/standard/php_var.h index 4898784c9..442762d40 100644 --- a/ext/standard/php_var.h +++ b/ext/standard/php_var.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_var.h,v 1.30.2.1.2.6.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_var.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_VAR_H #define PHP_VAR_H diff --git a/ext/standard/php_versioning.h b/ext/standard/php_versioning.h index c615fcb43..ecfd9483b 100644 --- a/ext/standard/php_versioning.h +++ b/ext/standard/php_versioning.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_versioning.h,v 1.10.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: php_versioning.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_VERSIONING_H #define PHP_VERSIONING_H diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index 1c7137fe9..d7dbccdf8 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -15,7 +15,7 @@ | Author: Wez Furlong | +----------------------------------------------------------------------+ */ -/* $Id: proc_open.c,v 1.36.2.1.2.17.2.8 2009/06/09 00:25:37 pajoye Exp $ */ +/* $Id: proc_open.c 286752 2009-08-03 19:05:56Z felipe $ */ #if 0 && (defined(__linux__) || defined(sun) || defined(__IRIX__)) # define _BSD_SOURCE /* linux wants this when XOPEN mode is on */ @@ -30,6 +30,7 @@ #include "php_string.h" #include "safe_mode.h" #include "ext/standard/head.h" +#include "ext/standard/basic_functions.h" #include "ext/standard/file.h" #include "exec.h" #include "php_globals.h" @@ -152,6 +153,34 @@ static php_process_env_t _php_array_to_envp(zval *environment, int is_persistent if (string_length == 0) { continue; } + if (PG(safe_mode)) { + /* Check the protected list */ + if (zend_hash_exists(&BG(sm_protected_env_vars), string_key, string_length - 1)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Safe Mode warning: Cannot override protected environment variable '%s'", string_key); + return env; + } + /* Check the allowed list */ + if (BG(sm_allowed_env_vars) && *BG(sm_allowed_env_vars)) { + char *allowed_env_vars = estrdup(BG(sm_allowed_env_vars)); + char *strtok_buf = NULL; + char *allowed_prefix = php_strtok_r(allowed_env_vars, ", ", &strtok_buf); + zend_bool allowed = 0; + + while (allowed_prefix) { + if (!strncmp(allowed_prefix, string_key, strlen(allowed_prefix))) { + allowed = 1; + break; + } + allowed_prefix = php_strtok_r(NULL, ", ", &strtok_buf); + } + efree(allowed_env_vars); + if (!allowed) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Safe Mode warning: Cannot set environment variable '%s' - it's not in the allowed list", string_key); + return env; + } + } + } + l = string_length + el_len + 1; memcpy(p, string_key, string_length); strcat(p, "="); @@ -231,9 +260,9 @@ static void proc_open_rsrc_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC) wait_pid = waitpid(proc->child, &wstatus, 0); } while (wait_pid == -1 && errno == EINTR); - if (wait_pid == -1) + if (wait_pid == -1) { FG(pclose_ret) = -1; - else { + } else { if (WIFEXITED(wstatus)) wstatus = WEXITSTATUS(wstatus); FG(pclose_ret) = wstatus; @@ -383,7 +412,7 @@ PHP_FUNCTION(proc_get_status) GetExitCodeProcess(proc->childHandle, &wstatus); running = wstatus == STILL_ACTIVE; - exitcode == STILL_ACTIVE ? -1 : wstatus; + exitcode = running ? -1 : wstatus; #elif HAVE_SYS_WAIT_H diff --git a/ext/standard/proc_open.h b/ext/standard/proc_open.h index 2e7c68b71..473c9f047 100644 --- a/ext/standard/proc_open.h +++ b/ext/standard/proc_open.h @@ -15,7 +15,7 @@ | Author: Wez Furlong | +----------------------------------------------------------------------+ */ -/* $Id: proc_open.h,v 1.5.2.1.2.2.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: proc_open.h 284431 2009-07-20 11:48:04Z gwynne $ */ #ifdef PHP_WIN32 typedef HANDLE php_file_descriptor_t; diff --git a/ext/standard/quot_print.c b/ext/standard/quot_print.c index ff18e96ae..c24ed0bb2 100644 --- a/ext/standard/quot_print.c +++ b/ext/standard/quot_print.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: quot_print.c,v 1.29.2.2.2.1.2.6 2009/01/07 17:20:18 felipe Exp $ */ +/* $Id: quot_print.c 272979 2009-01-07 17:20:18Z felipe $ */ #include diff --git a/ext/standard/quot_print.h b/ext/standard/quot_print.h index 9acbdab36..8f25c0b8b 100644 --- a/ext/standard/quot_print.h +++ b/ext/standard/quot_print.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: quot_print.h,v 1.13.2.1.2.1.2.3 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: quot_print.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef QUOT_PRINT_H #define QUOT_PRINT_H diff --git a/ext/standard/rand.c b/ext/standard/rand.c index a457cc6c3..4b1cac36b 100644 --- a/ext/standard/rand.c +++ b/ext/standard/rand.c @@ -23,7 +23,7 @@ | Shawn Cokus | +----------------------------------------------------------------------+ */ -/* $Id: rand.c,v 1.70.2.1.2.2.2.5 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: rand.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include diff --git a/ext/standard/scanf.c b/ext/standard/scanf.c index 761fcbe52..093c08a47 100644 --- a/ext/standard/scanf.c +++ b/ext/standard/scanf.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: scanf.c,v 1.31.2.2.2.5.2.6 2009/04/02 05:17:36 kalle Exp $ */ +/* $Id: scanf.c 278157 2009-04-02 05:17:36Z kalle $ */ /* scanf.c -- diff --git a/ext/standard/scanf.h b/ext/standard/scanf.h index c66176931..b1fbd49a7 100644 --- a/ext/standard/scanf.h +++ b/ext/standard/scanf.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: scanf.h,v 1.14.2.2.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: scanf.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SCANF_H #define SCANF_H diff --git a/ext/standard/sha1.c b/ext/standard/sha1.c index 7aee1331d..09c194353 100644 --- a/ext/standard/sha1.c +++ b/ext/standard/sha1.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sha1.c,v 1.13.2.1.2.3.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: sha1.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" diff --git a/ext/standard/sha1.h b/ext/standard/sha1.h index 5624bc4ed..885d98858 100644 --- a/ext/standard/sha1.h +++ b/ext/standard/sha1.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sha1.h,v 1.5.2.1.2.2.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: sha1.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SHA1_H #define SHA1_H diff --git a/ext/standard/soundex.c b/ext/standard/soundex.c index 2214cb4b2..aa42d9558 100644 --- a/ext/standard/soundex.c +++ b/ext/standard/soundex.c @@ -15,7 +15,7 @@ | Author: Bjrn Borud - Guardian Networks AS | +----------------------------------------------------------------------+ */ -/* $Id: soundex.c,v 1.25.2.1.2.1.2.2 2008/12/31 11:15:45 sebastian Exp $ */ +/* $Id: soundex.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index cb838c434..b57c7f9ae 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streamsfuncs.c,v 1.58.2.6.2.15.2.36 2009/04/19 17:10:35 lbarnaud Exp $ */ +/* $Id: streamsfuncs.c 286744 2009-08-03 15:58:18Z felipe $ */ #include "php.h" #include "php_globals.h" @@ -573,7 +573,7 @@ PHP_FUNCTION(stream_get_wrappers) if ((url_stream_wrappers_hash = php_stream_get_url_stream_wrappers_hash())) { HashPosition pos; array_init(return_value); - for(zend_hash_internal_pointer_reset_ex(url_stream_wrappers_hash, &pos); + for (zend_hash_internal_pointer_reset_ex(url_stream_wrappers_hash, &pos); (key_flags = zend_hash_get_current_key_ex(url_stream_wrappers_hash, &stream_protocol, &stream_protocol_len, &num_key, 0, &pos)) != HASH_KEY_NON_EXISTANT; zend_hash_move_forward_ex(url_stream_wrappers_hash, &pos)) { if (key_flags == HASH_KEY_IS_STRING) { @@ -1448,26 +1448,27 @@ PHP_FUNCTION(stream_socket_enable_crypto) */ PHP_FUNCTION(stream_is_local) { - zval *zstream; + zval **zstream; php_stream *stream = NULL; php_stream_wrapper *wrapper = NULL; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zstream) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "Z", &zstream) == FAILURE) { RETURN_FALSE; } - if(Z_TYPE_P(zstream) == IS_RESOURCE) { - php_stream_from_zval(stream, &zstream); - if(stream == NULL) { + if (Z_TYPE_PP(zstream) == IS_RESOURCE) { + php_stream_from_zval(stream, zstream); + if (stream == NULL) { RETURN_FALSE; } wrapper = stream->wrapper; } else { - convert_to_string_ex(&zstream); - wrapper = php_stream_locate_url_wrapper(Z_STRVAL_P(zstream), NULL, 0 TSRMLS_CC); + convert_to_string_ex(zstream); + + wrapper = php_stream_locate_url_wrapper(Z_STRVAL_PP(zstream), NULL, 0 TSRMLS_CC); } - if(!wrapper) { + if (!wrapper) { RETURN_FALSE; } diff --git a/ext/standard/streamsfuncs.h b/ext/standard/streamsfuncs.h index 9ac5d2e68..4519520ac 100644 --- a/ext/standard/streamsfuncs.h +++ b/ext/standard/streamsfuncs.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streamsfuncs.h,v 1.13.2.1.2.4.2.6 2009/01/23 15:49:49 kalle Exp $ */ +/* $Id: streamsfuncs.h 274392 2009-01-23 15:49:49Z kalle $ */ /* Flags for stream_socket_client */ #define PHP_STREAM_CLIENT_PERSISTENT 1 diff --git a/ext/standard/string.c b/ext/standard/string.c index ef4833705..88d3add13 100644 --- a/ext/standard/string.c +++ b/ext/standard/string.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: string.c,v 1.445.2.14.2.69.2.46 2009/04/01 17:05:35 mattwil Exp $ */ +/* $Id: string.c 287916 2009-08-31 12:28:46Z iliaa $ */ /* Synced with php 3.0 revision 1.193 1999-06-16 [ssb] */ @@ -120,7 +120,7 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t * register unsigned char *result = NULL; size_t i, j; - result = (char *) safe_emalloc(oldlen * 2, sizeof(char), 1); + result = (unsigned char *) safe_emalloc(oldlen * 2, sizeof(char), 1); for (i = j = 0; i < oldlen; i++) { result[j++] = hexconvtab[old[i] >> 4]; @@ -131,7 +131,7 @@ static char *php_bin2hex(const unsigned char *old, const size_t oldlen, size_t * if (newlen) *newlen = oldlen * 2 * sizeof(char); - return result; + return (char *)result; } /* }}} */ @@ -193,7 +193,7 @@ PHP_FUNCTION(bin2hex) return; } - result = php_bin2hex(data, datalen, &newlen); + result = php_bin2hex((unsigned char *)data, datalen, &newlen); if (!result) { RETURN_FALSE; @@ -412,12 +412,14 @@ PHP_MINIT_FUNCTION(nl_langinfo) #endif #ifdef DECIMAL_POINT REGISTER_NL_LANGINFO_CONSTANT(DECIMAL_POINT); -#elif defined(RADIXCHAR) +#endif +#ifdef RADIXCHAR REGISTER_NL_LANGINFO_CONSTANT(RADIXCHAR); #endif #ifdef THOUSANDS_SEP REGISTER_NL_LANGINFO_CONSTANT(THOUSANDS_SEP); -#elif defined(THOUSEP) +#endif +#ifdef THOUSEP REGISTER_NL_LANGINFO_CONSTANT(THOUSEP); #endif #ifdef GROUPING @@ -587,14 +589,12 @@ PHP_FUNCTION(nl_langinfo) #endif #ifdef DECIMAL_POINT case DECIMAL_POINT: -#endif -#ifdef RADIXCHAR +#elif defined(RADIXCHAR) case RADIXCHAR: #endif #ifdef THOUSANDS_SEP case THOUSANDS_SEP: -#endif -#ifdef THOUSEP +#elif defined(THOUSEP) case THOUSEP: #endif #ifdef GROUPING @@ -711,9 +711,9 @@ PHPAPI char *php_trim(char *c, int len, char *what, int what_len, zval *return_v char mask[256]; if (what) { - php_charmask(what, what_len, mask TSRMLS_CC); + php_charmask((unsigned char*)what, what_len, mask TSRMLS_CC); } else { - php_charmask(" \n\r\t\v\0", 6, mask TSRMLS_CC); + php_charmask((unsigned char*)" \n\r\t\v\0", 6, mask TSRMLS_CC); } if (mode & 1) { @@ -825,7 +825,7 @@ PHP_FUNCTION(wordwrap) laststart = lastspace = 0; for (current = 0; current < textlen; current++) { if (text[current] == breakchar[0]) { - laststart = lastspace = current; + laststart = lastspace = current + 1; } else if (text[current] == ' ') { if (current - laststart >= linelength) { newtext[current] = breakchar[0]; @@ -1001,36 +1001,37 @@ PHPAPI void php_explode_negative_limit(zval *delim, zval *str, zval *return_valu Splits a string on string separator and return array of components. If limit is positive only limit number of components is returned. If limit is negative all components except the last abs(limit) are returned. */ PHP_FUNCTION(explode) { - zval **str, **delim; + char *str, *delim; + int str_len = 0, delim_len = 0; long limit = LONG_MAX; /* No limit */ + zval zdelim, zstr; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|l", &delim, &str, &limit) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|l", &delim, &delim_len, &str, &str_len, &limit) == FAILURE) { return; } - convert_to_string_ex(str); - convert_to_string_ex(delim); - - if (! Z_STRLEN_PP(delim)) { + if (delim_len == 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter"); RETURN_FALSE; } array_init(return_value); - if (! Z_STRLEN_PP(str)) { + if (str_len == 0) { if (limit >= 0) { add_next_index_stringl(return_value, "", sizeof("") - 1, 1); } return; } + ZVAL_STRINGL(&zstr, str, str_len, 0); + ZVAL_STRINGL(&zdelim, delim, delim_len, 0); if (limit > 1) { - php_explode(*delim, *str, return_value, limit); + php_explode(&zdelim, &zstr, return_value, limit); } else if (limit < 0) { - php_explode_negative_limit(*delim, *str, return_value, limit); + php_explode_negative_limit(&zdelim, &zstr, return_value, limit); } else { - add_index_stringl(return_value, 0, Z_STRVAL_PP(str), Z_STRLEN_PP(str), 1); + add_index_stringl(return_value, 0, str, str_len, 1); } } /* }}} */ @@ -1262,8 +1263,8 @@ PHPAPI char *php_strtoupper(char *s, size_t len) { unsigned char *c, *e; - c = s; - e = c+len; + c = (unsigned char *)s; + e = (unsigned char *)c+len; while (c < e) { *c = toupper(*c); @@ -1296,7 +1297,7 @@ PHPAPI char *php_strtolower(char *s, size_t len) { unsigned char *c, *e; - c = s; + c = (unsigned char *)s; e = c+len; while (c < e) { @@ -1528,7 +1529,7 @@ PHP_FUNCTION(pathinfo) /* {{{ php_stristr case insensitve strstr */ -PHPAPI char *php_stristr(unsigned char *s, unsigned char *t, size_t s_len, size_t t_len) +PHPAPI char *php_stristr(char *s, char *t, size_t s_len, size_t t_len) { php_strtolower(s, s_len); php_strtolower(t, t_len); @@ -1574,57 +1575,91 @@ PHPAPI size_t php_strcspn(char *s1, char *s2, char *s1_end, char *s2_end) } /* }}} */ +/* {{{ php_needle_char + */ +static int php_needle_char(zval *needle, char *target TSRMLS_DC) +{ + switch (Z_TYPE_P(needle)) { + case IS_LONG: + case IS_BOOL: + *target = (char)Z_LVAL_P(needle); + return SUCCESS; + case IS_NULL: + *target = '\0'; + return SUCCESS; + case IS_DOUBLE: + *target = (char)(int)Z_DVAL_P(needle); + return SUCCESS; + case IS_OBJECT: + { + zval holder = *needle; + zval_copy_ctor(&(holder)); + convert_to_long(&(holder)); + if(Z_TYPE(holder) != IS_LONG) { + return FAILURE; + } + *target = (char)Z_LVAL(holder); + return SUCCESS; + } + default: { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "needle is not a string or an integer"); + return FAILURE; + } + } +} +/* }}} */ + /* {{{ proto string stristr(string haystack, string needle[, bool part]) Finds first occurrence of a string within another, case insensitive */ PHP_FUNCTION(stristr) { - zval **haystack, **needle; + zval *needle; + char *haystack; + int haystack_len; char *found = NULL; int found_offset; - char *haystack_orig; + char *haystack_dup; char needle_char[2]; zend_bool part = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|b", &haystack, &needle, &part) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &haystack, &haystack_len, &needle, &part) == FAILURE) { return; } - SEPARATE_ZVAL(haystack); - convert_to_string(*haystack); - - haystack_orig = estrndup(Z_STRVAL_PP(haystack), Z_STRLEN_PP(haystack)); + haystack_dup = estrndup(haystack, haystack_len); - if (Z_TYPE_PP(needle) == IS_STRING) { + if (Z_TYPE_P(needle) == IS_STRING) { char *orig_needle; - if (!Z_STRLEN_PP(needle)) { + if (!Z_STRLEN_P(needle)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter"); - efree(haystack_orig); + efree(haystack_dup); RETURN_FALSE; } - orig_needle = estrndup(Z_STRVAL_PP(needle), Z_STRLEN_PP(needle)); - found = php_stristr(Z_STRVAL_PP(haystack), orig_needle, Z_STRLEN_PP(haystack), Z_STRLEN_PP(needle)); + orig_needle = estrndup(Z_STRVAL_P(needle), Z_STRLEN_P(needle)); + found = php_stristr(haystack_dup, orig_needle, haystack_len, Z_STRLEN_P(needle)); efree(orig_needle); } else { - SEPARATE_ZVAL(needle); - convert_to_long(*needle); - needle_char[0] = (char) Z_LVAL_PP(needle); + if (php_needle_char(needle, needle_char TSRMLS_CC) != SUCCESS) { + efree(haystack_dup); + RETURN_FALSE; + } needle_char[1] = 0; - found = php_stristr(Z_STRVAL_PP(haystack), needle_char, Z_STRLEN_PP(haystack), 1); + found = php_stristr(haystack_dup, needle_char, haystack_len, 1); } if (found) { - found_offset = found - Z_STRVAL_PP(haystack); + found_offset = found - haystack_dup; if (part) { - RETVAL_STRINGL(haystack_orig, found_offset, 1); + RETVAL_STRINGL(haystack, found_offset, 1); } else { - RETVAL_STRINGL(haystack_orig + found_offset, Z_STRLEN_PP(haystack) - found_offset, 1); + RETVAL_STRINGL(haystack + found_offset, haystack_len - found_offset, 1); } } else { RETVAL_FALSE; } - efree(haystack_orig); + efree(haystack_dup); } /* }}} */ @@ -1632,41 +1667,40 @@ PHP_FUNCTION(stristr) Finds first occurrence of a string within another */ PHP_FUNCTION(strstr) { - zval **haystack, **needle; + zval *needle; + char *haystack; + int haystack_len; char *found = NULL; char needle_char[2]; long found_offset; zend_bool part = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|b", &haystack, &needle, &part) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|b", &haystack, &haystack_len, &needle, &part) == FAILURE) { return; } - SEPARATE_ZVAL(haystack); - convert_to_string(*haystack); - - if (Z_TYPE_PP(needle) == IS_STRING) { - if (!Z_STRLEN_PP(needle)) { + if (Z_TYPE_P(needle) == IS_STRING) { + if (!Z_STRLEN_P(needle)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter"); RETURN_FALSE; } - found = php_memnstr(Z_STRVAL_PP(haystack), Z_STRVAL_PP(needle), Z_STRLEN_PP(needle), Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); + found = php_memnstr(haystack, Z_STRVAL_P(needle), Z_STRLEN_P(needle), haystack + haystack_len); } else { - SEPARATE_ZVAL(needle); - convert_to_long(*needle); - needle_char[0] = (char) Z_LVAL_PP(needle); + if (php_needle_char(needle, needle_char TSRMLS_CC) != SUCCESS) { + RETURN_FALSE; + } needle_char[1] = 0; - found = php_memnstr(Z_STRVAL_PP(haystack), needle_char, 1, Z_STRVAL_PP(haystack) + Z_STRLEN_PP(haystack)); + found = php_memnstr(haystack, needle_char, 1, haystack + haystack_len); } if (found) { - found_offset = found - Z_STRVAL_PP(haystack); + found_offset = found - haystack; if (part) { - RETURN_STRINGL(Z_STRVAL_PP(haystack), found_offset, 1); + RETURN_STRINGL(haystack, found_offset, 1); } else { - RETURN_STRINGL(found, Z_STRLEN_PP(haystack) - found_offset, 1); + RETURN_STRINGL(found, haystack_len - found_offset, 1); } } RETURN_FALSE; @@ -1681,14 +1715,14 @@ PHP_FUNCTION(strstr) Finds position of first occurrence of a string within another */ PHP_FUNCTION(strpos) { - zval **needle; + zval *needle; char *haystack; char *found = NULL; char needle_char[2]; long offset = 0; int haystack_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ|l", &haystack, &haystack_len, &needle, &offset) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &haystack, &haystack_len, &needle, &offset) == FAILURE) { return; } @@ -1697,19 +1731,20 @@ PHP_FUNCTION(strpos) RETURN_FALSE; } - if (Z_TYPE_PP(needle) == IS_STRING) { - if (!Z_STRLEN_PP(needle)) { + if (Z_TYPE_P(needle) == IS_STRING) { + if (!Z_STRLEN_P(needle)) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty delimiter"); RETURN_FALSE; } found = php_memnstr(haystack + offset, - Z_STRVAL_PP(needle), - Z_STRLEN_PP(needle), + Z_STRVAL_P(needle), + Z_STRLEN_P(needle), haystack + haystack_len); } else { - convert_to_long_ex(needle); - needle_char[0] = (char) Z_LVAL_PP(needle); + if (php_needle_char(needle, needle_char TSRMLS_CC) != SUCCESS) { + RETURN_FALSE; + } needle_char[1] = 0; found = php_memnstr(haystack + offset, @@ -1764,21 +1799,11 @@ PHP_FUNCTION(stripos) php_strtolower(needle_dup, Z_STRLEN_P(needle)); found = php_memnstr(haystack_dup + offset, needle_dup, Z_STRLEN_P(needle), haystack_dup + haystack_len); } else { - switch (Z_TYPE_P(needle)) { - case IS_LONG: - case IS_BOOL: - needle_char[0] = tolower((char) Z_LVAL_P(needle)); - break; - case IS_DOUBLE: - needle_char[0] = tolower((char) Z_DVAL_P(needle)); - break; - default: - php_error_docref(NULL TSRMLS_CC, E_WARNING, "needle is not a string or an integer"); - efree(haystack_dup); - RETURN_FALSE; - break; - + if (php_needle_char(needle, needle_char TSRMLS_CC) != SUCCESS) { + efree(haystack_dup); + RETURN_FALSE; } + needle_char[0] = tolower(needle_char[0]); needle_char[1] = '\0'; found = php_memnstr(haystack_dup + offset, needle_char, @@ -1803,22 +1828,23 @@ PHP_FUNCTION(stripos) Finds position of last occurrence of a string within another string */ PHP_FUNCTION(strrpos) { - zval **zneedle; + zval *zneedle; char *needle, *haystack; int needle_len, haystack_len; long offset = 0; char *p, *e, ord_needle[2]; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ|l", &haystack, &haystack_len, &zneedle, &offset) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &haystack, &haystack_len, &zneedle, &offset) == FAILURE) { RETURN_FALSE; } - if (Z_TYPE_PP(zneedle) == IS_STRING) { - needle = Z_STRVAL_PP(zneedle); - needle_len = Z_STRLEN_PP(zneedle); + if (Z_TYPE_P(zneedle) == IS_STRING) { + needle = Z_STRVAL_P(zneedle); + needle_len = Z_STRLEN_P(zneedle); } else { - convert_to_long_ex(zneedle); - ord_needle[0] = (char)(Z_LVAL_PP(zneedle) & 0xFF); + if (php_needle_char(zneedle, ord_needle TSRMLS_CC) != SUCCESS) { + RETURN_FALSE; + } ord_needle[1] = '\0'; needle = ord_needle; needle_len = 1; @@ -1875,23 +1901,24 @@ PHP_FUNCTION(strrpos) Finds position of last occurrence of a string within another string */ PHP_FUNCTION(strripos) { - zval **zneedle; + zval *zneedle; char *needle, *haystack; int needle_len, haystack_len; long offset = 0; char *p, *e, ord_needle[2]; char *needle_dup, *haystack_dup; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ|l", &haystack, &haystack_len, &zneedle, &offset) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz|l", &haystack, &haystack_len, &zneedle, &offset) == FAILURE) { RETURN_FALSE; } - if (Z_TYPE_PP(zneedle) == IS_STRING) { - needle = Z_STRVAL_PP(zneedle); - needle_len = Z_STRLEN_PP(zneedle); + if (Z_TYPE_P(zneedle) == IS_STRING) { + needle = Z_STRVAL_P(zneedle); + needle_len = Z_STRLEN_P(zneedle); } else { - convert_to_long_ex(zneedle); - ord_needle[0] = (char)(Z_LVAL_PP(zneedle) & 0xFF); + if (php_needle_char(zneedle, ord_needle TSRMLS_CC) != SUCCESS) { + RETURN_FALSE; + } ord_needle[1] = '\0'; needle = ord_needle; needle_len = 1; @@ -1978,21 +2005,25 @@ PHP_FUNCTION(strripos) Finds the last occurrence of a character in a string within another */ PHP_FUNCTION(strrchr) { - zval **needle; + zval *needle; char *haystack; char *found = NULL; long found_offset; int haystack_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sZ", &haystack, &haystack_len, &needle) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sz", &haystack, &haystack_len, &needle) == FAILURE) { return; } - if (Z_TYPE_PP(needle) == IS_STRING) { - found = zend_memrchr(haystack, *Z_STRVAL_PP(needle), haystack_len); + if (Z_TYPE_P(needle) == IS_STRING) { + found = zend_memrchr(haystack, *Z_STRVAL_P(needle), haystack_len); } else { - convert_to_long_ex(needle); - found = zend_memrchr(haystack, (char) Z_LVAL_PP(needle), haystack_len); + char needle_chr; + if (php_needle_char(needle, &needle_chr TSRMLS_CC) != SUCCESS) { + RETURN_FALSE; + } + + found = zend_memrchr(haystack, needle_chr, haystack_len); } if (found) { @@ -2060,31 +2091,18 @@ static char *php_chunk_split(char *src, int srclen, char *end, int endlen, int c Returns split line */ PHP_FUNCTION(chunk_split) { - zval **p_chunklen = NULL, **p_ending = NULL; char *str; char *result; char *end = "\r\n"; int endlen = 2; long chunklen = 76; int result_len; - int argc = ZEND_NUM_ARGS(); int str_len; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ZZ", &str, &str_len, &p_chunklen, &p_ending) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|ls", &str, &str_len, &chunklen, &end, &endlen) == FAILURE) { return; } - if (argc > 1) { - convert_to_long_ex(p_chunklen); - chunklen = Z_LVAL_PP(p_chunklen); - } - - if (argc > 2) { - convert_to_string_ex(p_ending); - end = Z_STRVAL_PP(p_ending); - endlen = Z_STRLEN_PP(p_ending); - } - if (chunklen <= 0) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Chunk length should be greater than zero"); RETURN_FALSE; @@ -3110,7 +3128,7 @@ PHPAPI char *php_addcslashes(char *str, int length, int *new_length, int should_ wlength = strlen(what); } - php_charmask(what, wlength, flags TSRMLS_CC); + php_charmask((unsigned char *)what, wlength, flags TSRMLS_CC); for (source = str, end = source + length, target = new_str; source < end; source++) { c = *source; @@ -4104,11 +4122,11 @@ PHP_FUNCTION(setlocale) PHP_FUNCTION(parse_str) { char *arg; - zval **arrayArg = NULL; + zval *arrayArg = NULL; char *res = NULL; int arglen; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|Z", &arg, &arglen, &arrayArg) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|z", &arg, &arglen, &arrayArg) == FAILURE) { return; } @@ -4124,10 +4142,10 @@ PHP_FUNCTION(parse_str) sapi_module.treat_data(PARSE_STRING, res, &tmp TSRMLS_CC); } else { /* Clear out the array that was passed in. */ - zval_dtor(*arrayArg); - array_init(*arrayArg); + zval_dtor(arrayArg); + array_init(arrayArg); - sapi_module.treat_data(PARSE_STRING, res, *arrayArg TSRMLS_CC); + sapi_module.treat_data(PARSE_STRING, res, arrayArg TSRMLS_CC); } } /* }}} */ @@ -4995,7 +5013,7 @@ PHP_FUNCTION(str_word_count) } if (char_list) { - php_charmask(char_list, char_list_len, ch TSRMLS_CC); + php_charmask((unsigned char *)char_list, char_list_len, ch TSRMLS_CC); } p = str; diff --git a/ext/standard/strnatcmp.c b/ext/standard/strnatcmp.c index 2a958d9b6..3a60bc76e 100644 --- a/ext/standard/strnatcmp.c +++ b/ext/standard/strnatcmp.c @@ -38,7 +38,7 @@ #if 0 static char const *version UNUSED = - "$Id: strnatcmp.c,v 1.10.8.2 2009/04/09 15:55:46 rasmus Exp $"; + "$Id: strnatcmp.c 289419 2009-10-09 14:33:38Z pajoye $"; #endif /* {{{ compare_right */ @@ -101,11 +101,12 @@ compare_left(char const **a, char const *aend, char const **b, char const *bend) */ PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len, int fold_case) { - char ca, cb; + unsigned char ca, cb; char const *ap, *bp; char const *aend = a + a_len, *bend = b + b_len; int fractional, result; + short leading = 1; if (a_len == 0 || b_len == 0) return a_len - b_len; @@ -115,12 +116,25 @@ PHPAPI int strnatcmp_ex(char const *a, size_t a_len, char const *b, size_t b_len while (1) { ca = *ap; cb = *bp; - /* skip over leading spaces or zeros */ - while (isspace((int)(unsigned char)ca) || (ca == '0' && (ap+1 < aend) && (*(ap+1)!='.'))) + /* skip over leading zeros */ + while (leading && ca == '0' && (ap+1 < aend) && isdigit(*(ap+1))) { ca = *++ap; + } - while (isspace((int)(unsigned char)cb) || (cb == '0' && (bp+1 < bend) && (*(bp+1)!='.'))) + while (leading && cb == '0' && (bp+1 < bend) && isdigit(*(bp+1))) { cb = *++bp; + } + + leading = 0; + + /* Skip consecutive whitespace */ + while (isspace((int)(unsigned char)ca)) { + ca = *++ap; + } + + while (isspace((int)(unsigned char)cb)) { + cb = *++bp; + } /* process run of digits */ if (isdigit((int)(unsigned char)ca) && isdigit((int)(unsigned char)cb)) { diff --git a/ext/standard/syslog.c b/ext/standard/syslog.c index 7339e5bc0..aa8c47248 100644 --- a/ext/standard/syslog.c +++ b/ext/standard/syslog.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: syslog.c,v 1.49.2.3.2.2.2.6 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: syslog.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" diff --git a/ext/standard/tests/array/bug40709.phpt b/ext/standard/tests/array/bug40709.phpt index 6ab6bbd41..eb0c71200 100644 --- a/ext/standard/tests/array/bug40709.phpt +++ b/ext/standard/tests/array/bug40709.phpt @@ -1,6 +1,5 @@ --TEST-- Bug #40709 (array_reduce() behaves strange with one item stored arrays) ---SKIPIF-- --FILE-- --EXPECT-- -array(10) { +array(12) { [6]=> string(4) "-123" [8]=> string(2) "00" [9]=> string(1) "0" + [11]=> + string(3) "0-0" [7]=> string(5) "0.002" + [10]=> + string(3) "0_0" [0]=> string(3) "001" [4]=> diff --git a/ext/standard/tests/array/bug48854.phpt b/ext/standard/tests/array/bug48854.phpt new file mode 100644 index 000000000..090863750 --- /dev/null +++ b/ext/standard/tests/array/bug48854.phpt @@ -0,0 +1,43 @@ +--TEST-- +Bug #48854 (array_merge_recursive modifies arrays after first one) +--FILE-- + 5, + 'children' => array( + 'dogs' => 0, + ), +); + +$array2 = array( + 'friends' => 10, + 'children' => array( + 'cats' => 5, + ), +); + +$merged = array_merge_recursive($array1, $array2); + +var_dump($array1, $array2); + +?> +--EXPECTF-- +array(2) { + [%u|b%"friends"]=> + int(5) + [%u|b%"children"]=> + array(1) { + [%u|b%"dogs"]=> + int(0) + } +} +array(2) { + [%u|b%"friends"]=> + int(10) + [%u|b%"children"]=> + array(1) { + [%u|b%"cats"]=> + int(5) + } +} diff --git a/ext/standard/tests/array/key_exists_basic.phpt b/ext/standard/tests/array/key_exists_basic.phpt new file mode 100644 index 000000000..40d982da2 --- /dev/null +++ b/ext/standard/tests/array/key_exists_basic.phpt @@ -0,0 +1,15 @@ +--TEST-- +Test function key_exists() by calling it with its expected arguments +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 1); +var_dump(key_exists('bar', $a)); +var_dump(key_exists('foo', $a)); +--EXPECTF-- +*** test key_exists() by calling it with its expected arguments *** +bool(true) +bool(false) diff --git a/ext/standard/tests/array/key_exists_error.phpt b/ext/standard/tests/array/key_exists_error.phpt new file mode 100644 index 000000000..1bbd41e20 --- /dev/null +++ b/ext/standard/tests/array/key_exists_error.phpt @@ -0,0 +1,23 @@ +--TEST-- +Test function key_exists() by calling it more than or less than its expected arguments +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 1); +var_dump(key_exists()); +var_dump(key_exists('foo', $a, 'baz')); + +?> +--EXPECTF-- +*** Test by calling method or function with incorrect numbers of arguments *** + +Warning: key_exists() expects exactly 2 parameters, 0 given in %s on line %d +NULL + +Warning: key_exists() expects exactly 2 parameters, 3 given in %s on line %d +NULL diff --git a/ext/standard/tests/array/key_exists_variation1.phpt b/ext/standard/tests/array/key_exists_variation1.phpt new file mode 100644 index 000000000..94ea8d45f --- /dev/null +++ b/ext/standard/tests/array/key_exists_variation1.phpt @@ -0,0 +1,15 @@ +--TEST-- +Test function key_exists() by calling it with its expected arguments +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 1, 'foo' => array('bar' => 2, 'baz' => 3)); +var_dump(key_exists('baz', $a)); +var_dump(key_exists('baz', $a['foo'])); +--EXPECTF-- +*** test key_exists() by calling it with its expected arguments *** +bool(false) +bool(true) diff --git a/ext/standard/tests/array/key_exists_variation2.phpt b/ext/standard/tests/array/key_exists_variation2.phpt new file mode 100644 index 000000000..5f5ab86a4 --- /dev/null +++ b/ext/standard/tests/array/key_exists_variation2.phpt @@ -0,0 +1,72 @@ +--TEST-- +Test function key_exists() by calling it with its expected arguments +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + 'bar', 'foo' => 'baz'); +var_dump(key_exists(0, $a)); + +echo "integer\n"; +// 1 has index = 0 +$b = array(1, 'foo' => 'baz'); +var_dump(key_exists(0, $b)); + +// 42 has index = 0, netherless its position is the latest +$c = array('foo' => 'baz', 42); +var_dump(key_exists(0, $c)); + +echo "string\n"; +// 'bar' has index = 0, netherless it is a string +$d = array('bar', 'foo' => 'baz'); +var_dump(key_exists(0, $d)); + +// 'baz' has index = 0, netherless its position is the latest +$e = array('foo' => 'baz', 'baz'); +var_dump(key_exists(0, $e)); + +echo "obj\n"; +class ObjectA +{ + public $foo = 'bar'; +} + +$obj = new ObjectA(); + +// object has index = 0, netherless its position is the latest +$f = array('foo' => 'baz', $obj); +var_dump(key_exists(0, $f)); + +// object has index = 0, netherless its position is the first +$g = array($obj, 'foo' => 'baz'); +var_dump(key_exists(0, $g)); + +echo "stream resource\n"; +// stream resource has index = 0, netherless its position is the first +$st = fopen('php://memory', '+r'); +$h = array($st, 'foo' => 'baz'); +var_dump(key_exists(0, $h)); + +// stream resource has index = 0, netherless its position is the latest +$i = array('foo' => 'baz', $st); +var_dump(key_exists(0, $i)); + +--EXPECTF-- +*** test key_exists() by using mixed type of arrays *** +bool(false) +integer +bool(true) +bool(true) +string +bool(true) +bool(true) +obj +bool(true) +bool(true) +stream resource +bool(true) +bool(true) diff --git a/ext/standard/tests/array/max_basiclong_64bit.phpt b/ext/standard/tests/array/max_basiclong_64bit.phpt new file mode 100644 index 000000000..1eb7e31cd --- /dev/null +++ b/ext/standard/tests/array/max_basiclong_64bit.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test max function : 64bit long tests +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +int(9223372036854775807) +int(9223372036854775807) +===DONE=== diff --git a/ext/standard/tests/array/min_basiclong_64bit.phpt b/ext/standard/tests/array/min_basiclong_64bit.phpt new file mode 100644 index 000000000..52f63f391 --- /dev/null +++ b/ext/standard/tests/array/min_basiclong_64bit.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test min function : 64bit long tests +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECT-- +int(-9223372036854775808) +int(-9223372036854775808) +===DONE=== diff --git a/ext/standard/tests/array/unexpected_array_mod_bug.phpt b/ext/standard/tests/array/unexpected_array_mod_bug.phpt new file mode 100755 index 000000000..58f224920 --- /dev/null +++ b/ext/standard/tests/array/unexpected_array_mod_bug.phpt @@ -0,0 +1,21 @@ +--TEST-- +Crash when function parameter modified via reference +--FILE-- + "entry_1", +2 => "entry_2", +3 => "entry_3", +4 => "entry_4", +5 => "entry_5"); +usort($my_var, "usercompare"); + +echo "Done.\n"; +?> +--EXPECTF-- + +Warning: usort(): Array was modified by the user comparison function in %s on line %d +Done. diff --git a/ext/standard/tests/class_object/get_class_variation_001.phpt b/ext/standard/tests/class_object/get_class_variation_001.phpt index 4087d83bd..e2bf986c2 100644 --- a/ext/standard/tests/class_object/get_class_variation_001.phpt +++ b/ext/standard/tests/class_object/get_class_variation_001.phpt @@ -152,12 +152,12 @@ bool(false) Arg value: (type: NULL) -Warning: get_class() expects parameter 1 to be object, null given in %sget_class_variation_001.php on line %d +Warning: get_class() called without object from outside a class in %sget_class_variation_001.php on line %d bool(false) Arg value: (type: NULL) -Warning: get_class() expects parameter 1 to be object, null given in %sget_class_variation_001.php on line %d +Warning: get_class() called without object from outside a class in %sget_class_variation_001.php on line %d bool(false) Arg value: 1 (type: boolean) @@ -202,11 +202,11 @@ bool(false) Arg value: (type: NULL) -Warning: get_class() expects parameter 1 to be object, null given in %sget_class_variation_001.php on line %d +Warning: get_class() called without object from outside a class in %sget_class_variation_001.php on line %d bool(false) Arg value: (type: NULL) -Warning: get_class() expects parameter 1 to be object, null given in %sget_class_variation_001.php on line %d +Warning: get_class() called without object from outside a class in %sget_class_variation_001.php on line %d bool(false) Done diff --git a/ext/standard/tests/file/005_variation2-win32.phpt b/ext/standard/tests/file/005_variation2-win32.phpt index caed7e62f..513182dde 100644 --- a/ext/standard/tests/file/005_variation2-win32.phpt +++ b/ext/standard/tests/file/005_variation2-win32.phpt @@ -108,13 +108,13 @@ Warning: filectime(): stat failed for | in %s on line %d *** testing touch *** -Warning: touch(): Unable to create file because No such file or directory in %s on line %d +Warning: touch(): Unable to create file because %s in %s on line %d bool(false) -Warning: touch(): Unable to create file because No such file or directory in %s on line %d +Warning: touch(): Unable to create file because %s in %s on line %d bool(false) -Warning: touch(): Unable to create file because No such file or directory in %s on line %d +Warning: touch(): Unable to create file because %s in %s on line %d bool(false) Warning: touch(): Unable to create file because %s in %s on line %d diff --git a/ext/standard/tests/file/bug43353-win32.phpt b/ext/standard/tests/file/bug43353-win32.phpt new file mode 100644 index 000000000..46f21611b --- /dev/null +++ b/ext/standard/tests/file/bug43353-win32.phpt @@ -0,0 +1,23 @@ +--TEST-- +Bug #43353 wrong detection of 'data' wrapper +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +bool(false) +bool(false) +string(3) "foo" + +Warning: file_get_contents(datafoo:text/plain,foo): failed to open stream: Invalid argument in %s +bool(false) diff --git a/ext/standard/tests/file/bug43353.phpt b/ext/standard/tests/file/bug43353.phpt index a11817895..743146812 100644 --- a/ext/standard/tests/file/bug43353.phpt +++ b/ext/standard/tests/file/bug43353.phpt @@ -1,5 +1,10 @@ --TEST-- Bug #43353 wrong detection of 'data' wrapper +--SKIPIF-- + --FILE-- '; -$tempnam = tempnam(sys_get_temp_dir(), 'php'); +$tempnam = __DIR__ . '/' . 'tmpbug44607.txt'; $data = str_repeat('.', 14000); $data .= $eol; $data .= $data; @@ -14,6 +14,7 @@ var_dump(strlen(stream_get_line($fd, 15000, $eol))); fseek($fd, 1, SEEK_SET); var_dump(strlen(stream_get_line($fd, 15000, $eol))); var_dump(strlen(stream_get_line($fd, 15000, $eol))); +fclose($fd); unlink($tempnam); ?> --EXPECT-- diff --git a/ext/standard/tests/file/bug49047.phpt b/ext/standard/tests/file/bug49047.phpt new file mode 100644 index 000000000..1ccc94e28 --- /dev/null +++ b/ext/standard/tests/file/bug49047.phpt @@ -0,0 +1,17 @@ +--TEST-- +Test fopen() function : variation: interesting paths, no use include path +--FILE-- + +--EXPECTF-- +Ok. diff --git a/ext/standard/tests/file/file_get_contents_basic001.phpt b/ext/standard/tests/file/file_get_contents_basic001.phpt new file mode 100644 index 000000000..71b69634d --- /dev/null +++ b/ext/standard/tests/file/file_get_contents_basic001.phpt @@ -0,0 +1,21 @@ +--TEST-- +file_get_contents() test using basic syntax +--CREDITS-- +"Blanche V.N." +--FILE-- + +--CLEAN-- + +--EXPECT-- +Bienvenue au CodeFest a Montreal diff --git a/ext/standard/tests/file/file_get_contents_error001.phpt b/ext/standard/tests/file/file_get_contents_error001.phpt new file mode 100644 index 000000000..ced0da032 --- /dev/null +++ b/ext/standard/tests/file/file_get_contents_error001.phpt @@ -0,0 +1,18 @@ +--TEST-- +file_get_contents() test using offset parameter out of range +--CREDITS-- +"Blanche V.N." +"Sylvain R." +--INI-- +display_errors=false +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(false) diff --git a/ext/standard/tests/file/file_get_contents_error002.phpt b/ext/standard/tests/file/file_get_contents_error002.phpt new file mode 100644 index 000000000..47c7b9cd6 --- /dev/null +++ b/ext/standard/tests/file/file_get_contents_error002.phpt @@ -0,0 +1,18 @@ +--TEST-- +file_get_contents() test using negative parameter for length (last parameter) +--CREDITS-- +"Blanche V.N." +"Sylvain R." +--INI-- +display_errors=false +--SKIPIF-- + +--FILE-- + +--EXPECT-- +bool(false) diff --git a/ext/standard/tests/file/file_put_contents_variation5.phpt b/ext/standard/tests/file/file_put_contents_variation5.phpt index 8d50a19c7..4ecb5213a 100644 --- a/ext/standard/tests/file/file_put_contents_variation5.phpt +++ b/ext/standard/tests/file/file_put_contents_variation5.phpt @@ -24,7 +24,7 @@ runtest(); set_include_path(";; ; ;c:\\rubbish"); runtest(); -chdir(dirname('__FILE__')); +chdir(dirname(__FILE__)); rmdir($thisTestDir); diff --git a/ext/standard/tests/file/glob_error_002.phpt b/ext/standard/tests/file/glob_error_002.phpt deleted file mode 100644 index f5bad7369..000000000 --- a/ext/standard/tests/file/glob_error_002.phpt +++ /dev/null @@ -1,27 +0,0 @@ ---TEST-- -Test glob() function: long pattern. ---CREDITS-- -Dave Kelsey ---SKIPIF-- - ---FILE-- - ---EXPECTF-- -*** Testing glob() : long pattern. *** -array(0) { -} -Done - diff --git a/ext/standard/tests/file/is_uploaded_file_basic.phpt b/ext/standard/tests/file/is_uploaded_file_basic.phpt index 355125e83..1907d390b 100644 --- a/ext/standard/tests/file/is_uploaded_file_basic.phpt +++ b/ext/standard/tests/file/is_uploaded_file_basic.phpt @@ -2,8 +2,6 @@ is_uploaded_file() function --CREDITS-- Dave Kelsey ---SKIPIF-- - --POST_RAW-- Content-type: multipart/form-data, boundary=AaB03x diff --git a/ext/standard/tests/file/lchgrp_basic.phpt b/ext/standard/tests/file/lchgrp_basic.phpt new file mode 100644 index 000000000..1713bef9b --- /dev/null +++ b/ext/standard/tests/file/lchgrp_basic.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test lchgrp() function : basic functionality +--SKIPIF-- + +--FILE-- + +===DONE=== +--CLEAN-- + +--EXPECTF-- +bool(true) +bool(true) +bool(true) +bool(true) +===DONE=== diff --git a/ext/standard/tests/file/mkdir_variation5-win32.phpt b/ext/standard/tests/file/mkdir_variation5-win32.phpt index d93f6c6a9..c7ebd518d 100644 --- a/ext/standard/tests/file/mkdir_variation5-win32.phpt +++ b/ext/standard/tests/file/mkdir_variation5-win32.phpt @@ -2,7 +2,6 @@ Test mkdir() function : variation: various valid and invalid paths --CREDITS-- Dave Kelsey ---XFAIL-- --SKIPIF-- ---SKIPIF-- - --POST_RAW-- Content-type: multipart/form-data, boundary=AaB03x diff --git a/ext/standard/tests/file/realpath_basic2.phpt b/ext/standard/tests/file/realpath_basic2.phpt index b71feb98b..87fc8baaa 100644 --- a/ext/standard/tests/file/realpath_basic2.phpt +++ b/ext/standard/tests/file/realpath_basic2.phpt @@ -3,9 +3,9 @@ realpath() with relative directory --FILE-- --EXPECT-- diff --git a/ext/standard/tests/file/rename_variation6-win32.phpt b/ext/standard/tests/file/rename_variation6-win32.phpt new file mode 100644 index 000000000..6305447b9 --- /dev/null +++ b/ext/standard/tests/file/rename_variation6-win32.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test rename() function: usage variations-6 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: readlink(): Could not open file (error 2) in %s on line %d +bool(false) +string(%d) "%srename_variation6-win32.php.tmp" +bool(true) +Done diff --git a/ext/standard/tests/file/rename_variation6.phpt b/ext/standard/tests/file/rename_variation6.phpt index 25a4acf94..413dc6e04 100644 --- a/ext/standard/tests/file/rename_variation6.phpt +++ b/ext/standard/tests/file/rename_variation6.phpt @@ -1,7 +1,8 @@ --TEST-- -Test rename() function: usage variations-7 +Test rename() function: usage variations-6 --SKIPIF-- --FILE-- diff --git a/ext/standard/tests/file/rename_variation7-win32.phpt b/ext/standard/tests/file/rename_variation7-win32.phpt new file mode 100644 index 000000000..7bef31f22 --- /dev/null +++ b/ext/standard/tests/file/rename_variation7-win32.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test rename() function: usage variations-8 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Warning: symlink(): Could not fetch file information(error 2) in %s on line %d + +Warning: readlink(): Could not open file (error 2) in %s on line %d +bool(false) + +Warning: readlink(): Could not open file (error 2) in %s on line %d +bool(false) +Done diff --git a/ext/standard/tests/file/rename_variation7.phpt b/ext/standard/tests/file/rename_variation7.phpt index 47c2828d8..5b937728f 100644 --- a/ext/standard/tests/file/rename_variation7.phpt +++ b/ext/standard/tests/file/rename_variation7.phpt @@ -2,6 +2,7 @@ Test rename() function: usage variations-8 --SKIPIF-- --FILE-- diff --git a/ext/standard/tests/file/stat_variation8-win32.phpt b/ext/standard/tests/file/stat_variation8-win32.phpt index 13b78ebe6..079bd0d73 100644 --- a/ext/standard/tests/file/stat_variation8-win32.phpt +++ b/ext/standard/tests/file/stat_variation8-win32.phpt @@ -52,7 +52,7 @@ var_dump( compare_self_stat($old_stat) ); var_dump( compare_self_stat($new_stat) ); // compare the stat -$affected_members = array(7, 8, 9, 'size', 'atime', 'mtime'); +$affected_members = array(7, 9, 'size', 'mtime'); var_dump( compare_stats($old_stat, $new_stat, $affected_members, '!=') ); // clear the stat diff --git a/ext/standard/tests/file/touch_basic-win32.phpt b/ext/standard/tests/file/touch_basic-win32.phpt index 3f473fc48..b4ad29f03 100644 --- a/ext/standard/tests/file/touch_basic-win32.phpt +++ b/ext/standard/tests/file/touch_basic-win32.phpt @@ -2,7 +2,6 @@ Test touch() function : basic functionality --CREDITS-- Dave Kelsey ---XFAIL-- --SKIPIF-- ===DONE=== --EXPECTF-- @@ -117,4 +114,4 @@ file removed file removed -- removing /%s/unlinkVar9.tmp/file.tmp -- file removed -===DONE=== \ No newline at end of file +===DONE=== diff --git a/ext/standard/tests/file/windows_acls/bug44859_4.phpt b/ext/standard/tests/file/windows_acls/bug44859_4.phpt index fff90662e..c1768d02e 100644 --- a/ext/standard/tests/file/windows_acls/bug44859_4.phpt +++ b/ext/standard/tests/file/windows_acls/bug44859_4.phpt @@ -1,6 +1,6 @@ --TEST-- bug #44859 (incorrect result with NTFS ACL permissions, is_readable) ---CREDIT-- +--CREDITS-- Venkat Raman Don --SKIPIF-- +--CLEAN-- + +--EXPECTF-- +array(1) { + ["cases"]=> + array(5) { + ["Case.a"]=> + string(6) "avalue" + ["Case.b"]=> + string(12) "$dollar_sign" + ["Case.c"]=> + string(12) "dollar_sign$" + ["Case.d"]=> + string(13) "$dollar_sign$" + ["Case.e"]=> + string(2) "10" + } +} +array(1) { + ["cases"]=> + array(5) { + ["Case.a"]=> + string(6) "avalue" + ["Case.b"]=> + string(12) "$dollar_sign" + ["Case.c"]=> + string(12) "dollar_sign$" + ["Case.d"]=> + string(13) "$dollar_sign$" + ["Case.e"]=> + string(2) "10" + } +} diff --git a/ext/standard/tests/general_functions/bug48768.phpt b/ext/standard/tests/general_functions/bug48768.phpt new file mode 100644 index 000000000..ae8329ac4 --- /dev/null +++ b/ext/standard/tests/general_functions/bug48768.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #48768 (parse_ini_*() crashes with INI_SCANNER_RAW) +--FILE-- + +--CLEAN-- + +--EXPECT-- +array(1) { + ["equal"]=> + string(1) "=" +} +array(1) { + ["equal"]=> + string(1) "=" +} diff --git a/ext/standard/tests/general_functions/bug49056.phpt b/ext/standard/tests/general_functions/bug49056.phpt new file mode 100644 index 000000000..208766cce --- /dev/null +++ b/ext/standard/tests/general_functions/bug49056.phpt @@ -0,0 +1,26 @@ +--TEST-- +Bug #49056 (parse_ini_*() regression in 5.3.0 when using non-ASCII strings as option keys) +--FILE-- + +--CLEAN-- + +--EXPECT-- +array(2) { + ["Cooking_furniture"]=> + string(23) "Küchen Möbel (en)" + ["Küchen_Möbel"]=> + string(22) "Cooking furniture (en)" +} diff --git a/ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt b/ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt index ff715ff9b..340e4e5da 100644 --- a/ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt +++ b/ext/standard/tests/general_functions/call_user_func_array_variation_001.phpt @@ -1,59 +1,59 @@ ---TEST-- -call_user_func_array() passes by reference if the array element is referenced, regardless of function signature. ---FILE-- - ---EXPECTF-- ------- Calling by_val() with unreferenced argument ------ -array(1) { - [0]=> - string(8) "original" -} ------- Calling by_ref() with unreferenced argument ------ - -Warning: Parameter 1 to by_ref() expected to be a reference, value given in %s on line %d -array(1) { - [0]=> - string(8) "original" -} ------- Calling by_val() with referenced argument ------ -array(1) { - [0]=> - &string(7) "changed" -} ------- Calling by_ref() with referenced argument ------ -array(1) { - [0]=> - &string(7) "changed" -} +--TEST-- +call_user_func_array() passes by reference if the array element is referenced, regardless of function signature. +--FILE-- + +--EXPECTF-- +------ Calling by_val() with unreferenced argument ------ +array(1) { + [0]=> + string(8) "original" +} +------ Calling by_ref() with unreferenced argument ------ + +Warning: Parameter 1 to by_ref() expected to be a reference, value given in %s on line %d +array(1) { + [0]=> + string(8) "original" +} +------ Calling by_val() with referenced argument ------ +array(1) { + [0]=> + &string(7) "changed" +} +------ Calling by_ref() with referenced argument ------ +array(1) { + [0]=> + &string(7) "changed" +} diff --git a/ext/standard/tests/general_functions/get_cfg_var_basic.phpt b/ext/standard/tests/general_functions/get_cfg_var_basic.phpt new file mode 100644 index 000000000..3fb005655 --- /dev/null +++ b/ext/standard/tests/general_functions/get_cfg_var_basic.phpt @@ -0,0 +1,24 @@ +--TEST-- +Test function get_cfg_var() by calling it with its expected arguments +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--INI-- +session.use_cookies=0 +session.serialize_handler=php +session.save_handler=files +--FILE-- + +--EXPECTF-- +*** Test by calling method or function with its expected arguments *** +string(1) "0" +string(3) "php" +string(5) "files" diff --git a/ext/standard/tests/general_functions/get_cfg_var_error.phpt b/ext/standard/tests/general_functions/get_cfg_var_error.phpt new file mode 100644 index 000000000..1c319bf79 --- /dev/null +++ b/ext/standard/tests/general_functions/get_cfg_var_error.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test function get_cfg_var() by calling it more than or less than its expected arguments +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--INI-- +session.use_cookies=0 +session.serialize_handler=php +session.save_handler=files +--FILE-- + +--EXPECTF-- +*** Test by calling method or function with incorrect numbers of arguments *** + +Warning: get_cfg_var() expects exactly 1 parameter, 2 given in %s on line %d +NULL + +Warning: get_cfg_var() expects exactly 1 parameter, 0 given in %s on line %d +NULL diff --git a/ext/standard/tests/general_functions/get_cfg_var_variation1.phpt b/ext/standard/tests/general_functions/get_cfg_var_variation1.phpt new file mode 100644 index 000000000..4e59f288e --- /dev/null +++ b/ext/standard/tests/general_functions/get_cfg_var_variation1.phpt @@ -0,0 +1,46 @@ +--TEST-- +Test function get_cfg_var() by substituting argument 1 with array values. +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--INI-- +session.use_cookies=0 +session.serialize_handler=php +session.save_handler=files +--FILE-- + 'one', 2 => 'two'); + +$variation_array = array( + 'empty array' => array(), + 'int indexed array' => $index_array, + 'associative array' => $assoc_array, + 'nested arrays' => array('foo', $index_array, $assoc_array), + ); + + +foreach ( $variation_array as $var ) { + var_dump(get_cfg_var( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with array values *** + +Warning: get_cfg_var() expects parameter 1 to be string, array given in %s on line %d +NULL + +Warning: get_cfg_var() expects parameter 1 to be string, array given in %s on line %d +NULL + +Warning: get_cfg_var() expects parameter 1 to be string, array given in %s on line %d +NULL + +Warning: get_cfg_var() expects parameter 1 to be string, array given in %s on line %d +NULL diff --git a/ext/standard/tests/general_functions/get_cfg_var_variation2.phpt b/ext/standard/tests/general_functions/get_cfg_var_variation2.phpt new file mode 100644 index 000000000..68495a13d --- /dev/null +++ b/ext/standard/tests/general_functions/get_cfg_var_variation2.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test function get_cfg_var() by substituting argument 1 with boolean values. +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--INI-- +session.use_cookies=0 +session.serialize_handler=php +session.save_handler=files +--FILE-- + true, + 'lowercase false' =>false, + 'uppercase TRUE' =>TRUE, + 'uppercase FALSE' =>FALSE, + ); + + +foreach ( $variation_array as $var ) { + var_dump(get_cfg_var( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with boolean values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/get_cfg_var_variation3.phpt b/ext/standard/tests/general_functions/get_cfg_var_variation3.phpt new file mode 100644 index 000000000..d1fb5e7dd --- /dev/null +++ b/ext/standard/tests/general_functions/get_cfg_var_variation3.phpt @@ -0,0 +1,42 @@ +--TEST-- +Test function get_cfg_var() by substituting argument 1 with emptyUnsetUndefNull values. +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--INI-- +session.use_cookies=0 +session.serialize_handler=php +session.save_handler=files +--FILE-- + @$unset_var, + 'undefined var' => @$undefined_var, + 'empty string DQ' => "", + 'empty string SQ' => '', + 'uppercase NULL' => NULL, + 'lowercase null' => null + ); + + +foreach ( $variation_array as $var ) { + var_dump(get_cfg_var( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with emptyUnsetUndefNull values *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/get_cfg_var_variation4.phpt b/ext/standard/tests/general_functions/get_cfg_var_variation4.phpt new file mode 100644 index 000000000..8dac4f8a4 --- /dev/null +++ b/ext/standard/tests/general_functions/get_cfg_var_variation4.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test function get_cfg_var() by substituting argument 1 with float values. +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--INI-- +session.use_cookies=0 +session.serialize_handler=php +session.save_handler=files +--FILE-- + 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 12.3456789000e10, + 'float -12.3456789000e10' => -12.3456789000e10, + 'float .5' => .5, + ); + + +foreach ( $variation_array as $var ) { + var_dump(get_cfg_var( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with float values *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/get_cfg_var_variation5.phpt b/ext/standard/tests/general_functions/get_cfg_var_variation5.phpt new file mode 100644 index 000000000..392abb32c --- /dev/null +++ b/ext/standard/tests/general_functions/get_cfg_var_variation5.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test function get_cfg_var() by substituting argument 1 with int values. +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--INI-- +session.use_cookies=0 +session.serialize_handler=php +session.save_handler=files +--FILE-- + 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + ); + + +foreach ( $variation_array as $var ) { + var_dump(get_cfg_var( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with int values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/get_cfg_var_variation6.phpt b/ext/standard/tests/general_functions/get_cfg_var_variation6.phpt new file mode 100644 index 000000000..d142621a1 --- /dev/null +++ b/ext/standard/tests/general_functions/get_cfg_var_variation6.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test function get_cfg_var() by substituting argument 1 with object values. +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--INI-- +session.use_cookies=0 +session.serialize_handler=php +session.save_handler=files +--FILE-- + new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + ); + + +foreach ( $variation_array as $var ) { + var_dump(get_cfg_var( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with object values *** +string(1) "0" + +Warning: get_cfg_var() expects parameter 1 to be string, object given in %s.php on line %d +NULL diff --git a/ext/standard/tests/general_functions/get_cfg_var_variation7.phpt b/ext/standard/tests/general_functions/get_cfg_var_variation7.phpt new file mode 100644 index 000000000..3b5b08c6d --- /dev/null +++ b/ext/standard/tests/general_functions/get_cfg_var_variation7.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test function get_cfg_var() by substituting argument 1 with string values. +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--INI-- +session.use_cookies=0 +session.serialize_handler=php +session.save_handler=files +--FILE-- + "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc + ); + + +foreach ( $variation_array as $var ) { + var_dump(get_cfg_var( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with unknown string values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/get_cfg_var_variation8.phpt b/ext/standard/tests/general_functions/get_cfg_var_variation8.phpt new file mode 100644 index 000000000..22188c7e6 --- /dev/null +++ b/ext/standard/tests/general_functions/get_cfg_var_variation8.phpt @@ -0,0 +1,20 @@ +--TEST-- +Test function get_cfg_var() by calling deprecated option +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--INI-- +register_globals=1 +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +PHP Warning: Directive 'register_globals' is deprecated in PHP 5.3 and greater in %s on line 0 +*** Test by calling method or function with deprecated option *** +string(1) "1" + diff --git a/ext/standard/tests/general_functions/get_cfg_var_variation9.phpt b/ext/standard/tests/general_functions/get_cfg_var_variation9.phpt new file mode 100644 index 000000000..6e0ffc51f --- /dev/null +++ b/ext/standard/tests/general_functions/get_cfg_var_variation9.phpt @@ -0,0 +1,37 @@ +--TEST-- +Test function get_cfg_var() by substituting argument with array of valid parameters. +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--INI-- +session.use_cookies=0 +session.serialize_handler=php +session.save_handler=files +--FILE-- + +--EXPECTF-- +*** Test substituting argument with array of valid parameters *** +string(1) "0" +string(3) "php" +string(5) "files" diff --git a/ext/standard/tests/general_functions/get_defined_constants_basic.phpt b/ext/standard/tests/general_functions/get_defined_constants_basic.phpt new file mode 100644 index 000000000..9e2e66c94 --- /dev/null +++ b/ext/standard/tests/general_functions/get_defined_constants_basic.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test get_defined_constants() function : basic functionality +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing get_defined_constants() : basic functionality *** +string(5) "array" +string(5) "array" +array(0) { +} +TEST PASSED +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/general_functions/get_defined_constants_error.phpt b/ext/standard/tests/general_functions/get_defined_constants_error.phpt new file mode 100644 index 000000000..1092712ee --- /dev/null +++ b/ext/standard/tests/general_functions/get_defined_constants_error.phpt @@ -0,0 +1,25 @@ +--TEST-- +Test get_defined_constants() function : error conditions +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing get_defined_constants() : error conditions *** + +-- Testing get_defined_constants() function with more than expected no. of arguments -- + +Warning: get_defined_constants() expects at most 1 parameter, 2 given in %s on line 11 +NULL +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/general_functions/get_loaded_extensions_basic.phpt b/ext/standard/tests/general_functions/get_loaded_extensions_basic.phpt new file mode 100644 index 000000000..4a8eceb24 --- /dev/null +++ b/ext/standard/tests/general_functions/get_loaded_extensions_basic.phpt @@ -0,0 +1,23 @@ +--TEST-- +Test get_loaded_extensions() function : basic functionality +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing get_loaded_extensions() : basic functionality *** +Get loaded extensions +array(%d) { +%a +} +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/general_functions/get_loaded_extensions_error.phpt b/ext/standard/tests/general_functions/get_loaded_extensions_error.phpt new file mode 100644 index 000000000..d731046dc --- /dev/null +++ b/ext/standard/tests/general_functions/get_loaded_extensions_error.phpt @@ -0,0 +1,26 @@ +--TEST-- +Test get_loaded_extensions() function : error conditions +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing get_loaded_extensions() : error conditions *** + +-- Testing get_loaded_extensions() function with more than expected no. of arguments -- + +Warning: get_resource_type() expects exactly 1 parameter, 2 given in %s on line %d +NULL +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/general_functions/get_resource_type_basic.phpt b/ext/standard/tests/general_functions/get_resource_type_basic.phpt new file mode 100644 index 000000000..7ff4aec2c --- /dev/null +++ b/ext/standard/tests/general_functions/get_resource_type_basic.phpt @@ -0,0 +1,20 @@ +--TEST-- +Test get_resource_type() function : basic functionality +--FILE-- + +===DONE=== +--EXPECT-- +*** Testing get_resource_type() : basic functionality *** +string(6) "stream" +===DONE=== diff --git a/ext/standard/tests/general_functions/get_resource_type_error.phpt b/ext/standard/tests/general_functions/get_resource_type_error.phpt new file mode 100644 index 000000000..40dcf0779 --- /dev/null +++ b/ext/standard/tests/general_functions/get_resource_type_error.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test get_resource_type() function : error conditions +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing get_resource_type() : error conditions *** + +-- Testing get_resource_type() function with Zero arguments -- + +Warning: get_resource_type() expects exactly 1 parameter, 0 given in %s on line %d +NULL + +-- Testing get_resource_type() function with more than expected no. of arguments -- + +Warning: get_resource_type() expects exactly 1 parameter, 2 given in %s on line %d +NULL +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/general_functions/get_resource_type_variation1.phpt b/ext/standard/tests/general_functions/get_resource_type_variation1.phpt new file mode 100644 index 000000000..2c203af1f --- /dev/null +++ b/ext/standard/tests/general_functions/get_resource_type_variation1.phpt @@ -0,0 +1,74 @@ +--TEST-- +Test get_resource_type() function : usage variations - different data types as handle arg +--FILE-- +true, + "int 10"=>10, + "float 10.5"=>10.5, + "string"=>"Hello World", + "array"=>array(1,2,3,4,5), + "NULL"=>NULL, + "Object"=>new Hello() +); + +foreach($vars as $variation =>$object) { + echo "\n-- $variation --\n"; + var_dump(get_resource_type($object)); +}; + +?> +===DONE=== +--EXPECTF-- +*** Testing get_resource_type() : variation test *** + +-- bool -- + +Warning: get_resource_type() expects parameter 1 to be resource, boolean given in %s on line %d +NULL + +-- int 10 -- + +Warning: get_resource_type() expects parameter 1 to be resource, integer given in %s on line %d +NULL + +-- float 10.5 -- + +Warning: get_resource_type() expects parameter 1 to be resource, double given in %s on line %d +NULL + +-- string -- + +Warning: get_resource_type() expects parameter 1 to be resource, string given in %s on line %d +NULL + +-- array -- + +Warning: get_resource_type() expects parameter 1 to be resource, array given in %s on line %d +NULL + +-- NULL -- + +Warning: get_resource_type() expects parameter 1 to be resource, null given in %s on line %d +NULL + +-- Object -- + +Warning: get_resource_type() expects parameter 1 to be resource, object given in %s on line %d +NULL +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/general_functions/getservbyname_basic.phpt b/ext/standard/tests/general_functions/getservbyname_basic.phpt new file mode 100755 index 000000000..164e71afd --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_basic.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test function getservbyport() by calling it more than or less than its expected arguments +--CREDITS-- +Italian PHP TestFest 2009 Cesena 19-20-21 june +Fabio Fabbrucci (fabbrucci@grupporetina.com) +Michele Orselli (mo@ideato.it) +Simone Gentili (sensorario@gmail.com) +--FILE-- + +--EXPECTF-- +int(%d) +int(%d) +int(%d) +int(%d) +int(%d) +int(%d) +int(%d) +int(%d) +int(%d) +int(%d) +int(%d) diff --git a/ext/standard/tests/general_functions/getservbyname_error.phpt b/ext/standard/tests/general_functions/getservbyname_error.phpt new file mode 100755 index 000000000..eaeec6488 --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_error.phpt @@ -0,0 +1,21 @@ +--TEST-- +Test function getservbyname() by calling it more than or less than its expected arguments +--CREDITS-- +Italian PHP TestFest 2009 Cesena 19-20-21 june +Fabio Fabbrucci (fabbrucci@grupporetina.com) +Michele Orselli (mo@ideato.it) +Danilo Sanchi (sanchi@grupporetina.com) +--FILE-- + +--EXPECTF-- +Warning: getservbyname() expects exactly 2 parameters, %d given in %s on line %d +NULL + +Warning: getservbyname() expects exactly 2 parameters, %d given in %s on line %d +NULL diff --git a/ext/standard/tests/general_functions/getservbyname_variation1.phpt b/ext/standard/tests/general_functions/getservbyname_variation1.phpt new file mode 100755 index 000000000..7dd01aab3 --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation1.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test function getservbyname() by substituting argument 1 with array values. +--FILE-- + 'one', 2 => 'two'); + +$variation_array = array( + 'empty array' => array(), + 'int indexed array' => $index_array, + 'associative array' => $assoc_array, + 'nested arrays' => array('foo', $index_array, $assoc_array), + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $var , $protocol ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with array values *** + +Warning: getservbyname() expects parameter 1 to be string, array given in %s on line %d +NULL + +Warning: getservbyname() expects parameter 1 to be string, array given in %s on line %d +NULL + +Warning: getservbyname() expects parameter 1 to be string, array given in %s on line %d +NULL + +Warning: getservbyname() expects parameter 1 to be string, array given in %s on line %d +NULL diff --git a/ext/standard/tests/general_functions/getservbyname_variation10.phpt b/ext/standard/tests/general_functions/getservbyname_variation10.phpt new file mode 100755 index 000000000..70aa56764 --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation10.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test function getservbyname() by substituting argument 2 with emptyUnsetUndefNull values. +--FILE-- + @$unset_var, + 'undefined var' => @$undefined_var, + 'empty string DQ' => "", + 'empty string SQ' => '', + 'uppercase NULL' => NULL, + 'lowercase null' => null, + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $service, $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 2 with emptyUnsetUndefNull values *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/getservbyname_variation11.phpt b/ext/standard/tests/general_functions/getservbyname_variation11.phpt new file mode 100755 index 000000000..3c410c55b --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation11.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test function getservbyname() by substituting argument 2 with float values. +--FILE-- + 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 12.3456789000e10, + 'float -12.3456789000e10' => -12.3456789000e10, + 'float .5' => .5, + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $service, $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 2 with float values *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/getservbyname_variation12.phpt b/ext/standard/tests/general_functions/getservbyname_variation12.phpt new file mode 100755 index 000000000..7e5323cca --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation12.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test function getservbyname() by substituting argument 2 with int values. +--FILE-- + 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $service, $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 2 with int values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/getservbyname_variation13.phpt b/ext/standard/tests/general_functions/getservbyname_variation13.phpt new file mode 100755 index 000000000..8dad8cda5 --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation13.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test function getservbyname() by substituting argument 2 with object values. +--FILE-- + new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $service, $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 2 with object values *** +bool(false) + +Warning: getservbyname() expects parameter 2 to be string, object given in %s.php on line %d +NULL diff --git a/ext/standard/tests/general_functions/getservbyname_variation14.phpt b/ext/standard/tests/general_functions/getservbyname_variation14.phpt new file mode 100755 index 000000000..d93b53ece --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation14.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test function getservbyname() by substituting argument 2 with string values. +--FILE-- + "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $service, $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 2 with string values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/getservbyname_variation2.phpt b/ext/standard/tests/general_functions/getservbyname_variation2.phpt new file mode 100755 index 000000000..877c1d12a --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation2.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test function getservbyname() by substituting argument 1 with boolean values. +--FILE-- + true, + 'lowercase false' =>false, + 'uppercase TRUE' =>TRUE, + 'uppercase FALSE' =>FALSE, + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $var , $protocol ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with boolean values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/getservbyname_variation3.phpt b/ext/standard/tests/general_functions/getservbyname_variation3.phpt new file mode 100755 index 000000000..d34259d2a --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation3.phpt @@ -0,0 +1,36 @@ +--TEST-- +Test function getservbyname() by substituting argument 1 with emptyUnsetUndefNull values. +--FILE-- + @$unset_var, + 'undefined var' => @$undefined_var, + 'empty string DQ' => "", + 'empty string SQ' => '', + 'uppercase NULL' => NULL, + 'lowercase null' => null, + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $var , $protocol ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with emptyUnsetUndefNull values *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/getservbyname_variation4.phpt b/ext/standard/tests/general_functions/getservbyname_variation4.phpt new file mode 100755 index 000000000..6033c9436 --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation4.phpt @@ -0,0 +1,31 @@ +--TEST-- +Test function getservbyname() by substituting argument 1 with float values. +--FILE-- + 10.5, + 'float -10.5' => -10.5, + 'float 12.3456789000e10' => 12.3456789000e10, + 'float -12.3456789000e10' => -12.3456789000e10, + 'float .5' => .5, + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $var , $protocol ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with float values *** +bool(false) +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/getservbyname_variation5.phpt b/ext/standard/tests/general_functions/getservbyname_variation5.phpt new file mode 100755 index 000000000..1d3b8f6d7 --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation5.phpt @@ -0,0 +1,29 @@ +--TEST-- +Test function getservbyname() by substituting argument 1 with int values. +--FILE-- + 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $var , $protocol ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with int values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/getservbyname_variation6.phpt b/ext/standard/tests/general_functions/getservbyname_variation6.phpt new file mode 100755 index 000000000..0dfafa622 --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation6.phpt @@ -0,0 +1,38 @@ +--TEST-- +Test function getservbyname() by substituting argument 1 with object values. +--FILE-- + new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $var , $protocol ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with object values *** +bool(false) + +Warning: getservbyname() expects parameter 1 to be string, object given in %s.php on line %d +NULL diff --git a/ext/standard/tests/general_functions/getservbyname_variation7.phpt b/ext/standard/tests/general_functions/getservbyname_variation7.phpt new file mode 100755 index 000000000..a0e223c50 --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation7.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test function getservbyname() by substituting argument 1 with string values. +--FILE-- + "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $var , $protocol ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with string values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/getservbyname_variation8.phpt b/ext/standard/tests/general_functions/getservbyname_variation8.phpt new file mode 100755 index 000000000..69d1d77b6 --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation8.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test function getservbyname() by substituting argument 2 with array values. +--FILE-- + 'one', 2 => 'two'); + +$variation_array = array( + 'empty array' => array(), + 'int indexed array' => $index_array, + 'associative array' => $assoc_array, + 'nested arrays' => array('foo', $index_array, $assoc_array), + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $service, $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 2 with array values *** + +Warning: getservbyname() expects parameter 2 to be string, array given in %s on line %d +NULL + +Warning: getservbyname() expects parameter 2 to be string, array given in %s on line %d +NULL + +Warning: getservbyname() expects parameter 2 to be string, array given in %s on line %d +NULL + +Warning: getservbyname() expects parameter 2 to be string, array given in %s on line %d +NULL diff --git a/ext/standard/tests/general_functions/getservbyname_variation9.phpt b/ext/standard/tests/general_functions/getservbyname_variation9.phpt new file mode 100755 index 000000000..c1c231e14 --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyname_variation9.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test function getservbyname() by substituting argument 2 with boolean values. +--FILE-- + true, + 'lowercase false' =>false, + 'uppercase TRUE' =>TRUE, + 'uppercase FALSE' =>FALSE, + ); + + +foreach ( $variation_array as $var ) { + var_dump(getservbyname( $service, $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 2 with boolean values *** +bool(false) +bool(false) +bool(false) +bool(false) diff --git a/ext/standard/tests/general_functions/getservbyport_basic.phpt b/ext/standard/tests/general_functions/getservbyport_basic.phpt new file mode 100644 index 000000000..1695455ab --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyport_basic.phpt @@ -0,0 +1,26 @@ +--TEST-- +Test function getservbyport() by calling it more than or less than its expected arguments +--CREDITS-- +Italian PHP TestFest 2009 Cesena 19-20-21 june +Fabio Fabbrucci (fabbrucci@grupporetina.com) +Michele Orselli (mo@ideato.it) +Simone Gentili (sensorario@gmail.com) +--FILE-- + +--EXPECT-- +PASS diff --git a/ext/standard/tests/general_functions/getservbyport_error.phpt b/ext/standard/tests/general_functions/getservbyport_error.phpt new file mode 100644 index 000000000..e2c245b7e --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyport_error.phpt @@ -0,0 +1,21 @@ +--TEST-- +Test function getservbyport() by calling it more than or less than its expected arguments +--CREDITS-- +Italian PHP TestFest 2009 Cesena 19-20-21 june +Fabio Fabbrucci (fabbrucci@grupporetina.com) +Michele Orselli (mo@ideato.it) +Simone Gentili (sensorario@gmail.com) +--FILE-- + +--EXPECTF-- +Warning: getservbyport() expects exactly 2 parameters, %d given in %s on line %d +NULL + +Warning: getservbyport() expects exactly 2 parameters, %d given in %s on line %d +NULL diff --git a/ext/standard/tests/general_functions/getservbyport_variation1.phpt b/ext/standard/tests/general_functions/getservbyport_variation1.phpt new file mode 100644 index 000000000..3dd2d9abb --- /dev/null +++ b/ext/standard/tests/general_functions/getservbyport_variation1.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test function getservbyport() by calling it more than or less than its expected arguments +--DESCRIPTION-- +Test function passing invalid port number and invalid protocol name +--CREDITS-- +Italian PHP TestFest 2009 Cesena 19-20-21 june +Fabio Fabbrucci (fabbrucci@grupporetina.com) +Michele Orselli (mo@ideato.it) +Simone Gentili (sensorario@gmail.com) +--FILE-- +1, "two"=>2))); + var_dump(getservbyport( 2, 2)); + var_dump(getservbyport( "80", "tcp")); + var_dump(getservbyport( new stdClass(), new stdClass())); + +?> +--EXPECTF-- +bool(false) +bool(false) +bool(false) + +Warning: getservbyport() expects parameter 1 to be long, array given in %s on line %d +NULL + +Warning: getservbyport() expects parameter 1 to be long, array given in %s on line %d +NULL + +Warning: getservbyport() expects parameter 1 to be long, array given in %s on line %d +NULL +bool(false) +string(%d) "%s" + +Warning: getservbyport() expects parameter 1 to be long, object given in %s on line %d +NULL diff --git a/ext/standard/tests/general_functions/is_resource_basic.phpt b/ext/standard/tests/general_functions/is_resource_basic.phpt new file mode 100644 index 000000000..27583d3d8 --- /dev/null +++ b/ext/standard/tests/general_functions/is_resource_basic.phpt @@ -0,0 +1,92 @@ +--TEST-- +Test is_resource() function : basic functionality +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing is_resource() : basic functionality *** + +Non-resource type cases +bool=false test returns FALSE +bool=true test returns FALSE +integer test returns FALSE +double test returns FALSE +string test returns FALSE +array test returns FALSE +NULL test returns FALSE +object test returns FALSE + +Resource type..var_dump after file open returns +resource(%d) of type (%s) +Resource type..after file open is_resource() returns TRUE + +Resource type..var_dump after file close returns +resource(%d) of type (Unknown) +Resource type..after file close is_resource() returns FALSE +===DONE=== diff --git a/ext/standard/tests/general_functions/is_resource_error.phpt b/ext/standard/tests/general_functions/is_resource_error.phpt new file mode 100644 index 000000000..acb3cb660 --- /dev/null +++ b/ext/standard/tests/general_functions/is_resource_error.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test is_resource() function : error conditions +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing is_resource() : error conditions *** + +-- Testing is_resource() function with Zero arguments -- + +Warning: is_resource() expects exactly 1 parameter, 0 given in %s on line %d +bool(false) + +-- Testing is_resource() function with more than expected no. of arguments -- + +Warning: is_resource() expects exactly 1 parameter, 2 given in %s on line %d +bool(false) +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/general_functions/isset_basic1.phpt b/ext/standard/tests/general_functions/isset_basic1.phpt new file mode 100644 index 000000000..4c0321034 --- /dev/null +++ b/ext/standard/tests/general_functions/isset_basic1.phpt @@ -0,0 +1,66 @@ +--TEST-- +Test isset() function : basic functionality +--FILE-- + +===DONE=== +--EXPECT-- +*** Testing isset() : basic functionality *** +Integer test: YES +Float test: YES +String test: YES +Array test: YES +Boolean test: YES +Null test: NO +Object test: YES +Resource test: YES + + +Unset the variables + +Integer test: NO +Float test: NO +String test: NO +Array test: NO +Boolean test: NO +Null test: NO +Object test: NO +Resource test: NO +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/general_functions/isset_basic2.phpt b/ext/standard/tests/general_functions/isset_basic2.phpt new file mode 100644 index 000000000..9137aeb92 --- /dev/null +++ b/ext/standard/tests/general_functions/isset_basic2.phpt @@ -0,0 +1,60 @@ +--TEST-- +Test isset() function : basic functionality +--FILE-- + +===DONE=== +--EXPECT-- +*** Testing isset() : basic functionality *** +Test multiple scalar variables in a group +bool(true) +bool(false) +Unset a few +Test again +bool(false) + + +Array test: +bool(false) +bool(false) +bool(false) +..now set +bool(true) +bool(true) +bool(true) +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/general_functions/phpcredits2.phpt b/ext/standard/tests/general_functions/phpcredits2.phpt index 9c5148b1d..ee17f598f 100644 --- a/ext/standard/tests/general_functions/phpcredits2.phpt +++ b/ext/standard/tests/general_functions/phpcredits2.phpt @@ -1,7 +1,5 @@ --TEST-- phpcredits() CGI ---SKIPIF-- - --POST-- dummy=x --FILE-- diff --git a/ext/standard/tests/general_functions/phpinfo2.phpt b/ext/standard/tests/general_functions/phpinfo2.phpt index cf65e0c98..891867f2e 100644 --- a/ext/standard/tests/general_functions/phpinfo2.phpt +++ b/ext/standard/tests/general_functions/phpinfo2.phpt @@ -1,7 +1,5 @@ --TEST-- phpinfo() CGI ---SKIPIF-- - --POST-- dummy=x --FILE-- diff --git a/ext/standard/tests/general_functions/proc_nice_basic.phpt b/ext/standard/tests/general_functions/proc_nice_basic.phpt new file mode 100644 index 000000000..5a9575627 --- /dev/null +++ b/ext/standard/tests/general_functions/proc_nice_basic.phpt @@ -0,0 +1,27 @@ +--TEST-- +proc_nice() basic behaviour +--CREDITS-- +Italian PHP TestFest 2009 Cesena 19-20-21 june +Fabio Fabbrucci (fabbrucci@grupporetina.com) +Michele Orselli (mo@ideato.it) +Simone Gentili (sensorario@gmail.com) +--FILE-- + 2) + return $matches[2]; + else + return -1; + } + $delta = 10; + $pid = getmypid(); + $niceBefore = getNice($pid); + proc_nice($delta); + $niceAfter = getNice($pid); + var_dump($niceBefore == ($niceAfter - $delta)); +?> +--EXPECTF-- +bool(true) diff --git a/ext/standard/tests/general_functions/proc_nice_error.phpt b/ext/standard/tests/general_functions/proc_nice_error.phpt new file mode 100644 index 000000000..c50812c86 --- /dev/null +++ b/ext/standard/tests/general_functions/proc_nice_error.phpt @@ -0,0 +1,21 @@ +--TEST-- +Test function proc_nice() by calling it more than or less than its expected arguments +--FILE-- + +--EXPECTF-- +Parse error: syntax error, unexpected T_VARIABLE, expecting ',' or ';' in %s on line %d diff --git a/ext/standard/tests/general_functions/proc_nice_variation1.phpt b/ext/standard/tests/general_functions/proc_nice_variation1.phpt new file mode 100644 index 000000000..b86155c4b --- /dev/null +++ b/ext/standard/tests/general_functions/proc_nice_variation1.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test function proc_nice() by substituting argument 1 with array values. +--CREDITS-- +Italian PHP TestFest 2009 Cesena 19-20-21 june +Fabio Fabbrucci (fabbrucci@grupporetina.com) +Michele Orselli (mo@ideato.it) +Simone Gentili (sensorario@gmail.com) +--FILE-- + 'one', 2 => 'two'); + +$variation_array = array( + 'empty array' => array(), + 'int indexed array' => $index_array, + 'associative array' => $assoc_array, + 'nested arrays' => array('foo', $index_array, $assoc_array), + ); + + +foreach ( $variation_array as $var ) { + var_dump(proc_nice( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with array values *** + +Warning: proc_nice() expects parameter 1 to be long, array given in %s on line %d +bool(false) + +Warning: proc_nice() expects parameter 1 to be long, array given in %s on line %d +bool(false) + +Warning: proc_nice() expects parameter 1 to be long, array given in %s on line %d +bool(false) + +Warning: proc_nice() expects parameter 1 to be long, array given in %s on line %d +bool(false) diff --git a/ext/standard/tests/general_functions/proc_nice_variation2.phpt b/ext/standard/tests/general_functions/proc_nice_variation2.phpt new file mode 100644 index 000000000..620fe9144 --- /dev/null +++ b/ext/standard/tests/general_functions/proc_nice_variation2.phpt @@ -0,0 +1,33 @@ +--TEST-- +Test function proc_nice() by substituting argument 1 with boolean values. +--CREDITS-- +Italian PHP TestFest 2009 Cesena 19-20-21 june +Fabio Fabbrucci (fabbrucci@grupporetina.com) +Michele Orselli (mo@ideato.it) +Simone Gentili (sensorario@gmail.com) +--FILE-- + true, + 'lowercase false' =>false, + 'uppercase TRUE' =>TRUE, + 'uppercase FALSE' =>FALSE, + ); + + +foreach ( $variation_array as $var ) { + var_dump(proc_nice( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with boolean values *** +bool(true) +bool(true) +bool(true) +bool(true) diff --git a/ext/standard/tests/general_functions/proc_nice_variation3.phpt b/ext/standard/tests/general_functions/proc_nice_variation3.phpt new file mode 100644 index 000000000..458126db4 --- /dev/null +++ b/ext/standard/tests/general_functions/proc_nice_variation3.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test function proc_nice() by substituting argument 1 with emptyUnsetUndefNull values. +--CREDITS-- +Italian PHP TestFest 2009 Cesena 19-20-21 june +Fabio Fabbrucci (fabbrucci@grupporetina.com) +Michele Orselli (mo@ideato.it) +Simone Gentili (sensorario@gmail.com) +--FILE-- + @$unset_var, + 'undefined var' => @$undefined_var, + 'empty string DQ' => "", + 'empty string SQ' => '', + 'uppercase NULL' => NULL, + 'lowercase null' => null, + ); + + +foreach ( $variation_array as $var ) { + var_dump(proc_nice( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with emptyUnsetUndefNull values *** +bool(true) +bool(true) + +Warning: proc_nice() expects parameter 1 to be long, string given in %s on line %d +bool(false) + +Warning: proc_nice() expects parameter 1 to be long, string given in %s on line %d +bool(false) +bool(true) +bool(true) diff --git a/ext/standard/tests/general_functions/proc_nice_variation5.phpt b/ext/standard/tests/general_functions/proc_nice_variation5.phpt new file mode 100644 index 000000000..d8325106b --- /dev/null +++ b/ext/standard/tests/general_functions/proc_nice_variation5.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test function proc_nice() by substituting argument 1 with int values. +--CREDITS-- +Italian PHP TestFest 2009 Cesena 19-20-21 june +Fabio Fabbrucci (fabbrucci@grupporetina.com) +Michele Orselli (mo@ideato.it) +Simone Gentili (sensorario@gmail.com) +--FILE-- + 0, + 'int 1' => 1, + 'int 12345' => 12345, + 'int -12345' => -2345, + ); + + +foreach ( $variation_array as $var ) { + var_dump(proc_nice( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with int values *** +bool(true) +bool(true) +bool(true) + +Warning: proc_nice(): Only a super user may attempt to increase the priority of a process in %s on line %d +bool(false) diff --git a/ext/standard/tests/general_functions/proc_nice_variation6.phpt b/ext/standard/tests/general_functions/proc_nice_variation6.phpt new file mode 100644 index 000000000..b4babd593 --- /dev/null +++ b/ext/standard/tests/general_functions/proc_nice_variation6.phpt @@ -0,0 +1,52 @@ +--TEST-- +Test function proc_nice() by substituting argument 1 with object values. +--CREDITS-- +Italian PHP TestFest 2009 Cesena 19-20-21 june +Fabio Fabbrucci (fabbrucci@grupporetina.com) +Michele Orselli (mo@ideato.it) +Simone Gentili (sensorario@gmail.com) +--FILE-- + new classWithToString(), + 'instance of classWithoutToString' => new classWithoutToString(), + ); + + +foreach ( $variation_array as $var ) { + var_dump(proc_nice( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with object values *** +Error: 2 - proc_nice() expects parameter 1 to be long, object given, %s(%d) +bool(false) +Error: 2 - proc_nice() expects parameter 1 to be long, object given, %s(%d) +bool(false) diff --git a/ext/standard/tests/general_functions/proc_nice_variation7.phpt b/ext/standard/tests/general_functions/proc_nice_variation7.phpt new file mode 100644 index 000000000..70487dd09 --- /dev/null +++ b/ext/standard/tests/general_functions/proc_nice_variation7.phpt @@ -0,0 +1,45 @@ +--TEST-- +Test function proc_nice() by substituting argument 1 with string values. +--CREDITS-- +Italian PHP TestFest 2009 Cesena 19-20-21 june +Fabio Fabbrucci (fabbrucci@grupporetina.com) +Michele Orselli (mo@ideato.it) +Simone Gentili (sensorario@gmail.com) +--FILE-- + "string", + 'string SQ' => 'string', + 'mixed case string' => "sTrInG", + 'heredoc' => $heredoc, + ); + + +foreach ( $variation_array as $var ) { + var_dump(proc_nice( $var ) ); +} +?> +--EXPECTF-- +*** Test substituting argument 1 with string values *** + +Warning: proc_nice() expects parameter 1 to be long, string given in %s on line %d +bool(false) + +Warning: proc_nice() expects parameter 1 to be long, string given in %s on line %d +bool(false) + +Warning: proc_nice() expects parameter 1 to be long, string given in %s on line %d +bool(false) + +Warning: proc_nice() expects parameter 1 to be long, string given in %s on line %d +bool(false) diff --git a/ext/standard/tests/general_functions/sleep_basic.phpt b/ext/standard/tests/general_functions/sleep_basic.phpt new file mode 100644 index 000000000..cfc00c6ea --- /dev/null +++ b/ext/standard/tests/general_functions/sleep_basic.phpt @@ -0,0 +1,40 @@ +--TEST-- +Test sleep() function : basic functionality +--FILE-- += $sleeplow) { + echo "TEST PASSED\n"; +} else { + echo "TEST FAILED - time is ${time} secs and sleep was ${sleeptime} secs\n"; +} +?> +===DONE=== +--EXPECTF-- +*** Testing sleep() : basic functionality *** +Thread slept for %f seconds +TEST PASSED +===DONE=== diff --git a/ext/standard/tests/general_functions/sleep_error.phpt b/ext/standard/tests/general_functions/sleep_error.phpt new file mode 100644 index 000000000..199bd8e9b --- /dev/null +++ b/ext/standard/tests/general_functions/sleep_error.phpt @@ -0,0 +1,44 @@ +--TEST-- +Test sleep() function : error conditions +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing sleep() : error conditions *** + +-- Testing sleep() function with zero arguments -- + +Warning: sleep() expects exactly 1 parameter, 0 given in %s on line %d +bool(false) + +-- Testing sleep() function with more than expected no. of arguments -- + +Warning: sleep() expects exactly 1 parameter, 2 given in %s on line %d +bool(false) + +-- Testing sleep() function with negative interval -- + +Warning: sleep(): Number of seconds must be greater than or equal to 0 in %s on line %d +bool(false) +===DONE=== diff --git a/ext/standard/tests/general_functions/uniqid_basic.phpt b/ext/standard/tests/general_functions/uniqid_basic.phpt new file mode 100644 index 000000000..9a9c57332 --- /dev/null +++ b/ext/standard/tests/general_functions/uniqid_basic.phpt @@ -0,0 +1,73 @@ +--TEST-- +Test uniqid() function : basic functionality +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing uniqid() : basic functionality *** + +uniqid() without a prefix +string(13) "%s" +string(23) "%s.%s" +string(13) "%s" + + +uniqid() with a prefix +string(18) "99999%s" +string(28) "99999%s.%s" +string(18) "99999%s" + +string(18) "999994%s" +string(28) "999994%s.%s" +string(18) "999994%s" + +string(17) "1050%s" +string(27) "1050%s.%s" +string(17) "1050%s" + +string(13) "%s" +string(23) "%s.%s" +string(13) "%s" + +string(14) "1%s" +string(24) "1%s.%s" +string(14) "1%s" + +string(13) "%s" +string(23) "%s.%s" +string(13) "%s" + +===DONE=== + \ No newline at end of file diff --git a/ext/standard/tests/general_functions/uniqid_error.phpt b/ext/standard/tests/general_functions/uniqid_error.phpt new file mode 100644 index 000000000..96084313c --- /dev/null +++ b/ext/standard/tests/general_functions/uniqid_error.phpt @@ -0,0 +1,46 @@ +--TEST-- +Test uniqid() function : error conditions +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing uniqid() : error conditions *** + +-- Testing uniqid() function with more than expected no. of arguments -- + +Warning: uniqid() expects at most 2 parameters, 3 given in %s on line %d +NULL + +-- Testing uniqid() function with invalid values for $prefix -- + +Warning: uniqid() expects parameter 1 to be string, array given in %s on line %d + +Warning: uniqid() expects parameter 1 to be string, resource given in %s on line %d + +Warning: uniqid() expects parameter 1 to be string, object given in %s on line %d +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/general_functions/usleep_basic.phpt b/ext/standard/tests/general_functions/usleep_basic.phpt new file mode 100644 index 000000000..22c3e658b --- /dev/null +++ b/ext/standard/tests/general_functions/usleep_basic.phpt @@ -0,0 +1,39 @@ +--TEST-- +Test usleep() function +--FILE-- += $sleeplow) { + echo "TEST PASSED\n"; +} else { + echo "TEST FAILED\n"; +} +?> +===DONE=== +--EXPECTF-- +*** Testing usleep() : basic functionality *** +Thread slept for %f micro-seconds +TEST PASSED +===DONE=== diff --git a/ext/standard/tests/general_functions/usleep_error.phpt b/ext/standard/tests/general_functions/usleep_error.phpt new file mode 100644 index 000000000..bdd120cde --- /dev/null +++ b/ext/standard/tests/general_functions/usleep_error.phpt @@ -0,0 +1,45 @@ +--TEST-- +Test usleep() function : error conditions +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing usleep() : error conditions *** + +-- Testing usleep() function with zero arguments -- + +Warning: usleep() expects exactly 1 parameter, 0 given in %s on line %d +NULL + +-- Testing usleep() function with more than expected no. of arguments -- + +Warning: usleep() expects exactly 1 parameter, 2 given in %s on line %d +NULL + +-- Testing usleep() function with negative interval -- + +Warning: usleep(): Number of microseconds must be greater than or equal to 0 in %s on line %d +bool(false) +===DONE=== diff --git a/ext/standard/tests/general_functions/var_dump_64bit.phpt b/ext/standard/tests/general_functions/var_dump_64bit.phpt index fc076a0c2..3772536cf 100644 --- a/ext/standard/tests/general_functions/var_dump_64bit.phpt +++ b/ext/standard/tests/general_functions/var_dump_64bit.phpt @@ -462,7 +462,8 @@ string(34) "abcdefghijklmnop0qrstuvwx0yz" -- Iteration 14 -- string(22) "1234 5678 - 9100 abcda" + 9100 +abcda" *** Testing var_dump() on boolean variables *** -- Iteration 1 -- @@ -1302,7 +1303,8 @@ array(14) { [13]=> string(22) "1234 5678 - 9100 abcda" + 9100 +abcda" } array(15) { [0]=> diff --git a/ext/standard/tests/http/bug43510.phpt b/ext/standard/tests/http/bug43510.phpt new file mode 100644 index 000000000..7358ee12c --- /dev/null +++ b/ext/standard/tests/http/bug43510.phpt @@ -0,0 +1,28 @@ +--TEST-- +Bug #43510 (stream_get_meta_data() does not return same mode as used in fopen) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +string(1) "r" +string(2) "rb" diff --git a/ext/standard/tests/http/bug48929.phpt b/ext/standard/tests/http/bug48929.phpt new file mode 100644 index 000000000..035ebb12b --- /dev/null +++ b/ext/standard/tests/http/bug48929.phpt @@ -0,0 +1,56 @@ +--TEST-- +Bug #48929 (duplicate \r\n sent after last header line) +--SKIPIF-- + +--FILE-- + $context_options)); + + $responses = array( + "data://text/plain,HTTP/1.0 200 OK\r\n\r\n", + ); + + $pid = http_server("tcp://127.0.0.1:12342", $responses, $output); + + foreach($responses as $r) { + + $fd = fopen('http://127.0.0.1:12342/', 'rb', false, $context); + + fseek($output, 0, SEEK_SET); + var_dump(stream_get_contents($output)); + fseek($output, 0, SEEK_SET); + } + + http_server_kill($pid); +} + +echo "-- Test: requests with 'header' as array --\n"; + +do_test(array('header' => array('X-Foo: bar', 'Content-Type: text/plain'), 'method' => 'POST', 'content' => 'ohai')); + +echo "-- Test: requests with 'header' as string --\n"; + +do_test(array('header' => "X-Foo: bar\r\nContent-Type: text/plain", 'method' => 'POST', 'content' => 'ohai')); + +?> +--EXPECT-- +-- Test: requests with 'header' as array -- +string(103) "POST / HTTP/1.0 +Host: 127.0.0.1:12342 +Content-Length: 4 +X-Foo: bar +Content-Type: text/plain + +ohai" +-- Test: requests with 'header' as string -- +string(103) "POST / HTTP/1.0 +Host: 127.0.0.1:12342 +Content-Length: 4 +X-Foo: bar +Content-Type: text/plain + +ohai" diff --git a/ext/standard/tests/image/getimagesize_variation_003.phpt b/ext/standard/tests/image/getimagesize_variation_003.phpt index 42f409432..1de985065 100644 --- a/ext/standard/tests/image/getimagesize_variation_003.phpt +++ b/ext/standard/tests/image/getimagesize_variation_003.phpt @@ -1,70 +1,70 @@ ---TEST-- -Test getimagesize() function : variation - Passing non image files ---FILE-- - "test.txt", - - //File containing forcibly corrupted bmp image - "File with corrupted BMP data" => "200x100_unknown.unknown", - - //File which doesn't exist - "Non-existent file" => "nofile.ext", - - //File having no data - "Empty File" => "blank_file.bmp" -); - -echo "*** Testing getimagesize() : variation ***\n"; - -//loop through each element of the array for filename -foreach($file_types_array as $key => $filename) { - echo "\n-- $key ($filename) --\n"; - var_dump( getimagesize(dirname(__FILE__)."/$filename" ) ); - var_dump( getimagesize(dirname(__FILE__)."/$filename", $info) ); - var_dump( $info ); -}; -?> -===DONE=== ---EXPECTF-- -*** Testing getimagesize() : variation *** - --- File with text data (test.txt) -- -bool(false) -bool(false) -array(0) { -} - --- File with corrupted BMP data (200x100_unknown.unknown) -- -bool(false) -bool(false) -array(0) { -} - --- Non-existent file (nofile.ext) -- - -Warning: getimagesize(%s): failed to open stream: No such file or directory in %s on line %d -bool(false) - -Warning: getimagesize(%s): failed to open stream: No such file or directory in %s on line %d -bool(false) -array(0) { -} - --- Empty File (blank_file.bmp) -- - -Notice: getimagesize(): Read error! in %s on line %d -bool(false) - -Notice: getimagesize(): Read error! in %s on line %d -bool(false) -array(0) { -} +--TEST-- +Test getimagesize() function : variation - Passing non image files +--FILE-- + "test.txt", + + //File containing forcibly corrupted bmp image + "File with corrupted BMP data" => "200x100_unknown.unknown", + + //File which doesn't exist + "Non-existent file" => "nofile.ext", + + //File having no data + "Empty File" => "blank_file.bmp" +); + +echo "*** Testing getimagesize() : variation ***\n"; + +//loop through each element of the array for filename +foreach($file_types_array as $key => $filename) { + echo "\n-- $key ($filename) --\n"; + var_dump( getimagesize(dirname(__FILE__)."/$filename" ) ); + var_dump( getimagesize(dirname(__FILE__)."/$filename", $info) ); + var_dump( $info ); +}; +?> +===DONE=== +--EXPECTF-- +*** Testing getimagesize() : variation *** + +-- File with text data (test.txt) -- +bool(false) +bool(false) +array(0) { +} + +-- File with corrupted BMP data (200x100_unknown.unknown) -- +bool(false) +bool(false) +array(0) { +} + +-- Non-existent file (nofile.ext) -- + +Warning: getimagesize(%s): failed to open stream: No such file or directory in %s on line %d +bool(false) + +Warning: getimagesize(%s): failed to open stream: No such file or directory in %s on line %d +bool(false) +array(0) { +} + +-- Empty File (blank_file.bmp) -- + +Notice: getimagesize(): Read error! in %s on line %d +bool(false) + +Notice: getimagesize(): Read error! in %s on line %d +bool(false) +array(0) { +} ===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/image/getimagesize_variation_005.phpt b/ext/standard/tests/image/getimagesize_variation_005.phpt index 6b5f1a061..6f0ad8f19 100644 --- a/ext/standard/tests/image/getimagesize_variation_005.phpt +++ b/ext/standard/tests/image/getimagesize_variation_005.phpt @@ -1,38 +1,38 @@ ---TEST-- -Test getimagesize() function : basic functionality for shockwave-flash ---SKIPIF-- - ---FILE-- - -===DONE=== ---EXPECTF-- -*** Testing getimagesize() : basic functionality *** -array(5) { - [0]=> - int(550) - [1]=> - int(400) - [2]=> - int(13) - [3]=> - string(24) "width="550" height="400"" - ["mime"]=> - string(29) "application/x-shockwave-flash" -} -array(0) { -} +--TEST-- +Test getimagesize() function : basic functionality for shockwave-flash +--SKIPIF-- + +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing getimagesize() : basic functionality *** +array(5) { + [0]=> + int(550) + [1]=> + int(400) + [2]=> + int(13) + [3]=> + string(24) "width="550" height="400"" + ["mime"]=> + string(29) "application/x-shockwave-flash" +} +array(0) { +} ===DONE=== diff --git a/ext/standard/tests/mail/ezmlm_hash_variation1.phpt b/ext/standard/tests/mail/ezmlm_hash_variation1.phpt index 787f180fb..aa1e521e9 100644 --- a/ext/standard/tests/mail/ezmlm_hash_variation1.phpt +++ b/ext/standard/tests/mail/ezmlm_hash_variation1.phpt @@ -133,25 +133,16 @@ array(1) { } -- Iteration 10 -- -Notice: Array to string conversion in %s on line %d -array(1) { - [0]=> - string(41) "piece1 piece2 piece3 piece4 piece5 piece6" -} +Warning: explode() expects parameter 1 to be string, array given in %s on line %d +NULL -- Iteration 11 -- -Notice: Array to string conversion in %s on line %d -array(1) { - [0]=> - string(41) "piece1 piece2 piece3 piece4 piece5 piece6" -} +Warning: explode() expects parameter 1 to be string, array given in %s on line %d +NULL -- Iteration 12 -- -Notice: Array to string conversion in %s on line %d -array(1) { - [0]=> - string(41) "piece1 piece2 piece3 piece4 piece5 piece6" -} +Warning: explode() expects parameter 1 to be string, array given in %s on line %d +NULL -- Iteration 13 -- array(2) { [0]=> @@ -188,10 +179,9 @@ array(1) { string(41) "piece1 piece2 piece3 piece4 piece5 piece6" } -- Iteration 20 -- -array(1) { - [0]=> - string(%d) "%s" -} + +Warning: explode() expects parameter 1 to be string, resource given in %s on line %d +NULL -- Iteration 21 -- Warning: explode(): Empty delimiter in %s on line %d diff --git a/ext/standard/tests/math/abs.phpt b/ext/standard/tests/math/abs.phpt index c912c96a6..09d065c8b 100644 --- a/ext/standard/tests/math/abs.phpt +++ b/ext/standard/tests/math/abs.phpt @@ -1,7 +1,7 @@ --TEST-- Simple math tests --FILE-- - ".round($v, 2)."\n"; diff --git a/ext/standard/tests/math/ceil_basic.phpt b/ext/standard/tests/math/ceil_basic.phpt index 4264b1cf5..679460533 100644 --- a/ext/standard/tests/math/ceil_basic.phpt +++ b/ext/standard/tests/math/ceil_basic.phpt @@ -2,6 +2,10 @@ Test ceil() - basic function test for ceil() --INI-- precision=14 +--SKIPIF-- +if (strtolower(PHP_OS) == 'darwin') { + die('SKIP OSX does weird things with -0 so this test doesn't work there'); +} --FILE-- --CREDITS-- diff --git a/ext/standard/tests/misc/time_sleep_until_basic.phpt b/ext/standard/tests/misc/time_sleep_until_basic.phpt new file mode 100644 index 000000000..7f2f32d24 --- /dev/null +++ b/ext/standard/tests/misc/time_sleep_until_basic.phpt @@ -0,0 +1,14 @@ +--TEST-- +time_sleep_until() function - basic test for time_sleep_until() +--CREDITS-- +Manuel Baldassarri mb@ideato.it +Michele Orselli mo@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- += $time ); +?> +--EXPECT-- +bool(true) diff --git a/ext/standard/tests/misc/time_sleep_until_error1.phpt b/ext/standard/tests/misc/time_sleep_until_error1.phpt new file mode 100644 index 000000000..9752fd70e --- /dev/null +++ b/ext/standard/tests/misc/time_sleep_until_error1.phpt @@ -0,0 +1,13 @@ +--TEST-- +time_sleep_until() function - error test for time_sleep_until() +--CREDITS-- +Fabio Fabbrucci fabbrucci@grupporetina.com +Danilo Sanchi sanchi@grupporetina.com +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +--EXPECTF-- +Warning: time_sleep_until(): Sleep until to time is less than current time in %s on line 2 +bool(false) diff --git a/ext/standard/tests/misc/time_sleep_until_error2.phpt b/ext/standard/tests/misc/time_sleep_until_error2.phpt new file mode 100644 index 000000000..311dd72f6 --- /dev/null +++ b/ext/standard/tests/misc/time_sleep_until_error2.phpt @@ -0,0 +1,12 @@ +--TEST-- +time_sleep_until() function - error test for time_sleep_until() +--CREDITS-- +Filippo De Santis fd@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +--EXPECTF-- +Warning: time_sleep_until() expects parameter 1 to be double, string given in %s on line 2 +NULL diff --git a/ext/standard/tests/misc/time_sleep_until_error3.phpt b/ext/standard/tests/misc/time_sleep_until_error3.phpt new file mode 100644 index 000000000..64489618a --- /dev/null +++ b/ext/standard/tests/misc/time_sleep_until_error3.phpt @@ -0,0 +1,12 @@ +--TEST-- +time_sleep_until() function - error test for time_sleep_until() +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +--EXPECTF-- +Warning: time_sleep_until() expects exactly 1 parameter, 0 given in %s on line 2 +NULL diff --git a/ext/standard/tests/network/gethostbyaddr_basic1.phpt b/ext/standard/tests/network/gethostbyaddr_basic1.phpt new file mode 100644 index 000000000..2232d3626 --- /dev/null +++ b/ext/standard/tests/network/gethostbyaddr_basic1.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test gethostbyaddr() function : basic functionality +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing gethostbyaddr() : basic functionality *** +%rloopback|localhost(\.localdomain)?%r +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/network/gethostbyname_basic003.phpt b/ext/standard/tests/network/gethostbyname_basic003.phpt new file mode 100644 index 000000000..711490c41 --- /dev/null +++ b/ext/standard/tests/network/gethostbyname_basic003.phpt @@ -0,0 +1,18 @@ +--TEST-- +Test gethostbyname() function : basic functionality +--FILE-- + +===DONE=== +--EXPECT-- +*** Testing gethostbyname() : basic functionality *** +127.0.0.1 +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/network/gethostbynamel_basic1.phpt b/ext/standard/tests/network/gethostbynamel_basic1.phpt new file mode 100644 index 000000000..5ce7c4251 --- /dev/null +++ b/ext/standard/tests/network/gethostbynamel_basic1.phpt @@ -0,0 +1,19 @@ +--TEST-- +Test gethostbynamel() function : basic functionality +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing gethostbynamel() : basic functionality *** +array(%d) { + %a +} +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/php_ini_loaded_file.phpt b/ext/standard/tests/php_ini_loaded_file.phpt new file mode 100644 index 000000000..ab26953ea --- /dev/null +++ b/ext/standard/tests/php_ini_loaded_file.phpt @@ -0,0 +1,13 @@ +--TEST-- +Check the php_ini_loaded_file() function. No file is loaded in test, so false ins returned +--CREDITS-- +Sebastian Schürmann +sschuermann@chip.de +Testfest 2009 Munich +--FILE-- + +--EXPECT-- +bool(false) + diff --git a/ext/standard/tests/php_logo_guid.phpt b/ext/standard/tests/php_logo_guid.phpt new file mode 100644 index 000000000..c644b2893 --- /dev/null +++ b/ext/standard/tests/php_logo_guid.phpt @@ -0,0 +1,13 @@ +--TEST-- +Check the output of the php_logo_guid() function +--CREDITS-- +Sebastian Schürmann +sschuermann@chip.de +Testfest 2009 Munich +--FILE-- + +--EXPECT-- +PHPE9568F34-D428-11d2-A769-00AA001ACF42 + diff --git a/ext/standard/tests/php_real_logo_guid.phpt b/ext/standard/tests/php_real_logo_guid.phpt new file mode 100644 index 000000000..a9fa7d35d --- /dev/null +++ b/ext/standard/tests/php_real_logo_guid.phpt @@ -0,0 +1,12 @@ +--TEST-- +Testing the undocumented function php_real_logo_guid() +--CREDITS-- +Sebastian Schürmann +sschuermann@chip.de +Testfest 2009 Munich +--FILE-- + +--EXPECT-- +PHPE9568F34-D428-11d2-A769-00AA001ACF42 diff --git a/ext/standard/tests/serialize/autoload_implements.p5c b/ext/standard/tests/serialize/autoload_implements.p5c index 66c8f7e53..2c3479c86 100755 --- a/ext/standard/tests/serialize/autoload_implements.p5c +++ b/ext/standard/tests/serialize/autoload_implements.p5c @@ -1,10 +1,10 @@ - \ No newline at end of file diff --git a/ext/standard/tests/serialize/autoload_interface.p5c b/ext/standard/tests/serialize/autoload_interface.p5c index 3f9a4e70a..6908155e6 100755 --- a/ext/standard/tests/serialize/autoload_interface.p5c +++ b/ext/standard/tests/serialize/autoload_interface.p5c @@ -1,7 +1,7 @@ - \ No newline at end of file diff --git a/ext/standard/tests/streams/stream_is_local.phpt b/ext/standard/tests/streams/stream_is_local.phpt new file mode 100644 index 000000000..c90eb19cd --- /dev/null +++ b/ext/standard/tests/streams/stream_is_local.phpt @@ -0,0 +1,17 @@ +--TEST-- +Testing stream_is_local() +--FILE-- + +--EXPECT-- +bool(true) +int(1) +bool(true) diff --git a/ext/standard/tests/strings/006.phpt b/ext/standard/tests/strings/006.phpt index 3c9d6481a..fdfd58c02 100644 --- a/ext/standard/tests/strings/006.phpt +++ b/ext/standard/tests/strings/006.phpt @@ -15,7 +15,7 @@ var_dump(ob_get_contents()); ?> ===DONE=== --EXPECTF-- -Warning: highlight_file(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA): failed to open stream: File name too long in %s006.php on line %d +Warning: highlight_file(AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA): failed to open stream: %s006.php on line %d Warning: highlight_file(): Failed opening 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA' for highlighting in %s006.php on line %d bool(false) diff --git a/ext/standard/tests/strings/addslashes_basic.phpt b/ext/standard/tests/strings/addslashes_basic.phpt index 6ed121067..0912d34e4 100644 --- a/ext/standard/tests/strings/addslashes_basic.phpt +++ b/ext/standard/tests/strings/addslashes_basic.phpt @@ -1,6 +1,5 @@ --TEST-- Test addslashes() function : basic functionality ---INI-- --FILE-- --FILE-- +--EXPECTF-- +-- Before sorting: -- +array(6) { + [0]=> + %string|unicode%(6) "Süden" + [1]=> + %string|unicode%(7) "spielen" + [2]=> + %string|unicode%(5) "Sonne" + [3]=> + %string|unicode%(4) "Wind" + [4]=> + %string|unicode%(5) "Regen" + [5]=> + %string|unicode%(4) "Meer" +} + +-- After Sorting: -- +bool(true) +array(6) { + [5]=> + %string|unicode%(4) "Meer" + [4]=> + %string|unicode%(5) "Regen" + [2]=> + %string|unicode%(5) "Sonne" + [1]=> + %string|unicode%(7) "spielen" + [0]=> + %string|unicode%(6) "Süden" + [3]=> + %string|unicode%(4) "Wind" +} +Done diff --git a/ext/standard/tests/strings/bug48709.phpt b/ext/standard/tests/strings/bug48709.phpt new file mode 100644 index 000000000..999a2c651 --- /dev/null +++ b/ext/standard/tests/strings/bug48709.phpt @@ -0,0 +1,31 @@ +--TEST-- +Bug #48709 (metaphone and 'wh') +--FILE-- + %s\n", $letter, metaphone($letter)); +} + +?> +--EXPECT-- +kn => N +gn => N +pn => N +ae => E +wr => R +x => S +wh => W +wa => W diff --git a/ext/standard/tests/strings/bug50052.phpt b/ext/standard/tests/strings/bug50052.phpt new file mode 100644 index 000000000..24a5a201f --- /dev/null +++ b/ext/standard/tests/strings/bug50052.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #20934 (html_entity_decode() crash when "" is passed) +--FILE-- + +--EXPECT-- +$1$f+uslYF01$ +$1$f+uslYF0$orVloNmKSLvOeswusE0bY. diff --git a/ext/standard/tests/strings/chunk_split_variation2.phpt b/ext/standard/tests/strings/chunk_split_variation2.phpt index 752a5d870..d49ec3b1b 100644 --- a/ext/standard/tests/strings/chunk_split_variation2.phpt +++ b/ext/standard/tests/strings/chunk_split_variation2.phpt @@ -35,10 +35,10 @@ $values = array( // float data 10.5, -10.5, - 10.1234567e10, - 10.7654321E-10, + (float) PHP_INT_MAX + 1, + (float) -PHP_INT_MAX - 1, .5, - + // array data array(), array(0), @@ -83,12 +83,11 @@ for($count = 0; $count < count($values); $count++) { var_dump( chunk_split($str, $values[$count], $ending) ); } -echo "Done"; - //closing resource fclose($fp); ?> +===DONE=== --EXPECTF-- *** Testing chunk_split() : with unexpected values for 'chunklen' argument *** -- Iteration 1 -- @@ -111,16 +110,24 @@ Warning: chunk_split(): Chunk length should be greater than zero in %schunk_spli bool(false) -- Iteration 6 -- -Warning: chunk_split(): Chunk length should be greater than zero in %schunk_split_variation2.php on line %d -bool(false) +Warning: chunk_split() expects parameter 2 to be long, array given in %schunk_split_variation2.php on line %d +NULL -- Iteration 7 -- -string(50) "T*h*i*s* *i*s* *c*h*u*k*l*e*n* *v*a*r*i*a*t*i*o*n*" + +Warning: chunk_split() expects parameter 2 to be long, array given in %schunk_split_variation2.php on line %d +NULL -- Iteration 8 -- -string(50) "T*h*i*s* *i*s* *c*h*u*k*l*e*n* *v*a*r*i*a*t*i*o*n*" + +Warning: chunk_split() expects parameter 2 to be long, array given in %schunk_split_variation2.php on line %d +NULL -- Iteration 9 -- -string(50) "T*h*i*s* *i*s* *c*h*u*k*l*e*n* *v*a*r*i*a*t*i*o*n*" + +Warning: chunk_split() expects parameter 2 to be long, array given in %schunk_split_variation2.php on line %d +NULL -- Iteration 10 -- -string(50) "T*h*i*s* *i*s* *c*h*u*k*l*e*n* *v*a*r*i*a*t*i*o*n*" + +Warning: chunk_split() expects parameter 2 to be long, array given in %schunk_split_variation2.php on line %d +NULL -- Iteration 11 -- Warning: chunk_split(): Chunk length should be greater than zero in %schunk_split_variation2.php on line %d @@ -143,24 +150,24 @@ Warning: chunk_split(): Chunk length should be greater than zero in %schunk_spli bool(false) -- Iteration 17 -- -Warning: chunk_split(): Chunk length should be greater than zero in %schunk_split_variation2.php on line %d -bool(false) +Warning: chunk_split() expects parameter 2 to be long, string given in %schunk_split_variation2.php on line %d +NULL -- Iteration 18 -- -Warning: chunk_split(): Chunk length should be greater than zero in %schunk_split_variation2.php on line %d -bool(false) +Warning: chunk_split() expects parameter 2 to be long, string given in %schunk_split_variation2.php on line %d +NULL -- Iteration 19 -- -Warning: chunk_split(): Chunk length should be greater than zero in %schunk_split_variation2.php on line %d -bool(false) +Warning: chunk_split() expects parameter 2 to be long, string given in %schunk_split_variation2.php on line %d +NULL -- Iteration 20 -- -Warning: chunk_split(): Chunk length should be greater than zero in %schunk_split_variation2.php on line %d -bool(false) +Warning: chunk_split() expects parameter 2 to be long, string given in %schunk_split_variation2.php on line %d +NULL -- Iteration 21 -- -Notice: Object of class MyClass could not be converted to int in %schunk_split_variation2.php on line %d -string(50) "T*h*i*s* *i*s* *c*h*u*k*l*e*n* *v*a*r*i*a*t*i*o*n*" +Warning: chunk_split() expects parameter 2 to be long, object given in %schunk_split_variation2.php on line %d +NULL -- Iteration 22 -- Warning: chunk_split(): Chunk length should be greater than zero in %schunk_split_variation2.php on line %d @@ -170,5 +177,7 @@ bool(false) Warning: chunk_split(): Chunk length should be greater than zero in %schunk_split_variation2.php on line %d bool(false) -- Iteration 24 -- -string(30) "This *is ch*uklen* vari*ation*" -Done + +Warning: chunk_split() expects parameter 2 to be long, resource given in %schunk_split_variation2.php on line %d +NULL +===DONE=== diff --git a/ext/standard/tests/strings/chunk_split_variation3.phpt b/ext/standard/tests/strings/chunk_split_variation3.phpt index f314990c7..758bec088 100644 --- a/ext/standard/tests/strings/chunk_split_variation3.phpt +++ b/ext/standard/tests/strings/chunk_split_variation3.phpt @@ -113,24 +113,24 @@ string(100) "This1.07654321E-9 is 1.07654321E-9simp1.07654321E-9le s1.07654321E- string(40) "This0.5 is 0.5simp0.5le s0.5trin0.5g.0.5" -- Iteration 10 -- -Notice: Array to string conversion in %s on line %d -string(52) "ThisArray is ArraysimpArrayle sArraytrinArrayg.Array" +Warning: chunk_split() expects parameter 3 to be string, array given in %s on line %d +NULL -- Iteration 11 -- -Notice: Array to string conversion in %s on line %d -string(52) "ThisArray is ArraysimpArrayle sArraytrinArrayg.Array" +Warning: chunk_split() expects parameter 3 to be string, array given in %s on line %d +NULL -- Iteration 12 -- -Notice: Array to string conversion in %s on line %d -string(52) "ThisArray is ArraysimpArrayle sArraytrinArrayg.Array" +Warning: chunk_split() expects parameter 3 to be string, array given in %s on line %d +NULL -- Iteration 13 -- -Notice: Array to string conversion in %s on line %d -string(52) "ThisArray is ArraysimpArrayle sArraytrinArrayg.Array" +Warning: chunk_split() expects parameter 3 to be string, array given in %s on line %d +NULL -- Iteration 14 -- -Notice: Array to string conversion in %s on line %d -string(52) "ThisArray is ArraysimpArrayle sArraytrinArrayg.Array" +Warning: chunk_split() expects parameter 3 to be string, array given in %s on line %d +NULL -- Iteration 15 -- string(22) "This is simple string." -- Iteration 16 -- @@ -154,5 +154,7 @@ string(22) "This is simple string." -- Iteration 25 -- string(22) "This is simple string." -- Iteration 26 -- -string(%d) "ThisResource id #%d is Resource id #%dsimpResource id #%dle sResource id #%dtrinResource id #%dg.Resource id #%d" + +Warning: chunk_split() expects parameter 3 to be string, resource given in %s on line %d +NULL Done \ No newline at end of file diff --git a/ext/standard/tests/strings/chunk_split_variation5.phpt b/ext/standard/tests/strings/chunk_split_variation5.phpt index e01c126d3..580f8f0a6 100644 Binary files a/ext/standard/tests/strings/chunk_split_variation5.phpt and b/ext/standard/tests/strings/chunk_split_variation5.phpt differ diff --git a/ext/standard/tests/strings/chunk_split_variation8.phpt b/ext/standard/tests/strings/chunk_split_variation8.phpt index 6f8f2cde7..cfb440e92 100644 --- a/ext/standard/tests/strings/chunk_split_variation8.phpt +++ b/ext/standard/tests/strings/chunk_split_variation8.phpt @@ -1,5 +1,9 @@ --TEST-- Test chunk_split() function : usage variations - different integer values for 'chunklen' with heredoc string as 'str'(Bug#42796) +--SKIPIF-- + --FILE-- - string(41) "piece1 piece2 piece3 piece4 piece5 piece6" -} +Warning: explode() expects parameter 1 to be string, array given in %s on line %d +NULL -- Iteration 11 -- -Notice: Array to string conversion in %s on line %d -array(1) { - [0]=> - string(41) "piece1 piece2 piece3 piece4 piece5 piece6" -} +Warning: explode() expects parameter 1 to be string, array given in %s on line %d +NULL -- Iteration 12 -- -Notice: Array to string conversion in %s on line %d -array(1) { - [0]=> - string(41) "piece1 piece2 piece3 piece4 piece5 piece6" -} +Warning: explode() expects parameter 1 to be string, array given in %s on line %d +NULL -- Iteration 13 -- array(2) { [0]=> @@ -188,10 +179,9 @@ array(1) { string(41) "piece1 piece2 piece3 piece4 piece5 piece6" } -- Iteration 20 -- -array(1) { - [0]=> - string(%d) "%s" -} + +Warning: explode() expects parameter 1 to be string, resource given in %s on line %d +NULL -- Iteration 21 -- Warning: explode(): Empty delimiter in %s on line %d diff --git a/ext/standard/tests/strings/explode_variation2.phpt b/ext/standard/tests/strings/explode_variation2.phpt index f2c0057fe..9e1f72c5a 100644 --- a/ext/standard/tests/strings/explode_variation2.phpt +++ b/ext/standard/tests/strings/explode_variation2.phpt @@ -131,25 +131,16 @@ array(1) { } -- Iteration 10 -- -Notice: Array to string conversion in %s on line %d -array(1) { - [0]=> - string(5) "Array" -} +Warning: explode() expects parameter 2 to be string, array given in %s on line %d +NULL -- Iteration 11 -- -Notice: Array to string conversion in %s on line %d -array(1) { - [0]=> - string(5) "Array" -} +Warning: explode() expects parameter 2 to be string, array given in %s on line %d +NULL -- Iteration 12 -- -Notice: Array to string conversion in %s on line %d -array(1) { - [0]=> - string(5) "Array" -} +Warning: explode() expects parameter 2 to be string, array given in %s on line %d +NULL -- Iteration 13 -- array(1) { [0]=> @@ -188,14 +179,9 @@ array(2) { string(6) "object" } -- Iteration 20 -- -array(3) { - [0]=> - string(8) "Resource" - [1]=> - string(2) "id" - [2]=> - string(%d) "#%d" -} + +Warning: explode() expects parameter 2 to be string, resource given in %s on line %d +NULL -- Iteration 21 -- array(1) { [0]=> diff --git a/ext/standard/tests/strings/htmlentities02.phpt b/ext/standard/tests/strings/htmlentities02.phpt index babec44b5..b8b9e6315 100644 --- a/ext/standard/tests/strings/htmlentities02.phpt +++ b/ext/standard/tests/strings/htmlentities02.phpt @@ -6,7 +6,6 @@ $result = (bool)setlocale(LC_CTYPE, "fr_FR.ISO-8859-15", "fr_FR.ISO8859-15", 'fr if (!$result) { die("skip setlocale() failed\n"); } -echo "warn possibly braindead libc\n"; ?> --INI-- output_handler= diff --git a/ext/standard/tests/strings/htmlentities04.phpt b/ext/standard/tests/strings/htmlentities04.phpt index 2d67c77f0..8e362d073 100644 --- a/ext/standard/tests/strings/htmlentities04.phpt +++ b/ext/standard/tests/strings/htmlentities04.phpt @@ -6,7 +6,6 @@ $result = (bool)setlocale(LC_CTYPE, "ja_JP.EUC-JP", "ja_JP.eucJP"); if (!$result || preg_match('/EUC[^a-zA-Z]*JP/i', setlocale(LC_CTYPE, 0)) == 0) { die("skip setlocale() failed\n"); } -echo "warn possibly braindead libc\n"; ?> --INI-- output_handler= diff --git a/ext/standard/tests/strings/htmlentities15.phpt b/ext/standard/tests/strings/htmlentities15.phpt index a15948fbe..2dc36e6f7 100644 --- a/ext/standard/tests/strings/htmlentities15.phpt +++ b/ext/standard/tests/strings/htmlentities15.phpt @@ -10,7 +10,6 @@ $result = (bool)setlocale(LC_CTYPE, "ru_RU.koi8r", "ru_RU.KOI8-R"); if (!$result || preg_match('/koi8/i', setlocale(LC_CTYPE, 0)) == 0) { die("skip setlocale() failed\n"); } -echo "warn possibly braindead libc\n"; ?> --FILE-- +===DONE=== +--EXPECTF-- +*** Testing md5() : basic functionality *** +string(32) "1f3870be274f6c49b3e31a0c6728957f" +===DONE=== diff --git a/ext/standard/tests/strings/md5_basic2.phpt b/ext/standard/tests/strings/md5_basic2.phpt new file mode 100644 index 000000000..1f89ba82f --- /dev/null +++ b/ext/standard/tests/strings/md5_basic2.phpt @@ -0,0 +1,30 @@ +--TEST-- +Test md5() function : basic functionality - with raw output +--FILE-- + +===DONE=== +--EXPECT-- +*** Testing md5() : basic functionality - with raw output*** +string(32) "b10a8db164e0754105b7a99be72e3fe5" +TEST PASSED +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/strings/md5_error.phpt b/ext/standard/tests/strings/md5_error.phpt new file mode 100644 index 000000000..190b09c8e --- /dev/null +++ b/ext/standard/tests/strings/md5_error.phpt @@ -0,0 +1,35 @@ +--TEST-- +Test md5() function : error conditions +--FILE-- + +===DONE== +--EXPECTF-- +*** Testing md5() : error conditions *** + +-- Testing md5() function with no arguments -- + +Warning: md5() expects at least 1 parameter, 0 given in %s on line %d +NULL + +-- Testing md5() function with more than expected no. of arguments -- + +Warning: md5() expects at most 2 parameters, 3 given in %s on line %d +NULL +===DONE== \ No newline at end of file diff --git a/ext/standard/tests/strings/money_format_basic1.phpt b/ext/standard/tests/strings/money_format_basic1.phpt index e76aa6087..70b5ca574 100644 --- a/ext/standard/tests/strings/money_format_basic1.phpt +++ b/ext/standard/tests/strings/money_format_basic1.phpt @@ -2,13 +2,9 @@ Test money_format() function : basic functionality using national currency symbols --SKIPIF-- --FILE-- ===DONE=== --EXPECT-- -*** Testing money_format() : basic functionality using national currency symbols*** +*** Testing money_format() : basic functionality*** Format values with 14 positions, 8 digits to left, 2 to right using national format -string(15) " $ 1,234.57" -string(15) "-$ 1,234.57" +string +string Format again but with ( for negative values -string(15) " $ 1,234.57" -string(16) "($ 1,234.57)" +string +string Format with 0 for padding character -string(15) " $000001,234.57" -string(15) "-$000001,234.57" +string +string Format again with * for padding character -string(15) " $*****1,234.57" -string(15) "-$*****1,234.57" +string +string Format again but disable grouping character -string(14) " $****1234.57" -string(14) " -$****1234.57" +string +string Format again suppress currency symbol -string(14) " *****1,234.57" -string(14) "-*****1,234.57" +string +string ===DONE=== diff --git a/ext/standard/tests/strings/money_format_basic2.phpt b/ext/standard/tests/strings/money_format_basic2.phpt deleted file mode 100644 index 8074cf998..000000000 --- a/ext/standard/tests/strings/money_format_basic2.phpt +++ /dev/null @@ -1,84 +0,0 @@ ---TEST-- -Test money_format() function : basic functionality using international currency symbols ---SKIPIF-- - ---FILE-- - -===DONE=== ---EXPECT-- -*** Testing money_format() : basic functionality using international currency symbols*** -Format with 14 positions, 8 digits to left, 2 to right using national format -string(18) " USD 1,234.57" -string(18) "-USD 1,234.57" -Format with ( for negative values -string(18) " USD 1,234.57" -string(19) "(USD 1,234.57)" -Format with 0 for padding character -string(18) " USD 000001,234.57" -string(18) "-USD 000001,234.57" -Format with * for padding character -string(18) " USD *****1,234.57" -string(18) "-USD *****1,234.57" -Format again but disable grouping character -string(16) " USD ****1234.57" -string(16) "-USD ****1234.57" -Format again but suppress currency symbol -string(14) " *****1,234.57" -string(14) "-*****1,234.57" -===DONE=== - diff --git a/ext/standard/tests/strings/money_format_basic3.phpt b/ext/standard/tests/strings/money_format_basic3.phpt deleted file mode 100644 index 98d0fca7f..000000000 --- a/ext/standard/tests/strings/money_format_basic3.phpt +++ /dev/null @@ -1,83 +0,0 @@ ---TEST-- -Test money_format() function : basic functionality using national currency symbols and de_DE locale ---SKIPIF-- - ---FILE-- - -===DONE=== ---EXPECT-- -*** Testing money_format() : basic functionality using national currency symbols and de_DE locale*** -Format values with 14 positions, 8 digits to left, 2 to right using national format -string(18) " 1.234,57 EUR" -string(18) "- 1.234,57 EUR" -Format again but with ( for negative values -string(18) " 1.234,57 EUR" -string(19) "( 1.234,57 EUR)" -Format with 0 for padding character -string(18) " 000001.234,57 EUR" -string(18) "-000001.234,57 EUR" -Format again with * for padding character -string(18) " *****1.234,57 EUR" -string(18) "-*****1.234,57 EUR" -Format again but disable grouping character -string(16) " ****1234,57 EUR" -string(16) "-****1234,57 EUR" -Format again suppress currency symbol -string(14) " *****1.234,57" -string(14) "-*****1.234,57" -===DONE=== diff --git a/ext/standard/tests/strings/money_format_error.phpt b/ext/standard/tests/strings/money_format_error.phpt index fac89d1b5..cf110b43a 100644 --- a/ext/standard/tests/strings/money_format_error.phpt +++ b/ext/standard/tests/strings/money_format_error.phpt @@ -13,6 +13,10 @@ Test money_format() function : error conditions * Source code: ext/standard/string.c */ +// =========================================================================================== +// = We do not test for exact return-values, as those might be different between OS-versions = +// =========================================================================================== + $string = '%14#8.2n'; $value = 1234.56; $extra_arg = 10; diff --git a/ext/standard/tests/strings/money_format_variation1.phpt b/ext/standard/tests/strings/money_format_variation1.phpt index 7f2084355..d4fa687db 100644 --- a/ext/standard/tests/strings/money_format_variation1.phpt +++ b/ext/standard/tests/strings/money_format_variation1.phpt @@ -2,13 +2,9 @@ Test money_format() function : usage variations - test values for $format argument --SKIPIF-- --FILE-- ===Done=== --EXPECTF-- *** Testing money_format() function: with unexpected inputs for 'format' argument *** -- Iteration 1 -- -string(1) "0" +string -- Iteration 2 -- -string(1) "1" +string -- Iteration 3 -- -string(3) "255" +string -- Iteration 4 -- -string(3) "256" +string -- Iteration 5 -- -string(10) "2147483647" +string -- Iteration 6 -- -string(11) "-2147483648" +string -- Iteration 7 -- -string(4) "10.5" +string -- Iteration 8 -- -string(5) "-20.5" +string -- Iteration 9 -- -string(12) "101234567000" +string -- Iteration 10 -- Warning: money_format() expects parameter 1 to be string, array given in %s on line %d @@ -142,37 +136,37 @@ NULL Warning: money_format() expects parameter 1 to be string, array given in %s on line %d NULL -- Iteration 13 -- -string(1) "1" +string -- Iteration 14 -- -string(0) "" +string -- Iteration 15 -- -string(1) "1" +string -- Iteration 16 -- -string(0) "" +string -- Iteration 17 -- -string(0) "" +string -- Iteration 18 -- -string(0) "" +string -- Iteration 19 -- -string(4) "abcd" +string -- Iteration 20 -- -string(4) "abcd" +string -- Iteration 21 -- -string(5) "0x12f" +string -- Iteration 22 -- -string(18) " *****1,234.56abcd" +string -- Iteration 23 -- Warning: money_format() expects parameter 1 to be string, object given in %s on line %d NULL -- Iteration 24 -- -string(17) " sample object " +string -- Iteration 25 -- Warning: money_format() expects parameter 1 to be string, resource given in %s on line %d NULL -- Iteration 26 -- -string(0) "" +string -- Iteration 27 -- -string(0) "" +string ===Done=== diff --git a/ext/standard/tests/strings/money_format_variation2.phpt b/ext/standard/tests/strings/money_format_variation2.phpt index d3cb523a6..8ac4cb9a9 100644 --- a/ext/standard/tests/strings/money_format_variation2.phpt +++ b/ext/standard/tests/strings/money_format_variation2.phpt @@ -2,13 +2,9 @@ Test money_format() function : usage variations - test values for $number argument --SKIPIF-- --FILE-- ===Done=== --EXPECTF-- *** Testing money_format() function: with unexpected inputs for 'number' argument *** -- Iteration 1 -- -string(18) " USD 0.00" +string -- Iteration 2 -- -string(18) " USD 1.00" +string -- Iteration 3 -- -string(18) " USD 255.00" +string -- Iteration 4 -- -string(18) " USD 256.00" +string -- Iteration 5 -- -string(21) " USD 2,147,483,647.00" +string -- Iteration 6 -- -string(21) "-USD 2,147,483,648.00" +string -- Iteration 7 -- -string(18) " USD 10.50" +string -- Iteration 8 -- -string(18) "-USD 20.50" +string -- Iteration 9 -- -string(23) " USD 101,234,567,000.00" +string -- Iteration 10 -- Warning: money_format() expects parameter 2 to be double, array given in %s on line %d @@ -142,17 +136,17 @@ NULL Warning: money_format() expects parameter 2 to be double, array given in %s on line %d NULL -- Iteration 13 -- -string(18) " USD 1.00" +string -- Iteration 14 -- -string(18) " USD 0.00" +string -- Iteration 15 -- -string(18) " USD 1.00" +string -- Iteration 16 -- -string(18) " USD 0.00" +string -- Iteration 17 -- -string(18) " USD 0.00" +string -- Iteration 18 -- -string(18) " USD 0.00" +string -- Iteration 19 -- Warning: money_format() expects parameter 2 to be double, string given in %s on line %d @@ -162,7 +156,7 @@ NULL Warning: money_format() expects parameter 2 to be double, string given in %s on line %d NULL -- Iteration 21 -- -string(18) " USD 303.00" +string -- Iteration 22 -- Warning: money_format() expects parameter 2 to be double, string given in %s on line %d @@ -180,7 +174,7 @@ NULL Warning: money_format() expects parameter 2 to be double, resource given in %s on line %d NULL -- Iteration 26 -- -string(18) " USD 0.00" +string -- Iteration 27 -- -string(18) " USD 0.00" +string ===Done=== diff --git a/ext/standard/tests/strings/parse_str_basic3.phpt b/ext/standard/tests/strings/parse_str_basic3.phpt index a600fe01e..5b0641e14 100644 --- a/ext/standard/tests/strings/parse_str_basic3.phpt +++ b/ext/standard/tests/strings/parse_str_basic3.phpt @@ -1,11 +1,14 @@ --TEST-- Test parse_str() function : basic functionality +--INI-- +magic_quotes_gpc = on --FILE-- ===DONE=== --EXPECTF-- +PHP Warning: Directive 'magic_quotes_gpc' is deprecated in PHP 5.3 and greater in Unknown on line 0 *** Testing parse_str() : basic functionality *** Test string with array values @@ -263,4 +267,4 @@ array(1) { } } } -===DONE=== \ No newline at end of file +===DONE=== diff --git a/ext/standard/tests/strings/parse_str_basic4.phpt b/ext/standard/tests/strings/parse_str_basic4.phpt index 0e4baf8d7..894dbf0c2 100644 --- a/ext/standard/tests/strings/parse_str_basic4.phpt +++ b/ext/standard/tests/strings/parse_str_basic4.phpt @@ -20,6 +20,11 @@ $str = "arr[one=sid&arr[4][two=fred"; var_dump(parse_str($str, $res)); var_dump($res); +echo "\nTest string with badly formed % numbers\n"; +$str = "first=%41&second=%a&third=%b"; +var_dump(parse_str($str)); +var_dump($first, $second, $third); + echo "\nTest string with non-binary safe name\n"; $str = "arr.test[1]=sid&arr test[4][two]=fred"; var_dump(parse_str($str, $res)); @@ -59,6 +64,12 @@ array(2) { } } +Test string with badly formed % numbers +NULL +string(1) "A" +string(2) "%a" +string(2) "%b" + Test string with non-binary safe name NULL array(1) { diff --git a/ext/standard/tests/strings/show_source_basic.phpt b/ext/standard/tests/strings/show_source_basic.phpt new file mode 100644 index 000000000..cfd998fe9 --- /dev/null +++ b/ext/standard/tests/strings/show_source_basic.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test function show_source() by calling it with its expected arguments, more test for highlight_file() +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +--EXPECTF-- +*** Test by calling method or function with its expected arguments *** + +<?php
    echo "*** Test by calling method or function with its expected arguments ***\n";
    $foo 'bar';
    $baz "something ".$foo."\n";

    if ( 
    $foo == 'bar' 
    {
      
    $baz 'baz';
    }

     
    /* some code here */
       
    show_source(__FILE__);

    ?>
    +
    +
    diff --git a/ext/standard/tests/strings/show_source_variation1.phpt b/ext/standard/tests/strings/show_source_variation1.phpt new file mode 100644 index 000000000..a9993ed45 --- /dev/null +++ b/ext/standard/tests/strings/show_source_variation1.phpt @@ -0,0 +1,28 @@ +--TEST-- +Test function show_source() by calling it with its expected arguments and php output, more test for highlight_file() +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +--EXPECTF-- +*** Test by calling method or function with its expected arguments and php output *** +baz + +<?php
    echo "*** Test by calling method or function with its expected arguments and php output ***\n";
    $foo 'bar';
    $baz "something ".$foo."\n";

    if ( 
    $foo == 'bar' 
    {
      
    $baz "baz\n";
    }

     
    /* some code here */
    echo $baz;   
    show_source(__FILE__);
    echo 
    $foo;
    ?>
    +
    +
    bar diff --git a/ext/standard/tests/strings/show_source_variation2.phpt b/ext/standard/tests/strings/show_source_variation2.phpt new file mode 100644 index 000000000..06ef66c2d --- /dev/null +++ b/ext/standard/tests/strings/show_source_variation2.phpt @@ -0,0 +1,27 @@ +--TEST-- +Test function show_source() by calling it with its expected arguments and output to variable, more test for highlight_file() +--CREDITS-- +Francesco Fullone ff@ideato.it +#PHPTestFest Cesena Italia on 2009-06-20 +--FILE-- + +--EXPECTF-- +*** Test by calling method or function with its expected arguments and output to variable *** +string(1987) " +<?php
    echo "*** Test by calling method or function with its expected arguments and output to variable ***\n";
    $foo 'bar';
    $baz "something ".$foo."\n";

    if ( 
    $foo == 'bar' 
    {
      
    $baz "baz\n";
    }

     
    /* some code here */ 
    $source show_source(__FILE__true);

    var_dump($source);
    ?>
    +
    +
    " diff --git a/ext/standard/tests/strings/soundex_basic.phpt b/ext/standard/tests/strings/soundex_basic.phpt new file mode 100644 index 000000000..65bcb6425 --- /dev/null +++ b/ext/standard/tests/strings/soundex_basic.phpt @@ -0,0 +1,46 @@ +--TEST-- +Test soundex() function : basic functionality +--FILE-- + +===DONE=== +--EXPECT-- +*** Testing soundex() : basic functionality *** +string(4) "E460" +string(4) "G200" +string(4) "H416" +string(4) "K530" +string(4) "L300" +string(4) "L222" +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(true) +bool(false) +bool(false) + +===DONE=== diff --git a/ext/standard/tests/strings/soundex_error.phpt b/ext/standard/tests/strings/soundex_error.phpt new file mode 100644 index 000000000..a81b9d24f --- /dev/null +++ b/ext/standard/tests/strings/soundex_error.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test soundex() function : error conditions +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing soundex error conditions ***-- Testing soundex() function with Zero arguments -- + +Warning: soundex() expects exactly 1 parameter, 0 given in %s on line %d +NULL + + +-- Testing soundex() function with more than expected no. of arguments -- + +Warning: soundex() expects exactly 1 parameter, 2 given in %s on line %d +NULL + +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/strings/str_replace_basic.phpt b/ext/standard/tests/strings/str_replace_basic.phpt new file mode 100644 index 000000000..10bf54234 --- /dev/null +++ b/ext/standard/tests/strings/str_replace_basic.phpt @@ -0,0 +1,49 @@ +--TEST-- +Test str_replace() function basic function +--INI-- +precision=14 +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing str_replace() on basic operations *** +string(0) "" +string(4) "tbst" +string(0) "" +int(0) +string(1) "q" +int(1) +string(0) "" +int(0) +string(%d) "Resource id #%d" +int(1) +===DONE=== diff --git a/ext/standard/tests/strings/str_replace_error.phpt b/ext/standard/tests/strings/str_replace_error.phpt new file mode 100644 index 000000000..9fafc57a3 --- /dev/null +++ b/ext/standard/tests/strings/str_replace_error.phpt @@ -0,0 +1,41 @@ +--TEST-- +Test str_replace() function error conditions +--INI-- +precision=14 +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing str_replace error conditions *** +Warning: str_replace() expects at least 3 parameters, 0 given in %sstr_replace_error.php on line 12 +NULL + +Warning: str_replace() expects at least 3 parameters, 1 given in %sstr_replace_error.php on line 13 +NULL + +Warning: str_replace() expects at least 3 parameters, 1 given in %sstr_replace_error.php on line 14 +NULL + +Warning: str_replace() expects at least 3 parameters, 2 given in %sstr_replace_error.php on line 15 +NULL + +Warning: str_replace() expects at most 4 parameters, 5 given in %sstr_replace_error.php on line 16 +NULL +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/strings/str_replace_variation1.phpt b/ext/standard/tests/strings/str_replace_variation1.phpt new file mode 100644 index 000000000..279fb2201 --- /dev/null +++ b/ext/standard/tests/strings/str_replace_variation1.phpt @@ -0,0 +1,392 @@ +--TEST-- +Test str_replace() function - test search values +--INI-- +precision=14 +--FILE-- + +===DONE=== +--EXPECT-- +*** Testing str_replace() with various search values *** +-- Iteration 0 -- +array(12) { + [0]=> + string(5) "FOUND" + [1]=> + string(0) "" + [2]=> + string(5) "FOUND" + [3]=> + string(1) "0" + [4]=> + string(6) "-FOUND" + [5]=> + string(5) "FOUND" + [6]=> + string(1) "0" + [7]=> + string(6) "-FOUND" + [8]=> + string(0) "" + [9]=> + array(0) { + } + [10]=> + string(3) "php" + [11]=> + string(0) "" +} +int(5) + +-- Iteration 1 -- +array(12) { + [0]=> + string(1) "1" + [1]=> + string(0) "" + [2]=> + string(1) "1" + [3]=> + string(1) "0" + [4]=> + string(2) "-1" + [5]=> + string(1) "1" + [6]=> + string(1) "0" + [7]=> + string(2) "-1" + [8]=> + string(0) "" + [9]=> + array(0) { + } + [10]=> + string(3) "php" + [11]=> + string(0) "" +} +int(0) + +-- Iteration 2 -- +array(12) { + [0]=> + string(5) "FOUND" + [1]=> + string(0) "" + [2]=> + string(5) "FOUND" + [3]=> + string(1) "0" + [4]=> + string(6) "-FOUND" + [5]=> + string(5) "FOUND" + [6]=> + string(1) "0" + [7]=> + string(6) "-FOUND" + [8]=> + string(0) "" + [9]=> + array(0) { + } + [10]=> + string(3) "php" + [11]=> + string(0) "" +} +int(5) + +-- Iteration 3 -- +array(12) { + [0]=> + string(1) "1" + [1]=> + string(0) "" + [2]=> + string(1) "1" + [3]=> + string(5) "FOUND" + [4]=> + string(2) "-1" + [5]=> + string(1) "1" + [6]=> + string(5) "FOUND" + [7]=> + string(2) "-1" + [8]=> + string(0) "" + [9]=> + array(0) { + } + [10]=> + string(3) "php" + [11]=> + string(0) "" +} +int(2) + +-- Iteration 4 -- +array(12) { + [0]=> + string(1) "1" + [1]=> + string(0) "" + [2]=> + string(1) "1" + [3]=> + string(1) "0" + [4]=> + string(5) "FOUND" + [5]=> + string(1) "1" + [6]=> + string(1) "0" + [7]=> + string(5) "FOUND" + [8]=> + string(0) "" + [9]=> + array(0) { + } + [10]=> + string(3) "php" + [11]=> + string(0) "" +} +int(2) + +-- Iteration 5 -- +array(12) { + [0]=> + string(5) "FOUND" + [1]=> + string(0) "" + [2]=> + string(5) "FOUND" + [3]=> + string(1) "0" + [4]=> + string(6) "-FOUND" + [5]=> + string(5) "FOUND" + [6]=> + string(1) "0" + [7]=> + string(6) "-FOUND" + [8]=> + string(0) "" + [9]=> + array(0) { + } + [10]=> + string(3) "php" + [11]=> + string(0) "" +} +int(5) + +-- Iteration 6 -- +array(12) { + [0]=> + string(1) "1" + [1]=> + string(0) "" + [2]=> + string(1) "1" + [3]=> + string(5) "FOUND" + [4]=> + string(2) "-1" + [5]=> + string(1) "1" + [6]=> + string(5) "FOUND" + [7]=> + string(2) "-1" + [8]=> + string(0) "" + [9]=> + array(0) { + } + [10]=> + string(3) "php" + [11]=> + string(0) "" +} +int(2) + +-- Iteration 7 -- +array(12) { + [0]=> + string(1) "1" + [1]=> + string(0) "" + [2]=> + string(1) "1" + [3]=> + string(1) "0" + [4]=> + string(5) "FOUND" + [5]=> + string(1) "1" + [6]=> + string(1) "0" + [7]=> + string(5) "FOUND" + [8]=> + string(0) "" + [9]=> + array(0) { + } + [10]=> + string(3) "php" + [11]=> + string(0) "" +} +int(2) + +-- Iteration 8 -- +array(12) { + [0]=> + string(1) "1" + [1]=> + string(0) "" + [2]=> + string(1) "1" + [3]=> + string(1) "0" + [4]=> + string(2) "-1" + [5]=> + string(1) "1" + [6]=> + string(1) "0" + [7]=> + string(2) "-1" + [8]=> + string(0) "" + [9]=> + array(0) { + } + [10]=> + string(3) "php" + [11]=> + string(0) "" +} +int(0) + +-- Iteration 9 -- +array(12) { + [0]=> + string(1) "1" + [1]=> + string(0) "" + [2]=> + string(1) "1" + [3]=> + string(1) "0" + [4]=> + string(2) "-1" + [5]=> + string(1) "1" + [6]=> + string(1) "0" + [7]=> + string(2) "-1" + [8]=> + string(0) "" + [9]=> + array(0) { + } + [10]=> + string(3) "php" + [11]=> + string(0) "" +} +int(0) + +-- Iteration 10 -- +array(12) { + [0]=> + string(1) "1" + [1]=> + string(0) "" + [2]=> + string(1) "1" + [3]=> + string(1) "0" + [4]=> + string(2) "-1" + [5]=> + string(1) "1" + [6]=> + string(1) "0" + [7]=> + string(2) "-1" + [8]=> + string(0) "" + [9]=> + array(0) { + } + [10]=> + string(5) "FOUND" + [11]=> + string(0) "" +} +int(1) + +-- Iteration 11 -- +array(12) { + [0]=> + string(1) "1" + [1]=> + string(0) "" + [2]=> + string(1) "1" + [3]=> + string(1) "0" + [4]=> + string(2) "-1" + [5]=> + string(1) "1" + [6]=> + string(1) "0" + [7]=> + string(2) "-1" + [8]=> + string(0) "" + [9]=> + array(0) { + } + [10]=> + string(3) "php" + [11]=> + string(0) "" +} +int(0) +===DONE=== diff --git a/ext/standard/tests/strings/str_replace_variation2.phpt b/ext/standard/tests/strings/str_replace_variation2.phpt new file mode 100644 index 000000000..5534341dc Binary files /dev/null and b/ext/standard/tests/strings/str_replace_variation2.phpt differ diff --git a/ext/standard/tests/strings/str_replace_variation3.phpt b/ext/standard/tests/strings/str_replace_variation3.phpt new file mode 100644 index 000000000..9b19153fa --- /dev/null +++ b/ext/standard/tests/strings/str_replace_variation3.phpt @@ -0,0 +1,227 @@ +--TEST-- +Test str_replace() function +--INI-- +precision=14 +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing Miscelleneous input data *** +string(3) "qqq" +int(5) +array(3) { + [0]=> + string(3) "qqq" + [1]=> + string(0) "" + [2]=> + string(3) "ccc" +} +int(6) + +-- Testing objects -- +string(12) "Hello, world" +int(1) + +-- Testing arrays -- +string(15) "multimultimulti" +int(3) +string(3) "qqq" +int(3) +array(2) { + [0]=> + string(3) "qqq" + [1]=> + string(3) "ccc" +} +int(6) + +Notice: Array to string conversion in %s on line %d +array(1) { + [0]=> + string(15) "ArrayArrayArray" +} +int(3) +array(2) { + [0]=> + string(3) "111" + [1]=> + string(3) "bbb" +} +int(3) +array(2) { + [0]=> + string(4) "aaa3" + [1]=> + string(4) "2bbb" +} +int(1) + +-- Testing Resources -- +string(%d) "Resource id #%d" +int(0) +string(%d) "Resource id #%d" +int(0) + +-- Testing a longer and heredoc string -- +string(623) "FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 +FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 +FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 +FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 +FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 +FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 +FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789 +@#$%^&**&^%$#@!~:())))((((&&&**%$###@@@!!!~~~~@###$%^&* +FOUNDghijklmnopqrstuvwxyz0123456789FOUNDghijklmnopqrstuvwxyz0123456789" +int(16) + +-- Testing a heredoc null string -- +string(0) "" +int(0) + +-- Testing simple and complex syntax strings -- +string(5) "FOUND" +string(5) "FOUND" + +Notice: Undefined variable: strS in %s on line %d +string(0) "" +string(5) "FOUND" +string(5) "FOUND" +===DONE=== diff --git a/ext/standard/tests/strings/str_rot13_basic.phpt b/ext/standard/tests/strings/str_rot13_basic.phpt new file mode 100644 index 000000000..949d72575 --- /dev/null +++ b/ext/standard/tests/strings/str_rot13_basic.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test soundex() function : basic functionality +--FILE-- +.?"), "!%^&*()_-+={}[]:;@~#<,>.?")) { + echo "Strings equal : TEST PASSED\n"; +} else { + echo "Strings unequal : TEST FAILED\n"; +} + +echo "\nEnsure strings round trip\n"; +$str = "str_rot13() tests starting"; +$encode = str_rot13($str); +$decode = str_rot13($encode); +if (strcmp($str, $decode) == 0) { + echo "Strings equal : TEST PASSED\n"; +} else { + echo "Strings unequal : TEST FAILED\n"; +} +?> +===DONE=== +--EXPECTF-- +*** Testing str_rot13() : basic functionality *** + +Basic tests +string(26) "fge_ebg13() grfgf fgnegvat" +string(26) "nopqrstuvwxyzabcdefghijklm" + +Ensure numeric characters are left untouched +Strings equal : TEST PASSED + +Ensure non-alphabetic characters are left untouched +Strings unequal : TEST FAILED + +Ensure strings round trip +Strings equal : TEST PASSED +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/strings/str_rot13_error.phpt b/ext/standard/tests/strings/str_rot13_error.phpt new file mode 100644 index 000000000..99a99f29c --- /dev/null +++ b/ext/standard/tests/strings/str_rot13_error.phpt @@ -0,0 +1,32 @@ +--TEST-- +Test str_rot13() function : error conditions +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing str_rot13() : error conditions *** +-- Testing str_rot13() function with Zero arguments -- + +Warning: str_rot13() expects exactly 1 parameter, 0 given in %s on line %d +NULL + + +-- Testing str_rot13() function with more than expected no. of arguments -- + +Warning: str_rot13() expects exactly 1 parameter, 2 given in %s on line %d +NULL +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/strings/stripcslashes_variation1.phpt b/ext/standard/tests/strings/stripcslashes_variation1.phpt index a46276f13..32c8963df 100644 --- a/ext/standard/tests/strings/stripcslashes_variation1.phpt +++ b/ext/standard/tests/strings/stripcslashes_variation1.phpt @@ -1,6 +1,5 @@ --TEST-- Test stripcslashes() function : usage variations - non-string type argument ---INI-- --FILE-- +===DONE=== +--EXPECTF-- +*** Testing strnatcasecmp() : error conditions *** +-- Testing strnatcmp() function with Zero arguments -- + +Warning: strnatcasecmp() expects exactly 2 parameters, 0 given in %s on line %d +NULL + + +-- Testing strnatcasecmp() function with more than expected no. of arguments -- + +Warning: strnatcasecmp() expects exactly 2 parameters, 3 given in %s on line %d +NULL +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/strings/strnatcasecmp_variation1.phpt b/ext/standard/tests/strings/strnatcasecmp_variation1.phpt index c21117035..fb0fb79ae 100644 --- a/ext/standard/tests/strings/strnatcasecmp_variation1.phpt +++ b/ext/standard/tests/strings/strnatcasecmp_variation1.phpt @@ -36,7 +36,6 @@ function str_dump($a, $b) { echo "*** Testing strnatcasecmp() : variation ***\n"; -str_dump(chr(128), chr(255)); str_dump('0', false); str_dump('fooBar', ''); str_dump('', -1); @@ -48,7 +47,6 @@ str_dump($a, $b); ===DONE=== --EXPECT-- *** Testing strnatcasecmp() : variation *** -int(-1) int(1) int(6) int(-2) diff --git a/ext/standard/tests/strings/strnatcmp_basic.phpt b/ext/standard/tests/strings/strnatcmp_basic.phpt new file mode 100644 index 000000000..140bd48d6 --- /dev/null +++ b/ext/standard/tests/strings/strnatcmp_basic.phpt @@ -0,0 +1,80 @@ +--TEST-- +Test strnatcmp() function : basic functionality +--FILE-- + +===DONE=== +--EXPECT-- +*** Testing strnatcmp() : basic functionality *** +Less than tests +int(-1) +int(-1) +int(-1) +int(-1) +int(-1) +int(1) +int(1) +int(1) +int(1) +int(1) +Equal too tests +int(0) +int(1) +Greater than tests +int(1) +int(1) +int(1) +int(1) +int(1) +int(1) +int(1) +int(1) +int(1) +int(1) +===DONE=== \ No newline at end of file diff --git a/ext/standard/tests/strings/strnatcmp_error.phpt b/ext/standard/tests/strings/strnatcmp_error.phpt new file mode 100644 index 000000000..09cc668af --- /dev/null +++ b/ext/standard/tests/strings/strnatcmp_error.phpt @@ -0,0 +1,34 @@ +--TEST-- +Test strnatcmp() function : error conditions +--FILE-- + +===DONE=== +--EXPECTF-- +*** Testing strnatcmp() : error conditions *** +-- Testing strnatcmp() function with Zero arguments -- + +Warning: strnatcmp() expects exactly 2 parameters, 0 given in %s on line %d +NULL + + +-- Testing strnatcmp() function with more than expected no. of arguments -- + +Warning: strnatcmp() expects exactly 2 parameters, 3 given in %s on line %d +NULL +===DONE=== diff --git a/ext/standard/tests/strings/strpos.phpt b/ext/standard/tests/strings/strpos.phpt index dbc5d6d97..706ddfdcb 100644 Binary files a/ext/standard/tests/strings/strpos.phpt and b/ext/standard/tests/strings/strpos.phpt differ diff --git a/ext/standard/tests/strings/strrchr_variation10.phpt b/ext/standard/tests/strings/strrchr_variation10.phpt index c807dd449..a96f2b019 100644 --- a/ext/standard/tests/strings/strrchr_variation10.phpt +++ b/ext/standard/tests/strings/strrchr_variation10.phpt @@ -150,14 +150,24 @@ bool(false) -- Iteration 9 -- bool(false) -- Iteration 10 -- + +Warning: strrchr(): needle is not a string or an integer in %s on line %d bool(false) -- Iteration 11 -- + +Warning: strrchr(): needle is not a string or an integer in %s on line %d bool(false) -- Iteration 12 -- + +Warning: strrchr(): needle is not a string or an integer in %s on line %d bool(false) -- Iteration 13 -- + +Warning: strrchr(): needle is not a string or an integer in %s on line %d bool(false) -- Iteration 14 -- + +Warning: strrchr(): needle is not a string or an integer in %s on line %d bool(false) -- Iteration 15 -- bool(false) @@ -180,7 +190,9 @@ bool(false) -- Iteration 23 -- bool(false) -- Iteration 24 -- -%s + +Warning: strrchr(): needle is not a string or an integer in %s on line %d +bool(false) -- Iteration 25 -- bool(false) -- Iteration 26 -- diff --git a/ext/standard/tests/strings/strrpos_variation10.phpt b/ext/standard/tests/strings/strrpos_variation10.phpt index f3adb3ee9..86ca6cf92 100644 --- a/ext/standard/tests/strings/strrpos_variation10.phpt +++ b/ext/standard/tests/strings/strrpos_variation10.phpt @@ -112,14 +112,24 @@ bool(false) -- Iteration 9 -- bool(false) -- Iteration 10 -- + +Warning: strrpos(): needle is not a string or an integer in %s on line %d bool(false) -- Iteration 11 -- + +Warning: strrpos(): needle is not a string or an integer in %s on line %d bool(false) -- Iteration 12 -- + +Warning: strrpos(): needle is not a string or an integer in %s on line %d bool(false) -- Iteration 13 -- + +Warning: strrpos(): needle is not a string or an integer in %s on line %d bool(false) -- Iteration 14 -- + +Warning: strrpos(): needle is not a string or an integer in %s on line %d bool(false) -- Iteration 15 -- bool(false) @@ -142,7 +152,9 @@ bool(false) -- Iteration 23 -- bool(false) -- Iteration 24 -- -%s + +Warning: strrpos(): needle is not a string or an integer in %s on line %d +bool(false) -- Iteration 25 -- bool(false) -- Iteration 26 -- diff --git a/ext/standard/tests/strings/strstr.phpt b/ext/standard/tests/strings/strstr.phpt index fd15b9291..1c8d753e6 100644 Binary files a/ext/standard/tests/strings/strstr.phpt and b/ext/standard/tests/strings/strstr.phpt differ diff --git a/ext/standard/tests/strings/ucwords_basic.phpt b/ext/standard/tests/strings/ucwords_basic.phpt index f34d8e912..bba0d9bc4 100644 --- a/ext/standard/tests/strings/ucwords_basic.phpt +++ b/ext/standard/tests/strings/ucwords_basic.phpt @@ -1,6 +1,5 @@ --TEST-- Test ucwords() function : basic functionality ---INI-- --FILE-- +#PHPTestFest2009 Norway 2009-06-09 \o/ +--FILE-- + +--EXPECTF-- +*** Testing get_headers() : error conditions *** + +-- Testing get_headers() function with Zero arguments -- + +Warning: get_headers() expects at least 1 parameter, 0 given in %s on line 12 +NULL + +-- Testing get_headers() function with more than expected no. of arguments -- + +Warning: get_headers() expects at most 2 parameters, 3 given in %s on line 19 +NULL +Done + + + diff --git a/ext/standard/tests/url/get_headers_error_002.phpt b/ext/standard/tests/url/get_headers_error_002.phpt new file mode 100644 index 000000000..9626211cf --- /dev/null +++ b/ext/standard/tests/url/get_headers_error_002.phpt @@ -0,0 +1,55 @@ +--TEST-- +Test get_headers() function: wrong type for argument format +--CREDITS-- +June Henriksen +#PHPTestFest2009 Norway 2009-06-09 \o/ +--FILE-- + +--EXPECTF-- +*** Testing get_headers() : error conditions *** + +-- Testing get_headers() function with format argument as type string -- + +Warning: get_headers() expects parameter 2 to be long, string given in %s on line 13 +NULL + +-- Testing get_headers() function with format argument as type array -- + +Warning: get_headers() expects parameter 2 to be long, array given in %s on line 17 +NULL + +-- Testing get_headers() function with format argument as type object -- + +Warning: get_headers() expects parameter 2 to be long, object given in %s on line 26 +NULL +Done + diff --git a/ext/standard/tests/zend_logo_guid.phpt b/ext/standard/tests/zend_logo_guid.phpt new file mode 100644 index 000000000..d26ed45e9 --- /dev/null +++ b/ext/standard/tests/zend_logo_guid.phpt @@ -0,0 +1,12 @@ +--TEST-- +Checking the zend_logo_guid() functio +--CREDITS-- +Sebastian Schürmann +sschuermann@chip.de +Testfest 2009 Munich +--FILE-- + +--EXPECT-- +PHPE9568F35-D428-11d2-A769-00AA001ACF42 diff --git a/ext/standard/type.c b/ext/standard/type.c index edf9b2e3e..be165d6bf 100644 --- a/ext/standard/type.c +++ b/ext/standard/type.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: type.c,v 1.30.2.2.2.3.2.11 2009/04/02 09:56:33 dmitry Exp $ */ +/* $Id: type.c 278172 2009-04-02 09:56:33Z dmitry $ */ #include "php.h" #include "php_incomplete_class.h" diff --git a/ext/standard/uniqid.c b/ext/standard/uniqid.c index 67ea0aa3a..e69f00568 100644 --- a/ext/standard/uniqid.c +++ b/ext/standard/uniqid.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: uniqid.c,v 1.41.2.2.2.2.2.4 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: uniqid.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" diff --git a/ext/standard/uniqid.h b/ext/standard/uniqid.h index 1e038040a..716cb8c25 100644 --- a/ext/standard/uniqid.h +++ b/ext/standard/uniqid.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: uniqid.h,v 1.13.2.1.2.1.2.2 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: uniqid.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef UNIQID_H #define UNIQID_H diff --git a/ext/standard/url.c b/ext/standard/url.c index cbec5c357..06d33fd9f 100644 --- a/ext/standard/url.c +++ b/ext/standard/url.c @@ -15,7 +15,7 @@ | Author: Jim Winstead | +----------------------------------------------------------------------+ */ -/* $Id: url.c,v 1.86.2.5.2.7.2.7 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: url.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include #include diff --git a/ext/standard/url.h b/ext/standard/url.h index 25c10b6b7..a478d304a 100644 --- a/ext/standard/url.h +++ b/ext/standard/url.h @@ -15,7 +15,7 @@ | Author: Jim Winstead | +----------------------------------------------------------------------+ */ -/* $Id: url.h,v 1.20.2.2.2.1.2.2 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: url.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef URL_H #define URL_H diff --git a/ext/standard/url_scanner.c b/ext/standard/url_scanner.c deleted file mode 100644 index 3cb695b24..000000000 --- a/ext/standard/url_scanner.c +++ /dev/null @@ -1,373 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.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: Hartmut Holzgraefe | - +----------------------------------------------------------------------+ - */ -/* $Id: url_scanner.c,v 1.44.2.1.2.3.2.2 2008/12/31 11:15:46 sebastian Exp $ */ - -#include "php.h" - -#include "php_globals.h" - -#include -#include -#include -#include -#include "basic_functions.h" -#include "url_scanner.h" - -#ifndef BUFSIZE -#define BUFSIZE 256 -#endif - -int php_url_scanner_activate(TSRMLS_D) -{ - url_adapt(NULL,0,NULL,NULL); - return SUCCESS; -} - - -int php_url_scanner_deactivate(TSRMLS_D) -{ - url_adapt(NULL,0,NULL,NULL); - return SUCCESS; -} - -/* {{{ url_attr_addon - */ -static char *url_attr_addon(const char *tag,const char *attr,const char *val,const char *buf) -{ - int flag = 0; - - if (!strcasecmp(tag,"a") && !strcasecmp(attr,"href")) { - flag = 1; - } else if (!strcasecmp(tag,"area" ) && !strcasecmp(attr,"href" )) { - flag = 1; - } else if (!strcasecmp(tag,"form" ) && !strcasecmp(attr,"action" )) { - flag = 1; - } else if (!strcasecmp(tag,"frame") && !strcasecmp(attr,"source" )) { - flag = 1; - } else if (!strcasecmp(tag,"img" ) && !strcasecmp(attr,"action" )) { - flag = 1; - } - if(flag && !strstr(val,buf) && !strchr(val,':')) { - char *result; - TSRMLS_FETCH(); - - spprintf(&result, 0, "%s%s", (strchr(val,'?') ? PG(arg_separator).output : "?"), buf); - return result; - } - return NULL; -} -/* }}} */ - -#define US BG(url_adapt_state) - -/* {{{ url_adapt_ext - */ -char *url_adapt_ext(const char *src, uint srclen, const char *name, const char *val, size_t *newlen) -{ - char buf[1024]; - - snprintf(buf, sizeof(buf)-1, "%s=%s", name, val); - - return url_adapt(src, srclen, buf, newlen); -} -/* }}} */ - -/* {{{ url_adapt - */ -char *url_adapt(const char *src, size_t srclen, const char *data, size_t *newlen) -{ - char *out,*outp; - int maxl,n; - TSRMLS_FETCH(); - - if(src==NULL) { - US.state=STATE_NORMAL; - if(US.tag) { efree(US.tag); US.tag =NULL; } - if(US.attr) { efree(US.attr); US.attr=NULL; } - if(US.val) { efree(US.val); US.val =NULL; } - return NULL; - } - - if(srclen==0) - srclen=strlen(src); - - out=malloc(srclen+1); - maxl=srclen; - n=srclen; - - *newlen=0; - outp=out; - - while(n--) { - switch(US.state) { - case STATE_NORMAL: - if(*src=='<') - US.state=STATE_TAG_START; - break; - - case STATE_TAG_START: - if(! isalnum(*src)) - US.state=STATE_NORMAL; - US.state=STATE_TAG; - US.ml=BUFSIZE; - US.p=US.tag=erealloc(US.tag,US.ml); - *(US.p)++=*src; - US.l=1; - break; - - case STATE_TAG: - if(isalnum(*src)) { - *(US.p)++ = *src; - US.l++; - if(US.l==US.ml) { - US.ml+=BUFSIZE; - US.tag=erealloc(US.tag,US.ml); - US.p = US.tag+US.l; - } - } else if (isspace(*src)) { - US.state = STATE_IN_TAG; - *US.p='\0'; - US.tag=erealloc(US.tag,US.l); - } else { - US.state = STATE_NORMAL; - efree(US.tag); - US.tag=NULL; - } - break; - - case STATE_IN_TAG: - if(isalnum(*src)) { - US.state=STATE_TAG_ATTR; - US.ml=BUFSIZE; - US.p=US.attr=erealloc(US.attr,US.ml); - *(US.p)++=*src; - US.l=1; - } else if (! isspace(*src)) { - US.state = STATE_NORMAL; - efree(US.tag); - US.tag=NULL; - } - break; - - case STATE_TAG_ATTR: - if(isalnum(*src)) { - *US.p++=*src; - ++US.l; - if(US.l==US.ml) { - US.ml+=BUFSIZE; - US.attr=erealloc(US.attr,US.ml); - US.p = US.attr+US.l; - } - if(US.l==US.ml) { - US.ml+=BUFSIZE; - US.attr=erealloc(US.attr,US.ml); - US.p = US.attr+US.l; - } - } else if(isspace(*src)||(*src=='=')){ - US.state=STATE_TAG_IS; - *US.p=0; - US.attr=erealloc(US.attr,US.l); - } else if(*src=='>') { - US.state=STATE_NORMAL; - } else { - efree(US.attr); - US.attr=NULL; - US.state=STATE_IN_TAG; - } - break; - - case STATE_TAG_IS: - case STATE_TAG_IS2: - if(*src=='>'){ - US.state=STATE_NORMAL; - if(! (US.attr_done)) { - char *p; - p=url_attr_addon(US.tag,US.attr,"",data); - if(p) { - int l= strlen(p); - maxl+=l; - out=realloc(out,maxl); - outp=out+*newlen; - strlcpy(outp,p,maxl); - outp+=l; - *newlen+=l; - efree(p); - } - } - } else if(*src=='#') { - if(! (US.attr_done)) { - char *p; - US.attr_done=1; - p=url_attr_addon(US.tag,US.attr,"#",data); - if(p) { - int l= strlen(p); - maxl+=l; - out=realloc(out,maxl); - outp=out+*newlen; - strlcpy(outp, p, maxl); - outp+=l; - *newlen+=l; - efree(p); - } - } - } else if(!isspace(*src)&&(*src!='=')) { - US.ml=BUFSIZE; - US.p=US.val=erealloc(US.val,US.ml); - US.l=0; - US.attr_done=0; - if((*src=='"')||(*src=='\'')) { - US.state=STATE_TAG_QVAL2; - US.delim=*src; - } else { - US.state=STATE_TAG_VAL; - *US.p++=*src; - US.l++; - } - } - break; - - - case STATE_TAG_QVAL2: - if(*src=='#') { - if(! (US.attr_done)) { - char *p; - US.attr_done=1; - *US.p='\0'; - p=url_attr_addon(US.tag,US.attr,US.val,data); - if(p) { - int l= strlen(p); - maxl+=l; - out=realloc(out,maxl); - outp=out+*newlen; - strlcpy(outp,p,maxl); - outp+=l; - *newlen+=l; - efree(p); - } - } - } else if(*src==US.delim) { - US.state=STATE_IN_TAG; - *US.p='\0'; - if(! (US.attr_done)) { - char *p; - p=url_attr_addon(US.tag,US.attr,US.val,data); - if(p) { - int l= strlen(p); - maxl+=l; - out=realloc(out,maxl); - outp=out+*newlen; - strlcpy(outp,p,maxl); - outp+=l; - *newlen+=l; - efree(p); - } - } - break; - } else if(*src=='\\') { - US.state=STATE_TAG_QVAL2b; - } else if (*src=='>') { - US.state=STATE_NORMAL; - } - - *US.p++=*src; - ++US.l; - if(US.l==US.ml) { - US.ml+=BUFSIZE; - US.val=erealloc(US.val,US.ml); - US.p = US.val+US.l; - } - - break; - - case STATE_TAG_QVAL2b: - US.state=STATE_TAG_QVAL2; - *US.p++=*src; - ++US.l; - if(US.l==US.ml) { - US.ml+=BUFSIZE; - US.val=erealloc(US.val,US.ml); - US.p = US.val+US.l; - } - break; - - case STATE_TAG_VAL: - case STATE_TAG_VAL2: - if(*src=='#') { - if(! (US.attr_done)) { - char *p; - US.attr_done=1; - *US.p='\0'; - p=url_attr_addon(US.tag,US.attr,US.val,data); - if(p) { - int l= strlen(p); - maxl+=l; - out=realloc(out,maxl); - outp=out+*newlen; - strlcpy(outp,p,maxl); - outp+=l; - *newlen+=l; - efree(p); - } - } - } else if(isspace(*src)||(*src=='>')) { - US.state=(*src=='>')?STATE_NORMAL:STATE_IN_TAG; - *US.p='\0'; - if(! (US.attr_done)) { - char *p; - p=url_attr_addon(US.tag,US.attr,US.val,data); - if(p) { - int l= strlen(p); - maxl+=l; - out=realloc(out,maxl); - outp=out+*newlen; - strlcpy(outp,p,maxl); - outp+=l; - *newlen+=l; - efree(p); - } - } - } else { - *US.p++=*src; - US.l++; - if(US.l==US.ml) { - US.ml+=BUFSIZE; - US.val=erealloc(US.val,US.ml); - US.p = US.val+US.l; - } - } - break; - default: - break; - } - - *outp++=*src++; - *newlen+=1; - } - *outp='\0'; - return out; -} -/* }}} */ - -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * End: - * vim600: sw=4 ts=4 fdm=marker - * vim<600: sw=4 ts=4 - */ diff --git a/ext/standard/url_scanner.h b/ext/standard/url_scanner.h deleted file mode 100644 index fc87d331e..000000000 --- a/ext/standard/url_scanner.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2009 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.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 | - +----------------------------------------------------------------------+ - */ -/* $Id: url_scanner.h,v 1.16.2.1.2.1.2.2 2008/12/31 11:15:46 sebastian Exp $ */ - -#ifndef URI_SCANNER_H -#define URI_SCANNER_H - -int php_url_scanner_activate(TSRMLS_D); -int php_url_scanner_deactivate(TSRMLS_D); - -char *url_adapt(const char *src, size_t srclen, const char *data, size_t *newlen); - -enum url_state { - STATE_NORMAL, - STATE_TAG_START, - STATE_TAG, - STATE_IN_TAG, - STATE_TAG_ATTR, - STATE_TAG_IS, - STATE_TAG_IS2, - STATE_TAG_VAL, - STATE_TAG_VAL2, - STATE_TAG_QVAL1, - STATE_TAG_QVAL2, - STATE_TAG_QVAL2b -}; - -typedef struct url_adapt_struct { - enum url_state state; - char *tag; - char *attr; - char *val; - char delim; - char *p; - int l, ml; - int attr_done; -} url_adapt_state_t; - -#endif diff --git a/ext/standard/url_scanner_ex.c b/ext/standard/url_scanner_ex.c index aad323d54..e6a357a47 100644 --- a/ext/standard/url_scanner_ex.c +++ b/ext/standard/url_scanner_ex.c @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.4 on Tue Apr 8 13:43:20 2008 */ +/* Generated by re2c 0.13.5 on Mon Jul 27 02:20:40 2009 */ /* +----------------------------------------------------------------------+ | PHP Version 5 | @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: url_scanner_ex.c,v 1.95.2.4.2.3.2.5 2008/04/08 12:17:03 jani Exp $ */ +/* $Id: url_scanner_ex.c 286380 2009-07-26 23:22:27Z jani $ */ #include "php.h" @@ -907,7 +907,7 @@ static char *url_adapt_ext(const char *src, size_t srclen, size_t *newlen, zend_ return retval; } -int php_url_scanner_ex_activate(TSRMLS_D) +static int php_url_scanner_ex_activate(TSRMLS_D) { url_adapt_state_ex_t *ctx; @@ -918,7 +918,7 @@ int php_url_scanner_ex_activate(TSRMLS_D) return SUCCESS; } -int php_url_scanner_ex_deactivate(TSRMLS_D) +static int php_url_scanner_ex_deactivate(TSRMLS_D) { url_adapt_state_ex_t *ctx; @@ -963,7 +963,7 @@ static void php_url_scanner_output_handler(char *output, uint output_len, char * } } -int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC) +PHPAPI int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC) { char *encoded; int encoded_len; @@ -1003,7 +1003,7 @@ int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len return SUCCESS; } -int php_url_scanner_reset_vars(TSRMLS_D) +PHPAPI int php_url_scanner_reset_vars(TSRMLS_D) { BG(url_adapt_state_ex).form_app.len = 0; BG(url_adapt_state_ex).url_app.len = 0; diff --git a/ext/standard/url_scanner_ex.c.orig b/ext/standard/url_scanner_ex.c.orig index 582272d4c..35fa61e1a 100644 --- a/ext/standard/url_scanner_ex.c.orig +++ b/ext/standard/url_scanner_ex.c.orig @@ -1,4 +1,4 @@ -/* Generated by re2c 0.13.4 on Tue Apr 8 13:43:20 2008 */ +/* Generated by re2c 0.13.5 on Mon Jul 27 02:20:40 2009 */ #line 1 "ext/standard/url_scanner_ex.re" /* +----------------------------------------------------------------------+ @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: url_scanner_ex.c,v 1.95.2.4.2.3.2.5 2008/04/08 12:17:03 jani Exp $ */ +/* $Id: url_scanner_ex.c 286380 2009-07-26 23:22:27Z jani $ */ #include "php.h" @@ -963,7 +963,7 @@ static char *url_adapt_ext(const char *src, size_t srclen, size_t *newlen, zend_ return retval; } -int php_url_scanner_ex_activate(TSRMLS_D) +static int php_url_scanner_ex_activate(TSRMLS_D) { url_adapt_state_ex_t *ctx; @@ -974,7 +974,7 @@ int php_url_scanner_ex_activate(TSRMLS_D) return SUCCESS; } -int php_url_scanner_ex_deactivate(TSRMLS_D) +static int php_url_scanner_ex_deactivate(TSRMLS_D) { url_adapt_state_ex_t *ctx; @@ -1019,7 +1019,7 @@ static void php_url_scanner_output_handler(char *output, uint output_len, char * } } -int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC) +PHPAPI int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC) { char *encoded; int encoded_len; @@ -1059,7 +1059,7 @@ int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len return SUCCESS; } -int php_url_scanner_reset_vars(TSRMLS_D) +PHPAPI int php_url_scanner_reset_vars(TSRMLS_D) { BG(url_adapt_state_ex).form_app.len = 0; BG(url_adapt_state_ex).url_app.len = 0; diff --git a/ext/standard/url_scanner_ex.h b/ext/standard/url_scanner_ex.h index c93992315..d3fb96594 100644 --- a/ext/standard/url_scanner_ex.h +++ b/ext/standard/url_scanner_ex.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: url_scanner_ex.h,v 1.26.2.1.2.1.2.2 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: url_scanner_ex.h 286379 2009-07-26 23:20:34Z jani $ */ #ifndef URL_SCANNER_EX_H #define URL_SCANNER_EX_H @@ -27,13 +27,9 @@ PHP_MSHUTDOWN_FUNCTION(url_scanner_ex); PHP_RINIT_FUNCTION(url_scanner_ex); PHP_RSHUTDOWN_FUNCTION(url_scanner_ex); -char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen TSRMLS_DC); - -int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC); -int php_url_scanner_reset_vars(TSRMLS_D); - -int php_url_scanner_ex_activate(TSRMLS_D); -int php_url_scanner_ex_deactivate(TSRMLS_D); +PHPAPI char *php_url_scanner_adapt_single_url(const char *url, size_t urllen, const char *name, const char *value, size_t *newlen TSRMLS_DC); +PHPAPI int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC); +PHPAPI int php_url_scanner_reset_vars(TSRMLS_D); #include "php_smart_str_public.h" @@ -59,9 +55,4 @@ typedef struct { HashTable *tags; } url_adapt_state_ex_t; -typedef struct { - smart_str var; - smart_str val; -} url_adapt_var_t; - #endif diff --git a/ext/standard/url_scanner_ex.re b/ext/standard/url_scanner_ex.re index c1b32a2ed..91ba878aa 100644 --- a/ext/standard/url_scanner_ex.re +++ b/ext/standard/url_scanner_ex.re @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: url_scanner_ex.re,v 1.76.2.2.2.1.2.2 2008/03/12 19:34:37 felipe Exp $ */ +/* $Id: url_scanner_ex.re 286379 2009-07-26 23:20:34Z jani $ */ #include "php.h" @@ -401,7 +401,7 @@ static char *url_adapt_ext(const char *src, size_t srclen, size_t *newlen, zend_ return retval; } -int php_url_scanner_ex_activate(TSRMLS_D) +static int php_url_scanner_ex_activate(TSRMLS_D) { url_adapt_state_ex_t *ctx; @@ -412,7 +412,7 @@ int php_url_scanner_ex_activate(TSRMLS_D) return SUCCESS; } -int php_url_scanner_ex_deactivate(TSRMLS_D) +static int php_url_scanner_ex_deactivate(TSRMLS_D) { url_adapt_state_ex_t *ctx; @@ -457,7 +457,7 @@ static void php_url_scanner_output_handler(char *output, uint output_len, char * } } -int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC) +PHPAPI int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len, int urlencode TSRMLS_DC) { char *encoded; int encoded_len; @@ -497,7 +497,7 @@ int php_url_scanner_add_var(char *name, int name_len, char *value, int value_len return SUCCESS; } -int php_url_scanner_reset_vars(TSRMLS_D) +PHPAPI int php_url_scanner_reset_vars(TSRMLS_D) { BG(url_adapt_state_ex).form_app.len = 0; BG(url_adapt_state_ex).url_app.len = 0; diff --git a/ext/standard/user_filters.c b/ext/standard/user_filters.c index bc11f40c3..fc0069aff 100644 --- a/ext/standard/user_filters.c +++ b/ext/standard/user_filters.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: user_filters.c,v 1.31.2.4.2.9.2.11 2009/01/08 18:40:27 lbarnaud Exp $ */ +/* $Id: user_filters.c 273098 2009-01-08 18:40:27Z lbarnaud $ */ #include "php.h" #include "php_globals.h" diff --git a/ext/standard/uuencode.c b/ext/standard/uuencode.c index e9e2a9e8e..2980e1285 100644 --- a/ext/standard/uuencode.c +++ b/ext/standard/uuencode.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: uuencode.c,v 1.5.2.1.2.4.2.4 2009/05/13 16:29:26 kalle Exp $ */ +/* $Id: uuencode.c 280460 2009-05-13 16:29:26Z kalle $ */ /* * Portions of this code are based on Berkeley's uuencode/uudecode diff --git a/ext/standard/var.c b/ext/standard/var.c index 65f41f683..0ed635e2e 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: var.c,v 1.203.2.7.2.18.2.15 2009/01/07 14:36:06 derick Exp $ */ +/* $Id: var.c 287123 2009-08-11 22:46:07Z stas $ */ /* {{{ includes */ @@ -599,19 +599,19 @@ static void php_var_serialize_class(smart_str *buf, zval *struc, zval *retval_pt zend_mangle_property_name(&priv_name, &prop_name_length, ce->name, ce->name_length, Z_STRVAL_PP(name), Z_STRLEN_PP(name), ce->type & ZEND_INTERNAL_CLASS); if (zend_hash_find(Z_OBJPROP_P(struc), priv_name, prop_name_length + 1, (void *) &d) == SUCCESS) { php_var_serialize_string(buf, priv_name, prop_name_length); - efree(priv_name); + pefree(priv_name, ce->type & ZEND_INTERNAL_CLASS); php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC); break; } - efree(priv_name); + pefree(priv_name, ce->type & ZEND_INTERNAL_CLASS); zend_mangle_property_name(&prot_name, &prop_name_length, "*", 1, Z_STRVAL_PP(name), Z_STRLEN_PP(name), ce->type & ZEND_INTERNAL_CLASS); if (zend_hash_find(Z_OBJPROP_P(struc), prot_name, prop_name_length + 1, (void *) &d) == SUCCESS) { php_var_serialize_string(buf, prot_name, prop_name_length); - efree(prot_name); + pefree(prot_name, ce->type & ZEND_INTERNAL_CLASS); php_var_serialize_intern(buf, *d, var_hash TSRMLS_CC); break; } - efree(prot_name); + pefree(prot_name, ce->type & ZEND_INTERNAL_CLASS); php_error_docref(NULL TSRMLS_CC, E_NOTICE, "\"%s\" returned as member variable from __sleep() but does not exist", Z_STRVAL_PP(name)); php_var_serialize_string(buf, Z_STRVAL_PP(name), Z_STRLEN_PP(name)); php_var_serialize_intern(buf, nvalp, var_hash TSRMLS_CC); diff --git a/ext/standard/var_unserializer.c b/ext/standard/var_unserializer.c index 699667462..01d2fd9f6 100644 --- a/ext/standard/var_unserializer.c +++ b/ext/standard/var_unserializer.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: var_unserializer.c,v 1.70.2.4.2.7.2.11 2009/04/08 18:10:46 rasmus Exp $ */ +/* $Id: var_unserializer.c 278451 2009-04-08 18:10:46Z rasmus $ */ #include "php.h" #include "ext/standard/php_var.h" diff --git a/ext/standard/var_unserializer.c.orig b/ext/standard/var_unserializer.c.orig index d2e7d3e74..7eebfc0a8 100644 --- a/ext/standard/var_unserializer.c.orig +++ b/ext/standard/var_unserializer.c.orig @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: var_unserializer.c,v 1.70.2.4.2.7.2.11 2009/04/08 18:10:46 rasmus Exp $ */ +/* $Id: var_unserializer.c 278451 2009-04-08 18:10:46Z rasmus $ */ #include "php.h" #include "ext/standard/php_var.h" diff --git a/ext/standard/var_unserializer.re b/ext/standard/var_unserializer.re index 17949358b..0b009fa50 100644 --- a/ext/standard/var_unserializer.re +++ b/ext/standard/var_unserializer.re @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: var_unserializer.re,v 1.52.2.2.2.6.2.9 2009/03/17 23:07:40 felipe Exp $ */ +/* $Id: var_unserializer.re 277374 2009-03-17 23:07:40Z felipe $ */ #include "php.h" #include "ext/standard/php_var.h" diff --git a/ext/standard/versioning.c b/ext/standard/versioning.c index 3950db067..172c555b4 100644 --- a/ext/standard/versioning.c +++ b/ext/standard/versioning.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: versioning.c,v 1.19.2.1.2.3.2.4 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: versioning.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include #include diff --git a/ext/sybase_ct/config.m4 b/ext/sybase_ct/config.m4 index b4907db36..4b64dc23d 100644 --- a/ext/sybase_ct/config.m4 +++ b/ext/sybase_ct/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.15.4.1.2.1 2008/07/01 17:03:46 felipe Exp $ +dnl $Id: config.m4 261867 2008-07-01 17:03:46Z felipe $ dnl PHP_ARG_WITH(sybase-ct, for Sybase-CT support, diff --git a/ext/sybase_ct/config.w32 b/ext/sybase_ct/config.w32 index 1fe52c38a..603df21ae 100644 --- a/ext/sybase_ct/config.w32 +++ b/ext/sybase_ct/config.w32 @@ -1,5 +1,5 @@ -// $Id: config.w32,v 1.1 2003/12/19 17:00:13 wez Exp $ +// $Id: config.w32 242949 2007-09-26 15:44:16Z cvs2svn $ // vim:ft=javascript ARG_WITH("sybase-ct", "SYBASE_CT support", "no"); diff --git a/ext/sybase_ct/php_sybase_ct.c b/ext/sybase_ct/php_sybase_ct.c index 22b198c3e..b1774aea6 100644 --- a/ext/sybase_ct/php_sybase_ct.c +++ b/ext/sybase_ct/php_sybase_ct.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_sybase_ct.c,v 1.103.2.5.2.13.2.15 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: php_sybase_ct.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H diff --git a/ext/sybase_ct/php_sybase_ct.h b/ext/sybase_ct/php_sybase_ct.h index 81205c3da..d0da053f6 100644 --- a/ext/sybase_ct/php_sybase_ct.h +++ b/ext/sybase_ct/php_sybase_ct.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_sybase_ct.h,v 1.19.2.2.2.1.2.2 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: php_sybase_ct.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SYBASE_CT_H #define PHP_SYBASE_CT_H diff --git a/ext/sybase_ct/tests/bug22403.phpt b/ext/sybase_ct/tests/bug22403.phpt index 5e0669e63..5b4b5f32d 100644 --- a/ext/sybase_ct/tests/bug22403.phpt +++ b/ext/sybase_ct/tests/bug22403.phpt @@ -6,7 +6,7 @@ Sybase-CT bug #22403 (crash when executing a stored procedure without parameters expected= $expected; - } - - function matches($output) { } - } - // }}} - - // {{{ class PHPTRegexExpectancy - // Expectancy class for regular expressions - class PHPTRegexExpectancy extends PHPTExpectancy { - - function matches($output) { - return preg_match('^'.strtr(preg_quote(rtrim($this->expected), ''), array( - '%s' => '(.+)', - '%d' => '([0-9]+)' - )).'', $output); - } - } - // }}} - - // {{{ class PHPTTest - // Represents a single .phpt-style test - class PHPTTest { - var - $name = '', - $description = '', - $skipif = '', - $code = '', - $expectancy = NULL, - $output = ''; - - function &fromFile($filename) { - $fd= fopen($filename, 'r'); - - $sections= array(); - $current= NULL; - while (!feof($fd)) { - $line= fgets($fd, 0xFFFF); - if (1 == sscanf($line, '--%[^-]--', $section)) { - $sections[$section]= ''; - $current= $section; - continue; - } - $sections[$current].= $line; - } - fclose($fd); - - // Create instance from read data and return it - $t= &new PHPTTest(); { - $t->name= substr(realpath($filename), 0, -1); - $t->description= rtrim($sections['TEST']); - $t->skipif= $sections['SKIPIF']; - $t->code= $sections['FILE']; - - if (isset($sections['EXPECTF'])) { - $t->expectancy= &new PHPTRegexExpectancy($sections['EXPECTF']); - } else { - // XXX TBI XXX - } - } - return $t; - } - - function onError($errno, $errstr, $errfile, $errline) { - static $names= array( - E_NOTICE => 'Notice', - E_WARNING => 'Warning' - ); - - if (!(error_reporting() & $errno)) return; - printf( - "\n%s: %s in %s on line %d\n", - $names[$errno], - $errstr, - strstr($errfile, 'eval()\'d code') ? $this->name : $errfile, - $errline - ); - } - - function run() { - - // Precondition check - will die if test needs to be skipped - eval('?>'.$this->skipif); - - set_error_handler(array(&$this, 'onError')); { - error_reporting(E_ALL); - - ob_start(); - eval('?>'.$this->code); - $this->output= rtrim(ob_get_contents()); - ob_end_clean(); - } restore_error_handler(); - - return $this->expectancy->matches($this->output); - } - } - // }}} - - // {{{ main - if (isset($_GET['phpinfo'])) { - phpinfo((int)$_GET['phpinfo']); - - echo 'Home'; - exit(); - } - - echo <<<__ - - - PHPT Test - - - -__; - - $test= basename($_SERVER['QUERY_STRING']); - if ($test && file_exists($test)) { - $t= &PHPTTest::fromFile($test); - echo '

    '.basename($t->name), ': ', $t->description.'

    '; - echo 'Back to test suite'; - flush(); - - // Run the test - $result= $t->run(); - - // Evaluate results - if ($result) { - echo '

    Passed

    '; - } else { - echo '

    Failed


    '; - - echo '

    Actual output

    '; - echo '', $t->output, '
    '; - - echo '

    Expectancy

    '; - echo '', $t->expectancy->expected, ''; - } - - echo '
    '; - exit(); - } - - echo '

    Test suite

    '; - - // phpinfo() links - echo 'phpinfo(): '; - foreach (array( - 1 => 'General', - 4 => 'Configuration', - 8 => 'Modules' - ) as $const => $name) { - printf('%s | ', $const, $name); - } - echo '(All)'; - - echo '

    Select one to run

    '; - echo '
      '; - $d= dir(dirname(__FILE__)); - while ($entry= $d->read()) { - if ('.phpt' != substr($entry, -5)) continue; - echo '
    • '.$entry.'
    • '; - } - $d->close(); - echo '

    '; - - echo <<<__ - - -__; - // }}} -?> diff --git a/ext/sybase_ct/tests/skipif.inc b/ext/sybase_ct/tests/skipif.inc index 87fcddb81..5f2267cab 100644 --- a/ext/sybase_ct/tests/skipif.inc +++ b/ext/sybase_ct/tests/skipif.inc @@ -1,7 +1,7 @@ +--SKIPIF-- + +--FILE-- +'; +$config = array( + 'indent' => true, // AutoBool + 'indent-attributes' => true, // Boolean + 'indent-spaces' => 3, // Integer + 'language' => 'de'); // String +$tidy = new tidy(); +$tidy->parseString($buffer, $config); +$c = $tidy->getConfig(); +var_dump($c['indent']); +var_dump($c['indent-attributes']); +var_dump($c['indent-spaces']); +var_dump($c['language']); +?> +--EXPECTF-- +int(1) +bool(true) +int(3) +%s(2) "de" diff --git a/ext/tidy/tests/031.phpt b/ext/tidy/tests/031.phpt new file mode 100644 index 000000000..cf6aed9cc --- /dev/null +++ b/ext/tidy/tests/031.phpt @@ -0,0 +1,18 @@ +--TEST-- +tidy_config_count() function - basic test for tidy_config_count() +--CREDITS-- +Christian Wenz +--SKIPIF-- + +--FILE-- +'; +$config = array('doctype' => 'php'); + +$tidy = tidy_parse_string($buffer, $config); +var_dump(tidy_config_count($tidy)); +?> +--EXPECTF-- +int(%d) diff --git a/ext/tidy/tests/032.phpt b/ext/tidy/tests/032.phpt new file mode 100644 index 000000000..23230b065 --- /dev/null +++ b/ext/tidy/tests/032.phpt @@ -0,0 +1,17 @@ +--TEST-- +tidy_error_count() function - basic test for tidy_error_count() +--CREDITS-- +Christian Wenz +--SKIPIF-- + +--FILE-- +'; + +$tidy = tidy_parse_string($buffer); +var_dump(tidy_error_count($tidy)); +?> +--EXPECTF-- +int(%d) diff --git a/ext/tidy/tests/033.phpt b/ext/tidy/tests/033.phpt new file mode 100644 index 000000000..2c4bb44d4 --- /dev/null +++ b/ext/tidy/tests/033.phpt @@ -0,0 +1,17 @@ +--TEST-- +tidy_warning_count() function - basic test for tidy_warning_count() +--CREDITS-- +Christian Wenz +--SKIPIF-- + +--FILE-- +'; + +$tidy = tidy_parse_string($buffer); +var_dump(tidy_warning_count($tidy)); +?> +--EXPECTF-- +int(%d) diff --git a/ext/tidy/tests/034.phpt b/ext/tidy/tests/034.phpt new file mode 100644 index 000000000..978031523 --- /dev/null +++ b/ext/tidy/tests/034.phpt @@ -0,0 +1,20 @@ +--TEST-- +tidy_access_count() function - basic test for tidy_access_count() +--CREDITS-- +Christian Wenz +--SKIPIF-- + +--FILE-- +'; +$config = array( + 'accessibility-check' => 1); + +$tidy = tidy_parse_string($buffer, $config); +$tidy->diagnose(); +var_dump(tidy_access_count($tidy)); +?> +--EXPECTF-- +int(%d) diff --git a/ext/tidy/tests/tidy_error1.phpt b/ext/tidy/tests/tidy_error1.phpt new file mode 100644 index 000000000..a92446925 --- /dev/null +++ b/ext/tidy/tests/tidy_error1.phpt @@ -0,0 +1,19 @@ +--TEST-- +Notice triggered by invalid configuration options +--CREDITS-- +Christian Wenz +--SKIPIF-- + +--FILE-- +'; +$config = array('bogus' => 'willnotwork'); + +$tidy = new tidy(); +var_dump($tidy->parseString($buffer, $config)); +?> +--EXPECTF-- +Notice: tidy::parseString(): Unknown Tidy Configuration Option 'bogus' in %s on line %d +bool(true) diff --git a/ext/tidy/tidy.c b/ext/tidy/tidy.c index 9fbdc0939..43c6a413d 100644 --- a/ext/tidy/tidy.c +++ b/ext/tidy/tidy.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tidy.c,v 1.66.2.8.2.24.2.14 2009/01/06 23:45:16 iliaa Exp $ */ +/* $Id: tidy.c 272922 2009-01-06 23:45:16Z iliaa $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -1098,7 +1098,7 @@ static PHP_MINFO_FUNCTION(tidy) php_info_print_table_start(); php_info_print_table_header(2, "Tidy support", "enabled"); php_info_print_table_row(2, "libTidy Release", (char *)tidyReleaseDate()); - php_info_print_table_row(2, "Extension Version", PHP_TIDY_MODULE_VERSION " ($Id: tidy.c,v 1.66.2.8.2.24.2.14 2009/01/06 23:45:16 iliaa Exp $)"); + php_info_print_table_row(2, "Extension Version", PHP_TIDY_MODULE_VERSION " ($Id: tidy.c 272922 2009-01-06 23:45:16Z iliaa $)"); php_info_print_table_end(); DISPLAY_INI_ENTRIES(); diff --git a/ext/tokenizer/config.m4 b/ext/tokenizer/config.m4 index 924b2a15b..e5f04c5e8 100644 --- a/ext/tokenizer/config.m4 +++ b/ext/tokenizer/config.m4 @@ -1,4 +1,4 @@ -dnl $Id: config.m4,v 1.5.22.1 2007/07/31 23:24:11 johannes Exp $ +dnl $Id: config.m4 240543 2007-07-31 23:24:11Z johannes $ dnl config.m4 for extension tokenizer dnl Otherwise use enable: diff --git a/ext/tokenizer/config.w32 b/ext/tokenizer/config.w32 index 8aef99ddd..0b6ff63e2 100644 --- a/ext/tokenizer/config.w32 +++ b/ext/tokenizer/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.1.6.1 2007/08/01 15:13:40 pajoye Exp $ +// $Id: config.w32 240568 2007-08-01 15:13:40Z pajoye $ // vim:ft=javascript ARG_ENABLE("tokenizer", "tokenizer support", "yes"); diff --git a/ext/tokenizer/php_tokenizer.h b/ext/tokenizer/php_tokenizer.h index 9d2ec96b1..6f5e7e82c 100644 --- a/ext/tokenizer/php_tokenizer.h +++ b/ext/tokenizer/php_tokenizer.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_tokenizer.h,v 1.9.2.1.2.4.2.3 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: php_tokenizer.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_TOKENIZER_H #define PHP_TOKENIZER_H diff --git a/ext/tokenizer/tokenizer.c b/ext/tokenizer/tokenizer.c index 3c551f187..afc20f0d1 100644 --- a/ext/tokenizer/tokenizer.c +++ b/ext/tokenizer/tokenizer.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tokenizer.c,v 1.31.2.5.2.7.2.14 2009/03/25 15:23:17 dmitry Exp $ */ +/* $Id: tokenizer.c 277761 2009-03-25 15:23:58Z dmitry $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/tokenizer/tokenizer_data.c b/ext/tokenizer/tokenizer_data.c index ef31da6bb..a1e86960c 100644 --- a/ext/tokenizer/tokenizer_data.c +++ b/ext/tokenizer/tokenizer_data.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: tokenizer_data.c,v 1.1.2.2.2.10 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: tokenizer_data.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* DO NOT EDIT THIS FILE! diff --git a/ext/tokenizer/tokenizer_data_gen.sh b/ext/tokenizer/tokenizer_data_gen.sh index 44b502068..169530c4c 100755 --- a/ext/tokenizer/tokenizer_data_gen.sh +++ b/ext/tokenizer/tokenizer_data_gen.sh @@ -30,7 +30,7 @@ echo '/* +----------------------------------------------------------------------+ */ -/* $Id: tokenizer_data_gen.sh,v 1.1.2.2.2.1 2008/02/12 00:45:14 stas Exp $ */ +/* $Id: tokenizer_data_gen.sh,v 1.1.2.2.2.1 2008-02-12 00:45:14 stas Exp $ */ /* DO NOT EDIT THIS FILE! diff --git a/ext/wddx/config.m4 b/ext/wddx/config.m4 index 2eff124b2..3a086e7db 100644 --- a/ext/wddx/config.m4 +++ b/ext/wddx/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.11.2.1.2.1 2006/07/27 01:18:55 sniper Exp $ +dnl $Id: config.m4 217130 2006-07-27 01:18:55Z sniper $ dnl PHP_ARG_ENABLE(wddx,whether to enable WDDX support, diff --git a/ext/wddx/config.w32 b/ext/wddx/config.w32 index cdb79fb5f..2166862cc 100644 --- a/ext/wddx/config.w32 +++ b/ext/wddx/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.2.4.1 2005/10/06 13:03:43 derick Exp $ +// $Id: config.w32 197743 2005-10-06 13:03:43Z derick $ // vim:ft=javascript ARG_WITH("wddx", "WDDX support", "yes"); diff --git a/ext/wddx/php_wddx.h b/ext/wddx/php_wddx.h index ada3488f3..4ba445ab0 100644 --- a/ext/wddx/php_wddx.h +++ b/ext/wddx/php_wddx.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_wddx.h,v 1.18.2.1.2.1.2.2 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: php_wddx.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_WDDX_H #define PHP_WDDX_H diff --git a/ext/wddx/php_wddx_api.h b/ext/wddx/php_wddx_api.h index be8fc03fa..6a069bfad 100644 --- a/ext/wddx/php_wddx_api.h +++ b/ext/wddx/php_wddx_api.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_wddx_api.h,v 1.23.2.3.2.1.2.3 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: php_wddx_api.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_WDDX_API_H #define PHP_WDDX_API_H diff --git a/ext/wddx/wddx.c b/ext/wddx/wddx.c index 26f19ac97..82b3eb906 100644 --- a/ext/wddx/wddx.c +++ b/ext/wddx/wddx.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: wddx.c,v 1.119.2.10.2.17.2.19 2009/06/16 02:54:26 felipe Exp $ */ +/* $Id: wddx.c 282200 2009-06-16 02:54:26Z felipe $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/xml/config.m4 b/ext/xml/config.m4 index e5fa565ab..986515d26 100644 --- a/ext/xml/config.m4 +++ b/ext/xml/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.54.2.1 2005/12/22 08:57:38 helly Exp $ +dnl $Id: config.m4 203466 2005-12-22 08:57:38Z helly $ dnl PHP_ARG_ENABLE(xml,whether to enable XML support, diff --git a/ext/xml/config.w32 b/ext/xml/config.w32 index 1c3bbf386..5c4ac0a22 100644 --- a/ext/xml/config.w32 +++ b/ext/xml/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.3.8.2 2008/06/23 18:40:29 pajoye Exp $ +// $Id: config.w32 261548 2008-06-23 18:40:29Z pajoye $ // vim:ft=javascript ARG_WITH("xml", "XML support", "yes"); diff --git a/ext/xml/expat_compat.h b/ext/xml/expat_compat.h index f30a0887c..83c79ed4f 100644 --- a/ext/xml/expat_compat.h +++ b/ext/xml/expat_compat.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: expat_compat.h,v 1.19.2.1.2.1.2.2 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: expat_compat.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_EXPAT_COMPAT_H #define PHP_EXPAT_COMPAT_H diff --git a/ext/xml/php_xml.h b/ext/xml/php_xml.h index 79ae6acb3..db2d79290 100644 --- a/ext/xml/php_xml.h +++ b/ext/xml/php_xml.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_xml.h,v 1.28.2.2.2.3.2.3 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: php_xml.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_XML_H #define PHP_XML_H diff --git a/ext/xml/xml.c b/ext/xml/xml.c index 50f93807a..2a9240e6c 100644 --- a/ext/xml/xml.c +++ b/ext/xml/xml.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xml.c,v 1.157.2.4.2.5.2.16 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: xml.c 287790 2009-08-27 05:05:42Z rasmus $ */ #define IS_EXT_MODULE @@ -664,7 +664,7 @@ PHPAPI char *xml_utf8_decode(const XML_Char *s, int len, int *newlen, const XML_ { int pos = len; char *newbuf = emalloc(len + 1); - unsigned short c; + unsigned int c; char (*decoder)(unsigned short) = NULL; xml_encoding *enc = xml_get_encoding(encoding); diff --git a/ext/xmlreader/config.m4 b/ext/xmlreader/config.m4 index 3c3e8b76e..e7b9be2b4 100644 --- a/ext/xmlreader/config.m4 +++ b/ext/xmlreader/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.3.2.2 2005/12/17 15:40:37 helly Exp $ +dnl $Id: config.m4 203045 2005-12-17 15:40:37Z helly $ dnl PHP_ARG_ENABLE(xmlreader, whether to enable XMLReader support, diff --git a/ext/xmlreader/config.w32 b/ext/xmlreader/config.w32 index a84725d5c..52636e391 100644 --- a/ext/xmlreader/config.w32 +++ b/ext/xmlreader/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.2.2.1 2005/12/01 08:54:22 sniper Exp $ +// $Id: config.w32 201797 2005-12-01 08:54:22Z sniper $ // vim:ft=javascript ARG_ENABLE("xmlreader", "XMLReader support", "yes"); diff --git a/ext/xmlreader/php_xmlreader.c b/ext/xmlreader/php_xmlreader.c index 8fc3075b7..26c8bd272 100644 --- a/ext/xmlreader/php_xmlreader.c +++ b/ext/xmlreader/php_xmlreader.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_xmlreader.c,v 1.13.2.14.2.9.2.10 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: php_xmlreader.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/xmlreader/php_xmlreader.h b/ext/xmlreader/php_xmlreader.h index 81aa8f183..de3790ce0 100644 --- a/ext/xmlreader/php_xmlreader.h +++ b/ext/xmlreader/php_xmlreader.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_xmlreader.h,v 1.3.2.2.2.2.2.3 2008/12/31 11:15:46 sebastian Exp $ */ +/* $Id: php_xmlreader.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_XMLREADER_H #define PHP_XMLREADER_H diff --git a/ext/xmlreader/tests/001.phpt b/ext/xmlreader/tests/001.phpt index cf3d312b9..2b386356a 100644 --- a/ext/xmlreader/tests/001.phpt +++ b/ext/xmlreader/tests/001.phpt @@ -4,7 +4,7 @@ XMLReader: libxml2 XML Reader, string data --FILE-- '; diff --git a/ext/xmlreader/tests/002.phpt b/ext/xmlreader/tests/002.phpt index c9bf68ba1..dbb1241b5 100644 --- a/ext/xmlreader/tests/002.phpt +++ b/ext/xmlreader/tests/002.phpt @@ -4,7 +4,7 @@ XMLReader: libxml2 XML Reader, file data --FILE-- '; diff --git a/ext/xmlreader/tests/003.phpt b/ext/xmlreader/tests/003.phpt index bddb58dea..be5192e9f 100644 --- a/ext/xmlreader/tests/003.phpt +++ b/ext/xmlreader/tests/003.phpt @@ -4,7 +4,7 @@ XMLReader: libxml2 XML Reader, attributes test --FILE-- diff --git a/ext/xmlreader/tests/004.phpt b/ext/xmlreader/tests/004.phpt index ff22cce8e..cf15a91f3 100644 --- a/ext/xmlreader/tests/004.phpt +++ b/ext/xmlreader/tests/004.phpt @@ -4,7 +4,7 @@ XMLReader: libxml2 XML Reader, attributes test --FILE-- diff --git a/ext/xmlreader/tests/005.phpt b/ext/xmlreader/tests/005.phpt index ce2a5361d..0ef32b5bb 100644 --- a/ext/xmlreader/tests/005.phpt +++ b/ext/xmlreader/tests/005.phpt @@ -4,7 +4,7 @@ XMLReader: libxml2 XML Reader, parser property set/get --FILE-- '; diff --git a/ext/xmlreader/tests/006.phpt b/ext/xmlreader/tests/006.phpt index d482d020b..bbe6c2783 100644 --- a/ext/xmlreader/tests/006.phpt +++ b/ext/xmlreader/tests/006.phpt @@ -4,7 +4,7 @@ XMLReader: libxml2 XML Reader, moveToElement --FILE-- '; diff --git a/ext/xmlreader/tests/007.phpt b/ext/xmlreader/tests/007.phpt index a94bc3859..fab60dd34 100644 --- a/ext/xmlreader/tests/007.phpt +++ b/ext/xmlreader/tests/007.phpt @@ -4,7 +4,7 @@ XMLReader: libxml2 XML Reader, setRelaxNGSchema --FILE-- hello'; $relaxngfile = dirname(__FILE__) . '/relaxNG.rng'; diff --git a/ext/xmlreader/tests/008.phpt b/ext/xmlreader/tests/008.phpt index 8f3354726..938a02d39 100644 --- a/ext/xmlreader/tests/008.phpt +++ b/ext/xmlreader/tests/008.phpt @@ -4,7 +4,7 @@ XMLReader: libxml2 XML Reader, DTD --FILE-- diff --git a/ext/xmlreader/tests/009.phpt b/ext/xmlreader/tests/009.phpt index 3e9957d3e..4993f3811 100644 --- a/ext/xmlreader/tests/009.phpt +++ b/ext/xmlreader/tests/009.phpt @@ -4,7 +4,7 @@ XMLReader: libxml2 XML Reader, next --FILE-- '; diff --git a/ext/xmlreader/tests/010.phpt b/ext/xmlreader/tests/010.phpt index 37d2a8ede..32f592c30 100644 --- a/ext/xmlreader/tests/010.phpt +++ b/ext/xmlreader/tests/010.phpt @@ -4,7 +4,7 @@ XMLReader: libxml2 XML Reader, next --FILE-- book1'; diff --git a/ext/xmlreader/tests/011.phpt b/ext/xmlreader/tests/011.phpt index be31bbe47..6251f8cfe 100644 --- a/ext/xmlreader/tests/011.phpt +++ b/ext/xmlreader/tests/011.phpt @@ -7,7 +7,7 @@ if (!method_exists($reader, 'readInnerXml')) print "skip"; ?> --FILE-- test'; diff --git a/ext/xmlreader/tests/012.phpt b/ext/xmlreader/tests/012.phpt index ccd9d3b0b..efc42350d 100755 --- a/ext/xmlreader/tests/012.phpt +++ b/ext/xmlreader/tests/012.phpt @@ -4,7 +4,7 @@ XMLReader: accessing empty and non existing attributes --FILE-- diff --git a/ext/xmlreader/tests/013.phpt b/ext/xmlreader/tests/013.phpt index 673aa9ca9..31fea40cd 100755 --- a/ext/xmlreader/tests/013.phpt +++ b/ext/xmlreader/tests/013.phpt @@ -5,7 +5,7 @@ XMLReader: Schema validation --FILE-- diff --git a/ext/xmlrpc/config.m4 b/ext/xmlrpc/config.m4 index e7b4c34b8..ffda30231 100644 --- a/ext/xmlrpc/config.m4 +++ b/ext/xmlrpc/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.25.2.3.4.1 2009/04/27 17:49:32 scottmac Exp $ +dnl $Id: config.m4 279452 2009-04-27 17:49:32Z scottmac $ dnl sinclude(ext/xmlrpc/libxmlrpc/acinclude.m4) diff --git a/ext/xmlrpc/config.w32 b/ext/xmlrpc/config.w32 index 250ba5662..cc04d5625 100644 --- a/ext/xmlrpc/config.w32 +++ b/ext/xmlrpc/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.2.8.2 2008/07/06 16:52:59 pajoye Exp $ +// $Id: config.w32 262125 2008-07-06 16:52:59Z pajoye $ // vim:ft=javascript ARG_WITH("xmlrpc", "XMLRPC-EPI support", "no"); diff --git a/ext/xmlrpc/libxmlrpc/base64.c b/ext/xmlrpc/libxmlrpc/base64.c index 75f283411..28309e009 100644 --- a/ext/xmlrpc/libxmlrpc/base64.c +++ b/ext/xmlrpc/libxmlrpc/base64.c @@ -1,4 +1,4 @@ -static const char rcsid[] = "#(@) $Id: base64.c,v 1.4.6.1 2007/03/04 18:24:49 iliaa Exp $"; +static const char rcsid[] = "#(@) $Id: base64.c 242949 2007-09-26 15:44:16Z cvs2svn $"; /* diff --git a/ext/xmlrpc/libxmlrpc/encodings.c b/ext/xmlrpc/libxmlrpc/encodings.c index 3352a51ff..cb541892e 100644 --- a/ext/xmlrpc/libxmlrpc/encodings.c +++ b/ext/xmlrpc/libxmlrpc/encodings.c @@ -41,7 +41,7 @@ #include #endif -static const char rcsid[] = "#(@) $Id: encodings.c,v 1.7.6.1 2007/09/19 00:33:43 stas Exp $"; +static const char rcsid[] = "#(@) $Id: encodings.c 242949 2007-09-26 15:44:16Z cvs2svn $"; #include diff --git a/ext/xmlrpc/libxmlrpc/queue.c b/ext/xmlrpc/libxmlrpc/queue.c index ca9603432..1b46fec64 100644 --- a/ext/xmlrpc/libxmlrpc/queue.c +++ b/ext/xmlrpc/libxmlrpc/queue.c @@ -1,4 +1,4 @@ -static const char rcsid[] = "#(@) $Id: queue.c,v 1.4 2002/07/05 04:43:53 danda Exp $"; +static const char rcsid[] = "#(@) $Id: queue.c 87765 2002-07-05 04:43:55Z danda $"; /* * Date last modified: Jan 2001 diff --git a/ext/xmlrpc/libxmlrpc/simplestring.c b/ext/xmlrpc/libxmlrpc/simplestring.c index 68dab918d..3cc9863af 100644 --- a/ext/xmlrpc/libxmlrpc/simplestring.c +++ b/ext/xmlrpc/libxmlrpc/simplestring.c @@ -31,7 +31,7 @@ */ -static const char rcsid[] = "#(@) $Id: simplestring.c,v 1.4 2003/12/16 21:00:21 sniper Exp $"; +static const char rcsid[] = "#(@) $Id: simplestring.c 146618 2003-12-16 21:00:21Z sniper $"; #define SIMPLESTRING_INCR 32 @@ -44,10 +44,7 @@ static const char rcsid[] = "#(@) $Id: simplestring.c,v 1.4 2003/12/16 21:00:21 * CREATION DATE * 06/2000 * HISTORY - * $Log: simplestring.c,v $ - * Revision 1.4 2003/12/16 21:00:21 sniper - * Fix some compile warnings (patch by Joe Orton) - * + * $Log$ * Revision 1.3 2002/08/22 01:25:50 sniper * kill some compile warnings * diff --git a/ext/xmlrpc/libxmlrpc/system_methods.c b/ext/xmlrpc/libxmlrpc/system_methods.c index c3c2b8891..c47236df1 100644 --- a/ext/xmlrpc/libxmlrpc/system_methods.c +++ b/ext/xmlrpc/libxmlrpc/system_methods.c @@ -35,10 +35,7 @@ * AUTHOR * Dan Libby, aka danda (dan@libby.com) * HISTORY - * $Log: system_methods.c,v $ - * Revision 1.2 2002/07/05 04:43:53 danda - * merged in updates from SF project. bring php repository up to date with xmlrpc-epi version 0.51 - * + * $Log$ * Revision 1.7 2001/09/29 21:58:05 danda * adding cvs log to history section * diff --git a/ext/xmlrpc/libxmlrpc/xml_element.c b/ext/xmlrpc/libxmlrpc/xml_element.c index f65ee5a7e..3385f8990 100644 --- a/ext/xmlrpc/libxmlrpc/xml_element.c +++ b/ext/xmlrpc/libxmlrpc/xml_element.c @@ -31,7 +31,7 @@ */ -static const char rcsid[] = "#(@) $Id: xml_element.c,v 1.9.4.1.2.2 2008/12/17 00:30:27 iliaa Exp $"; +static const char rcsid[] = "#(@) $Id: xml_element.c 271367 2008-12-17 00:30:27Z iliaa $"; @@ -43,11 +43,7 @@ static const char rcsid[] = "#(@) $Id: xml_element.c,v 1.9.4.1.2.2 2008/12/17 00 * CREATION DATE * 06/2000 * HISTORY - * $Log: xml_element.c,v $ - * Revision 1.9.4.1.2.2 2008/12/17 00:30:27 iliaa - * - * Removed unused variable - * + * $Log$ * Revision 1.9.4.1.2.1 2008/12/09 17:22:12 iliaa * * MFH: Fixed bug #46746 (xmlrpc_decode_request outputs non-suppressable error diff --git a/ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c b/ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c index b99a0afec..30c2d09e4 100644 --- a/ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c +++ b/ext/xmlrpc/libxmlrpc/xml_to_xmlrpc.c @@ -31,7 +31,7 @@ */ -static const char rcsid[] = "#(@) $Id: xml_to_xmlrpc.c,v 1.5.6.3 2007/05/03 04:16:32 edink Exp $"; +static const char rcsid[] = "#(@) $Id: xml_to_xmlrpc.c 242949 2007-09-26 15:44:16Z cvs2svn $"; #include "php.h" #include "main/snprintf.h" diff --git a/ext/xmlrpc/libxmlrpc/xmlrpc.c b/ext/xmlrpc/libxmlrpc/xmlrpc.c index 926ecfaa4..c54184cea 100644 --- a/ext/xmlrpc/libxmlrpc/xmlrpc.c +++ b/ext/xmlrpc/libxmlrpc/xmlrpc.c @@ -31,7 +31,7 @@ */ -static const char rcsid[] = "#(@) $Id: xmlrpc.c,v 1.8.4.3.2.2 2008/12/09 17:22:12 iliaa Exp $"; +static const char rcsid[] = "#(@) $Id: xmlrpc.c 270900 2008-12-09 17:22:12Z iliaa $"; /****h* ABOUT/xmlrpc @@ -42,12 +42,7 @@ static const char rcsid[] = "#(@) $Id: xmlrpc.c,v 1.8.4.3.2.2 2008/12/09 17:22:1 * CREATION DATE * 9/1999 - 10/2000 * HISTORY - * $Log: xmlrpc.c,v $ - * Revision 1.8.4.3.2.2 2008/12/09 17:22:12 iliaa - * - * MFH: Fixed bug #46746 (xmlrpc_decode_request outputs non-suppressable error - * when given bad data). - * + * $Log$ * Revision 1.8.4.3.2.1 2008/09/10 00:07:44 felipe * MFH: * - Merged fix from SF project (Import Jeff Lawsons patches for XML datetime bug fixes) diff --git a/ext/xmlrpc/libxmlrpc/xmlrpc_introspection.c b/ext/xmlrpc/libxmlrpc/xmlrpc_introspection.c index aa8fcd842..9964d839f 100644 --- a/ext/xmlrpc/libxmlrpc/xmlrpc_introspection.c +++ b/ext/xmlrpc/libxmlrpc/xmlrpc_introspection.c @@ -35,10 +35,7 @@ * AUTHOR * Dan Libby, aka danda (dan@libby.com) * HISTORY - * $Log: xmlrpc_introspection.c,v $ - * Revision 1.4.4.1 2005/12/18 22:59:57 sniper - * MFH: - Fixed bug #35723 (xmlrpc_introspection.c fails compile per C99 std) - * + * $Log$ * Revision 1.4 2003/12/16 21:00:21 sniper * Fix some compile warnings (patch by Joe Orton) * diff --git a/ext/xmlrpc/php_xmlrpc.h b/ext/xmlrpc/php_xmlrpc.h index 94ee1f158..ce18b53a8 100644 --- a/ext/xmlrpc/php_xmlrpc.h +++ b/ext/xmlrpc/php_xmlrpc.h @@ -51,7 +51,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_xmlrpc.h,v 1.11.2.1.2.2.2.3 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_xmlrpc.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef _PHP_XMLRPC_H #define _PHP_XMLRPC_H diff --git a/ext/xmlrpc/tests/001.phpt b/ext/xmlrpc/tests/001.phpt index 99fd958d2..262509671 100644 --- a/ext/xmlrpc/tests/001.phpt +++ b/ext/xmlrpc/tests/001.phpt @@ -38,19 +38,8 @@ string(160) " " -Notice: Array to string conversion in %s on line %d -string(177) " - -Array - - - - 1 - - - - -" +Warning: xmlrpc_encode_request() expects parameter 1 to be string, array given in %s on line %d +NULL string(175) " 3.4 diff --git a/ext/xmlrpc/tests/002.phpt b/ext/xmlrpc/tests/002.phpt index c8d722b80..83586464b 100644 --- a/ext/xmlrpc/tests/002.phpt +++ b/ext/xmlrpc/tests/002.phpt @@ -47,10 +47,7 @@ array(1) { } string(2) "-1" -Notice: Array to string conversion in %s on line %d -array(1) { - [0]=> - int(1) -} -string(5) "Array" +Warning: xmlrpc_encode_request() expects parameter 1 to be string, array given in %s on line %d +NULL +string(2) "-1" Done diff --git a/ext/xmlrpc/xmlrpc-epi-php.c b/ext/xmlrpc/xmlrpc-epi-php.c index b45e27401..77ec4ecbf 100644 --- a/ext/xmlrpc/xmlrpc-epi-php.c +++ b/ext/xmlrpc/xmlrpc-epi-php.c @@ -51,7 +51,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xmlrpc-epi-php.c,v 1.39.2.5.2.6.2.23 2009/05/22 12:49:40 felipe Exp $ */ +/* $Id: xmlrpc-epi-php.c 287434 2009-08-18 00:41:43Z stas $ */ /********************************************************************** * BUGS: * @@ -682,10 +682,12 @@ PHP_FUNCTION(xmlrpc_encode_request) { XMLRPC_REQUEST xRequest = NULL; char *outBuf; - zval **method, **vals, *out_opts = NULL; + zval *vals, *out_opts = NULL; + char *method = NULL; + int method_len; php_output_options out; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ZZ|a", &method, &vals, &out_opts) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s!z|a", &method, &method_len, &vals, &out_opts) == FAILURE) { return; } @@ -696,15 +698,14 @@ PHP_FUNCTION(xmlrpc_encode_request) if (xRequest) { XMLRPC_RequestSetOutputOptions(xRequest, &out.xmlrpc_out); - if (Z_TYPE_PP(method) == IS_NULL) { + if (method == NULL) { XMLRPC_RequestSetRequestType(xRequest, xmlrpc_request_response); } else { - convert_to_string_ex(method); - XMLRPC_RequestSetMethodName(xRequest, Z_STRVAL_PP(method)); + XMLRPC_RequestSetMethodName(xRequest, method); XMLRPC_RequestSetRequestType(xRequest, xmlrpc_request_call); } - if (Z_TYPE_PP(vals) != IS_NULL) { - XMLRPC_RequestSetData(xRequest, PHP_to_XMLRPC(*vals TSRMLS_CC)); + if (Z_TYPE_P(vals) != IS_NULL) { + XMLRPC_RequestSetData(xRequest, PHP_to_XMLRPC(vals TSRMLS_CC)); } outBuf = XMLRPC_REQUEST_ToXML(xRequest, 0); @@ -794,7 +795,6 @@ PHP_FUNCTION(xmlrpc_decode_request) return; } - convert_to_string_ex(method); if (return_value_used) { zval* retval = decode_request_worker(xml, xml_len, encoding_len ? encoding : NULL, *method); @@ -1055,20 +1055,20 @@ PHP_FUNCTION(xmlrpc_server_call_method) XMLRPC_REQUEST xRequest; STRUCT_XMLRPC_REQUEST_INPUT_OPTIONS input_opts; xmlrpc_server_data* server; - zval **caller_params, *handle, **output_opts = NULL; + zval **caller_params, *handle, *output_opts = NULL; char *rawxml; int rawxml_len, type; php_output_options out; int argc =ZEND_NUM_ARGS(); - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsZ|Z", &handle, &rawxml, &rawxml_len, &caller_params, &output_opts) != SUCCESS) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rsZ|a", &handle, &rawxml, &rawxml_len, &caller_params, &output_opts) != SUCCESS) { return; } /* user output options */ if (argc == 3) { set_output_options(&out, NULL); } else { - set_output_options(&out, *output_opts); + set_output_options(&out, output_opts); } server = zend_list_find(Z_LVAL_P(handle), &type); diff --git a/ext/xmlwriter/config.m4 b/ext/xmlwriter/config.m4 index 92bfef1ea..229a74d64 100644 --- a/ext/xmlwriter/config.m4 +++ b/ext/xmlwriter/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.4.2.6 2005/12/04 00:21:39 tony2001 Exp $ +dnl $Id: config.m4 201989 2005-12-04 00:21:39Z tony2001 $ dnl PHP_ARG_ENABLE(xmlwriter, whether to enable XMLWriter support, diff --git a/ext/xmlwriter/config.w32 b/ext/xmlwriter/config.w32 index 11ea39edd..c04fca377 100644 --- a/ext/xmlwriter/config.w32 +++ b/ext/xmlwriter/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.3.2.3 2005/12/02 10:55:33 mike Exp $ +// $Id: config.w32 201877 2005-12-02 10:55:33Z mike $ // vim:ft=javascript ARG_ENABLE("xmlwriter", "XMLWriter support", "yes"); diff --git a/ext/xmlwriter/php_xmlwriter.c b/ext/xmlwriter/php_xmlwriter.c index 21516a15a..9af9809d7 100644 --- a/ext/xmlwriter/php_xmlwriter.c +++ b/ext/xmlwriter/php_xmlwriter.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_xmlwriter.c,v 1.20.2.12.2.15.2.15 2009/05/26 08:10:49 pajoye Exp $ */ +/* $Id: php_xmlwriter.c 281145 2009-05-26 08:10:49Z pajoye $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/xmlwriter/php_xmlwriter.h b/ext/xmlwriter/php_xmlwriter.h index 4212d60ee..86240b3a5 100644 --- a/ext/xmlwriter/php_xmlwriter.h +++ b/ext/xmlwriter/php_xmlwriter.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_xmlwriter.h,v 1.10.2.5.2.3.2.2 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_xmlwriter.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_XMLWRITER_H #define PHP_XMLWRITER_H diff --git a/ext/xmlwriter/tests/001.phpt b/ext/xmlwriter/tests/001.phpt index b21fd148c..67cbebae3 100644 --- a/ext/xmlwriter/tests/001.phpt +++ b/ext/xmlwriter/tests/001.phpt @@ -4,7 +4,7 @@ XMLWriter: libxml2 XML Writer, file buffer, flush --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- --FILE-- openMemory(); diff --git a/ext/xmlwriter/tests/OO_003.phpt b/ext/xmlwriter/tests/OO_003.phpt index 1e50a31a8..46b88c392 100644 --- a/ext/xmlwriter/tests/OO_003.phpt +++ b/ext/xmlwriter/tests/OO_003.phpt @@ -4,7 +4,7 @@ XMLWriter: libxml2 XML Writer, membuffer, flush, text, attribute --FILE-- openMemory(); diff --git a/ext/xmlwriter/tests/OO_004.phpt b/ext/xmlwriter/tests/OO_004.phpt index b3e3b2af1..ab69e5a79 100644 --- a/ext/xmlwriter/tests/OO_004.phpt +++ b/ext/xmlwriter/tests/OO_004.phpt @@ -4,7 +4,7 @@ XMLWriter: libxml2 XML Writer, file buffer, flush --FILE-- --FILE-- --FILE-- --FILE-- openMemory(); diff --git a/ext/xmlwriter/tests/OO_008.phpt b/ext/xmlwriter/tests/OO_008.phpt index 5541ba1dc..6e7fd6f45 100644 --- a/ext/xmlwriter/tests/OO_008.phpt +++ b/ext/xmlwriter/tests/OO_008.phpt @@ -6,7 +6,7 @@ if (!extension_loaded("xmlwriter")) die("skip"); ?> --FILE-- openMemory(); diff --git a/ext/xmlwriter/tests/OO_009.phpt b/ext/xmlwriter/tests/OO_009.phpt index 7fc918ab1..868f2b23b 100644 --- a/ext/xmlwriter/tests/OO_009.phpt +++ b/ext/xmlwriter/tests/OO_009.phpt @@ -6,7 +6,7 @@ if (!extension_loaded("xmlwriter")) die("skip"); ?> --FILE-- ---CREDIT-- +--CREDITS-- Koen Kuipers koenk82@gmail.com Theo van der Zee #Test Fest Utrecht 09-05-2009 diff --git a/ext/xmlwriter/tests/xmlwriter_open_uri_error_001.phpt b/ext/xmlwriter/tests/xmlwriter_open_uri_error_001.phpt index 8bdf7eaea..fb7602b53 100644 --- a/ext/xmlwriter/tests/xmlwriter_open_uri_error_001.phpt +++ b/ext/xmlwriter/tests/xmlwriter_open_uri_error_001.phpt @@ -6,7 +6,7 @@ xmlwriter_open_uri with empty string as parameter ---CREDIT-- +--CREDITS-- Koen Kuipers koenk82@gmail.com Theo van der Zee #Test Fest Utrecht 09-05-2009 diff --git a/ext/xmlwriter/tests/xmlwriter_open_uri_error_002.phpt b/ext/xmlwriter/tests/xmlwriter_open_uri_error_002.phpt index cfda44e21..9cd33f731 100644 --- a/ext/xmlwriter/tests/xmlwriter_open_uri_error_002.phpt +++ b/ext/xmlwriter/tests/xmlwriter_open_uri_error_002.phpt @@ -6,7 +6,7 @@ xmlwriter_open_uri without parameter ---CREDIT-- +--CREDITS-- Koen Kuipers koenk82@gmail.com Theo van der Zee #Test Fest Utrecht 09-05-2009 diff --git a/ext/xmlwriter/tests/xmlwriter_open_uri_error_003.phpt b/ext/xmlwriter/tests/xmlwriter_open_uri_error_003.phpt index 49a293853..0e56d891d 100644 --- a/ext/xmlwriter/tests/xmlwriter_open_uri_error_003.phpt +++ b/ext/xmlwriter/tests/xmlwriter_open_uri_error_003.phpt @@ -6,7 +6,7 @@ xmlwriter_open_uri with non existing file ---CREDIT-- +--CREDITS-- Koen Kuipers koenk82@gmail.com Theo van der Zee #Test Fest Utrecht 09-05-2009 diff --git a/ext/xmlwriter/tests/xmlwriter_open_uri_error_004.phpt b/ext/xmlwriter/tests/xmlwriter_open_uri_error_004.phpt index d4e72ffda..6970c0eda 100644 --- a/ext/xmlwriter/tests/xmlwriter_open_uri_error_004.phpt +++ b/ext/xmlwriter/tests/xmlwriter_open_uri_error_004.phpt @@ -6,7 +6,7 @@ xmlwriter_open_uri with file:/// ---CREDIT-- +--CREDITS-- Koen Kuipers koenk82@gmail.com Theo van der Zee #Test Fest Utrecht 09-05-2009 diff --git a/ext/xmlwriter/tests/xmlwriter_open_uri_error_005.phpt b/ext/xmlwriter/tests/xmlwriter_open_uri_error_005.phpt index 20a28afcd..9d08716cc 100644 --- a/ext/xmlwriter/tests/xmlwriter_open_uri_error_005.phpt +++ b/ext/xmlwriter/tests/xmlwriter_open_uri_error_005.phpt @@ -6,7 +6,7 @@ xmlwriter_open_uri with file://localhost/ ---CREDIT-- +--CREDITS-- Koen Kuipers koenk82@gmail.com Theo van der Zee #Test Fest Utrecht 09-05-2009 diff --git a/ext/xmlwriter/tests/xmlwriter_set_indent_string_basic_001.phpt b/ext/xmlwriter/tests/xmlwriter_set_indent_string_basic_001.phpt index 896778b02..8c3e7d925 100644 --- a/ext/xmlwriter/tests/xmlwriter_set_indent_string_basic_001.phpt +++ b/ext/xmlwriter/tests/xmlwriter_set_indent_string_basic_001.phpt @@ -16,7 +16,7 @@ var_dump(xmlwriter_set_indent_string($resource, ' ')); $temp_filename = dirname(__FILE__)."/xmlwriter_set_indent_string.tmp"; unlink($temp_filename); ?> ---CREDIT-- +--CREDITS-- Koen Kuipers koenk82@gmail.com Theo van der Zee #Test Fest Utrecht 09-05-2009 diff --git a/ext/xmlwriter/tests/xmlwriter_set_indent_string_error_001.phpt b/ext/xmlwriter/tests/xmlwriter_set_indent_string_error_001.phpt index c39678dac..5bb9ef8b6 100644 --- a/ext/xmlwriter/tests/xmlwriter_set_indent_string_error_001.phpt +++ b/ext/xmlwriter/tests/xmlwriter_set_indent_string_error_001.phpt @@ -16,7 +16,7 @@ var_dump(xmlwriter_set_indent_string($resource)); $temp_filename = dirname(__FILE__)."/xmlwriter_set_indent_string_error.tmp"; unlink($temp_filename); ?> ---CREDIT-- +--CREDITS-- Koen Kuipers koenk82@gmail.com --EXPECTF-- diff --git a/ext/xmlwriter/tests/xmlwriter_write_attribute_ns_basic_001.phpt b/ext/xmlwriter/tests/xmlwriter_write_attribute_ns_basic_001.phpt index 090327b66..f24804964 100644 --- a/ext/xmlwriter/tests/xmlwriter_write_attribute_ns_basic_001.phpt +++ b/ext/xmlwriter/tests/xmlwriter_write_attribute_ns_basic_001.phpt @@ -18,7 +18,7 @@ xmlwriter_end_document($xw); $output = xmlwriter_flush($xw, true); print $output; ?> ---CREDIT-- +--CREDITS-- Koen Kuipers koenk82@gmail.com --EXPECT-- diff --git a/ext/xmlwriter/tests/xmlwriter_write_attribute_ns_error_001.phpt b/ext/xmlwriter/tests/xmlwriter_write_attribute_ns_error_001.phpt index 251672313..1968b1b14 100644 --- a/ext/xmlwriter/tests/xmlwriter_write_attribute_ns_error_001.phpt +++ b/ext/xmlwriter/tests/xmlwriter_write_attribute_ns_error_001.phpt @@ -23,7 +23,7 @@ $xw = xmlwriter_open_memory(); var_dump(xmlwriter_write_attribute_ns($xw, 'prefix', 'id', 'http://www.php.net/uri', 'elem1')); print xmlwriter_output_memory($xw); ?> ---CREDIT-- +--CREDITS-- Koen Kuipers koenk82@gmail.com --EXPECTF-- diff --git a/ext/xmlwriter/tests/xmlwriter_write_dtd_basic_001.phpt b/ext/xmlwriter/tests/xmlwriter_write_dtd_basic_001.phpt index 62adce818..af3dce61a 100644 --- a/ext/xmlwriter/tests/xmlwriter_write_dtd_basic_001.phpt +++ b/ext/xmlwriter/tests/xmlwriter_write_dtd_basic_001.phpt @@ -14,7 +14,7 @@ var_dump(xmlwriter_write_dtd($xmlwriter, '', '', '')); $output = xmlwriter_flush($xmlwriter, true); print $output; ?> ---CREDIT-- +--CREDITS-- Koen Kuipers koenk82@gmail.com --EXPECT-- bool(true) diff --git a/ext/xmlwriter/tests/xmlwriter_write_dtd_error_001.phpt b/ext/xmlwriter/tests/xmlwriter_write_dtd_error_001.phpt index 7968eb456..69a6a7f6c 100644 --- a/ext/xmlwriter/tests/xmlwriter_write_dtd_error_001.phpt +++ b/ext/xmlwriter/tests/xmlwriter_write_dtd_error_001.phpt @@ -7,7 +7,7 @@ xmlwriter_write_dtd with missing param(s) $xmlwriter = xmlwriter_open_memory(); var_dump(xmlwriter_write_dtd($xmlwriter)); ?> ---CREDIT-- +--CREDITS-- Koen Kuipers koenk82@gmail.com --EXPECTF-- diff --git a/ext/xsl/config.m4 b/ext/xsl/config.m4 index 606963f60..84d76f069 100644 --- a/ext/xsl/config.m4 +++ b/ext/xsl/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.11.4.2 2007/07/03 17:25:35 sniper Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(xsl, for XSL support, diff --git a/ext/xsl/config.w32 b/ext/xsl/config.w32 index aed0c84a3..27f68a11d 100644 --- a/ext/xsl/config.w32 +++ b/ext/xsl/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.9.6.1 2008/12/26 14:05:05 pajoye Exp $ +// $Id: config.w32 271909 2008-12-26 14:05:05Z pajoye $ // vim: ft=javascript ARG_WITH("xsl", "xsl support", "no"); diff --git a/ext/xsl/php_xsl.c b/ext/xsl/php_xsl.c index e129655f7..4bbf59d37 100644 --- a/ext/xsl/php_xsl.c +++ b/ext/xsl/php_xsl.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_xsl.c,v 1.32.2.6.2.2.2.6 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_xsl.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef HAVE_CONFIG_H #include "config.h" diff --git a/ext/xsl/php_xsl.h b/ext/xsl/php_xsl.h index c759d60cc..38d2c87db 100644 --- a/ext/xsl/php_xsl.h +++ b/ext/xsl/php_xsl.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_xsl.h,v 1.15.2.1.2.1.2.4 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_xsl.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_XSL_H #define PHP_XSL_H diff --git a/ext/xsl/tests/documentxpath.xsl b/ext/xsl/tests/documentxpath.xsl index 01035e82b..0e5c5c181 100644 --- a/ext/xsl/tests/documentxpath.xsl +++ b/ext/xsl/tests/documentxpath.xsl @@ -1,5 +1,5 @@ - + diff --git a/ext/xsl/tests/phpfunc-nostring.xsl b/ext/xsl/tests/phpfunc-nostring.xsl index 7558ebeb2..f278fafdc 100644 --- a/ext/xsl/tests/phpfunc-nostring.xsl +++ b/ext/xsl/tests/phpfunc-nostring.xsl @@ -1,5 +1,5 @@ - + diff --git a/ext/xsl/tests/phpfunc-undef.xsl b/ext/xsl/tests/phpfunc-undef.xsl index 69db215d2..e05b03b8d 100644 --- a/ext/xsl/tests/phpfunc-undef.xsl +++ b/ext/xsl/tests/phpfunc-undef.xsl @@ -1,5 +1,5 @@ - + diff --git a/ext/xsl/tests/phpfunc.xsl b/ext/xsl/tests/phpfunc.xsl index 3efb7d8b0..3031ab7c1 100644 --- a/ext/xsl/tests/phpfunc.xsl +++ b/ext/xsl/tests/phpfunc.xsl @@ -1,5 +1,5 @@ - + diff --git a/ext/xsl/tests/streamsinclude.xsl b/ext/xsl/tests/streamsinclude.xsl index 9b1c8be42..6f8bc40ed 100644 --- a/ext/xsl/tests/streamsinclude.xsl +++ b/ext/xsl/tests/streamsinclude.xsl @@ -1,5 +1,5 @@ - + diff --git a/ext/xsl/tests/xslt.xsl b/ext/xsl/tests/xslt.xsl index 755687482..8331ccc2b 100644 --- a/ext/xsl/tests/xslt.xsl +++ b/ext/xsl/tests/xslt.xsl @@ -1,5 +1,5 @@ - + diff --git a/ext/xsl/tests/xslt012.xsl b/ext/xsl/tests/xslt012.xsl index eb0c491da..27f413855 100644 --- a/ext/xsl/tests/xslt012.xsl +++ b/ext/xsl/tests/xslt012.xsl @@ -1,5 +1,5 @@ - + diff --git a/ext/xsl/xsl_fe.h b/ext/xsl/xsl_fe.h index 28619e895..f21b89846 100644 --- a/ext/xsl/xsl_fe.h +++ b/ext/xsl/xsl_fe.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xsl_fe.h,v 1.8.2.1.2.1.2.5 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: xsl_fe.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef XSL_FE_H #define XSL_FE_H diff --git a/ext/xsl/xsltprocessor.c b/ext/xsl/xsltprocessor.c index 1345c10c6..e07bdd564 100644 --- a/ext/xsl/xsltprocessor.c +++ b/ext/xsl/xsltprocessor.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xsltprocessor.c,v 1.39.2.2.2.9.2.19 2009/06/06 02:40:49 mattwil Exp $ */ +/* $Id: xsltprocessor.c 287968 2009-09-02 13:07:44Z iliaa $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -675,7 +675,7 @@ PHP_FUNCTION(xsl_xsltprocessor_transform_to_xml) ret = -1; if (newdocp) { ret = xsltSaveResultToString(&doc_txt_ptr, &doc_txt_len, newdocp, sheetp); - if (doc_txt_ptr) { + if (doc_txt_ptr && doc_txt_len) { RETVAL_STRINGL(doc_txt_ptr, doc_txt_len, 1); xmlFree(doc_txt_ptr); } diff --git a/ext/zip/config.m4 b/ext/zip/config.m4 index 4ee9105e7..7b2cf03f0 100644 --- a/ext/zip/config.m4 +++ b/ext/zip/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.8.2.3.2.6 2008/08/08 09:47:15 pajoye Exp $ +dnl $Id: config.m4 264447 2008-08-08 09:47:15Z pajoye $ dnl PHP_ARG_ENABLE(zip, for zip archive read/writesupport, diff --git a/ext/zip/config.w32 b/ext/zip/config.w32 index 53078fd2c..a06ee9385 100644 --- a/ext/zip/config.w32 +++ b/ext/zip/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.1.2.1.2.6 2008/08/07 23:24:11 pajoye Exp $ +// $Id: config.w32 264425 2008-08-07 23:24:11Z pajoye $ // vim:ft=javascript ARG_ENABLE("zip", "ZIP support", "yes"); diff --git a/ext/zip/examples/im.php b/ext/zip/examples/im.php index a922ab263..efd025fd5 100644 --- a/ext/zip/examples/im.php +++ b/ext/zip/examples/im.php @@ -1,5 +1,5 @@ open('zip://' . dirname(__FILE__) . '/test.odt#meta.xml'); diff --git a/ext/zip/lib/zip_close.c b/ext/zip/lib/zip_close.c index d9fc6eea4..bc640c77b 100644 --- a/ext/zip/lib/zip_close.c +++ b/ext/zip/lib/zip_close.c @@ -175,6 +175,7 @@ zip_close(struct zip *za) de.filename = strdup("-"); de.filename_len = 1; cd->entry[j].filename = "-"; + cd->entry[j].filename_len = 1; } else { de.filename = strdup(za->cdir->entry[i].filename); @@ -195,13 +196,15 @@ zip_close(struct zip *za) error = 1; break; } + memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j])); + if (de.bitflags & ZIP_GPBF_DATA_DESCRIPTOR) { de.crc = za->cdir->entry[i].crc; de.comp_size = za->cdir->entry[i].comp_size; de.uncomp_size = za->cdir->entry[i].uncomp_size; de.bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; - } - memcpy(cd->entry+j, za->cdir->entry+i, sizeof(cd->entry[j])); + cd->entry[j].bitflags &= ~ZIP_GPBF_DATA_DESCRIPTOR; + } } if (za->entry[i].ch_filename) { @@ -229,11 +232,10 @@ zip_close(struct zip *za) zs = NULL; if (!ZIP_ENTRY_DATA_CHANGED(za->entry+i)) { - if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1)) - == NULL) { - error = 1; - break; - } + if ((zs=zip_source_zip(za, za, i, ZIP_FL_RECOMPRESS, 0, -1)) == NULL) { + error = 1; + break; + } } if (add_data(za, zs ? zs : za->entry[i].source, &de, out) < 0) { @@ -286,27 +288,27 @@ zip_close(struct zip *za) return -1; } - if (za->zp) { - fclose(za->zp); - za->zp = NULL; - reopen_on_error = 1; + if (za->zp) { + fclose(za->zp); + za->zp = NULL; + reopen_on_error = 1; } if (_zip_rename(temp, za->zn) != 0) { - _zip_error_set(&za->error, ZIP_ER_RENAME, errno); - remove(temp); - free(temp); - if (reopen_on_error) { - /* ignore errors, since we're already in an error case */ - za->zp = fopen(za->zn, "rb"); + _zip_error_set(&za->error, ZIP_ER_RENAME, errno); + remove(temp); + free(temp); + if (reopen_on_error) { + /* ignore errors, since we're already in an error case */ + za->zp = fopen(za->zn, "rb"); + } + return -1; } - return -1; - } mask = umask(0); umask(mask); chmod(za->zn, 0666&~mask); _zip_free(za); - free(temp); + free(temp); return 0; } diff --git a/ext/zip/lib/zip_fclose.c b/ext/zip/lib/zip_fclose.c index 6bf697301..8f062d9d0 100644 --- a/ext/zip/lib/zip_fclose.c +++ b/ext/zip/lib/zip_fclose.c @@ -49,13 +49,13 @@ zip_fclose(struct zip_file *zf) free(zf->buffer); free(zf->zstr); if (zf->za) { - for (i=0; iza->nfile; i++) { - if (zf->za->file[i] == zf) { - zf->za->file[i] = zf->za->file[zf->za->nfile-1]; - zf->za->nfile--; - break; - } - } + for (i=0; iza->nfile; i++) { + if (zf->za->file[i] == zf) { + zf->za->file[i] = zf->za->file[zf->za->nfile-1]; + zf->za->nfile--; + break; + } + } } ret = 0; diff --git a/ext/zip/lib/zip_fread.c b/ext/zip/lib/zip_fread.c index 1c0c8ac63..c0b71b861 100644 --- a/ext/zip/lib/zip_fread.c +++ b/ext/zip/lib/zip_fread.c @@ -41,7 +41,7 @@ ZIP_EXTERN(ssize_t) zip_fread(struct zip_file *zf, void *outbuf, size_t toread) { int ret; - size_t out_before, len; + size_t out_before, len; int i; if (!zf) @@ -63,7 +63,7 @@ zip_fread(struct zip_file *zf, void *outbuf, size_t toread) } return 0; } - + if ((zf->flags & ZIP_ZF_DECOMP) == 0) { ret = _zip_file_fillbuf(outbuf, toread, zf); if (ret > 0) { @@ -83,15 +83,26 @@ zip_fread(struct zip_file *zf, void *outbuf, size_t toread) ret = inflate(zf->zstr, Z_SYNC_FLUSH); switch (ret) { - case Z_OK: case Z_STREAM_END: + zf->flags |= ZIP_ZF_EOF; + + case Z_OK: + /* all ok */ /* Z_STREAM_END probably won't happen, since we didn't have a header */ len = zf->zstr->total_out - out_before; if (len >= zf->bytes_left || len >= toread) { - if (zf->flags & ZIP_ZF_CRC) - zf->crc = crc32(zf->crc, (Bytef *)outbuf, len); + if (zf->flags & ZIP_ZF_CRC) { + zf->crc = crc32(zf->crc, (Bytef *)outbuf, len); + if (zf->flags & ZIP_ZF_EOF == 1) { + if (zf->crc != zf->crc_orig) { + _zip_error_set(&zf->error, ZIP_ER_CRC, 0); + return -1; + } + + } + } zf->bytes_left -= len; return len; } diff --git a/ext/zip/lib/zip_get_archive_comment.c b/ext/zip/lib/zip_get_archive_comment.c index fe97e6e8c..ed1324fd5 100644 --- a/ext/zip/lib/zip_get_archive_comment.c +++ b/ext/zip/lib/zip_get_archive_comment.c @@ -42,11 +42,11 @@ zip_get_archive_comment(struct zip *za, int *lenp, int flags) { if ((flags & ZIP_FL_UNCHANGED) || (za->ch_comment_len == -1)) { - if (za->cdir) { - if (lenp != NULL) - *lenp = za->cdir->comment_len; - return za->cdir->comment; - } + if (za->cdir) { + if (lenp != NULL) + *lenp = za->cdir->comment_len; + return za->cdir->comment; + } else { if (lenp != NULL) *lenp = -1; diff --git a/ext/zip/lib/zip_open.c b/ext/zip/lib/zip_open.c index dbab6ec4a..e3840197d 100644 --- a/ext/zip/lib/zip_open.c +++ b/ext/zip/lib/zip_open.c @@ -75,9 +75,10 @@ zip_open(const char *fn, int flags, int *zep) if (!(flags & ZIP_OVERWRITE)) { return NULL; } - + case 0: return _zip_allocate_new(fn, zep); + default: break; } diff --git a/ext/zip/php_zip.c b/ext/zip/php_zip.c index 983aa5949..ab2c4e7a7 100644 --- a/ext/zip/php_zip.c +++ b/ext/zip/php_zip.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_zip.c,v 1.1.2.38.2.29 2009/02/24 23:55:14 iliaa Exp $ */ +/* $Id: php_zip.c 276389 2009-02-24 23:55:14Z iliaa $ */ #ifdef HAVE_CONFIG_H #include "config.h" @@ -2674,7 +2674,7 @@ static PHP_MINFO_FUNCTION(zip) php_info_print_table_start(); php_info_print_table_row(2, "Zip", "enabled"); - php_info_print_table_row(2, "Extension Version","$Id: php_zip.c,v 1.1.2.38.2.29 2009/02/24 23:55:14 iliaa Exp $"); + php_info_print_table_row(2, "Extension Version","$Id: php_zip.c 276389 2009-02-24 23:55:14Z iliaa $"); php_info_print_table_row(2, "Zip version", PHP_ZIP_VERSION_STRING); php_info_print_table_row(2, "Libzip version", "0.9.0"); diff --git a/ext/zip/php_zip.h b/ext/zip/php_zip.h index 7a2774db0..e75c11814 100644 --- a/ext/zip/php_zip.h +++ b/ext/zip/php_zip.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_zip.h,v 1.10.2.3.2.10 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_zip.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_ZIP_H #define PHP_ZIP_H diff --git a/ext/zip/tests/bug11216.phpt b/ext/zip/tests/bug11216.phpt index 4c6efa6cc..576e321b1 100644 --- a/ext/zip/tests/bug11216.phpt +++ b/ext/zip/tests/bug11216.phpt @@ -2,7 +2,7 @@ Bug #11216 (::addEmptyDir() crashes when the directory already exists) --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/bug14962.phpt b/ext/zip/tests/bug14962.phpt index 5cecbae30..5193c0469 100644 --- a/ext/zip/tests/bug14962.phpt +++ b/ext/zip/tests/bug14962.phpt @@ -2,7 +2,7 @@ Bug #14962 (::extractTo second argument is not really optional) --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/bug38943.phpt b/ext/zip/tests/bug38943.phpt index 1fbfdaa67..856818275 100644 --- a/ext/zip/tests/bug38943.phpt +++ b/ext/zip/tests/bug38943.phpt @@ -2,7 +2,7 @@ #38943, properties in extended class cannot be set (< 5.3) --SKIPIF-- diff --git a/ext/zip/tests/bug38943_2.phpt b/ext/zip/tests/bug38943_2.phpt index b1a48f81a..0045f0d1c 100644 --- a/ext/zip/tests/bug38943_2.phpt +++ b/ext/zip/tests/bug38943_2.phpt @@ -2,7 +2,7 @@ #38943, properties in extended class cannot be set (5.3) --SKIPIF-- diff --git a/ext/zip/tests/bug47667.phpt b/ext/zip/tests/bug47667.phpt index 3b985a3cf..d0a4566f2 100644 --- a/ext/zip/tests/bug47667.phpt +++ b/ext/zip/tests/bug47667.phpt @@ -2,7 +2,7 @@ Bug #47667 (ZipArchive::OVERWRITE seems to have no effect) --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/bug49072.phpt b/ext/zip/tests/bug49072.phpt new file mode 100644 index 000000000..04bd06e4a --- /dev/null +++ b/ext/zip/tests/bug49072.phpt @@ -0,0 +1,24 @@ +--TEST-- +Bug #49072 (feof never returns true for damaged file in zip) +--SKIPIF-- + +--FILE-- +open($f, ZipArchive::CHECKCONS)) { + exit ('error can\'t open'); +} +$r = $o->getStream('file1'); // this file has a wrong crc +if (!$r)die('failed to open a stream for file1'); +$s = ''; +while (! feof($r)) { + $s .= fread($r,1024); +} +?> +--EXPECTF-- + +Warning: fread(): Zip stream error: CRC error in %s on line %d diff --git a/ext/zip/tests/bug49072.zip b/ext/zip/tests/bug49072.zip new file mode 100644 index 000000000..16bbcd011 Binary files /dev/null and b/ext/zip/tests/bug49072.zip differ diff --git a/ext/zip/tests/bug7214.phpt b/ext/zip/tests/bug7214.phpt index bcf04deed..061e7e4cd 100644 --- a/ext/zip/tests/bug7214.phpt +++ b/ext/zip/tests/bug7214.phpt @@ -2,7 +2,7 @@ Bug #7214 (zip_entry_read() binary safe) --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/bug7658.phpt b/ext/zip/tests/bug7658.phpt index 3746862ef..267d8ff62 100644 --- a/ext/zip/tests/bug7658.phpt +++ b/ext/zip/tests/bug7658.phpt @@ -2,7 +2,7 @@ Bug #7658 (modify archive with general bit flag 3 set) --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/bug8009.phpt b/ext/zip/tests/bug8009.phpt index 9168d7369..8fcfbd9d3 100644 --- a/ext/zip/tests/bug8009.phpt +++ b/ext/zip/tests/bug8009.phpt @@ -2,7 +2,7 @@ Bug #8009 (cannot add again same entry to an archive) --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/bug8700.phpt b/ext/zip/tests/bug8700.phpt index e36519ee4..c00e76355 100644 --- a/ext/zip/tests/bug8700.phpt +++ b/ext/zip/tests/bug8700.phpt @@ -2,7 +2,7 @@ Bug #8700 (getFromIndex(0) fails) --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_addemptydir.phpt b/ext/zip/tests/oo_addemptydir.phpt index e2d2373c3..0a051894b 100644 --- a/ext/zip/tests/oo_addemptydir.phpt +++ b/ext/zip/tests/oo_addemptydir.phpt @@ -2,7 +2,7 @@ ziparchive::addEmptyDir --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_addfile.phpt b/ext/zip/tests/oo_addfile.phpt index 17b2fb466..83bfda5ab 100644 --- a/ext/zip/tests/oo_addfile.phpt +++ b/ext/zip/tests/oo_addfile.phpt @@ -2,7 +2,7 @@ ziparchive::addFile() function --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_close.phpt b/ext/zip/tests/oo_close.phpt index b5a4dacd0..4301447a7 100644 --- a/ext/zip/tests/oo_close.phpt +++ b/ext/zip/tests/oo_close.phpt @@ -2,7 +2,7 @@ zip::close() function --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_delete.phpt b/ext/zip/tests/oo_delete.phpt index 8b608927b..68085054a 100644 --- a/ext/zip/tests/oo_delete.phpt +++ b/ext/zip/tests/oo_delete.phpt @@ -2,7 +2,7 @@ Delete entries --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_ext_zip.phpt b/ext/zip/tests/oo_ext_zip.phpt index 93fb3cce9..c76e96f43 100644 --- a/ext/zip/tests/oo_ext_zip.phpt +++ b/ext/zip/tests/oo_ext_zip.phpt @@ -2,7 +2,7 @@ Extending Zip class and array property --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_extract.phpt b/ext/zip/tests/oo_extract.phpt index a83d26fe9..05d932420 100644 --- a/ext/zip/tests/oo_extract.phpt +++ b/ext/zip/tests/oo_extract.phpt @@ -2,7 +2,7 @@ extractTo --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_getcomment.phpt b/ext/zip/tests/oo_getcomment.phpt index 5a71e7556..7044be160 100644 --- a/ext/zip/tests/oo_getcomment.phpt +++ b/ext/zip/tests/oo_getcomment.phpt @@ -2,7 +2,7 @@ getComment --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_getnameindex.phpt b/ext/zip/tests/oo_getnameindex.phpt index e012c20dd..7b70f38c6 100644 --- a/ext/zip/tests/oo_getnameindex.phpt +++ b/ext/zip/tests/oo_getnameindex.phpt @@ -2,7 +2,7 @@ getNameIndex --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_getstatusstring.phpt b/ext/zip/tests/oo_getstatusstring.phpt new file mode 100644 index 000000000..efd19e318 --- /dev/null +++ b/ext/zip/tests/oo_getstatusstring.phpt @@ -0,0 +1,28 @@ +--TEST-- +This test will test getStatusString method in ZipArchive +--CREDITS-- +Ole-Petter Wikene +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- +open($dirname.'foo.zip',ZIPARCHIVE::CREATE); +var_dump($arch->getStatusString()); +//delete an index that does not exist - trigger error +$arch->deleteIndex(2); +var_dump($arch->getStatusString()); +$arch->close(); + +?> +--CLEAN-- + +--EXPECT-- +string(8) "No error" +string(16) "Invalid argument" + diff --git a/ext/zip/tests/oo_namelocate.phpt b/ext/zip/tests/oo_namelocate.phpt index a4ff384ee..579a00952 100644 --- a/ext/zip/tests/oo_namelocate.phpt +++ b/ext/zip/tests/oo_namelocate.phpt @@ -2,7 +2,7 @@ Locate entries by name --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_open.phpt b/ext/zip/tests/oo_open.phpt index 6a04351c8..e8acad0a0 100644 --- a/ext/zip/tests/oo_open.phpt +++ b/ext/zip/tests/oo_open.phpt @@ -2,7 +2,7 @@ zip::open() function --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_properties.phpt b/ext/zip/tests/oo_properties.phpt index c07fd0012..b47154c2d 100644 --- a/ext/zip/tests/oo_properties.phpt +++ b/ext/zip/tests/oo_properties.phpt @@ -2,7 +2,7 @@ ziparchive::properties isset()/empty() checks --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_rename.phpt b/ext/zip/tests/oo_rename.phpt index 5c619aa82..aa0a88658 100644 --- a/ext/zip/tests/oo_rename.phpt +++ b/ext/zip/tests/oo_rename.phpt @@ -2,7 +2,7 @@ Rename entries --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_setcomment.phpt b/ext/zip/tests/oo_setcomment.phpt index 872f6e6ff..9fb742d9a 100644 --- a/ext/zip/tests/oo_setcomment.phpt +++ b/ext/zip/tests/oo_setcomment.phpt @@ -2,7 +2,7 @@ setComment --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/oo_stream.phpt b/ext/zip/tests/oo_stream.phpt index 3d952b805..cddd5e8e7 100644 --- a/ext/zip/tests/oo_stream.phpt +++ b/ext/zip/tests/oo_stream.phpt @@ -2,7 +2,7 @@ getStream --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/utils.inc b/ext/zip/tests/utils.inc index c9ab36976..3b4cb6b9c 100644 --- a/ext/zip/tests/utils.inc +++ b/ext/zip/tests/utils.inc @@ -1,5 +1,5 @@ numFiles; $i++) { $sb = $z->statIndex($i); diff --git a/ext/zip/tests/zip_close.phpt b/ext/zip/tests/zip_close.phpt index 93753e4fe..e59bf3ed7 100644 --- a/ext/zip/tests/zip_close.phpt +++ b/ext/zip/tests/zip_close.phpt @@ -2,7 +2,7 @@ zip_close() function --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/zip_entry_compressedsize.phpt b/ext/zip/tests/zip_entry_compressedsize.phpt index ced546db4..29f305cc6 100644 --- a/ext/zip/tests/zip_entry_compressedsize.phpt +++ b/ext/zip/tests/zip_entry_compressedsize.phpt @@ -2,7 +2,7 @@ zip_entry_compressedsize() function --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/zip_entry_compressionmethod.phpt b/ext/zip/tests/zip_entry_compressionmethod.phpt index c52a3e7fe..1705d32c0 100644 --- a/ext/zip/tests/zip_entry_compressionmethod.phpt +++ b/ext/zip/tests/zip_entry_compressionmethod.phpt @@ -2,7 +2,7 @@ zip_entry_compressionmethod() function --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/zip_entry_filesize.phpt b/ext/zip/tests/zip_entry_filesize.phpt index 0d71f5f70..a10a0b22c 100644 --- a/ext/zip/tests/zip_entry_filesize.phpt +++ b/ext/zip/tests/zip_entry_filesize.phpt @@ -2,7 +2,7 @@ zip_entry_filesize() function --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/zip_entry_name.phpt b/ext/zip/tests/zip_entry_name.phpt index 178c4fb60..42bb07cf6 100644 --- a/ext/zip/tests/zip_entry_name.phpt +++ b/ext/zip/tests/zip_entry_name.phpt @@ -2,7 +2,7 @@ zip_entry_name() function --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/zip_entry_open.phpt b/ext/zip/tests/zip_entry_open.phpt index 1933025f4..c3dabe858 100644 --- a/ext/zip/tests/zip_entry_open.phpt +++ b/ext/zip/tests/zip_entry_open.phpt @@ -2,7 +2,7 @@ zip_entry_open() function --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/zip_entry_read.phpt b/ext/zip/tests/zip_entry_read.phpt index ba020e316..f2b502297 100644 --- a/ext/zip/tests/zip_entry_read.phpt +++ b/ext/zip/tests/zip_entry_read.phpt @@ -2,7 +2,7 @@ zip_entry_read() function --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/zip_open.phpt b/ext/zip/tests/zip_open.phpt index 4e038745b..e63c40e30 100644 --- a/ext/zip/tests/zip_open.phpt +++ b/ext/zip/tests/zip_open.phpt @@ -2,7 +2,7 @@ zip_open() function --SKIPIF-- --FILE-- diff --git a/ext/zip/tests/zip_open_error.phpt b/ext/zip/tests/zip_open_error.phpt new file mode 100644 index 000000000..eaa1d9731 --- /dev/null +++ b/ext/zip/tests/zip_open_error.phpt @@ -0,0 +1,28 @@ +--TEST-- +zip_open() error conditions +--CREDITS-- +Birgitte Kvarme +#PHPTestFest2009 Norway 2009-06-09 \o/ +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +Test case 1: +Warning: zip_open(): Empty string as source in %s on line %d +Test case 2: +Warning: zip_open() expects exactly 1 parameter, 2 given in %s on line %d +Test case 3: +Failure diff --git a/ext/zip/tests/zip_read.phpt b/ext/zip/tests/zip_read.phpt index f9b722654..654e22fa4 100644 --- a/ext/zip/tests/zip_read.phpt +++ b/ext/zip/tests/zip_read.phpt @@ -2,7 +2,7 @@ zip_read() function --SKIPIF-- --FILE-- diff --git a/ext/zip/zip_stream.c b/ext/zip/zip_stream.c index 5acf4d57c..a3c37ffd0 100644 --- a/ext/zip/zip_stream.c +++ b/ext/zip/zip_stream.c @@ -1,4 +1,4 @@ -/* $Id: zip_stream.c,v 1.1.2.5.2.2 2008/07/23 11:25:14 tony2001 Exp $ */ +/* $Id: zip_stream.c 287101 2009-08-11 17:08:23Z pajoye $ */ #ifdef HAVE_CONFIG_H # include "config.h" #endif @@ -35,14 +35,20 @@ static size_t php_zip_ops_read(php_stream *stream, char *buf, size_t count TSRML if (self->za && self->zf) { n = (size_t)zip_fread(self->zf, buf, (int)count); - - if (n == 0) { + if (n < 0) { + int ze, se; + zip_file_error_get(self->zf, &ze, &se); + stream->eof = 1; + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Zip stream error: %s", zip_file_strerror(self->zf)); + return 0; + } + if (n == 0 || n < count) { stream->eof = 1; } else { self->cursor += n; } } - return n<1 ? 0 : n; + return (n < 1 ? 0 : n); } /* }}} */ @@ -62,14 +68,15 @@ static int php_zip_ops_close(php_stream *stream, int close_handle TSRMLS_DC) { STREAM_DATA_FROM_STREAM(); if (close_handle) { - if (self->za) { - zip_close(self->za); - self->za = NULL; - } if (self->zf) { zip_fclose(self->zf); self->zf = NULL; } + + if (self->za) { + zip_close(self->za); + self->za = NULL; + } } efree(self); stream->abstract = NULL; diff --git a/ext/zlib/config.w32 b/ext/zlib/config.w32 index 54ee96b02..5e51cfed9 100644 --- a/ext/zlib/config.w32 +++ b/ext/zlib/config.w32 @@ -1,4 +1,4 @@ -// $Id: config.w32,v 1.8.6.2 2008/06/22 21:55:59 pajoye Exp $ +// $Id: config.w32 261512 2008-06-22 21:55:59Z pajoye $ // vim:ft=javascript ARG_ENABLE("zlib", "ZLIB support", "yes"); diff --git a/ext/zlib/config0.m4 b/ext/zlib/config0.m4 index 0e9f4cd80..e8f57d830 100644 --- a/ext/zlib/config0.m4 +++ b/ext/zlib/config0.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config0.m4,v 1.17.2.1 2005/11/29 18:35:26 tony2001 Exp $ +dnl $Id: config0.m4 201617 2005-11-29 18:35:26Z tony2001 $ dnl PHP_ARG_WITH(zlib,for ZLIB support, diff --git a/ext/zlib/php_zlib.h b/ext/zlib/php_zlib.h index 7470f1a14..a4271324d 100644 --- a/ext/zlib/php_zlib.h +++ b/ext/zlib/php_zlib.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_zlib.h,v 1.42.2.1.2.2.2.2 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_zlib.h 286751 2009-08-03 18:15:30Z jani $ */ #ifndef PHP_ZLIB_H #define PHP_ZLIB_H @@ -35,6 +35,8 @@ ZEND_BEGIN_MODULE_GLOBALS(zlib) char *output_handler; ZEND_END_MODULE_GLOBALS(zlib) +PHPAPI ZEND_EXTERN_MODULE_GLOBALS(zlib) + extern php_stream_filter_factory php_zlib_filter_factory; extern zend_module_entry php_zlib_module_entry; #define zlib_module_ptr &php_zlib_module_entry diff --git a/ext/zlib/tests/001.phpt b/ext/zlib/tests/001.phpt index c1e679f97..f789c2737 100644 --- a/ext/zlib/tests/001.phpt +++ b/ext/zlib/tests/001.phpt @@ -3,7 +3,7 @@ gzdeflate()/gzinflate() --SKIPIF-- --FILE-- - --FILE-- - --FILE-- --FILE-- - +--FILE-- + 9)); +fwrite($fp, $text); +fclose($fp); + +?> +--EXPECT-- +A Dѫ΍1MBUv_(EL/aP=Pi ;6fCe4U9;w5 m / diff --git a/ext/zlib/tests/zlib_filter_inflate.phpt b/ext/zlib/tests/zlib_filter_inflate.phpt index 0220c85e5..0a5836e3c 100644 --- a/ext/zlib/tests/zlib_filter_inflate.phpt +++ b/ext/zlib/tests/zlib_filter_inflate.phpt @@ -3,7 +3,7 @@ zlib.inflate (with convert.base64-decode) --SKIPIF-- --FILE-- - --FILE-- - 9) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid compression level specified. (%ld)", Z_LVAL(tmp)); - } else { - level = Z_LVAL(tmp); - } + zval_copy_ctor(&tmp); + convert_to_long(&tmp); + + /* Set compression level within reason (-1 == default, 0 == none, 1-9 == least to most compression */ + if (Z_LVAL(tmp) < -1 || Z_LVAL(tmp) > 9) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid compression level specified. (%ld)", Z_LVAL(tmp)); + } else { + level = Z_LVAL(tmp); } break; default: diff --git a/ext/zlib/zlib_fopen_wrapper.c b/ext/zlib/zlib_fopen_wrapper.c index e4aa217bd..465637941 100644 --- a/ext/zlib/zlib_fopen_wrapper.c +++ b/ext/zlib/zlib_fopen_wrapper.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: zlib_fopen_wrapper.c,v 1.46.2.1.2.4.2.3 2009/01/20 15:41:23 felipe Exp $ */ +/* $Id: zlib_fopen_wrapper.c 274034 2009-01-20 15:41:23Z felipe $ */ #define _GNU_SOURCE diff --git a/header b/header index 762442294..c7c2e6339 100644 --- a/header +++ b/header @@ -16,4 +16,4 @@ +----------------------------------------------------------------------+ */ -/* $Id: header,v 1.16.2.1.2.1.2.1 2008/02/07 19:39:50 iliaa Exp $ */ +/* $Id: header 252479 2008-02-07 19:39:50Z iliaa $ */ diff --git a/main/SAPI.c b/main/SAPI.c index f13bab533..a4a8ed787 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: SAPI.c,v 1.202.2.7.2.15.2.7 2009/04/28 21:30:23 stas Exp $ */ +/* $Id: SAPI.c 287423 2009-08-17 17:30:32Z jani $ */ #include #include @@ -32,9 +32,6 @@ #if (HAVE_PCRE || HAVE_BUNDLED_PCRE) && !defined(COMPILE_DL_PCRE) #include "ext/pcre/php_pcre.h" #endif -#if HAVE_ZLIB -#include "ext/zlib/php_zlib.h" -#endif #ifdef ZTS #include "TSRM.h" #endif @@ -637,11 +634,12 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) ptr++; len--; } -#if HAVE_ZLIB - if(!strncmp(ptr, "image/", sizeof("image/")-1)) { + + /* Disable possible output compression for images */ + if (!strncmp(ptr, "image/", sizeof("image/")-1)) { zend_alter_ini_entry("zlib.output_compression", sizeof("zlib.output_compression"), "0", sizeof("0") - 1, PHP_INI_USER, PHP_INI_STAGE_RUNTIME); } -#endif + mimetype = estrdup(ptr); newlen = sapi_apply_default_charset(&mimetype, len TSRMLS_CC); if (!SG(sapi_headers).mimetype){ @@ -789,36 +787,6 @@ SAPI_API int sapi_send_headers(TSRMLS_D) return SUCCESS; } -#if HAVE_ZLIB - /* Add output compression headers at this late stage in order to make - it possible to switch it off inside the script. */ - - if (zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0)) { - zval nm_zlib_get_coding_type; - zval *uf_result = NULL; - - ZVAL_STRINGL(&nm_zlib_get_coding_type, "zlib_get_coding_type", sizeof("zlib_get_coding_type") - 1, 0); - - if (call_user_function_ex(CG(function_table), NULL, &nm_zlib_get_coding_type, &uf_result, 0, NULL, 1, NULL TSRMLS_CC) != FAILURE && uf_result != NULL && Z_TYPE_P(uf_result) == IS_STRING) { - char buf[128]; - int len; - - assert(Z_STRVAL_P(uf_result) != NULL); - - len = slprintf(buf, sizeof(buf), "Content-Encoding: %s", Z_STRVAL_P(uf_result)); - if (len <= 0 || sapi_add_header(buf, len, 1) == FAILURE) { - return FAILURE; - } - if (sapi_add_header_ex("Vary: Accept-Encoding", sizeof("Vary: Accept-Encoding") - 1, 1, 0 TSRMLS_CC) == FAILURE) { - return FAILURE; - } - } - if (uf_result != NULL) { - zval_ptr_dtor(&uf_result); - } - } -#endif - /* Success-oriented. We set headers_sent to 1 here to avoid an infinite loop * in case of an error situation. */ diff --git a/main/SAPI.h b/main/SAPI.h index 3b96d70ab..b978bc438 100644 --- a/main/SAPI.h +++ b/main/SAPI.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: SAPI.h,v 1.114.2.1.2.3.2.8 2009/04/28 21:30:23 stas Exp $ */ +/* $Id: SAPI.h 279522 2009-04-28 21:30:23Z stas $ */ #ifndef SAPI_H #define SAPI_H diff --git a/main/alloca.c b/main/alloca.c index ea7885621..2fb937021 100644 --- a/main/alloca.c +++ b/main/alloca.c @@ -21,7 +21,7 @@ allocating any. It is a good idea to use alloca(0) in your main control loop, etc. to force garbage collection. */ -/* $Id: alloca.c,v 1.8 2005/01/09 21:05:06 sniper Exp $ */ +/* $Id: alloca.c 242949 2007-09-26 15:44:16Z cvs2svn $ */ #include diff --git a/main/build-defs.h.in b/main/build-defs.h.in index 2f280e52f..5be687988 100644 --- a/main/build-defs.h.in +++ b/main/build-defs.h.in @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: build-defs.h.in,v 1.15.2.2.2.2.2.1 2008/03/25 02:00:26 sixd Exp $ */ +/* $Id: build-defs.h.in 256027 2008-03-25 02:00:32Z sixd $ */ #define CONFIGURE_COMMAND "@CONFIGURE_COMMAND@" #define PHP_ADA_INCLUDE "" diff --git a/main/fopen_wrappers.c b/main/fopen_wrappers.c index 91a1685cf..3d65c85d7 100644 --- a/main/fopen_wrappers.c +++ b/main/fopen_wrappers.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: fopen_wrappers.c,v 1.175.2.3.2.13.2.19 2009/06/18 06:38:30 rasmus Exp $ */ +/* $Id: fopen_wrappers.c 289428 2009-10-09 17:03:56Z pajoye $ */ /* {{{ includes */ @@ -93,7 +93,7 @@ PHPAPI ZEND_INI_MH(OnUpdateBaseDir) p = (char **) (base + (size_t) mh_arg1); - if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN) { + if (stage == PHP_INI_STAGE_STARTUP || stage == PHP_INI_STAGE_SHUTDOWN || stage == PHP_INI_STAGE_ACTIVATE || stage == PHP_INI_STAGE_DEACTIVATE) { /* We're in a PHP_INI_SYSTEM context, no restrictions */ *p = new_value; return SUCCESS; @@ -382,9 +382,12 @@ static FILE *php_fopen_and_set_opened_path(const char *path, const char *mode, c */ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC) { + FILE *fp; +#ifndef PHP_WIN32 + struct stat st; +#endif char *path_info, *filename; int length; - zend_bool orig_display_errors; filename = SG(request_info).path_translated; path_info = SG(request_info).request_uri; @@ -451,7 +454,7 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC) } } /* if doc_root && path_info */ - if(filename) { + if (filename) { filename = zend_resolve_path(filename, strlen(filename) TSRMLS_CC); } @@ -463,20 +466,32 @@ PHPAPI int php_fopen_primary_script(zend_file_handle *file_handle TSRMLS_DC) STR_FREE(SG(request_info).path_translated); SG(request_info).path_translated = NULL; return FAILURE; - } else { - STR_FREE(SG(request_info).path_translated); - SG(request_info).path_translated = filename; } + fp = VCWD_FOPEN(filename, "rb"); + +#ifndef PHP_WIN32 + /* refuse to open anything that is not a regular file */ + if (fp && (0 > fstat(fileno(fp), &st) || !S_ISREG(st.st_mode))) { + fclose(fp); + fp = NULL; + } +#endif - orig_display_errors = PG(display_errors); - PG(display_errors) = 0; - if (zend_stream_open(filename, file_handle TSRMLS_CC) == FAILURE) { - PG(display_errors) = orig_display_errors; + if (!fp) { STR_FREE(SG(request_info).path_translated); /* for same reason as above */ SG(request_info).path_translated = NULL; return FAILURE; } - PG(display_errors) = orig_display_errors; + + file_handle->opened_path = expand_filepath(filename, NULL TSRMLS_CC); + + STR_FREE(SG(request_info).path_translated); /* for same reason as above */ + SG(request_info).path_translated = filename; + + file_handle->filename = SG(request_info).path_translated; + file_handle->free_filename = 0; + file_handle->handle.fp = fp; + file_handle->type = ZEND_HANDLE_FP; return SUCCESS; } diff --git a/main/fopen_wrappers.h b/main/fopen_wrappers.h index e62440496..36db81594 100644 --- a/main/fopen_wrappers.h +++ b/main/fopen_wrappers.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: fopen_wrappers.h,v 1.44.2.1.2.2.2.7 2009/01/16 10:06:10 pajoye Exp $ */ +/* $Id: fopen_wrappers.h 273621 2009-01-16 10:06:10Z pajoye $ */ #ifndef FOPEN_WRAPPERS_H #define FOPEN_WRAPPERS_H diff --git a/main/getopt.c b/main/getopt.c index 2c5350c10..3eb9ecfb8 100644 --- a/main/getopt.c +++ b/main/getopt.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: getopt.c,v 1.1.2.5 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: getopt.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include #include diff --git a/main/internal_functions.c.in b/main/internal_functions.c.in index 2a3914d4d..b0f9ef6b8 100644 --- a/main/internal_functions.c.in +++ b/main/internal_functions.c.in @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: internal_functions.c.in,v 1.30.2.1.2.2.2.1 2008/08/22 12:59:46 helly Exp $ */ +/* $Id: internal_functions.c.in 265279 2008-08-22 12:59:46Z helly $ */ #include "php.h" #include "php_main.h" diff --git a/main/internal_functions_nw.c b/main/internal_functions_nw.c index f20f134ac..da63dd4ae 100644 --- a/main/internal_functions_nw.c +++ b/main/internal_functions_nw.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: internal_functions_nw.c,v 1.9.2.1.2.2.2.3 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: internal_functions_nw.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* {{{ includes */ diff --git a/main/internal_functions_win32.c b/main/internal_functions_win32.c index a1732aa45..f99c16f8e 100644 --- a/main/internal_functions_win32.c +++ b/main/internal_functions_win32.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: internal_functions_win32.c,v 1.87.2.1.2.3.2.3 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: internal_functions_win32.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* {{{ includes */ diff --git a/main/logos.h b/main/logos.h index 645ef84dd..3c1d55bfc 100644 --- a/main/logos.h +++ b/main/logos.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: logos.h,v 1.14.2.3.2.2.2.3 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: logos.h 272370 2008-12-31 11:15:49Z sebastian $ */ #define CONTEXT_TYPE_IMAGE_GIF "Content-Type: image/gif" diff --git a/main/main.c b/main/main.c index 33d174e21..acd0f4c52 100644 --- a/main/main.c +++ b/main/main.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: main.c,v 1.640.2.23.2.57.2.55 2009/06/04 07:41:01 pajoye Exp $ */ +/* $Id: main.c 290034 2009-10-28 15:19:32Z pajoye $ */ /* {{{ includes */ @@ -349,8 +349,27 @@ static PHP_INI_DISP(display_errors_mode) static PHP_INI_MH(OnUpdateErrorLog) { /* Only do the safemode/open_basedir check at runtime */ - if ((stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) && - strcmp(new_value, "syslog")) { + if ((stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) && new_value && strcmp(new_value, "syslog")) { + if (PG(safe_mode) && (!php_checkuid(new_value, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { + return FAILURE; + } + + if (PG(open_basedir) && php_check_open_basedir(new_value TSRMLS_CC)) { + return FAILURE; + } + + } + OnUpdateString(entry, new_value, new_value_length, mh_arg1, mh_arg2, mh_arg3, stage TSRMLS_CC); + return SUCCESS; +} +/* }}} */ + +/* {{{ PHP_INI_MH + */ +static PHP_INI_MH(OnUpdateMailLog) +{ + /* Only do the safemode/open_basedir check at runtime */ + if ((stage == PHP_INI_STAGE_RUNTIME || stage == PHP_INI_STAGE_HTACCESS) && new_value) { if (PG(safe_mode) && (!php_checkuid(new_value, NULL, CHECKUID_CHECK_FILE_AND_DIR))) { return FAILURE; } @@ -487,7 +506,7 @@ PHP_INI_BEGIN() PHP_INI_ENTRY("SMTP", "localhost",PHP_INI_ALL, NULL) PHP_INI_ENTRY("smtp_port", "25", PHP_INI_ALL, NULL) STD_PHP_INI_BOOLEAN("mail.add_x_header", "0", PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateBool, mail_x_header, php_core_globals, core_globals) - STD_PHP_INI_ENTRY("mail.log", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateString, mail_log, php_core_globals, core_globals) + STD_PHP_INI_ENTRY("mail.log", NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnUpdateMailLog, mail_log, php_core_globals, core_globals) PHP_INI_ENTRY("browscap", NULL, PHP_INI_SYSTEM, NULL) PHP_INI_ENTRY("memory_limit", "128M", PHP_INI_ALL, OnChangeMemoryLimit) PHP_INI_ENTRY("precision", "14", PHP_INI_ALL, OnSetPrecision) @@ -496,6 +515,7 @@ PHP_INI_BEGIN() PHP_INI_ENTRY("mail.force_extra_parameters",NULL, PHP_INI_SYSTEM|PHP_INI_PERDIR, OnChangeMailForceExtra) PHP_INI_ENTRY("disable_functions", "", PHP_INI_SYSTEM, NULL) PHP_INI_ENTRY("disable_classes", "", PHP_INI_SYSTEM, NULL) + PHP_INI_ENTRY("max_file_uploads", "20", PHP_INI_SYSTEM, NULL) STD_PHP_INI_BOOLEAN("allow_url_fopen", "1", PHP_INI_SYSTEM, OnUpdateBool, allow_url_fopen, php_core_globals, core_globals) STD_PHP_INI_BOOLEAN("allow_url_include", "0", PHP_INI_SYSTEM, OnUpdateBool, allow_url_include, php_core_globals, core_globals) @@ -516,6 +536,20 @@ static int module_initialized = 0; static int module_startup = 1; static int module_shutdown = 0; +/* {{{ php_during_module_startup */ +static int php_during_module_startup(void) +{ + return module_startup; +} +/* }}} */ + +/* {{{ php_during_module_shutdown */ +static int php_during_module_shutdown(void) +{ + return module_shutdown; +} +/* }}} */ + /* {{{ php_log_err */ PHPAPI void php_log_err(char *log_message TSRMLS_DC) @@ -523,11 +557,18 @@ PHPAPI void php_log_err(char *log_message TSRMLS_DC) int fd = -1; time_t error_time; + if (PG(in_error_log)) { + /* prevent recursive invocation */ + return; + } + PG(in_error_log) = 1; + /* Try to use the specified logging location. */ if (PG(error_log) != NULL) { #ifdef HAVE_SYSLOG_H if (!strcmp(PG(error_log), "syslog")) { php_syslog(LOG_NOTICE, "%.500s", log_message); + PG(in_error_log) = 0; return; } #endif @@ -547,6 +588,7 @@ PHPAPI void php_log_err(char *log_message TSRMLS_DC) efree(tmp); efree(error_time_str); close(fd); + PG(in_error_log) = 0; return; } } @@ -556,6 +598,7 @@ PHPAPI void php_log_err(char *log_message TSRMLS_DC) if (sapi_module.log_message) { sapi_module.log_message(log_message); } + PG(in_error_log) = 0; } /* }}} */ @@ -587,24 +630,6 @@ PHPAPI int php_printf(const char *format, ...) } /* }}} */ -/* {{{ php_verror helpers */ - -/* {{{ php_during_module_startup */ -static int php_during_module_startup(void) -{ - return module_startup; -} -/* }}} */ - -/* {{{ php_during_module_shutdown */ -static int php_during_module_shutdown(void) -{ - return module_shutdown; -} -/* }}} */ - -/* }}} */ - /* {{{ php_verror */ /* php_verror is called from php_error_docref functions. * Its purpose is to unify error messages and automatically generate clickable @@ -1337,6 +1362,7 @@ int php_request_startup(TSRMLS_D) #endif zend_try { + PG(in_error_log) = 0; PG(during_request_startup) = 1; php_output_activate(TSRMLS_C); @@ -1991,10 +2017,6 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod php_ini_register_extensions(TSRMLS_C); zend_startup_modules(TSRMLS_C); - /* disable certain classes and functions as requested by php.ini */ - php_disable_functions(TSRMLS_C); - php_disable_classes(TSRMLS_C); - /* start Zend extensions */ zend_startup_extensions(); @@ -2007,12 +2029,17 @@ int php_module_startup(sapi_module_struct *sf, zend_module_entry *additional_mod } } + /* disable certain classes and functions as requested by php.ini */ + php_disable_functions(TSRMLS_C); + php_disable_classes(TSRMLS_C); + /* make core report what it should */ if (zend_hash_find(&module_registry, "core", sizeof("core"), (void**)&module)==SUCCESS) { module->version = PHP_VERSION; module->info_func = PHP_MINFO(php_core); } + #ifdef PHP_WIN32 /* Disable incompatible functions for the running platform */ if (php_win32_disable_functions() == FAILURE) { @@ -2136,7 +2163,9 @@ PHPAPI int php_execute_script(zend_file_handle *primary_file TSRMLS_DC) char realfile[MAXPATHLEN]; #ifdef PHP_WIN32 - UpdateIniFromRegistry(primary_file->filename TSRMLS_CC); + if(primary_file->filename) { + UpdateIniFromRegistry(primary_file->filename TSRMLS_CC); + } #endif PG(during_request_startup) = 0; @@ -2226,7 +2255,9 @@ PHPAPI int php_execute_simple_script(zend_file_handle *primary_file, zval **ret zend_try { #ifdef PHP_WIN32 - UpdateIniFromRegistry(primary_file->filename TSRMLS_CC); + if(primary_file->filename) { + UpdateIniFromRegistry(primary_file->filename TSRMLS_CC); + } #endif PG(during_request_startup) = 0; diff --git a/main/mergesort.c b/main/mergesort.c index 6c7e559d5..fb62625d6 100644 --- a/main/mergesort.c +++ b/main/mergesort.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. */ -/* $Id: mergesort.c,v 1.15.6.1 2008/08/22 12:59:46 helly Exp $ */ +/* $Id: mergesort.c 265279 2008-08-22 12:59:46Z helly $ */ #if defined(LIBC_SCCS) && !defined(lint) static char sccsid[] = "@(#)merge.c 8.2 (Berkeley) 2/14/94"; diff --git a/main/network.c b/main/network.c index 012493287..0d2f777cd 100644 --- a/main/network.c +++ b/main/network.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: network.c,v 1.118.2.2.2.6.2.17 2009/05/04 14:44:46 tony2001 Exp $ */ +/* $Id: network.c 289498 2009-10-10 12:21:08Z pajoye $ */ /*#define DEBUG_MAIN_NETWORK 1*/ @@ -314,7 +314,7 @@ PHPAPI int php_network_connect_socket(php_socket_t sockfd, SET_SOCKET_BLOCKING_MODE(sockfd, orig_flags); - if ((n = connect(sockfd, addr, addrlen)) < 0) { + if ((n = connect(sockfd, addr, addrlen)) != 0) { error = php_socket_errno(); if (error_code) { @@ -348,7 +348,7 @@ PHPAPI int php_network_connect_socket(php_socket_t sockfd, BSD-derived systems set errno correctly Solaris returns -1 from getsockopt in case of error */ - if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&error, &len) < 0) { + if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (char*)&error, &len) != 0) { ret = -1; } } else { @@ -375,7 +375,7 @@ ok: if (asynchronous) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "Asynchronous connect() not supported on this platform"); } - return connect(sockfd, addr, addrlen); + return (connect(sockfd, addr, addrlen) == 0) ? 0 : -1; #endif } /* }}} */ @@ -715,7 +715,7 @@ PHPAPI php_socket_t php_network_accept_incoming(php_socket_t srvsock, clisock = accept(srvsock, (struct sockaddr*)&sa, &sl); - if (clisock >= 0) { + if (clisock != SOCK_ERR) { php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl, textaddr, textaddrlen, addr, addrlen @@ -792,7 +792,7 @@ php_socket_t php_network_connect_socket_to_host(const char *host, unsigned short switch (sa->sa_family) { #if HAVE_GETADDRINFO && HAVE_IPV6 case AF_INET6: - if (bindto && strchr(bindto, ':')) { + if (!bindto || strchr(bindto, ':')) { ((struct sockaddr_in6 *)sa)->sin6_family = sa->sa_family; ((struct sockaddr_in6 *)sa)->sin6_port = htons(port); socklen = sizeof(struct sockaddr_in6); @@ -867,7 +867,7 @@ skip_bind: timeout ? &working_timeout : NULL, error_string, error_code); - if (n != SOCK_CONN_ERR) { + if (n != -1) { goto connected; } diff --git a/main/output.c b/main/output.c index 0c44cdf39..4c9c65438 100644 --- a/main/output.c +++ b/main/output.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: output.c,v 1.167.2.3.2.4.2.13 2009/03/25 23:59:45 cseiler Exp $ */ +/* $Id: output.c 289444 2009-10-09 19:13:33Z pajoye $ */ #include "php.h" #include "ext/standard/head.h" @@ -227,8 +227,6 @@ PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush TSRMLS ALLOC_INIT_ZVAL(orig_buffer); ZVAL_STRINGL(orig_buffer, OG(active_ob_buffer).buffer, OG(active_ob_buffer).text_length, 1); - Z_SET_REFCOUNT_P(orig_buffer, 2); /* don't let call_user_function() destroy our buffer */ - Z_SET_ISREF_P(orig_buffer); ALLOC_INIT_ZVAL(z_status); ZVAL_LONG(z_status, status); @@ -248,11 +246,7 @@ PHPAPI void php_end_ob_buffer(zend_bool send_buffer, zend_bool just_flush TSRMLS if (!just_flush) { zval_ptr_dtor(&OG(active_ob_buffer).output_handler); } - Z_SET_REFCOUNT_P(orig_buffer, Z_REFCOUNT_P(orig_buffer) - 2); - if (Z_REFCOUNT_P(orig_buffer) <= 0) { /* free the zval */ - zval_dtor(orig_buffer); - FREE_ZVAL(orig_buffer); - } + zval_ptr_dtor(&orig_buffer); zval_ptr_dtor(&z_status); } diff --git a/main/php.h b/main/php.h index 58f414240..6655f3cb3 100644 --- a/main/php.h +++ b/main/php.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php.h,v 1.221.2.4.2.8.2.13 2009/06/26 15:44:19 johannes Exp $ */ +/* $Id: php.h 282827 2009-06-26 15:44:19Z johannes $ */ #ifndef PHP_H #define PHP_H diff --git a/main/php3_compat.h b/main/php3_compat.h index 62549593b..8b994b9f9 100644 --- a/main/php3_compat.h +++ b/main/php3_compat.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php3_compat.h,v 1.20.2.1.2.1.2.2 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php3_compat.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP3_COMPAT_H #define PHP3_COMPAT_H diff --git a/main/php_compat.h b/main/php_compat.h index 5bd7eb5c4..3c6f5928b 100644 --- a/main/php_compat.h +++ b/main/php_compat.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_compat.h,v 1.25.2.3.2.4.2.4 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_compat.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_COMPAT_H #define PHP_COMPAT_H diff --git a/main/php_config.h.in b/main/php_config.h.in index 277ac23e0..e75aad767 100644 --- a/main/php_config.h.in +++ b/main/php_config.h.in @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: acconfig.h,v 1.40.2.1.2.1.2.3 2008/12/31 11:15:31 sebastian Exp $ */ +/* $Id: acconfig.h 272370 2008-12-31 11:15:49Z sebastian $ */ #if defined(__GNUC__) && __GNUC__ >= 4 # define ZEND_API __attribute__ ((visibility("default"))) @@ -434,9 +434,6 @@ /* Define if you have the realpath function. */ #undef HAVE_REALPATH -/* Define if you have the res_search function. */ -#undef HAVE_RES_SEARCH - /* Define if you have the rl_completion_matches function. */ #undef HAVE_RL_COMPLETION_MATCHES @@ -623,6 +620,9 @@ /* Define if you have the header file. */ #undef HAVE_ARPA_NAMESER_H +/* Define if you have the header file. */ +#undef HAVE_ARPA_NAMESER_COMPAT_H + /* Define if you have the header file. */ #undef HAVE_ASSERT_H @@ -638,6 +638,9 @@ /* Define if you have the header file. */ #undef HAVE_DLFCN_H +/* Define if you have the header file. */ +#undef HAVE_DNS_H + /* Define if you have the header file. */ #undef HAVE_ERRNO_H @@ -662,9 +665,6 @@ /* Define if you have the header file. */ #undef HAVE_LOCALE_H -/* Define if you have the header file. */ -#undef HAVE_MACH_O_DYLD_H - /* Define if you have the header file. */ #undef HAVE_MALLOC_H @@ -830,9 +830,6 @@ /* Define if you have the m library (-lm). */ #undef HAVE_LIBM -/* Enabling BIND8 compatibility for Panther */ -#undef BIND_8_COMPAT - /* Define if the target system has /dev/urandom device */ #undef HAVE_DEV_URANDOM @@ -1058,6 +1055,15 @@ /* */ #undef HAVE_LIBBIND +/* */ +#undef HAVE_NANOSLEEP + +/* */ +#undef HAVE_NANOSLEEP + +/* */ +#undef HAVE_LIBRT + /* */ #undef HAVE_FOPENCOOKIE @@ -1424,6 +1430,12 @@ /* */ #undef HAVE_ENCHANT +/* */ +#undef HAVE_ENCHANT_BROKER_SET_PARAM + +/* */ +#undef ENCHANT_VERSION_STRING + /* Whether you want EXIF (metadata from images) support */ #undef HAVE_EXIF @@ -2463,64 +2475,43 @@ #undef ENABLE_CHROOT_FUNC /* */ -#undef HAVE_RES_NMKQUERY - -/* */ -#undef HAVE_RES_NMKQUERY - -/* */ -#undef HAVE_LIBRESOLV - -/* */ -#undef HAVE_RES_NMKQUERY - -/* */ -#undef HAVE_LIBBIND - -/* */ -#undef HAVE_RES_NMKQUERY +#undef HAVE_RES_NSEARCH /* */ -#undef HAVE_LIBSOCKET - -/* */ -#undef HAVE_RES_NSEND - -/* */ -#undef HAVE_RES_NSEND +#undef HAVE_RES_NSEARCH /* */ #undef HAVE_LIBRESOLV /* */ -#undef HAVE_RES_NSEND +#undef HAVE_RES_NSEARCH /* */ #undef HAVE_LIBBIND /* */ -#undef HAVE_RES_NSEND +#undef HAVE_RES_NSEARCH /* */ #undef HAVE_LIBSOCKET /* */ -#undef HAVE_RES_SEARCH +#undef HAVE_DNS_SEARCH /* */ -#undef HAVE_RES_SEARCH +#undef HAVE_DNS_SEARCH /* */ #undef HAVE_LIBRESOLV /* */ -#undef HAVE_RES_SEARCH +#undef HAVE_DNS_SEARCH /* */ #undef HAVE_LIBBIND /* */ -#undef HAVE_RES_SEARCH +#undef HAVE_DNS_SEARCH /* */ #undef HAVE_LIBSOCKET @@ -2568,43 +2559,22 @@ #undef HAVE_LIBSOCKET /* */ -#undef HAVE_RES_MKQUERY - -/* */ -#undef HAVE_RES_MKQUERY - -/* */ -#undef HAVE_LIBRESOLV - -/* */ -#undef HAVE_RES_MKQUERY - -/* */ -#undef HAVE_LIBBIND - -/* */ -#undef HAVE_RES_MKQUERY - -/* */ -#undef HAVE_LIBSOCKET - -/* */ -#undef HAVE_RES_SEND +#undef HAVE_RES_SEARCH /* */ -#undef HAVE_RES_SEND +#undef HAVE_RES_SEARCH /* */ #undef HAVE_LIBRESOLV /* */ -#undef HAVE_RES_SEND +#undef HAVE_RES_SEARCH /* */ #undef HAVE_LIBBIND /* */ -#undef HAVE_RES_SEND +#undef HAVE_RES_SEARCH /* */ #undef HAVE_LIBSOCKET diff --git a/main/php_content_types.c b/main/php_content_types.c index 2a55f48f1..85bdd69fb 100644 --- a/main/php_content_types.c +++ b/main/php_content_types.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_content_types.c,v 1.32.2.1.2.4.2.3 2009/04/28 21:30:23 stas Exp $ */ +/* $Id: php_content_types.c 279522 2009-04-28 21:30:23Z stas $ */ #include "php.h" #include "SAPI.h" diff --git a/main/php_content_types.h b/main/php_content_types.h index 63a641c72..9d1c91065 100644 --- a/main/php_content_types.h +++ b/main/php_content_types.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_content_types.h,v 1.12.2.1.2.1.2.2 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_content_types.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_CONTENT_TYPES_H #define PHP_CONTENT_TYPES_H diff --git a/main/php_getopt.h b/main/php_getopt.h index 024ea5c05..e21d11815 100644 --- a/main/php_getopt.h +++ b/main/php_getopt.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_getopt.h,v 1.1.2.4 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_getopt.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_GETOPT_H #define PHP_GETOPT_H diff --git a/main/php_globals.h b/main/php_globals.h index 4af4b3ab0..5a8942bce 100644 --- a/main/php_globals.h +++ b/main/php_globals.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_globals.h,v 1.98.2.1.2.7.2.7 2009/01/09 14:59:30 iliaa Exp $ */ +/* $Id: php_globals.h 289442 2009-10-09 19:06:10Z pajoye $ */ #ifndef PHP_GLOBALS_H #define PHP_GLOBALS_H @@ -168,6 +168,8 @@ struct _php_core_globals { zend_bool mail_x_header; char *mail_log; + + zend_bool in_error_log; }; diff --git a/main/php_ini.c b/main/php_ini.c index c021d6575..f1918f4a0 100644 --- a/main/php_ini.c +++ b/main/php_ini.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ini.c,v 1.136.2.4.2.15.2.14 2009/05/18 21:33:38 derick Exp $ */ +/* $Id: php_ini.c 289668 2009-10-15 13:28:55Z pajoye $ */ #include "php.h" #include "ext/standard/info.h" @@ -41,6 +41,21 @@ #define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) #endif +#ifdef PHP_WIN32 +#define TRANSLATE_SLASHES_LOWER(path) \ + { \ + char *tmp = path; \ + while (*tmp) { \ + if (*tmp == '\\') *tmp = '/'; \ + else *tmp = tolower(*tmp); \ + tmp++; \ + } \ + } +#else +#define TRANSLATE_SLASHES_LOWER(path) +#endif + + typedef struct _php_extension_lists { zend_llist engine; zend_llist functions; @@ -274,6 +289,9 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t is_special_section = 1; has_per_dir_config = 1; + /* make the path lowercase on Windows, for case insensitivty. Does nothign for other platforms */ + TRANSLATE_SLASHES_LOWER(key); + /* HOST sections */ } else if (!strncasecmp(Z_STRVAL_P(arg1), "HOST", sizeof("HOST") - 1)) { key = Z_STRVAL_P(arg1); @@ -281,6 +299,7 @@ static void php_ini_parser_cb(zval *arg1, zval *arg2, zval *arg3, int callback_t key_len = Z_STRLEN_P(arg1) - sizeof("HOST") + 1; is_special_section = 1; has_per_host_config = 1; + zend_str_tolower(key, key_len); /* host names are case-insensitive. */ } else { is_special_section = 0; @@ -488,33 +507,18 @@ int php_init_config(TSRMLS_D) } strlcat(php_ini_search_path, default_location, search_path_size); } - efree(default_location); - { - /* For people running under terminal services, GetWindowsDirectory will - * return their personal Windows directory, so lets add the system - * windows directory too */ - typedef UINT (WINAPI *get_system_windows_directory_func)(char *buffer, UINT size); - static get_system_windows_directory_func get_system_windows_directory = NULL; - HMODULE kern; - - if (get_system_windows_directory == NULL) { - kern = LoadLibrary("kernel32.dll"); - if (kern) { - get_system_windows_directory = (get_system_windows_directory_func)GetProcAddress(kern, "GetSystemWindowsDirectoryA"); - } - } - if (get_system_windows_directory != NULL) { - default_location = (char *) emalloc(MAXPATHLEN + 1); - if (0 < get_system_windows_directory(default_location, MAXPATHLEN)) { - if (*php_ini_search_path) { - strlcat(php_ini_search_path, paths_separator, search_path_size); - } - strlcat(php_ini_search_path, default_location, search_path_size); - } - efree(default_location); + /* For people running under terminal services, GetWindowsDirectory will + * return their personal Windows directory, so lets add the system + * windows directory too */ + if (0 < GetSystemWindowsDirectory(default_location, MAXPATHLEN)) { + if (*php_ini_search_path) { + strlcat(php_ini_search_path, paths_separator, search_path_size); } + strlcat(php_ini_search_path, default_location, search_path_size); } + efree(default_location); + #else default_location = PHP_CONFIG_FILE_PATH; if (*php_ini_search_path) { @@ -789,10 +793,18 @@ PHPAPI void php_ini_activate_per_dir_config(char *path, uint path_len TSRMLS_DC) zval *tmp; char *ptr; +#if PHP_WIN32 + char path_bak[MAXPATHLEN]; + memcpy(path_bak, path, path_len); + path_bak[path_len] = 0; + TRANSLATE_SLASHES_LOWER(path_bak); + path = path_bak; +#endif + /* Walk through each directory in path and apply any found per-dir-system-configuration from configuration_hash */ if (has_per_dir_config && path && path_len) { ptr = path + 1; - while ((ptr = strchr(ptr, DEFAULT_SLASH)) != NULL) { + while ((ptr = strchr(ptr, '/')) != NULL) { *ptr = 0; /* Search for source array matching the path from configuration_hash */ if (zend_hash_find(&configuration_hash, path, path_len, (void **) &tmp) == SUCCESS) { diff --git a/main/php_ini.h b/main/php_ini.h index a05247160..3d6cb5d1e 100644 --- a/main/php_ini.h +++ b/main/php_ini.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ini.h,v 1.45.2.3.2.3.2.9 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_ini.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_INI_H #define PHP_INI_H diff --git a/main/php_logos.c b/main/php_logos.c index 5cfa9c3f2..ae6d69b45 100644 --- a/main/php_logos.c +++ b/main/php_logos.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_logos.c,v 1.19.2.1.2.5.2.2 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_logos.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "logos.h" diff --git a/main/php_logos.h b/main/php_logos.h index 8bf484c6c..644ee1614 100644 --- a/main/php_logos.h +++ b/main/php_logos.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_logos.h,v 1.9.2.1.2.3.2.2 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_logos.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef _PHP_LOGOS_H diff --git a/main/php_main.h b/main/php_main.h index 618edabb2..2d27f920b 100644 --- a/main/php_main.h +++ b/main/php_main.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_main.h,v 1.34.2.1.2.2.2.2 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_main.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_MAIN_H #define PHP_MAIN_H diff --git a/main/php_memory_streams.h b/main/php_memory_streams.h index 8f212e9fd..6b17dcaf8 100644 --- a/main/php_memory_streams.h +++ b/main/php_memory_streams.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_memory_streams.h,v 1.13.2.1.2.3.2.2 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_memory_streams.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_MEMORY_STREAM_H #define PHP_MEMORY_STREAM_H diff --git a/main/php_network.h b/main/php_network.h index 322a58e7e..51a2071ae 100644 --- a/main/php_network.h +++ b/main/php_network.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_network.h,v 1.56.2.1.2.1.2.5 2009/01/07 20:21:46 felipe Exp $ */ +/* $Id: php_network.h 273010 2009-01-07 20:21:46Z felipe $ */ #ifndef _PHP_NETWORK_H #define _PHP_NETWORK_H diff --git a/main/php_open_temporary_file.c b/main/php_open_temporary_file.c index 5834549b1..28623381e 100644 --- a/main/php_open_temporary_file.c +++ b/main/php_open_temporary_file.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_open_temporary_file.c,v 1.34.2.1.2.10.2.4 2009/06/24 20:08:54 iliaa Exp $ */ +/* $Id: php_open_temporary_file.c 283130 2009-06-30 12:20:35Z iliaa $ */ #include "php.h" @@ -199,8 +199,15 @@ PHPAPI const char* php_get_temporary_directory(void) /* On Unix use the (usual) TMPDIR environment variable. */ { char* s = getenv("TMPDIR"); - if (s) { - temporary_directory = strdup(s); + if (s && *s) { + int len = strlen(s); + + if (s[len - 1] == DEFAULT_SLASH) { + temporary_directory = zend_strndup(s, len - 1); + } else { + temporary_directory = zend_strndup(s, len); + } + return temporary_directory; } } diff --git a/main/php_open_temporary_file.h b/main/php_open_temporary_file.h index 0ae00c59f..094ebd26b 100644 --- a/main/php_open_temporary_file.h +++ b/main/php_open_temporary_file.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_open_temporary_file.h,v 1.13.2.1.2.4.2.2 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_open_temporary_file.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_OPEN_TEMPORARY_FILE_H #define PHP_OPEN_TEMPORARY_FILE_H diff --git a/main/php_output.h b/main/php_output.h index a1fefe765..8ad9cf593 100644 --- a/main/php_output.h +++ b/main/php_output.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_output.h,v 1.53.2.1.2.1.2.2 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_output.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_OUTPUT_H #define PHP_OUTPUT_H diff --git a/main/php_reentrancy.h b/main/php_reentrancy.h index 6ed1adf63..d076a4e40 100644 --- a/main/php_reentrancy.h +++ b/main/php_reentrancy.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_reentrancy.h,v 1.23.2.1.2.1.2.2 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_reentrancy.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_REENTRANCY_H #define PHP_REENTRANCY_H diff --git a/main/php_scandir.c b/main/php_scandir.c index 6e02b2b69..d142731fc 100644 --- a/main/php_scandir.c +++ b/main/php_scandir.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_scandir.c,v 1.12.2.1.2.5.2.3 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_scandir.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "php_scandir.h" diff --git a/main/php_scandir.h b/main/php_scandir.h index 9e900abb1..cf74ddfee 100644 --- a/main/php_scandir.h +++ b/main/php_scandir.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_scandir.h,v 1.12.2.1.2.1.2.3 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_scandir.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SCANDIR_H #define PHP_SCANDIR_H diff --git a/main/php_sprintf.c b/main/php_sprintf.c index 04f2b556c..d6890b673 100644 --- a/main/php_sprintf.c +++ b/main/php_sprintf.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_sprintf.c,v 1.23.2.1.2.1.2.3 2009/05/14 08:21:54 dmitry Exp $ */ +/* $Id: php_sprintf.c 280501 2009-05-14 08:21:54Z dmitry $ */ #include #include diff --git a/main/php_streams.h b/main/php_streams.h index 1ec46decc..28b9c19b8 100755 --- a/main/php_streams.h +++ b/main/php_streams.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_streams.h,v 1.103.2.1.2.4.2.10 2009/04/19 17:10:34 lbarnaud Exp $ */ +/* $Id: php_streams.h 279002 2009-04-19 17:10:35Z lbarnaud $ */ #ifndef PHP_STREAMS_H #define PHP_STREAMS_H diff --git a/main/php_syslog.h b/main/php_syslog.h index bbf1e053b..71c65cacc 100644 --- a/main/php_syslog.h +++ b/main/php_syslog.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_syslog.h,v 1.12.2.1.2.1.2.2 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_syslog.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_SYSLOG_H #define PHP_SYSLOG_H diff --git a/main/php_ticks.c b/main/php_ticks.c index 63b887110..1d544e43b 100644 --- a/main/php_ticks.c +++ b/main/php_ticks.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ticks.c,v 1.20.2.1.2.1.2.3 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_ticks.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "php_ticks.h" diff --git a/main/php_ticks.h b/main/php_ticks.h index af7062c83..dc7ae672b 100644 --- a/main/php_ticks.h +++ b/main/php_ticks.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_ticks.h,v 1.14.2.1.2.1.2.3 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_ticks.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_TICKS_H #define PHP_TICKS_H diff --git a/main/php_variables.c b/main/php_variables.c index b331354d1..83b6a94dd 100644 --- a/main/php_variables.c +++ b/main/php_variables.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_variables.c,v 1.104.2.10.2.11.2.9 2008/12/31 11:15:47 sebastian Exp $ */ +/* $Id: php_variables.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include #include "php.h" diff --git a/main/php_variables.h b/main/php_variables.h index e1421eea6..0237a2e5e 100644 --- a/main/php_variables.h +++ b/main/php_variables.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_variables.h,v 1.22.2.3.2.2.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: php_variables.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_VARIABLES_H #define PHP_VARIABLES_H diff --git a/main/php_version.h b/main/php_version.h index b73190a26..7adb32efd 100644 --- a/main/php_version.h +++ b/main/php_version.h @@ -2,7 +2,7 @@ /* edit configure.in to change version number */ #define PHP_MAJOR_VERSION 5 #define PHP_MINOR_VERSION 3 -#define PHP_RELEASE_VERSION 0 +#define PHP_RELEASE_VERSION 1 #define PHP_EXTRA_VERSION "" -#define PHP_VERSION "5.3.0" -#define PHP_VERSION_ID 50300 +#define PHP_VERSION "5.3.1" +#define PHP_VERSION_ID 50301 diff --git a/main/reentrancy.c b/main/reentrancy.c index 13e4f93ed..7d2410aa2 100644 --- a/main/reentrancy.c +++ b/main/reentrancy.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: reentrancy.c,v 1.43.2.1.2.2.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: reentrancy.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include #include diff --git a/main/rfc1867.c b/main/rfc1867.c index ca76a7f30..31b74c164 100644 --- a/main/rfc1867.c +++ b/main/rfc1867.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: rfc1867.c,v 1.173.2.1.2.9.2.9 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: rfc1867.c 290025 2009-10-28 11:03:36Z pajoye $ */ /* * This product includes software developed by the Apache Group @@ -795,6 +795,12 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) zend_llist header; void *event_extra_data = NULL; int llen = 0; + char *max_uploads = INI_STR("max_file_uploads"); + int upload_cnt = 0; + + if (max_uploads && *max_uploads) { + upload_cnt = atoi(max_uploads); + } if (SG(request_info).content_length > SG(post_max_size)) { sapi_module.sapi_error(E_WARNING, "POST Content-Length of %ld bytes exceeds the limit of %ld bytes", SG(request_info).content_length, SG(post_max_size)); @@ -973,6 +979,9 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) /* If file_uploads=off, skip the file part */ if (!PG(file_uploads)) { skip_upload = 1; + } else if (upload_cnt <= 0) { + skip_upload = 1; + sapi_module.sapi_error(E_WARNING, "Maximum number of allowable file uploads has been exceeded"); } /* Return with an error if the posted data is garbled */ @@ -1017,6 +1026,7 @@ SAPI_API SAPI_POST_HANDLER_FUNC(rfc1867_post_handler) if (!skip_upload) { /* Handle file */ fd = php_open_temporary_fd_ex(PG(upload_tmp_dir), "php", &temp_filename, 1 TSRMLS_CC); + upload_cnt--; if (fd==-1) { sapi_module.sapi_error(E_WARNING, "File upload error - unable to create a temporary file"); cancel_upload = UPLOAD_ERROR_E; diff --git a/main/rfc1867.h b/main/rfc1867.h index 8a68526c2..7038fadc7 100644 --- a/main/rfc1867.h +++ b/main/rfc1867.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: rfc1867.h,v 1.13.2.1.2.3.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: rfc1867.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef RFC1867_H #define RFC1867_H diff --git a/main/safe_mode.c b/main/safe_mode.c index b0903609e..f57626fdc 100644 --- a/main/safe_mode.c +++ b/main/safe_mode.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: safe_mode.c,v 1.62.2.1.2.10.2.8 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: safe_mode.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" diff --git a/main/safe_mode.h b/main/safe_mode.h index 0eac08265..cd52b11e5 100644 --- a/main/safe_mode.h +++ b/main/safe_mode.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: safe_mode.h,v 1.13.2.1.2.2.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: safe_mode.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SAFE_MODE_H #define SAFE_MODE_H diff --git a/main/snprintf.c b/main/snprintf.c index 1f2396b1d..0a3f5a46b 100644 --- a/main/snprintf.c +++ b/main/snprintf.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: snprintf.c,v 1.37.2.4.2.14.2.8 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: snprintf.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" diff --git a/main/snprintf.h b/main/snprintf.h index 970a1e7f5..8b21c8a3e 100644 --- a/main/snprintf.h +++ b/main/snprintf.h @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: snprintf.h,v 1.32.2.3.2.5.2.5 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: snprintf.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* diff --git a/main/spprintf.c b/main/spprintf.c index ddc023705..eb9e46915 100644 --- a/main/spprintf.c +++ b/main/spprintf.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spprintf.c,v 1.25.2.2.2.10.2.6 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: spprintf.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* This is the spprintf implementation. * It has emerged from apache snprintf. See original header: diff --git a/main/spprintf.h b/main/spprintf.h index 7c566bfab..7e5661480 100644 --- a/main/spprintf.h +++ b/main/spprintf.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: spprintf.h,v 1.11.2.1.2.1.2.3 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: spprintf.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* diff --git a/main/streams/cast.c b/main/streams/cast.c index ae5cb2988..f42494601 100644 --- a/main/streams/cast.c +++ b/main/streams/cast.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: cast.c,v 1.12.2.1.2.1.2.6 2009/04/20 08:28:44 pajoye Exp $ */ +/* $Id: cast.c 279036 2009-04-20 08:28:44Z pajoye $ */ #define _GNU_SOURCE #include "php.h" diff --git a/main/streams/filter.c b/main/streams/filter.c index 00f79b311..e08efe643 100644 --- a/main/streams/filter.c +++ b/main/streams/filter.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: filter.c,v 1.17.2.3.2.10.2.4 2009/01/08 17:01:58 lbarnaud Exp $ */ +/* $Id: filter.c 273087 2009-01-08 17:01:58Z lbarnaud $ */ #include "php.h" #include "php_globals.h" diff --git a/main/streams/glob_wrapper.c b/main/streams/glob_wrapper.c index 55a8f3816..955aa806f 100755 --- a/main/streams/glob_wrapper.c +++ b/main/streams/glob_wrapper.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: glob_wrapper.c,v 1.6.2.6 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: glob_wrapper.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "php_streams_int.h" diff --git a/main/streams/memory.c b/main/streams/memory.c index 11cd2fee8..062524649 100644 --- a/main/streams/memory.c +++ b/main/streams/memory.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: memory.c,v 1.8.2.6.2.17.2.4 2009/05/16 20:27:36 lbarnaud Exp $ */ +/* $Id: memory.c 289437 2009-10-09 17:45:03Z pajoye $ */ #define _GNU_SOURCE #include "php.h" @@ -563,7 +563,7 @@ PHPAPI php_stream *_php_stream_temp_create(int mode, size_t max_memory_usage STR stream = php_stream_alloc_rel(&php_stream_temp_ops, self, 0, mode & TEMP_STREAM_READONLY ? "rb" : "w+b"); stream->flags |= PHP_STREAM_FLAG_NO_BUFFER; self->innerstream = php_stream_memory_create_rel(mode); - php_stream_auto_cleanup(self->innerstream); // do not warn if innerstream is GC'ed before stream + php_stream_auto_cleanup(self->innerstream); /* do not warn if innerstream is GC'ed before stream */ ((php_stream_memory_data*)self->innerstream->abstract)->owner_ptr = &self->innerstream; return stream; diff --git a/main/streams/mmap.c b/main/streams/mmap.c index 409962632..78d8a66ea 100644 --- a/main/streams/mmap.c +++ b/main/streams/mmap.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mmap.c,v 1.8.2.1.2.1.2.6 2009/05/17 14:58:10 lbarnaud Exp $ */ +/* $Id: mmap.c 280678 2009-05-17 14:58:10Z lbarnaud $ */ /* Memory Mapping interface for streams */ #include "php.h" diff --git a/main/streams/php_stream_context.h b/main/streams/php_stream_context.h index 8326d2116..a45808b25 100644 --- a/main/streams/php_stream_context.h +++ b/main/streams/php_stream_context.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_stream_context.h,v 1.11.2.1.2.1.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: php_stream_context.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* Stream context and status notification related definitions */ diff --git a/main/streams/php_stream_filter_api.h b/main/streams/php_stream_filter_api.h index e6342ad1b..4f1477008 100644 --- a/main/streams/php_stream_filter_api.h +++ b/main/streams/php_stream_filter_api.h @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_stream_filter_api.h,v 1.13.2.1.2.1.2.4 2009/01/08 17:01:58 lbarnaud Exp $ */ +/* $Id: php_stream_filter_api.h 273087 2009-01-08 17:01:58Z lbarnaud $ */ /* The filter API works on the principle of "Bucket-Brigades". This is * partially inspired by the Apache 2 method of doing things, although diff --git a/main/streams/php_stream_glob_wrapper.h b/main/streams/php_stream_glob_wrapper.h index 819c8de9c..63b4cf076 100755 --- a/main/streams/php_stream_glob_wrapper.h +++ b/main/streams/php_stream_glob_wrapper.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_stream_glob_wrapper.h,v 1.5.2.4 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: php_stream_glob_wrapper.h 272370 2008-12-31 11:15:49Z sebastian $ */ PHPAPI extern php_stream_wrapper php_glob_stream_wrapper; PHPAPI extern php_stream_ops php_glob_stream_ops; diff --git a/main/streams/php_stream_mmap.h b/main/streams/php_stream_mmap.h index f383f4a27..a3a2dbf6c 100644 --- a/main/streams/php_stream_mmap.h +++ b/main/streams/php_stream_mmap.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_stream_mmap.h,v 1.5.2.1.2.1.2.3 2009/05/17 14:58:10 lbarnaud Exp $ */ +/* $Id: php_stream_mmap.h 280678 2009-05-17 14:58:10Z lbarnaud $ */ /* Memory Mapping interface for streams. * The intention is to provide a uniform interface over the most common diff --git a/main/streams/php_stream_plain_wrapper.h b/main/streams/php_stream_plain_wrapper.h index e5a221109..36031719b 100644 --- a/main/streams/php_stream_plain_wrapper.h +++ b/main/streams/php_stream_plain_wrapper.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_stream_plain_wrapper.h,v 1.7.2.2.2.1.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: php_stream_plain_wrapper.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* definitions for the plain files wrapper */ diff --git a/main/streams/php_stream_transport.h b/main/streams/php_stream_transport.h index 8f3c4d7e2..ec32b1eb6 100644 --- a/main/streams/php_stream_transport.h +++ b/main/streams/php_stream_transport.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_stream_transport.h,v 1.10.2.1.2.4.2.3 2009/02/02 09:41:46 pajoye Exp $ */ +/* $Id: php_stream_transport.h 275024 2009-02-02 09:41:46Z pajoye $ */ #ifdef PHP_WIN32 #include "config.w32.h" #include diff --git a/main/streams/php_stream_userspace.h b/main/streams/php_stream_userspace.h index b268b460a..625c22b21 100644 --- a/main/streams/php_stream_userspace.h +++ b/main/streams/php_stream_userspace.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_stream_userspace.h,v 1.5.2.1.2.1.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: php_stream_userspace.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* for user-space streams */ diff --git a/main/streams/php_streams_int.h b/main/streams/php_streams_int.h index 46792f489..b0a1f3327 100644 --- a/main/streams/php_streams_int.h +++ b/main/streams/php_streams_int.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_streams_int.h,v 1.7.2.2.2.2.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: php_streams_int.h 272370 2008-12-31 11:15:49Z sebastian $ */ #if ZEND_DEBUG diff --git a/main/streams/plain_wrapper.c b/main/streams/plain_wrapper.c index c7e46ff69..549d38292 100644 --- a/main/streams/plain_wrapper.c +++ b/main/streams/plain_wrapper.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: plain_wrapper.c,v 1.52.2.6.2.23.2.14 2009/04/11 11:44:15 mkoppanen Exp $ */ +/* $Id: plain_wrapper.c 290578 2009-11-12 15:05:03Z johannes $ */ #include "php.h" #include "php_globals.h" @@ -988,6 +988,10 @@ static php_stream *php_plain_files_stream_opener(php_stream_wrapper *wrapper, ch return NULL; } + if ((php_check_safe_mode_include_dir(path TSRMLS_CC)) == 0) { + return php_stream_fopen_rel(path, mode, opened_path, options); + } + if ((options & ENFORCE_SAFE_MODE) && PG(safe_mode) && (!php_checkuid(path, mode, CHECKUID_CHECK_MODE_PARAM))) return NULL; diff --git a/main/streams/streams.c b/main/streams/streams.c index d18974f02..c2b4e3f85 100755 --- a/main/streams/streams.c +++ b/main/streams/streams.c @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: streams.c,v 1.82.2.6.2.18.2.28 2009/05/17 14:58:10 lbarnaud Exp $ */ +/* $Id: streams.c 280678 2009-05-17 14:58:10Z lbarnaud $ */ #define _GNU_SOURCE #include "php.h" diff --git a/main/streams/transports.c b/main/streams/transports.c index dbe495d29..1ac6677d9 100644 --- a/main/streams/transports.c +++ b/main/streams/transports.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: transports.c,v 1.16.2.1.2.4.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: transports.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "php_streams_int.h" diff --git a/main/streams/userspace.c b/main/streams/userspace.c index 3117f3333..74e2f9173 100644 --- a/main/streams/userspace.c +++ b/main/streams/userspace.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: userspace.c,v 1.31.2.3.2.7.2.10 2009/05/08 11:35:12 bjori Exp $ */ +/* $Id: userspace.c 280151 2009-05-08 11:35:12Z bjori $ */ #include "php.h" #include "php_globals.h" diff --git a/main/streams/xp_socket.c b/main/streams/xp_socket.c index c83493ce6..214c0118b 100644 --- a/main/streams/xp_socket.c +++ b/main/streams/xp_socket.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: xp_socket.c,v 1.33.2.2.2.6.2.10 2009/02/09 02:55:45 iliaa Exp $ */ +/* $Id: xp_socket.c 289416 2009-10-09 14:20:17Z pajoye $ */ #include "php.h" #include "ext/standard/file.h" @@ -181,6 +181,10 @@ static int php_sockop_close(php_stream *stream, int close_handle TSRMLS_DC) if (close_handle) { +#ifdef PHP_WIN32 + if (sock->socket == -1) + sock->socket = SOCK_ERR; +#endif if (sock->socket != SOCK_ERR) { #ifdef PHP_WIN32 /* prevent more data from coming in */ @@ -226,10 +230,12 @@ static inline int sock_sendto(php_netstream_data_t *sock, char *buf, size_t bufl struct sockaddr *addr, socklen_t addrlen TSRMLS_DC) { + int ret; if (addr) { - return sendto(sock->socket, buf, buflen, flags, addr, addrlen); + ret = sendto(sock->socket, buf, buflen, flags, addr, addrlen); + return (ret == SOCK_CONN_ERR) ? -1 : ret; } - return send(sock->socket, buf, buflen, flags); + return ((ret = send(sock->socket, buf, buflen, flags)) == SOCK_CONN_ERR) ? -1 : ret; } static inline int sock_recvfrom(php_netstream_data_t *sock, char *buf, size_t buflen, int flags, @@ -244,10 +250,12 @@ static inline int sock_recvfrom(php_netstream_data_t *sock, char *buf, size_t bu if (want_addr) { ret = recvfrom(sock->socket, buf, buflen, flags, (struct sockaddr*)&sa, &sl); + ret = (ret == SOCK_CONN_ERR) ? -1 : ret; php_network_populate_name_from_sockaddr((struct sockaddr*)&sa, sl, textaddr, textaddrlen, addr, addrlen TSRMLS_CC); } else { ret = recv(sock->socket, buf, buflen, flags); + ret = (ret == SOCK_CONN_ERR) ? -1 : ret; } return ret; @@ -312,7 +320,7 @@ static int php_sockop_set_option(php_stream *stream, int option, int value, void switch (xparam->op) { case STREAM_XPORT_OP_LISTEN: - xparam->outputs.returncode = listen(sock->socket, 5); + xparam->outputs.returncode = (listen(sock->socket, 5) == 0) ? 0: -1; return PHP_STREAM_OPTION_RETURN_OK; case STREAM_XPORT_OP_GET_NAME: diff --git a/main/strlcat.c b/main/strlcat.c index 17bb241a8..fe4ca4207 100644 --- a/main/strlcat.c +++ b/main/strlcat.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: strlcat.c,v 1.13.2.1.2.1.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: strlcat.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" diff --git a/main/strlcpy.c b/main/strlcpy.c index 92760975b..d3b474667 100644 --- a/main/strlcpy.c +++ b/main/strlcpy.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: strlcpy.c,v 1.13.2.1.2.1.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: strlcpy.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" diff --git a/main/win32_internal_function_disabled.h b/main/win32_internal_function_disabled.h index e87090106..6681064bd 100644 --- a/main/win32_internal_function_disabled.h +++ b/main/win32_internal_function_disabled.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: win32_internal_function_disabled.h,v 1.1.2.2 2009/01/16 13:52:13 pajoye Exp $ */ +/* $Id: win32_internal_function_disabled.h 273638 2009-01-16 13:52:13Z pajoye $ */ /* 5 means the min version is 5 (XP/2000), 6 (2k8/vista), etc. */ diff --git a/main/win95nt.h b/main/win95nt.h index 61e34deb6..789294554 100644 --- a/main/win95nt.h +++ b/main/win95nt.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: win95nt.h,v 1.20.2.2.2.2.2.4 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: win95nt.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* Defines and types for Windows 95/NT */ #define HAVE_DECLARED_TIMEZONE diff --git a/makedist b/makedist index 3f67a498a..1df8eda77 100755 --- a/makedist +++ b/makedist @@ -1,30 +1,27 @@ #!/bin/sh # -# Distribution generator for CVS based packages. +# Distribution generator for SVN based packages. # To work, this script needs a consistent tagging of all releases. # Each release of a package should have a tag of the form # # _ # -# where is the package name and the CVS module +# where is the package name and the SVN module # and s the version number with underscores instead of dots. # -# For example: cvs tag php_5_0_1 +# For example: svn cp $PHPROOT/php/php-src/trunk $PHPROOT/php/php-src/tags/php_5_0_1 # # The distribution ends up in a .tar.gz file that contains the distribution # in a directory called -. The distribution contains all -# directories from the CVS module except the one called "nodist", but only +# directories from the SVN module except the one called "nodist", but only # the files INSTALL, README and config* are included. -# -# Since you can no longer set the CVS password via an env variable, you -# need to have previously done a cvs login for the server and user id -# this script uses so it will have an entry in your ~/.cvspasswd file. +# A .tar.bz2 file is also created. # # Usage: makedist # # Written by Stig Bakken 1997-05-28. # -# $Id: makedist,v 1.31.6.1 2006/05/12 14:54:10 iliaa Exp $ +# $Id: makedist 284087 2009-07-14 21:49:44Z gwynne $ # if test "$#" != "2"; then @@ -44,8 +41,8 @@ if test "${1}" = "1" -a "${2}" -lt "28"; then fi IFS="$old_IFS" -PHPROOT=:pserver:cvsread@cvs.php.net:/repository -PHPMOD=php-src +PHPROOT=http://svn.php.net/repository +PHPMOD=php/php-src LT_TARGETS='ltconfig ltmain.sh config.guess config.sub' if echo '\c' | grep -s c >/dev/null 2>&1 @@ -62,7 +59,7 @@ MY_OLDPWD=`pwd` # the destination .tar.gz file ARCHIVE=$MY_OLDPWD/$PKG-$VER.tar -# temporary directory used to check out files from CVS +# temporary directory used to check out files from SVN DIR=$PKG-$VER DIRPATH=$MY_OLDPWD/$DIR @@ -72,28 +69,28 @@ if test -d "$DIRPATH"; then exit 1 fi -# version part of the CVS release tag -CVSVER=`echo $VER | sed -e 's/[\.\-]/_/g'` +# version part of the SVN release tag +SVNVER=`echo $VER | sed -e 's/[\.\-]/_/g'` -# CVS release tag -if test "$VER" != "HEAD"; then - CVSTAG=${PKG}_$CVSVER +# SVN release tag +if test "$VER" != "HEAD" -a "$VER" != "trunk"; then + SVNTAG=tags/${PKG}_$SVNVER else - CVSTAG=HEAD + SVNTAG=trunk fi -if test ! -d $DIRPATH; then - mkdir -p $DIRPATH || exit 2 -fi +#if test ! -d $DIRPATH; then +# mkdir -p $DIRPATH || exit 2 +#fi # Export PHP -$ECHO_N "makedist: exporting tag '$CVSTAG' from '$PHPMOD'...$ECHO_C" -cvs -z 9 -d $PHPROOT export -d $DIR -r $CVSTAG $PHPMOD || exit 4 +$ECHO_N "makedist: exporting tag '$SVNTAG' from '$PHPMOD'...$ECHO_C" +svn export $PHPROOT/$PHPMOD/$SVNTAG $DIRPATH || exit 4 echo "" -# remove CVS stuff... +# remove SVN stuff... cd $DIR || exit 5 -find . \( \( -name CVS -type d \) -o -name .cvsignore \) -exec rm -rf {} \; +find . \( -name .svn -type d \) -exec rm -rf {} \; # The full ChangeLog is available separately from lxr.php.net rm -f ChangeLog* diff --git a/pear/Makefile.frag b/pear/Makefile.frag index e036dcbaa..1f6f70ec0 100644 --- a/pear/Makefile.frag +++ b/pear/Makefile.frag @@ -7,9 +7,11 @@ PEAR_INSTALL_FLAGS = -n -dshort_open_tag=0 -dsafe_mode=0 -dopen_basedir= -derror WGET = `which wget 2>/dev/null` FETCH = `which fetch 2>/dev/null` +PEAR_PREFIX = -dp a${program_prefix} +PEAR_SUFFIX = -ds a$(program_suffix) install-pear-installer: $(SAPI_CLI_PATH) - @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) $(builddir)/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)" + @$(top_builddir)/sapi/cli/php $(PEAR_INSTALL_FLAGS) pear/install-pear-nozlib.phar -d "$(peardir)" -b "$(bindir)" ${PEAR_PREFIX} ${PEAR_SUFFIX} install-pear: @echo "Installing PEAR environment: $(INSTALL_ROOT)$(peardir)/" diff --git a/pear/install-pear-nozlib.phar b/pear/install-pear-nozlib.phar index 81f77ebe9..33424482c 100644 --- a/pear/install-pear-nozlib.phar +++ b/pear/install-pear-nozlib.phar @@ -1234,27 +1234,54 @@ if (extension_loaded('phar')) {if (isset($_SERVER) && isset($_SERVER['REQUEST_UR require_once 'phar://install-pear-nozlib.phar/index.php'; -__HALT_COMPILER(); Einstall-pear-nozlib.pharArchive/Tar.php+IrdImArchive_Tar-1.3.3.tarv+Iv` mConsole/Getopt.php(+I(=mConsole_Getopt-1.2.3.tarF+IFYxm index.php$+I$$m OS/Guess.php)+I) ymPEAR-1.8.0.tar<+I<f;mPEAR.php+I$8MmPEAR/ChannelFile.php+I;]RmPEAR/ChannelFile/Parser.php>+I>r׷mPEAR/Command.php62+I62{~mPEAR/Command/Common.php +I mPEAR/Command/Install.php+I?RbmPEAR/Command/Install.xml~!+I~!W_EmPEAR/Common.php#i+I#if4mPEAR/Config.php +I P mPEAR/Dependency2.phpL+IL7+mPEAR/DependencyDB.php_+I_mPEAR/Downloader.php+IJ mPEAR/Downloader/Package.php++I+N"mPEAR/ErrorStack.php+Ib!mPEAR/Frontend.phpJ+IJ`mPEAR/Frontend/CLI.phpa+IamPEAR/Installer.php*+I*mPEAR/Installer/Role.php +I bCimPEAR/Installer/Role/Common.php+It]mPEAR/Installer/Role/Data.phpp+Ip[rmPEAR/Installer/Role/Data.xml+IfszmPEAR/Installer/Role/Doc.phpm+Im mPEAR/Installer/Role/Doc.xml+Ih&P*mPEAR/Installer/Role/Php.phpm+ImmPEAR/Installer/Role/Php.xml+IzqmPEAR/Installer/Role/Script.phpv+Iv |mPEAR/Installer/Role/Script.xml+I@vmPEAR/Installer/Role/Test.phpp+Ip}amPEAR/Installer/Role/Test.xml+IB] mPEAR/PackageFile.php@+I@ulAm!PEAR/PackageFile/Generator/v1.php+I7|m!PEAR/PackageFile/Generator/v2.php+IT)+lmPEAR/PackageFile/Parser/v1.php@+I@yU3mPEAR/PackageFile/Parser/v2.php +I ﴓmPEAR/PackageFile/v1.php+IpmPEAR/PackageFile/v2.php+Iݮm!PEAR/PackageFile/v2/Validator.php%P+I%PhsRmPEAR/Registry.phpc0+Ic0gxm PEAR/REST.php<+I< *mPEAR/REST/10.php +I %mPEAR/Start.php6+I6=mPEAR/Start/CLI.phpQ+IQw -mPEAR/Task/Common.php+I]7bmPEAR/Task/Postinstallscript.php8+I8Ym"PEAR/Task/Postinstallscript/rw.php+I$mPEAR/Task/Replace.php+I]>mPEAR/Task/Replace/rw.php+I}mPEAR/Task/Unixeol.php +I ymPEAR/Task/Unixeol/rw.php+ItmPEAR/Task/Windowseol.php +I u(mPEAR/Task/Windowseol/rw.php+IBXmPEAR/Validate.phpzV+IzV-mPEAR/Validator/PECL.php+IHmPEAR/XMLParser.php+IhemStructures/Graph.php+Ir *m,Structures/Graph/Manipulator/AcyclicTest.php+I1sm2Structures/Graph/Manipulator/TopologicalSorter.php+IEmStructures/Graph/Node.php*+I*TmStructures_Graph-1.0.2.tarX+IX'(m -System.phpLN+ILNOjm XML/Util.phpv+IvmXML_Util-1.2.1.tar+I7l\m | -// +----------------------------------------------------------------------+ -// -// $Id: Tar.php,v 1.24 2007/01/06 04:03:32 cellog Exp $ +__HALT_COMPILER(); Finstall-pear-nozlib.pharArchive/Tar.php 8£J wmArchive_Tar-1.3.3.tarv8£Jv` mConsole/Getopt.php_28£J_2 + * 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. + * * 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. + * + * 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 OWNER 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. + * + * + * @category File_Formats + * @package Archive_Tar + * @author Vincent Blavet + * @copyright 1997-2008 The Authors + * @license http://www.opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Tar.php 287963 2009-09-02 08:18:55Z mrook $ + * @link http://pear.php.net/package/Archive_Tar + */ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; @@ -1266,8 +1293,9 @@ define ('ARCHIVE_TAR_END_BLOCK', pack("a512", '')); * Creates a (compressed) Tar archive * * @author Vincent Blavet -* @version $Revision: 1.24 $ -* @package Archive +* @version $Revision: 287963 $ +* @license http://www.opensource.org/licenses/bsd-license.php New BSD License +* @package Archive_Tar */ class Archive_Tar extends PEAR { @@ -1356,7 +1384,7 @@ class Archive_Tar extends PEAR $this->_compress = true; $this->_compress_type = 'bz2'; } else { - die("Unsupported compression type '$p_compress'\n". + $this->_error("Unsupported compression type '$p_compress'\n". "Supported types are 'gz' and 'bz2'.\n"); return false; } @@ -1372,7 +1400,7 @@ class Archive_Tar extends PEAR PEAR::loadExtension($extname); } if (!extension_loaded($extname)) { - die("The extension '$extname' couldn't be found.\n". + $this->_error("The extension '$extname' couldn't be found.\n". "Please make sure your version of PHP was built ". "with '$extname' support.\n"); return false; @@ -1615,14 +1643,14 @@ class Archive_Tar extends PEAR function addString($p_filename, $p_string) { $v_result = true; - + if (!$this->_isArchive()) { if (!$this->_openWrite()) { return false; } $this->_close(); } - + if (!$this->_openAppend()) return false; @@ -1762,12 +1790,12 @@ class Archive_Tar extends PEAR function setAttribute() { $v_result = true; - + // ----- Get the number of variable list of arguments if (($v_size = func_num_args()) == 0) { return true; } - + // ----- Get the arguments $v_att_list = &func_get_args(); @@ -1827,7 +1855,7 @@ class Archive_Tar extends PEAR $p_filename = $this->_tarname; } clearstatcache(); - return @is_file($p_filename); + return @is_file($p_filename) && !@is_link($p_filename); } // }}} @@ -1837,7 +1865,7 @@ class Archive_Tar extends PEAR if ($this->_compress_type == 'gz') $this->_file = @gzopen($this->_tarname, "wb9"); else if ($this->_compress_type == 'bz2') - $this->_file = @bzopen($this->_tarname, "wb"); + $this->_file = @bzopen($this->_tarname, "w"); else if ($this->_compress_type == 'none') $this->_file = @fopen($this->_tarname, "wb"); else @@ -1890,7 +1918,7 @@ class Archive_Tar extends PEAR if ($this->_compress_type == 'gz') $this->_file = @gzopen($v_filename, "rb"); else if ($this->_compress_type == 'bz2') - $this->_file = @bzopen($v_filename, "rb"); + $this->_file = @bzopen($v_filename, "r"); else if ($this->_compress_type == 'none') $this->_file = @fopen($v_filename, "rb"); else @@ -1911,9 +1939,11 @@ class Archive_Tar extends PEAR { if ($this->_compress_type == 'gz') $this->_file = @gzopen($this->_tarname, "r+b"); - else if ($this->_compress_type == 'bz2') - $this->_file = @bzopen($this->_tarname, "r+b"); - else if ($this->_compress_type == 'none') + else if ($this->_compress_type == 'bz2') { + $this->_error('Unable to open bz2 in read/write mode \'' + .$this->_tarname.'\' (limitation of bz2 extension)'); + return false; + } else if ($this->_compress_type == 'none') $this->_file = @fopen($this->_tarname, "r+b"); else $this->_error('Unknown or missing compression type (' @@ -2104,7 +2134,7 @@ class Archive_Tar extends PEAR if (!$this->_addFile($v_filename, $v_header, $p_add_dir, $p_remove_dir)) return false; - if (@is_dir($v_filename)) { + if (@is_dir($v_filename) && !@is_link($v_filename)) { if (!($p_hdir = opendir($v_filename))) { $this->_warning("Directory '$v_filename' can not be read"); continue; @@ -2237,31 +2267,45 @@ class Archive_Tar extends PEAR return false; } - $v_info = stat($p_filename); - $v_uid = sprintf("%6s ", DecOct($v_info[4])); - $v_gid = sprintf("%6s ", DecOct($v_info[5])); - $v_perms = sprintf("%6s ", DecOct(fileperms($p_filename))); + $v_info = lstat($p_filename); + $v_uid = sprintf("%07s", DecOct($v_info[4])); + $v_gid = sprintf("%07s", DecOct($v_info[5])); + $v_perms = sprintf("%07s", DecOct($v_info['mode'] & 000777)); - $v_mtime = sprintf("%11s", DecOct(filemtime($p_filename))); + $v_mtime = sprintf("%011s", DecOct($v_info['mtime'])); + + $v_linkname = ''; - if (@is_dir($p_filename)) { + if (@is_link($p_filename)) { + $v_typeflag = '2'; + $v_linkname = readlink($p_filename); + $v_size = sprintf("%011s", DecOct(0)); + } elseif (@is_dir($p_filename)) { $v_typeflag = "5"; - $v_size = sprintf("%11s ", DecOct(0)); + $v_size = sprintf("%011s", DecOct(0)); } else { - $v_typeflag = ''; + $v_typeflag = '0'; clearstatcache(); - $v_size = sprintf("%11s ", DecOct(filesize($p_filename))); + $v_size = sprintf("%011s", DecOct($v_info['size'])); } - $v_linkname = ''; - - $v_magic = ''; - - $v_version = ''; + $v_magic = 'ustar '; - $v_uname = ''; - - $v_gname = ''; + $v_version = ' '; + + if (function_exists('posix_getpwuid')) + { + $userinfo = posix_getpwuid($v_info[4]); + $groupinfo = posix_getgrgid($v_info[5]); + + $v_uname = $userinfo['name']; + $v_gname = $groupinfo['name']; + } + else + { + $v_uname = ''; + $v_gname = ''; + } $v_devmajor = ''; @@ -2269,7 +2313,7 @@ class Archive_Tar extends PEAR $v_prefix = ''; - $v_binary_data_first = pack("a100a8a8a8a12A12", + $v_binary_data_first = pack("a100a8a8a8a12a12", $v_reduce_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime); $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", @@ -2293,7 +2337,7 @@ class Archive_Tar extends PEAR $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum - $v_checksum = sprintf("%6s ", DecOct($v_checksum)); + $v_checksum = sprintf("%06s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); @@ -2316,27 +2360,37 @@ class Archive_Tar extends PEAR } if ($p_type == "5") { - $v_size = sprintf("%11s ", DecOct(0)); + $v_size = sprintf("%011s", DecOct(0)); } else { - $v_size = sprintf("%11s ", DecOct($p_size)); + $v_size = sprintf("%011s", DecOct($p_size)); } - $v_uid = sprintf("%6s ", DecOct($p_uid)); - $v_gid = sprintf("%6s ", DecOct($p_gid)); - $v_perms = sprintf("%6s ", DecOct($p_perms)); + $v_uid = sprintf("%07s", DecOct($p_uid)); + $v_gid = sprintf("%07s", DecOct($p_gid)); + $v_perms = sprintf("%07s", DecOct($p_perms & 000777)); $v_mtime = sprintf("%11s", DecOct($p_mtime)); $v_linkname = ''; - $v_magic = ''; + $v_magic = 'ustar '; - $v_version = ''; - - $v_uname = ''; - - $v_gname = ''; + $v_version = ' '; + if (function_exists('posix_getpwuid')) + { + $userinfo = posix_getpwuid($p_uid); + $groupinfo = posix_getgrgid($p_gid); + + $v_uname = $userinfo['name']; + $v_gname = $groupinfo['name']; + } + else + { + $v_uname = ''; + $v_gname = ''; + } + $v_devmajor = ''; $v_devminor = ''; @@ -2367,7 +2421,7 @@ class Archive_Tar extends PEAR $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum - $v_checksum = sprintf("%6s ", DecOct($v_checksum)); + $v_checksum = sprintf("%06s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); @@ -2401,7 +2455,7 @@ class Archive_Tar extends PEAR $v_prefix = ''; - $v_binary_data_first = pack("a100a8a8a8a12A12", + $v_binary_data_first = pack("a100a8a8a8a12a12", '././@LongLink', 0, 0, 0, $v_size, 0); $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, @@ -2424,7 +2478,7 @@ class Archive_Tar extends PEAR $this->_writeBlock($v_binary_data_first, 148); // ----- Write the calculated checksum - $v_checksum = sprintf("%6s ", DecOct($v_checksum)); + $v_checksum = sprintf("%06s ", DecOct($v_checksum)); $v_binary_data = pack("a8", $v_checksum); $this->_writeBlock($v_binary_data, 8); @@ -2492,7 +2546,7 @@ class Archive_Tar extends PEAR } // ----- Extract the properties - $v_header['filename'] = trim($v_data['filename']); + $v_header['filename'] = $v_data['filename']; if ($this->_maliciousFilename($v_header['filename'])) { $this->_error('Malicious .tar detected, file "' . $v_header['filename'] . '" will not install in desired directory tree'); @@ -2552,7 +2606,7 @@ class Archive_Tar extends PEAR } if (($v_header['size'] % 512) != 0) { $v_content = $this->_readBlock(); - $v_filename .= $v_content; + $v_filename .= trim($v_content); } // ----- Read the next header @@ -2561,6 +2615,7 @@ class Archive_Tar extends PEAR if (!$this->_readHeader($v_binary_data, $v_header)) return false; + $v_filename = trim($v_filename); $v_header['filename'] = $v_filename; if ($this->_maliciousFilename($v_filename)) { $this->_error('Malicious .tar detected, file "' . $v_filename . @@ -2768,6 +2823,9 @@ class Archive_Tar extends PEAR } } } elseif ($v_header['typeflag'] == "2") { + if (@file_exists($v_header['filename'])) { + @unlink($v_header['filename']); + } if (!@symlink($v_header['link'], $v_header['filename'])) { $this->_error('Unable to extract symbolic link {' .$v_header['filename'].'}'); @@ -2849,7 +2907,7 @@ class Archive_Tar extends PEAR { if (filesize($this->_tarname) == 0) return $this->_openWrite(); - + if ($this->_compress) { $this->_close(); @@ -2863,8 +2921,8 @@ class Archive_Tar extends PEAR if ($this->_compress_type == 'gz') $v_temp_tar = @gzopen($this->_tarname.".tmp", "rb"); elseif ($this->_compress_type == 'bz2') - $v_temp_tar = @bzopen($this->_tarname.".tmp", "rb"); - + $v_temp_tar = @bzopen($this->_tarname.".tmp", "r"); + if ($v_temp_tar == 0) { $this->_error('Unable to open file \''.$this->_tarname .'.tmp\' in binary read mode'); @@ -2918,14 +2976,14 @@ class Archive_Tar extends PEAR $v_size = filesize($this->_tarname); // We might have zero, one or two end blocks. - // The standard is two, but we should try to handle + // The standard is two, but we should try to handle // other cases. fseek($this->_file, $v_size - 1024); if (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { fseek($this->_file, $v_size - 1024); } elseif (fread($this->_file, 512) == ARCHIVE_TAR_END_BLOCK) { - fseek($this->_file, $v_size - 512); + fseek($this->_file, $v_size - 512); } } @@ -2938,7 +2996,7 @@ class Archive_Tar extends PEAR { if (!$this->_openAppend()) return false; - + if ($this->_addList($p_filelist, $p_add_dir, $p_remove_dir)) $this->_writeFooter(); @@ -2984,7 +3042,7 @@ class Archive_Tar extends PEAR // {{{ _pathReduction() /** - * Compress path by changing for example "/dir/foo/../bar" to "/dir/bar", + * Compress path by changing for example "/dir/foo/../bar" to "/dir/bar", * rand emove double slashes. * * @param string $p_dir path to reduce @@ -5764,33 +5822,43 @@ Correct Bug #9352 Bug on _dirCheck function over nfs path | -// +----------------------------------------------------------------------+ -// -// $Id: Getopt.php,v 1.32 2007/02/18 04:13:07 cellog Exp $ +/** + * Color.php + * + * PHP Version 5 + * + * Copyright (c) 1997-2004 The PHP Group + * + * This source file is subject to version 3.0 of the PHP license, + * that is bundled with this package in the file LICENSE, and is + * available through the world-wide-web at the following url: + * http://www.php.net/license/3_0.txt. + * If you did not receive a copy of the PHP license and are unable to + * obtain it through the world-wide-web, please send a note to + * license@php.net so we can mail you a copy immediately. + * + * @category Console + * @package Console_Getopt + * @author Andrei Zmievski + * @license http://www.php.net/license/3_0.txt PHP 3.0 + * @version CVS: $Id: Getopt.php 267328 2008-10-14 18:53:25Z andrei $ + * @link http://pear.php.net/package/Console_Getopt + */ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; /** * Command-line options parsing class. * - * @author Andrei Zmievski - * + * @category Console + * @package Console_Getopt + * @author Andrei Zmievski + * @license http://www.php.net/license/3_0.txt PHP 3.0 + * @link http://pear.php.net/package/Console_Getopt */ -class Console_Getopt { +class Console_Getopt +{ + /** * Parses the command-line options. * @@ -5817,15 +5885,13 @@ class Console_Getopt { * * Most of the semantics of this function are based on GNU getopt_long(). * - * @param array $args an array of command-line arguments - * @param string $short_options specifies the list of allowed short options - * @param array $long_options specifies the list of allowed long options + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options * * @return array two-element array containing the list of parsed options and * the non-option arguments - * * @access public - * */ function getopt2($args, $short_options, $long_options = null) { @@ -5835,7 +5901,14 @@ class Console_Getopt { /** * This function expects $args to start with the script name (POSIX-style). * Preserved for backwards compatibility. + * + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options + * * @see getopt2() + * @return array two-element array containing the list of parsed options and + * the non-option arguments */ function getopt($args, $short_options, $long_options = null) { @@ -5844,6 +5917,13 @@ class Console_Getopt { /** * The actual implementation of the argument parsing code. + * + * @param int $version Version to use + * @param array $args an array of command-line arguments + * @param string $short_options specifies the list of allowed short options + * @param array $long_options specifies the list of allowed long options + * + * @return array */ function doGetopt($version, $args, $short_options, $long_options = null) { @@ -5884,17 +5964,28 @@ class Console_Getopt { break; } - if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' && !$long_options)) { + if ($arg{0} != '-' || (strlen($arg) > 1 && $arg{1} == '-' + && !$long_options)) { $non_opts = array_merge($non_opts, array_slice($args, $i)); break; } elseif (strlen($arg) > 1 && $arg{1} == '-') { - $error = Console_Getopt::_parseLongOption(substr($arg, 2), $long_options, $opts, $args); - if (PEAR::isError($error)) + $error = Console_Getopt::_parseLongOption(substr($arg, 2), + $long_options, $opts, + $args); + if (PEAR::isError($error)) { return $error; + } + } elseif ($arg == '-') { + // - is stdin + $non_opts = array_merge($non_opts, array_slice($args, $i)); + break; } else { - $error = Console_Getopt::_parseShortOption(substr($arg, 1), $short_options, $opts, $args); - if (PEAR::isError($error)) + $error = Console_Getopt::_parseShortOption(substr($arg, 1), + $short_options, $opts, + $args); + if (PEAR::isError($error)) { return $error; + } } } @@ -5902,19 +5993,27 @@ class Console_Getopt { } /** - * @access private + * Parse short option + * + * @param string $arg Argument + * @param string[] $short_options Available short options + * @param string[][] &$opts + * @param string[] &$args * + * @access private + * @return void */ function _parseShortOption($arg, $short_options, &$opts, &$args) { for ($i = 0; $i < strlen($arg); $i++) { - $opt = $arg{$i}; + $opt = $arg{$i}; $opt_arg = null; /* Try to find the short option in the specifier string. */ - if (($spec = strstr($short_options, $opt)) === false || $arg{$i} == ':') - { - return PEAR::raiseError("Console_Getopt: unrecognized option -- $opt"); + if (($spec = strstr($short_options, $opt)) === false + || $arg{$i} == ':') { + $msg = "Console_Getopt: unrecognized option -- $opt"; + return PEAR::raiseError($msg); } if (strlen($spec) > 1 && $spec{1} == ':') { @@ -5933,11 +6032,14 @@ class Console_Getopt { break; } else if (list(, $opt_arg) = each($args)) { /* Else use the next argument. */; - if (Console_Getopt::_isShortOpt($opt_arg) || Console_Getopt::_isLongOpt($opt_arg)) { - return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt"); + if (Console_Getopt::_isShortOpt($opt_arg) + || Console_Getopt::_isLongOpt($opt_arg)) { + $msg = "option requires an argument --$opt"; + return PEAR::raiseError("Console_Getopt:" . $msg); } } else { - return PEAR::raiseError("Console_Getopt: option requires an argument -- $opt"); + $msg = "option requires an argument --$opt"; + return PEAR::raiseError("Console_Getopt:" . $msg); } } } @@ -5947,36 +6049,54 @@ class Console_Getopt { } /** - * @access private + * Checks if an argument is a short option + * + * @param string $arg Argument to check * + * @access private + * @return bool */ function _isShortOpt($arg) { - return strlen($arg) == 2 && $arg[0] == '-' && preg_match('/[a-zA-Z]/', $arg[1]); + return strlen($arg) == 2 && $arg[0] == '-' + && preg_match('/[a-zA-Z]/', $arg[1]); } /** - * @access private + * Checks if an argument is a long option + * + * @param string $arg Argument to check * + * @access private + * @return bool */ function _isLongOpt($arg) { return strlen($arg) > 2 && $arg[0] == '-' && $arg[1] == '-' && - preg_match('/[a-zA-Z]+$/', substr($arg, 2)); + preg_match('/[a-zA-Z]+$/', substr($arg, 2)); } /** - * @access private + * Parse long option * + * @param string $arg Argument + * @param string[] $long_options Available long options + * @param string[][] &$opts + * @param string[] &$args + * + * @access private + * @return void|PEAR_Error */ function _parseLongOption($arg, $long_options, &$opts, &$args) { @list($opt, $opt_arg) = explode('=', $arg, 2); + $opt_len = strlen($opt); for ($i = 0; $i < count($long_options); $i++) { $long_opt = $long_options[$i]; $opt_start = substr($long_opt, 0, $opt_len); + $long_opt_name = str_replace('=', '', $long_opt); /* Option doesn't match. Go on to the next one. */ @@ -5984,17 +6104,24 @@ class Console_Getopt { continue; } - $opt_rest = substr($long_opt, $opt_len); + $opt_rest = substr($long_opt, $opt_len); /* Check that the options uniquely matches one of the allowed options. */ - $next_option_rest = substr($long_options[$i + 1], $opt_len); + if ($i + 1 < count($long_options)) { + $next_option_rest = substr($long_options[$i + 1], $opt_len); + } else { + $next_option_rest = ''; + } + if ($opt_rest != '' && $opt{0} != '=' && $i + 1 < count($long_options) && $opt == substr($long_options[$i+1], 0, $opt_len) && $next_option_rest != '' && $next_option_rest{0} != '=') { - return PEAR::raiseError("Console_Getopt: option --$opt is ambiguous"); + + $msg = "Console_Getopt: option --$opt is ambiguous"; + return PEAR::raiseError($msg); } if (substr($long_opt, -1) == '=') { @@ -6002,11 +6129,19 @@ class Console_Getopt { /* Long option requires an argument. Take the next argument if one wasn't specified. */; if (!strlen($opt_arg) && !(list(, $opt_arg) = each($args))) { - return PEAR::raiseError("Console_Getopt: option --$opt requires an argument"); + $msg = "Console_Getopt: option requires an argument --$opt"; + return PEAR::raiseError($msg); + } + + if (Console_Getopt::_isShortOpt($opt_arg) + || Console_Getopt::_isLongOpt($opt_arg)) { + $msg = "Console_Getopt: option requires an argument --$opt"; + return PEAR::raiseError($msg); } } } else if ($opt_arg) { - return PEAR::raiseError("Console_Getopt: option --$opt doesn't allow an argument"); + $msg = "Console_Getopt: option --$opt doesn't allow an argument"; + return PEAR::raiseError($msg); } $opts[] = array('--' . $opt, $opt_arg); @@ -6017,19 +6152,20 @@ class Console_Getopt { } /** - * Safely read the $argv PHP array across different PHP configurations. - * Will take care on register_globals and register_argc_argv ini directives - * - * @access public - * @return mixed the $argv PHP array or PEAR error if not registered - */ + * Safely read the $argv PHP array across different PHP configurations. + * Will take care on register_globals and register_argc_argv ini directives + * + * @access public + * @return mixed the $argv PHP array or PEAR error if not registered + */ function readPHPArgv() { global $argv; if (!is_array($argv)) { if (!@is_array($_SERVER['argv'])) { if (!@is_array($GLOBALS['HTTP_SERVER_VARS']['argv'])) { - return PEAR::raiseError("Console_Getopt: Could not read cmd args (register_argc_argv=Off?)"); + $msg = "Could not read cmd args (register_argc_argv=Off?)"; + return PEAR::raiseError("Console_Getopt: " . $msg); } return $GLOBALS['HTTP_SERVER_VARS']['argv']; } @@ -6486,278 +6622,307 @@ class Console_Getopt { } ?> - 'phar://install-pear-nozlib.phar/Archive_Tar-1.3.3.tar', 'Console_Getopt' => 'phar://install-pear-nozlib.phar/Console_Getopt-1.2.3.tar', 'Structures_Graph' => 'phar://install-pear-nozlib.phar/Structures_Graph-1.0.2.tar', 'XML_Util' => 'phar://install-pear-nozlib.phar/XML_Util-1.2.1.tar', -'PEAR' => 'phar://install-pear-nozlib.phar/PEAR-1.8.0.tar', -); -array_shift($argv); -$debug = false; -for ($i = 0; $i < sizeof($argv); $i++) { - $arg = $argv[$i]; - $bn = basename($arg); - if (ereg('package-(.*)\.xml$', $bn, $matches) || - ereg('([A-Za-z0-9_:]+)-.*\.(tar|tgz)$', $bn, $matches)) { - $install_files[$matches[1]] = $arg; - } elseif ($arg == '-a') { - $cache_dir = $argv[$i+1]; - $i++; - } elseif ($arg == '--force') { - $force = true; - } elseif ($arg == '-d') { - $with_dir = $argv[$i+1]; - $i++; - } elseif ($arg == '-b') { - $bin_dir = $argv[$i+1]; - $i++; - } elseif ($arg == '-c') { - $cfg_dir = $argv[$i+1]; - $i++; - } elseif ($arg == '-w') { - $www_dir = $argv[$i+1]; - $i++; - } elseif ($arg == '-p') { - $php_bin = $argv[$i+1]; - $i++; - } elseif ($arg == '-o') { - $download_dir = $argv[$i+1]; - $i++; - } elseif ($arg == '-t') { - $temp_dir = $argv[$i+1]; - $i++; - } elseif ($arg == '--debug') { - $debug = 1; - } elseif ($arg == '--extremedebug') { - $debug = 2; - } -} - -$config = PEAR_Config::singleton(); - -if (PEAR::isError($config)) { - $locs = PEAR_Config::getDefaultConfigFiles(); - die("ERROR: One of $locs[user] or $locs[system] is corrupt, please remove them and try again"); -} - -// make sure we use only default values -$config_layers = $config->getLayers(); -foreach ($config_layers as $layer) { - if ($layer == 'default') continue; - $config->removeLayer($layer); -} -$keys = $config->getKeys(); -if ($debug) { - $config->set('verbose', 5, 'default'); -} else { - $config->set('verbose', 0, 'default'); -} -// PEAR executables -if (!empty($bin_dir)) { - $config->set('bin_dir', $bin_dir, 'default'); -} - -// Cache files -if (!empty($cache_dir)) { - $config->set('cache_dir', $cache_dir, 'default'); -} - -// Config files -if (!empty($cfg_dir)) { - $config->set('cfg_dir', $cfg_dir, 'default'); -} - -// Web files -if (!empty($www_dir)) { - $config->set('www_dir', $www_dir, 'default'); -} - -// Downloaded files -if (!empty($download_dir)) { - $config->set('download_dir', $download_dir, 'default'); -} - -// Temporary files -if (!empty($temp_dir)) { - $config->set('temp_dir', $temp_dir, 'default'); -} - -// User supplied a dir prefix -if (!empty($with_dir)) { - $ds = DIRECTORY_SEPARATOR; - $config->set('php_dir', $with_dir, 'default'); - $config->set('doc_dir', $with_dir . $ds . 'doc', 'default'); - $config->set('data_dir', $with_dir . $ds . 'data', 'default'); - $config->set('test_dir', $with_dir . $ds . 'test', 'default'); - if (empty($www_dir)) { - $config->set('www_dir', $with_dir . $ds . 'htdocs', 'default'); - } - if (empty($cfg_dir)) { - $config->set('cfg_dir', $with_dir . $ds . 'cfg', 'default'); - } - if (!is_writable($config->get('cache_dir'))) { - include_once 'phar://install-pear-nozlib.phar/System.php'; - $cdir = System::mktemp(array('-d', 'pear')); - if (PEAR::isError($cdir)) { - $ui->outputData("[PEAR] cannot make new temporary directory: " . $cdir); - die(1); - } - $oldcachedir = $config->get('cache_dir'); - $config->set('cache_dir', $cdir); - } -} -if (!empty($php_bin)) { - $config->set('php_bin', $php_bin); -} -/* Print PEAR Conf (useful for debuging do NOT REMOVE) */ -if ($debug) { - sort($keys); - foreach ($keys as $key) { - echo $key . ' ' . - $config->getPrompt($key) . ": " . $config->get($key, null, 'default') . "\n"; - } - if ($debug == 2) { // extreme debugging - exit; - } -} -// end print - -$php_dir = $config->get('php_dir'); -$options = array(); -$options['upgrade'] = true; -$install_root = getenv('INSTALL_ROOT'); -if (!empty($install_root)) { - $options['packagingroot'] = $install_root; - $reg = &new PEAR_Registry($options['packagingroot']); -} else { - $reg = $config->getRegistry('default'); -} - -$ui = PEAR_Frontend::singleton('PEAR_Frontend_CLI'); -if (PEAR::isError($ui)) { - die($ui->getMessage()); -} -$installer = new PEAR_Installer($ui); -$pkg = new PEAR_PackageFile($config, $debug); - -foreach ($install_files as $package => $instfile) { - $info = $pkg->fromAnyFile($instfile, PEAR_VALIDATE_INSTALLING); - if (PEAR::isError($info)) { - if (is_array($info->getUserInfo())) { - foreach ($info->getUserInfo() as $err) { - $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err['message'])); - } - } - $ui->outputData(sprintf("[PEAR] %s: %s", $package, $info->getMessage())); - continue; - } - $new_ver = $info->getVersion(); - $downloaderpackage = new PEAR_Downloader_Package($installer); - $err = $downloaderpackage->initialize($instfile); - if (PEAR::isError($err)) { - $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); - continue; - } - if ($reg->packageExists($package)) { - $old_ver = $reg->packageInfo($package, 'version'); - if (version_compare($new_ver, $old_ver, 'gt')) { - $installer->setOptions($options); - $dp = array($downloaderpackage); - $installer->setDownloadedPackages($dp); - $err = $installer->install($downloaderpackage, $options); - if (PEAR::isError($err)) { - $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); - continue; - } - $ui->outputData(sprintf("[PEAR] %-15s- upgraded: %s", $package, $new_ver)); - } else { - if ($force) { - $options['force'] = true; - $installer->setOptions($options); - $dp = array($downloaderpackage); - $installer->setDownloadedPackages($dp); - $err = $installer->install($downloaderpackage, $options); - if (PEAR::isError($err)) { - $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); - continue; - } - $ui->outputData(sprintf("[PEAR] %-15s- installed: %s", $package, $new_ver)); - } else { - $ui->outputData(sprintf("[PEAR] %-15s- already installed: %s", $package, $old_ver)); - } - } - } else { - $options['nodeps'] = true; - $installer->setOptions($options); - $dp = array($downloaderpackage); - $installer->setDownloadedPackages($dp); - $err = $installer->install($downloaderpackage, $options); - if (PEAR::isError($err)) { - $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); - continue; - } - $ui->outputData(sprintf("[PEAR] %-15s- installed: %s", $package, $new_ver)); - } - if ($package == 'PEAR') { - if (is_file($ufile = $config->getConfFile('user'))) { - $ui->outputData('Warning! a PEAR user config file already exists from ' . - 'a previous PEAR installation at ' . - "'$ufile'. You may probably want to remove it."); - } - $config->set('verbose', 1, 'default'); - if (isset($oldcachedir)) { - $config->set('cache_dir', $oldcachedir); - } - $data = array(); - foreach ($config->getKeys() as $key) { - $data[$key] = $config->get($key); - } - $cnf_file = $config->getConfFile('system'); - if (!empty($install_root)) { - $cnf_file = $install_root . DIRECTORY_SEPARATOR . $cnf_file; - } - $config->writeConfigFile($cnf_file, 'system', $data); - $ui->outputData('Wrote PEAR system config file at: ' . $cnf_file); - $ui->outputData('You may want to add: ' . $config->get('php_dir') . ' to your php.ini include_path'); - } -} -?> +'PEAR' => 'phar://install-pear-nozlib.phar/PEAR-1.9.0.tar', +); +array_shift($argv); +$debug = false; +for ($i = 0; $i < sizeof($argv); $i++) { + $arg = $argv[$i]; + $bn = basename($arg); + if (preg_match('/package-(.*)\.xml$/', $bn, $matches) || + preg_match('/([A-Za-z0-9_:]+)-.*\.(tar|tgz)$/', $bn, $matches)) { + $install_files[$matches[1]] = $arg; + } elseif ($arg == '-a') { + $cache_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '--force') { + $force = true; + } elseif ($arg == '-dp') { + $prefix = $argv[$i+1]; + $i++; + } elseif ($arg == '-ds') { + $suffix = $argv[$i+1]; + $i++; + } elseif ($arg == '-d') { + $with_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '-b') { + $bin_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '-c') { + $cfg_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '-w') { + $www_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '-p') { + $php_bin = $argv[$i+1]; + $i++; + } elseif ($arg == '-o') { + $download_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '-t') { + $temp_dir = $argv[$i+1]; + $i++; + } elseif ($arg == '--debug') { + $debug = 1; + } elseif ($arg == '--extremedebug') { + $debug = 2; + } +} + +$config = PEAR_Config::singleton(); + +if (PEAR::isError($config)) { + $locs = PEAR_Config::getDefaultConfigFiles(); + die("ERROR: One of $locs[user] or $locs[system] is corrupt, please remove them and try again"); +} + +// make sure we use only default values +$config_layers = $config->getLayers(); +foreach ($config_layers as $layer) { + if ($layer == 'default') continue; + $config->removeLayer($layer); +} +$keys = $config->getKeys(); +if ($debug) { + $config->set('verbose', 5, 'default'); +} else { + $config->set('verbose', 0, 'default'); +} +// PEAR executables +if (!empty($bin_dir)) { + $config->set('bin_dir', $bin_dir, 'default'); +} + +// Cache files +if (!empty($cache_dir)) { + $config->set('cache_dir', $cache_dir, 'default'); +} + +// Config files +if (!empty($cfg_dir)) { + $config->set('cfg_dir', $cfg_dir, 'default'); +} + +// Web files +if (!empty($www_dir)) { + $config->set('www_dir', $www_dir, 'default'); +} + +// Downloaded files +if (!empty($download_dir)) { + $config->set('download_dir', $download_dir, 'default'); +} + +// Temporary files +if (!empty($temp_dir)) { + $config->set('temp_dir', $temp_dir, 'default'); +} + +// User supplied a dir prefix +if (!empty($with_dir)) { + $ds = DIRECTORY_SEPARATOR; + $config->set('php_dir', $with_dir, 'default'); + $config->set('doc_dir', $with_dir . $ds . 'doc', 'default'); + $config->set('data_dir', $with_dir . $ds . 'data', 'default'); + $config->set('test_dir', $with_dir . $ds . 'test', 'default'); + if (empty($www_dir)) { + $config->set('www_dir', $with_dir . $ds . 'htdocs', 'default'); + } + if (empty($cfg_dir)) { + $config->set('cfg_dir', $with_dir . $ds . 'cfg', 'default'); + } + if (!is_writable($config->get('cache_dir'))) { + include_once 'phar://install-pear-nozlib.phar/System.php'; + $cdir = System::mktemp(array('-d', 'pear')); + if (PEAR::isError($cdir)) { + $ui->outputData("[PEAR] cannot make new temporary directory: " . $cdir); + die(1); + } + $oldcachedir = $config->get('cache_dir'); + $config->set('cache_dir', $cdir); + } +} + +// PHP executable +if (!empty($php_bin)) { + $config->set('php_bin', $php_bin); +} + +// PHP prefix +if (isset($prefix)) { + if ($prefix != 'a') { + if ($prefix[0] == 'a') { + $prefix = substr($prefix, 1); + } + $config->set('php_prefix', $prefix, 'system'); + } +} + +// PHP suffix +if (isset($suffix)) { + if ($suffix != 'a') { + if ($suffix[0] == 'a') { + $suffix = substr($suffix, 1); + } + $config->set('php_suffix', $suffix, 'system'); + } +} + +/* Print PEAR Conf (useful for debuging do NOT REMOVE) */ +if ($debug) { + sort($keys); + foreach ($keys as $key) { + echo $key . ' ' . + $config->getPrompt($key) . ": " . $config->get($key, null, 'default') . "\n"; + } + if ($debug == 2) { // extreme debugging + exit; + } +} +// end print + +$php_dir = $config->get('php_dir'); +$options = array(); +$options['upgrade'] = true; +$install_root = getenv('INSTALL_ROOT'); +if (!empty($install_root)) { + $options['packagingroot'] = $install_root; + $reg = &new PEAR_Registry($options['packagingroot']); +} else { + $reg = $config->getRegistry('default'); +} + +$ui = PEAR_Frontend::singleton('PEAR_Frontend_CLI'); +if (PEAR::isError($ui)) { + die($ui->getMessage()); +} +$installer = new PEAR_Installer($ui); +$pkg = new PEAR_PackageFile($config, $debug); + +foreach ($install_files as $package => $instfile) { + $info = $pkg->fromAnyFile($instfile, PEAR_VALIDATE_INSTALLING); + if (PEAR::isError($info)) { + if (is_array($info->getUserInfo())) { + foreach ($info->getUserInfo() as $err) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err['message'])); + } + } + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $info->getMessage())); + continue; + } + $new_ver = $info->getVersion(); + $downloaderpackage = new PEAR_Downloader_Package($installer); + $err = $downloaderpackage->initialize($instfile); + if (PEAR::isError($err)) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); + continue; + } + if ($reg->packageExists($package)) { + $old_ver = $reg->packageInfo($package, 'version'); + if (version_compare($new_ver, $old_ver, 'gt')) { + $installer->setOptions($options); + $dp = array($downloaderpackage); + $installer->setDownloadedPackages($dp); + $err = $installer->install($downloaderpackage, $options); + if (PEAR::isError($err)) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); + continue; + } + $ui->outputData(sprintf("[PEAR] %-15s- upgraded: %s", $package, $new_ver)); + } else { + if ($force) { + $options['force'] = true; + $installer->setOptions($options); + $dp = array($downloaderpackage); + $installer->setDownloadedPackages($dp); + $err = $installer->install($downloaderpackage, $options); + if (PEAR::isError($err)) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); + continue; + } + $ui->outputData(sprintf("[PEAR] %-15s- installed: %s", $package, $new_ver)); + } else { + $ui->outputData(sprintf("[PEAR] %-15s- already installed: %s", $package, $old_ver)); + } + } + } else { + $options['nodeps'] = true; + $installer->setOptions($options); + $dp = array($downloaderpackage); + $installer->setDownloadedPackages($dp); + $err = $installer->install($downloaderpackage, $options); + if (PEAR::isError($err)) { + $ui->outputData(sprintf("[PEAR] %s: %s", $package, $err->getMessage())); + continue; + } + $ui->outputData(sprintf("[PEAR] %-15s- installed: %s", $package, $new_ver)); + } + if ($package == 'PEAR') { + if (is_file($ufile = $config->getConfFile('user'))) { + $ui->outputData('Warning! a PEAR user config file already exists from ' . + 'a previous PEAR installation at ' . + "'$ufile'. You may probably want to remove it."); + } + $config->set('verbose', 1, 'default'); + if (isset($oldcachedir)) { + $config->set('cache_dir', $oldcachedir); + } + $data = array(); + foreach ($config->getKeys() as $key) { + $data[$key] = $config->get($key); + } + $cnf_file = $config->getConfFile('system'); + if (!empty($install_root)) { + $cnf_file = $install_root . DIRECTORY_SEPARATOR . $cnf_file; + } + $config->writeConfigFile($cnf_file, 'system', $data); + $ui->outputData('Wrote PEAR system config file at: ' . $cnf_file); + $ui->outputData('You may want to add: ' . $config->get('php_dir') . ' to your php.ini include_path'); + } +} +?> $instfile) { * @author Gregory Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Guess.php,v 1.29 2009/04/09 22:24:12 dufuz Exp $ + * @version CVS: $Id: Guess.php 278521 2009-04-09 22:24:12Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since PEAR 0.1 */ @@ -6847,7 +7012,7 @@ foreach ($install_files as $package => $instfile) { * @author Gregory Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -7095,8 +7260,8 @@ class OS_Guess * indent-tabs-mode: nil * c-basic-offset: 4 * End: - */package2.xml100664 764 764 123245 100664 6362 - + */package2.xml100664 764 764 117255 100664 6366 + PEAR pear.php.net PEAR Base System @@ -7178,325 +7343,246 @@ class OS_Guess mj@php.net no - 2009-04-10 - + 2009-09-03 + - 1.8.0 - 1.8.0 + 1.9.0 + 1.9.0 stable stable - New BSD License + New BSD License -Changes since RC1: - * Fix Bug #14792: Bad md5sum for files with replaced content [dufuz] - * Fix Bug #16057:-r is limited to 4 directories in depth [dufuz] - * Fix Bug #16077: PEAR5::getStaticProperty does not return a reference to the property [dufuz] - - Remove custom XML_Util class in favor of using upstream XML_Util package as dependency - -RC1 Release Notes: - * Fix Bug #14331: pear cvstag only works from inside the package directory [dufuz] - * Fix Bug #16045: E_Notice: Undefined index: channel in PEAR/DependencyDB.php [dufuz] - - * Implemented Request #11230: better error message when mirror not in channel.xml file [dufuz] - * Implemented Request #13150: Add support for following HTTP 302 redirects [dufuz] - -Alpha1 Release Notes: - * Implement Request #10373: if pref_state=stable and installed package=beta, allow up to latest beta version [dufuz] - * Implement Request #10581: login / logout should map to channel-login / channel-logout [dufuz] - * Implement Request #10825: Only display the "invalid or missing package file"-error if it makes sense [dufuz] - * Implement Request #11170: script to generate Command/[command].xml [dufuz] - * Implement Request #11176: improve channel ... has updated its protocols message [dufuz] - * Implement Request #12706: pear list -a hard to read [dufuz] - * Implement Request #11353: upgrade-all and upgrade commands to upgrade within the same stability level [dufuz] - * Implement Request #13015: Add https discovery for channel.xml [dufuz / initial patch by Martin Roos] - * Implement Request #13927: install-pear.php should have option to set www_dir [timj] - * Implement Request #14324: Make the pear install command behave similar to apt-get [dufuz] - * Implement Request #14325: make pear upgrade with no params behave like pear upgrade-all [dufuz] - - upgrade-all can be considered deprecated in favor of calling upgrade with no parameters to replicate - better what other package managers are doing. upgrade-all will still work as intended. - * Implement Request #14504: add a channel parameter support to the upgrade function [dufuz] - - Options -c ezc and --channel=ezc got added to upgrade and upgrade-all to allow for - channel specific upgrades - * Implement Request #14556: install-pear-nozlib.phar should get download_dir config and other options [cweiske] - * Implement Request #15566: Add doc.php.net as a default channel [dufuz / saltybeagle] - - * Fix PHP Bug #43857: --program-suffix not always reflected everywhere [cellog] - * Fix PHP Bug #47323: strotime warnings in make install [dufuz] - - * Fix Bug #13908: pear info command and maintainers inactive not mentioned [dufuz] - * Fix Bug #13926: install-pear.php does not set cfg_dir if -d option set with no -c option [timj] - * Fix Bug #13943: tests fail when php.exe path contains spaces [dufuz / jorrit] - * Fix Bug #13953: config-set/config-show with channel alias fail [cellog] - * Fix Bug #13958: When a phpt tests exit() or die() xdebug coverage is not generated, patch by izi (David Jean Louis) [izi / dufuz] - * Fix Bug #14041: Unpredictable unit test processing sequence [dufuz] - * Fix Bug #14140: Strict warning not suppressed in the shutdown function [dufuz] - * Fix Bug #14210: pear list -ia brings warnings [dufuz] - * Fix Bug #14274: PEAR packager mangles package.xml encoding, then complains about it [dufuz] - * Fix Bug #14287: cannot upgrade from stable to beta via -beta when config is set to stable [dufuz] - * Fix Bug #14300: Package files themselves can not be served over https [dufuz / initial patch by Martin Roos] - * Fix Bug #14437: openbasedir warning when loading config [dufuz] - * Fix Bug #14558: PackageFile.php creates tmp directory outside configured temp_dir [cweiske] - * Fix Bug #14947: downloadHttp() is missing Host part of the HTTP Request when using Proxy [ifeghali] - * Fix Bug #14977: PEAR/Frontend.php doesn't require_once PEAR.php [dufuz] - * Fix Bug #15750: Unreachable code in PEAR_Downloader [dufuz] - * Fix Bug #15979: Package files incorrectly removed when splitting a package into multiple pkgs [dufuz] - * Fix Bug #15914: pear upgrade installs different version if desired version not found [dufuz] - - NOTE! - Functions that have been deprecated for 3+ years in PEAR_Common, please take a moment - to migrate over to one of the alternatives that have ben provided: - * PEAR_Common->downloadHttp (use PEAR_Downloader->downloadHttp instead) - * PEAR_Common->infoFromTgzFile (use PEAR_PackageFile->fromTgzFile instead) - * PEAR_Common->infoFromDescriptionFile (use PEAR_PackageFile->fromPackageFile instead) - * PEAR_Common->infoFromString (use PEAR_PackageFile->fromXmlstring instead) - * PEAR_Common->infoFromArray (use PEAR_PackageFile->fromAnyFile instead) - * PEAR_Common->xmlFromInfo (use a PEAR_PackageFile_v* object's generator instead) - * PEAR_Common->validatePackageInfo (use the validation of PEAR_PackageFile objects) - * PEAR_Common->analyzeSourceCode (use a PEAR_PackageFile_v* object instead) - * PEAR_Common->detectDependencies (use PEAR_Downloader_Package->detectDependencies instead) - * PEAR_Common->buildProvidesArray (use PEAR_PackageFile_v1->_buildProvidesArray or - PEAR_PackageFile_v2_Validator->_buildProvidesArray) - - PHP 4.4 and 5.1.6 are now the minimum PHP requirements, for brave souls - pear upgrade -f PEAR will allow people with lower versions - to upgrade to this release but no guarantees will be made that it will work properly. - - Support for XML RPC channels has been dropped - The only ones that used it - (pear.php.net and pecl.php.net) have used the REST interface for years now. - SOAP support also removed as it was only proof of concept. - - Move codebase from the PHP License to New BSD 2 clause license +* Fix Bug #16547: The phar for PEAR installer uses ereg() which is deprecated [dufuz] - + - + - + - - + + - - + + - + - + - - + + - + - - + + - + - + - + - - + + - + - + - + - + - + - + - + - + - + - - + + - + - - + + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -7505,7 +7591,7 @@ Alpha1 Release Notes: - + @@ -7538,26 +7624,27 @@ Alpha1 Release Notes: - + - + - - - + + + + - - + + @@ -7684,7 +7771,7 @@ Alpha1 Release Notes: stable 2009-03-09 - New BSD License + New BSD License * Implement Request #10373: if pref_state=stable and installed package=beta, allow up to latest beta version [dufuz] * Implement Request #10581: login / logout should map to channel-login / channel-logout [dufuz] @@ -7763,7 +7850,7 @@ Move codebase from the PHP License to New BSD 2 clause license beta stable - New BSD License + New BSD License * Fix Bug #14331: pear cvstag only works from inside the package directory [dufuz] * Fix Bug #16045: E_Notice: Undefined index: channel in PEAR/DependencyDB.php [dufuz] @@ -7782,7 +7869,7 @@ Move codebase from the PHP License to New BSD 2 clause license stable stable - New BSD License + New BSD License Changes since RC1: * Fix Bug #14792: Bad md5sum for files with replaced content [dufuz] @@ -7866,9 +7953,116 @@ Alpha1 Release Notes: Move codebase from the PHP License to New BSD 2 clause license + + 2009-04-15 + + 1.8.1 + 1.8.1 + + + stable + stable + + New BSD License + +* Fix Bug #16099 PEAR crash on PHP4 (parse error) [dufuz] + + + + 2009-08-18 + + 1.9.0RC1 + 1.9.0RC1 + + + beta + stable + + New BSD License + +* Implement Request #16213: add alias to list-channels output [dufuz] +* Implement Request #16378: pear svntag [dufuz] +* Implement Request #16386: PEAR_Config::remove() does not support specifying a channel [timj] +* Implement Request #16396: package-dependencies should allow package names [dufuz] + +* Fix Bug #11181: pear requests channel.xml from main server instead from mirror [dufuz] +* Fix Bug #14493: pear install --offline doesn't print out errors [dufuz] +* Fix Bug #11348: pear package-dependencies isn't well explained [dufuz] +* Fix Bug #16108: PEAR_PackageFile_Generator_v2 PHP4 parse error when running upgrade-all [dufuz] +* Fix Bug #16113: Installing certain packages fails due incorrect encoding handling [dufuz] +* Fix Bug #16122: PEAR RunTest failed to run as expected [dufuz] +* Fix Bug #16366: compiling 5.2.10 leads to non-functioning pear [dufuz] +* Fix Bug #16387: channel-logout does not support logging out from a non-default channel [timj] +* Fix Bug #16444: Setting preferred mirror fails [dufuz] +* Fix the shutdown functions where a index might not exist and thus raise a notice [derick] + + + + 2009-08-20 + + 1.9.0RC2 + 1.9.0RC2 + + + beta + stable + + New BSD License + +* REST 1.4 file was occasionally being included but REST 1.4 is not intended for this release cycle [dufuz] + + + + 2009-08-21 + + 1.9.0RC3 + 1.9.0RC3 + + + beta + stable + + New BSD License + +* Improved svntag support to handle packages like PEAR it self [dufuz] + + + + 2009-08-23 + + 1.9.0RC4 + 1.9.0RC4 + + + beta + stable + + New BSD License + +* Fixed a problem where the original channel could not be set as a preferred_mirror again [dufuz] +* Make sure channel aliases can't be made to start with - [dufuz] +* Output issues with pear search [dufuz] +* Fixed couple of stray notices [dufuz] + + + + 2009-09-03 + + 1.9.0 + 1.9.0 + + + stable + stable + + New BSD License + +* Fix Bug #16547: The phar for PEAR installer uses ereg() which is deprecated [dufuz] + + -PEAR-1.8.0/OS/Guess.php100664 764 764 24637 100664 7461 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Guess.php,v 1.29 2009/04/09 22:24:12 dufuz Exp $ + * @version CVS: $Id: Guess.php 278521 2009-04-09 22:24:12Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since PEAR 0.1 */ @@ -7957,7 +8151,7 @@ Alpha1 Release Notes: * @author Gregory Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -8205,7 +8399,7 @@ class OS_Guess * indent-tabs-mode: nil * c-basic-offset: 4 * End: - */PEAR-1.8.0/PEAR/ChannelFile/Parser.php100664 764 764 3364 100664 12157 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Parser.php,v 1.7 2009/02/24 23:39:07 dufuz Exp $ + * @version CVS: $Id: Parser.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -8233,7 +8427,7 @@ require_once 'PEAR/ChannelFile.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -8272,7 +8466,7 @@ class PEAR_ChannelFile_Parser extends PEAR_XMLParser $ret->setPackagefile($file, $archive); return $ret; } -}PEAR-1.8.0/PEAR/Command/Auth.xml100777 764 764 2314 100777 11047 +}PEAR-1.9.0/PEAR/Command/Auth.xml100664 764 764 2314 100664 11036 Connects and authenticates to remote server [Deprecated in favor of channel-login] doLogin @@ -8301,7 +8495,7 @@ Logs out from the remote server. This command does not actually connect to the remote server, it only deletes the stored username and password from your user configuration. -PEAR-1.8.0/PEAR/Command/Auth.php100664 764 764 5141 100664 11025 PEAR-1.9.0/PEAR/Command/Auth.php100664 764 764 5136 100664 11032 * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Auth.php,v 1.36 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Auth.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 * @deprecated since 1.8.0alpha1 @@ -8333,7 +8527,7 @@ require_once 'PEAR/Command/Channels.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 * @deprecated since 1.8.0alpha1 @@ -8381,100 +8575,100 @@ password from your user configuration.', { parent::PEAR_Command_Channels($ui, $config); } -}PEAR-1.8.0/PEAR/Command/Build.xml100777 764 764 405 100777 11164 +}PEAR-1.9.0/PEAR/Command/Build.xml100664 764 764 404 100664 11152 Build an Extension From C Source doBuild b - [package.xml] + [package.xml] Builds one or more extensions contained in a package. -PEAR-1.8.0/PEAR/Command/Build.php100664 764 764 4602 100664 11164 - * @author Tomas V.V.Cox - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Build.php,v 1.16 2009/02/24 23:39:29 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ - -/** - * base class - */ -require_once 'PEAR/Command/Common.php'; - -/** - * PEAR commands for building extensions. - * - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Tomas V.V.Cox - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 - */ -class PEAR_Command_Build extends PEAR_Command_Common -{ - var $commands = array( - 'build' => array( - 'summary' => 'Build an Extension From C Source', - 'function' => 'doBuild', - 'shortcut' => 'b', - 'options' => array(), - 'doc' => '[package.xml] -Builds one or more extensions contained in a package.' - ), - ); - - /** - * PEAR_Command_Build constructor. - * - * @access public - */ - function PEAR_Command_Build(&$ui, &$config) - { - parent::PEAR_Command_Common($ui, $config); - } - - function doBuild($command, $options, $params) - { - require_once 'PEAR/Builder.php'; - if (sizeof($params) < 1) { - $params[0] = 'package.xml'; - } - - $builder = &new PEAR_Builder($this->ui); - $this->debug = $this->config->get('verbose'); - $err = $builder->build($params[0], array(&$this, 'buildCallback')); - if (PEAR::isError($err)) { - return $err; - } - - return true; - } - - function buildCallback($what, $data) - { - if (($what == 'cmdoutput' && $this->debug > 1) || - ($what == 'output' && $this->debug > 0)) { - $this->ui->outputData(rtrim($data), 'build'); - } - } -}PEAR-1.8.0/PEAR/Command/Channels.xml100777 764 764 10032 100777 11715 +PEAR-1.9.0/PEAR/Command/Build.php100664 764 764 4453 100664 11171 + * @author Tomas V.V.Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Build.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for building extensions. + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V.V.Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Command_Build extends PEAR_Command_Common +{ + var $commands = array( + 'build' => array( + 'summary' => 'Build an Extension From C Source', + 'function' => 'doBuild', + 'shortcut' => 'b', + 'options' => array(), + 'doc' => '[package.xml] +Builds one or more extensions contained in a package.' + ), + ); + + /** + * PEAR_Command_Build constructor. + * + * @access public + */ + function PEAR_Command_Build(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + function doBuild($command, $options, $params) + { + require_once 'PEAR/Builder.php'; + if (sizeof($params) < 1) { + $params[0] = 'package.xml'; + } + + $builder = &new PEAR_Builder($this->ui); + $this->debug = $this->config->get('verbose'); + $err = $builder->build($params[0], array(&$this, 'buildCallback')); + if (PEAR::isError($err)) { + return $err; + } + + return true; + } + + function buildCallback($what, $data) + { + if (($what == 'cmdoutput' && $this->debug > 1) || + ($what == 'output' && $this->debug > 0)) { + $this->ui->outputData(rtrim($data), 'build'); + } + } +}PEAR-1.9.0/PEAR/Command/Channels.xml100664 764 764 10172 100664 11711 List Available Channels doList @@ -8590,12 +8784,13 @@ operations on the remote server. doLogout clo - -Logs out from the remote server. This command does not actually -connect to the remote server, it only deletes the stored username and -password from your user configuration. + <channel name> +Logs out from a remote channel server. If <channel name> is not supplied, +the default channel is used. This command does not actually connect to the +remote server, it only deletes the stored username and password from your user +configuration. -PEAR-1.8.0/PEAR/Command/Channels.php100664 764 764 100632 100664 11720 PEAR-1.9.0/PEAR/Command/Channels.php100664 764 764 101377 100664 11730 * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Channels.php,v 1.64 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Channels.php 287561 2009-08-21 22:42:58Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -8629,7 +8824,7 @@ define('PEAR_COMMAND_CHANNELS_CHANNEL_EXISTS', -500); * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -8751,10 +8946,11 @@ operations on the remote server.', 'shortcut' => 'clo', 'function' => 'doLogout', 'options' => array(), - 'doc' => ' -Logs out from the remote server. This command does not actually -connect to the remote server, it only deletes the stored username and -password from your user configuration.', + 'doc' => ' +Logs out from a remote channel server. If is not supplied, +the default channel is used. This command does not actually connect to the +remote server, it only deletes the stored username and password from your user +configuration.', ), ); @@ -8782,11 +8978,12 @@ password from your user configuration.', $data = array( 'caption' => 'Registered Channels:', 'border' => true, - 'headline' => array('Channel', 'Summary') + 'headline' => array('Channel', 'Alias', 'Summary') ); foreach ($registered as $channel) { $data['data'][] = array($channel->getName(), - $channel->getSummary()); + $channel->getAlias(), + $channel->getSummary()); } if (count($registered) === 0) { @@ -9269,7 +9466,7 @@ password from your user configuration.', return $this->raiseError('No channel alias specified'); } - if (count($params) !== 2) { + if (count($params) !== 2 || (!empty($params[1]) && $params[1]{0} == '-')) { return $this->raiseError( 'Invalid format, correct is: channel-alias channel alias'); } @@ -9459,20 +9656,23 @@ password from your user configuration.', function doLogout($command, $options, $params) { $reg = &$this->config->getRegistry(); - $channel = $this->config->get('default_channel'); + + // If a parameter is supplied, use that as the channel to log in to + $channel = isset($params[0]) ? $params[0] : $this->config->get('default_channel'); + $chan = $reg->getChannel($channel); if (PEAR::isError($chan)) { return $this->raiseError($chan); } - $server = $this->config->get('preferred_mirror'); + $server = $this->config->get('preferred_mirror', null, $channel); $this->ui->outputData("Logging out from $server.", $command); - $this->config->remove('username'); - $this->config->remove('password'); + $this->config->remove('username', 'user', $channel); + $this->config->remove('password', 'user', $channel); $this->config->store(); return true; } -}PEAR-1.8.0/PEAR/Command/Common.php100664 764 764 20147 100664 11377 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.39 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Common.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -9503,7 +9703,7 @@ require_once 'PEAR.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -9744,7 +9944,7 @@ class PEAR_Command_Common extends PEAR return $this->$func($command, $options, $params); } -}PEAR-1.8.0/PEAR/Command/Config.xml100777 764 764 6466 100777 11367 +}PEAR-1.9.0/PEAR/Command/Config.xml100664 764 764 6466 100664 11356 Show All Settings doConfigShow @@ -9835,7 +10035,7 @@ PEAR installation (using the --remoteconfig option of install, upgrade, and uninstall). -PEAR-1.8.0/PEAR/Command/Config.php100664 764 764 35663 100664 11365 PEAR-1.9.0/PEAR/Command/Config.php100664 764 764 36076 100664 11365 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Config.php,v 1.61 2009/03/26 21:36:32 dufuz Exp $ + * @version CVS: $Id: Config.php 287554 2009-08-21 21:16:25Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -9866,7 +10066,7 @@ require_once 'PEAR/Command/Common.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -10079,7 +10279,12 @@ and uninstall). return $this->raiseError('Channel "' . $params[1] . '" does not exist'); } - if ($params[0] == 'preferred_mirror' && !$reg->channelExists($params[1])) { + if ($params[0] == 'preferred_mirror' + && ( + !$reg->mirrorExists($channel, $params[1]) && + (!$reg->channelExists($params[1]) || $channel != $params[1]) + ) + ) { $msg = 'Channel Mirror "' . $params[1] . '" does not exist'; $msg .= ' in your registry for channel "' . $channel . '".'; $msg .= "\n" . 'Attempt to run "pear channel-update ' . $channel .'"'; @@ -10242,7 +10447,7 @@ and uninstall). return false; } -}PEAR-1.8.0/PEAR/Command/Install.xml100775 764 764 20576 100775 11602 +}PEAR-1.9.0/PEAR/Command/Install.xml100664 764 764 20576 100664 11575 Install Package doInstall @@ -10474,7 +10679,7 @@ more stable. DIR - f + force install even if there were errors @@ -10499,7 +10704,7 @@ channel not in your default channel ({config default_channel}) DIR - + f Force the unpacking even if there were errors in the package @@ -10517,7 +10722,7 @@ package if needed. Run post-installation scripts in package <package>, if any exist. -PEAR-1.8.0/PEAR/Command/Install.php100664 764 764 142453 100664 11602 PEAR-1.9.0/PEAR/Command/Install.php100664 764 764 143164 100664 11603 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Install.php,v 1.153 2009/03/08 04:01:11 dufuz Exp $ + * @version CVS: $Id: Install.php 287477 2009-08-19 14:19:43Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -10549,7 +10754,7 @@ require_once 'PEAR/Command/Common.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -11082,8 +11287,7 @@ Run post-installation scripts in package , if any exist. } } - $abstractpackages = array(); - $otherpackages = array(); + $abstractpackages = $otherpackages = array(); // parse params PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); @@ -11177,7 +11381,7 @@ Run post-installation scripts in package , if any exist. } $this->downloader = &$this->getDownloader($this->ui, $options, $this->config); - $errors = $downloaded = $binaries = array(); + $errors = $downloaded = $binaries = array(); $downloaded = &$this->downloader->download($packages); if (PEAR::isError($downloaded)) { return $this->raiseError($downloaded); @@ -11222,8 +11426,7 @@ Run post-installation scripts in package , if any exist. return true; } - $extrainfo = array(); - $binaries = array(); + $binaries = $extrainfo = array(); foreach ($downloaded as $param) { PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); $info = $this->installer->install($param, $options); @@ -11722,10 +11925,14 @@ Run post-installation scripts in package , if any exist. return $this->raiseError($chan); } + $base2 = false; $preferred_mirror = $this->config->get('preferred_mirror', null, $channel); if ($chan->supportsREST($preferred_mirror) && - $base = $chan->getBaseURL('REST1.0', $preferred_mirror)) - { + ( + //($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) || + ($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) + ) + ) { $dorest = true; } @@ -11737,10 +11944,15 @@ Run post-installation scripts in package , if any exist. } if ($dorest) { - $rest = &$this->config->getREST('1.0', array()); - $installed = array_flip($reg->listPackages($channel)); + if ($base2) { + $rest = &$this->config->getREST('1.4', array()); + $base = $base2; + } else { + $rest = &$this->config->getREST('1.0', array()); + } - $latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg); + $installed = array_flip($reg->listPackages($channel)); + $latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg); } PEAR::staticPopErrorHandling(); @@ -11775,7 +11987,7 @@ Run post-installation scripts in package , if any exist. return $ret; } -}PEAR-1.8.0/PEAR/Command/Mirror.xml100777 764 764 1151 100777 11416 +}PEAR-1.9.0/PEAR/Command/Mirror.xml100664 764 764 1151 100664 11405 Downloads each available package from the default channel doDownloadAll @@ -11792,7 +12004,7 @@ Requests a list of available packages from the default channel ({config default_ and downloads them to current working directory. Note: only packages within preferred_state ({config preferred_state}) will be downloaded -PEAR-1.8.0/PEAR/Command/Mirror.php100664 764 764 10765 100664 11426 PEAR-1.9.0/PEAR/Command/Mirror.php100664 764 764 10762 100664 11424 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Mirror.php,v 1.23 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Mirror.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.2.0 */ @@ -11821,7 +12033,7 @@ require_once 'PEAR/Command/Common.php'; * @author Alexander Merz * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.2.0 */ @@ -11930,7 +12142,7 @@ packages within preferred_state ({config preferred_state}) will be downloaded' return true; } -}PEAR-1.8.0/PEAR/Command/Package.xml100777 764 764 13665 100777 11534 +}PEAR-1.9.0/PEAR/Command/Package.xml100664 764 764 16066 100664 11521 Build Package doPackage @@ -11945,13 +12157,13 @@ packages within preferred_state ({config preferred_state}) will be downloaded' Print the name of the packaged file. - [descfile] [descfile2] -Creates a PEAR package from its description file (usually called -package.xml). If a second packagefile is passed in, then -the packager will check to make sure that one is a package.xml -version 1.0, and the other is a package.xml version 2.0. The -package.xml version 1.0 will be saved as "package.xml" in the archive, -and the other as "package2.xml" in the archive" + [descfile] [descfile2] +Creates a PEAR package from its description file (usually called +package.xml). If a second packagefile is passed in, then +the packager will check to make sure that one is a package.xml +version 1.0, and the other is a package.xml version 2.0. The +package.xml version 1.0 will be saved as "package.xml" in the archive, +and the other as "package2.xml" in the archive" @@ -11959,7 +12171,7 @@ and the other as "package2.xml" in the archive" doPackageValidate pv - + @@ -12019,13 +12231,46 @@ and the other as "package2.xml" in the archive" Don't do anything, just pretend - <package.xml> -Compares all the files in a package. Without any options, this -command will compare the current code with the last checked-in code. -Using the -r or -R option you may compare the current code with that -of a specific release. + <package.xml> +Compares all the files in a package. Without any options, this +command will compare the current code with the last checked-in code. +Using the -r or -R option you may compare the current code with that +of a specific release. + + Set SVN Release Tag + doSvnTag + sv + + + q + Be quiet + + + F + Move (slide) tag if it exists + + + d + Remove tag + + + n + Don't do anything, just pretend + + + <package.xml> [files...] + Sets a SVN tag on all files in a package. Use this command after you have + packaged a distribution tarball with the "package" command to tag what + revisions of what files were in that release. If need to fix something + after running cvstag once, but before the tarball is released to the public, + use the "slide" option to move the release tag. + + to include files (such as a second package.xml, or tests not included in the + release), pass them as additional parameters. + + Set CVS Release Tag doCvsTag @@ -12052,15 +12297,15 @@ of a specific release. Don't do anything, just pretend - <package.xml> [files...] -Sets a CVS tag on all files in a package. Use this command after you have -packaged a distribution tarball with the "package" command to tag what -revisions of what files were in that release. If need to fix something -after running cvstag once, but before the tarball is released to the public, -use the "slide" option to move the release tag. - -to include files (such as a second package.xml, or tests not included in the -release), pass them as additional parameters. + <package.xml> [files...] +Sets a CVS tag on all files in a package. Use this command after you have +packaged a distribution tarball with the "package" command to tag what +revisions of what files were in that release. If need to fix something +after running cvstag once, but before the tarball is released to the public, +use the "slide" option to move the release tag. + +to include files (such as a second package.xml, or tests not included in the +release), pass them as additional parameters. @@ -12068,8 +12313,9 @@ release), pass them as additional parameters. doPackageDependencies pd - -List all dependencies the package has. + <package-file> or <package.xml> or <install-package-name> +List all dependencies the package has. +Can take a tgz / tar file, package.xml or a package name of an installed package. Sign a package distribution file @@ -12081,7 +12327,7 @@ List all dependencies the package has. Display GnuPG output - <package-file> + <package-file> Signs a package distribution (.tar or .tgz) file with GnuPG. @@ -12096,22 +12342,22 @@ Signs a package distribution (.tar or .tgz) file with GnuPG. p - Use FORMAT as format string for RPM package name, %s is replaced + Use FORMAT as format string for RPM package name, %s is replaced by the PEAR package name, defaults to "PEAR::%s". FORMAT - <package-file> - -Creates an RPM .spec file for wrapping a PEAR package inside an RPM -package. Intended to be used from the SPECS directory, with the PEAR -package tarball in the SOURCES directory: - -$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz -Wrote RPM spec file PEAR::Net_Geo-1.0.spec -$ rpm -bb PEAR::Net_Socket-1.0.spec -... -Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm + <package-file> + +Creates an RPM .spec file for wrapping a PEAR package inside an RPM +package. Intended to be used from the SPECS directory, with the PEAR +package tarball in the SOURCES directory: + +$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz +Wrote RPM spec file PEAR::Net_Geo-1.0.spec +$ rpm -bb PEAR::Net_Socket-1.0.spec +... +Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm @@ -12124,929 +12370,31 @@ Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm do not beautify the filelist. - [descfile] [descfile2] -Converts a package.xml in 1.0 format into a package.xml -in 2.0 format. The new file will be named package2.xml by default, -and package.xml will be used as the old file by default. -This is not the most intelligent conversion, and should only be -used for automated conversion or learning the format. + [descfile] [descfile2] +Converts a package.xml in 1.0 format into a package.xml +in 2.0 format. The new file will be named package2.xml by default, +and package.xml will be used as the old file by default. +This is not the most intelligent conversion, and should only be +used for automated conversion or learning the format. -PEAR-1.8.0/PEAR/Command/Package.php100664 764 764 76030 100664 11504 - * @author Martin Jansen - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Package.php,v 1.133 2009/03/25 02:15:57 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ - -/** - * base class - */ -require_once 'PEAR/Command/Common.php'; - -/** - * PEAR commands for login/logout - * - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Martin Jansen - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: @package_version@ - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 - */ - -class PEAR_Command_Package extends PEAR_Command_Common -{ - var $commands = array( - 'package' => array( - 'summary' => 'Build Package', - 'function' => 'doPackage', - 'shortcut' => 'p', - 'options' => array( - 'nocompress' => array( - 'shortopt' => 'Z', - 'doc' => 'Do not gzip the package file' - ), - 'showname' => array( - 'shortopt' => 'n', - 'doc' => 'Print the name of the packaged file.', - ), - ), - 'doc' => '[descfile] [descfile2] -Creates a PEAR package from its description file (usually called -package.xml). If a second packagefile is passed in, then -the packager will check to make sure that one is a package.xml -version 1.0, and the other is a package.xml version 2.0. The -package.xml version 1.0 will be saved as "package.xml" in the archive, -and the other as "package2.xml" in the archive" -' - ), - 'package-validate' => array( - 'summary' => 'Validate Package Consistency', - 'function' => 'doPackageValidate', - 'shortcut' => 'pv', - 'options' => array(), - 'doc' => ' -', - ), - 'cvsdiff' => array( - 'summary' => 'Run a "cvs diff" for all files in a package', - 'function' => 'doCvsDiff', - 'shortcut' => 'cd', - 'options' => array( - 'quiet' => array( - 'shortopt' => 'q', - 'doc' => 'Be quiet', - ), - 'reallyquiet' => array( - 'shortopt' => 'Q', - 'doc' => 'Be really quiet', - ), - 'date' => array( - 'shortopt' => 'D', - 'doc' => 'Diff against revision of DATE', - 'arg' => 'DATE', - ), - 'release' => array( - 'shortopt' => 'R', - 'doc' => 'Diff against tag for package release REL', - 'arg' => 'REL', - ), - 'revision' => array( - 'shortopt' => 'r', - 'doc' => 'Diff against revision REV', - 'arg' => 'REV', - ), - 'context' => array( - 'shortopt' => 'c', - 'doc' => 'Generate context diff', - ), - 'unified' => array( - 'shortopt' => 'u', - 'doc' => 'Generate unified diff', - ), - 'ignore-case' => array( - 'shortopt' => 'i', - 'doc' => 'Ignore case, consider upper- and lower-case letters equivalent', - ), - 'ignore-whitespace' => array( - 'shortopt' => 'b', - 'doc' => 'Ignore changes in amount of white space', - ), - 'ignore-blank-lines' => array( - 'shortopt' => 'B', - 'doc' => 'Ignore changes that insert or delete blank lines', - ), - 'brief' => array( - 'doc' => 'Report only whether the files differ, no details', - ), - 'dry-run' => array( - 'shortopt' => 'n', - 'doc' => 'Don\'t do anything, just pretend', - ), - ), - 'doc' => ' -Compares all the files in a package. Without any options, this -command will compare the current code with the last checked-in code. -Using the -r or -R option you may compare the current code with that -of a specific release. -', - ), - 'cvstag' => array( - 'summary' => 'Set CVS Release Tag', - 'function' => 'doCvsTag', - 'shortcut' => 'ct', - 'options' => array( - 'quiet' => array( - 'shortopt' => 'q', - 'doc' => 'Be quiet', - ), - 'reallyquiet' => array( - 'shortopt' => 'Q', - 'doc' => 'Be really quiet', - ), - 'slide' => array( - 'shortopt' => 'F', - 'doc' => 'Move (slide) tag if it exists', - ), - 'delete' => array( - 'shortopt' => 'd', - 'doc' => 'Remove tag', - ), - 'dry-run' => array( - 'shortopt' => 'n', - 'doc' => 'Don\'t do anything, just pretend', - ), - ), - 'doc' => ' [files...] -Sets a CVS tag on all files in a package. Use this command after you have -packaged a distribution tarball with the "package" command to tag what -revisions of what files were in that release. If need to fix something -after running cvstag once, but before the tarball is released to the public, -use the "slide" option to move the release tag. - -to include files (such as a second package.xml, or tests not included in the -release), pass them as additional parameters. -', - ), - 'package-dependencies' => array( - 'summary' => 'Show package dependencies', - 'function' => 'doPackageDependencies', - 'shortcut' => 'pd', - 'options' => array(), - 'doc' => ' -List all dependencies the package has.' - ), - 'sign' => array( - 'summary' => 'Sign a package distribution file', - 'function' => 'doSign', - 'shortcut' => 'si', - 'options' => array( - 'verbose' => array( - 'shortopt' => 'v', - 'doc' => 'Display GnuPG output', - ), - ), - 'doc' => ' -Signs a package distribution (.tar or .tgz) file with GnuPG.', - ), - 'makerpm' => array( - 'summary' => 'Builds an RPM spec file from a PEAR package', - 'function' => 'doMakeRPM', - 'shortcut' => 'rpm', - 'options' => array( - 'spec-template' => array( - 'shortopt' => 't', - 'arg' => 'FILE', - 'doc' => 'Use FILE as RPM spec file template' - ), - 'rpm-pkgname' => array( - 'shortopt' => 'p', - 'arg' => 'FORMAT', - 'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced -by the PEAR package name, defaults to "PEAR::%s".', - ), - ), - 'doc' => ' - -Creates an RPM .spec file for wrapping a PEAR package inside an RPM -package. Intended to be used from the SPECS directory, with the PEAR -package tarball in the SOURCES directory: - -$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz -Wrote RPM spec file PEAR::Net_Geo-1.0.spec -$ rpm -bb PEAR::Net_Socket-1.0.spec -... -Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm -', - ), - 'convert' => array( - 'summary' => 'Convert a package.xml 1.0 to package.xml 2.0 format', - 'function' => 'doConvert', - 'shortcut' => 'c2', - 'options' => array( - 'flat' => array( - 'shortopt' => 'f', - 'doc' => 'do not beautify the filelist.', - ), - ), - 'doc' => '[descfile] [descfile2] -Converts a package.xml in 1.0 format into a package.xml -in 2.0 format. The new file will be named package2.xml by default, -and package.xml will be used as the old file by default. -This is not the most intelligent conversion, and should only be -used for automated conversion or learning the format. -' - ), - ); - - var $output; - - /** - * PEAR_Command_Package constructor. - * - * @access public - */ - function PEAR_Command_Package(&$ui, &$config) - { - parent::PEAR_Command_Common($ui, $config); - } - - function _displayValidationResults($err, $warn, $strict = false) - { - foreach ($err as $e) { - $this->output .= "Error: $e\n"; - } - foreach ($warn as $w) { - $this->output .= "Warning: $w\n"; - } - $this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n", - sizeof($err), sizeof($warn)); - if ($strict && count($err) > 0) { - $this->output .= "Fix these errors and try again."; - return false; - } - return true; - } - - function &getPackager() - { - if (!class_exists('PEAR_Packager')) { - require_once 'PEAR/Packager.php'; - } - $a = &new PEAR_Packager; - return $a; - } - - function &getPackageFile($config, $debug = false, $tmpdir = null) - { - if (!class_exists('PEAR_Common')) { - require_once 'PEAR/Common.php'; - } - if (!class_exists('PEAR_PackageFile')) { - require_once 'PEAR/PackageFile.php'; - } - $a = &new PEAR_PackageFile($config, $debug, $tmpdir); - $common = new PEAR_Common; - $common->ui = $this->ui; - $a->setLogger($common); - return $a; - } - - function doPackage($command, $options, $params) - { - $this->output = ''; - $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml'; - $pkg2 = isset($params[1]) ? $params[1] : null; - if (!$pkg2 && !isset($params[0]) && file_exists('package2.xml')) { - $pkg2 = 'package2.xml'; - } - - $packager = &$this->getPackager(); - $compress = empty($options['nocompress']) ? true : false; - $result = $packager->package($pkginfofile, $compress, $pkg2); - if (PEAR::isError($result)) { - return $this->raiseError($result); - } - - // Don't want output, only the package file name just created - if (isset($options['showname'])) { - $this->output = $result; - } - - if ($this->output) { - $this->ui->outputData($this->output, $command); - } - - return true; - } - - function doPackageValidate($command, $options, $params) - { - $this->output = ''; - if (count($params) < 1) { - $params[0] = 'package.xml'; - } - - $obj = &$this->getPackageFile($this->config, $this->_debug); - $obj->rawReturn(); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); - if (PEAR::isError($info)) { - $info = $obj->fromPackageFile($params[0], PEAR_VALIDATE_NORMAL); - } else { - $archive = $info->getArchiveFile(); - $tar = &new Archive_Tar($archive); - $tar->extract(dirname($info->getPackageFile())); - $info->setPackageFile(dirname($info->getPackageFile()) . DIRECTORY_SEPARATOR . - $info->getPackage() . '-' . $info->getVersion() . DIRECTORY_SEPARATOR . - basename($info->getPackageFile())); - } - - PEAR::staticPopErrorHandling(); - if (PEAR::isError($info)) { - return $this->raiseError($info); - } - - $valid = false; - if ($info->getPackagexmlVersion() == '2.0') { - if ($valid = $info->validate(PEAR_VALIDATE_NORMAL)) { - $info->flattenFileList(); - $valid = $info->validate(PEAR_VALIDATE_PACKAGING); - } - } else { - $valid = $info->validate(PEAR_VALIDATE_PACKAGING); - } - - $err = $warn = array(); - if ($errors = $info->getValidationWarnings()) { - foreach ($errors as $error) { - if ($error['level'] == 'warning') { - $warn[] = $error['message']; - } else { - $err[] = $error['message']; - } - } - } - - $this->_displayValidationResults($err, $warn); - $this->ui->outputData($this->output, $command); - return true; - } - - function doCvsTag($command, $options, $params) - { - $this->output = ''; - $_cmd = $command; - if (count($params) < 1) { - $help = $this->getHelp($command); - return $this->raiseError("$command: missing parameter: $help[0]"); - } - - $packageFile = realpath($params[0]); - $obj = &$this->getPackageFile($this->config, $this->_debug); - $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($info)) { - return $this->raiseError($info); - } - - $err = $warn = array(); - if (!$info->validate()) { - foreach ($info->getValidationWarnings() as $error) { - if ($error['level'] == 'warning') { - $warn[] = $error['message']; - } else { - $err[] = $error['message']; - } - } - } - - if (!$this->_displayValidationResults($err, $warn, true)) { - $this->ui->outputData($this->output, $command); - return $this->raiseError('CVS tag failed'); - } - - $version = $info->getVersion(); - $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version); - $cvstag = "RELEASE_$cvsversion"; - $files = array_keys($info->getFilelist()); - $command = 'cvs'; - if (isset($options['quiet'])) { - $command .= ' -q'; - } - - if (isset($options['reallyquiet'])) { - $command .= ' -Q'; - } - - $command .= ' tag'; - if (isset($options['slide'])) { - $command .= ' -F'; - } - - if (isset($options['delete'])) { - $command .= ' -d'; - } - - $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]); - array_shift($params); - if (count($params)) { - // add in additional files to be tagged - $files = array_merge($files, $params); - } - - $dir = dirname($packageFile); - $dir = substr($dir, strrpos($dir, '/') + 1); - foreach ($files as $file) { - if (!file_exists($file)) { - $file = $dir . DIRECTORY_SEPARATOR . $file; - } - $command .= ' ' . escapeshellarg($file); - } - - if ($this->config->get('verbose') > 1) { - $this->output .= "+ $command\n"; - } - - $this->output .= "+ $command\n"; - if (empty($options['dry-run'])) { - $fp = popen($command, "r"); - while ($line = fgets($fp, 1024)) { - $this->output .= rtrim($line)."\n"; - } - pclose($fp); - } - - $this->ui->outputData($this->output, $_cmd); - return true; - } - - function doCvsDiff($command, $options, $params) - { - $this->output = ''; - if (sizeof($params) < 1) { - $help = $this->getHelp($command); - return $this->raiseError("$command: missing parameter: $help[0]"); - } - - $file = realpath($params[0]); - $obj = &$this->getPackageFile($this->config, $this->_debug); - $info = $obj->fromAnyFile($file, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($info)) { - return $this->raiseError($info); - } - - $err = $warn = array(); - if (!$info->validate()) { - foreach ($info->getValidationWarnings() as $error) { - if ($error['level'] == 'warning') { - $warn[] = $error['message']; - } else { - $err[] = $error['message']; - } - } - } - - if (!$this->_displayValidationResults($err, $warn, true)) { - $this->ui->outputData($this->output, $command); - return $this->raiseError('CVS diff failed'); - } - - $info1 = $info->getFilelist(); - $files = $info1; - $cmd = "cvs"; - if (isset($options['quiet'])) { - $cmd .= ' -q'; - unset($options['quiet']); - } - - if (isset($options['reallyquiet'])) { - $cmd .= ' -Q'; - unset($options['reallyquiet']); - } - - if (isset($options['release'])) { - $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']); - $cvstag = "RELEASE_$cvsversion"; - $options['revision'] = $cvstag; - unset($options['release']); - } - - $execute = true; - if (isset($options['dry-run'])) { - $execute = false; - unset($options['dry-run']); - } - - $cmd .= ' diff'; - // the rest of the options are passed right on to "cvs diff" - foreach ($options as $option => $optarg) { - $arg = $short = false; - if (isset($this->commands[$command]['options'][$option])) { - $arg = $this->commands[$command]['options'][$option]['arg']; - $short = $this->commands[$command]['options'][$option]['shortopt']; - } - $cmd .= $short ? " -$short" : " --$option"; - if ($arg && $optarg) { - $cmd .= ($short ? '' : '=') . escapeshellarg($optarg); - } - } - - foreach ($files as $file) { - $cmd .= ' ' . escapeshellarg($file['name']); - } - - if ($this->config->get('verbose') > 1) { - $this->output .= "+ $cmd\n"; - } - - if ($execute) { - $fp = popen($cmd, "r"); - while ($line = fgets($fp, 1024)) { - $this->output .= rtrim($line)."\n"; - } - pclose($fp); - } - - $this->ui->outputData($this->output, $command); - return true; - } - - function doPackageDependencies($command, $options, $params) - { - // $params[0] -> the PEAR package to list its information - if (count($params) !== 1) { - return $this->raiseError("bad parameter(s), try \"help $command\""); - } - - $obj = &$this->getPackageFile($this->config, $this->_debug); - $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); - if (PEAR::isError($info)) { - return $this->raiseError($info); - } - - $deps = $info->getDeps(); - if (is_array($deps)) { - if ($info->getPackagexmlVersion() == '1.0') { - $data = array( - 'caption' => 'Dependencies for pear/' . $info->getPackage(), - 'border' => true, - 'headline' => array("Required?", "Type", "Name", "Relation", "Version"), - ); - - foreach ($deps as $d) { - if (isset($d['optional'])) { - if ($d['optional'] == 'yes') { - $req = 'No'; - } else { - $req = 'Yes'; - } - } else { - $req = 'Yes'; - } - - if (isset($this->_deps_rel_trans[$d['rel']])) { - $rel = $this->_deps_rel_trans[$d['rel']]; - } else { - $rel = $d['rel']; - } - - if (isset($this->_deps_type_trans[$d['type']])) { - $type = ucfirst($this->_deps_type_trans[$d['type']]); - } else { - $type = $d['type']; - } - - if (isset($d['name'])) { - $name = $d['name']; - } else { - $name = ''; - } - - if (isset($d['version'])) { - $version = $d['version']; - } else { - $version = ''; - } - - $data['data'][] = array($req, $type, $name, $rel, $version); - } - } else { // package.xml 2.0 dependencies display - require_once 'PEAR/Dependency2.php'; - $deps = $info->getDependencies(); - $reg = &$this->config->getRegistry(); - if (is_array($deps)) { - $d = new PEAR_Dependency2($this->config, array(), ''); - $data = array( - 'caption' => 'Dependencies for ' . $info->getPackage(), - 'border' => true, - 'headline' => array("Required?", "Type", "Name", 'Versioning', 'Group'), - ); - foreach ($deps as $type => $subd) { - $req = ($type == 'required') ? 'Yes' : 'No'; - if ($type == 'group') { - $group = $subd['attribs']['name']; - } else { - $group = ''; - } - - if (!isset($subd[0])) { - $subd = array($subd); - } - - foreach ($subd as $groupa) { - foreach ($groupa as $deptype => $depinfo) { - if ($deptype == 'attribs') { - continue; - } - - if ($deptype == 'pearinstaller') { - $deptype = 'pear Installer'; - } - - if (!isset($depinfo[0])) { - $depinfo = array($depinfo); - } - - foreach ($depinfo as $inf) { - $name = ''; - if (isset($inf['channel'])) { - $alias = $reg->channelAlias($inf['channel']); - if (!$alias) { - $alias = '(channel?) ' .$inf['channel']; - } - $name = $alias . '/'; - - } - if (isset($inf['name'])) { - $name .= $inf['name']; - } elseif (isset($inf['pattern'])) { - $name .= $inf['pattern']; - } else { - $name .= ''; - } - - if (isset($inf['uri'])) { - $name .= ' [' . $inf['uri'] . ']'; - } - - if (isset($inf['conflicts'])) { - $ver = 'conflicts'; - } else { - $ver = $d->_getExtraString($inf); - } - - $data['data'][] = array($req, ucfirst($deptype), $name, - $ver, $group); - } - } - } - } - } - } - - $this->ui->outputData($data, $command); - return true; - } - - // Fallback - $this->ui->outputData("This package does not have any dependencies.", $command); - } - - function doSign($command, $options, $params) - { - // should move most of this code into PEAR_Packager - // so it'll be easy to implement "pear package --sign" - if (count($params) !== 1) { - return $this->raiseError("bad parameter(s), try \"help $command\""); - } - - require_once 'System.php'; - require_once 'Archive/Tar.php'; - - if (!file_exists($params[0])) { - return $this->raiseError("file does not exist: $params[0]"); - } - - $obj = $this->getPackageFile($this->config, $this->_debug); - $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); - if (PEAR::isError($info)) { - return $this->raiseError($info); - } - - $tar = new Archive_Tar($params[0]); - $tmpdir = System::mktemp('-d pearsign'); - if (!$tar->extractList('package2.xml package.xml package.sig', $tmpdir)) { - return $this->raiseError("failed to extract tar file"); - } - - if (file_exists("$tmpdir/package.sig")) { - return $this->raiseError("package already signed"); - } - - $packagexml = 'package.xml'; - if (file_exists("$tmpdir/package2.xml")) { - $packagexml = 'package2.xml'; - } - - if (file_exists("$tmpdir/package.sig")) { - unlink("$tmpdir/package.sig"); - } - - if (!file_exists("$tmpdir/$packagexml")) { - return $this->raiseError("Extracted file $tmpdir/$packagexml not found."); - } - - $input = $this->ui->userDialog($command, - array('GnuPG Passphrase'), - array('password')); - if (!isset($input[0])) { - //use empty passphrase - $input[0] = ''; - } - - $devnull = (isset($options['verbose'])) ? '' : ' 2>/dev/null'; - $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml" . $devnull, "w"); - if (!$gpg) { - return $this->raiseError("gpg command failed"); - } - - fwrite($gpg, "$input[0]\n"); - if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) { - return $this->raiseError("gpg sign failed"); - } - - if (!$tar->addModify("$tmpdir/package.sig", '', $tmpdir)) { - return $this->raiseError('failed adding signature to file'); - } - - $this->ui->outputData("Package signed.", $command); - return true; - } - - /** - * For unit testing purposes - */ - function &getInstaller(&$ui) - { - if (!class_exists('PEAR_Installer')) { - require_once 'PEAR/Installer.php'; - } - $a = &new PEAR_Installer($ui); - return $a; - } - - /** - * For unit testing purposes - */ - function &getCommandPackaging(&$ui, &$config) - { - if (!class_exists('PEAR_Command_Packaging')) { - if ($fp = @fopen('PEAR/Command/Packaging.php', 'r', true)) { - fclose($fp); - include_once 'PEAR/Command/Packaging.php'; - } - } - - if (class_exists('PEAR_Command_Packaging')) { - $a = &new PEAR_Command_Packaging($ui, $config); - } else { - $a = null; - } - - return $a; - } - - function doMakeRPM($command, $options, $params) - { - - // Check to see if PEAR_Command_Packaging is installed, and - // transparently switch to use the "make-rpm-spec" command from it - // instead, if it does. Otherwise, continue to use the old version - // of "makerpm" supplied with this package (PEAR). - $packaging_cmd = $this->getCommandPackaging($this->ui, $this->config); - if ($packaging_cmd !== null) { - $this->ui->outputData('PEAR_Command_Packaging is installed; using '. - 'newer "make-rpm-spec" command instead'); - return $packaging_cmd->run('make-rpm-spec', $options, $params); - } - - $this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '. - 'improved version is available via "pear make-rpm-spec", which '. - 'is available by installing PEAR_Command_Packaging'); - return true; - } - - function doConvert($command, $options, $params) - { - $packagexml = isset($params[0]) ? $params[0] : 'package.xml'; - $newpackagexml = isset($params[1]) ? $params[1] : dirname($packagexml) . - DIRECTORY_SEPARATOR . 'package2.xml'; - $pkg = &$this->getPackageFile($this->config, $this->_debug); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $pf = $pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($pf)) { - if (is_array($pf->getUserInfo())) { - foreach ($pf->getUserInfo() as $warning) { - $this->ui->outputData($warning['message']); - } - } - return $this->raiseError($pf); - } - - if (is_a($pf, 'PEAR_PackageFile_v2')) { - $this->ui->outputData($packagexml . ' is already a package.xml version 2.0'); - return true; - } - - $gen = &$pf->getDefaultGenerator(); - $newpf = &$gen->toV2(); - $newpf->setPackagefile($newpackagexml); - $gen = &$newpf->getDefaultGenerator(); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL); - $saved = $gen->toPackageFile(dirname($newpackagexml), $state, basename($newpackagexml)); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($saved)) { - if (is_array($saved->getUserInfo())) { - foreach ($saved->getUserInfo() as $warning) { - $this->ui->outputData($warning['message']); - } - } - - $this->ui->outputData($saved->getMessage()); - return true; - } - - $this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"'); - return true; - } -}PEAR-1.8.0/PEAR/Command/Pickle.xml100777 764 764 2233 100777 11355 - - Build PECL Package - doPackage - pi - - - Z - Do not gzip the package file - - - n - Print the name of the packaged file. - - - [descfile] -Creates a PECL package from its package2.xml file. - -An automatic conversion will be made to a package.xml 1.0 and written out to -disk in the current directory as "package.xml". Note that -only simple package.xml 2.0 will be converted. package.xml 2.0 with: - - - dependency types other than required/optional PECL package/ext/php/pearinstaller - - more than one extsrcrelease or zendextsrcrelease - - zendextbinrelease, extbinrelease, phprelease, or bundle release type - - dependency groups - - ignore tags in release filelist - - tasks other than replace - - custom roles - -will cause pickle to fail, and output an error message. If your package2.xml -uses any of these features, you are best off using PEAR_PackageFileManager to -generate both package.xml. - - -PEAR-1.8.0/PEAR/Command/Pickle.php100664 764 764 37212 100664 11357 PEAR-1.9.0/PEAR/Command/Package.php100664 764 764 114657 100664 11535 + * @author Martin Jansen * @author Greg Beaver - * @copyright 2005-2009 The Authors + * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Pickle.php,v 1.13 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Package.php 287559 2009-08-21 22:33:10Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.1 + * @since File available since Release 0.1 */ /** @@ -13059,21 +12407,23 @@ require_once 'PEAR/Command/Common.php'; * * @category pear * @package PEAR + * @author Stig Bakken + * @author Martin Jansen * @author Greg Beaver - * @copyright 2005-2009 The Authors + * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: @package_version@ * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.1 + * @since Class available since Release 0.1 */ -class PEAR_Command_Pickle extends PEAR_Command_Common +class PEAR_Command_Package extends PEAR_Command_Common { var $commands = array( - 'pickle' => array( - 'summary' => 'Build PECL Package', + 'package' => array( + 'summary' => 'Build Package', 'function' => 'doPackage', - 'shortcut' => 'pi', + 'shortcut' => 'p', 'options' => array( 'nocompress' => array( 'shortopt' => 'Z', @@ -13084,71 +12434,274 @@ class PEAR_Command_Pickle extends PEAR_Command_Common 'doc' => 'Print the name of the packaged file.', ), ), - 'doc' => '[descfile] -Creates a PECL package from its package2.xml file. - -An automatic conversion will be made to a package.xml 1.0 and written out to -disk in the current directory as "package.xml". Note that -only simple package.xml 2.0 will be converted. package.xml 2.0 with: + 'doc' => '[descfile] [descfile2] +Creates a PEAR package from its description file (usually called +package.xml). If a second packagefile is passed in, then +the packager will check to make sure that one is a package.xml +version 1.0, and the other is a package.xml version 2.0. The +package.xml version 1.0 will be saved as "package.xml" in the archive, +and the other as "package2.xml" in the archive" +' + ), + 'package-validate' => array( + 'summary' => 'Validate Package Consistency', + 'function' => 'doPackageValidate', + 'shortcut' => 'pv', + 'options' => array(), + 'doc' => ' +', + ), + 'cvsdiff' => array( + 'summary' => 'Run a "cvs diff" for all files in a package', + 'function' => 'doCvsDiff', + 'shortcut' => 'cd', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'reallyquiet' => array( + 'shortopt' => 'Q', + 'doc' => 'Be really quiet', + ), + 'date' => array( + 'shortopt' => 'D', + 'doc' => 'Diff against revision of DATE', + 'arg' => 'DATE', + ), + 'release' => array( + 'shortopt' => 'R', + 'doc' => 'Diff against tag for package release REL', + 'arg' => 'REL', + ), + 'revision' => array( + 'shortopt' => 'r', + 'doc' => 'Diff against revision REV', + 'arg' => 'REV', + ), + 'context' => array( + 'shortopt' => 'c', + 'doc' => 'Generate context diff', + ), + 'unified' => array( + 'shortopt' => 'u', + 'doc' => 'Generate unified diff', + ), + 'ignore-case' => array( + 'shortopt' => 'i', + 'doc' => 'Ignore case, consider upper- and lower-case letters equivalent', + ), + 'ignore-whitespace' => array( + 'shortopt' => 'b', + 'doc' => 'Ignore changes in amount of white space', + ), + 'ignore-blank-lines' => array( + 'shortopt' => 'B', + 'doc' => 'Ignore changes that insert or delete blank lines', + ), + 'brief' => array( + 'doc' => 'Report only whether the files differ, no details', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => ' +Compares all the files in a package. Without any options, this +command will compare the current code with the last checked-in code. +Using the -r or -R option you may compare the current code with that +of a specific release. +', + ), + 'svntag' => array( + 'summary' => 'Set SVN Release Tag', + 'function' => 'doSvnTag', + 'shortcut' => 'sv', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'slide' => array( + 'shortopt' => 'F', + 'doc' => 'Move (slide) tag if it exists', + ), + 'delete' => array( + 'shortopt' => 'd', + 'doc' => 'Remove tag', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => ' [files...] + Sets a SVN tag on all files in a package. Use this command after you have + packaged a distribution tarball with the "package" command to tag what + revisions of what files were in that release. If need to fix something + after running cvstag once, but before the tarball is released to the public, + use the "slide" option to move the release tag. + + to include files (such as a second package.xml, or tests not included in the + release), pass them as additional parameters. + ', + ), + 'cvstag' => array( + 'summary' => 'Set CVS Release Tag', + 'function' => 'doCvsTag', + 'shortcut' => 'ct', + 'options' => array( + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Be quiet', + ), + 'reallyquiet' => array( + 'shortopt' => 'Q', + 'doc' => 'Be really quiet', + ), + 'slide' => array( + 'shortopt' => 'F', + 'doc' => 'Move (slide) tag if it exists', + ), + 'delete' => array( + 'shortopt' => 'd', + 'doc' => 'Remove tag', + ), + 'dry-run' => array( + 'shortopt' => 'n', + 'doc' => 'Don\'t do anything, just pretend', + ), + ), + 'doc' => ' [files...] +Sets a CVS tag on all files in a package. Use this command after you have +packaged a distribution tarball with the "package" command to tag what +revisions of what files were in that release. If need to fix something +after running cvstag once, but before the tarball is released to the public, +use the "slide" option to move the release tag. + +to include files (such as a second package.xml, or tests not included in the +release), pass them as additional parameters. +', + ), + 'package-dependencies' => array( + 'summary' => 'Show package dependencies', + 'function' => 'doPackageDependencies', + 'shortcut' => 'pd', + 'options' => array(), + 'doc' => ' or or +List all dependencies the package has. +Can take a tgz / tar file, package.xml or a package name of an installed package.' + ), + 'sign' => array( + 'summary' => 'Sign a package distribution file', + 'function' => 'doSign', + 'shortcut' => 'si', + 'options' => array( + 'verbose' => array( + 'shortopt' => 'v', + 'doc' => 'Display GnuPG output', + ), + ), + 'doc' => ' +Signs a package distribution (.tar or .tgz) file with GnuPG.', + ), + 'makerpm' => array( + 'summary' => 'Builds an RPM spec file from a PEAR package', + 'function' => 'doMakeRPM', + 'shortcut' => 'rpm', + 'options' => array( + 'spec-template' => array( + 'shortopt' => 't', + 'arg' => 'FILE', + 'doc' => 'Use FILE as RPM spec file template' + ), + 'rpm-pkgname' => array( + 'shortopt' => 'p', + 'arg' => 'FORMAT', + 'doc' => 'Use FORMAT as format string for RPM package name, %s is replaced +by the PEAR package name, defaults to "PEAR::%s".', + ), + ), + 'doc' => ' - - dependency types other than required/optional PECL package/ext/php/pearinstaller - - more than one extsrcrelease or zendextsrcrelease - - zendextbinrelease, extbinrelease, phprelease, or bundle release type - - dependency groups - - ignore tags in release filelist - - tasks other than replace - - custom roles +Creates an RPM .spec file for wrapping a PEAR package inside an RPM +package. Intended to be used from the SPECS directory, with the PEAR +package tarball in the SOURCES directory: -will cause pickle to fail, and output an error message. If your package2.xml -uses any of these features, you are best off using PEAR_PackageFileManager to -generate both package.xml. +$ pear makerpm ../SOURCES/Net_Socket-1.0.tgz +Wrote RPM spec file PEAR::Net_Geo-1.0.spec +$ rpm -bb PEAR::Net_Socket-1.0.spec +... +Wrote: /usr/src/redhat/RPMS/i386/PEAR::Net_Socket-1.0-1.i386.rpm +', + ), + 'convert' => array( + 'summary' => 'Convert a package.xml 1.0 to package.xml 2.0 format', + 'function' => 'doConvert', + 'shortcut' => 'c2', + 'options' => array( + 'flat' => array( + 'shortopt' => 'f', + 'doc' => 'do not beautify the filelist.', + ), + ), + 'doc' => '[descfile] [descfile2] +Converts a package.xml in 1.0 format into a package.xml +in 2.0 format. The new file will be named package2.xml by default, +and package.xml will be used as the old file by default. +This is not the most intelligent conversion, and should only be +used for automated conversion or learning the format. ' ), ); + var $output; + /** * PEAR_Command_Package constructor. * * @access public */ - function PEAR_Command_Pickle(&$ui, &$config) + function PEAR_Command_Package(&$ui, &$config) { parent::PEAR_Command_Common($ui, $config); } - /** - * For unit-testing ease - * - * @return PEAR_Packager - */ + function _displayValidationResults($err, $warn, $strict = false) + { + foreach ($err as $e) { + $this->output .= "Error: $e\n"; + } + foreach ($warn as $w) { + $this->output .= "Warning: $w\n"; + } + $this->output .= sprintf('Validation: %d error(s), %d warning(s)'."\n", + sizeof($err), sizeof($warn)); + if ($strict && count($err) > 0) { + $this->output .= "Fix these errors and try again."; + return false; + } + return true; + } + function &getPackager() { if (!class_exists('PEAR_Packager')) { require_once 'PEAR/Packager.php'; } - $a = &new PEAR_Packager; return $a; } - /** - * For unit-testing ease - * - * @param PEAR_Config $config - * @param bool $debug - * @param string|null $tmpdir - * @return PEAR_PackageFile - */ function &getPackageFile($config, $debug = false, $tmpdir = null) { if (!class_exists('PEAR_Common')) { require_once 'PEAR/Common.php'; } - if (!class_exists('PEAR_PackageFile')) { require_once 'PEAR/PackageFile.php'; } - $a = &new PEAR_PackageFile($config, $debug, $tmpdir); $common = new PEAR_Common; $common->ui = $this->ui; @@ -13159,372 +12712,828 @@ generate both package.xml. function doPackage($command, $options, $params) { $this->output = ''; - $pkginfofile = isset($params[0]) ? $params[0] : 'package2.xml'; - $packager = &$this->getPackager(); - if (PEAR::isError($err = $this->_convertPackage($pkginfofile))) { - return $err; + $pkginfofile = isset($params[0]) ? $params[0] : 'package.xml'; + $pkg2 = isset($params[1]) ? $params[1] : null; + if (!$pkg2 && !isset($params[0]) && file_exists('package2.xml')) { + $pkg2 = 'package2.xml'; } + $packager = &$this->getPackager(); $compress = empty($options['nocompress']) ? true : false; - $result = $packager->package($pkginfofile, $compress, 'package.xml'); + $result = $packager->package($pkginfofile, $compress, $pkg2); if (PEAR::isError($result)) { return $this->raiseError($result); } // Don't want output, only the package file name just created if (isset($options['showname'])) { - $this->ui->outputData($result, $command); + $this->output = $result; + } + + if ($this->output) { + $this->ui->outputData($this->output, $command); } return true; } - function _convertPackage($packagexml) + function doPackageValidate($command, $options, $params) { - $pkg = &$this->getPackageFile($this->config); - $pf2 = &$pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL); - if (!is_a($pf2, 'PEAR_PackageFile_v2')) { - return $this->raiseError('Cannot process "' . - $packagexml . '", is not a package.xml 2.0'); + $this->output = ''; + if (count($params) < 1) { + $params[0] = 'package.xml'; } - require_once 'PEAR/PackageFile/v1.php'; - $pf = new PEAR_PackageFile_v1; - $pf->setConfig($this->config); - if ($pf2->getPackageType() != 'extsrc' && $pf2->getPackageType() != 'zendextsrc') { - return $this->raiseError('Cannot safely convert "' . $packagexml . - '", is not an extension source package. Using a PEAR_PackageFileManager-based ' . - 'script is an option'); + $obj = &$this->getPackageFile($this->config, $this->_debug); + $obj->rawReturn(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + $info = $obj->fromPackageFile($params[0], PEAR_VALIDATE_NORMAL); + } else { + $archive = $info->getArchiveFile(); + $tar = &new Archive_Tar($archive); + $tar->extract(dirname($info->getPackageFile())); + $info->setPackageFile(dirname($info->getPackageFile()) . DIRECTORY_SEPARATOR . + $info->getPackage() . '-' . $info->getVersion() . DIRECTORY_SEPARATOR . + basename($info->getPackageFile())); } - if (is_array($pf2->getUsesRole())) { - return $this->raiseError('Cannot safely convert "' . $packagexml . - '", contains custom roles. Using a PEAR_PackageFileManager-based script or ' . - 'the convert command is an option'); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($info)) { + return $this->raiseError($info); } - if (is_array($pf2->getUsesTask())) { - return $this->raiseError('Cannot safely convert "' . $packagexml . - '", contains custom tasks. Using a PEAR_PackageFileManager-based script or ' . - 'the convert command is an option'); + $valid = false; + if ($info->getPackagexmlVersion() == '2.0') { + if ($valid = $info->validate(PEAR_VALIDATE_NORMAL)) { + $info->flattenFileList(); + $valid = $info->validate(PEAR_VALIDATE_PACKAGING); + } + } else { + $valid = $info->validate(PEAR_VALIDATE_PACKAGING); } - $deps = $pf2->getDependencies(); - if (isset($deps['group'])) { - return $this->raiseError('Cannot safely convert "' . $packagexml . - '", contains dependency groups. Using a PEAR_PackageFileManager-based script ' . - 'or the convert command is an option'); + $err = $warn = array(); + if ($errors = $info->getValidationWarnings()) { + foreach ($errors as $error) { + if ($error['level'] == 'warning') { + $warn[] = $error['message']; + } else { + $err[] = $error['message']; + } + } } - if (isset($deps['required']['subpackage']) || - isset($deps['optional']['subpackage'])) { - return $this->raiseError('Cannot safely convert "' . $packagexml . - '", contains subpackage dependencies. Using a PEAR_PackageFileManager-based '. - 'script is an option'); + $this->_displayValidationResults($err, $warn); + $this->ui->outputData($this->output, $command); + return true; + } + + function doSvnTag($command, $options, $params) + { + $this->output = ''; + $_cmd = $command; + if (count($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); } - if (isset($deps['required']['os'])) { - return $this->raiseError('Cannot safely convert "' . $packagexml . - '", contains os dependencies. Using a PEAR_PackageFileManager-based '. - 'script is an option'); + $packageFile = realpath($params[0]); + $dir = dirname($packageFile); + $dir = substr($dir, strrpos($dir, '/') + 1); + $obj = &$this->getPackageFile($this->config, $this->_debug); + $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + return $this->raiseError($info); } - if (isset($deps['required']['arch'])) { - return $this->raiseError('Cannot safely convert "' . $packagexml . - '", contains arch dependencies. Using a PEAR_PackageFileManager-based '. - 'script is an option'); + $err = $warn = array(); + if (!$info->validate()) { + foreach ($info->getValidationWarnings() as $error) { + if ($error['level'] == 'warning') { + $warn[] = $error['message']; + } else { + $err[] = $error['message']; + } + } } - $pf->setPackage($pf2->getPackage()); - $pf->setSummary($pf2->getSummary()); - $pf->setDescription($pf2->getDescription()); - foreach ($pf2->getMaintainers() as $maintainer) { - $pf->addMaintainer($maintainer['role'], $maintainer['handle'], - $maintainer['name'], $maintainer['email']); + if (!$this->_displayValidationResults($err, $warn, true)) { + $this->ui->outputData($this->output, $command); + return $this->raiseError('SVN tag failed'); } - $pf->setVersion($pf2->getVersion()); - $pf->setDate($pf2->getDate()); - $pf->setLicense($pf2->getLicense()); - $pf->setState($pf2->getState()); - $pf->setNotes($pf2->getNotes()); - $pf->addPhpDep($deps['required']['php']['min'], 'ge'); - if (isset($deps['required']['php']['max'])) { - $pf->addPhpDep($deps['required']['php']['max'], 'le'); + $version = $info->getVersion(); + $package = $info->getName(); + $svntag = "$package-$version"; + + if (isset($options['delete'])) { + return $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options); } - if (isset($deps['required']['package'])) { - if (!isset($deps['required']['package'][0])) { - $deps['required']['package'] = array($deps['required']['package']); + $path = $this->_svnFindPath($packageFile); + + // Check if there are any modified files + $fp = popen('svn st --xml ' . dirname($packageFile), "r"); + $out = ''; + while ($line = fgets($fp, 1024)) { + $out .= rtrim($line)."\n"; + } + pclose($fp); + + if (!isset($options['quiet']) && strpos($out, 'item="modified"')) { + $params = array(array( + 'name' => 'modified', + 'type' => 'yesno', + 'default' => 'no', + 'prompt' => 'You have files in your SVN checkout (' . $path['from'] . ') that have been modified but not commited, do you still want to tag ' . $version . '?', + )); + $answers = $this->ui->confirmDialog($params); + + if (!in_array($answers['modified'], array('y', 'yes', 'on', '1'))) { + return true; } + } - foreach ($deps['required']['package'] as $dep) { - if (!isset($dep['channel'])) { - return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . - ' contains uri-based dependency on a package. Using a ' . - 'PEAR_PackageFileManager-based script is an option'); - } + if (isset($options['slide'])) { + $this->_svnRemoveTag($version, $package, $svntag, $packageFile, $options); + } - if ($dep['channel'] != 'pear.php.net' - && $dep['channel'] != 'pecl.php.net' - && $dep['channel'] != 'doc.php.net') { - return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . - ' contains dependency on a non-standard channel package. Using a ' . - 'PEAR_PackageFileManager-based script is an option'); - } + // Check if tag already exists + $releaseTag = $path['local']['base'] . 'tags/' . $svntag; + $existsCommand = 'svn ls ' . $path['base'] . 'tags/'; - if (isset($dep['conflicts'])) { - return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . - ' contains conflicts dependency. Using a ' . - 'PEAR_PackageFileManager-based script is an option'); - } + $fp = popen($existsCommand, "r"); + $out = ''; + while ($line = fgets($fp, 1024)) { + $out .= rtrim($line)."\n"; + } + pclose($fp); - if (isset($dep['exclude'])) { - $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); + if (in_array($svntag . '/', explode("\n", $out))) { + $this->ui->outputData($this->output, $command); + return $this->raiseError('SVN tag ' . $svntag . ' for ' . $package . ' already exists.'); + } else { + $makeCommand = 'svn mkdir ' . $releaseTag; + $this->output .= "+ $makeCommand\n"; + if (empty($options['dry-run'])) { + // We need to create the tag dir. + $fp = popen($makeCommand, "r"); + $out = ''; + while ($line = fgets($fp, 1024)) { + $out .= rtrim($line)."\n"; } + pclose($fp); + $this->output .= "$out\n"; + } + } - if (isset($dep['min'])) { - $pf->addPackageDep($dep['name'], $dep['min'], 'ge'); - } + $command = 'svn'; + if (isset($options['quiet'])) { + $command .= ' -q'; + } - if (isset($dep['max'])) { - $pf->addPackageDep($dep['name'], $dep['max'], 'le'); + $command .= ' copy --parents '; + + $dir = dirname($packageFile); + $dir = substr($dir, strrpos($dir, '/') + 1); + $files = array_keys($info->getFilelist()); + $commands = array(); + foreach ($files as $file) { + if (!file_exists($file)) { + $file = $dir . DIRECTORY_SEPARATOR . $file; + } + $commands[] = $command . ' ' . escapeshellarg($file) . ' ' . + escapeshellarg($releaseTag . DIRECTORY_SEPARATOR . $file); + } + + $this->output .= implode("\n", $commands) . "\n"; + if (empty($options['dry-run'])) { + foreach ($commands as $command) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; } + pclose($fp); } } - if (isset($deps['required']['extension'])) { - if (!isset($deps['required']['extension'][0])) { - $deps['required']['extension'] = array($deps['required']['extension']); + $command = 'svn ci -m "Tagging the ' . $version . ' release" ' . $releaseTag . "\n"; + $this->output .= "+ $command\n"; + if (empty($options['dry-run'])) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; } + pclose($fp); + } - foreach ($deps['required']['extension'] as $dep) { - if (isset($dep['conflicts'])) { - return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . - ' contains conflicts dependency. Using a ' . - 'PEAR_PackageFileManager-based script is an option'); - } + $this->ui->outputData($this->output, $_cmd); + return true; + } - if (isset($dep['exclude'])) { - $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); - } + function _svnFindPath($file) + { + $xml = ''; + $command = "svn info --xml $file"; + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $xml .= rtrim($line)."\n"; + } + pclose($fp); + $url_tag = strpos($xml, ''); + $url = substr($xml, $url_tag + 5, strpos($xml, '', $url_tag + 5) - ($url_tag + 5)); - if (isset($dep['min'])) { - $pf->addExtensionDep($dep['name'], $dep['min'], 'ge'); - } + $path = array(); + $path['from'] = substr($url, 0, strrpos($url, '/')); + $path['base'] = substr($path['from'], 0, strrpos($path['from'], '/') + 1); - if (isset($dep['max'])) { - $pf->addExtensionDep($dep['name'], $dep['max'], 'le'); - } - } + // Figure out the local paths + $pos = strpos($file, '/trunk/'); + if ($pos === false) { + $pos = strpos($file, '/branches/'); } + $path['local']['base'] = substr($file, 0, $pos + 1); - if (isset($deps['optional']['package'])) { - if (!isset($deps['optional']['package'][0])) { - $deps['optional']['package'] = array($deps['optional']['package']); - } + return $path; + } - foreach ($deps['optional']['package'] as $dep) { - if (!isset($dep['channel'])) { - return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . - ' contains uri-based dependency on a package. Using a ' . - 'PEAR_PackageFileManager-based script is an option'); - } + function _svnRemoveTag($version, $package, $tag, $packageFile, $options) + { + $command = 'svn'; - if ($dep['channel'] != 'pear.php.net' - && $dep['channel'] != 'pecl.php.net' - && $dep['channel'] != 'doc.php.net') { - return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . - ' contains dependency on a non-standard channel package. Using a ' . - 'PEAR_PackageFileManager-based script is an option'); - } + if (isset($options['quiet'])) { + $command .= ' -q'; + } - if (isset($dep['exclude'])) { - $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); - } + $command .= ' remove'; + $command .= ' -m "Removing tag for the ' . $version . ' release."'; - if (isset($dep['min'])) { - $pf->addPackageDep($dep['name'], $dep['min'], 'ge', 'yes'); - } + $path = $this->_svnFindPath($packageFile); + $command .= ' ' . $path['base'] . 'tags/' . $tag; - if (isset($dep['max'])) { - $pf->addPackageDep($dep['name'], $dep['max'], 'le', 'yes'); - } - } + + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $command\n"; } - if (isset($deps['optional']['extension'])) { - if (!isset($deps['optional']['extension'][0])) { - $deps['optional']['extension'] = array($deps['optional']['extension']); + $this->output .= "+ $command\n"; + if (empty($options['dry-run'])) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; } + pclose($fp); + } - foreach ($deps['optional']['extension'] as $dep) { - if (isset($dep['exclude'])) { - $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); - } + $this->ui->outputData($this->output, $command); + return true; + } - if (isset($dep['min'])) { - $pf->addExtensionDep($dep['name'], $dep['min'], 'ge', 'yes'); - } + function doCvsTag($command, $options, $params) + { + $this->output = ''; + $_cmd = $command; + if (count($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); + } - if (isset($dep['max'])) { - $pf->addExtensionDep($dep['name'], $dep['max'], 'le', 'yes'); + $packageFile = realpath($params[0]); + $obj = &$this->getPackageFile($this->config, $this->_debug); + $info = $obj->fromAnyFile($packageFile, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $err = $warn = array(); + if (!$info->validate()) { + foreach ($info->getValidationWarnings() as $error) { + if ($error['level'] == 'warning') { + $warn[] = $error['message']; + } else { + $err[] = $error['message']; } } } - $contents = $pf2->getContents(); - $release = $pf2->getReleases(); - if (isset($releases[0])) { - return $this->raiseError('Cannot safely process "' . $packagexml . '" contains ' - . 'multiple extsrcrelease/zendextsrcrelease tags. Using a PEAR_PackageFileManager-based script ' . - 'or the convert command is an option'); + if (!$this->_displayValidationResults($err, $warn, true)) { + $this->ui->outputData($this->output, $command); + return $this->raiseError('CVS tag failed'); } - if ($configoptions = $pf2->getConfigureOptions()) { - foreach ($configoptions as $option) { - $default = isset($option['default']) ? $option['default'] : false; - $pf->addConfigureOption($option['name'], $option['prompt'], $default); - } + $version = $info->getVersion(); + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $version); + $cvstag = "RELEASE_$cvsversion"; + $files = array_keys($info->getFilelist()); + $command = 'cvs'; + if (isset($options['quiet'])) { + $command .= ' -q'; } - if (isset($release['filelist']['ignore'])) { - return $this->raiseError('Cannot safely process "' . $packagexml . '" contains ' - . 'ignore tags. Using a PEAR_PackageFileManager-based script or the convert' . - ' command is an option'); + if (isset($options['reallyquiet'])) { + $command .= ' -Q'; } - if (isset($release['filelist']['install']) && - !isset($release['filelist']['install'][0])) { - $release['filelist']['install'] = array($release['filelist']['install']); + $command .= ' tag'; + if (isset($options['slide'])) { + $command .= ' -F'; } - if (isset($contents['dir']['attribs']['baseinstalldir'])) { - $baseinstalldir = $contents['dir']['attribs']['baseinstalldir']; - } else { - $baseinstalldir = false; + if (isset($options['delete'])) { + $command .= ' -d'; } - if (!isset($contents['dir']['file'][0])) { - $contents['dir']['file'] = array($contents['dir']['file']); + $command .= ' ' . $cvstag . ' ' . escapeshellarg($params[0]); + array_shift($params); + if (count($params)) { + // add in additional files to be tagged + $files = array_merge($files, $params); } - foreach ($contents['dir']['file'] as $file) { - if ($baseinstalldir && !isset($file['attribs']['baseinstalldir'])) { - $file['attribs']['baseinstalldir'] = $baseinstalldir; + $dir = dirname($packageFile); + $dir = substr($dir, strrpos($dir, '/') + 1); + foreach ($files as $file) { + if (!file_exists($file)) { + $file = $dir . DIRECTORY_SEPARATOR . $file; } + $command .= ' ' . escapeshellarg($file); + } - $processFile = $file; - unset($processFile['attribs']); - if (count($processFile)) { - foreach ($processFile as $name => $task) { - if ($name != $pf2->getTasksNs() . ':replace') { - return $this->raiseError('Cannot safely process "' . $packagexml . - '" contains tasks other than replace. Using a ' . - 'PEAR_PackageFileManager-based script is an option.'); - } - $file['attribs']['replace'][] = $task; - } - } + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $command\n"; + } - if (!in_array($file['attribs']['role'], PEAR_Common::getFileRoles())) { - return $this->raiseError('Cannot safely convert "' . $packagexml . - '", contains custom roles. Using a PEAR_PackageFileManager-based script ' . - 'or the convert command is an option'); + $this->output .= "+ $command\n"; + if (empty($options['dry-run'])) { + $fp = popen($command, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; } + pclose($fp); + } - if (isset($release['filelist']['install'])) { - foreach ($release['filelist']['install'] as $installas) { - if ($installas['attribs']['name'] == $file['attribs']['name']) { - $file['attribs']['install-as'] = $installas['attribs']['as']; + $this->ui->outputData($this->output, $_cmd); + return true; + } + + function doCvsDiff($command, $options, $params) + { + $this->output = ''; + if (sizeof($params) < 1) { + $help = $this->getHelp($command); + return $this->raiseError("$command: missing parameter: $help[0]"); + } + + $file = realpath($params[0]); + $obj = &$this->getPackageFile($this->config, $this->_debug); + $info = $obj->fromAnyFile($file, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $err = $warn = array(); + if (!$info->validate()) { + foreach ($info->getValidationWarnings() as $error) { + if ($error['level'] == 'warning') { + $warn[] = $error['message']; + } else { + $err[] = $error['message']; + } + } + } + + if (!$this->_displayValidationResults($err, $warn, true)) { + $this->ui->outputData($this->output, $command); + return $this->raiseError('CVS diff failed'); + } + + $info1 = $info->getFilelist(); + $files = $info1; + $cmd = "cvs"; + if (isset($options['quiet'])) { + $cmd .= ' -q'; + unset($options['quiet']); + } + + if (isset($options['reallyquiet'])) { + $cmd .= ' -Q'; + unset($options['reallyquiet']); + } + + if (isset($options['release'])) { + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $options['release']); + $cvstag = "RELEASE_$cvsversion"; + $options['revision'] = $cvstag; + unset($options['release']); + } + + $execute = true; + if (isset($options['dry-run'])) { + $execute = false; + unset($options['dry-run']); + } + + $cmd .= ' diff'; + // the rest of the options are passed right on to "cvs diff" + foreach ($options as $option => $optarg) { + $arg = $short = false; + if (isset($this->commands[$command]['options'][$option])) { + $arg = $this->commands[$command]['options'][$option]['arg']; + $short = $this->commands[$command]['options'][$option]['shortopt']; + } + $cmd .= $short ? " -$short" : " --$option"; + if ($arg && $optarg) { + $cmd .= ($short ? '' : '=') . escapeshellarg($optarg); + } + } + + foreach ($files as $file) { + $cmd .= ' ' . escapeshellarg($file['name']); + } + + if ($this->config->get('verbose') > 1) { + $this->output .= "+ $cmd\n"; + } + + if ($execute) { + $fp = popen($cmd, "r"); + while ($line = fgets($fp, 1024)) { + $this->output .= rtrim($line)."\n"; + } + pclose($fp); + } + + $this->ui->outputData($this->output, $command); + return true; + } + + function doPackageDependencies($command, $options, $params) + { + // $params[0] -> the PEAR package to list its information + if (count($params) !== 1) { + return $this->raiseError("bad parameter(s), try \"help $command\""); + } + + $obj = &$this->getPackageFile($this->config, $this->_debug); + if (is_file($params[0]) || strpos($params[0], '.xml') > 0) { + $info = $obj->fromAnyFile($params[0], PEAR_VALIDATE_NORMAL); + } else { + $reg = $this->config->getRegistry(); + $info = $obj->fromArray($reg->packageInfo($params[0])); + } + + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $deps = $info->getDeps(); + if (is_array($deps)) { + if ($info->getPackagexmlVersion() == '1.0') { + $data = array( + 'caption' => 'Dependencies for pear/' . $info->getPackage(), + 'border' => true, + 'headline' => array("Required?", "Type", "Name", "Relation", "Version"), + ); + + foreach ($deps as $d) { + if (isset($d['optional'])) { + if ($d['optional'] == 'yes') { + $req = 'No'; + } else { + $req = 'Yes'; + } + } else { + $req = 'Yes'; + } + + if (isset($this->_deps_rel_trans[$d['rel']])) { + $rel = $this->_deps_rel_trans[$d['rel']]; + } else { + $rel = $d['rel']; + } + + if (isset($this->_deps_type_trans[$d['type']])) { + $type = ucfirst($this->_deps_type_trans[$d['type']]); + } else { + $type = $d['type']; + } + + if (isset($d['name'])) { + $name = $d['name']; + } else { + $name = ''; + } + + if (isset($d['version'])) { + $version = $d['version']; + } else { + $version = ''; + } + + $data['data'][] = array($req, $type, $name, $rel, $version); + } + } else { // package.xml 2.0 dependencies display + require_once 'PEAR/Dependency2.php'; + $deps = $info->getDependencies(); + $reg = &$this->config->getRegistry(); + if (is_array($deps)) { + $d = new PEAR_Dependency2($this->config, array(), ''); + $data = array( + 'caption' => 'Dependencies for ' . $info->getPackage(), + 'border' => true, + 'headline' => array("Required?", "Type", "Name", 'Versioning', 'Group'), + ); + foreach ($deps as $type => $subd) { + $req = ($type == 'required') ? 'Yes' : 'No'; + if ($type == 'group') { + $group = $subd['attribs']['name']; + } else { + $group = ''; + } + + if (!isset($subd[0])) { + $subd = array($subd); + } + + foreach ($subd as $groupa) { + foreach ($groupa as $deptype => $depinfo) { + if ($deptype == 'attribs') { + continue; + } + + if ($deptype == 'pearinstaller') { + $deptype = 'pear Installer'; + } + + if (!isset($depinfo[0])) { + $depinfo = array($depinfo); + } + + foreach ($depinfo as $inf) { + $name = ''; + if (isset($inf['channel'])) { + $alias = $reg->channelAlias($inf['channel']); + if (!$alias) { + $alias = '(channel?) ' .$inf['channel']; + } + $name = $alias . '/'; + + } + if (isset($inf['name'])) { + $name .= $inf['name']; + } elseif (isset($inf['pattern'])) { + $name .= $inf['pattern']; + } else { + $name .= ''; + } + + if (isset($inf['uri'])) { + $name .= ' [' . $inf['uri'] . ']'; + } + + if (isset($inf['conflicts'])) { + $ver = 'conflicts'; + } else { + $ver = $d->_getExtraString($inf); + } + + $data['data'][] = array($req, ucfirst($deptype), $name, + $ver, $group); + } + } + } } } } - $pf->addFile('/', $file['attribs']['name'], $file['attribs']); + $this->ui->outputData($data, $command); + return true; } - if ($pf2->getChangeLog()) { - $this->ui->outputData('WARNING: changelog is not translated to package.xml ' . - '1.0, use PEAR_PackageFileManager-based script if you need changelog-' . - 'translation for package.xml 1.0'); + // Fallback + $this->ui->outputData("This package does not have any dependencies.", $command); + } + + function doSign($command, $options, $params) + { + // should move most of this code into PEAR_Packager + // so it'll be easy to implement "pear package --sign" + if (count($params) !== 1) { + return $this->raiseError("bad parameter(s), try \"help $command\""); } - $gen = &$pf->getDefaultGenerator(); - $gen->toPackageFile('.'); + require_once 'System.php'; + require_once 'Archive/Tar.php'; + + if (!file_exists($params[0])) { + return $this->raiseError("file does not exist: $params[0]"); + } + + $obj = $this->getPackageFile($this->config, $this->_debug); + $info = $obj->fromTgzFile($params[0], PEAR_VALIDATE_NORMAL); + if (PEAR::isError($info)) { + return $this->raiseError($info); + } + + $tar = new Archive_Tar($params[0]); + $tmpdir = System::mktemp('-d pearsign'); + if (!$tar->extractList('package2.xml package.xml package.sig', $tmpdir)) { + return $this->raiseError("failed to extract tar file"); + } + + if (file_exists("$tmpdir/package.sig")) { + return $this->raiseError("package already signed"); + } + + $packagexml = 'package.xml'; + if (file_exists("$tmpdir/package2.xml")) { + $packagexml = 'package2.xml'; + } + + if (file_exists("$tmpdir/package.sig")) { + unlink("$tmpdir/package.sig"); + } + + if (!file_exists("$tmpdir/$packagexml")) { + return $this->raiseError("Extracted file $tmpdir/$packagexml not found."); + } + + $input = $this->ui->userDialog($command, + array('GnuPG Passphrase'), + array('password')); + if (!isset($input[0])) { + //use empty passphrase + $input[0] = ''; + } + + $devnull = (isset($options['verbose'])) ? '' : ' 2>/dev/null'; + $gpg = popen("gpg --batch --passphrase-fd 0 --armor --detach-sign --output $tmpdir/package.sig $tmpdir/$packagexml" . $devnull, "w"); + if (!$gpg) { + return $this->raiseError("gpg command failed"); + } + + fwrite($gpg, "$input[0]\n"); + if (pclose($gpg) || !file_exists("$tmpdir/package.sig")) { + return $this->raiseError("gpg sign failed"); + } + + if (!$tar->addModify("$tmpdir/package.sig", '', $tmpdir)) { + return $this->raiseError('failed adding signature to file'); + } + + $this->ui->outputData("Package signed.", $command); + return true; } -}PEAR-1.8.0/PEAR/Command/Registry.xml100777 764 764 3376 100777 11767 - - List Installed Packages In The Default Channel - doList - l + + /** + * For unit testing purposes + */ + function &getInstaller(&$ui) + { + if (!class_exists('PEAR_Installer')) { + require_once 'PEAR/Installer.php'; + } + $a = &new PEAR_Installer($ui); + return $a; + } + + /** + * For unit testing purposes + */ + function &getCommandPackaging(&$ui, &$config) + { + if (!class_exists('PEAR_Command_Packaging')) { + if ($fp = @fopen('PEAR/Command/Packaging.php', 'r', true)) { + fclose($fp); + include_once 'PEAR/Command/Packaging.php'; + } + } + + if (class_exists('PEAR_Command_Packaging')) { + $a = &new PEAR_Command_Packaging($ui, $config); + } else { + $a = null; + } + + return $a; + } + + function doMakeRPM($command, $options, $params) + { + + // Check to see if PEAR_Command_Packaging is installed, and + // transparently switch to use the "make-rpm-spec" command from it + // instead, if it does. Otherwise, continue to use the old version + // of "makerpm" supplied with this package (PEAR). + $packaging_cmd = $this->getCommandPackaging($this->ui, $this->config); + if ($packaging_cmd !== null) { + $this->ui->outputData('PEAR_Command_Packaging is installed; using '. + 'newer "make-rpm-spec" command instead'); + return $packaging_cmd->run('make-rpm-spec', $options, $params); + } + + $this->ui->outputData('WARNING: "pear makerpm" is no longer available; an '. + 'improved version is available via "pear make-rpm-spec", which '. + 'is available by installing PEAR_Command_Packaging'); + return true; + } + + function doConvert($command, $options, $params) + { + $packagexml = isset($params[0]) ? $params[0] : 'package.xml'; + $newpackagexml = isset($params[1]) ? $params[1] : dirname($packagexml) . + DIRECTORY_SEPARATOR . 'package2.xml'; + $pkg = &$this->getPackageFile($this->config, $this->_debug); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $pf = $pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf)) { + if (is_array($pf->getUserInfo())) { + foreach ($pf->getUserInfo() as $warning) { + $this->ui->outputData($warning['message']); + } + } + return $this->raiseError($pf); + } + + if (is_a($pf, 'PEAR_PackageFile_v2')) { + $this->ui->outputData($packagexml . ' is already a package.xml version 2.0'); + return true; + } + + $gen = &$pf->getDefaultGenerator(); + $newpf = &$gen->toV2(); + $newpf->setPackagefile($newpackagexml); + $gen = &$newpf->getDefaultGenerator(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $state = (isset($options['flat']) ? PEAR_VALIDATE_PACKAGING : PEAR_VALIDATE_NORMAL); + $saved = $gen->toPackageFile(dirname($newpackagexml), $state, basename($newpackagexml)); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($saved)) { + if (is_array($saved->getUserInfo())) { + foreach ($saved->getUserInfo() as $warning) { + $this->ui->outputData($warning['message']); + } + } + + $this->ui->outputData($saved->getMessage()); + return true; + } + + $this->ui->outputData('Wrote new version 2.0 package.xml to "' . $saved . '"'); + return true; + } +}PEAR-1.9.0/PEAR/Command/Pickle.xml100664 764 764 2233 100664 11344 + + Build PECL Package + doPackage + pi - - c - list installed packages from this channel - CHAN - - - a - list installed packages from all channels - - - i - output fully channel-aware data, even on failure - + + Z + Do not gzip the package file + + + n + Print the name of the packaged file. + - <package> -If invoked without parameters, this command lists the PEAR packages -installed in your php_dir ({config php_dir}). With a parameter, it -lists the files in a package. - - - - List Files In Installed Package - doFileList - fl - - <package> -List the files in an installed package. - - - - Shell Script Test - doShellTest - st - - <package> [[relation] version] -Tests if a package is installed in the system. Will exit(1) if it is not. - <relation> The version comparison operator. One of: - <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne - <version> The version to compare with + [descfile] +Creates a PECL package from its package2.xml file. + +An automatic conversion will be made to a package.xml 1.0 and written out to +disk in the current directory as "package.xml". Note that +only simple package.xml 2.0 will be converted. package.xml 2.0 with: + + - dependency types other than required/optional PECL package/ext/php/pearinstaller + - more than one extsrcrelease or zendextsrcrelease + - zendextbinrelease, extbinrelease, phprelease, or bundle release type + - dependency groups + - ignore tags in release filelist + - tasks other than replace + - custom roles + +will cause pickle to fail, and output an error message. If your package2.xml +uses any of these features, you are best off using PEAR_PackageFileManager to +generate both package.xml. - - - Display information about a package - doInfo - in - - <package> -Displays information about a package. The package argument may be a -local package file, an URL to a package file, or the name of an -installed package. - -PEAR-1.8.0/PEAR/Command/Registry.php100664 764 764 132374 100664 12005 +PEAR-1.9.0/PEAR/Command/Pickle.php100664 764 764 37207 100664 11364 * @author Greg Beaver - * @copyright 1997-2009 The Authors + * @copyright 2005-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Registry.php,v 1.88 2009/02/24 23:39:29 dufuz Exp $ + * @version CVS: $Id: Pickle.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 + * @since File available since Release 1.4.1 */ /** @@ -13533,165 +13542,643 @@ installed package. require_once 'PEAR/Command/Common.php'; /** - * PEAR commands for registry manipulation + * PEAR commands for login/logout * * @category pear * @package PEAR - * @author Stig Bakken * @author Greg Beaver - * @copyright 1997-2009 The Authors + * @copyright 2005-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 + * @since Class available since Release 1.4.1 */ -class PEAR_Command_Registry extends PEAR_Command_Common + +class PEAR_Command_Pickle extends PEAR_Command_Common { var $commands = array( - 'list' => array( - 'summary' => 'List Installed Packages In The Default Channel', - 'function' => 'doList', - 'shortcut' => 'l', + 'pickle' => array( + 'summary' => 'Build PECL Package', + 'function' => 'doPackage', + 'shortcut' => 'pi', 'options' => array( - 'channel' => array( - 'shortopt' => 'c', - 'doc' => 'list installed packages from this channel', - 'arg' => 'CHAN', - ), - 'allchannels' => array( - 'shortopt' => 'a', - 'doc' => 'list installed packages from all channels', + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'Do not gzip the package file' ), - 'channelinfo' => array( - 'shortopt' => 'i', - 'doc' => 'output fully channel-aware data, even on failure', + 'showname' => array( + 'shortopt' => 'n', + 'doc' => 'Print the name of the packaged file.', ), ), - 'doc' => ' -If invoked without parameters, this command lists the PEAR packages -installed in your php_dir ({config php_dir}). With a parameter, it -lists the files in a package. -', - ), - 'list-files' => array( - 'summary' => 'List Files In Installed Package', - 'function' => 'doFileList', - 'shortcut' => 'fl', - 'options' => array(), - 'doc' => ' -List the files in an installed package. + 'doc' => '[descfile] +Creates a PECL package from its package2.xml file. + +An automatic conversion will be made to a package.xml 1.0 and written out to +disk in the current directory as "package.xml". Note that +only simple package.xml 2.0 will be converted. package.xml 2.0 with: + + - dependency types other than required/optional PECL package/ext/php/pearinstaller + - more than one extsrcrelease or zendextsrcrelease + - zendextbinrelease, extbinrelease, phprelease, or bundle release type + - dependency groups + - ignore tags in release filelist + - tasks other than replace + - custom roles + +will cause pickle to fail, and output an error message. If your package2.xml +uses any of these features, you are best off using PEAR_PackageFileManager to +generate both package.xml. ' ), - 'shell-test' => array( - 'summary' => 'Shell Script Test', - 'function' => 'doShellTest', - 'shortcut' => 'st', - 'options' => array(), - 'doc' => ' [[relation] version] -Tests if a package is installed in the system. Will exit(1) if it is not. - The version comparison operator. One of: - <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne - The version to compare with -'), - 'info' => array( - 'summary' => 'Display information about a package', - 'function' => 'doInfo', - 'shortcut' => 'in', - 'options' => array(), - 'doc' => ' -Displays information about a package. The package argument may be a -local package file, an URL to a package file, or the name of an -installed package.' - ) ); /** - * PEAR_Command_Registry constructor. + * PEAR_Command_Package constructor. * * @access public */ - function PEAR_Command_Registry(&$ui, &$config) + function PEAR_Command_Pickle(&$ui, &$config) { parent::PEAR_Command_Common($ui, $config); } - function _sortinfo($a, $b) + /** + * For unit-testing ease + * + * @return PEAR_Packager + */ + function &getPackager() { - $apackage = isset($a['package']) ? $a['package'] : $a['name']; - $bpackage = isset($b['package']) ? $b['package'] : $b['name']; - return strcmp($apackage, $bpackage); + if (!class_exists('PEAR_Packager')) { + require_once 'PEAR/Packager.php'; + } + + $a = &new PEAR_Packager; + return $a; } - function doList($command, $options, $params) + /** + * For unit-testing ease + * + * @param PEAR_Config $config + * @param bool $debug + * @param string|null $tmpdir + * @return PEAR_PackageFile + */ + function &getPackageFile($config, $debug = false, $tmpdir = null) { - $reg = &$this->config->getRegistry(); - $channelinfo = isset($options['channelinfo']); - if (isset($options['allchannels']) && !$channelinfo) { - return $this->doListAll($command, array(), $params); + if (!class_exists('PEAR_Common')) { + require_once 'PEAR/Common.php'; } - if (isset($options['allchannels']) && $channelinfo) { - // allchannels with $channelinfo - unset($options['allchannels']); - $channels = $reg->getChannels(); - $errors = array(); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - foreach ($channels as $channel) { - $options['channel'] = $channel->getName(); - $ret = $this->doList($command, $options, $params); + if (!class_exists('PEAR_PackageFile')) { + require_once 'PEAR/PackageFile.php'; + } - if (PEAR::isError($ret)) { - $errors[] = $ret; - } - } + $a = &new PEAR_PackageFile($config, $debug, $tmpdir); + $common = new PEAR_Common; + $common->ui = $this->ui; + $a->setLogger($common); + return $a; + } - PEAR::staticPopErrorHandling(); - if (count($errors)) { - // for now, only give first error - return PEAR::raiseError($errors[0]); - } + function doPackage($command, $options, $params) + { + $this->output = ''; + $pkginfofile = isset($params[0]) ? $params[0] : 'package2.xml'; + $packager = &$this->getPackager(); + if (PEAR::isError($err = $this->_convertPackage($pkginfofile))) { + return $err; + } - return true; + $compress = empty($options['nocompress']) ? true : false; + $result = $packager->package($pkginfofile, $compress, 'package.xml'); + if (PEAR::isError($result)) { + return $this->raiseError($result); } - if (count($params) === 1) { - return $this->doFileList($command, $options, $params); + // Don't want output, only the package file name just created + if (isset($options['showname'])) { + $this->ui->outputData($result, $command); } - if (isset($options['channel'])) { - if (!$reg->channelExists($options['channel'])) { - return $this->raiseError('Channel "' . $options['channel'] .'" does not exist'); - } + return true; + } - $channel = $reg->channelName($options['channel']); - } else { - $channel = $this->config->get('default_channel'); + function _convertPackage($packagexml) + { + $pkg = &$this->getPackageFile($this->config); + $pf2 = &$pkg->fromPackageFile($packagexml, PEAR_VALIDATE_NORMAL); + if (!is_a($pf2, 'PEAR_PackageFile_v2')) { + return $this->raiseError('Cannot process "' . + $packagexml . '", is not a package.xml 2.0'); } - $installed = $reg->packageInfo(null, null, $channel); - usort($installed, array(&$this, '_sortinfo')); + require_once 'PEAR/PackageFile/v1.php'; + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->config); + if ($pf2->getPackageType() != 'extsrc' && $pf2->getPackageType() != 'zendextsrc') { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", is not an extension source package. Using a PEAR_PackageFileManager-based ' . + 'script is an option'); + } - $data = array( - 'caption' => 'Installed packages, channel ' . - $channel . ':', - 'border' => true, - 'headline' => array('Package', 'Version', 'State'), - 'channel' => $channel, - ); - if ($channelinfo) { - $data['headline'] = array('Channel', 'Package', 'Version', 'State'); + if (is_array($pf2->getUsesRole())) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains custom roles. Using a PEAR_PackageFileManager-based script or ' . + 'the convert command is an option'); } - if (count($installed) && !isset($data['data'])) { - $data['data'] = array(); + if (is_array($pf2->getUsesTask())) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains custom tasks. Using a PEAR_PackageFileManager-based script or ' . + 'the convert command is an option'); } - foreach ($installed as $package) { - $pobj = $reg->getPackage(isset($package['package']) ? - $package['package'] : $package['name'], $channel); - if ($channelinfo) { - $packageinfo = array($pobj->getChannel(), $pobj->getPackage(), $pobj->getVersion(), - $pobj->getState() ? $pobj->getState() : null); + $deps = $pf2->getDependencies(); + if (isset($deps['group'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains dependency groups. Using a PEAR_PackageFileManager-based script ' . + 'or the convert command is an option'); + } + + if (isset($deps['required']['subpackage']) || + isset($deps['optional']['subpackage'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains subpackage dependencies. Using a PEAR_PackageFileManager-based '. + 'script is an option'); + } + + if (isset($deps['required']['os'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains os dependencies. Using a PEAR_PackageFileManager-based '. + 'script is an option'); + } + + if (isset($deps['required']['arch'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains arch dependencies. Using a PEAR_PackageFileManager-based '. + 'script is an option'); + } + + $pf->setPackage($pf2->getPackage()); + $pf->setSummary($pf2->getSummary()); + $pf->setDescription($pf2->getDescription()); + foreach ($pf2->getMaintainers() as $maintainer) { + $pf->addMaintainer($maintainer['role'], $maintainer['handle'], + $maintainer['name'], $maintainer['email']); + } + + $pf->setVersion($pf2->getVersion()); + $pf->setDate($pf2->getDate()); + $pf->setLicense($pf2->getLicense()); + $pf->setState($pf2->getState()); + $pf->setNotes($pf2->getNotes()); + $pf->addPhpDep($deps['required']['php']['min'], 'ge'); + if (isset($deps['required']['php']['max'])) { + $pf->addPhpDep($deps['required']['php']['max'], 'le'); + } + + if (isset($deps['required']['package'])) { + if (!isset($deps['required']['package'][0])) { + $deps['required']['package'] = array($deps['required']['package']); + } + + foreach ($deps['required']['package'] as $dep) { + if (!isset($dep['channel'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . + ' contains uri-based dependency on a package. Using a ' . + 'PEAR_PackageFileManager-based script is an option'); + } + + if ($dep['channel'] != 'pear.php.net' + && $dep['channel'] != 'pecl.php.net' + && $dep['channel'] != 'doc.php.net') { + return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . + ' contains dependency on a non-standard channel package. Using a ' . + 'PEAR_PackageFileManager-based script is an option'); + } + + if (isset($dep['conflicts'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . + ' contains conflicts dependency. Using a ' . + 'PEAR_PackageFileManager-based script is an option'); + } + + if (isset($dep['exclude'])) { + $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); + } + + if (isset($dep['min'])) { + $pf->addPackageDep($dep['name'], $dep['min'], 'ge'); + } + + if (isset($dep['max'])) { + $pf->addPackageDep($dep['name'], $dep['max'], 'le'); + } + } + } + + if (isset($deps['required']['extension'])) { + if (!isset($deps['required']['extension'][0])) { + $deps['required']['extension'] = array($deps['required']['extension']); + } + + foreach ($deps['required']['extension'] as $dep) { + if (isset($dep['conflicts'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . + ' contains conflicts dependency. Using a ' . + 'PEAR_PackageFileManager-based script is an option'); + } + + if (isset($dep['exclude'])) { + $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); + } + + if (isset($dep['min'])) { + $pf->addExtensionDep($dep['name'], $dep['min'], 'ge'); + } + + if (isset($dep['max'])) { + $pf->addExtensionDep($dep['name'], $dep['max'], 'le'); + } + } + } + + if (isset($deps['optional']['package'])) { + if (!isset($deps['optional']['package'][0])) { + $deps['optional']['package'] = array($deps['optional']['package']); + } + + foreach ($deps['optional']['package'] as $dep) { + if (!isset($dep['channel'])) { + return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . + ' contains uri-based dependency on a package. Using a ' . + 'PEAR_PackageFileManager-based script is an option'); + } + + if ($dep['channel'] != 'pear.php.net' + && $dep['channel'] != 'pecl.php.net' + && $dep['channel'] != 'doc.php.net') { + return $this->raiseError('Cannot safely convert "' . $packagexml . '"' . + ' contains dependency on a non-standard channel package. Using a ' . + 'PEAR_PackageFileManager-based script is an option'); + } + + if (isset($dep['exclude'])) { + $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); + } + + if (isset($dep['min'])) { + $pf->addPackageDep($dep['name'], $dep['min'], 'ge', 'yes'); + } + + if (isset($dep['max'])) { + $pf->addPackageDep($dep['name'], $dep['max'], 'le', 'yes'); + } + } + } + + if (isset($deps['optional']['extension'])) { + if (!isset($deps['optional']['extension'][0])) { + $deps['optional']['extension'] = array($deps['optional']['extension']); + } + + foreach ($deps['optional']['extension'] as $dep) { + if (isset($dep['exclude'])) { + $this->ui->outputData('WARNING: exclude tags are ignored in conversion'); + } + + if (isset($dep['min'])) { + $pf->addExtensionDep($dep['name'], $dep['min'], 'ge', 'yes'); + } + + if (isset($dep['max'])) { + $pf->addExtensionDep($dep['name'], $dep['max'], 'le', 'yes'); + } + } + } + + $contents = $pf2->getContents(); + $release = $pf2->getReleases(); + if (isset($releases[0])) { + return $this->raiseError('Cannot safely process "' . $packagexml . '" contains ' + . 'multiple extsrcrelease/zendextsrcrelease tags. Using a PEAR_PackageFileManager-based script ' . + 'or the convert command is an option'); + } + + if ($configoptions = $pf2->getConfigureOptions()) { + foreach ($configoptions as $option) { + $default = isset($option['default']) ? $option['default'] : false; + $pf->addConfigureOption($option['name'], $option['prompt'], $default); + } + } + + if (isset($release['filelist']['ignore'])) { + return $this->raiseError('Cannot safely process "' . $packagexml . '" contains ' + . 'ignore tags. Using a PEAR_PackageFileManager-based script or the convert' . + ' command is an option'); + } + + if (isset($release['filelist']['install']) && + !isset($release['filelist']['install'][0])) { + $release['filelist']['install'] = array($release['filelist']['install']); + } + + if (isset($contents['dir']['attribs']['baseinstalldir'])) { + $baseinstalldir = $contents['dir']['attribs']['baseinstalldir']; + } else { + $baseinstalldir = false; + } + + if (!isset($contents['dir']['file'][0])) { + $contents['dir']['file'] = array($contents['dir']['file']); + } + + foreach ($contents['dir']['file'] as $file) { + if ($baseinstalldir && !isset($file['attribs']['baseinstalldir'])) { + $file['attribs']['baseinstalldir'] = $baseinstalldir; + } + + $processFile = $file; + unset($processFile['attribs']); + if (count($processFile)) { + foreach ($processFile as $name => $task) { + if ($name != $pf2->getTasksNs() . ':replace') { + return $this->raiseError('Cannot safely process "' . $packagexml . + '" contains tasks other than replace. Using a ' . + 'PEAR_PackageFileManager-based script is an option.'); + } + $file['attribs']['replace'][] = $task; + } + } + + if (!in_array($file['attribs']['role'], PEAR_Common::getFileRoles())) { + return $this->raiseError('Cannot safely convert "' . $packagexml . + '", contains custom roles. Using a PEAR_PackageFileManager-based script ' . + 'or the convert command is an option'); + } + + if (isset($release['filelist']['install'])) { + foreach ($release['filelist']['install'] as $installas) { + if ($installas['attribs']['name'] == $file['attribs']['name']) { + $file['attribs']['install-as'] = $installas['attribs']['as']; + } + } + } + + $pf->addFile('/', $file['attribs']['name'], $file['attribs']); + } + + if ($pf2->getChangeLog()) { + $this->ui->outputData('WARNING: changelog is not translated to package.xml ' . + '1.0, use PEAR_PackageFileManager-based script if you need changelog-' . + 'translation for package.xml 1.0'); + } + + $gen = &$pf->getDefaultGenerator(); + $gen->toPackageFile('.'); + } +}PEAR-1.9.0/PEAR/Command/Registry.xml100664 764 764 3376 100664 11756 + + List Installed Packages In The Default Channel + doList + l + + + c + list installed packages from this channel + CHAN + + + a + list installed packages from all channels + + + i + output fully channel-aware data, even on failure + + + <package> +If invoked without parameters, this command lists the PEAR packages +installed in your php_dir ({config php_dir}). With a parameter, it +lists the files in a package. + + + + List Files In Installed Package + doFileList + fl + + <package> +List the files in an installed package. + + + + Shell Script Test + doShellTest + st + + <package> [[relation] version] +Tests if a package is installed in the system. Will exit(1) if it is not. + <relation> The version comparison operator. One of: + <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne + <version> The version to compare with + + + + Display information about a package + doInfo + in + + <package> +Displays information about a package. The package argument may be a +local package file, an URL to a package file, or the name of an +installed package. + +PEAR-1.9.0/PEAR/Command/Registry.php100664 764 764 132371 100664 12003 + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Registry.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for registry manipulation + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Command_Registry extends PEAR_Command_Common +{ + var $commands = array( + 'list' => array( + 'summary' => 'List Installed Packages In The Default Channel', + 'function' => 'doList', + 'shortcut' => 'l', + 'options' => array( + 'channel' => array( + 'shortopt' => 'c', + 'doc' => 'list installed packages from this channel', + 'arg' => 'CHAN', + ), + 'allchannels' => array( + 'shortopt' => 'a', + 'doc' => 'list installed packages from all channels', + ), + 'channelinfo' => array( + 'shortopt' => 'i', + 'doc' => 'output fully channel-aware data, even on failure', + ), + ), + 'doc' => ' +If invoked without parameters, this command lists the PEAR packages +installed in your php_dir ({config php_dir}). With a parameter, it +lists the files in a package. +', + ), + 'list-files' => array( + 'summary' => 'List Files In Installed Package', + 'function' => 'doFileList', + 'shortcut' => 'fl', + 'options' => array(), + 'doc' => ' +List the files in an installed package. +' + ), + 'shell-test' => array( + 'summary' => 'Shell Script Test', + 'function' => 'doShellTest', + 'shortcut' => 'st', + 'options' => array(), + 'doc' => ' [[relation] version] +Tests if a package is installed in the system. Will exit(1) if it is not. + The version comparison operator. One of: + <, lt, <=, le, >, gt, >=, ge, ==, =, eq, !=, <>, ne + The version to compare with +'), + 'info' => array( + 'summary' => 'Display information about a package', + 'function' => 'doInfo', + 'shortcut' => 'in', + 'options' => array(), + 'doc' => ' +Displays information about a package. The package argument may be a +local package file, an URL to a package file, or the name of an +installed package.' + ) + ); + + /** + * PEAR_Command_Registry constructor. + * + * @access public + */ + function PEAR_Command_Registry(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + function _sortinfo($a, $b) + { + $apackage = isset($a['package']) ? $a['package'] : $a['name']; + $bpackage = isset($b['package']) ? $b['package'] : $b['name']; + return strcmp($apackage, $bpackage); + } + + function doList($command, $options, $params) + { + $reg = &$this->config->getRegistry(); + $channelinfo = isset($options['channelinfo']); + if (isset($options['allchannels']) && !$channelinfo) { + return $this->doListAll($command, array(), $params); + } + + if (isset($options['allchannels']) && $channelinfo) { + // allchannels with $channelinfo + unset($options['allchannels']); + $channels = $reg->getChannels(); + $errors = array(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + foreach ($channels as $channel) { + $options['channel'] = $channel->getName(); + $ret = $this->doList($command, $options, $params); + + if (PEAR::isError($ret)) { + $errors[] = $ret; + } + } + + PEAR::staticPopErrorHandling(); + if (count($errors)) { + // for now, only give first error + return PEAR::raiseError($errors[0]); + } + + return true; + } + + if (count($params) === 1) { + return $this->doFileList($command, $options, $params); + } + + if (isset($options['channel'])) { + if (!$reg->channelExists($options['channel'])) { + return $this->raiseError('Channel "' . $options['channel'] .'" does not exist'); + } + + $channel = $reg->channelName($options['channel']); + } else { + $channel = $this->config->get('default_channel'); + } + + $installed = $reg->packageInfo(null, null, $channel); + usort($installed, array(&$this, '_sortinfo')); + + $data = array( + 'caption' => 'Installed packages, channel ' . + $channel . ':', + 'border' => true, + 'headline' => array('Package', 'Version', 'State'), + 'channel' => $channel, + ); + if ($channelinfo) { + $data['headline'] = array('Channel', 'Package', 'Version', 'State'); + } + + if (count($installed) && !isset($data['data'])) { + $data['data'] = array(); + } + + foreach ($installed as $package) { + $pobj = $reg->getPackage(isset($package['package']) ? + $package['package'] : $package['name'], $channel); + if ($channelinfo) { + $packageinfo = array($pobj->getChannel(), $pobj->getPackage(), $pobj->getVersion(), + $pobj->getState() ? $pobj->getState() : null); } else { $packageinfo = array($pobj->getPackage(), $pobj->getVersion(), $pobj->getState() ? $pobj->getState() : null); @@ -14652,7 +15139,7 @@ installed package.' $data['raw'] = $obj->getArray(); // no validation needed $this->ui->outputData($data, 'package-info'); } -}PEAR-1.8.0/PEAR/Command/Remote.xml100777 764 764 6357 100777 11414 +}PEAR-1.9.0/PEAR/Command/Remote.xml100664 764 764 6357 100664 11403 Information About Remote Packages doRemoteInfo @@ -14760,7 +15247,7 @@ Clear the XML-RPC/REST cache. See also the cache_ttl configuration parameter. -PEAR-1.8.0/PEAR/Command/Remote.php100664 764 764 72007 100664 11404 PEAR-1.9.0/PEAR/Command/Remote.php100664 764 764 72576 100664 11420 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Remote.php,v 1.120 2009/03/09 01:33:20 dufuz Exp $ + * @version CVS: $Id: Remote.php 287477 2009-08-19 14:19:43Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -14793,7 +15280,7 @@ require_once 'PEAR/REST.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -15426,9 +15913,22 @@ parameter. } $latest = array(); - if ($chan->supportsREST($this->config->get('preferred_mirror')) && - $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror'))) { - $rest = &$this->config->getREST('1.0', array()); + $base2 = false; + $preferred_mirror = $this->config->get('preferred_mirror'); + if ($chan->supportsREST($preferred_mirror) && + ( + //($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) || + ($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) + ) + + ) { + if ($base2) { + $rest = &$this->config->getREST('1.4', array()); + $base = $base2; + } else { + $rest = &$this->config->getREST('1.0', array()); + } + if (empty($state) || $state == 'any') { $state = false; } else { @@ -15555,7 +16055,7 @@ parameter. $this->ui->outputData(rtrim($output), $command); return $num; } -}PEAR-1.8.0/PEAR/Command/Test.xml100777 764 764 3153 100777 11067 +}PEAR-1.9.0/PEAR/Command/Test.xml100664 764 764 3151 100664 11054 Run Regression Tests doRunTests @@ -15588,7 +16088,7 @@ parameter. u - Search parameters for AllTests.php, and use that to run phpunit-based tests + Search parameters for AllTests.php, and use that to run phpunit-based tests If none is found, all .phpt tests will be tried instead. @@ -15605,346 +16105,346 @@ If none is found, all .phpt tests will be tried instead. Generate a code coverage report (requires Xdebug 2.0.0+) - [testfile|dir ...] + [testfile|dir ...] Run regression tests with PHP's regression testing script (run-tests.php). -PEAR-1.8.0/PEAR/Command/Test.php100664 764 764 30011 100664 11055 - * @author Martin Jansen - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Test.php,v 1.32 2009/04/04 00:06:17 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ - -/** - * base class - */ -require_once 'PEAR/Command/Common.php'; - -/** - * PEAR commands for login/logout - * - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Martin Jansen - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 - */ - -class PEAR_Command_Test extends PEAR_Command_Common -{ - var $commands = array( - 'run-tests' => array( - 'summary' => 'Run Regression Tests', - 'function' => 'doRunTests', - 'shortcut' => 'rt', - 'options' => array( - 'recur' => array( - 'shortopt' => 'r', - 'doc' => 'Run tests in child directories, recursively. 4 dirs deep maximum', - ), - 'ini' => array( - 'shortopt' => 'i', - 'doc' => 'actual string of settings to pass to php in format " -d setting=blah"', - 'arg' => 'SETTINGS' - ), - 'realtimelog' => array( - 'shortopt' => 'l', - 'doc' => 'Log test runs/results as they are run', - ), - 'quiet' => array( - 'shortopt' => 'q', - 'doc' => 'Only display detail for failed tests', - ), - 'simple' => array( - 'shortopt' => 's', - 'doc' => 'Display simple output for all tests', - ), - 'package' => array( - 'shortopt' => 'p', - 'doc' => 'Treat parameters as installed packages from which to run tests', - ), - 'phpunit' => array( - 'shortopt' => 'u', - 'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests -If none is found, all .phpt tests will be tried instead.', - ), - 'tapoutput' => array( - 'shortopt' => 't', - 'doc' => 'Output run-tests.log in TAP-compliant format', - ), - 'cgi' => array( - 'shortopt' => 'c', - 'doc' => 'CGI php executable (needed for tests with POST/GET section)', - 'arg' => 'PHPCGI', - ), - 'coverage' => array( - 'shortopt' => 'x', - 'doc' => 'Generate a code coverage report (requires Xdebug 2.0.0+)', - ), - ), - 'doc' => '[testfile|dir ...] -Run regression tests with PHP\'s regression testing script (run-tests.php).', - ), - ); - - var $output; - - /** - * PEAR_Command_Test constructor. - * - * @access public - */ - function PEAR_Command_Test(&$ui, &$config) - { - parent::PEAR_Command_Common($ui, $config); - } - - function doRunTests($command, $options, $params) - { - if (isset($options['phpunit']) && isset($options['tapoutput'])) { - return $this->raiseError('ERROR: cannot use both --phpunit and --tapoutput at the same time'); - } - - require_once 'PEAR/Common.php'; - require_once 'System.php'; - $log = new PEAR_Common; - $log->ui = &$this->ui; // slightly hacky, but it will work - $tests = array(); - $depth = isset($options['recur']) ? 14 : 1; - - if (!count($params)) { - $params[] = '.'; - } - - if (isset($options['package'])) { - $oldparams = $params; - $params = array(); - $reg = &$this->config->getRegistry(); - foreach ($oldparams as $param) { - $pname = $reg->parsePackageName($param, $this->config->get('default_channel')); - if (PEAR::isError($pname)) { - return $this->raiseError($pname); - } - - $package = &$reg->getPackage($pname['package'], $pname['channel']); - if (!$package) { - return PEAR::raiseError('Unknown package "' . - $reg->parsedPackageNameToString($pname) . '"'); - } - - $filelist = $package->getFilelist(); - foreach ($filelist as $name => $atts) { - if (isset($atts['role']) && $atts['role'] != 'test') { - continue; - } - - if (isset($options['phpunit']) && preg_match('/AllTests\.php\\z/i', $name)) { - $params[] = $atts['installed_as']; - continue; - } elseif (!preg_match('/\.phpt\\z/', $name)) { - continue; - } - $params[] = $atts['installed_as']; - } - } - } - - foreach ($params as $p) { - if (is_dir($p)) { - if (isset($options['phpunit'])) { - $dir = System::find(array($p, '-type', 'f', - '-maxdepth', $depth, - '-name', 'AllTests.php')); - if (count($dir)) { - foreach ($dir as $p) { - $p = realpath($p); - if (!count($tests) || - (count($tests) && strlen($p) < strlen($tests[0]))) { - // this is in a higher-level directory, use this one instead. - $tests = array($p); - } - } - } - continue; - } - - $args = array($p, '-type', 'f', '-name', '*.phpt'); - } else { - if (isset($options['phpunit'])) { - if (preg_match('/AllTests\.php\\z/i', $p)) { - $p = realpath($p); - if (!count($tests) || - (count($tests) && strlen($p) < strlen($tests[0]))) { - // this is in a higher-level directory, use this one instead. - $tests = array($p); - } - } - continue; - } - - if (file_exists($p) && preg_match('/\.phpt$/', $p)) { - $tests[] = $p; - continue; - } - - if (!preg_match('/\.phpt\\z/', $p)) { - $p .= '.phpt'; - } - - $args = array(dirname($p), '-type', 'f', '-name', $p); - } - - if (!isset($options['recur'])) { - $args[] = '-maxdepth'; - $args[] = 1; - } - - $dir = System::find($args); - $tests = array_merge($tests, $dir); - } - - $ini_settings = ''; - if (isset($options['ini'])) { - $ini_settings .= $options['ini']; - } - - if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) { - $ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}"; - } - - if ($ini_settings) { - $this->ui->outputData('Using INI settings: "' . $ini_settings . '"'); - } - - $skipped = $passed = $failed = array(); - $tests_count = count($tests); - $this->ui->outputData('Running ' . $tests_count . ' tests', $command); - $start = time(); - if (isset($options['realtimelog']) && file_exists('run-tests.log')) { - unlink('run-tests.log'); - } - - if (isset($options['tapoutput'])) { - $tap = '1..' . $tests_count . "\n"; - } - - require_once 'PEAR/RunTest.php'; - $run = new PEAR_RunTest($log, $options); - $run->tests_count = $tests_count; - - if (isset($options['coverage']) && extension_loaded('xdebug')){ - $run->xdebug_loaded = true; - } else { - $run->xdebug_loaded = false; - } - - $j = $i = 1; - foreach ($tests as $t) { - if (isset($options['realtimelog'])) { - $fp = @fopen('run-tests.log', 'a'); - if ($fp) { - fwrite($fp, "Running test [$i / $tests_count] $t..."); - fclose($fp); - } - } - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - if (isset($options['phpunit'])) { - $result = $run->runPHPUnit($t, $ini_settings); - } else { - $result = $run->run($t, $ini_settings, $j); - } - PEAR::staticPopErrorHandling(); - if (PEAR::isError($result)) { - $this->ui->log($result->getMessage()); - continue; - } - - if (isset($options['tapoutput'])) { - $tap .= $result[0] . ' ' . $i . $result[1] . "\n"; - continue; - } - - if (isset($options['realtimelog'])) { - $fp = @fopen('run-tests.log', 'a'); - if ($fp) { - fwrite($fp, "$result\n"); - fclose($fp); - } - } - - if ($result == 'FAILED') { - $failed[] = $t; - } - if ($result == 'PASSED') { - $passed[] = $t; - } - if ($result == 'SKIPPED') { - $skipped[] = $t; - } - - $j++; - } - - $total = date('i:s', time() - $start); - if (isset($options['tapoutput'])) { - $fp = @fopen('run-tests.log', 'w'); - if ($fp) { - fwrite($fp, $tap, strlen($tap)); - fclose($fp); - $this->ui->outputData('wrote TAP-format log to "' .realpath('run-tests.log') . - '"', $command); - } - } else { - if (count($failed)) { - $output = "TOTAL TIME: $total\n"; - $output .= count($passed) . " PASSED TESTS\n"; - $output .= count($skipped) . " SKIPPED TESTS\n"; - $output .= count($failed) . " FAILED TESTS:\n"; - foreach ($failed as $failure) { - $output .= $failure . "\n"; - } - - $mode = isset($options['realtimelog']) ? 'a' : 'w'; - $fp = @fopen('run-tests.log', $mode); - - if ($fp) { - fwrite($fp, $output, strlen($output)); - fclose($fp); - $this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command); - } - } elseif (file_exists('run-tests.log') && !is_dir('run-tests.log')) { - @unlink('run-tests.log'); - } - } - $this->ui->outputData('TOTAL TIME: ' . $total); - $this->ui->outputData(count($passed) . ' PASSED TESTS', $command); - $this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command); - if (count($failed)) { - $this->ui->outputData(count($failed) . ' FAILED TESTS:', $command); - foreach ($failed as $failure) { - $this->ui->outputData($failure, $command); - } - } - - return true; - } -}PEAR-1.8.0/PEAR/Downloader/Package.php100664 764 764 225261 100664 12246 PEAR-1.9.0/PEAR/Command/Test.php100664 764 764 27267 100664 11101 + * @author Martin Jansen + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Test.php 279072 2009-04-20 19:57:41Z cellog $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR/Command/Common.php'; + +/** + * PEAR commands for login/logout + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Martin Jansen + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ + +class PEAR_Command_Test extends PEAR_Command_Common +{ + var $commands = array( + 'run-tests' => array( + 'summary' => 'Run Regression Tests', + 'function' => 'doRunTests', + 'shortcut' => 'rt', + 'options' => array( + 'recur' => array( + 'shortopt' => 'r', + 'doc' => 'Run tests in child directories, recursively. 4 dirs deep maximum', + ), + 'ini' => array( + 'shortopt' => 'i', + 'doc' => 'actual string of settings to pass to php in format " -d setting=blah"', + 'arg' => 'SETTINGS' + ), + 'realtimelog' => array( + 'shortopt' => 'l', + 'doc' => 'Log test runs/results as they are run', + ), + 'quiet' => array( + 'shortopt' => 'q', + 'doc' => 'Only display detail for failed tests', + ), + 'simple' => array( + 'shortopt' => 's', + 'doc' => 'Display simple output for all tests', + ), + 'package' => array( + 'shortopt' => 'p', + 'doc' => 'Treat parameters as installed packages from which to run tests', + ), + 'phpunit' => array( + 'shortopt' => 'u', + 'doc' => 'Search parameters for AllTests.php, and use that to run phpunit-based tests +If none is found, all .phpt tests will be tried instead.', + ), + 'tapoutput' => array( + 'shortopt' => 't', + 'doc' => 'Output run-tests.log in TAP-compliant format', + ), + 'cgi' => array( + 'shortopt' => 'c', + 'doc' => 'CGI php executable (needed for tests with POST/GET section)', + 'arg' => 'PHPCGI', + ), + 'coverage' => array( + 'shortopt' => 'x', + 'doc' => 'Generate a code coverage report (requires Xdebug 2.0.0+)', + ), + ), + 'doc' => '[testfile|dir ...] +Run regression tests with PHP\'s regression testing script (run-tests.php).', + ), + ); + + var $output; + + /** + * PEAR_Command_Test constructor. + * + * @access public + */ + function PEAR_Command_Test(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + function doRunTests($command, $options, $params) + { + if (isset($options['phpunit']) && isset($options['tapoutput'])) { + return $this->raiseError('ERROR: cannot use both --phpunit and --tapoutput at the same time'); + } + + require_once 'PEAR/Common.php'; + require_once 'System.php'; + $log = new PEAR_Common; + $log->ui = &$this->ui; // slightly hacky, but it will work + $tests = array(); + $depth = isset($options['recur']) ? 14 : 1; + + if (!count($params)) { + $params[] = '.'; + } + + if (isset($options['package'])) { + $oldparams = $params; + $params = array(); + $reg = &$this->config->getRegistry(); + foreach ($oldparams as $param) { + $pname = $reg->parsePackageName($param, $this->config->get('default_channel')); + if (PEAR::isError($pname)) { + return $this->raiseError($pname); + } + + $package = &$reg->getPackage($pname['package'], $pname['channel']); + if (!$package) { + return PEAR::raiseError('Unknown package "' . + $reg->parsedPackageNameToString($pname) . '"'); + } + + $filelist = $package->getFilelist(); + foreach ($filelist as $name => $atts) { + if (isset($atts['role']) && $atts['role'] != 'test') { + continue; + } + + if (isset($options['phpunit']) && preg_match('/AllTests\.php\\z/i', $name)) { + $params[] = $atts['installed_as']; + continue; + } elseif (!preg_match('/\.phpt\\z/', $name)) { + continue; + } + $params[] = $atts['installed_as']; + } + } + } + + foreach ($params as $p) { + if (is_dir($p)) { + if (isset($options['phpunit'])) { + $dir = System::find(array($p, '-type', 'f', + '-maxdepth', $depth, + '-name', 'AllTests.php')); + if (count($dir)) { + foreach ($dir as $p) { + $p = realpath($p); + if (!count($tests) || + (count($tests) && strlen($p) < strlen($tests[0]))) { + // this is in a higher-level directory, use this one instead. + $tests = array($p); + } + } + } + continue; + } + + $args = array($p, '-type', 'f', '-name', '*.phpt'); + } else { + if (isset($options['phpunit'])) { + if (preg_match('/AllTests\.php\\z/i', $p)) { + $p = realpath($p); + if (!count($tests) || + (count($tests) && strlen($p) < strlen($tests[0]))) { + // this is in a higher-level directory, use this one instead. + $tests = array($p); + } + } + continue; + } + + if (file_exists($p) && preg_match('/\.phpt$/', $p)) { + $tests[] = $p; + continue; + } + + if (!preg_match('/\.phpt\\z/', $p)) { + $p .= '.phpt'; + } + + $args = array(dirname($p), '-type', 'f', '-name', $p); + } + + if (!isset($options['recur'])) { + $args[] = '-maxdepth'; + $args[] = 1; + } + + $dir = System::find($args); + $tests = array_merge($tests, $dir); + } + + $ini_settings = ''; + if (isset($options['ini'])) { + $ini_settings .= $options['ini']; + } + + if (isset($_ENV['TEST_PHP_INCLUDE_PATH'])) { + $ini_settings .= " -d include_path={$_ENV['TEST_PHP_INCLUDE_PATH']}"; + } + + if ($ini_settings) { + $this->ui->outputData('Using INI settings: "' . $ini_settings . '"'); + } + + $skipped = $passed = $failed = array(); + $tests_count = count($tests); + $this->ui->outputData('Running ' . $tests_count . ' tests', $command); + $start = time(); + if (isset($options['realtimelog']) && file_exists('run-tests.log')) { + unlink('run-tests.log'); + } + + if (isset($options['tapoutput'])) { + $tap = '1..' . $tests_count . "\n"; + } + + require_once 'PEAR/RunTest.php'; + $run = new PEAR_RunTest($log, $options); + $run->tests_count = $tests_count; + + if (isset($options['coverage']) && extension_loaded('xdebug')){ + $run->xdebug_loaded = true; + } else { + $run->xdebug_loaded = false; + } + + $j = $i = 1; + foreach ($tests as $t) { + if (isset($options['realtimelog'])) { + $fp = @fopen('run-tests.log', 'a'); + if ($fp) { + fwrite($fp, "Running test [$i / $tests_count] $t..."); + fclose($fp); + } + } + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (isset($options['phpunit'])) { + $result = $run->runPHPUnit($t, $ini_settings); + } else { + $result = $run->run($t, $ini_settings, $j); + } + PEAR::staticPopErrorHandling(); + if (PEAR::isError($result)) { + $this->ui->log($result->getMessage()); + continue; + } + + if (isset($options['tapoutput'])) { + $tap .= $result[0] . ' ' . $i . $result[1] . "\n"; + continue; + } + + if (isset($options['realtimelog'])) { + $fp = @fopen('run-tests.log', 'a'); + if ($fp) { + fwrite($fp, "$result\n"); + fclose($fp); + } + } + + if ($result == 'FAILED') { + $failed[] = $t; + } + if ($result == 'PASSED') { + $passed[] = $t; + } + if ($result == 'SKIPPED') { + $skipped[] = $t; + } + + $j++; + } + + $total = date('i:s', time() - $start); + if (isset($options['tapoutput'])) { + $fp = @fopen('run-tests.log', 'w'); + if ($fp) { + fwrite($fp, $tap, strlen($tap)); + fclose($fp); + $this->ui->outputData('wrote TAP-format log to "' .realpath('run-tests.log') . + '"', $command); + } + } else { + if (count($failed)) { + $output = "TOTAL TIME: $total\n"; + $output .= count($passed) . " PASSED TESTS\n"; + $output .= count($skipped) . " SKIPPED TESTS\n"; + $output .= count($failed) . " FAILED TESTS:\n"; + foreach ($failed as $failure) { + $output .= $failure . "\n"; + } + + $mode = isset($options['realtimelog']) ? 'a' : 'w'; + $fp = @fopen('run-tests.log', $mode); + + if ($fp) { + fwrite($fp, $output, strlen($output)); + fclose($fp); + $this->ui->outputData('wrote log to "' . realpath('run-tests.log') . '"', $command); + } + } elseif (file_exists('run-tests.log') && !is_dir('run-tests.log')) { + @unlink('run-tests.log'); + } + } + $this->ui->outputData('TOTAL TIME: ' . $total); + $this->ui->outputData(count($passed) . ' PASSED TESTS', $command); + $this->ui->outputData(count($skipped) . ' SKIPPED TESTS', $command); + if (count($failed)) { + $this->ui->outputData(count($failed) . ' FAILED TESTS:', $command); + foreach ($failed as $failure) { + $this->ui->outputData($failure, $command); + } + } + + return true; + } +}PEAR-1.9.0/PEAR/Downloader/Package.php100664 764 764 226171 100664 12250 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Package.php,v 1.126 2009/03/07 21:51:52 dufuz Exp $ + * @version CVS: $Id: Package.php 287560 2009-08-21 22:36:18Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -15996,7 +16496,7 @@ define('PEAR_DOWNLOADER_PACKAGE_PHPVERSION', -1004); * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -16111,6 +16611,12 @@ class PEAR_Downloader_Package $options = $this->_downloader->getOptions(); if (isset($options['offline'])) { if (PEAR::isError($origErr) && !isset($options['soft'])) { + foreach ($origErr->getUserInfo() as $userInfo) { + if (isset($userInfo['message'])) { + $this->_downloader->log(0, $userInfo['message']); + } + } + $this->_downloader->log(0, $origErr->getMessage()); } @@ -16208,8 +16714,15 @@ class PEAR_Downloader_Package if ($info != $newinfo) { do { - if ($info['package'] == 'pecl.php.net' && $newinfo['package'] == 'pear.php.net') { - $info['package'] = 'pear.php.net'; + if ($info['channel'] == 'pecl.php.net' && $newinfo['channel'] == 'pear.php.net') { + $info['channel'] = 'pear.php.net'; + if ($info == $newinfo) { + // skip the channel check if a pecl package says it's a PEAR package + break; + } + } + if ($info['channel'] == 'pear.php.net' && $newinfo['channel'] == 'pecl.php.net') { + $info['channel'] = 'pecl.php.net'; if ($info == $newinfo) { // skip the channel check if a pecl package says it's a PEAR package break; @@ -16598,8 +17111,7 @@ class PEAR_Downloader_Package // we can't determine whether upgrade is necessary until we know what // version would be downloaded if (!isset($options['force']) && $this->isInstalled($ret, $oper)) { - $version = $this->_installRegistry->packageInfo($dep['name'], 'version', - $dep['channel']); + $version = $this->_installRegistry->packageInfo($dep['name'], 'version', $dep['channel']); $dep['package'] = $dep['name']; if (!isset($options['soft'])) { $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group . @@ -16676,8 +17188,7 @@ class PEAR_Downloader_Package $newdep = $newdep[0]; $newdep['channel'] = 'pecl.php.net'; $chan = 'pecl.php.net'; - $url = - $this->_downloader->_getDepPackageDownloadUrl($newdep, $pname); + $url = $this->_downloader->_getDepPackageDownloadUrl($newdep, $pname); $obj = &$this->_installRegistry->getPackage($dep['name']); if (PEAR::isError($url)) { PEAR::popErrorHandling(); @@ -16761,8 +17272,7 @@ class PEAR_Downloader_Package 'optional'; $dep['package'] = $dep['name']; if (isset($newdep)) { - $version = $this->_installRegistry->packageInfo($newdep['name'], 'version', - $newdep['channel']); + $version = $this->_installRegistry->packageInfo($newdep['name'], 'version', $newdep['channel']); } else { $version = $this->_installRegistry->packageInfo($dep['name'], 'version'); } @@ -17081,6 +17591,7 @@ class PEAR_Downloader_Package $channel = 'pear.php.net'; } } + return (strtolower($package) == strtolower($this->getPackage()) && $channel == $this->getChannel() && version_compare($newdep['min'], $this->getVersion(), '<=') && @@ -17225,13 +17736,9 @@ class PEAR_Downloader_Package if (!$param) { continue; } - if ($param->getPackage()) { - if ($ignoreGroups) { - $group = ''; - } else { - $group = $param->getGroup(); - } + if ($param->getPackage()) { + $group = $ignoreGroups ? '' : $param->getGroup(); $pnames[$i] = $param->getChannel() . '/' . $param->getPackage() . '-' . $param->getVersion() . '#' . $group; } @@ -17761,7 +18268,7 @@ class PEAR_Downloader_Package if ($info['version'] === $package_version) { if (!isset($options['soft'])) { $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . - '/' . $pname['package'] . '-' . $pname['version'] . ', additionally the suggested version' . + '/' . $pname['package'] . '-' . $package_version. ', additionally the suggested version' . ' (' . $package_version . ') is the same as the locally installed one.'); } @@ -17771,7 +18278,7 @@ class PEAR_Downloader_Package if (version_compare($info['version'], $package_version, '<=')) { if (!isset($options['soft'])) { $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . - '/' . $pname['package'] . '-' . $pname['version'] . ', additionally the suggested version' . + '/' . $pname['package'] . '-' . $package_version . ', additionally the suggested version' . ' (' . $info['version'] . ') is a lower version than the locally installed one (' . $package_version . ').'); } @@ -17940,7 +18447,7 @@ class PEAR_Downloader_Package return $info; } -}PEAR-1.8.0/PEAR/Frontend/CLI.php100664 764 764 60645 100664 10766 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: CLI.php,v 1.76 2009/04/04 00:09:14 dufuz Exp $ + * @version CVS: $Id: CLI.php 278236 2009-04-04 00:09:14Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -17969,7 +18476,7 @@ require_once 'PEAR/Frontend.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 */ @@ -18671,7 +19178,7 @@ class PEAR_Frontend_CLI extends PEAR_Frontend { print $text; } -}PEAR-1.8.0/PEAR/Installer/Role/Common.php100664 764 764 14236 100664 12661 * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.13 2009/02/24 23:39:37 dufuz Exp $ + * @version CVS: $Id: Common.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -18697,7 +19204,7 @@ class PEAR_Frontend_CLI extends PEAR_Frontend * @author Greg Beaver * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -18844,7 +19351,7 @@ class PEAR_Installer_Role_Common return $roleInfo['phpextension']; } } -?>PEAR-1.8.0/PEAR/Installer/Role/Cfg.xml100777 764 764 645 100777 12112 +?>PEAR-1.9.0/PEAR/Installer/Role/Cfg.xml100664 764 764 645 100664 12101 php extsrc extbin @@ -18858,7 +19365,7 @@ class PEAR_Installer_Role_Common -PEAR-1.8.0/PEAR/Installer/Role/Cfg.php100664 764 764 7704 100664 12112 PEAR-1.9.0/PEAR/Installer/Role/Cfg.php100664 764 764 7702 100664 12111 * @copyright 2007-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Cfg.php,v 1.9 2009/02/24 23:39:37 dufuz Exp $ + * @version CVS: $Id: Cfg.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.7.0 */ @@ -18880,7 +19387,7 @@ class PEAR_Installer_Role_Common * @author Greg Beaver * @copyright 2007-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.7.0 */ @@ -18963,7 +19470,7 @@ class PEAR_Installer_Role_Cfg extends PEAR_Installer_Role_Common return $test; } -}PEAR-1.8.0/PEAR/Installer/Role/Data.xml100777 764 764 622 100777 12257 +}PEAR-1.9.0/PEAR/Installer/Role/Data.xml100664 764 764 622 100664 12246 php extsrc extbin @@ -18977,34 +19484,34 @@ class PEAR_Installer_Role_Cfg extends PEAR_Installer_Role_Common -PEAR-1.8.0/PEAR/Installer/Role/Data.php100664 764 764 1560 100664 12256 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Data.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {} -?>PEAR-1.8.0/PEAR/Installer/Role/Doc.xml100777 764 764 621 100777 12112 +PEAR-1.9.0/PEAR/Installer/Role/Data.php100664 764 764 1523 100664 12256 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Data.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {} +?>PEAR-1.9.0/PEAR/Installer/Role/Doc.xml100664 764 764 621 100664 12101 php extsrc extbin @@ -19018,34 +19525,34 @@ class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {} -PEAR-1.8.0/PEAR/Installer/Role/Doc.php100664 764 764 1555 100664 12116 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Doc.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {} -?>PEAR-1.8.0/PEAR/Installer/Role/Ext.xml100777 764 764 502 100777 12143 +PEAR-1.9.0/PEAR/Installer/Role/Doc.php100664 764 764 1520 100664 12107 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Doc.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {} +?>PEAR-1.9.0/PEAR/Installer/Role/Ext.xml100664 764 764 502 100664 12132 extbin zendextbin 1 @@ -19056,34 +19563,34 @@ class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {} 1 -PEAR-1.8.0/PEAR/Installer/Role/Ext.php100664 764 764 1555 100664 12151 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Ext.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role_Ext extends PEAR_Installer_Role_Common {} -?>PEAR-1.8.0/PEAR/Installer/Role/Php.xml100777 764 764 655 100777 12143 +PEAR-1.9.0/PEAR/Installer/Role/Ext.php100664 764 764 1520 100664 12142 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Ext.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Ext extends PEAR_Installer_Role_Common {} +?>PEAR-1.9.0/PEAR/Installer/Role/Php.xml100664 764 764 655 100664 12132 php extsrc extbin @@ -19097,34 +19604,34 @@ class PEAR_Installer_Role_Ext extends PEAR_Installer_Role_Common {} -PEAR-1.8.0/PEAR/Installer/Role/Php.php100664 764 764 1555 100664 12140 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Php.php,v 1.9 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {} -?>PEAR-1.8.0/PEAR/Installer/Role/Script.xml100777 764 764 660 100777 12654 +PEAR-1.9.0/PEAR/Installer/Role/Php.php100664 764 764 1520 100664 12131 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Php.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {} +?>PEAR-1.9.0/PEAR/Installer/Role/Script.xml100664 764 764 660 100664 12643 php extsrc extbin @@ -19138,78 +19645,78 @@ class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {} 1 -PEAR-1.8.0/PEAR/Installer/Role/Script.php100664 764 764 1566 100664 12657 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Script.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {} -?>PEAR-1.8.0/PEAR/Installer/Role/Src.xml100777 764 764 455 100777 12141 - extsrc - zendextsrc - 1 - temp_dir - - - - - - -PEAR-1.8.0/PEAR/Installer/Role/Src.php100664 764 764 1730 100664 12133 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Src.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role_Src extends PEAR_Installer_Role_Common -{ - function setup(&$installer, $pkg, $atts, $file) - { - $installer->source_files++; - } -} -?>PEAR-1.8.0/PEAR/Installer/Role/Test.xml100777 764 764 622 100777 12325 +PEAR-1.9.0/PEAR/Installer/Role/Script.php100664 764 764 1531 100664 12650 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Script.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {} +?>PEAR-1.9.0/PEAR/Installer/Role/Src.xml100664 764 764 442 100664 12124 + extsrc + zendextsrc + 1 + temp_dir + + + + + + +PEAR-1.9.0/PEAR/Installer/Role/Src.php100664 764 764 1665 100664 12143 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Src.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Src extends PEAR_Installer_Role_Common +{ + function setup(&$installer, $pkg, $atts, $file) + { + $installer->source_files++; + } +} +?>PEAR-1.9.0/PEAR/Installer/Role/Test.xml100664 764 764 622 100664 12314 php extsrc extbin @@ -19223,352 +19730,9 @@ class PEAR_Installer_Role_Src extends PEAR_Installer_Role_Common -PEAR-1.8.0/PEAR/Installer/Role/Test.php100664 764 764 1560 100664 12324 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Test.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {} -?>PEAR-1.8.0/PEAR/Installer/Role/Www.xml100777 764 764 662 100777 12176 - php - extsrc - extbin - zendextsrc - zendextbin - 1 - www_dir - 1 - - - - - -PEAR-1.8.0/PEAR/Installer/Role/Www.php100664 764 764 1551 100664 12171 - * @copyright 2007-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Www.php,v 1.3 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.7.0 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 2007-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.7.0 - */ -class PEAR_Installer_Role_Www extends PEAR_Installer_Role_Common {} -?>PEAR-1.8.0/PEAR/Installer/Role.php100664 764 764 20112 100664 11417 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Role.php,v 1.22 2009/04/10 19:42:49 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * base class for installer roles - */ -require_once 'PEAR/Installer/Role/Common.php'; -require_once 'PEAR/XMLParser.php'; -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role -{ - /** - * Set up any additional configuration variables that file roles require - * - * Never call this directly, it is called by the PEAR_Config constructor - * @param PEAR_Config - * @access private - * @static - */ - function initializeConfig(&$config) - { - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { - PEAR_Installer_Role::registerRoles(); - } - - foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) { - if (!$info['config_vars']) { - continue; - } - - $config->_addConfigVars($class, $info['config_vars']); - } - } - - /** - * @param PEAR_PackageFile_v2 - * @param string role name - * @param PEAR_Config - * @return PEAR_Installer_Role_Common - * @static - */ - function &factory($pkg, $role, &$config) - { - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { - PEAR_Installer_Role::registerRoles(); - } - - if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { - $a = false; - return $a; - } - - $a = 'PEAR_Installer_Role_' . ucfirst($role); - if (!class_exists($a)) { - require_once str_replace('_', '/', $a) . '.php'; - } - - $b = new $a($config); - return $b; - } - - /** - * Get a list of file roles that are valid for the particular release type. - * - * For instance, src files serve no purpose in regular php releases. - * @param string - * @param bool clear cache - * @return array - * @static - */ - function getValidRoles($release, $clear = false) - { - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { - PEAR_Installer_Role::registerRoles(); - } - - static $ret = array(); - if ($clear) { - $ret = array(); - } - - if (isset($ret[$release])) { - return $ret[$release]; - } - - $ret[$release] = array(); - foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { - if (in_array($release, $okreleases['releasetypes'])) { - $ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); - } - } - - return $ret[$release]; - } - - /** - * Get a list of roles that require their files to be installed - * - * Most roles must be installed, but src and package roles, for instance - * are pseudo-roles. src files are compiled into a new extension. Package - * roles are actually fully bundled releases of a package - * @param bool clear cache - * @return array - * @static - */ - function getInstallableRoles($clear = false) - { - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { - PEAR_Installer_Role::registerRoles(); - } - - static $ret; - if ($clear) { - unset($ret); - } - - if (isset($ret)) { - return $ret; - } - - $ret = array(); - foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { - if ($okreleases['installable']) { - $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); - } - } - - return $ret; - } - - /** - * Return an array of roles that are affected by the baseinstalldir attribute - * - * Most roles ignore this attribute, and instead install directly into: - * PackageName/filepath - * so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php - * @param bool clear cache - * @return array - * @static - */ - function getBaseinstallRoles($clear = false) - { - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { - PEAR_Installer_Role::registerRoles(); - } - - static $ret; - if ($clear) { - unset($ret); - } - - if (isset($ret)) { - return $ret; - } - - $ret = array(); - foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { - if ($okreleases['honorsbaseinstall']) { - $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); - } - } - - return $ret; - } - - /** - * Return an array of file roles that should be analyzed for PHP content at package time, - * like the "php" role. - * @param bool clear cache - * @return array - * @static - */ - function getPhpRoles($clear = false) - { - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { - PEAR_Installer_Role::registerRoles(); - } - - static $ret; - if ($clear) { - unset($ret); - } - - if (isset($ret)) { - return $ret; - } - - $ret = array(); - foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { - if ($okreleases['phpfile']) { - $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); - } - } - - return $ret; - } - - /** - * Scan through the Command directory looking for classes - * and see what commands they implement. - * @param string which directory to look for classes, defaults to - * the Installer/Roles subdirectory of - * the directory from where this file (__FILE__) is - * included. - * - * @return bool TRUE on success, a PEAR error on failure - * @access public - * @static - */ - function registerRoles($dir = null) - { - $GLOBALS['_PEAR_INSTALLER_ROLES'] = array(); - $parser = new PEAR_XMLParser; - if ($dir === null) { - $dir = dirname(__FILE__) . '/Role'; - } - - if (!file_exists($dir) || !is_dir($dir)) { - return PEAR::raiseError("registerRoles: opendir($dir) failed: does not exist/is not directory"); - } - - $dp = @opendir($dir); - if (empty($dp)) { - return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg"); - } - - while ($entry = readdir($dp)) { - if ($entry{0} == '.' || substr($entry, -4) != '.xml') { - continue; - } - - $class = "PEAR_Installer_Role_".substr($entry, 0, -4); - // List of roles - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) { - $file = "$dir/$entry"; - $parser->parse(file_get_contents($file)); - $data = $parser->getData(); - if (!is_array($data['releasetypes'])) { - $data['releasetypes'] = array($data['releasetypes']); - } - - $GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data; - } - } - - closedir($dp); - ksort($GLOBALS['_PEAR_INSTALLER_ROLES']); - PEAR_Installer_Role::getBaseinstallRoles(true); - PEAR_Installer_Role::getInstallableRoles(true); - PEAR_Installer_Role::getPhpRoles(true); - PEAR_Installer_Role::getValidRoles('****', true); - return true; - } -}PEAR-1.8.0/PEAR/PackageFile/Generator/v1.php100664 764 764 142407 100664 13224 PEAR-1.9.0/PEAR/Installer/Role/Test.php100664 764 764 1523 100664 12324 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v1.php,v 1.76 2009/02/24 23:45:26 dufuz Exp $ + * @version CVS: $Id: Test.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ + /** - * needed for PEAR_VALIDATE_* constants + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 */ -require_once 'PEAR/Validate.php'; -require_once 'System.php'; -require_once 'PEAR/PackageFile/v2.php'; +class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {} +?>PEAR-1.9.0/PEAR/Installer/Role/Www.xml100664 764 764 644 100664 12165 + php + extsrc + extbin + zendextsrc + zendextbin + 1 + www_dir + 1 + + + + + +PEAR-1.9.0/PEAR/Installer/Role/Www.php100664 764 764 1514 100664 12171 + * @copyright 2007-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Www.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.7.0 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 2007-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.7.0 + */ +class PEAR_Installer_Role_Www extends PEAR_Installer_Role_Common {} +?>PEAR-1.9.0/PEAR/Installer/Role.php100664 764 764 17464 100664 11440 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Role.php 278552 2009-04-10 19:42:49Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * base class for installer roles + */ +require_once 'PEAR/Installer/Role/Common.php'; +require_once 'PEAR/XMLParser.php'; +/** * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ -class PEAR_PackageFile_Generator_v1 +class PEAR_Installer_Role { /** - * @var PEAR_PackageFile_v1 + * Set up any additional configuration variables that file roles require + * + * Never call this directly, it is called by the PEAR_Config constructor + * @param PEAR_Config + * @access private + * @static */ - var $_packagefile; - function PEAR_PackageFile_Generator_v1(&$packagefile) + function initializeConfig(&$config) { - $this->_packagefile = &$packagefile; - } + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } - function getPackagerVersion() - { - return '1.8.0'; + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) { + if (!$info['config_vars']) { + continue; + } + + $config->_addConfigVars($class, $info['config_vars']); + } } /** - * @param PEAR_Packager - * @param bool if true, a .tgz is written, otherwise a .tar is written - * @param string|null directory in which to save the .tgz - * @return string|PEAR_Error location of package or error object + * @param PEAR_PackageFile_v2 + * @param string role name + * @param PEAR_Config + * @return PEAR_Installer_Role_Common + * @static */ - function toTgz(&$packager, $compress = true, $where = null) + function &factory($pkg, $role, &$config) { - require_once 'Archive/Tar.php'; - if ($where === null) { - if (!($where = System::mktemp(array('-d')))) { - return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: mktemp failed'); - } - } elseif (!@System::mkDir(array('-p', $where))) { - return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: "' . $where . '" could' . - ' not be created'); + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); } - if (file_exists($where . DIRECTORY_SEPARATOR . 'package.xml') && - !is_file($where . DIRECTORY_SEPARATOR . 'package.xml')) { - return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: unable to save package.xml as' . + + if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { + $a = false; + return $a; + } + + $a = 'PEAR_Installer_Role_' . ucfirst($role); + if (!class_exists($a)) { + require_once str_replace('_', '/', $a) . '.php'; + } + + $b = new $a($config); + return $b; + } + + /** + * Get a list of file roles that are valid for the particular release type. + * + * For instance, src files serve no purpose in regular php releases. + * @param string + * @param bool clear cache + * @return array + * @static + */ + function getValidRoles($release, $clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret = array(); + if ($clear) { + $ret = array(); + } + + if (isset($ret[$release])) { + return $ret[$release]; + } + + $ret[$release] = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if (in_array($release, $okreleases['releasetypes'])) { + $ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret[$release]; + } + + /** + * Get a list of roles that require their files to be installed + * + * Most roles must be installed, but src and package roles, for instance + * are pseudo-roles. src files are compiled into a new extension. Package + * roles are actually fully bundled releases of a package + * @param bool clear cache + * @return array + * @static + */ + function getInstallableRoles($clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret; + if ($clear) { + unset($ret); + } + + if (isset($ret)) { + return $ret; + } + + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['installable']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; + } + + /** + * Return an array of roles that are affected by the baseinstalldir attribute + * + * Most roles ignore this attribute, and instead install directly into: + * PackageName/filepath + * so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php + * @param bool clear cache + * @return array + * @static + */ + function getBaseinstallRoles($clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret; + if ($clear) { + unset($ret); + } + + if (isset($ret)) { + return $ret; + } + + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['honorsbaseinstall']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; + } + + /** + * Return an array of file roles that should be analyzed for PHP content at package time, + * like the "php" role. + * @param bool clear cache + * @return array + * @static + */ + function getPhpRoles($clear = false) + { + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } + + static $ret; + if ($clear) { + unset($ret); + } + + if (isset($ret)) { + return $ret; + } + + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['phpfile']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; + } + + /** + * Scan through the Command directory looking for classes + * and see what commands they implement. + * @param string which directory to look for classes, defaults to + * the Installer/Roles subdirectory of + * the directory from where this file (__FILE__) is + * included. + * + * @return bool TRUE on success, a PEAR error on failure + * @access public + * @static + */ + function registerRoles($dir = null) + { + $GLOBALS['_PEAR_INSTALLER_ROLES'] = array(); + $parser = new PEAR_XMLParser; + if ($dir === null) { + $dir = dirname(__FILE__) . '/Role'; + } + + if (!file_exists($dir) || !is_dir($dir)) { + return PEAR::raiseError("registerRoles: opendir($dir) failed: does not exist/is not directory"); + } + + $dp = @opendir($dir); + if (empty($dp)) { + return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg"); + } + + while ($entry = readdir($dp)) { + if ($entry{0} == '.' || substr($entry, -4) != '.xml') { + continue; + } + + $class = "PEAR_Installer_Role_".substr($entry, 0, -4); + // List of roles + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) { + $file = "$dir/$entry"; + $parser->parse(file_get_contents($file)); + $data = $parser->getData(); + if (!is_array($data['releasetypes'])) { + $data['releasetypes'] = array($data['releasetypes']); + } + + $GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data; + } + } + + closedir($dp); + ksort($GLOBALS['_PEAR_INSTALLER_ROLES']); + PEAR_Installer_Role::getBaseinstallRoles(true); + PEAR_Installer_Role::getInstallableRoles(true); + PEAR_Installer_Role::getPhpRoles(true); + PEAR_Installer_Role::getValidRoles('****', true); + return true; + } +}PEAR-1.9.0/PEAR/PackageFile/Generator/v1.php100664 764 764 142342 100664 13223 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: v1.php 286494 2009-07-29 06:57:11Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * needed for PEAR_VALIDATE_* constants + */ +require_once 'PEAR/Validate.php'; +require_once 'System.php'; +require_once 'PEAR/PackageFile/v2.php'; +/** + * This class converts a PEAR_PackageFile_v1 object into any output format. + * + * Supported output formats include array, XML string, and a PEAR_PackageFile_v2 + * object, for converting package.xml 1.0 into package.xml 2.0 with no sweat. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_Generator_v1 +{ + /** + * @var PEAR_PackageFile_v1 + */ + var $_packagefile; + function PEAR_PackageFile_Generator_v1(&$packagefile) + { + $this->_packagefile = &$packagefile; + } + + function getPackagerVersion() + { + return '1.9.0'; + } + + /** + * @param PEAR_Packager + * @param bool if true, a .tgz is written, otherwise a .tar is written + * @param string|null directory in which to save the .tgz + * @return string|PEAR_Error location of package or error object + */ + function toTgz(&$packager, $compress = true, $where = null) + { + require_once 'Archive/Tar.php'; + if ($where === null) { + if (!($where = System::mktemp(array('-d')))) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: mktemp failed'); + } + } elseif (!@System::mkDir(array('-p', $where))) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: "' . $where . '" could' . + ' not be created'); + } + if (file_exists($where . DIRECTORY_SEPARATOR . 'package.xml') && + !is_file($where . DIRECTORY_SEPARATOR . 'package.xml')) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: unable to save package.xml as' . ' "' . $where . DIRECTORY_SEPARATOR . 'package.xml"'); } if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) { @@ -19768,7 +20275,7 @@ class PEAR_PackageFile_Generator_v1 ); $ret = "\n"; $ret .= "\n"; - $ret .= "\n" . + $ret .= "\n" . " $pkginfo[package]"; if (isset($pkginfo['extends'])) { $ret .= "\n$pkginfo[extends]"; @@ -20783,16 +21290,15 @@ class PEAR_PackageFile_Generator_v1 */ function _processMultipleDepsName($deps) { - $tests = array(); + $ret = $tests = array(); foreach ($deps as $name => $dep) { foreach ($dep as $d) { $tests[$name][] = $this->_processDep($d); } } + foreach ($tests as $name => $test) { - $php = array(); - $min = array(); - $max = array(); + $max = $min = $php = array(); $php['name'] = $name; foreach ($test as $dep) { if (!$dep) { @@ -20850,7 +21356,7 @@ class PEAR_PackageFile_Generator_v1 return $ret; } } -?>PEAR-1.8.0/PEAR/PackageFile/Generator/v2.php100664 764 764 101226 100664 13217 PEAR-1.9.0/PEAR/PackageFile/Generator/v2.php100664 764 764 101360 100664 13217 options['beautifyFilelist'] = true; } - $arr['attribs']['packagerversion'] = '1.8.0'; + $arr['attribs']['packagerversion'] = '1.9.0'; if ($this->serialize($arr, $options)) { return $this->_serializedData . "\n"; } @@ -21723,7 +22230,7 @@ http://pear.php.net/dtd/package-2.0.xsd', if ($this->options['encoding'] == 'UTF-8' && version_compare(phpversion(), '5.0.0', 'lt') ) { - $tag = utf8_encode($tag); + $tag['content'] = utf8_encode($tag['content']); } if ($replaceEntities === true) { @@ -21741,7 +22248,7 @@ http://pear.php.net/dtd/package-2.0.xsd', } return $tag; } -}PEAR-1.8.0/PEAR/PackageFile/Parser/v1.php100664 764 764 40317 100664 12507 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v1.php,v 1.30 2009/02/24 23:45:22 dufuz Exp $ + * @version CVS: $Id: v1.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -22199,7 +22706,7 @@ class PEAR_PackageFile_Parser_v1 // }}} } -?>PEAR-1.8.0/PEAR/PackageFile/Parser/v2.php100664 764 764 6220 100664 12463 PEAR-1.9.0/PEAR/PackageFile/Parser/v2.php100664 764 764 6215 100664 12470 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v2.php,v 1.24 2009/02/24 23:45:22 dufuz Exp $ + * @version CVS: $Id: v2.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -22311,7 +22818,7 @@ class PEAR_PackageFile_Parser_v2 extends PEAR_XMLParser $ret->setPackagefile($file, $archive); return $ret; } -}PEAR-1.8.0/PEAR/PackageFile/v2/rw.php100664 764 764 173213 100664 11726 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: rw.php,v 1.25 2009/02/24 23:46:03 dufuz Exp $ + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a8 */ @@ -22336,7 +22843,7 @@ require_once 'PEAR/PackageFile/v2.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a8 */ @@ -23914,7 +24421,7 @@ class PEAR_PackageFile_v2_rw extends PEAR_PackageFile_v2 { unset($this->_packageInfo['changelog']); } -}PEAR-1.8.0/PEAR/PackageFile/v2/Validator.php100664 764 764 250045 100664 13222 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Validator.php,v 1.110 2009/03/27 19:29:31 dufuz Exp $ + * @version CVS: $Id: Validator.php 277885 2009-03-27 19:29:31Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a8 */ @@ -23937,7 +24444,7 @@ class PEAR_PackageFile_v2_rw extends PEAR_PackageFile_v2 * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a8 * @access private @@ -24028,7 +24535,7 @@ class PEAR_PackageFile_v2_Validator isset($test['dependencies']['required']) && isset($test['dependencies']['required']['pearinstaller']) && isset($test['dependencies']['required']['pearinstaller']['min']) && - version_compare('1.8.0', + version_compare('1.9.0', $test['dependencies']['required']['pearinstaller']['min'], '<') ) { $this->_pearVersionTooLow($test['dependencies']['required']['pearinstaller']['min']); @@ -25267,7 +25774,7 @@ class PEAR_PackageFile_v2_Validator $this->_stack->push(__FUNCTION__, 'error', array('version' => $version), 'This package.xml requires PEAR version %version% to parse properly, we are ' . - 'version 1.8.0'); + 'version 1.9.0'); } function _invalidTagOrder($oktags, $actual, $root) @@ -26067,1621 +26574,9 @@ class PEAR_PackageFile_v2_Validator return $providesret; } -}PEAR-1.8.0/PEAR/PackageFile/v1.php100664 764 764 147077 100664 11306 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v1.php,v 1.75 2009/02/24 23:39:16 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/** - * For error handling - */ -require_once 'PEAR/ErrorStack.php'; - -/** - * Error code if parsing is attempted with no xml extension - */ -define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3); - -/** - * Error code if creating the xml parser resource fails - */ -define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4); - -/** - * Error code used for all sax xml parsing errors - */ -define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5); - -/** - * Error code used when there is no name - */ -define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6); - -/** - * Error code when a package name is not valid - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7); - -/** - * Error code used when no summary is parsed - */ -define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8); - -/** - * Error code for summaries that are more than 1 line - */ -define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9); - -/** - * Error code used when no description is present - */ -define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10); - -/** - * Error code used when no license is present - */ -define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11); - -/** - * Error code used when a version number is not present - */ -define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12); - -/** - * Error code used when a version number is invalid - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13); - -/** - * Error code when release state is missing - */ -define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14); - -/** - * Error code when release state is invalid - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15); - -/** - * Error code when release state is missing - */ -define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16); - -/** - * Error code when release state is invalid - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17); - -/** - * Error code when no release notes are found - */ -define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18); - -/** - * Error code when no maintainers are found - */ -define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19); - -/** - * Error code when a maintainer has no handle - */ -define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20); - -/** - * Error code when a maintainer has no handle - */ -define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21); - -/** - * Error code when a maintainer has no name - */ -define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22); - -/** - * Error code when a maintainer has no email - */ -define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23); - -/** - * Error code when a maintainer has no handle - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24); - -/** - * Error code when a dependency is not a PHP dependency, but has no name - */ -define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25); - -/** - * Error code when a dependency has no type (pkg, php, etc.) - */ -define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26); - -/** - * Error code when a dependency has no relation (lt, ge, has, etc.) - */ -define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27); - -/** - * Error code when a dependency is not a 'has' relation, but has no version - */ -define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28); - -/** - * Error code when a dependency has an invalid relation - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29); - -/** - * Error code when a dependency has an invalid type - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30); - -/** - * Error code when a dependency has an invalid optional option - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31); - -/** - * Error code when a dependency is a pkg dependency, and has an invalid package name - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32); - -/** - * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel - */ -define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33); - -/** - * Error code when rel="has" and version attribute is present. - */ -define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34); - -/** - * Error code when type="php" and dependency name is present - */ -define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35); - -/** - * Error code when a configure option has no name - */ -define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36); - -/** - * Error code when a configure option has no name - */ -define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37); - -/** - * Error code when a file in the filelist has an invalid role - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38); - -/** - * Error code when a file in the filelist has no role - */ -define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39); - -/** - * Error code when analyzing a php source file that has parse errors - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40); - -/** - * Error code when analyzing a php source file reveals a source element - * without a package name prefix - */ -define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41); - -/** - * Error code when an unknown channel is specified - */ -define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42); - -/** - * Error code when no files are found in the filelist - */ -define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43); - -/** - * Error code when a file is not valid php according to _analyzeSourceCode() - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44); - -/** - * Error code when the channel validator returns an error or warning - */ -define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45); - -/** - * Error code when a php5 package is packaged in php4 (analysis doesn't work) - */ -define('PEAR_PACKAGEFILE_ERROR_PHP5', 46); - -/** - * Error code when a file is listed in package.xml but does not exist - */ -define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47); - -/** - * Error code when a - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_PackageFile_v1 -{ - /** - * @access private - * @var PEAR_ErrorStack - * @access private - */ - var $_stack; - - /** - * A registry object, used to access the package name validation regex for non-standard channels - * @var PEAR_Registry - * @access private - */ - var $_registry; - - /** - * An object that contains a log method that matches PEAR_Common::log's signature - * @var object - * @access private - */ - var $_logger; - - /** - * Parsed package information - * @var array - * @access private - */ - var $_packageInfo; - - /** - * path to package.xml - * @var string - * @access private - */ - var $_packageFile; - - /** - * path to package .tgz or false if this is a local/extracted package.xml - * @var string - * @access private - */ - var $_archiveFile; - - /** - * @var int - * @access private - */ - var $_isValid = 0; - - /** - * Determines whether this packagefile was initialized only with partial package info - * - * If this package file was constructed via parsing REST, it will only contain - * - * - package name - * - channel name - * - dependencies - * @var boolean - * @access private - */ - var $_incomplete = true; - - /** - * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack - * @param string Name of Error Stack class to use. - */ - function PEAR_PackageFile_v1() - { - $this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1'); - $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); - $this->_isValid = 0; - } - - function installBinary($installer) - { - return false; - } - - function isExtension($name) - { - return false; - } - - function setConfig(&$config) - { - $this->_config = &$config; - $this->_registry = &$config->getRegistry(); - } - - function setRequestedGroup() - { - // placeholder - } - - /** - * For saving in the registry. - * - * Set the last version that was installed - * @param string - */ - function setLastInstalledVersion($version) - { - $this->_packageInfo['_lastversion'] = $version; - } - - /** - * @return string|false - */ - function getLastInstalledVersion() - { - if (isset($this->_packageInfo['_lastversion'])) { - return $this->_packageInfo['_lastversion']; - } - return false; - } - - function getInstalledBinary() - { - return false; - } - - function listPostinstallScripts() - { - return false; - } - - function initPostinstallScripts() - { - return false; - } - - function setLogger(&$logger) - { - if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) { - return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); - } - $this->_logger = &$logger; - } - - function setPackagefile($file, $archive = false) - { - $this->_packageFile = $file; - $this->_archiveFile = $archive ? $archive : $file; - } - - function getPackageFile() - { - return isset($this->_packageFile) ? $this->_packageFile : false; - } - - function getPackageType() - { - return 'php'; - } - - function getArchiveFile() - { - return $this->_archiveFile; - } - - function packageInfo($field) - { - if (!is_string($field) || empty($field) || - !isset($this->_packageInfo[$field])) { - return false; - } - return $this->_packageInfo[$field]; - } - - function setDirtree($path) - { - if (!isset($this->_packageInfo['dirtree'])) { - $this->_packageInfo['dirtree'] = array(); - } - $this->_packageInfo['dirtree'][$path] = true; - } - - function getDirtree() - { - if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { - return $this->_packageInfo['dirtree']; - } - return false; - } - - function resetDirtree() - { - unset($this->_packageInfo['dirtree']); - } - - function fromArray($pinfo) - { - $this->_incomplete = false; - $this->_packageInfo = $pinfo; - } - - function isIncomplete() - { - return $this->_incomplete; - } - - function getChannel() - { - return 'pear.php.net'; - } - - function getUri() - { - return false; - } - - function getTime() - { - return false; - } - - function getExtends() - { - if (isset($this->_packageInfo['extends'])) { - return $this->_packageInfo['extends']; - } - return false; - } - - /** - * @return array - */ - function toArray() - { - if (!$this->validate(PEAR_VALIDATE_NORMAL)) { - return false; - } - return $this->getArray(); - } - - function getArray() - { - return $this->_packageInfo; - } - - function getName() - { - return $this->getPackage(); - } - - function getPackage() - { - if (isset($this->_packageInfo['package'])) { - return $this->_packageInfo['package']; - } - return false; - } - - /** - * WARNING - don't use this unless you know what you are doing - */ - function setRawPackage($package) - { - $this->_packageInfo['package'] = $package; - } - - function setPackage($package) - { - $this->_packageInfo['package'] = $package; - $this->_isValid = false; - } - - function getVersion() - { - if (isset($this->_packageInfo['version'])) { - return $this->_packageInfo['version']; - } - return false; - } - - function setVersion($version) - { - $this->_packageInfo['version'] = $version; - $this->_isValid = false; - } - - function clearMaintainers() - { - unset($this->_packageInfo['maintainers']); - } - - function getMaintainers() - { - if (isset($this->_packageInfo['maintainers'])) { - return $this->_packageInfo['maintainers']; - } - return false; - } - - /** - * Adds a new maintainer - no checking of duplicates is performed, use - * updatemaintainer for that purpose. - */ - function addMaintainer($role, $handle, $name, $email) - { - $this->_packageInfo['maintainers'][] = - array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name); - $this->_isValid = false; - } - - function updateMaintainer($role, $handle, $name, $email) - { - $found = false; - if (!isset($this->_packageInfo['maintainers']) || - !is_array($this->_packageInfo['maintainers'])) { - return $this->addMaintainer($role, $handle, $name, $email); - } - foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { - if ($maintainer['handle'] == $handle) { - $found = $i; - break; - } - } - if ($found !== false) { - unset($this->_packageInfo['maintainers'][$found]); - $this->_packageInfo['maintainers'] = - array_values($this->_packageInfo['maintainers']); - } - $this->addMaintainer($role, $handle, $name, $email); - } - - function deleteMaintainer($handle) - { - $found = false; - foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { - if ($maintainer['handle'] == $handle) { - $found = $i; - break; - } - } - if ($found !== false) { - unset($this->_packageInfo['maintainers'][$found]); - $this->_packageInfo['maintainers'] = - array_values($this->_packageInfo['maintainers']); - return true; - } - return false; - } - - function getState() - { - if (isset($this->_packageInfo['release_state'])) { - return $this->_packageInfo['release_state']; - } - return false; - } - - function setRawState($state) - { - $this->_packageInfo['release_state'] = $state; - } - - function setState($state) - { - $this->_packageInfo['release_state'] = $state; - $this->_isValid = false; - } - - function getDate() - { - if (isset($this->_packageInfo['release_date'])) { - return $this->_packageInfo['release_date']; - } - return false; - } - - function setDate($date) - { - $this->_packageInfo['release_date'] = $date; - $this->_isValid = false; - } - - function getLicense() - { - if (isset($this->_packageInfo['release_license'])) { - return $this->_packageInfo['release_license']; - } - return false; - } - - function setLicense($date) - { - $this->_packageInfo['release_license'] = $date; - $this->_isValid = false; - } - - function getSummary() - { - if (isset($this->_packageInfo['summary'])) { - return $this->_packageInfo['summary']; - } - return false; - } - - function setSummary($summary) - { - $this->_packageInfo['summary'] = $summary; - $this->_isValid = false; - } - - function getDescription() - { - if (isset($this->_packageInfo['description'])) { - return $this->_packageInfo['description']; - } - return false; - } - - function setDescription($desc) - { - $this->_packageInfo['description'] = $desc; - $this->_isValid = false; - } - - function getNotes() - { - if (isset($this->_packageInfo['release_notes'])) { - return $this->_packageInfo['release_notes']; - } - return false; - } - - function setNotes($notes) - { - $this->_packageInfo['release_notes'] = $notes; - $this->_isValid = false; - } - - function getDeps() - { - if (isset($this->_packageInfo['release_deps'])) { - return $this->_packageInfo['release_deps']; - } - return false; - } - - /** - * Reset dependencies prior to adding new ones - */ - function clearDeps() - { - unset($this->_packageInfo['release_deps']); - } - - function addPhpDep($version, $rel) - { - $this->_isValid = false; - $this->_packageInfo['release_deps'][] = - array('type' => 'php', - 'rel' => $rel, - 'version' => $version); - } - - function addPackageDep($name, $version, $rel, $optional = 'no') - { - $this->_isValid = false; - $dep = - array('type' => 'pkg', - 'name' => $name, - 'rel' => $rel, - 'optional' => $optional); - if ($rel != 'has' && $rel != 'not') { - $dep['version'] = $version; - } - $this->_packageInfo['release_deps'][] = $dep; - } - - function addExtensionDep($name, $version, $rel, $optional = 'no') - { - $this->_isValid = false; - $this->_packageInfo['release_deps'][] = - array('type' => 'ext', - 'name' => $name, - 'rel' => $rel, - 'version' => $version, - 'optional' => $optional); - } - - /** - * WARNING - do not use this function directly unless you know what you're doing - */ - function setDeps($deps) - { - $this->_packageInfo['release_deps'] = $deps; - } - - function hasDeps() - { - return isset($this->_packageInfo['release_deps']) && - count($this->_packageInfo['release_deps']); - } - - function getDependencyGroup($group) - { - return false; - } - - function isCompatible($pf) - { - return false; - } - - function isSubpackageOf($p) - { - return $p->isSubpackage($this); - } - - function isSubpackage($p) - { - return false; - } - - function dependsOn($package, $channel) - { - if (strtolower($channel) != 'pear.php.net') { - return false; - } - if (!($deps = $this->getDeps())) { - return false; - } - foreach ($deps as $dep) { - if ($dep['type'] != 'pkg') { - continue; - } - if (strtolower($dep['name']) == strtolower($package)) { - return true; - } - } - return false; - } - - function getConfigureOptions() - { - if (isset($this->_packageInfo['configure_options'])) { - return $this->_packageInfo['configure_options']; - } - return false; - } - - function hasConfigureOptions() - { - return isset($this->_packageInfo['configure_options']) && - count($this->_packageInfo['configure_options']); - } - - function addConfigureOption($name, $prompt, $default = false) - { - $o = array('name' => $name, 'prompt' => $prompt); - if ($default !== false) { - $o['default'] = $default; - } - if (!isset($this->_packageInfo['configure_options'])) { - $this->_packageInfo['configure_options'] = array(); - } - $this->_packageInfo['configure_options'][] = $o; - } - - function clearConfigureOptions() - { - unset($this->_packageInfo['configure_options']); - } - - function getProvides() - { - if (isset($this->_packageInfo['provides'])) { - return $this->_packageInfo['provides']; - } - return false; - } - - function getProvidesExtension() - { - return false; - } - - function addFile($dir, $file, $attrs) - { - $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); - if ($dir == '/' || $dir == '') { - $dir = ''; - } else { - $dir .= '/'; - } - $file = $dir . $file; - $file = preg_replace('![\\/]+!', '/', $file); - $this->_packageInfo['filelist'][$file] = $attrs; - } - - function getInstallationFilelist() - { - return $this->getFilelist(); - } - - function getFilelist() - { - if (isset($this->_packageInfo['filelist'])) { - return $this->_packageInfo['filelist']; - } - return false; - } - - function setFileAttribute($file, $attr, $value) - { - $this->_packageInfo['filelist'][$file][$attr] = $value; - } - - function resetFilelist() - { - $this->_packageInfo['filelist'] = array(); - } - - function setInstalledAs($file, $path) - { - if ($path) { - return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; - } - unset($this->_packageInfo['filelist'][$file]['installed_as']); - } - - function installedFile($file, $atts) - { - if (isset($this->_packageInfo['filelist'][$file])) { - $this->_packageInfo['filelist'][$file] = - array_merge($this->_packageInfo['filelist'][$file], $atts); - } else { - $this->_packageInfo['filelist'][$file] = $atts; - } - } - - function getChangelog() - { - if (isset($this->_packageInfo['changelog'])) { - return $this->_packageInfo['changelog']; - } - return false; - } - - function getPackagexmlVersion() - { - return '1.0'; - } - - /** - * Wrapper to {@link PEAR_ErrorStack::getErrors()} - * @param boolean determines whether to purge the error stack after retrieving - * @return array - */ - function getValidationWarnings($purge = true) - { - return $this->_stack->getErrors($purge); - } - - // }}} - /** - * Validation error. Also marks the object contents as invalid - * @param error code - * @param array error information - * @access private - */ - function _validateError($code, $params = array()) - { - $this->_stack->push($code, 'error', $params, false, false, debug_backtrace()); - $this->_isValid = false; - } - - /** - * Validation warning. Does not mark the object contents invalid. - * @param error code - * @param array error information - * @access private - */ - function _validateWarning($code, $params = array()) - { - $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace()); - } - - /** - * @param integer error code - * @access protected - */ - function _getErrorMessage() - { - return array( - PEAR_PACKAGEFILE_ERROR_NO_NAME => - 'Missing Package Name', - PEAR_PACKAGEFILE_ERROR_NO_SUMMARY => - 'No summary found', - PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY => - 'Summary should be on one line', - PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION => - 'Missing description', - PEAR_PACKAGEFILE_ERROR_NO_LICENSE => - 'Missing license', - PEAR_PACKAGEFILE_ERROR_NO_VERSION => - 'No release version found', - PEAR_PACKAGEFILE_ERROR_NO_STATE => - 'No release state found', - PEAR_PACKAGEFILE_ERROR_NO_DATE => - 'No release date found', - PEAR_PACKAGEFILE_ERROR_NO_NOTES => - 'No release notes found', - PEAR_PACKAGEFILE_ERROR_NO_LEAD => - 'Package must have at least one lead maintainer', - PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS => - 'No maintainers found, at least one must be defined', - PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE => - 'Maintainer %index% has no handle (user ID at channel server)', - PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE => - 'Maintainer %index% has no role', - PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME => - 'Maintainer %index% has no name', - PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL => - 'Maintainer %index% has no email', - PEAR_PACKAGEFILE_ERROR_NO_DEPNAME => - 'Dependency %index% is not a php dependency, and has no name', - PEAR_PACKAGEFILE_ERROR_NO_DEPREL => - 'Dependency %index% has no relation (rel)', - PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE => - 'Dependency %index% has no type', - PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED => - 'PHP Dependency %index% has a name attribute of "%name%" which will be' . - ' ignored!', - PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION => - 'Dependency %index% is not a rel="has" or rel="not" dependency, ' . - 'and has no version', - PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION => - 'Dependency %index% is a type="php" dependency, ' . - 'and has no version', - PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED => - 'Dependency %index% is a rel="%rel%" dependency, versioning is ignored', - PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL => - 'Dependency %index% has invalid optional value "%opt%", should be yes or no', - PEAR_PACKAGEFILE_PHP_NO_NOT => - 'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' . - ' to exclude specific versions', - PEAR_PACKAGEFILE_ERROR_NO_CONFNAME => - 'Configure Option %index% has no name', - PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT => - 'Configure Option %index% has no prompt', - PEAR_PACKAGEFILE_ERROR_NO_FILES => - 'No files in section of package.xml', - PEAR_PACKAGEFILE_ERROR_NO_FILEROLE => - 'File "%file%" has no role, expecting one of "%roles%"', - PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE => - 'File "%file%" has invalid role "%role%", expecting one of "%roles%"', - PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME => - 'File "%file%" cannot start with ".", cannot package or install', - PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE => - 'Parser error: invalid PHP found in file "%file%"', - PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX => - 'in %file%: %type% "%name%" not prefixed with package name "%package%"', - PEAR_PACKAGEFILE_ERROR_INVALID_FILE => - 'Parser error: invalid PHP file "%file%"', - PEAR_PACKAGEFILE_ERROR_CHANNELVAL => - 'Channel validator error: field "%field%" - %reason%', - PEAR_PACKAGEFILE_ERROR_PHP5 => - 'Error, PHP5 token encountered in %file%, analysis should be in PHP5', - PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND => - 'File "%file%" in package.xml does not exist', - PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS => - 'Package.xml contains non-ISO-8859-1 characters, and may not validate', - ); - } - - /** - * Validate XML package definition file. - * - * @access public - * @return boolean - */ - function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false) - { - if (($this->_isValid & $state) == $state) { - return true; - } - $this->_isValid = true; - $info = $this->_packageInfo; - if (empty($info['package'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME); - $this->_packageName = $pn = 'unknown'; - } else { - $this->_packageName = $pn = $info['package']; - } - - if (empty($info['summary'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY); - } elseif (strpos(trim($info['summary']), "\n") !== false) { - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY, - array('summary' => $info['summary'])); - } - if (empty($info['description'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION); - } - if (empty($info['release_license'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE); - } - if (empty($info['version'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION); - } - if (empty($info['release_state'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE); - } - if (empty($info['release_date'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE); - } - if (empty($info['release_notes'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES); - } - if (empty($info['maintainers'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS); - } else { - $haslead = false; - $i = 1; - foreach ($info['maintainers'] as $m) { - if (empty($m['handle'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE, - array('index' => $i)); - } - if (empty($m['role'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE, - array('index' => $i, 'roles' => PEAR_Common::getUserRoles())); - } elseif ($m['role'] == 'lead') { - $haslead = true; - } - if (empty($m['name'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME, - array('index' => $i)); - } - if (empty($m['email'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL, - array('index' => $i)); - } - $i++; - } - if (!$haslead) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD); - } - } - if (!empty($info['release_deps'])) { - $i = 1; - foreach ($info['release_deps'] as $d) { - if (!isset($d['type']) || empty($d['type'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE, - array('index' => $i, 'types' => PEAR_Common::getDependencyTypes())); - continue; - } - if (!isset($d['rel']) || empty($d['rel'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL, - array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations())); - continue; - } - if (!empty($d['optional'])) { - if (!in_array($d['optional'], array('yes', 'no'))) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL, - array('index' => $i, 'opt' => $d['optional'])); - } - } - if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION, - array('index' => $i)); - } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) { - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED, - array('index' => $i, 'rel' => $d['rel'])); - } - if ($d['type'] == 'php' && !empty($d['name'])) { - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED, - array('index' => $i, 'name' => $d['name'])); - } elseif ($d['type'] != 'php' && empty($d['name'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME, - array('index' => $i)); - } - if ($d['type'] == 'php' && empty($d['version'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION, - array('index' => $i)); - } - if (($d['rel'] == 'not') && ($d['type'] == 'php')) { - $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT, - array('index' => $i)); - } - $i++; - } - } - if (!empty($info['configure_options'])) { - $i = 1; - foreach ($info['configure_options'] as $c) { - if (empty($c['name'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME, - array('index' => $i)); - } - if (empty($c['prompt'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT, - array('index' => $i)); - } - $i++; - } - } - if (empty($info['filelist'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES); - $errors[] = 'no files'; - } else { - foreach ($info['filelist'] as $file => $fa) { - if (empty($fa['role'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE, - array('file' => $file, 'roles' => PEAR_Common::getFileRoles())); - continue; - } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE, - array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles())); - } - if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) { - // file contains .. parent directory or . cur directory references - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, - array('file' => $file)); - } - if (isset($fa['install-as']) && - preg_match('~/\.\.?(/|\\z)|^\.\.?/~', - str_replace('\\', '/', $fa['install-as']))) { - // install-as contains .. parent directory or . cur directory references - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, - array('file' => $file . ' [installed as ' . $fa['install-as'] . ']')); - } - if (isset($fa['baseinstalldir']) && - preg_match('~/\.\.?(/|\\z)|^\.\.?/~', - str_replace('\\', '/', $fa['baseinstalldir']))) { - // install-as contains .. parent directory or . cur directory references - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, - array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']')); - } - } - } - if (isset($this->_registry) && $this->_isValid) { - $chan = $this->_registry->getChannel('pear.php.net'); - if (PEAR::isError($chan)) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage()); - return $this->_isValid = 0; - } - $validator = $chan->getValidationObject(); - $validator->setPackageFile($this); - $validator->validate($state); - $failures = $validator->getFailures(); - foreach ($failures['errors'] as $error) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error); - } - foreach ($failures['warnings'] as $warning) { - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning); - } - } - if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) { - if ($this->_analyzePhpFiles()) { - $this->_isValid = true; - } - } - if ($this->_isValid) { - return $this->_isValid = $state; - } - return $this->_isValid = 0; - } - - function _analyzePhpFiles() - { - if (!$this->_isValid) { - return false; - } - if (!isset($this->_packageFile)) { - return false; - } - $dir_prefix = dirname($this->_packageFile); - $common = new PEAR_Common; - $log = isset($this->_logger) ? array(&$this->_logger, 'log') : - array($common, 'log'); - $info = $this->getFilelist(); - foreach ($info as $file => $fa) { - if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND, - array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file)); - continue; - } - if ($fa['role'] == 'php' && $dir_prefix) { - call_user_func_array($log, array(1, "Analyzing $file")); - $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); - if ($srcinfo) { - $this->_buildProvidesArray($srcinfo); - } - } - } - $this->_packageName = $pn = $this->getPackage(); - $pnl = strlen($pn); - if (isset($this->_packageInfo['provides'])) { - foreach ((array) $this->_packageInfo['provides'] as $key => $what) { - if (isset($what['explicit'])) { - // skip conformance checks if the provides entry is - // specified in the package.xml file - continue; - } - extract($what); - if ($type == 'class') { - if (!strncasecmp($name, $pn, $pnl)) { - continue; - } - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, - array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); - } elseif ($type == 'function') { - if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { - continue; - } - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, - array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); - } - } - } - return $this->_isValid; - } - - /** - * Get the default xml generator object - * - * @return PEAR_PackageFile_Generator_v1 - */ - function &getDefaultGenerator() - { - if (!class_exists('PEAR_PackageFile_Generator_v1')) { - require_once 'PEAR/PackageFile/Generator/v1.php'; - } - $a = &new PEAR_PackageFile_Generator_v1($this); - return $a; - } - - /** - * Get the contents of a file listed within the package.xml - * @param string - * @return string - */ - function getFileContents($file) - { - if ($this->_archiveFile == $this->_packageFile) { // unpacked - $dir = dirname($this->_packageFile); - $file = $dir . DIRECTORY_SEPARATOR . $file; - $file = str_replace(array('/', '\\'), - array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); - if (file_exists($file) && is_readable($file)) { - return implode('', file($file)); - } - } else { // tgz - if (!class_exists('Archive_Tar')) { - require_once 'Archive/Tar.php'; - } - $tar = &new Archive_Tar($this->_archiveFile); - $tar->pushErrorHandling(PEAR_ERROR_RETURN); - if ($file != 'package.xml' && $file != 'package2.xml') { - $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; - } - $file = $tar->extractInString($file); - $tar->popErrorHandling(); - if (PEAR::isError($file)) { - return PEAR::raiseError("Cannot locate file '$file' in archive"); - } - return $file; - } - } - - // {{{ analyzeSourceCode() - /** - * Analyze the source code of the given PHP file - * - * @param string Filename of the PHP file - * @return mixed - * @access private - */ - function _analyzeSourceCode($file) - { - if (!function_exists("token_get_all")) { - return false; - } - if (!defined('T_DOC_COMMENT')) { - define('T_DOC_COMMENT', T_COMMENT); - } - if (!defined('T_INTERFACE')) { - define('T_INTERFACE', -1); - } - if (!defined('T_IMPLEMENTS')) { - define('T_IMPLEMENTS', -1); - } - if (!$fp = @fopen($file, "r")) { - return false; - } - fclose($fp); - $contents = file_get_contents($file); - $tokens = token_get_all($contents); -/* - for ($i = 0; $i < sizeof($tokens); $i++) { - @list($token, $data) = $tokens[$i]; - if (is_string($token)) { - var_dump($token); - } else { - print token_name($token) . ' '; - var_dump(rtrim($data)); - } - } -*/ - $look_for = 0; - $paren_level = 0; - $bracket_level = 0; - $brace_level = 0; - $lastphpdoc = ''; - $current_class = ''; - $current_interface = ''; - $current_class_level = -1; - $current_function = ''; - $current_function_level = -1; - $declared_classes = array(); - $declared_interfaces = array(); - $declared_functions = array(); - $declared_methods = array(); - $used_classes = array(); - $used_functions = array(); - $extends = array(); - $implements = array(); - $nodeps = array(); - $inquote = false; - $interface = false; - for ($i = 0; $i < sizeof($tokens); $i++) { - if (is_array($tokens[$i])) { - list($token, $data) = $tokens[$i]; - } else { - $token = $tokens[$i]; - $data = ''; - } - if ($inquote) { - if ($token != '"' && $token != T_END_HEREDOC) { - continue; - } else { - $inquote = false; - continue; - } - } - switch ($token) { - case T_WHITESPACE : - continue; - case ';': - if ($interface) { - $current_function = ''; - $current_function_level = -1; - } - break; - case '"': - case T_START_HEREDOC: - $inquote = true; - break; - case T_CURLY_OPEN: - case T_DOLLAR_OPEN_CURLY_BRACES: - case '{': $brace_level++; continue 2; - case '}': - $brace_level--; - if ($current_class_level == $brace_level) { - $current_class = ''; - $current_class_level = -1; - } - if ($current_function_level == $brace_level) { - $current_function = ''; - $current_function_level = -1; - } - continue 2; - case '[': $bracket_level++; continue 2; - case ']': $bracket_level--; continue 2; - case '(': $paren_level++; continue 2; - case ')': $paren_level--; continue 2; - case T_INTERFACE: - $interface = true; - case T_CLASS: - if (($current_class_level != -1) || ($current_function_level != -1)) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, - array('file' => $file)); - return false; - } - case T_FUNCTION: - case T_NEW: - case T_EXTENDS: - case T_IMPLEMENTS: - $look_for = $token; - continue 2; - case T_STRING: - if (version_compare(zend_version(), '2.0', '<')) { - if (in_array(strtolower($data), - array('public', 'private', 'protected', 'abstract', - 'interface', 'implements', 'throw') - )) { - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5, - array($file)); - } - } - if ($look_for == T_CLASS) { - $current_class = $data; - $current_class_level = $brace_level; - $declared_classes[] = $current_class; - } elseif ($look_for == T_INTERFACE) { - $current_interface = $data; - $current_class_level = $brace_level; - $declared_interfaces[] = $current_interface; - } elseif ($look_for == T_IMPLEMENTS) { - $implements[$current_class] = $data; - } elseif ($look_for == T_EXTENDS) { - $extends[$current_class] = $data; - } elseif ($look_for == T_FUNCTION) { - if ($current_class) { - $current_function = "$current_class::$data"; - $declared_methods[$current_class][] = $data; - } elseif ($current_interface) { - $current_function = "$current_interface::$data"; - $declared_methods[$current_interface][] = $data; - } else { - $current_function = $data; - $declared_functions[] = $current_function; - } - $current_function_level = $brace_level; - $m = array(); - } elseif ($look_for == T_NEW) { - $used_classes[$data] = true; - } - $look_for = 0; - continue 2; - case T_VARIABLE: - $look_for = 0; - continue 2; - case T_DOC_COMMENT: - case T_COMMENT: - if (preg_match('!^/\*\*\s!', $data)) { - $lastphpdoc = $data; - if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { - $nodeps = array_merge($nodeps, $m[1]); - } - } - continue 2; - case T_DOUBLE_COLON: - if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, - array('file' => $file)); - return false; - } - $class = $tokens[$i - 1][1]; - if (strtolower($class) != 'parent') { - $used_classes[$class] = true; - } - continue 2; - } - } - return array( - "source_file" => $file, - "declared_classes" => $declared_classes, - "declared_interfaces" => $declared_interfaces, - "declared_methods" => $declared_methods, - "declared_functions" => $declared_functions, - "used_classes" => array_diff(array_keys($used_classes), $nodeps), - "inheritance" => $extends, - "implements" => $implements, - ); - } - - /** - * Build a "provides" array from data returned by - * analyzeSourceCode(). The format of the built array is like - * this: - * - * array( - * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), - * ... - * ) - * - * - * @param array $srcinfo array with information about a source file - * as returned by the analyzeSourceCode() method. - * - * @return void - * - * @access private - * - */ - function _buildProvidesArray($srcinfo) - { - if (!$this->_isValid) { - return false; - } - $file = basename($srcinfo['source_file']); - $pn = $this->getPackage(); - $pnl = strlen($pn); - foreach ($srcinfo['declared_classes'] as $class) { - $key = "class;$class"; - if (isset($this->_packageInfo['provides'][$key])) { - continue; - } - $this->_packageInfo['provides'][$key] = - array('file'=> $file, 'type' => 'class', 'name' => $class); - if (isset($srcinfo['inheritance'][$class])) { - $this->_packageInfo['provides'][$key]['extends'] = - $srcinfo['inheritance'][$class]; - } - } - foreach ($srcinfo['declared_methods'] as $class => $methods) { - foreach ($methods as $method) { - $function = "$class::$method"; - $key = "function;$function"; - if ($method{0} == '_' || !strcasecmp($method, $class) || - isset($this->_packageInfo['provides'][$key])) { - continue; - } - $this->_packageInfo['provides'][$key] = - array('file'=> $file, 'type' => 'function', 'name' => $function); - } - } - - foreach ($srcinfo['declared_functions'] as $function) { - $key = "function;$function"; - if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) { - continue; - } - if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { - $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; - } - $this->_packageInfo['provides'][$key] = - array('file'=> $file, 'type' => 'function', 'name' => $function); - } - } - - // }}} -} -?> -PEAR-1.8.0/PEAR/PackageFile/v2.php100664 764 764 207602 100664 11276 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v2.php,v 1.145 2009/02/24 23:39:16 dufuz Exp $ + * @version CVS: $Id: v1.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -27698,96 +26593,317 @@ class PEAR_PackageFile_v1 * For error handling */ require_once 'PEAR/ErrorStack.php'; + +/** + * Error code if parsing is attempted with no xml extension + */ +define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3); + +/** + * Error code if creating the xml parser resource fails + */ +define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4); + +/** + * Error code used for all sax xml parsing errors + */ +define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5); + +/** + * Error code used when there is no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6); + +/** + * Error code when a package name is not valid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7); + +/** + * Error code used when no summary is parsed + */ +define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8); + +/** + * Error code for summaries that are more than 1 line + */ +define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9); + +/** + * Error code used when no description is present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10); + +/** + * Error code used when no license is present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11); + +/** + * Error code used when a version number is not present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12); + +/** + * Error code used when a version number is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13); + +/** + * Error code when release state is missing + */ +define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14); + +/** + * Error code when release state is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15); + +/** + * Error code when release state is missing + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16); + +/** + * Error code when release state is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17); + +/** + * Error code when no release notes are found + */ +define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18); + +/** + * Error code when no maintainers are found + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21); + +/** + * Error code when a maintainer has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22); + +/** + * Error code when a maintainer has no email + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24); + +/** + * Error code when a dependency is not a PHP dependency, but has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25); + +/** + * Error code when a dependency has no type (pkg, php, etc.) + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26); + +/** + * Error code when a dependency has no relation (lt, ge, has, etc.) + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27); + +/** + * Error code when a dependency is not a 'has' relation, but has no version + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28); + +/** + * Error code when a dependency has an invalid relation + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29); + +/** + * Error code when a dependency has an invalid type + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30); + +/** + * Error code when a dependency has an invalid optional option + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31); + +/** + * Error code when a dependency is a pkg dependency, and has an invalid package name + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32); + +/** + * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel + */ +define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33); + +/** + * Error code when rel="has" and version attribute is present. + */ +define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34); + +/** + * Error code when type="php" and dependency name is present + */ +define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35); + +/** + * Error code when a configure option has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36); + +/** + * Error code when a configure option has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37); + +/** + * Error code when a file in the filelist has an invalid role + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38); + +/** + * Error code when a file in the filelist has no role + */ +define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39); + +/** + * Error code when analyzing a php source file that has parse errors + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40); + +/** + * Error code when analyzing a php source file reveals a source element + * without a package name prefix + */ +define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41); + +/** + * Error code when an unknown channel is specified + */ +define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42); + +/** + * Error code when no files are found in the filelist + */ +define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43); + +/** + * Error code when a file is not valid php according to _analyzeSourceCode() + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44); + +/** + * Error code when the channel validator returns an error or warning + */ +define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45); + +/** + * Error code when a php5 package is packaged in php4 (analysis doesn't work) + */ +define('PEAR_PACKAGEFILE_ERROR_PHP5', 46); + +/** + * Error code when a file is listed in package.xml but does not exist + */ +define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47); + +/** + * Error code when a * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ -class PEAR_PackageFile_v2 +class PEAR_PackageFile_v1 { - /** - * Parsed package information - * @var array + * @access private + * @var PEAR_ErrorStack * @access private */ - var $_packageInfo = array(); + var $_stack; /** - * path to package .tgz or false if this is a local/extracted package.xml - * @var string|false + * A registry object, used to access the package name validation regex for non-standard channels + * @var PEAR_Registry * @access private */ - var $_archiveFile; + var $_registry; /** - * path to package .xml or false if this is an abstract parsed-from-string xml - * @var string|false + * An object that contains a log method that matches PEAR_Common::log's signature + * @var object * @access private */ - var $_packageFile; + var $_logger; /** - * This is used by file analysis routines to log progress information - * @var PEAR_Common - * @access protected - */ - var $_logger; - - /** - * This is set to the highest validation level that has been validated - * - * If the package.xml is invalid or unknown, this is set to 0. If - * normal validation has occurred, this is set to PEAR_VALIDATE_NORMAL. If - * downloading/installation validation has occurred it is set to PEAR_VALIDATE_DOWNLOADING - * or INSTALLING, and so on up to PEAR_VALIDATE_PACKAGING. This allows validation - * "caching" to occur, which is particularly important for package validation, so - * that PHP files are not validated twice - * @var int + * Parsed package information + * @var array * @access private */ - var $_isValid = 0; - - /** - * True if the filelist has been validated - * @param bool - */ - var $_filesValid = false; - - /** - * @var PEAR_Registry - * @access protected - */ - var $_registry; - - /** - * @var PEAR_Config - * @access protected - */ - var $_config; + var $_packageInfo; /** - * Optional Dependency group requested for installation + * path to package.xml * @var string * @access private */ - var $_requestedGroup = false; + var $_packageFile; /** - * @var PEAR_ErrorStack - * @access protected + * path to package .tgz or false if this is a local/extracted package.xml + * @var string + * @access private */ - var $_stack; + var $_archiveFile; /** - * Namespace prefix used for tasks in this package.xml - use tasks: whenever possible + * @var int + * @access private */ - var $_tasksNs; + var $_isValid = 0; /** * Determines whether this packagefile was initialized only with partial package info @@ -27796,5335 +26912,3328 @@ class PEAR_PackageFile_v2 * * - package name * - channel name - * - dependencies + * - dependencies * @var boolean * @access private */ var $_incomplete = true; /** - * @var PEAR_PackageFile_v2_Validator + * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack + * @param string Name of Error Stack class to use. */ - var $_v2Validator; + function PEAR_PackageFile_v1() + { + $this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1'); + $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); + $this->_isValid = 0; + } - /** - * The constructor merely sets up the private error stack - */ - function PEAR_PackageFile_v2() + function installBinary($installer) { - $this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null); - $this->_isValid = false; + return false; } - /** - * To make unit-testing easier - * @param PEAR_Frontend_* - * @param array options - * @param PEAR_Config - * @return PEAR_Downloader - * @access protected - */ - function &getPEARDownloader(&$i, $o, &$c) + function isExtension($name) { - $z = &new PEAR_Downloader($i, $o, $c); - return $z; + return false; } - /** - * To make unit-testing easier - * @param PEAR_Config - * @param array options - * @param array package name as returned from {@link PEAR_Registry::parsePackageName()} - * @param int PEAR_VALIDATE_* constant - * @return PEAR_Dependency2 - * @access protected - */ - function &getPEARDependency2(&$c, $o, $p, $s = PEAR_VALIDATE_INSTALLING) + function setConfig(&$config) { - if (!class_exists('PEAR_Dependency2')) { - require_once 'PEAR/Dependency2.php'; - } - $z = &new PEAR_Dependency2($c, $o, $p, $s); - return $z; + $this->_config = &$config; + $this->_registry = &$config->getRegistry(); } - function getInstalledBinary() + function setRequestedGroup() { - return isset($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] : - false; + // placeholder } /** - * Installation of source package has failed, attempt to download and install the - * binary version of this package. - * @param PEAR_Installer - * @return array|false + * For saving in the registry. + * + * Set the last version that was installed + * @param string */ - function installBinary(&$installer) + function setLastInstalledVersion($version) { - if (!OS_WINDOWS) { - $a = false; - return $a; - } - if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { - $releasetype = $this->getPackageType() . 'release'; - if (!is_array($installer->getInstallPackages())) { - $a = false; - return $a; - } - foreach ($installer->getInstallPackages() as $p) { - if ($p->isExtension($this->_packageInfo['providesextension'])) { - if ($p->getPackageType() != 'extsrc' && $p->getPackageType() != 'zendextsrc') { - $a = false; - return $a; // the user probably downloaded it separately - } - } - } - if (isset($this->_packageInfo[$releasetype]['binarypackage'])) { - $installer->log(0, 'Attempting to download binary version of extension "' . - $this->_packageInfo['providesextension'] . '"'); - $params = $this->_packageInfo[$releasetype]['binarypackage']; - if (!is_array($params) || !isset($params[0])) { - $params = array($params); - } - if (isset($this->_packageInfo['channel'])) { - foreach ($params as $i => $param) { - $params[$i] = array('channel' => $this->_packageInfo['channel'], - 'package' => $param, 'version' => $this->getVersion()); - } - } - $dl = &$this->getPEARDownloader($installer->ui, $installer->getOptions(), - $installer->config); - $verbose = $dl->config->get('verbose'); - $dl->config->set('verbose', -1); - foreach ($params as $param) { - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $ret = $dl->download(array($param)); - PEAR::popErrorHandling(); - if (is_array($ret) && count($ret)) { - break; - } - } - $dl->config->set('verbose', $verbose); - if (is_array($ret)) { - if (count($ret) == 1) { - $pf = $ret[0]->getPackageFile(); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $err = $installer->install($ret[0]); - PEAR::popErrorHandling(); - if (is_array($err)) { - $this->_packageInfo['#binarypackage'] = $ret[0]->getPackage(); - // "install" self, so all dependencies will work transparently - $this->_registry->addPackage2($this); - $installer->log(0, 'Download and install of binary extension "' . - $this->_registry->parsedPackageNameToString( - array('channel' => $pf->getChannel(), - 'package' => $pf->getPackage()), true) . '" successful'); - $a = array($ret[0], $err); - return $a; - } - $installer->log(0, 'Download and install of binary extension "' . - $this->_registry->parsedPackageNameToString( - array('channel' => $pf->getChannel(), - 'package' => $pf->getPackage()), true) . '" failed'); - } - } - } - } - $a = false; - return $a; + $this->_packageInfo['_lastversion'] = $version; } /** - * @return string|false Extension name + * @return string|false */ - function getProvidesExtension() + function getLastInstalledVersion() { - if (in_array($this->getPackageType(), - array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { - if (isset($this->_packageInfo['providesextension'])) { - return $this->_packageInfo['providesextension']; - } + if (isset($this->_packageInfo['_lastversion'])) { + return $this->_packageInfo['_lastversion']; } return false; } - /** - * @param string Extension name - * @return bool - */ - function isExtension($extension) + function getInstalledBinary() { - if (in_array($this->getPackageType(), - array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { - return $this->_packageInfo['providesextension'] == $extension; - } return false; } - /** - * Tests whether every part of the package.xml 1.0 is represented in - * this package.xml 2.0 - * @param PEAR_PackageFile_v1 - * @return bool - */ - function isEquivalent($pf1) + function listPostinstallScripts() { - if (!$pf1) { - return true; - } - if ($this->getPackageType() == 'bundle') { - return false; - } - $this->_stack->getErrors(true); - if (!$pf1->validate(PEAR_VALIDATE_NORMAL)) { - return false; - } - $pass = true; - if ($pf1->getPackage() != $this->getPackage()) { - $this->_differentPackage($pf1->getPackage()); - $pass = false; - } - if ($pf1->getVersion() != $this->getVersion()) { - $this->_differentVersion($pf1->getVersion()); - $pass = false; - } - if (trim($pf1->getSummary()) != $this->getSummary()) { - $this->_differentSummary($pf1->getSummary()); - $pass = false; - } - if (preg_replace('/\s+/', '', $pf1->getDescription()) != - preg_replace('/\s+/', '', $this->getDescription())) { - $this->_differentDescription($pf1->getDescription()); - $pass = false; - } - if ($pf1->getState() != $this->getState()) { - $this->_differentState($pf1->getState()); - $pass = false; - } - if (!strstr(preg_replace('/\s+/', '', $this->getNotes()), - preg_replace('/\s+/', '', $pf1->getNotes()))) { - $this->_differentNotes($pf1->getNotes()); - $pass = false; - } - $mymaintainers = $this->getMaintainers(); - $yourmaintainers = $pf1->getMaintainers(); - for ($i1 = 0; $i1 < count($yourmaintainers); $i1++) { - $reset = false; - for ($i2 = 0; $i2 < count($mymaintainers); $i2++) { - if ($mymaintainers[$i2]['handle'] == $yourmaintainers[$i1]['handle']) { - if ($mymaintainers[$i2]['role'] != $yourmaintainers[$i1]['role']) { - $this->_differentRole($mymaintainers[$i2]['handle'], - $yourmaintainers[$i1]['role'], $mymaintainers[$i2]['role']); - $pass = false; - } - if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) { - $this->_differentEmail($mymaintainers[$i2]['handle'], - $yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']); - $pass = false; - } - if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) { - $this->_differentName($mymaintainers[$i2]['handle'], - $yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']); - $pass = false; - } - unset($mymaintainers[$i2]); - $mymaintainers = array_values($mymaintainers); - unset($yourmaintainers[$i1]); - $yourmaintainers = array_values($yourmaintainers); - $reset = true; - break; - } - } - if ($reset) { - $i1 = -1; - } - } - $this->_unmatchedMaintainers($mymaintainers, $yourmaintainers); - $filelist = $this->getFilelist(); - foreach ($pf1->getFilelist() as $file => $atts) { - if (!isset($filelist[$file])) { - $this->_missingFile($file); - $pass = false; - } - } - return $pass; + return false; } - function _differentPackage($package) + function initPostinstallScripts() { - $this->_stack->push(__FUNCTION__, 'error', array('package' => $package, - 'self' => $this->getPackage()), - 'package.xml 1.0 package "%package%" does not match "%self%"'); + return false; } - function _differentVersion($version) + function setLogger(&$logger) { - $this->_stack->push(__FUNCTION__, 'error', array('version' => $version, - 'self' => $this->getVersion()), - 'package.xml 1.0 version "%version%" does not match "%self%"'); + if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) { + return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); + } + $this->_logger = &$logger; } - function _differentState($state) + function setPackagefile($file, $archive = false) { - $this->_stack->push(__FUNCTION__, 'error', array('state' => $state, - 'self' => $this->getState()), - 'package.xml 1.0 state "%state%" does not match "%self%"'); + $this->_packageFile = $file; + $this->_archiveFile = $archive ? $archive : $file; } - function _differentRole($handle, $role, $selfrole) + function getPackageFile() { - $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, - 'role' => $role, 'self' => $selfrole), - 'package.xml 1.0 maintainer "%handle%" role "%role%" does not match "%self%"'); + return isset($this->_packageFile) ? $this->_packageFile : false; } - function _differentEmail($handle, $email, $selfemail) + function getPackageType() { - $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, - 'email' => $email, 'self' => $selfemail), - 'package.xml 1.0 maintainer "%handle%" email "%email%" does not match "%self%"'); + return 'php'; } - function _differentName($handle, $name, $selfname) + function getArchiveFile() { - $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, - 'name' => $name, 'self' => $selfname), - 'package.xml 1.0 maintainer "%handle%" name "%name%" does not match "%self%"'); + return $this->_archiveFile; } - function _unmatchedMaintainers($my, $yours) + function packageInfo($field) { - if ($my) { - array_walk($my, create_function('&$i, $k', '$i = $i["handle"];')); - $this->_stack->push(__FUNCTION__, 'error', array('handles' => $my), - 'package.xml 2.0 has unmatched extra maintainers "%handles%"'); + if (!is_string($field) || empty($field) || + !isset($this->_packageInfo[$field])) { + return false; } - if ($yours) { - array_walk($yours, create_function('&$i, $k', '$i = $i["handle"];')); - $this->_stack->push(__FUNCTION__, 'error', array('handles' => $yours), - 'package.xml 1.0 has unmatched extra maintainers "%handles%"'); + return $this->_packageInfo[$field]; + } + + function setDirtree($path) + { + if (!isset($this->_packageInfo['dirtree'])) { + $this->_packageInfo['dirtree'] = array(); } + $this->_packageInfo['dirtree'][$path] = true; } - function _differentNotes($notes) + function getDirtree() { - $truncnotes = strlen($notes) < 25 ? $notes : substr($notes, 0, 24) . '...'; - $truncmynotes = strlen($this->getNotes()) < 25 ? $this->getNotes() : - substr($this->getNotes(), 0, 24) . '...'; - $this->_stack->push(__FUNCTION__, 'error', array('notes' => $truncnotes, - 'self' => $truncmynotes), - 'package.xml 1.0 release notes "%notes%" do not match "%self%"'); + if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { + return $this->_packageInfo['dirtree']; + } + return false; } - function _differentSummary($summary) + function resetDirtree() { - $truncsummary = strlen($summary) < 25 ? $summary : substr($summary, 0, 24) . '...'; - $truncmysummary = strlen($this->getsummary()) < 25 ? $this->getSummary() : - substr($this->getsummary(), 0, 24) . '...'; - $this->_stack->push(__FUNCTION__, 'error', array('summary' => $truncsummary, - 'self' => $truncmysummary), - 'package.xml 1.0 summary "%summary%" does not match "%self%"'); + unset($this->_packageInfo['dirtree']); } - function _differentDescription($description) + function fromArray($pinfo) { - $truncdescription = trim(strlen($description) < 25 ? $description : substr($description, 0, 24) . '...'); - $truncmydescription = trim(strlen($this->getDescription()) < 25 ? $this->getDescription() : - substr($this->getdescription(), 0, 24) . '...'); - $this->_stack->push(__FUNCTION__, 'error', array('description' => $truncdescription, - 'self' => $truncmydescription), - 'package.xml 1.0 description "%description%" does not match "%self%"'); + $this->_incomplete = false; + $this->_packageInfo = $pinfo; } - function _missingFile($file) + function isIncomplete() { - $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), - 'package.xml 1.0 file "%file%" is not present in '); + return $this->_incomplete; } - /** - * WARNING - do not use this function unless you know what you're doing - */ - function setRawState($state) + function getChannel() { - if (!isset($this->_packageInfo['stability'])) { - $this->_packageInfo['stability'] = array(); + return 'pear.php.net'; + } + + function getUri() + { + return false; + } + + function getTime() + { + return false; + } + + function getExtends() + { + if (isset($this->_packageInfo['extends'])) { + return $this->_packageInfo['extends']; } - $this->_packageInfo['stability']['release'] = $state; + return false; } /** - * WARNING - do not use this function unless you know what you're doing + * @return array */ - function setRawCompatible($compatible) + function toArray() { - $this->_packageInfo['compatible'] = $compatible; + if (!$this->validate(PEAR_VALIDATE_NORMAL)) { + return false; + } + return $this->getArray(); } - /** - * WARNING - do not use this function unless you know what you're doing - */ - function setRawPackage($package) + function getArray() { - $this->_packageInfo['name'] = $package; + return $this->_packageInfo; + } + + function getName() + { + return $this->getPackage(); + } + + function getPackage() + { + if (isset($this->_packageInfo['package'])) { + return $this->_packageInfo['package']; + } + return false; } /** - * WARNING - do not use this function unless you know what you're doing + * WARNING - don't use this unless you know what you are doing */ - function setRawChannel($channel) + function setRawPackage($package) { - $this->_packageInfo['channel'] = $channel; + $this->_packageInfo['package'] = $package; } - function setRequestedGroup($group) + function setPackage($package) { - $this->_requestedGroup = $group; + $this->_packageInfo['package'] = $package; + $this->_isValid = false; } - function getRequestedGroup() + function getVersion() { - if (isset($this->_requestedGroup)) { - return $this->_requestedGroup; + if (isset($this->_packageInfo['version'])) { + return $this->_packageInfo['version']; } return false; } - /** - * For saving in the registry. - * - * Set the last version that was installed - * @param string - */ - function setLastInstalledVersion($version) + function setVersion($version) { - $this->_packageInfo['_lastversion'] = $version; + $this->_packageInfo['version'] = $version; + $this->_isValid = false; } - /** - * @return string|false - */ - function getLastInstalledVersion() + function clearMaintainers() { - if (isset($this->_packageInfo['_lastversion'])) { - return $this->_packageInfo['_lastversion']; + unset($this->_packageInfo['maintainers']); + } + + function getMaintainers() + { + if (isset($this->_packageInfo['maintainers'])) { + return $this->_packageInfo['maintainers']; } return false; } /** - * Determines whether this package.xml has post-install scripts or not - * @return array|false + * Adds a new maintainer - no checking of duplicates is performed, use + * updatemaintainer for that purpose. */ - function listPostinstallScripts() + function addMaintainer($role, $handle, $name, $email) { - $filelist = $this->getFilelist(); - $contents = $this->getContents(); - $contents = $contents['dir']['file']; - if (!is_array($contents) || !isset($contents[0])) { - $contents = array($contents); + $this->_packageInfo['maintainers'][] = + array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name); + $this->_isValid = false; + } + + function updateMaintainer($role, $handle, $name, $email) + { + $found = false; + if (!isset($this->_packageInfo['maintainers']) || + !is_array($this->_packageInfo['maintainers'])) { + return $this->addMaintainer($role, $handle, $name, $email); } - $taskfiles = array(); - foreach ($contents as $file) { - $atts = $file['attribs']; - unset($file['attribs']); - if (count($file)) { - $taskfiles[$atts['name']] = $file; + foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { + if ($maintainer['handle'] == $handle) { + $found = $i; + break; } } - $common = new PEAR_Common; - $common->debug = $this->_config->get('verbose'); - $this->_scripts = array(); - $ret = array(); - foreach ($taskfiles as $name => $tasks) { - if (!isset($filelist[$name])) { - // ignored files will not be in the filelist - continue; - } - $atts = $filelist[$name]; - foreach ($tasks as $tag => $raw) { - $task = $this->getTask($tag); - $task = &new $task($this->_config, $common, PEAR_TASK_INSTALL); - if ($task->isScript()) { - $ret[] = $filelist[$name]['installed_as']; - } + if ($found !== false) { + unset($this->_packageInfo['maintainers'][$found]); + $this->_packageInfo['maintainers'] = + array_values($this->_packageInfo['maintainers']); + } + $this->addMaintainer($role, $handle, $name, $email); + } + + function deleteMaintainer($handle) + { + $found = false; + foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { + if ($maintainer['handle'] == $handle) { + $found = $i; + break; } } - if (count($ret)) { - return $ret; + if ($found !== false) { + unset($this->_packageInfo['maintainers'][$found]); + $this->_packageInfo['maintainers'] = + array_values($this->_packageInfo['maintainers']); + return true; } return false; } - /** - * Initialize post-install scripts for running - * - * This method can be used to detect post-install scripts, as the return value - * indicates whether any exist - * @return bool - */ - function initPostinstallScripts() + function getState() { - $filelist = $this->getFilelist(); - $contents = $this->getContents(); - $contents = $contents['dir']['file']; - if (!is_array($contents) || !isset($contents[0])) { - $contents = array($contents); - } - $taskfiles = array(); - foreach ($contents as $file) { - $atts = $file['attribs']; - unset($file['attribs']); - if (count($file)) { - $taskfiles[$atts['name']] = $file; - } - } - $common = new PEAR_Common; - $common->debug = $this->_config->get('verbose'); - $this->_scripts = array(); - foreach ($taskfiles as $name => $tasks) { - if (!isset($filelist[$name])) { - // file was not installed due to installconditions - continue; - } - $atts = $filelist[$name]; - foreach ($tasks as $tag => $raw) { - $taskname = $this->getTask($tag); - $task = &new $taskname($this->_config, $common, PEAR_TASK_INSTALL); - if (!$task->isScript()) { - continue; // scripts are only handled after installation - } - $lastversion = isset($this->_packageInfo['_lastversion']) ? - $this->_packageInfo['_lastversion'] : null; - $task->init($raw, $atts, $lastversion); - $res = $task->startSession($this, $atts['installed_as']); - if (!$res) { - continue; // skip this file - } - if (PEAR::isError($res)) { - return $res; - } - $assign = &$task; - $this->_scripts[] = &$assign; - } - } - if (count($this->_scripts)) { - return true; + if (isset($this->_packageInfo['release_state'])) { + return $this->_packageInfo['release_state']; } return false; } - function runPostinstallScripts() + function setRawState($state) { - if ($this->initPostinstallScripts()) { - $ui = &PEAR_Frontend::singleton(); - if ($ui) { - $ui->runPostinstallScripts($this->_scripts, $this); - } - } + $this->_packageInfo['release_state'] = $state; } - - /** - * Convert a recursive set of and tags into a single tag with - * tags. - */ - function flattenFilelist() + function setState($state) { - if (isset($this->_packageInfo['bundle'])) { - return; - } - $filelist = array(); - if (isset($this->_packageInfo['contents']['dir']['dir'])) { - $this->_getFlattenedFilelist($filelist, $this->_packageInfo['contents']['dir']); - if (!isset($filelist[1])) { - $filelist = $filelist[0]; - } - $this->_packageInfo['contents']['dir']['file'] = $filelist; - unset($this->_packageInfo['contents']['dir']['dir']); - } else { - // else already flattened but check for baseinstalldir propagation - if (isset($this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'])) { - if (isset($this->_packageInfo['contents']['dir']['file'][0])) { - foreach ($this->_packageInfo['contents']['dir']['file'] as $i => $file) { - if (isset($file['attribs']['baseinstalldir'])) { - continue; - } - $this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir'] - = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; - } - } else { - if (!isset($this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'])) { - $this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'] - = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; - } - } - } - } + $this->_packageInfo['release_state'] = $state; + $this->_isValid = false; } - /** - * @param array the final flattened file list - * @param array the current directory being processed - * @param string|false any recursively inherited baeinstalldir attribute - * @param string private recursion variable - * @return array - * @access protected - */ - function _getFlattenedFilelist(&$files, $dir, $baseinstall = false, $path = '') + function getDate() { - if (isset($dir['attribs']) && isset($dir['attribs']['baseinstalldir'])) { - $baseinstall = $dir['attribs']['baseinstalldir']; - } - if (isset($dir['dir'])) { - if (!isset($dir['dir'][0])) { - $dir['dir'] = array($dir['dir']); - } - foreach ($dir['dir'] as $subdir) { - if (!isset($subdir['attribs']) || !isset($subdir['attribs']['name'])) { - $name = '*unknown*'; - } else { - $name = $subdir['attribs']['name']; - } - $newpath = empty($path) ? $name : - $path . '/' . $name; - $this->_getFlattenedFilelist($files, $subdir, - $baseinstall, $newpath); - } - } - if (isset($dir['file'])) { - if (!isset($dir['file'][0])) { - $dir['file'] = array($dir['file']); - } - foreach ($dir['file'] as $file) { - $attrs = $file['attribs']; - $name = $attrs['name']; - if ($baseinstall && !isset($attrs['baseinstalldir'])) { - $attrs['baseinstalldir'] = $baseinstall; - } - $attrs['name'] = empty($path) ? $name : $path . '/' . $name; - $attrs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), - $attrs['name']); - $file['attribs'] = $attrs; - $files[] = $file; - } + if (isset($this->_packageInfo['release_date'])) { + return $this->_packageInfo['release_date']; } + return false; } - function setConfig(&$config) + function setDate($date) { - $this->_config = &$config; - $this->_registry = &$config->getRegistry(); + $this->_packageInfo['release_date'] = $date; + $this->_isValid = false; } - function setLogger(&$logger) + function getLicense() { - if (!is_object($logger) || !method_exists($logger, 'log')) { - return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); + if (isset($this->_packageInfo['release_license'])) { + return $this->_packageInfo['release_license']; } - $this->_logger = &$logger; + return false; } - /** - * WARNING - do not use this function directly unless you know what you're doing - */ - function setDeps($deps) + function setLicense($date) { - $this->_packageInfo['dependencies'] = $deps; + $this->_packageInfo['release_license'] = $date; + $this->_isValid = false; } - /** - * WARNING - do not use this function directly unless you know what you're doing - */ - function setCompatible($compat) + function getSummary() { - $this->_packageInfo['compatible'] = $compat; + if (isset($this->_packageInfo['summary'])) { + return $this->_packageInfo['summary']; + } + return false; } - function setPackagefile($file, $archive = false) + function setSummary($summary) { - $this->_packageFile = $file; - $this->_archiveFile = $archive ? $archive : $file; + $this->_packageInfo['summary'] = $summary; + $this->_isValid = false; } - /** - * Wrapper to {@link PEAR_ErrorStack::getErrors()} - * @param boolean determines whether to purge the error stack after retrieving - * @return array - */ - function getValidationWarnings($purge = true) + function getDescription() { - return $this->_stack->getErrors($purge); + if (isset($this->_packageInfo['description'])) { + return $this->_packageInfo['description']; + } + return false; } - function getPackageFile() + function setDescription($desc) { - return $this->_packageFile; + $this->_packageInfo['description'] = $desc; + $this->_isValid = false; } - function getArchiveFile() + function getNotes() { - return $this->_archiveFile; + if (isset($this->_packageInfo['release_notes'])) { + return $this->_packageInfo['release_notes']; + } + return false; } - - /** - * Directly set the array that defines this packagefile - * - * WARNING: no validation. This should only be performed by internal methods - * inside PEAR or by inputting an array saved from an existing PEAR_PackageFile_v2 - * @param array - */ - function fromArray($pinfo) + function setNotes($notes) { - unset($pinfo['old']); - unset($pinfo['xsdversion']); - $this->_incomplete = false; - $this->_packageInfo = $pinfo; + $this->_packageInfo['release_notes'] = $notes; + $this->_isValid = false; } - function isIncomplete() + function getDeps() { - return $this->_incomplete; + if (isset($this->_packageInfo['release_deps'])) { + return $this->_packageInfo['release_deps']; + } + return false; } /** - * @return array + * Reset dependencies prior to adding new ones */ - function toArray($forreg = false) + function clearDeps() { - if (!$this->validate(PEAR_VALIDATE_NORMAL)) { - return false; - } - return $this->getArray($forreg); + unset($this->_packageInfo['release_deps']); } - function getArray($forReg = false) + function addPhpDep($version, $rel) { - if ($forReg) { - $arr = $this->_packageInfo; - $arr['old'] = array(); - $arr['old']['version'] = $this->getVersion(); - $arr['old']['release_date'] = $this->getDate(); - $arr['old']['release_state'] = $this->getState(); - $arr['old']['release_license'] = $this->getLicense(); - $arr['old']['release_notes'] = $this->getNotes(); - $arr['old']['release_deps'] = $this->getDeps(); - $arr['old']['maintainers'] = $this->getMaintainers(); - $arr['xsdversion'] = '2.0'; - return $arr; - } else { - $info = $this->_packageInfo; - unset($info['dirtree']); - if (isset($info['_lastversion'])) { - unset($info['_lastversion']); - } - if (isset($info['#binarypackage'])) { - unset($info['#binarypackage']); - } - return $info; - } + $this->_isValid = false; + $this->_packageInfo['release_deps'][] = + array('type' => 'php', + 'rel' => $rel, + 'version' => $version); } - function packageInfo($field) + function addPackageDep($name, $version, $rel, $optional = 'no') { - $arr = $this->getArray(true); - if ($field == 'state') { - return $arr['stability']['release']; - } - if ($field == 'api-version') { - return $arr['version']['api']; - } - if ($field == 'api-state') { - return $arr['stability']['api']; - } - if (isset($arr['old'][$field])) { - if (!is_string($arr['old'][$field])) { - return null; - } - return $arr['old'][$field]; - } - if (isset($arr[$field])) { - if (!is_string($arr[$field])) { - return null; - } - return $arr[$field]; + $this->_isValid = false; + $dep = + array('type' => 'pkg', + 'name' => $name, + 'rel' => $rel, + 'optional' => $optional); + if ($rel != 'has' && $rel != 'not') { + $dep['version'] = $version; } - return null; + $this->_packageInfo['release_deps'][] = $dep; } - function getName() + function addExtensionDep($name, $version, $rel, $optional = 'no') { - return $this->getPackage(); + $this->_isValid = false; + $this->_packageInfo['release_deps'][] = + array('type' => 'ext', + 'name' => $name, + 'rel' => $rel, + 'version' => $version, + 'optional' => $optional); } - function getPackage() + /** + * WARNING - do not use this function directly unless you know what you're doing + */ + function setDeps($deps) { - if (isset($this->_packageInfo['name'])) { - return $this->_packageInfo['name']; - } - return false; + $this->_packageInfo['release_deps'] = $deps; } - function getChannel() + function hasDeps() { - if (isset($this->_packageInfo['uri'])) { - return '__uri'; - } - if (isset($this->_packageInfo['channel'])) { - return strtolower($this->_packageInfo['channel']); - } - return false; + return isset($this->_packageInfo['release_deps']) && + count($this->_packageInfo['release_deps']); } - function getUri() + function getDependencyGroup($group) { - if (isset($this->_packageInfo['uri'])) { - return $this->_packageInfo['uri']; - } return false; } - function getExtends() + function isCompatible($pf) { - if (isset($this->_packageInfo['extends'])) { - return $this->_packageInfo['extends']; - } return false; } - function getSummary() + function isSubpackageOf($p) { - if (isset($this->_packageInfo['summary'])) { - return $this->_packageInfo['summary']; - } - return false; + return $p->isSubpackage($this); } - function getDescription() + function isSubpackage($p) { - if (isset($this->_packageInfo['description'])) { - return $this->_packageInfo['description']; - } return false; } - function getMaintainers($raw = false) + function dependsOn($package, $channel) { - if (!isset($this->_packageInfo['lead'])) { + if (strtolower($channel) != 'pear.php.net') { return false; } - if ($raw) { - $ret = array('lead' => $this->_packageInfo['lead']); - (isset($this->_packageInfo['developer'])) ? - $ret['developer'] = $this->_packageInfo['developer'] :null; - (isset($this->_packageInfo['contributor'])) ? - $ret['contributor'] = $this->_packageInfo['contributor'] :null; - (isset($this->_packageInfo['helper'])) ? - $ret['helper'] = $this->_packageInfo['helper'] :null; - return $ret; - } else { - $ret = array(); - $leads = isset($this->_packageInfo['lead'][0]) ? $this->_packageInfo['lead'] : - array($this->_packageInfo['lead']); - foreach ($leads as $lead) { - $s = $lead; - $s['handle'] = $s['user']; - unset($s['user']); - $s['role'] = 'lead'; - $ret[] = $s; - } - if (isset($this->_packageInfo['developer'])) { - $leads = isset($this->_packageInfo['developer'][0]) ? - $this->_packageInfo['developer'] : - array($this->_packageInfo['developer']); - foreach ($leads as $maintainer) { - $s = $maintainer; - $s['handle'] = $s['user']; - unset($s['user']); - $s['role'] = 'developer'; - $ret[] = $s; - } - } - if (isset($this->_packageInfo['contributor'])) { - $leads = isset($this->_packageInfo['contributor'][0]) ? - $this->_packageInfo['contributor'] : - array($this->_packageInfo['contributor']); - foreach ($leads as $maintainer) { - $s = $maintainer; - $s['handle'] = $s['user']; - unset($s['user']); - $s['role'] = 'contributor'; - $ret[] = $s; - } + if (!($deps = $this->getDeps())) { + return false; + } + foreach ($deps as $dep) { + if ($dep['type'] != 'pkg') { + continue; } - if (isset($this->_packageInfo['helper'])) { - $leads = isset($this->_packageInfo['helper'][0]) ? - $this->_packageInfo['helper'] : - array($this->_packageInfo['helper']); - foreach ($leads as $maintainer) { - $s = $maintainer; - $s['handle'] = $s['user']; - unset($s['user']); - $s['role'] = 'helper'; - $ret[] = $s; - } + if (strtolower($dep['name']) == strtolower($package)) { + return true; } - return $ret; } return false; } - function getLeads() + function getConfigureOptions() { - if (isset($this->_packageInfo['lead'])) { - return $this->_packageInfo['lead']; + if (isset($this->_packageInfo['configure_options'])) { + return $this->_packageInfo['configure_options']; } return false; } - function getDevelopers() + function hasConfigureOptions() { - if (isset($this->_packageInfo['developer'])) { - return $this->_packageInfo['developer']; - } - return false; + return isset($this->_packageInfo['configure_options']) && + count($this->_packageInfo['configure_options']); } - function getContributors() + function addConfigureOption($name, $prompt, $default = false) { - if (isset($this->_packageInfo['contributor'])) { - return $this->_packageInfo['contributor']; + $o = array('name' => $name, 'prompt' => $prompt); + if ($default !== false) { + $o['default'] = $default; } - return false; + if (!isset($this->_packageInfo['configure_options'])) { + $this->_packageInfo['configure_options'] = array(); + } + $this->_packageInfo['configure_options'][] = $o; } - function getHelpers() + function clearConfigureOptions() { - if (isset($this->_packageInfo['helper'])) { - return $this->_packageInfo['helper']; - } - return false; + unset($this->_packageInfo['configure_options']); } - function setDate($date) + function getProvides() { - if (!isset($this->_packageInfo['date'])) { - // ensure that the extends tag is set up in the right location - $this->_packageInfo = $this->_insertBefore($this->_packageInfo, - array('time', 'version', - 'stability', 'license', 'notes', 'contents', 'compatible', - 'dependencies', 'providesextension', 'srcpackage', 'srcuri', - 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', - 'zendextbinrelease', 'bundle', 'changelog'), array(), 'date'); + if (isset($this->_packageInfo['provides'])) { + return $this->_packageInfo['provides']; } - $this->_packageInfo['date'] = $date; - $this->_isValid = 0; + return false; } - function setTime($time) + function getProvidesExtension() { - $this->_isValid = 0; - if (!isset($this->_packageInfo['time'])) { - // ensure that the time tag is set up in the right location - $this->_packageInfo = $this->_insertBefore($this->_packageInfo, - array('version', - 'stability', 'license', 'notes', 'contents', 'compatible', - 'dependencies', 'providesextension', 'srcpackage', 'srcuri', - 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', - 'zendextbinrelease', 'bundle', 'changelog'), $time, 'time'); - } - $this->_packageInfo['time'] = $time; + return false; } - function getDate() + function addFile($dir, $file, $attrs) { - if (isset($this->_packageInfo['date'])) { - return $this->_packageInfo['date']; + $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); + if ($dir == '/' || $dir == '') { + $dir = ''; + } else { + $dir .= '/'; } - return false; + $file = $dir . $file; + $file = preg_replace('![\\/]+!', '/', $file); + $this->_packageInfo['filelist'][$file] = $attrs; } - function getTime() + function getInstallationFilelist() { - if (isset($this->_packageInfo['time'])) { - return $this->_packageInfo['time']; - } - return false; + return $this->getFilelist(); } - /** - * @param package|api version category to return - */ - function getVersion($key = 'release') + function getFilelist() { - if (isset($this->_packageInfo['version'][$key])) { - return $this->_packageInfo['version'][$key]; + if (isset($this->_packageInfo['filelist'])) { + return $this->_packageInfo['filelist']; } return false; } - function getStability() + function setFileAttribute($file, $attr, $value) { - if (isset($this->_packageInfo['stability'])) { - return $this->_packageInfo['stability']; - } - return false; + $this->_packageInfo['filelist'][$file][$attr] = $value; } - function getState($key = 'release') + function resetFilelist() { - if (isset($this->_packageInfo['stability'][$key])) { - return $this->_packageInfo['stability'][$key]; - } - return false; + $this->_packageInfo['filelist'] = array(); } - function getLicense($raw = false) + function setInstalledAs($file, $path) { - if (isset($this->_packageInfo['license'])) { - if ($raw) { - return $this->_packageInfo['license']; - } - if (is_array($this->_packageInfo['license'])) { - return $this->_packageInfo['license']['_content']; - } else { - return $this->_packageInfo['license']; - } + if ($path) { + return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; } - return false; + unset($this->_packageInfo['filelist'][$file]['installed_as']); } - function getLicenseLocation() + function installedFile($file, $atts) { - if (!isset($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) { - return false; + if (isset($this->_packageInfo['filelist'][$file])) { + $this->_packageInfo['filelist'][$file] = + array_merge($this->_packageInfo['filelist'][$file], $atts); + } else { + $this->_packageInfo['filelist'][$file] = $atts; } - return $this->_packageInfo['license']['attribs']; } - function getNotes() + function getChangelog() { - if (isset($this->_packageInfo['notes'])) { - return $this->_packageInfo['notes']; + if (isset($this->_packageInfo['changelog'])) { + return $this->_packageInfo['changelog']; } return false; } - /** - * Return the tag contents, if any - * @return array|false - */ - function getUsesrole() + function getPackagexmlVersion() { - if (isset($this->_packageInfo['usesrole'])) { - return $this->_packageInfo['usesrole']; - } - return false; + return '1.0'; } /** - * Return the tag contents, if any - * @return array|false + * Wrapper to {@link PEAR_ErrorStack::getErrors()} + * @param boolean determines whether to purge the error stack after retrieving + * @return array */ - function getUsestask() + function getValidationWarnings($purge = true) { - if (isset($this->_packageInfo['usestask'])) { - return $this->_packageInfo['usestask']; - } - return false; + return $this->_stack->getErrors($purge); } + // }}} /** - * This should only be used to retrieve filenames and install attributes + * Validation error. Also marks the object contents as invalid + * @param error code + * @param array error information + * @access private */ - function getFilelist($preserve = false) + function _validateError($code, $params = array()) { - if (isset($this->_packageInfo['filelist']) && !$preserve) { - return $this->_packageInfo['filelist']; - } - $this->flattenFilelist(); - if ($contents = $this->getContents()) { - $ret = array(); - if (!isset($contents['dir'])) { - return false; - } - if (!isset($contents['dir']['file'][0])) { - $contents['dir']['file'] = array($contents['dir']['file']); - } - foreach ($contents['dir']['file'] as $file) { - $name = $file['attribs']['name']; - if (!$preserve) { - $file = $file['attribs']; - } - $ret[$name] = $file; - } - if (!$preserve) { - $this->_packageInfo['filelist'] = $ret; - } - return $ret; - } - return false; + $this->_stack->push($code, 'error', $params, false, false, debug_backtrace()); + $this->_isValid = false; } /** - * Return configure options array, if any - * - * @return array|false + * Validation warning. Does not mark the object contents invalid. + * @param error code + * @param array error information + * @access private */ - function getConfigureOptions() + function _validateWarning($code, $params = array()) { - if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { - return false; - } - - $releases = $this->getReleases(); - if (isset($releases[0])) { - $releases = $releases[0]; - } - - if (isset($releases['configureoption'])) { - if (!isset($releases['configureoption'][0])) { - $releases['configureoption'] = array($releases['configureoption']); - } - - for ($i = 0; $i < count($releases['configureoption']); $i++) { - $releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs']; - } - - return $releases['configureoption']; - } - - return false; + $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace()); } /** - * This is only used at install-time, after all serialization - * is over. + * @param integer error code + * @access protected */ - function resetFilelist() + function _getErrorMessage() { - $this->_packageInfo['filelist'] = array(); + return array( + PEAR_PACKAGEFILE_ERROR_NO_NAME => + 'Missing Package Name', + PEAR_PACKAGEFILE_ERROR_NO_SUMMARY => + 'No summary found', + PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY => + 'Summary should be on one line', + PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION => + 'Missing description', + PEAR_PACKAGEFILE_ERROR_NO_LICENSE => + 'Missing license', + PEAR_PACKAGEFILE_ERROR_NO_VERSION => + 'No release version found', + PEAR_PACKAGEFILE_ERROR_NO_STATE => + 'No release state found', + PEAR_PACKAGEFILE_ERROR_NO_DATE => + 'No release date found', + PEAR_PACKAGEFILE_ERROR_NO_NOTES => + 'No release notes found', + PEAR_PACKAGEFILE_ERROR_NO_LEAD => + 'Package must have at least one lead maintainer', + PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS => + 'No maintainers found, at least one must be defined', + PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE => + 'Maintainer %index% has no handle (user ID at channel server)', + PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE => + 'Maintainer %index% has no role', + PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME => + 'Maintainer %index% has no name', + PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL => + 'Maintainer %index% has no email', + PEAR_PACKAGEFILE_ERROR_NO_DEPNAME => + 'Dependency %index% is not a php dependency, and has no name', + PEAR_PACKAGEFILE_ERROR_NO_DEPREL => + 'Dependency %index% has no relation (rel)', + PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE => + 'Dependency %index% has no type', + PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED => + 'PHP Dependency %index% has a name attribute of "%name%" which will be' . + ' ignored!', + PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION => + 'Dependency %index% is not a rel="has" or rel="not" dependency, ' . + 'and has no version', + PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION => + 'Dependency %index% is a type="php" dependency, ' . + 'and has no version', + PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED => + 'Dependency %index% is a rel="%rel%" dependency, versioning is ignored', + PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL => + 'Dependency %index% has invalid optional value "%opt%", should be yes or no', + PEAR_PACKAGEFILE_PHP_NO_NOT => + 'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' . + ' to exclude specific versions', + PEAR_PACKAGEFILE_ERROR_NO_CONFNAME => + 'Configure Option %index% has no name', + PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT => + 'Configure Option %index% has no prompt', + PEAR_PACKAGEFILE_ERROR_NO_FILES => + 'No files in section of package.xml', + PEAR_PACKAGEFILE_ERROR_NO_FILEROLE => + 'File "%file%" has no role, expecting one of "%roles%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE => + 'File "%file%" has invalid role "%role%", expecting one of "%roles%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME => + 'File "%file%" cannot start with ".", cannot package or install', + PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE => + 'Parser error: invalid PHP found in file "%file%"', + PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX => + 'in %file%: %type% "%name%" not prefixed with package name "%package%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILE => + 'Parser error: invalid PHP file "%file%"', + PEAR_PACKAGEFILE_ERROR_CHANNELVAL => + 'Channel validator error: field "%field%" - %reason%', + PEAR_PACKAGEFILE_ERROR_PHP5 => + 'Error, PHP5 token encountered in %file%, analysis should be in PHP5', + PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND => + 'File "%file%" in package.xml does not exist', + PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS => + 'Package.xml contains non-ISO-8859-1 characters, and may not validate', + ); } /** - * Retrieve a list of files that should be installed on this computer - * @return array + * Validate XML package definition file. + * + * @access public + * @return boolean */ - function getInstallationFilelist($forfilecheck = false) + function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false) { - $contents = $this->getFilelist(true); - if (isset($contents['dir']['attribs']['baseinstalldir'])) { - $base = $contents['dir']['attribs']['baseinstalldir']; - } - if (isset($this->_packageInfo['bundle'])) { - return PEAR::raiseError( - 'Exception: bundles should be handled in download code only'); + if (($this->_isValid & $state) == $state) { + return true; } - $release = $this->getReleases(); - if ($release) { - if (!isset($release[0])) { - if (!isset($release['installconditions']) && !isset($release['filelist'])) { - if ($forfilecheck) { - return $this->getFilelist(); - } - return $contents; - } - $release = array($release); - } - $depchecker = &$this->getPEARDependency2($this->_config, array(), - array('channel' => $this->getChannel(), 'package' => $this->getPackage()), - PEAR_VALIDATE_INSTALLING); - foreach ($release as $instance) { - if (isset($instance['installconditions'])) { - $installconditions = $instance['installconditions']; - if (is_array($installconditions)) { - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - foreach ($installconditions as $type => $conditions) { - if (!isset($conditions[0])) { - $conditions = array($conditions); - } - foreach ($conditions as $condition) { - $ret = $depchecker->{"validate{$type}Dependency"}($condition); - if (PEAR::isError($ret)) { - PEAR::popErrorHandling(); - continue 3; // skip this release - } - } - } - PEAR::popErrorHandling(); - } - } - // this is the release to use - if (isset($instance['filelist'])) { - // ignore files - if (isset($instance['filelist']['ignore'])) { - $ignore = isset($instance['filelist']['ignore'][0]) ? - $instance['filelist']['ignore'] : - array($instance['filelist']['ignore']); - foreach ($ignore as $ig) { - unset ($contents[$ig['attribs']['name']]); - } - } - // install files as this name - if (isset($instance['filelist']['install'])) { - $installas = isset($instance['filelist']['install'][0]) ? - $instance['filelist']['install'] : - array($instance['filelist']['install']); - foreach ($installas as $as) { - $contents[$as['attribs']['name']]['attribs']['install-as'] = - $as['attribs']['as']; - } - } - } - if ($forfilecheck) { - foreach ($contents as $file => $attrs) { - $contents[$file] = $attrs['attribs']; - } - } - return $contents; - } - } else { // simple release - no installconditions or install-as - if ($forfilecheck) { - return $this->getFilelist(); - } - return $contents; + $this->_isValid = true; + $info = $this->_packageInfo; + if (empty($info['package'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME); + $this->_packageName = $pn = 'unknown'; + } else { + $this->_packageName = $pn = $info['package']; } - // no releases matched - return PEAR::raiseError('No releases in package.xml matched the existing operating ' . - 'system, extensions installed, or architecture, cannot install'); - } - /** - * This is only used at install-time, after all serialization - * is over. - * @param string file name - * @param string installed path - */ - function setInstalledAs($file, $path) - { - if ($path) { - return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; + if (empty($info['summary'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY); + } elseif (strpos(trim($info['summary']), "\n") !== false) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY, + array('summary' => $info['summary'])); } - unset($this->_packageInfo['filelist'][$file]['installed_as']); - } - - function getInstalledLocation($file) - { - if (isset($this->_packageInfo['filelist'][$file]['installed_as'])) { - return $this->_packageInfo['filelist'][$file]['installed_as']; + if (empty($info['description'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION); } - return false; - } - - /** - * This is only used at install-time, after all serialization - * is over. - */ - function installedFile($file, $atts) - { - if (isset($this->_packageInfo['filelist'][$file])) { - $this->_packageInfo['filelist'][$file] = - array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']); - } else { - $this->_packageInfo['filelist'][$file] = $atts['attribs']; + if (empty($info['release_license'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE); } - } - - /** - * Retrieve the contents tag - */ - function getContents() - { - if (isset($this->_packageInfo['contents'])) { - return $this->_packageInfo['contents']; + if (empty($info['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION); } - return false; - } - - /** - * @param string full path to file - * @param string attribute name - * @param string attribute value - * @param int risky but fast - use this to choose a file based on its position in the list - * of files. Index is zero-based like PHP arrays. - * @return bool success of operation - */ - function setFileAttribute($filename, $attr, $value, $index = false) - { - $this->_isValid = 0; - if (in_array($attr, array('role', 'name', 'baseinstalldir'))) { - $this->_filesValid = false; + if (empty($info['release_state'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE); } - if ($index !== false && - isset($this->_packageInfo['contents']['dir']['file'][$index]['attribs'])) { - $this->_packageInfo['contents']['dir']['file'][$index]['attribs'][$attr] = $value; - return true; + if (empty($info['release_date'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE); } - if (!isset($this->_packageInfo['contents']['dir']['file'])) { - return false; + if (empty($info['release_notes'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES); } - $files = $this->_packageInfo['contents']['dir']['file']; - if (!isset($files[0])) { - $files = array($files); - $ind = false; + if (empty($info['maintainers'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS); } else { - $ind = true; - } - foreach ($files as $i => $file) { - if (isset($file['attribs'])) { - if ($file['attribs']['name'] == $filename) { - if ($ind) { - $this->_packageInfo['contents']['dir']['file'][$i]['attribs'][$attr] = $value; - } else { - $this->_packageInfo['contents']['dir']['file']['attribs'][$attr] = $value; + $haslead = false; + $i = 1; + foreach ($info['maintainers'] as $m) { + if (empty($m['handle'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE, + array('index' => $i)); + } + if (empty($m['role'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE, + array('index' => $i, 'roles' => PEAR_Common::getUserRoles())); + } elseif ($m['role'] == 'lead') { + $haslead = true; + } + if (empty($m['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME, + array('index' => $i)); + } + if (empty($m['email'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL, + array('index' => $i)); + } + $i++; + } + if (!$haslead) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD); + } + } + if (!empty($info['release_deps'])) { + $i = 1; + foreach ($info['release_deps'] as $d) { + if (!isset($d['type']) || empty($d['type'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE, + array('index' => $i, 'types' => PEAR_Common::getDependencyTypes())); + continue; + } + if (!isset($d['rel']) || empty($d['rel'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL, + array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations())); + continue; + } + if (!empty($d['optional'])) { + if (!in_array($d['optional'], array('yes', 'no'))) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL, + array('index' => $i, 'opt' => $d['optional'])); } - return true; } + if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION, + array('index' => $i)); + } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED, + array('index' => $i, 'rel' => $d['rel'])); + } + if ($d['type'] == 'php' && !empty($d['name'])) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED, + array('index' => $i, 'name' => $d['name'])); + } elseif ($d['type'] != 'php' && empty($d['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME, + array('index' => $i)); + } + if ($d['type'] == 'php' && empty($d['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION, + array('index' => $i)); + } + if (($d['rel'] == 'not') && ($d['type'] == 'php')) { + $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT, + array('index' => $i)); + } + $i++; } } - return false; - } - - function setDirtree($path) - { - if (!isset($this->_packageInfo['dirtree'])) { - $this->_packageInfo['dirtree'] = array(); - } - $this->_packageInfo['dirtree'][$path] = true; - } - - function getDirtree() - { - if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { - return $this->_packageInfo['dirtree']; - } - return false; - } - - function resetDirtree() - { - unset($this->_packageInfo['dirtree']); - } - - /** - * Determines whether this package claims it is compatible with the version of - * the package that has a recommended version dependency - * @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package - * @return boolean - */ - function isCompatible($pf) - { - if (!isset($this->_packageInfo['compatible'])) { - return false; - } - if (!isset($this->_packageInfo['channel'])) { - return false; - } - $me = $pf->getVersion(); - $compatible = $this->_packageInfo['compatible']; - if (!isset($compatible[0])) { - $compatible = array($compatible); - } - $found = false; - foreach ($compatible as $info) { - if (strtolower($info['name']) == strtolower($pf->getPackage())) { - if (strtolower($info['channel']) == strtolower($pf->getChannel())) { - $found = true; - break; + if (!empty($info['configure_options'])) { + $i = 1; + foreach ($info['configure_options'] as $c) { + if (empty($c['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME, + array('index' => $i)); } + if (empty($c['prompt'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT, + array('index' => $i)); + } + $i++; } } - if (!$found) { - return false; - } - if (isset($info['exclude'])) { - if (!isset($info['exclude'][0])) { - $info['exclude'] = array($info['exclude']); - } - foreach ($info['exclude'] as $exclude) { - if (version_compare($me, $exclude, '==')) { - return false; + if (empty($info['filelist'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES); + $errors[] = 'no files'; + } else { + foreach ($info['filelist'] as $file => $fa) { + if (empty($fa['role'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE, + array('file' => $file, 'roles' => PEAR_Common::getFileRoles())); + continue; + } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE, + array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles())); + } + if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) { + // file contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file)); + } + if (isset($fa['install-as']) && + preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $fa['install-as']))) { + // install-as contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file . ' [installed as ' . $fa['install-as'] . ']')); + } + if (isset($fa['baseinstalldir']) && + preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $fa['baseinstalldir']))) { + // install-as contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']')); } } } - if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) { - return true; + if (isset($this->_registry) && $this->_isValid) { + $chan = $this->_registry->getChannel('pear.php.net'); + if (PEAR::isError($chan)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage()); + return $this->_isValid = 0; + } + $validator = $chan->getValidationObject(); + $validator->setPackageFile($this); + $validator->validate($state); + $failures = $validator->getFailures(); + foreach ($failures['errors'] as $error) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error); + } + foreach ($failures['warnings'] as $warning) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning); + } } - return false; - } - - /** - * @return array|false - */ - function getCompatible() - { - if (isset($this->_packageInfo['compatible'])) { - return $this->_packageInfo['compatible']; + if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) { + if ($this->_analyzePhpFiles()) { + $this->_isValid = true; + } } - return false; - } - - function getDependencies() - { - if (isset($this->_packageInfo['dependencies'])) { - return $this->_packageInfo['dependencies']; + if ($this->_isValid) { + return $this->_isValid = $state; } - return false; - } - - function isSubpackageOf($p) - { - return $p->isSubpackage($this); + return $this->_isValid = 0; } - /** - * Determines whether the passed in package is a subpackage of this package. - * - * No version checking is done, only name verification. - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @return bool - */ - function isSubpackage($p) + function _analyzePhpFiles() { - $sub = array(); - if (isset($this->_packageInfo['dependencies']['required']['subpackage'])) { - $sub = $this->_packageInfo['dependencies']['required']['subpackage']; - if (!isset($sub[0])) { - $sub = array($sub); - } + if (!$this->_isValid) { + return false; } - if (isset($this->_packageInfo['dependencies']['optional']['subpackage'])) { - $sub1 = $this->_packageInfo['dependencies']['optional']['subpackage']; - if (!isset($sub1[0])) { - $sub1 = array($sub1); - } - $sub = array_merge($sub, $sub1); + if (!isset($this->_packageFile)) { + return false; } - if (isset($this->_packageInfo['dependencies']['group'])) { - $group = $this->_packageInfo['dependencies']['group']; - if (!isset($group[0])) { - $group = array($group); + $dir_prefix = dirname($this->_packageFile); + $common = new PEAR_Common; + $log = isset($this->_logger) ? array(&$this->_logger, 'log') : + array($common, 'log'); + $info = $this->getFilelist(); + foreach ($info as $file => $fa) { + if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND, + array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file)); + continue; } - foreach ($group as $deps) { - if (isset($deps['subpackage'])) { - $sub2 = $deps['subpackage']; - if (!isset($sub2[0])) { - $sub2 = array($sub2); - } - $sub = array_merge($sub, $sub2); + if ($fa['role'] == 'php' && $dir_prefix) { + call_user_func_array($log, array(1, "Analyzing $file")); + $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); + if ($srcinfo) { + $this->_buildProvidesArray($srcinfo); } } } - foreach ($sub as $dep) { - if (strtolower($dep['name']) == strtolower($p->getPackage())) { - if (isset($dep['channel'])) { - if (strtolower($dep['channel']) == strtolower($p->getChannel())) { - return true; + $this->_packageName = $pn = $this->getPackage(); + $pnl = strlen($pn); + if (isset($this->_packageInfo['provides'])) { + foreach ((array) $this->_packageInfo['provides'] as $key => $what) { + if (isset($what['explicit'])) { + // skip conformance checks if the provides entry is + // specified in the package.xml file + continue; + } + extract($what); + if ($type == 'class') { + if (!strncasecmp($name, $pn, $pnl)) { + continue; } - } else { - if ($dep['uri'] == $p->getURI()) { - return true; + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); + } elseif ($type == 'function') { + if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { + continue; } + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); } } } - return false; + return $this->_isValid; } - function dependsOn($package, $channel) + /** + * Get the default xml generator object + * + * @return PEAR_PackageFile_Generator_v1 + */ + function &getDefaultGenerator() { - if (!($deps = $this->getDependencies())) { - return false; - } - foreach (array('package', 'subpackage') as $type) { - foreach (array('required', 'optional') as $needed) { - if (isset($deps[$needed][$type])) { - if (!isset($deps[$needed][$type][0])) { - $deps[$needed][$type] = array($deps[$needed][$type]); - } - foreach ($deps[$needed][$type] as $dep) { - $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; - if (strtolower($dep['name']) == strtolower($package) && - $depchannel == $channel) { - return true; - } - } - } - } - if (isset($deps['group'])) { - if (!isset($deps['group'][0])) { - $dep['group'] = array($deps['group']); - } - foreach ($deps['group'] as $group) { - if (isset($group[$type])) { - if (!is_array($group[$type])) { - $group[$type] = array($group[$type]); - } - foreach ($group[$type] as $dep) { - $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; - if (strtolower($dep['name']) == strtolower($package) && - $depchannel == $channel) { - return true; - } - } - } - } - } + if (!class_exists('PEAR_PackageFile_Generator_v1')) { + require_once 'PEAR/PackageFile/Generator/v1.php'; } - return false; + $a = &new PEAR_PackageFile_Generator_v1($this); + return $a; } /** - * Get the contents of a dependency group + * Get the contents of a file listed within the package.xml * @param string - * @return array|false + * @return string */ - function getDependencyGroup($name) + function getFileContents($file) { - $name = strtolower($name); - if (!isset($this->_packageInfo['dependencies']['group'])) { - return false; - } - $groups = $this->_packageInfo['dependencies']['group']; - if (!isset($groups[0])) { - $groups = array($groups); - } - foreach ($groups as $group) { - if (strtolower($group['attribs']['name']) == $name) { - return $group; + if ($this->_archiveFile == $this->_packageFile) { // unpacked + $dir = dirname($this->_packageFile); + $file = $dir . DIRECTORY_SEPARATOR . $file; + $file = str_replace(array('/', '\\'), + array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); + if (file_exists($file) && is_readable($file)) { + return implode('', file($file)); + } + } else { // tgz + if (!class_exists('Archive_Tar')) { + require_once 'Archive/Tar.php'; + } + $tar = &new Archive_Tar($this->_archiveFile); + $tar->pushErrorHandling(PEAR_ERROR_RETURN); + if ($file != 'package.xml' && $file != 'package2.xml') { + $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; + } + $file = $tar->extractInString($file); + $tar->popErrorHandling(); + if (PEAR::isError($file)) { + return PEAR::raiseError("Cannot locate file '$file' in archive"); } + return $file; } - return false; } + // {{{ analyzeSourceCode() /** - * Retrieve a partial package.xml 1.0 representation of dependencies + * Analyze the source code of the given PHP file * - * a very limited representation of dependencies is returned by this method. - * The tag for excluding certain versions of a dependency is - * completely ignored. In addition, dependency groups are ignored, with the - * assumption that all dependencies in dependency groups are also listed in - * the optional group that work with all dependency groups - * @param boolean return package.xml 2.0 tag - * @return array|false + * @param string Filename of the PHP file + * @return mixed + * @access private */ - function getDeps($raw = false, $nopearinstaller = false) + function _analyzeSourceCode($file) { - if (isset($this->_packageInfo['dependencies'])) { - if ($raw) { - return $this->_packageInfo['dependencies']; - } - $ret = array(); - $map = array( - 'php' => 'php', - 'package' => 'pkg', - 'subpackage' => 'pkg', - 'extension' => 'ext', - 'os' => 'os', - 'pearinstaller' => 'pkg', - ); - foreach (array('required', 'optional') as $type) { - $optional = ($type == 'optional') ? 'yes' : 'no'; - if (!isset($this->_packageInfo['dependencies'][$type]) - || empty($this->_packageInfo['dependencies'][$type])) { + if (!function_exists("token_get_all")) { + return false; + } + if (!defined('T_DOC_COMMENT')) { + define('T_DOC_COMMENT', T_COMMENT); + } + if (!defined('T_INTERFACE')) { + define('T_INTERFACE', -1); + } + if (!defined('T_IMPLEMENTS')) { + define('T_IMPLEMENTS', -1); + } + if (!$fp = @fopen($file, "r")) { + return false; + } + fclose($fp); + $contents = file_get_contents($file); + $tokens = token_get_all($contents); +/* + for ($i = 0; $i < sizeof($tokens); $i++) { + @list($token, $data) = $tokens[$i]; + if (is_string($token)) { + var_dump($token); + } else { + print token_name($token) . ' '; + var_dump(rtrim($data)); + } + } +*/ + $look_for = 0; + $paren_level = 0; + $bracket_level = 0; + $brace_level = 0; + $lastphpdoc = ''; + $current_class = ''; + $current_interface = ''; + $current_class_level = -1; + $current_function = ''; + $current_function_level = -1; + $declared_classes = array(); + $declared_interfaces = array(); + $declared_functions = array(); + $declared_methods = array(); + $used_classes = array(); + $used_functions = array(); + $extends = array(); + $implements = array(); + $nodeps = array(); + $inquote = false; + $interface = false; + for ($i = 0; $i < sizeof($tokens); $i++) { + if (is_array($tokens[$i])) { + list($token, $data) = $tokens[$i]; + } else { + $token = $tokens[$i]; + $data = ''; + } + if ($inquote) { + if ($token != '"' && $token != T_END_HEREDOC) { + continue; + } else { + $inquote = false; continue; } - foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) { - if ($dtype == 'pearinstaller' && $nopearinstaller) { - continue; + } + switch ($token) { + case T_WHITESPACE : + continue; + case ';': + if ($interface) { + $current_function = ''; + $current_function_level = -1; } - if (!isset($deps[0])) { - $deps = array($deps); + break; + case '"': + case T_START_HEREDOC: + $inquote = true; + break; + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + case '{': $brace_level++; continue 2; + case '}': + $brace_level--; + if ($current_class_level == $brace_level) { + $current_class = ''; + $current_class_level = -1; } - foreach ($deps as $dep) { - if (!isset($map[$dtype])) { - // no support for arch type - continue; - } - if ($dtype == 'pearinstaller') { - $dep['name'] = 'PEAR'; - $dep['channel'] = 'pear.php.net'; - } - $s = array('type' => $map[$dtype]); - if (isset($dep['channel'])) { - $s['channel'] = $dep['channel']; - } - if (isset($dep['uri'])) { - $s['uri'] = $dep['uri']; - } - if (isset($dep['name'])) { - $s['name'] = $dep['name']; + if ($current_function_level == $brace_level) { + $current_function = ''; + $current_function_level = -1; + } + continue 2; + case '[': $bracket_level++; continue 2; + case ']': $bracket_level--; continue 2; + case '(': $paren_level++; continue 2; + case ')': $paren_level--; continue 2; + case T_INTERFACE: + $interface = true; + case T_CLASS: + if (($current_class_level != -1) || ($current_function_level != -1)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, + array('file' => $file)); + return false; + } + case T_FUNCTION: + case T_NEW: + case T_EXTENDS: + case T_IMPLEMENTS: + $look_for = $token; + continue 2; + case T_STRING: + if (version_compare(zend_version(), '2.0', '<')) { + if (in_array(strtolower($data), + array('public', 'private', 'protected', 'abstract', + 'interface', 'implements', 'throw') + )) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5, + array($file)); } - if (isset($dep['conflicts'])) { - $s['rel'] = 'not'; + } + if ($look_for == T_CLASS) { + $current_class = $data; + $current_class_level = $brace_level; + $declared_classes[] = $current_class; + } elseif ($look_for == T_INTERFACE) { + $current_interface = $data; + $current_class_level = $brace_level; + $declared_interfaces[] = $current_interface; + } elseif ($look_for == T_IMPLEMENTS) { + $implements[$current_class] = $data; + } elseif ($look_for == T_EXTENDS) { + $extends[$current_class] = $data; + } elseif ($look_for == T_FUNCTION) { + if ($current_class) { + $current_function = "$current_class::$data"; + $declared_methods[$current_class][] = $data; + } elseif ($current_interface) { + $current_function = "$current_interface::$data"; + $declared_methods[$current_interface][] = $data; } else { - if (!isset($dep['min']) && - !isset($dep['max'])) { - $s['rel'] = 'has'; - $s['optional'] = $optional; - } elseif (isset($dep['min']) && - isset($dep['max'])) { - $s['rel'] = 'ge'; - $s1 = $s; - $s1['rel'] = 'le'; - $s['version'] = $dep['min']; - $s1['version'] = $dep['max']; - if (isset($dep['channel'])) { - $s1['channel'] = $dep['channel']; - } - if ($dtype != 'php') { - $s['name'] = $dep['name']; - $s1['name'] = $dep['name']; - } - $s['optional'] = $optional; - $s1['optional'] = $optional; - $ret[] = $s1; - } elseif (isset($dep['min'])) { - if (isset($dep['exclude']) && - $dep['exclude'] == $dep['min']) { - $s['rel'] = 'gt'; - } else { - $s['rel'] = 'ge'; - } - $s['version'] = $dep['min']; - $s['optional'] = $optional; - if ($dtype != 'php') { - $s['name'] = $dep['name']; - } - } elseif (isset($dep['max'])) { - if (isset($dep['exclude']) && - $dep['exclude'] == $dep['max']) { - $s['rel'] = 'lt'; - } else { - $s['rel'] = 'le'; - } - $s['version'] = $dep['max']; - $s['optional'] = $optional; - if ($dtype != 'php') { - $s['name'] = $dep['name']; - } - } + $current_function = $data; + $declared_functions[] = $current_function; } - $ret[] = $s; + $current_function_level = $brace_level; + $m = array(); + } elseif ($look_for == T_NEW) { + $used_classes[$data] = true; } - } - } - if (count($ret)) { - return $ret; + $look_for = 0; + continue 2; + case T_VARIABLE: + $look_for = 0; + continue 2; + case T_DOC_COMMENT: + case T_COMMENT: + if (preg_match('!^/\*\*\s!', $data)) { + $lastphpdoc = $data; + if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { + $nodeps = array_merge($nodeps, $m[1]); + } + } + continue 2; + case T_DOUBLE_COLON: + if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, + array('file' => $file)); + return false; + } + $class = $tokens[$i - 1][1]; + if (strtolower($class) != 'parent') { + $used_classes[$class] = true; + } + continue 2; } } - return false; + return array( + "source_file" => $file, + "declared_classes" => $declared_classes, + "declared_interfaces" => $declared_interfaces, + "declared_methods" => $declared_methods, + "declared_functions" => $declared_functions, + "used_classes" => array_diff(array_keys($used_classes), $nodeps), + "inheritance" => $extends, + "implements" => $implements, + ); } /** - * @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false + * Build a "provides" array from data returned by + * analyzeSourceCode(). The format of the built array is like + * this: + * + * array( + * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), + * ... + * ) + * + * + * @param array $srcinfo array with information about a source file + * as returned by the analyzeSourceCode() method. + * + * @return void + * + * @access private + * */ - function getPackageType() + function _buildProvidesArray($srcinfo) { - if (isset($this->_packageInfo['phprelease'])) { - return 'php'; - } - if (isset($this->_packageInfo['extsrcrelease'])) { - return 'extsrc'; - } - if (isset($this->_packageInfo['extbinrelease'])) { - return 'extbin'; + if (!$this->_isValid) { + return false; } - if (isset($this->_packageInfo['zendextsrcrelease'])) { - return 'zendextsrc'; + $file = basename($srcinfo['source_file']); + $pn = $this->getPackage(); + $pnl = strlen($pn); + foreach ($srcinfo['declared_classes'] as $class) { + $key = "class;$class"; + if (isset($this->_packageInfo['provides'][$key])) { + continue; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'class', 'name' => $class); + if (isset($srcinfo['inheritance'][$class])) { + $this->_packageInfo['provides'][$key]['extends'] = + $srcinfo['inheritance'][$class]; + } } - if (isset($this->_packageInfo['zendextbinrelease'])) { - return 'zendextbin'; + foreach ($srcinfo['declared_methods'] as $class => $methods) { + foreach ($methods as $method) { + $function = "$class::$method"; + $key = "function;$function"; + if ($method{0} == '_' || !strcasecmp($method, $class) || + isset($this->_packageInfo['provides'][$key])) { + continue; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } } - if (isset($this->_packageInfo['bundle'])) { - return 'bundle'; + + foreach ($srcinfo['declared_functions'] as $function) { + $key = "function;$function"; + if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) { + continue; + } + if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { + $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); } - return false; } + // }}} +} +?> +PEAR-1.9.0/PEAR/PackageFile/v2.php100664 764 764 207576 100664 11311 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: v2.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * For error handling + */ +require_once 'PEAR/ErrorStack.php'; +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_v2 +{ + /** - * @return array|false + * Parsed package information + * @var array + * @access private */ - function getReleases() - { - $type = $this->getPackageType(); - if ($type != 'bundle') { - $type .= 'release'; - } - if ($this->getPackageType() && isset($this->_packageInfo[$type])) { - return $this->_packageInfo[$type]; - } - return false; - } + var $_packageInfo = array(); /** - * @return array + * path to package .tgz or false if this is a local/extracted package.xml + * @var string|false + * @access private */ - function getChangelog() - { - if (isset($this->_packageInfo['changelog'])) { - return $this->_packageInfo['changelog']; - } - return false; - } + var $_archiveFile; - function hasDeps() - { - return isset($this->_packageInfo['dependencies']); - } + /** + * path to package .xml or false if this is an abstract parsed-from-string xml + * @var string|false + * @access private + */ + var $_packageFile; - function getPackagexmlVersion() + /** + * This is used by file analysis routines to log progress information + * @var PEAR_Common + * @access protected + */ + var $_logger; + + /** + * This is set to the highest validation level that has been validated + * + * If the package.xml is invalid or unknown, this is set to 0. If + * normal validation has occurred, this is set to PEAR_VALIDATE_NORMAL. If + * downloading/installation validation has occurred it is set to PEAR_VALIDATE_DOWNLOADING + * or INSTALLING, and so on up to PEAR_VALIDATE_PACKAGING. This allows validation + * "caching" to occur, which is particularly important for package validation, so + * that PHP files are not validated twice + * @var int + * @access private + */ + var $_isValid = 0; + + /** + * True if the filelist has been validated + * @param bool + */ + var $_filesValid = false; + + /** + * @var PEAR_Registry + * @access protected + */ + var $_registry; + + /** + * @var PEAR_Config + * @access protected + */ + var $_config; + + /** + * Optional Dependency group requested for installation + * @var string + * @access private + */ + var $_requestedGroup = false; + + /** + * @var PEAR_ErrorStack + * @access protected + */ + var $_stack; + + /** + * Namespace prefix used for tasks in this package.xml - use tasks: whenever possible + */ + var $_tasksNs; + + /** + * Determines whether this packagefile was initialized only with partial package info + * + * If this package file was constructed via parsing REST, it will only contain + * + * - package name + * - channel name + * - dependencies + * @var boolean + * @access private + */ + var $_incomplete = true; + + /** + * @var PEAR_PackageFile_v2_Validator + */ + var $_v2Validator; + + /** + * The constructor merely sets up the private error stack + */ + function PEAR_PackageFile_v2() { - if (isset($this->_packageInfo['zendextsrcrelease'])) { - return '2.1'; - } - if (isset($this->_packageInfo['zendextbinrelease'])) { - return '2.1'; - } - return '2.0'; + $this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null); + $this->_isValid = false; } /** - * @return array|false + * To make unit-testing easier + * @param PEAR_Frontend_* + * @param array options + * @param PEAR_Config + * @return PEAR_Downloader + * @access protected */ - function getSourcePackage() + function &getPEARDownloader(&$i, $o, &$c) { - if (isset($this->_packageInfo['extbinrelease']) || - isset($this->_packageInfo['zendextbinrelease'])) { - return array('channel' => $this->_packageInfo['srcchannel'], - 'package' => $this->_packageInfo['srcpackage']); - } - return false; + $z = &new PEAR_Downloader($i, $o, $c); + return $z; } - function getBundledPackages() + /** + * To make unit-testing easier + * @param PEAR_Config + * @param array options + * @param array package name as returned from {@link PEAR_Registry::parsePackageName()} + * @param int PEAR_VALIDATE_* constant + * @return PEAR_Dependency2 + * @access protected + */ + function &getPEARDependency2(&$c, $o, $p, $s = PEAR_VALIDATE_INSTALLING) { - if (isset($this->_packageInfo['bundle'])) { - return $this->_packageInfo['contents']['bundledpackage']; + if (!class_exists('PEAR_Dependency2')) { + require_once 'PEAR/Dependency2.php'; } - return false; + $z = &new PEAR_Dependency2($c, $o, $p, $s); + return $z; } - function getLastModified() + function getInstalledBinary() { - if (isset($this->_packageInfo['_lastmodified'])) { - return $this->_packageInfo['_lastmodified']; - } - return false; + return isset($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] : + false; } /** - * Get the contents of a file listed within the package.xml - * @param string - * @return string + * Installation of source package has failed, attempt to download and install the + * binary version of this package. + * @param PEAR_Installer + * @return array|false */ - function getFileContents($file) + function installBinary(&$installer) { - if ($this->_archiveFile == $this->_packageFile) { // unpacked - $dir = dirname($this->_packageFile); - $file = $dir . DIRECTORY_SEPARATOR . $file; - $file = str_replace(array('/', '\\'), - array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); - if (file_exists($file) && is_readable($file)) { - return implode('', file($file)); + if (!OS_WINDOWS) { + $a = false; + return $a; + } + if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { + $releasetype = $this->getPackageType() . 'release'; + if (!is_array($installer->getInstallPackages())) { + $a = false; + return $a; } - } else { // tgz - $tar = &new Archive_Tar($this->_archiveFile); - $tar->pushErrorHandling(PEAR_ERROR_RETURN); - if ($file != 'package.xml' && $file != 'package2.xml') { - $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; + foreach ($installer->getInstallPackages() as $p) { + if ($p->isExtension($this->_packageInfo['providesextension'])) { + if ($p->getPackageType() != 'extsrc' && $p->getPackageType() != 'zendextsrc') { + $a = false; + return $a; // the user probably downloaded it separately + } + } } - $file = $tar->extractInString($file); - $tar->popErrorHandling(); - if (PEAR::isError($file)) { - return PEAR::raiseError("Cannot locate file '$file' in archive"); + if (isset($this->_packageInfo[$releasetype]['binarypackage'])) { + $installer->log(0, 'Attempting to download binary version of extension "' . + $this->_packageInfo['providesextension'] . '"'); + $params = $this->_packageInfo[$releasetype]['binarypackage']; + if (!is_array($params) || !isset($params[0])) { + $params = array($params); + } + if (isset($this->_packageInfo['channel'])) { + foreach ($params as $i => $param) { + $params[$i] = array('channel' => $this->_packageInfo['channel'], + 'package' => $param, 'version' => $this->getVersion()); + } + } + $dl = &$this->getPEARDownloader($installer->ui, $installer->getOptions(), + $installer->config); + $verbose = $dl->config->get('verbose'); + $dl->config->set('verbose', -1); + foreach ($params as $param) { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $ret = $dl->download(array($param)); + PEAR::popErrorHandling(); + if (is_array($ret) && count($ret)) { + break; + } + } + $dl->config->set('verbose', $verbose); + if (is_array($ret)) { + if (count($ret) == 1) { + $pf = $ret[0]->getPackageFile(); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $installer->install($ret[0]); + PEAR::popErrorHandling(); + if (is_array($err)) { + $this->_packageInfo['#binarypackage'] = $ret[0]->getPackage(); + // "install" self, so all dependencies will work transparently + $this->_registry->addPackage2($this); + $installer->log(0, 'Download and install of binary extension "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pf->getChannel(), + 'package' => $pf->getPackage()), true) . '" successful'); + $a = array($ret[0], $err); + return $a; + } + $installer->log(0, 'Download and install of binary extension "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pf->getChannel(), + 'package' => $pf->getPackage()), true) . '" failed'); + } + } } - return $file; } + $a = false; + return $a; } - function &getRW() + /** + * @return string|false Extension name + */ + function getProvidesExtension() { - if (!class_exists('PEAR_PackageFile_v2_rw')) { - require_once 'PEAR/PackageFile/v2/rw.php'; - } - $a = new PEAR_PackageFile_v2_rw; - foreach (get_object_vars($this) as $name => $unused) { - if (!isset($this->$name)) { - continue; - } - if ($name == '_config' || $name == '_logger'|| $name == '_registry' || - $name == '_stack') { - $a->$name = &$this->$name; - } else { - $a->$name = $this->$name; + if (in_array($this->getPackageType(), + array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { + if (isset($this->_packageInfo['providesextension'])) { + return $this->_packageInfo['providesextension']; } } - return $a; + return false; } - function &getDefaultGenerator() + /** + * @param string Extension name + * @return bool + */ + function isExtension($extension) { - if (!class_exists('PEAR_PackageFile_Generator_v2')) { - require_once 'PEAR/PackageFile/Generator/v2.php'; + if (in_array($this->getPackageType(), + array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { + return $this->_packageInfo['providesextension'] == $extension; } - $a = &new PEAR_PackageFile_Generator_v2($this); - return $a; + return false; } - function analyzeSourceCode($file, $string = false) + /** + * Tests whether every part of the package.xml 1.0 is represented in + * this package.xml 2.0 + * @param PEAR_PackageFile_v1 + * @return bool + */ + function isEquivalent($pf1) { - if (!isset($this->_v2Validator) || - !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { - if (!class_exists('PEAR_PackageFile_v2_Validator')) { - require_once 'PEAR/PackageFile/v2/Validator.php'; - } - $this->_v2Validator = new PEAR_PackageFile_v2_Validator; + if (!$pf1) { + return true; } - return $this->_v2Validator->analyzeSourceCode($file, $string); - } - - function validate($state = PEAR_VALIDATE_NORMAL) - { - if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { + if ($this->getPackageType() == 'bundle') { return false; } - if (!isset($this->_v2Validator) || - !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { - if (!class_exists('PEAR_PackageFile_v2_Validator')) { - require_once 'PEAR/PackageFile/v2/Validator.php'; + $this->_stack->getErrors(true); + if (!$pf1->validate(PEAR_VALIDATE_NORMAL)) { + return false; + } + $pass = true; + if ($pf1->getPackage() != $this->getPackage()) { + $this->_differentPackage($pf1->getPackage()); + $pass = false; + } + if ($pf1->getVersion() != $this->getVersion()) { + $this->_differentVersion($pf1->getVersion()); + $pass = false; + } + if (trim($pf1->getSummary()) != $this->getSummary()) { + $this->_differentSummary($pf1->getSummary()); + $pass = false; + } + if (preg_replace('/\s+/', '', $pf1->getDescription()) != + preg_replace('/\s+/', '', $this->getDescription())) { + $this->_differentDescription($pf1->getDescription()); + $pass = false; + } + if ($pf1->getState() != $this->getState()) { + $this->_differentState($pf1->getState()); + $pass = false; + } + if (!strstr(preg_replace('/\s+/', '', $this->getNotes()), + preg_replace('/\s+/', '', $pf1->getNotes()))) { + $this->_differentNotes($pf1->getNotes()); + $pass = false; + } + $mymaintainers = $this->getMaintainers(); + $yourmaintainers = $pf1->getMaintainers(); + for ($i1 = 0; $i1 < count($yourmaintainers); $i1++) { + $reset = false; + for ($i2 = 0; $i2 < count($mymaintainers); $i2++) { + if ($mymaintainers[$i2]['handle'] == $yourmaintainers[$i1]['handle']) { + if ($mymaintainers[$i2]['role'] != $yourmaintainers[$i1]['role']) { + $this->_differentRole($mymaintainers[$i2]['handle'], + $yourmaintainers[$i1]['role'], $mymaintainers[$i2]['role']); + $pass = false; + } + if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) { + $this->_differentEmail($mymaintainers[$i2]['handle'], + $yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']); + $pass = false; + } + if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) { + $this->_differentName($mymaintainers[$i2]['handle'], + $yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']); + $pass = false; + } + unset($mymaintainers[$i2]); + $mymaintainers = array_values($mymaintainers); + unset($yourmaintainers[$i1]); + $yourmaintainers = array_values($yourmaintainers); + $reset = true; + break; + } + } + if ($reset) { + $i1 = -1; } - $this->_v2Validator = new PEAR_PackageFile_v2_Validator; } - if (isset($this->_packageInfo['xsdversion'])) { - unset($this->_packageInfo['xsdversion']); + $this->_unmatchedMaintainers($mymaintainers, $yourmaintainers); + $filelist = $this->getFilelist(); + foreach ($pf1->getFilelist() as $file => $atts) { + if (!isset($filelist[$file])) { + $this->_missingFile($file); + $pass = false; + } } - return $this->_v2Validator->validate($this, $state); + return $pass; } - function getTasksNs() + function _differentPackage($package) { - if (!isset($this->_tasksNs)) { - if (isset($this->_packageInfo['attribs'])) { - foreach ($this->_packageInfo['attribs'] as $name => $value) { - if ($value == 'http://pear.php.net/dtd/tasks-1.0') { - $this->_tasksNs = str_replace('xmlns:', '', $name); - break; - } - } - } + $this->_stack->push(__FUNCTION__, 'error', array('package' => $package, + 'self' => $this->getPackage()), + 'package.xml 1.0 package "%package%" does not match "%self%"'); + } + + function _differentVersion($version) + { + $this->_stack->push(__FUNCTION__, 'error', array('version' => $version, + 'self' => $this->getVersion()), + 'package.xml 1.0 version "%version%" does not match "%self%"'); + } + + function _differentState($state) + { + $this->_stack->push(__FUNCTION__, 'error', array('state' => $state, + 'self' => $this->getState()), + 'package.xml 1.0 state "%state%" does not match "%self%"'); + } + + function _differentRole($handle, $role, $selfrole) + { + $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, + 'role' => $role, 'self' => $selfrole), + 'package.xml 1.0 maintainer "%handle%" role "%role%" does not match "%self%"'); + } + + function _differentEmail($handle, $email, $selfemail) + { + $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, + 'email' => $email, 'self' => $selfemail), + 'package.xml 1.0 maintainer "%handle%" email "%email%" does not match "%self%"'); + } + + function _differentName($handle, $name, $selfname) + { + $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, + 'name' => $name, 'self' => $selfname), + 'package.xml 1.0 maintainer "%handle%" name "%name%" does not match "%self%"'); + } + + function _unmatchedMaintainers($my, $yours) + { + if ($my) { + array_walk($my, create_function('&$i, $k', '$i = $i["handle"];')); + $this->_stack->push(__FUNCTION__, 'error', array('handles' => $my), + 'package.xml 2.0 has unmatched extra maintainers "%handles%"'); } - return $this->_tasksNs; + if ($yours) { + array_walk($yours, create_function('&$i, $k', '$i = $i["handle"];')); + $this->_stack->push(__FUNCTION__, 'error', array('handles' => $yours), + 'package.xml 1.0 has unmatched extra maintainers "%handles%"'); + } + } + + function _differentNotes($notes) + { + $truncnotes = strlen($notes) < 25 ? $notes : substr($notes, 0, 24) . '...'; + $truncmynotes = strlen($this->getNotes()) < 25 ? $this->getNotes() : + substr($this->getNotes(), 0, 24) . '...'; + $this->_stack->push(__FUNCTION__, 'error', array('notes' => $truncnotes, + 'self' => $truncmynotes), + 'package.xml 1.0 release notes "%notes%" do not match "%self%"'); + } + + function _differentSummary($summary) + { + $truncsummary = strlen($summary) < 25 ? $summary : substr($summary, 0, 24) . '...'; + $truncmysummary = strlen($this->getsummary()) < 25 ? $this->getSummary() : + substr($this->getsummary(), 0, 24) . '...'; + $this->_stack->push(__FUNCTION__, 'error', array('summary' => $truncsummary, + 'self' => $truncmysummary), + 'package.xml 1.0 summary "%summary%" does not match "%self%"'); + } + + function _differentDescription($description) + { + $truncdescription = trim(strlen($description) < 25 ? $description : substr($description, 0, 24) . '...'); + $truncmydescription = trim(strlen($this->getDescription()) < 25 ? $this->getDescription() : + substr($this->getdescription(), 0, 24) . '...'); + $this->_stack->push(__FUNCTION__, 'error', array('description' => $truncdescription, + 'self' => $truncmydescription), + 'package.xml 1.0 description "%description%" does not match "%self%"'); + } + + function _missingFile($file) + { + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'package.xml 1.0 file "%file%" is not present in '); } /** - * Determine whether a task name is a valid task. Custom tasks may be defined - * using subdirectories by putting a "-" in the name, as in - * - * Note that this method will auto-load the task class file and test for the existence - * of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class - * PEAR_Task_mycustom_task - * @param string - * @return boolean + * WARNING - do not use this function unless you know what you're doing */ - function getTask($task) + function setRawState($state) { - $this->getTasksNs(); - // transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace - $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task); - $taskfile = str_replace(' ', '/', ucwords($task)); - $task = str_replace(array(' ', '/'), '_', ucwords($task)); - if (class_exists("PEAR_Task_$task")) { - return "PEAR_Task_$task"; - } - $fp = @fopen("PEAR/Task/$taskfile.php", 'r', true); - if ($fp) { - fclose($fp); - require_once "PEAR/Task/$taskfile.php"; - return "PEAR_Task_$task"; + if (!isset($this->_packageInfo['stability'])) { + $this->_packageInfo['stability'] = array(); } - return false; + $this->_packageInfo['stability']['release'] = $state; } /** - * Key-friendly array_splice - * @param tagname to splice a value in before - * @param mixed the value to splice in - * @param string the new tag name + * WARNING - do not use this function unless you know what you're doing */ - function _ksplice($array, $key, $value, $newkey) + function setRawCompatible($compatible) { - $offset = array_search($key, array_keys($array)); - $after = array_slice($array, $offset); - $before = array_slice($array, 0, $offset); - $before[$newkey] = $value; - return array_merge($before, $after); + $this->_packageInfo['compatible'] = $compatible; } /** - * @param array a list of possible keys, in the order they may occur - * @param mixed contents of the new package.xml tag - * @param string tag name - * @access private + * WARNING - do not use this function unless you know what you're doing */ - function _insertBefore($array, $keys, $contents, $newkey) + function setRawPackage($package) { - foreach ($keys as $key) { - if (isset($array[$key])) { - return $array = $this->_ksplice($array, $key, $contents, $newkey); - } - } - $array[$newkey] = $contents; - return $array; + $this->_packageInfo['name'] = $package; } /** - * @param subsection of {@link $_packageInfo} - * @param array|string tag contents - * @param array format: - *
    -     * array(
    -     *   tagname => array(list of tag names that follow this one),
    -     *   childtagname => array(list of child tag names that follow this one),
    -     * )
    -     * 
    - * - * This allows construction of nested tags - * @access private + * WARNING - do not use this function unless you know what you're doing */ - function _mergeTag($manip, $contents, $order) + function setRawChannel($channel) { - if (count($order)) { - foreach ($order as $tag => $curorder) { - if (!isset($manip[$tag])) { - // ensure that the tag is set up - $manip = $this->_insertBefore($manip, $curorder, array(), $tag); - } - if (count($order) > 1) { - $manip[$tag] = $this->_mergeTag($manip[$tag], $contents, array_slice($order, 1)); - return $manip; - } - } - } else { - return $manip; - } - if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) { - $manip[$tag][] = $contents; - } else { - if (!count($manip[$tag])) { - $manip[$tag] = $contents; - } else { - $manip[$tag] = array($manip[$tag]); - $manip[$tag][] = $contents; - } - } - return $manip; + $this->_packageInfo['channel'] = $channel; } -} -?> -PEAR-1.8.0/PEAR/REST/10.php100664 764 764 100236 100664 7604 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: 10.php,v 1.60 2009/03/07 23:09:56 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a12 - */ -/** - * For downloading REST xml/txt files - */ -require_once 'PEAR/REST.php'; + function setRequestedGroup($group) + { + $this->_requestedGroup = $group; + } -/** - * Implement REST 1.0 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a12 - */ -class PEAR_REST_10 -{ - /** - * @var PEAR_REST - */ - var $_rest; - function PEAR_REST_10($config, $options = array()) + function getRequestedGroup() { - $this->_rest = &new PEAR_REST($config, $options); + if (isset($this->_requestedGroup)) { + return $this->_requestedGroup; + } + return false; } /** - * Retrieve information about a remote package to be downloaded from a REST server + * For saving in the registry. * - * @param string $base The uri to prepend to all REST calls - * @param array $packageinfo an array of format: - *
    -     *  array(
    -     *   'package' => 'packagename',
    -     *   'channel' => 'channelname',
    -     *  ['state' => 'alpha' (or valid state),]
    -     *  -or-
    -     *  ['version' => '1.whatever']
    -     * 
    - * @param string $prefstate Current preferred_state config variable value - * @param bool $installed the installed version of this package to compare against - * @return array|false|PEAR_Error see {@link _returnDownloadURL()} + * Set the last version that was installed + * @param string */ - function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false) + function setLastInstalledVersion($version) { - $channel = $packageinfo['channel']; - $package = $packageinfo['package']; - $states = $this->betterStates($prefstate, true); - if (!$states) { - return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); - } + $this->_packageInfo['_lastversion'] = $version; + } - $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; - $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; - $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml', false, false, $channel); - if (PEAR::isError($info)) { - return PEAR::raiseError('No releases available for package "' . - $channel . '/' . $package . '"'); + /** + * @return string|false + */ + function getLastInstalledVersion() + { + if (isset($this->_packageInfo['_lastversion'])) { + return $this->_packageInfo['_lastversion']; } + return false; + } - if (!isset($info['r'])) { - return false; + /** + * Determines whether this package.xml has post-install scripts or not + * @return array|false + */ + function listPostinstallScripts() + { + $filelist = $this->getFilelist(); + $contents = $this->getContents(); + $contents = $contents['dir']['file']; + if (!is_array($contents) || !isset($contents[0])) { + $contents = array($contents); } - - $release = $found = false; - if (!is_array($info['r']) || !isset($info['r'][0])) { - $info['r'] = array($info['r']); + $taskfiles = array(); + foreach ($contents as $file) { + $atts = $file['attribs']; + unset($file['attribs']); + if (count($file)) { + $taskfiles[$atts['name']] = $file; + } } - - foreach ($info['r'] as $release) { - if (!isset($this->_rest->_options['force']) && ($installed && - version_compare($release['v'], $installed, '<'))) { + $common = new PEAR_Common; + $common->debug = $this->_config->get('verbose'); + $this->_scripts = array(); + $ret = array(); + foreach ($taskfiles as $name => $tasks) { + if (!isset($filelist[$name])) { + // ignored files will not be in the filelist continue; } - - if (isset($state)) { - // try our preferred state first - if ($release['s'] == $state) { - $found = true; - break; - } - // see if there is something newer and more stable - // bug #7221 - if (in_array($release['s'], $this->betterStates($state), true)) { - $found = true; - break; - } - } elseif (isset($version)) { - if ($release['v'] == $version) { - $found = true; - break; - } - } else { - if (in_array($release['s'], $states)) { - $found = true; - break; + $atts = $filelist[$name]; + foreach ($tasks as $tag => $raw) { + $task = $this->getTask($tag); + $task = &new $task($this->_config, $common, PEAR_TASK_INSTALL); + if ($task->isScript()) { + $ret[] = $filelist[$name]['installed_as']; } } } - - return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel); + if (count($ret)) { + return $ret; + } + return false; } - function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage, - $prefstate = 'stable', $installed = false, $channel = false) + /** + * Initialize post-install scripts for running + * + * This method can be used to detect post-install scripts, as the return value + * indicates whether any exist + * @return bool + */ + function initPostinstallScripts() { - $channel = $dependency['channel']; - $package = $dependency['name']; - $states = $this->betterStates($prefstate, true); - if (!$states) { - return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); - } - $state = isset($dependency['state']) ? $dependency['state'] : null; - $version = isset($dependency['version']) ? $dependency['version'] : null; - $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml', false, false, $channel); - if (PEAR::isError($info)) { - return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package'] - . '" dependency "' . $channel . '/' . $package . '" has no releases'); + $filelist = $this->getFilelist(); + $contents = $this->getContents(); + $contents = $contents['dir']['file']; + if (!is_array($contents) || !isset($contents[0])) { + $contents = array($contents); } - if (!is_array($info) || !isset($info['r'])) { - return false; + $taskfiles = array(); + foreach ($contents as $file) { + $atts = $file['attribs']; + unset($file['attribs']); + if (count($file)) { + $taskfiles[$atts['name']] = $file; + } } - $exclude = array(); - $min = $max = $recommended = false; - if ($xsdversion == '1.0') { - switch ($dependency['rel']) { - case 'ge' : - $min = $dependency['version']; - break; - case 'gt' : - $min = $dependency['version']; - $exclude = array($dependency['version']); - break; - case 'eq' : - $recommended = $dependency['version']; - break; - case 'lt' : - $max = $dependency['version']; - $exclude = array($dependency['version']); - break; - case 'le' : - $max = $dependency['version']; - break; - case 'ne' : - $exclude = array($dependency['version']); - break; + $common = new PEAR_Common; + $common->debug = $this->_config->get('verbose'); + $this->_scripts = array(); + foreach ($taskfiles as $name => $tasks) { + if (!isset($filelist[$name])) { + // file was not installed due to installconditions + continue; } - } else { - $min = isset($dependency['min']) ? $dependency['min'] : false; - $max = isset($dependency['max']) ? $dependency['max'] : false; - $recommended = isset($dependency['recommended']) ? - $dependency['recommended'] : false; - if (isset($dependency['exclude'])) { - if (!isset($dependency['exclude'][0])) { - $exclude = array($dependency['exclude']); + $atts = $filelist[$name]; + foreach ($tasks as $tag => $raw) { + $taskname = $this->getTask($tag); + $task = &new $taskname($this->_config, $common, PEAR_TASK_INSTALL); + if (!$task->isScript()) { + continue; // scripts are only handled after installation + } + $lastversion = isset($this->_packageInfo['_lastversion']) ? + $this->_packageInfo['_lastversion'] : null; + $task->init($raw, $atts, $lastversion); + $res = $task->startSession($this, $atts['installed_as']); + if (!$res) { + continue; // skip this file } + if (PEAR::isError($res)) { + return $res; + } + $assign = &$task; + $this->_scripts[] = &$assign; } } - $release = $found = false; - if (!is_array($info['r']) || !isset($info['r'][0])) { - $info['r'] = array($info['r']); + if (count($this->_scripts)) { + return true; } - foreach ($info['r'] as $release) { - if (!isset($this->_rest->_options['force']) && ($installed && - version_compare($release['v'], $installed, '<'))) { - continue; + return false; + } + + function runPostinstallScripts() + { + if ($this->initPostinstallScripts()) { + $ui = &PEAR_Frontend::singleton(); + if ($ui) { + $ui->runPostinstallScripts($this->_scripts, $this); } - if (in_array($release['v'], $exclude)) { // skip excluded versions - continue; + } + } + + + /** + * Convert a recursive set of and tags into a single tag with + * tags. + */ + function flattenFilelist() + { + if (isset($this->_packageInfo['bundle'])) { + return; + } + $filelist = array(); + if (isset($this->_packageInfo['contents']['dir']['dir'])) { + $this->_getFlattenedFilelist($filelist, $this->_packageInfo['contents']['dir']); + if (!isset($filelist[1])) { + $filelist = $filelist[0]; } - // allow newer releases to say "I'm OK with the dependent package" - if ($xsdversion == '2.0' && isset($release['co'])) { - if (!is_array($release['co']) || !isset($release['co'][0])) { - $release['co'] = array($release['co']); - } - foreach ($release['co'] as $entry) { - if (isset($entry['x']) && !is_array($entry['x'])) { - $entry['x'] = array($entry['x']); - } elseif (!isset($entry['x'])) { - $entry['x'] = array(); - } - if ($entry['c'] == $deppackage['channel'] && - strtolower($entry['p']) == strtolower($deppackage['package']) && - version_compare($deppackage['version'], $entry['min'], '>=') && - version_compare($deppackage['version'], $entry['max'], '<=') && - !in_array($release['v'], $entry['x'])) { - $recommended = $release['v']; - break; + $this->_packageInfo['contents']['dir']['file'] = $filelist; + unset($this->_packageInfo['contents']['dir']['dir']); + } else { + // else already flattened but check for baseinstalldir propagation + if (isset($this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'])) { + if (isset($this->_packageInfo['contents']['dir']['file'][0])) { + foreach ($this->_packageInfo['contents']['dir']['file'] as $i => $file) { + if (isset($file['attribs']['baseinstalldir'])) { + continue; + } + $this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir'] + = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; } - } - } - if ($recommended) { - if ($release['v'] != $recommended) { // if we want a specific - // version, then skip all others - continue; } else { - if (!in_array($release['s'], $states)) { - // the stability is too low, but we must return the - // recommended version if possible - return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel); + if (!isset($this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'])) { + $this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'] + = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; } } } - if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions - continue; - } - if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions - continue; - } - if ($installed && version_compare($release['v'], $installed, '<')) { - continue; - } - if (in_array($release['s'], $states)) { // if in the preferred state... - $found = true; // ... then use it - break; - } } - return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel); } /** - * Take raw data and return the array needed for processing a download URL - * - * @param string $base REST base uri - * @param string $package Package name - * @param array $release an array of format array('v' => version, 's' => state) - * describing the release to download - * @param array $info list of all releases as defined by allreleases.xml - * @param bool|null $found determines whether the release was found or this is the next - * best alternative. If null, then versions were skipped because - * of PHP dependency - * @return array|PEAR_Error - * @access private + * @param array the final flattened file list + * @param array the current directory being processed + * @param string|false any recursively inherited baeinstalldir attribute + * @param string private recursion variable + * @return array + * @access protected */ - function _returnDownloadURL($base, $package, $release, $info, $found, $phpversion = false, $channel = false) + function _getFlattenedFilelist(&$files, $dir, $baseinstall = false, $path = '') { - if (!$found) { - $release = $info['r'][0]; - } - $pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . strtolower($package) . '/' . - 'info.xml', false, false, $channel); - if (PEAR::isError($pinfo)) { - return PEAR::raiseError('Package "' . $package . - '" does not have REST info xml available'); - } - $releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . - $release['v'] . '.xml', false, false, $channel); - if (PEAR::isError($releaseinfo)) { - return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . - '" does not have REST xml available'); - } - $packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . - 'deps.' . $release['v'] . '.txt', false, true, $channel); - if (PEAR::isError($packagexml)) { - return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . - '" does not have REST dependency information available'); - } - - $packagexml = unserialize($packagexml); - if (!$packagexml) { - $packagexml = array(); - } - $allinfo = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . - '/allreleases.xml', false, false, $channel); - if (!is_array($allinfo['r']) || !isset($allinfo['r'][0])) { - $allinfo['r'] = array($allinfo['r']); + if (isset($dir['attribs']) && isset($dir['attribs']['baseinstalldir'])) { + $baseinstall = $dir['attribs']['baseinstalldir']; } - $compatible = false; - foreach ($allinfo['r'] as $release) { - if ($release['v'] != $releaseinfo['v']) { - continue; - } - if (!isset($release['co'])) { - break; - } - $compatible = array(); - if (!is_array($release['co']) || !isset($release['co'][0])) { - $release['co'] = array($release['co']); + if (isset($dir['dir'])) { + if (!isset($dir['dir'][0])) { + $dir['dir'] = array($dir['dir']); } - foreach ($release['co'] as $entry) { - $comp = array(); - $comp['name'] = $entry['p']; - $comp['channel'] = $entry['c']; - $comp['min'] = $entry['min']; - $comp['max'] = $entry['max']; - if (isset($entry['x']) && !is_array($entry['x'])) { - $comp['exclude'] = $entry['x']; + foreach ($dir['dir'] as $subdir) { + if (!isset($subdir['attribs']) || !isset($subdir['attribs']['name'])) { + $name = '*unknown*'; + } else { + $name = $subdir['attribs']['name']; } - $compatible[] = $comp; - } - if (count($compatible) == 1) { - $compatible = $compatible[0]; + $newpath = empty($path) ? $name : + $path . '/' . $name; + $this->_getFlattenedFilelist($files, $subdir, + $baseinstall, $newpath); } - break; } - if (isset($pinfo['dc']) && isset($pinfo['dp'])) { - if (is_array($pinfo['dp'])) { - $deprecated = array('channel' => (string) $pinfo['dc'], - 'package' => trim($pinfo['dp']['_content'])); - } else { - $deprecated = array('channel' => (string) $pinfo['dc'], - 'package' => trim($pinfo['dp'])); + if (isset($dir['file'])) { + if (!isset($dir['file'][0])) { + $dir['file'] = array($dir['file']); + } + foreach ($dir['file'] as $file) { + $attrs = $file['attribs']; + $name = $attrs['name']; + if ($baseinstall && !isset($attrs['baseinstalldir'])) { + $attrs['baseinstalldir'] = $baseinstall; + } + $attrs['name'] = empty($path) ? $name : $path . '/' . $name; + $attrs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), + $attrs['name']); + $file['attribs'] = $attrs; + $files[] = $file; } - } else { - $deprecated = false; - } - if ($found) { - return - array('version' => $releaseinfo['v'], - 'info' => $packagexml, - 'package' => $releaseinfo['p']['_content'], - 'stability' => $releaseinfo['st'], - 'url' => $releaseinfo['g'], - 'compatible' => $compatible, - 'deprecated' => $deprecated, - ); - } else { - return - array('version' => $releaseinfo['v'], - 'package' => $releaseinfo['p']['_content'], - 'stability' => $releaseinfo['st'], - 'info' => $packagexml, - 'compatible' => $compatible, - 'deprecated' => $deprecated, - 'php' => $phpversion - ); } } - function listPackages($base, $channel = false) + function setConfig(&$config) { - $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); - if (PEAR::isError($packagelist)) { - return $packagelist; - } - if (!is_array($packagelist) || !isset($packagelist['p'])) { - return array(); - } - if (!is_array($packagelist['p'])) { - $packagelist['p'] = array($packagelist['p']); + $this->_config = &$config; + $this->_registry = &$config->getRegistry(); + } + + function setLogger(&$logger) + { + if (!is_object($logger) || !method_exists($logger, 'log')) { + return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); } - return $packagelist['p']; + $this->_logger = &$logger; } /** - * List all categories of a REST server - * - * @param string $base base URL of the server - * @return array of categorynames + * WARNING - do not use this function directly unless you know what you're doing */ - function listCategories($base, $channel = false) + function setDeps($deps) { - $categories = array(); + $this->_packageInfo['dependencies'] = $deps; + } - // c/categories.xml does not exist; - // check for every package its category manually - // This is SLOOOWWWW : /// - $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); - if (PEAR::isError($packagelist)) { - return $packagelist; - } - if (!is_array($packagelist) || !isset($packagelist['p'])) { - $ret = array(); - return $ret; - } - if (!is_array($packagelist['p'])) { - $packagelist['p'] = array($packagelist['p']); - } + /** + * WARNING - do not use this function directly unless you know what you're doing + */ + function setCompatible($compat) + { + $this->_packageInfo['compatible'] = $compat; + } - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - foreach ($packagelist['p'] as $package) { - $inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel); - if (PEAR::isError($inf)) { - PEAR::popErrorHandling(); - return $inf; - } - $cat = $inf['ca']['_content']; - if (!isset($categories[$cat])) { - $categories[$cat] = $inf['ca']; - } - } - return array_values($categories); + function setPackagefile($file, $archive = false) + { + $this->_packageFile = $file; + $this->_archiveFile = $archive ? $archive : $file; } /** - * List a category of a REST server - * - * @param string $base base URL of the server - * @param string $category name of the category - * @param boolean $info also download full package info - * @return array of packagenames + * Wrapper to {@link PEAR_ErrorStack::getErrors()} + * @param boolean determines whether to purge the error stack after retrieving + * @return array */ - function listCategory($base, $category, $info = false, $channel = false) + function getValidationWarnings($purge = true) { - // gives '404 Not Found' error when category doesn't exist - $packagelist = $this->_rest->retrieveData($base.'c/'.urlencode($category).'/packages.xml', false, false, $channel); - if (PEAR::isError($packagelist)) { - return $packagelist; - } - if (!is_array($packagelist) || !isset($packagelist['p'])) { - return array(); - } - if (!is_array($packagelist['p']) || - !isset($packagelist['p'][0])) { // only 1 pkg - $packagelist = array($packagelist['p']); - } else { - $packagelist = $packagelist['p']; - } + return $this->_stack->getErrors($purge); + } - if ($info == true) { - // get individual package info - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - foreach ($packagelist as $i => $packageitem) { - $url = sprintf('%s'.'r/%s/latest.txt', - $base, - strtolower($packageitem['_content'])); - $version = $this->_rest->retrieveData($url, false, false, $channel); - if (PEAR::isError($version)) { - break; // skipit - } - $url = sprintf('%s'.'r/%s/%s.xml', - $base, - strtolower($packageitem['_content']), - $version); - $info = $this->_rest->retrieveData($url, false, false, $channel); - if (PEAR::isError($info)) { - break; // skipit - } - $packagelist[$i]['info'] = $info; - } - PEAR::popErrorHandling(); - } + function getPackageFile() + { + return $this->_packageFile; + } - return $packagelist; + function getArchiveFile() + { + return $this->_archiveFile; } - function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false) + /** + * Directly set the array that defines this packagefile + * + * WARNING: no validation. This should only be performed by internal methods + * inside PEAR or by inputting an array saved from an existing PEAR_PackageFile_v2 + * @param array + */ + function fromArray($pinfo) { - $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); - if (PEAR::isError($packagelist)) { - return $packagelist; - } - if ($this->_rest->config->get('verbose') > 0) { - $ui = &PEAR_Frontend::singleton(); - $ui->log('Retrieving data...0%', false); - } - $ret = array(); - if (!is_array($packagelist) || !isset($packagelist['p'])) { - return $ret; - } - if (!is_array($packagelist['p'])) { - $packagelist['p'] = array($packagelist['p']); - } + unset($pinfo['old']); + unset($pinfo['xsdversion']); + $this->_incomplete = false; + $this->_packageInfo = $pinfo; + } - // only search-packagename = quicksearch ! - if ($searchpackage && (!$searchsummary || empty($searchpackage))) { - $newpackagelist = array(); - foreach ($packagelist['p'] as $package) { - if (!empty($searchpackage) && stristr($package, $searchpackage) !== false) { - $newpackagelist[] = $package; - } - } - $packagelist['p'] = $newpackagelist; + function isIncomplete() + { + return $this->_incomplete; + } + + /** + * @return array + */ + function toArray($forreg = false) + { + if (!$this->validate(PEAR_VALIDATE_NORMAL)) { + return false; } - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $next = .1; - foreach ($packagelist['p'] as $progress => $package) { - if ($this->_rest->config->get('verbose') > 0) { - if ($progress / count($packagelist['p']) >= $next) { - if ($next == .5) { - $ui->log('50%', false); - } else { - $ui->log('.', false); - } - $next += .1; - } - } + return $this->getArray($forreg); + } - if ($basic) { // remote-list command - if ($dostable) { - $latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . - '/stable.txt', false, false, $channel); - } else { - $latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . - '/latest.txt', false, false, $channel); - } - if (PEAR::isError($latest)) { - $latest = false; - } - $info = array('stable' => $latest); - } else { // list-all command - $inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel); - if (PEAR::isError($inf)) { - PEAR::popErrorHandling(); - return $inf; - } - if ($searchpackage) { - $found = (!empty($searchpackage) && stristr($package, $searchpackage) !== false); - if (!$found && !(isset($searchsummary) && !empty($searchsummary) - && (stristr($inf['s'], $searchsummary) !== false - || stristr($inf['d'], $searchsummary) !== false))) - { - continue; - }; - } - $releases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . - '/allreleases.xml', false, false, $channel); - if (PEAR::isError($releases)) { - continue; - } - if (!isset($releases['r'][0])) { - $releases['r'] = array($releases['r']); - } - unset($latest); - unset($unstable); - unset($stable); - unset($state); - foreach ($releases['r'] as $release) { - if (!isset($latest)) { - if ($dostable && $release['s'] == 'stable') { - $latest = $release['v']; - $state = 'stable'; - } - if (!$dostable) { - $latest = $release['v']; - $state = $release['s']; - } - } - if (!isset($stable) && $release['s'] == 'stable') { - $stable = $release['v']; - if (!isset($unstable)) { - $unstable = $stable; - } - } - if (!isset($unstable) && $release['s'] != 'stable') { - $latest = $unstable = $release['v']; - $state = $release['s']; - } - if (isset($latest) && !isset($state)) { - $state = $release['s']; - } - if (isset($latest) && isset($stable) && isset($unstable)) { - break; - } - } - $deps = array(); - if (!isset($unstable)) { - $unstable = false; - $state = 'stable'; - if (isset($stable)) { - $latest = $unstable = $stable; - } - } else { - $latest = $unstable; - } - if (!isset($latest)) { - $latest = false; - } - if ($latest) { - $d = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' . - $latest . '.txt', false, false, $channel); - if (!PEAR::isError($d)) { - $d = unserialize($d); - if ($d) { - if (isset($d['required'])) { - if (!class_exists('PEAR_PackageFile_v2')) { - require_once 'PEAR/PackageFile/v2.php'; - } - if (!isset($pf)) { - $pf = new PEAR_PackageFile_v2; - } - $pf->setDeps($d); - $tdeps = $pf->getDeps(); - } else { - $tdeps = $d; - } - foreach ($tdeps as $dep) { - if ($dep['type'] !== 'pkg') { - continue; - } - $deps[] = $dep; - } - } - } - } - if (!isset($stable)) { - $stable = '-n/a-'; - } - if (!$searchpackage) { - $info = array('stable' => $latest, 'summary' => $inf['s'], 'description' => - $inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'], - 'unstable' => $unstable, 'state' => $state); - } else { - $info = array('stable' => $stable, 'summary' => $inf['s'], 'description' => - $inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'], - 'unstable' => $unstable, 'state' => $state); - } + function getArray($forReg = false) + { + if ($forReg) { + $arr = $this->_packageInfo; + $arr['old'] = array(); + $arr['old']['version'] = $this->getVersion(); + $arr['old']['release_date'] = $this->getDate(); + $arr['old']['release_state'] = $this->getState(); + $arr['old']['release_license'] = $this->getLicense(); + $arr['old']['release_notes'] = $this->getNotes(); + $arr['old']['release_deps'] = $this->getDeps(); + $arr['old']['maintainers'] = $this->getMaintainers(); + $arr['xsdversion'] = '2.0'; + return $arr; + } else { + $info = $this->_packageInfo; + unset($info['dirtree']); + if (isset($info['_lastversion'])) { + unset($info['_lastversion']); } - $ret[$package] = $info; + if (isset($info['#binarypackage'])) { + unset($info['#binarypackage']); + } + return $info; } - PEAR::popErrorHandling(); - return $ret; } - function listLatestUpgrades($base, $pref_state, $installed, $channel, &$reg) + function packageInfo($field) { - $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); - if (PEAR::isError($packagelist)) { - return $packagelist; + $arr = $this->getArray(true); + if ($field == 'state') { + return $arr['stability']['release']; } - - $ret = array(); - if (!is_array($packagelist) || !isset($packagelist['p'])) { - return $ret; + if ($field == 'api-version') { + return $arr['version']['api']; } - - if (!is_array($packagelist['p'])) { - $packagelist['p'] = array($packagelist['p']); + if ($field == 'api-state') { + return $arr['stability']['api']; } - - foreach ($packagelist['p'] as $package) { - if (!isset($installed[strtolower($package)])) { - continue; - } - - $inst_version = $reg->packageInfo($package, 'version', $channel); - $inst_state = $reg->packageInfo($package, 'release_state', $channel); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . - '/allreleases.xml', false, false, $channel); - PEAR::popErrorHandling(); - if (PEAR::isError($info)) { - continue; // no remote releases - } - - if (!isset($info['r'])) { - continue; + if (isset($arr['old'][$field])) { + if (!is_string($arr['old'][$field])) { + return null; } - - $release = $found = false; - if (!is_array($info['r']) || !isset($info['r'][0])) { - $info['r'] = array($info['r']); + return $arr['old'][$field]; + } + if (isset($arr[$field])) { + if (!is_string($arr[$field])) { + return null; } + return $arr[$field]; + } + return null; + } - // $info['r'] is sorted by version number - usort($info['r'], array($this, '_sortReleasesByVersionNumber')); - foreach ($info['r'] as $release) { - if ($inst_version && version_compare($release['v'], $inst_version, '<=')) { - // not newer than the one installed - break; - } - - // new version > installed version - if (!$pref_state) { - // every state is a good state - $found = true; - break; - } else { - $new_state = $release['s']; - // if new state >= installed state: go - if (in_array($new_state, $this->betterStates($inst_state, true))) { - $found = true; - break; - } else { - // only allow to lower the state of package, - // if new state >= preferred state: go - if (in_array($new_state, $this->betterStates($pref_state, true))) { - $found = true; - break; - } - } - } - } + function getName() + { + return $this->getPackage(); + } - if (!$found) { - continue; - } + function getPackage() + { + if (isset($this->_packageInfo['name'])) { + return $this->_packageInfo['name']; + } + return false; + } - $relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . - $release['v'] . '.xml', false, false, $channel); - if (PEAR::isError($relinfo)) { - return $relinfo; - } + function getChannel() + { + if (isset($this->_packageInfo['uri'])) { + return '__uri'; + } + if (isset($this->_packageInfo['channel'])) { + return strtolower($this->_packageInfo['channel']); + } + return false; + } - $ret[$package] = array( - 'version' => $release['v'], - 'state' => $release['s'], - 'filesize' => $relinfo['f'], - ); + function getUri() + { + if (isset($this->_packageInfo['uri'])) { + return $this->_packageInfo['uri']; } + return false; + } - return $ret; + function getExtends() + { + if (isset($this->_packageInfo['extends'])) { + return $this->_packageInfo['extends']; + } + return false; } - function packageInfo($base, $package, $channel = false) + function getSummary() { - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $pinfo = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel); - if (PEAR::isError($pinfo)) { - PEAR::popErrorHandling(); - return PEAR::raiseError('Unknown package: "' . $package . '" in channel "' . $channel . '"' . "\n". 'Debug: ' . - $pinfo->getMessage()); + if (isset($this->_packageInfo['summary'])) { + return $this->_packageInfo['summary']; } + return false; + } - $releases = array(); - $allreleases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . - '/allreleases.xml', false, false, $channel); - if (!PEAR::isError($allreleases)) { - if (!class_exists('PEAR_PackageFile_v2')) { - require_once 'PEAR/PackageFile/v2.php'; - } + function getDescription() + { + if (isset($this->_packageInfo['description'])) { + return $this->_packageInfo['description']; + } + return false; + } - if (!is_array($allreleases['r']) || !isset($allreleases['r'][0])) { - $allreleases['r'] = array($allreleases['r']); + function getMaintainers($raw = false) + { + if (!isset($this->_packageInfo['lead'])) { + return false; + } + if ($raw) { + $ret = array('lead' => $this->_packageInfo['lead']); + (isset($this->_packageInfo['developer'])) ? + $ret['developer'] = $this->_packageInfo['developer'] :null; + (isset($this->_packageInfo['contributor'])) ? + $ret['contributor'] = $this->_packageInfo['contributor'] :null; + (isset($this->_packageInfo['helper'])) ? + $ret['helper'] = $this->_packageInfo['helper'] :null; + return $ret; + } else { + $ret = array(); + $leads = isset($this->_packageInfo['lead'][0]) ? $this->_packageInfo['lead'] : + array($this->_packageInfo['lead']); + foreach ($leads as $lead) { + $s = $lead; + $s['handle'] = $s['user']; + unset($s['user']); + $s['role'] = 'lead'; + $ret[] = $s; } - - $pf = new PEAR_PackageFile_v2; - foreach ($allreleases['r'] as $release) { - $ds = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' . - $release['v'] . '.txt', false, false, $channel); - if (PEAR::isError($ds)) { - continue; - } - - if (!isset($latest)) { - $latest = $release['v']; + if (isset($this->_packageInfo['developer'])) { + $leads = isset($this->_packageInfo['developer'][0]) ? + $this->_packageInfo['developer'] : + array($this->_packageInfo['developer']); + foreach ($leads as $maintainer) { + $s = $maintainer; + $s['handle'] = $s['user']; + unset($s['user']); + $s['role'] = 'developer'; + $ret[] = $s; } - - $pf->setDeps(unserialize($ds)); - $ds = $pf->getDeps(); - $info = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) - . '/' . $release['v'] . '.xml', false, false, $channel); - - if (PEAR::isError($info)) { - continue; + } + if (isset($this->_packageInfo['contributor'])) { + $leads = isset($this->_packageInfo['contributor'][0]) ? + $this->_packageInfo['contributor'] : + array($this->_packageInfo['contributor']); + foreach ($leads as $maintainer) { + $s = $maintainer; + $s['handle'] = $s['user']; + unset($s['user']); + $s['role'] = 'contributor'; + $ret[] = $s; } - - $releases[$release['v']] = array( - 'doneby' => $info['m'], - 'license' => $info['l'], - 'summary' => $info['s'], - 'description' => $info['d'], - 'releasedate' => $info['da'], - 'releasenotes' => $info['n'], - 'state' => $release['s'], - 'deps' => $ds ? $ds : array(), - ); } - } else { - $latest = ''; - } - - PEAR::popErrorHandling(); - if (isset($pinfo['dc']) && isset($pinfo['dp'])) { - if (is_array($pinfo['dp'])) { - $deprecated = array('channel' => (string) $pinfo['dc'], - 'package' => trim($pinfo['dp']['_content'])); - } else { - $deprecated = array('channel' => (string) $pinfo['dc'], - 'package' => trim($pinfo['dp'])); + if (isset($this->_packageInfo['helper'])) { + $leads = isset($this->_packageInfo['helper'][0]) ? + $this->_packageInfo['helper'] : + array($this->_packageInfo['helper']); + foreach ($leads as $maintainer) { + $s = $maintainer; + $s['handle'] = $s['user']; + unset($s['user']); + $s['role'] = 'helper'; + $ret[] = $s; + } } - } else { - $deprecated = false; - } - - if (!isset($latest)) { - $latest = ''; + return $ret; } - - return array( - 'name' => $pinfo['n'], - 'channel' => $pinfo['c'], - 'category' => $pinfo['ca']['_content'], - 'stable' => $latest, - 'license' => $pinfo['l'], - 'summary' => $pinfo['s'], - 'description' => $pinfo['d'], - 'releases' => $releases, - 'deprecated' => $deprecated, - ); + return false; } - /** - * Return an array containing all of the states that are more stable than - * or equal to the passed in state - * - * @param string Release state - * @param boolean Determines whether to include $state in the list - * @return false|array False if $state is not a valid release state - */ - function betterStates($state, $include = false) + function getLeads() { - static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); - $i = array_search($state, $states); - if ($i === false) { - return false; + if (isset($this->_packageInfo['lead'])) { + return $this->_packageInfo['lead']; } + return false; + } - if ($include) { - $i--; + function getDevelopers() + { + if (isset($this->_packageInfo['developer'])) { + return $this->_packageInfo['developer']; } - - return array_slice($states, $i + 1); + return false; } - /** - * Sort releases by version number - * - * @access private - */ - function _sortReleasesByVersionNumber($a, $b) + function getContributors() { - if (version_compare($a['v'], $b['v'], '=')) { - return 0; + if (isset($this->_packageInfo['contributor'])) { + return $this->_packageInfo['contributor']; } + return false; + } - if (version_compare($a['v'], $b['v'], '>')) { - return -1; + function getHelpers() + { + if (isset($this->_packageInfo['helper'])) { + return $this->_packageInfo['helper']; } + return false; + } - if (version_compare($a['v'], $b['v'], '<')) { - return 1; + function setDate($date) + { + if (!isset($this->_packageInfo['date'])) { + // ensure that the extends tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('time', 'version', + 'stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', + 'zendextbinrelease', 'bundle', 'changelog'), array(), 'date'); } + $this->_packageInfo['date'] = $date; + $this->_isValid = 0; } -}PEAR-1.8.0/PEAR/REST/11.php100664 764 764 26471 100664 7575 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: 11.php,v 1.16 2009/02/24 23:39:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.3 - */ - -/** - * For downloading REST xml/txt files - */ -require_once 'PEAR/REST.php'; - -/** - * Implement REST 1.1 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.3 - */ -class PEAR_REST_11 -{ - /** - * @var PEAR_REST - */ - var $_rest; - - function PEAR_REST_11($config, $options = array()) - { - $this->_rest = &new PEAR_REST($config, $options); - } - - function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false) - { - $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel); - if (PEAR::isError($categorylist)) { - return $categorylist; - } - - $ret = array(); - if (!is_array($categorylist['c']) || !isset($categorylist['c'][0])) { - $categorylist['c'] = array($categorylist['c']); - } - - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - - foreach ($categorylist['c'] as $progress => $category) { - $category = $category['_content']; - $packagesinfo = $this->_rest->retrieveData($base . - 'c/' . urlencode($category) . '/packagesinfo.xml', false, false, $channel); - - if (PEAR::isError($packagesinfo)) { - continue; - } - - if (!is_array($packagesinfo) || !isset($packagesinfo['pi'])) { - continue; - } - - if (!is_array($packagesinfo['pi']) || !isset($packagesinfo['pi'][0])) { - $packagesinfo['pi'] = array($packagesinfo['pi']); - } - - foreach ($packagesinfo['pi'] as $packageinfo) { - if (empty($packageinfo)) { - continue; - } - - $info = $packageinfo['p']; - $package = $info['n']; - $releases = isset($packageinfo['a']) ? $packageinfo['a'] : false; - unset($latest); - unset($unstable); - unset($stable); - unset($state); - - if ($releases) { - if (!isset($releases['r'][0])) { - $releases['r'] = array($releases['r']); - } - foreach ($releases['r'] as $release) { - if (!isset($latest)) { - if ($dostable && $release['s'] == 'stable') { - $latest = $release['v']; - $state = 'stable'; - } - if (!$dostable) { - $latest = $release['v']; - $state = $release['s']; - } - } - if (!isset($stable) && $release['s'] == 'stable') { - $stable = $release['v']; - if (!isset($unstable)) { - $unstable = $stable; - } - } - if (!isset($unstable) && $release['s'] != 'stable') { - $unstable = $release['v']; - $state = $release['s']; - } - if (isset($latest) && !isset($state)) { - $state = $release['s']; - } - if (isset($latest) && isset($stable) && isset($unstable)) { - break; - } - } - } - - if ($basic) { // remote-list command - if (!isset($latest)) { - $latest = false; - } - if ($dostable) { - // $state is not set if there are no releases - if (isset($state) && $state == 'stable') { - $ret[$package] = array('stable' => $latest); - } else { - $ret[$package] = array('stable' => '-n/a-'); - } - } else { - $ret[$package] = array('stable' => $latest); - } - continue; - } - - // list-all command - $deps = array(); - if (!isset($unstable)) { - $unstable = false; - $state = 'stable'; - if (isset($stable)) { - $latest = $unstable = $stable; - } - } else { - $latest = $unstable; - } - - if (!isset($latest)) { - $latest = false; - } - - if ($latest && isset($packageinfo['deps'])) { - if (!is_array($packageinfo['deps']) || - !isset($packageinfo['deps'][0])) { - $packageinfo['deps'] = array($packageinfo['deps']); - } - $d = false; - foreach ($packageinfo['deps'] as $dep) { - if ($dep['v'] == $latest) { - $d = unserialize($dep['d']); - } - } - if ($d) { - if (isset($d['required'])) { - if (!class_exists('PEAR_PackageFile_v2')) { - require_once 'PEAR/PackageFile/v2.php'; - } - if (!isset($pf)) { - $pf = new PEAR_PackageFile_v2; - } - $pf->setDeps($d); - $tdeps = $pf->getDeps(); - } else { - $tdeps = $d; - } - foreach ($tdeps as $dep) { - if ($dep['type'] !== 'pkg') { - continue; - } - $deps[] = $dep; - } - } - } - - $info = array('stable' => $latest, 'summary' => $info['s'], - 'description' => - $info['d'], 'deps' => $deps, 'category' => $info['ca']['_content'], - 'unstable' => $unstable, 'state' => $state); - $ret[$package] = $info; - } - } - PEAR::popErrorHandling(); - return $ret; - } - - /** - * List all categories of a REST server - * - * @param string $base base URL of the server - * @return array of categorynames - */ - function listCategories($base, $channel = false) - { - $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel); - if (PEAR::isError($categorylist)) { - return $categorylist; - } - if (!is_array($categorylist) || !isset($categorylist['c'])) { - return array(); - } - if (isset($categorylist['c']['_content'])) { - // only 1 category - $categorylist['c'] = array($categorylist['c']); - } - return $categorylist['c']; - } - - /** - * List packages in a category of a REST server - * - * @param string $base base URL of the server - * @param string $category name of the category - * @param boolean $info also download full package info - * @return array of packagenames - */ - function listCategory($base, $category, $info = false, $channel = false) - { - if ($info == false) { - $url = '%s'.'c/%s/packages.xml'; - } else { - $url = '%s'.'c/%s/packagesinfo.xml'; - } - $url = sprintf($url, - $base, - urlencode($category)); - - // gives '404 Not Found' error when category doesn't exist - $packagelist = $this->_rest->retrieveData($url, false, false, $channel); - if (PEAR::isError($packagelist)) { - return $packagelist; - } - if (!is_array($packagelist)) { - return array(); - } - - if ($info == false) { - if (!isset($packagelist['p'])) { - return array(); - } - if (!is_array($packagelist['p']) || - !isset($packagelist['p'][0])) { // only 1 pkg - $packagelist = array($packagelist['p']); - } else { - $packagelist = $packagelist['p']; - } - return $packagelist; - } else { - // info == true - if (!isset($packagelist['pi'])) { - return array(); - } - if (!is_array($packagelist['pi']) || - !isset($packagelist['pi'][0])) { // only 1 pkg - $packagelist_pre = array($packagelist['pi']); - } else { - $packagelist_pre = $packagelist['pi']; - } - - $packagelist = array(); - foreach ($packagelist_pre as $i => $item) { - // compatibility with r/.xml - if (isset($item['a']['r'][0])) { - // multiple releases - $item['p']['v'] = $item['a']['r'][0]['v']; - $item['p']['st'] = $item['a']['r'][0]['s']; - } elseif (isset($item['a'])) { - // first and only release - $item['p']['v'] = $item['a']['r']['v']; - $item['p']['st'] = $item['a']['r']['s']; - } - - $packagelist[$i] = array('attribs' => $item['p']['r'], - '_content' => $item['p']['n'], - 'info' => $item['p']); - } - } - - return $packagelist; - } - - /** - * Return an array containing all of the states that are more stable than - * or equal to the passed in state - * - * @param string Release state - * @param boolean Determines whether to include $state in the list - * @return false|array False if $state is not a valid release state - */ - function betterStates($state, $include = false) - { - static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); - $i = array_search($state, $states); - if ($i === false) { - return false; - } - if ($include) { - $i--; - } - return array_slice($states, $i + 1); - } -} -?>PEAR-1.8.0/PEAR/REST/13.php100664 764 764 27117 100664 7575 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: 13.php,v 1.8 2009/02/24 23:39:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a12 - */ - -/** - * For downloading REST xml/txt files - */ -require_once 'PEAR/REST.php'; -require_once 'PEAR/REST/10.php'; - -/** - * Implement REST 1.3 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a12 - */ -class PEAR_REST_13 extends PEAR_REST_10 -{ - /** - * Retrieve information about a remote package to be downloaded from a REST server - * - * This is smart enough to resolve the minimum PHP version dependency prior to download - * @param string $base The uri to prepend to all REST calls - * @param array $packageinfo an array of format: - *
    -     *  array(
    -     *   'package' => 'packagename',
    -     *   'channel' => 'channelname',
    -     *  ['state' => 'alpha' (or valid state),]
    -     *  -or-
    -     *  ['version' => '1.whatever']
    -     * 
    - * @param string $prefstate Current preferred_state config variable value - * @param bool $installed the installed version of this package to compare against - * @return array|false|PEAR_Error see {@link _returnDownloadURL()} - */ - function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false) - { - $channel = $packageinfo['channel']; - $package = $packageinfo['package']; - $states = $this->betterStates($prefstate, true); - if (!$states) { - return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); - } - - $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; - $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; - $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . - '/allreleases2.xml'); - if (PEAR::isError($info)) { - return PEAR::raiseError('No releases available for package "' . - $channel . '/' . $package . '"'); - } - - if (!isset($info['r'])) { - return false; - } - - $release = $found = false; - if (!is_array($info['r']) || !isset($info['r'][0])) { - $info['r'] = array($info['r']); - } - - $skippedphp = false; - foreach ($info['r'] as $release) { - if (!isset($this->_rest->_options['force']) && ($installed && - version_compare($release['v'], $installed, '<'))) { - continue; - } - - if (isset($state)) { - // try our preferred state first - if ($release['s'] == $state) { - if (!isset($version) && version_compare($release['m'], phpversion(), '>')) { - // skip releases that require a PHP version newer than our PHP version - $skippedphp = $release; - continue; - } - $found = true; - break; - } - - // see if there is something newer and more stable - // bug #7221 - if (in_array($release['s'], $this->betterStates($state), true)) { - if (!isset($version) && version_compare($release['m'], phpversion(), '>')) { - // skip releases that require a PHP version newer than our PHP version - $skippedphp = $release; - continue; - } - $found = true; - break; - } - } elseif (isset($version)) { - if ($release['v'] == $version) { - if (!isset($this->_rest->_options['force']) && - !isset($version) && - version_compare($release['m'], phpversion(), '>')) { - // skip releases that require a PHP version newer than our PHP version - $skippedphp = $release; - continue; - } - $found = true; - break; - } - } else { - if (in_array($release['s'], $states)) { - if (version_compare($release['m'], phpversion(), '>')) { - // skip releases that require a PHP version newer than our PHP version - $skippedphp = $release; - continue; - } - $found = true; - break; - } - } - } - - if (!$found && $skippedphp) { - $found = null; - } - - return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel); - } - - function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage, - $prefstate = 'stable', $installed = false, $channel = false) - { - $channel = $dependency['channel']; - $package = $dependency['name']; - $states = $this->betterStates($prefstate, true); - if (!$states) { - return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); - } - - $state = isset($dependency['state']) ? $dependency['state'] : null; - $version = isset($dependency['version']) ? $dependency['version'] : null; - $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . - '/allreleases2.xml'); - if (PEAR::isError($info)) { - return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package'] - . '" dependency "' . $channel . '/' . $package . '" has no releases'); - } - - if (!is_array($info) || !isset($info['r'])) { - return false; - } - - $exclude = array(); - $min = $max = $recommended = false; - if ($xsdversion == '1.0') { - $pinfo['package'] = $dependency['name']; - $pinfo['channel'] = 'pear.php.net'; // this is always true - don't change this - switch ($dependency['rel']) { - case 'ge' : - $min = $dependency['version']; - break; - case 'gt' : - $min = $dependency['version']; - $exclude = array($dependency['version']); - break; - case 'eq' : - $recommended = $dependency['version']; - break; - case 'lt' : - $max = $dependency['version']; - $exclude = array($dependency['version']); - break; - case 'le' : - $max = $dependency['version']; - break; - case 'ne' : - $exclude = array($dependency['version']); - break; - } - } else { - $pinfo['package'] = $dependency['name']; - $min = isset($dependency['min']) ? $dependency['min'] : false; - $max = isset($dependency['max']) ? $dependency['max'] : false; - $recommended = isset($dependency['recommended']) ? - $dependency['recommended'] : false; - if (isset($dependency['exclude'])) { - if (!isset($dependency['exclude'][0])) { - $exclude = array($dependency['exclude']); - } - } - } - - $found = false; - $release = false; - $skippedphp = false; - if (!is_array($info['r']) || !isset($info['r'][0])) { - $info['r'] = array($info['r']); - } - - foreach ($info['r'] as $release) { - if (!isset($this->_rest->_options['force']) && ($installed && - version_compare($release['v'], $installed, '<'))) { - continue; - } - - if (in_array($release['v'], $exclude)) { // skip excluded versions - continue; - } - - // allow newer releases to say "I'm OK with the dependent package" - if ($xsdversion == '2.0' && isset($release['co'])) { - if (!is_array($release['co']) || !isset($release['co'][0])) { - $release['co'] = array($release['co']); - } - - foreach ($release['co'] as $entry) { - if (isset($entry['x']) && !is_array($entry['x'])) { - $entry['x'] = array($entry['x']); - } elseif (!isset($entry['x'])) { - $entry['x'] = array(); - } - - if ($entry['c'] == $deppackage['channel'] && - strtolower($entry['p']) == strtolower($deppackage['package']) && - version_compare($deppackage['version'], $entry['min'], '>=') && - version_compare($deppackage['version'], $entry['max'], '<=') && - !in_array($release['v'], $entry['x'])) { - if (version_compare($release['m'], phpversion(), '>')) { - // skip dependency releases that require a PHP version - // newer than our PHP version - $skippedphp = $release; - continue; - } - - $recommended = $release['v']; - break; - } - } - } - - if ($recommended) { - if ($release['v'] != $recommended) { // if we want a specific - // version, then skip all others - continue; - } - - if (!in_array($release['s'], $states)) { - // the stability is too low, but we must return the - // recommended version if possible - return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel); - } - } - - if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions - continue; - } - - if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions - continue; - } - - if ($installed && version_compare($release['v'], $installed, '<')) { - continue; - } - - if (in_array($release['s'], $states)) { // if in the preferred state... - if (version_compare($release['m'], phpversion(), '>')) { - // skip dependency releases that require a PHP version - // newer than our PHP version - $skippedphp = $release; - continue; - } - - $found = true; // ... then use it - break; - } - } - - if (!$found && $skippedphp) { - $found = null; - } - - return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel); - } -}PEAR-1.8.0/PEAR/Task/Postinstallscript/rw.php100664 764 764 13314 100664 13662 - read/write version - * - * PHP versions 4 and 5 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: rw.php,v 1.14 2009/02/24 23:45:32 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a10 - */ -/** - * Base class - */ -require_once 'PEAR/Task/Postinstallscript.php'; -/** - * Abstracts the postinstallscript file task xml. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a10 - */ -class PEAR_Task_Postinstallscript_rw extends PEAR_Task_Postinstallscript -{ - /** - * parent package file object - * - * @var PEAR_PackageFile_v2_rw - */ - var $_pkg; - /** - * Enter description here... - * - * @param PEAR_PackageFile_v2_rw $pkg - * @param PEAR_Config $config - * @param PEAR_Frontend $logger - * @param array $fileXml - * @return PEAR_Task_Postinstallscript_rw - */ - function PEAR_Task_Postinstallscript_rw(&$pkg, &$config, &$logger, $fileXml) + + function setTime($time) { - parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); - $this->_contents = $fileXml; - $this->_pkg = &$pkg; - $this->_params = array(); + $this->_isValid = 0; + if (!isset($this->_packageInfo['time'])) { + // ensure that the time tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('version', + 'stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', + 'zendextbinrelease', 'bundle', 'changelog'), $time, 'time'); + } + $this->_packageInfo['time'] = $time; } - function validate() + function getDate() { - return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents); + if (isset($this->_packageInfo['date'])) { + return $this->_packageInfo['date']; + } + return false; } - function getName() + function getTime() { - return 'postinstallscript'; + if (isset($this->_packageInfo['time'])) { + return $this->_packageInfo['time']; + } + return false; } /** - * add a simple to the post-install script - * - * Order is significant, so call this method in the same - * sequence the users should see the paramgroups. The $params - * parameter should either be the result of a call to {@link getParam()} - * or an array of calls to getParam(). - * - * Use {@link addConditionTypeGroup()} to add a containing - * a tag - * @param string $id id as seen by the script - * @param array|false $params array of getParam() calls, or false for no params - * @param string|false $instructions + * @param package|api version category to return */ - function addParamGroup($id, $params = false, $instructions = false) + function getVersion($key = 'release') { - if ($params && isset($params[0]) && !isset($params[1])) { - $params = $params[0]; - } - $stuff = - array( - $this->_pkg->getTasksNs() . ':id' => $id, - ); - if ($instructions) { - $stuff[$this->_pkg->getTasksNs() . ':instructions'] = $instructions; - } - if ($params) { - $stuff[$this->_pkg->getTasksNs() . ':param'] = $params; + if (isset($this->_packageInfo['version'][$key])) { + return $this->_packageInfo['version'][$key]; } - $this->_params[$this->_pkg->getTasksNs() . ':paramgroup'][] = $stuff; + return false; } - /** - * add a complex to the post-install script with conditions - * - * This inserts a with - * - * Order is significant, so call this method in the same - * sequence the users should see the paramgroups. The $params - * parameter should either be the result of a call to {@link getParam()} - * or an array of calls to getParam(). - * - * Use {@link addParamGroup()} to add a simple - * - * @param string $id id as seen by the script - * @param string $oldgroup id of the section referenced by - * - * @param string $param name of the from the older section referenced - * by - * @param string $value value to match of the parameter - * @param string $conditiontype one of '=', '!=', 'preg_match' - * @param array|false $params array of getParam() calls, or false for no params - * @param string|false $instructions - */ - function addConditionTypeGroup($id, $oldgroup, $param, $value, $conditiontype = '=', - $params = false, $instructions = false) + function getStability() { - if ($params && isset($params[0]) && !isset($params[1])) { - $params = $params[0]; - } - $stuff = array( - $this->_pkg->getTasksNs() . ':id' => $id, - ); - if ($instructions) { - $stuff[$this->_pkg->getTasksNs() . ':instructions'] = $instructions; - } - $stuff[$this->_pkg->getTasksNs() . ':name'] = $oldgroup . '::' . $param; - $stuff[$this->_pkg->getTasksNs() . ':conditiontype'] = $conditiontype; - $stuff[$this->_pkg->getTasksNs() . ':value'] = $value; - if ($params) { - $stuff[$this->_pkg->getTasksNs() . ':param'] = $params; + if (isset($this->_packageInfo['stability'])) { + return $this->_packageInfo['stability']; } - $this->_params[$this->_pkg->getTasksNs() . ':paramgroup'][] = $stuff; + return false; } - function getXml() + function getState($key = 'release') { - return $this->_params; + if (isset($this->_packageInfo['stability'][$key])) { + return $this->_packageInfo['stability'][$key]; + } + return false; } - /** - * Use to set up a param tag for use in creating a paramgroup - * @static - */ - function getParam($name, $prompt, $type = 'string', $default = null) + function getLicense($raw = false) { - if ($default !== null) { - return - array( - $this->_pkg->getTasksNs() . ':name' => $name, - $this->_pkg->getTasksNs() . ':prompt' => $prompt, - $this->_pkg->getTasksNs() . ':type' => $type, - $this->_pkg->getTasksNs() . ':default' => $default - ); + if (isset($this->_packageInfo['license'])) { + if ($raw) { + return $this->_packageInfo['license']; + } + if (is_array($this->_packageInfo['license'])) { + return $this->_packageInfo['license']['_content']; + } else { + return $this->_packageInfo['license']; + } } - return - array( - $this->_pkg->getTasksNs() . ':name' => $name, - $this->_pkg->getTasksNs() . ':prompt' => $prompt, - $this->_pkg->getTasksNs() . ':type' => $type, - ); + return false; } -} -?>PEAR-1.8.0/PEAR/Task/Replace/rw.php100664 764 764 3213 100664 11451 - read/write version - * - * PHP versions 4 and 5 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: rw.php,v 1.5 2009/02/24 23:45:44 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a10 - */ -/** - * Base class - */ -require_once 'PEAR/Task/Replace.php'; -/** - * Abstracts the replace task xml. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a10 - */ -class PEAR_Task_Replace_rw extends PEAR_Task_Replace -{ - function PEAR_Task_Replace_rw(&$pkg, &$config, &$logger, $fileXml) - { - parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); - $this->_contents = $fileXml; - $this->_pkg = &$pkg; - $this->_params = array(); - } - - function validate() - { - return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents); - } - - function setInfo($from, $to, $type) - { - $this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type)); - } - - function getName() - { - return 'replace'; - } - - function getXml() - { - return $this->_params; - } -} -?>PEAR-1.8.0/PEAR/Task/Unixeol/rw.php100664 764 764 2626 100664 11530 - read/write version - * - * PHP versions 4 and 5 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: rw.php,v 1.6 2009/02/24 23:45:30 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a10 - */ -/** - * Base class - */ -require_once 'PEAR/Task/Unixeol.php'; -/** - * Abstracts the unixeol task xml. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a10 - */ -class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol -{ - function PEAR_Task_Unixeol_rw(&$pkg, &$config, &$logger, $fileXml) - { - parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); - $this->_contents = $fileXml; - $this->_pkg = &$pkg; - $this->_params = array(); - } - - function validate() - { - return true; - } - - function getName() - { - return 'unixeol'; - } - - function getXml() - { - return ''; - } -} -?>PEAR-1.8.0/PEAR/Task/Windowseol/rw.php100664 764 764 2653 100664 12237 - read/write version - * - * PHP versions 4 and 5 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: rw.php,v 1.6 2009/02/24 23:45:20 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a10 - */ -/** - * Base class - */ -require_once 'PEAR/Task/Windowseol.php'; -/** - * Abstracts the windowseol task xml. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a10 - */ -class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol -{ - function PEAR_Task_Windowseol_rw(&$pkg, &$config, &$logger, $fileXml) - { - parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); - $this->_contents = $fileXml; - $this->_pkg = &$pkg; - $this->_params = array(); - } - - function validate() - { - return true; - } - - function getName() - { - return 'windowseol'; - } - - function getXml() - { - return ''; - } -} -?>PEAR-1.8.0/PEAR/Task/Common.php100664 764 764 13741 100664 10725 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.20 2009/02/25 00:15:49 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/**#@+ - * Error codes for task validation routines - */ -define('PEAR_TASK_ERROR_NOATTRIBS', 1); -define('PEAR_TASK_ERROR_MISSING_ATTRIB', 2); -define('PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE', 3); -define('PEAR_TASK_ERROR_INVALID', 4); -/**#@-*/ -define('PEAR_TASK_PACKAGE', 1); -define('PEAR_TASK_INSTALL', 2); -define('PEAR_TASK_PACKAGEANDINSTALL', 3); -/** - * A task is an operation that manipulates the contents of a file. - * - * Simple tasks operate on 1 file. Multiple tasks are executed after all files have been - * processed and installed, and are designed to operate on all files containing the task. - * The Post-install script task simply takes advantage of the fact that it will be run - * after installation, replace is a simple task. - * - * Combining tasks is possible, but ordering is significant. - * - * - * - * - * - * - * This will first replace any instance of @data-dir@ in the test.php file - * with the path to the current data directory. Then, it will include the - * test.php file and run the script it contains to configure the package post-installation. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - * @abstract - */ -class PEAR_Task_Common -{ - /** - * Valid types for this version are 'simple' and 'multiple' - * - * - simple tasks operate on the contents of a file and write out changes to disk - * - multiple tasks operate on the contents of many files and write out the - * changes directly to disk - * - * Child task classes must override this property. - * @access protected - */ - var $type = 'simple'; - /** - * Determines which install phase this task is executed under - */ - var $phase = PEAR_TASK_INSTALL; - /** - * @access protected - */ - var $config; - /** - * @access protected - */ - var $registry; - /** - * @access protected - */ - var $logger; - /** - * @access protected - */ - var $installphase; - /** - * @param PEAR_Config - * @param PEAR_Common - */ - function PEAR_Task_Common(&$config, &$logger, $phase) + + function getLicenseLocation() { - $this->config = &$config; - $this->registry = &$config->getRegistry(); - $this->logger = &$logger; - $this->installphase = $phase; - if ($this->type == 'multiple') { - $GLOBALS['_PEAR_TASK_POSTINSTANCES'][get_class($this)][] = &$this; + if (!isset($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) { + return false; } + return $this->_packageInfo['license']['attribs']; } - /** - * Validate the basic contents of a task tag. - * @param PEAR_PackageFile_v2 - * @param array - * @param PEAR_Config - * @param array the entire parsed tag - * @return true|array On error, return an array in format: - * array(PEAR_TASK_ERROR_???[, param1][, param2][, ...]) - * - * For PEAR_TASK_ERROR_MISSING_ATTRIB, pass the attribute name in - * For PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, pass the attribute name and an array - * of legal values in - * @static - * @abstract - */ - function validateXml($pkg, $xml, $config, $fileXml) + function getNotes() { + if (isset($this->_packageInfo['notes'])) { + return $this->_packageInfo['notes']; + } + return false; } /** - * Initialize a task instance with the parameters - * @param array raw, parsed xml - * @param array attributes from the tag containing this task - * @param string|null last installed version of this package - * @abstract + * Return the tag contents, if any + * @return array|false */ - function init($xml, $fileAttributes, $lastVersion) + function getUsesrole() { + if (isset($this->_packageInfo['usesrole'])) { + return $this->_packageInfo['usesrole']; + } + return false; } /** - * Begin a task processing session. All multiple tasks will be processed after each file - * has been successfully installed, all simple tasks should perform their task here and - * return any errors using the custom throwError() method to allow forward compatibility - * - * This method MUST NOT write out any changes to disk - * @param PEAR_PackageFile_v2 - * @param string file contents - * @param string the eventual final file location (informational only) - * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail - * (use $this->throwError), otherwise return the new contents - * @abstract + * Return the tag contents, if any + * @return array|false */ - function startSession($pkg, $contents, $dest) + function getUsestask() { + if (isset($this->_packageInfo['usestask'])) { + return $this->_packageInfo['usestask']; + } + return false; } /** - * This method is used to process each of the tasks for a particular multiple class - * type. Simple tasks need not implement this method. - * @param array an array of tasks - * @access protected - * @static - * @abstract + * This should only be used to retrieve filenames and install attributes */ - function run($tasks) + function getFilelist($preserve = false) { + if (isset($this->_packageInfo['filelist']) && !$preserve) { + return $this->_packageInfo['filelist']; + } + $this->flattenFilelist(); + if ($contents = $this->getContents()) { + $ret = array(); + if (!isset($contents['dir'])) { + return false; + } + if (!isset($contents['dir']['file'][0])) { + $contents['dir']['file'] = array($contents['dir']['file']); + } + foreach ($contents['dir']['file'] as $file) { + $name = $file['attribs']['name']; + if (!$preserve) { + $file = $file['attribs']; + } + $ret[$name] = $file; + } + if (!$preserve) { + $this->_packageInfo['filelist'] = $ret; + } + return $ret; + } + return false; } /** - * @static - * @final + * Return configure options array, if any + * + * @return array|false */ - function hasPostinstallTasks() + function getConfigureOptions() { - return isset($GLOBALS['_PEAR_TASK_POSTINSTANCES']); + if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { + return false; + } + + $releases = $this->getReleases(); + if (isset($releases[0])) { + $releases = $releases[0]; + } + + if (isset($releases['configureoption'])) { + if (!isset($releases['configureoption'][0])) { + $releases['configureoption'] = array($releases['configureoption']); + } + + for ($i = 0; $i < count($releases['configureoption']); $i++) { + $releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs']; + } + + return $releases['configureoption']; + } + + return false; } /** - * @static - * @final + * This is only used at install-time, after all serialization + * is over. */ - function runPostinstallTasks() - { - foreach ($GLOBALS['_PEAR_TASK_POSTINSTANCES'] as $class => $tasks) { - $err = call_user_func(array($class, 'run'), - $GLOBALS['_PEAR_TASK_POSTINSTANCES'][$class]); - if ($err) { - return PEAR_Task_Common::throwError($err); - } - } - unset($GLOBALS['_PEAR_TASK_POSTINSTANCES']); + function resetFilelist() + { + $this->_packageInfo['filelist'] = array(); } /** - * Determines whether a role is a script - * @return bool + * Retrieve a list of files that should be installed on this computer + * @return array */ - function isScript() + function getInstallationFilelist($forfilecheck = false) { - return $this->type == 'script'; - } - - function throwError($msg, $code = -1) - { - include_once 'PEAR.php'; - return PEAR::raiseError($msg, $code); - } -} -?>PEAR-1.8.0/PEAR/Task/Postinstallscript.php100664 764 764 34125 100664 13235 - * - * PHP versions 4 and 5 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Postinstallscript.php,v 1.22 2009/02/24 23:45:56 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/** - * Base class - */ -require_once 'PEAR/Task/Common.php'; -/** - * Implements the postinstallscript file task. - * - * Note that post-install scripts are handled separately from installation, by the - * "pear run-scripts" command - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Task_Postinstallscript extends PEAR_Task_Common -{ - var $type = 'script'; - var $_class; - var $_params; - var $_obj; - /** - * - * @var PEAR_PackageFile_v2 - */ - var $_pkg; - var $_contents; - var $phase = PEAR_TASK_INSTALL; - - /** - * Validate the raw xml at parsing-time. - * - * This also attempts to validate the script to make sure it meets the criteria - * for a post-install script - * @param PEAR_PackageFile_v2 - * @param array The XML contents of the tag - * @param PEAR_Config - * @param array the entire parsed tag - * @static - */ - function validateXml($pkg, $xml, $config, $fileXml) - { - if ($fileXml['role'] != 'php') { - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" must be role="php"'); - } - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $file = $pkg->getFileContents($fileXml['name']); - if (PEAR::isError($file)) { - PEAR::popErrorHandling(); - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" is not valid: ' . - $file->getMessage()); - } elseif ($file === null) { - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" could not be retrieved for processing!'); - } else { - $analysis = $pkg->analyzeSourceCode($file, true); - if (!$analysis) { - PEAR::popErrorHandling(); - $warnings = ''; - foreach ($pkg->getValidationWarnings() as $warn) { - $warnings .= $warn['message'] . "\n"; - } - return array(PEAR_TASK_ERROR_INVALID, 'Analysis of post-install script "' . - $fileXml['name'] . '" failed: ' . $warnings); - } - if (count($analysis['declared_classes']) != 1) { - PEAR::popErrorHandling(); - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" must declare exactly 1 class'); - } - $class = $analysis['declared_classes'][0]; - if ($class != str_replace(array('/', '.php'), array('_', ''), - $fileXml['name']) . '_postinstall') { - PEAR::popErrorHandling(); - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" class "' . $class . '" must be named "' . - str_replace(array('/', '.php'), array('_', ''), - $fileXml['name']) . '_postinstall"'); - } - if (!isset($analysis['declared_methods'][$class])) { - PEAR::popErrorHandling(); - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" must declare methods init() and run()'); - } - $methods = array('init' => 0, 'run' => 1); - foreach ($analysis['declared_methods'][$class] as $method) { - if (isset($methods[$method])) { - unset($methods[$method]); - } - } - if (count($methods)) { - PEAR::popErrorHandling(); - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" must declare methods init() and run()'); - } + $contents = $this->getFilelist(true); + if (isset($contents['dir']['attribs']['baseinstalldir'])) { + $base = $contents['dir']['attribs']['baseinstalldir']; } - PEAR::popErrorHandling(); - $definedparams = array(); - $tasksNamespace = $pkg->getTasksNs() . ':'; - if (!isset($xml[$tasksNamespace . 'paramgroup']) && isset($xml['paramgroup'])) { - // in order to support the older betas, which did not expect internal tags - // to also use the namespace - $tasksNamespace = ''; + if (isset($this->_packageInfo['bundle'])) { + return PEAR::raiseError( + 'Exception: bundles should be handled in download code only'); } - if (isset($xml[$tasksNamespace . 'paramgroup'])) { - $params = $xml[$tasksNamespace . 'paramgroup']; - if (!is_array($params) || !isset($params[0])) { - $params = array($params); - } - foreach ($params as $param) { - if (!isset($param[$tasksNamespace . 'id'])) { - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" must have ' . - 'an ' . $tasksNamespace . 'id> tag'); - } - if (isset($param[$tasksNamespace . 'name'])) { - if (!in_array($param[$tasksNamespace . 'name'], $definedparams)) { - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" ' . $tasksNamespace . - 'paramgroup> id "' . $param[$tasksNamespace . 'id'] . - '" parameter "' . $param[$tasksNamespace . 'name'] . - '" has not been previously defined'); - } - if (!isset($param[$tasksNamespace . 'conditiontype'])) { - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" ' . $tasksNamespace . - 'paramgroup> id "' . $param[$tasksNamespace . 'id'] . - '" must have a ' . $tasksNamespace . - 'conditiontype> tag containing either "=", ' . - '"!=", or "preg_match"'); - } - if (!in_array($param[$tasksNamespace . 'conditiontype'], - array('=', '!=', 'preg_match'))) { - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" ' . $tasksNamespace . - 'paramgroup> id "' . $param[$tasksNamespace . 'id'] . - '" must have a ' . $tasksNamespace . - 'conditiontype> tag containing either "=", ' . - '"!=", or "preg_match"'); - } - if (!isset($param[$tasksNamespace . 'value'])) { - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" ' . $tasksNamespace . - 'paramgroup> id "' . $param[$tasksNamespace . 'id'] . - '" must have a ' . $tasksNamespace . - 'value> tag containing expected parameter value'); + $release = $this->getReleases(); + if ($release) { + if (!isset($release[0])) { + if (!isset($release['installconditions']) && !isset($release['filelist'])) { + if ($forfilecheck) { + return $this->getFilelist(); } + return $contents; } - if (isset($param[$tasksNamespace . 'instructions'])) { - if (!is_string($param[$tasksNamespace . 'instructions'])) { - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" ' . $tasksNamespace . - 'paramgroup> id "' . $param[$tasksNamespace . 'id'] . - '" ' . $tasksNamespace . 'instructions> must be simple text'); + $release = array($release); + } + $depchecker = &$this->getPEARDependency2($this->_config, array(), + array('channel' => $this->getChannel(), 'package' => $this->getPackage()), + PEAR_VALIDATE_INSTALLING); + foreach ($release as $instance) { + if (isset($instance['installconditions'])) { + $installconditions = $instance['installconditions']; + if (is_array($installconditions)) { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + foreach ($installconditions as $type => $conditions) { + if (!isset($conditions[0])) { + $conditions = array($conditions); + } + foreach ($conditions as $condition) { + $ret = $depchecker->{"validate{$type}Dependency"}($condition); + if (PEAR::isError($ret)) { + PEAR::popErrorHandling(); + continue 3; // skip this release + } + } + } + PEAR::popErrorHandling(); } } - if (!isset($param[$tasksNamespace . 'param'])) { - continue; // is no longer required - } - $subparams = $param[$tasksNamespace . 'param']; - if (!is_array($subparams) || !isset($subparams[0])) { - $subparams = array($subparams); - } - foreach ($subparams as $subparam) { - if (!isset($subparam[$tasksNamespace . 'name'])) { - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" parameter for ' . - $tasksNamespace . 'paramgroup> id "' . - $param[$tasksNamespace . 'id'] . '" must have ' . - 'a ' . $tasksNamespace . 'name> tag'); - } - if (!preg_match('/[a-zA-Z0-9]+/', - $subparam[$tasksNamespace . 'name'])) { - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" parameter "' . - $subparam[$tasksNamespace . 'name'] . - '" for ' . $tasksNamespace . 'paramgroup> id "' . - $param[$tasksNamespace . 'id'] . - '" is not a valid name. Must contain only alphanumeric characters'); + // this is the release to use + if (isset($instance['filelist'])) { + // ignore files + if (isset($instance['filelist']['ignore'])) { + $ignore = isset($instance['filelist']['ignore'][0]) ? + $instance['filelist']['ignore'] : + array($instance['filelist']['ignore']); + foreach ($ignore as $ig) { + unset ($contents[$ig['attribs']['name']]); + } } - if (!isset($subparam[$tasksNamespace . 'prompt'])) { - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" parameter "' . - $subparam[$tasksNamespace . 'name'] . - '" for ' . $tasksNamespace . 'paramgroup> id "' . - $param[$tasksNamespace . 'id'] . - '" must have a ' . $tasksNamespace . 'prompt> tag'); + // install files as this name + if (isset($instance['filelist']['install'])) { + $installas = isset($instance['filelist']['install'][0]) ? + $instance['filelist']['install'] : + array($instance['filelist']['install']); + foreach ($installas as $as) { + $contents[$as['attribs']['name']]['attribs']['install-as'] = + $as['attribs']['as']; + } } - if (!isset($subparam[$tasksNamespace . 'type'])) { - return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . - $fileXml['name'] . '" parameter "' . - $subparam[$tasksNamespace . 'name'] . - '" for ' . $tasksNamespace . 'paramgroup> id "' . - $param[$tasksNamespace . 'id'] . - '" must have a ' . $tasksNamespace . 'type> tag'); + } + if ($forfilecheck) { + foreach ($contents as $file => $attrs) { + $contents[$file] = $attrs['attribs']; } - $definedparams[] = $param[$tasksNamespace . 'id'] . '::' . - $subparam[$tasksNamespace . 'name']; } + return $contents; + } + } else { // simple release - no installconditions or install-as + if ($forfilecheck) { + return $this->getFilelist(); } + return $contents; } - return true; + // no releases matched + return PEAR::raiseError('No releases in package.xml matched the existing operating ' . + 'system, extensions installed, or architecture, cannot install'); } /** - * Initialize a task instance with the parameters - * @param array raw, parsed xml - * @param array attributes from the tag containing this task - * @param string|null last installed version of this package, if any (useful for upgrades) + * This is only used at install-time, after all serialization + * is over. + * @param string file name + * @param string installed path */ - function init($xml, $fileattribs, $lastversion) + function setInstalledAs($file, $path) { - $this->_class = str_replace('/', '_', $fileattribs['name']); - $this->_filename = $fileattribs['name']; - $this->_class = str_replace ('.php', '', $this->_class) . '_postinstall'; - $this->_params = $xml; - $this->_lastversion = $lastversion; + if ($path) { + return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; + } + unset($this->_packageInfo['filelist'][$file]['installed_as']); } - /** - * Strip the tasks: namespace from internal params - * - * @access private - */ - function _stripNamespace($params = null) + function getInstalledLocation($file) { - if ($params === null) { - $params = array(); - if (!is_array($this->_params)) { - return; - } - foreach ($this->_params as $i => $param) { - if (is_array($param)) { - $param = $this->_stripNamespace($param); - } - $params[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param; - } - $this->_params = $params; - } else { - $newparams = array(); - foreach ($params as $i => $param) { - if (is_array($param)) { - $param = $this->_stripNamespace($param); - } - $newparams[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param; - } - return $newparams; + if (isset($this->_packageInfo['filelist'][$file]['installed_as'])) { + return $this->_packageInfo['filelist'][$file]['installed_as']; } + return false; } /** - * Unlike other tasks, the installed file name is passed in instead of the file contents, - * because this task is handled post-installation - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @param string file name - * @return bool|PEAR_Error false to skip this file, PEAR_Error to fail - * (use $this->throwError) + * This is only used at install-time, after all serialization + * is over. */ - function startSession($pkg, $contents) + function installedFile($file, $atts) { - if ($this->installphase != PEAR_TASK_INSTALL) { - return false; - } - // remove the tasks: namespace if present - $this->_pkg = $pkg; - $this->_stripNamespace(); - $this->logger->log(0, 'Including external post-installation script "' . - $contents . '" - any errors are in this script'); - include_once $contents; - if (class_exists($this->_class)) { - $this->logger->log(0, 'Inclusion succeeded'); - } else { - return $this->throwError('init of post-install script class "' . $this->_class - . '" failed'); - } - $this->_obj = new $this->_class; - $this->logger->log(1, 'running post-install script "' . $this->_class . '->init()"'); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $res = $this->_obj->init($this->config, $pkg, $this->_lastversion); - PEAR::popErrorHandling(); - if ($res) { - $this->logger->log(0, 'init succeeded'); + if (isset($this->_packageInfo['filelist'][$file])) { + $this->_packageInfo['filelist'][$file] = + array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']); } else { - return $this->throwError('init of post-install script "' . $this->_class . - '->init()" failed'); + $this->_packageInfo['filelist'][$file] = $atts['attribs']; } - $this->_contents = $contents; - return true; } /** - * No longer used - * @see PEAR_PackageFile_v2::runPostinstallScripts() - * @param array an array of tasks - * @param string install or upgrade - * @access protected - * @static + * Retrieve the contents tag */ - function run() + function getContents() { + if (isset($this->_packageInfo['contents'])) { + return $this->_packageInfo['contents']; + } + return false; } -} -?>PEAR-1.8.0/PEAR/Task/Replace.php100664 764 764 15235 100664 11050 - * - * PHP versions 4 and 5 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Replace.php,v 1.19 2009/02/25 00:15:49 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/** - * Base class - */ -require_once 'PEAR/Task/Common.php'; -/** - * Implements the replace file task. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Task_Replace extends PEAR_Task_Common -{ - var $type = 'simple'; - var $phase = PEAR_TASK_PACKAGEANDINSTALL; - var $_replacements; /** - * Validate the raw xml at parsing-time. - * @param PEAR_PackageFile_v2 - * @param array raw, parsed xml - * @param PEAR_Config - * @static + * @param string full path to file + * @param string attribute name + * @param string attribute value + * @param int risky but fast - use this to choose a file based on its position in the list + * of files. Index is zero-based like PHP arrays. + * @return bool success of operation */ - function validateXml($pkg, $xml, $config, $fileXml) + function setFileAttribute($filename, $attr, $value, $index = false) { - if (!isset($xml['attribs'])) { - return array(PEAR_TASK_ERROR_NOATTRIBS); + $this->_isValid = 0; + if (in_array($attr, array('role', 'name', 'baseinstalldir'))) { + $this->_filesValid = false; } - if (!isset($xml['attribs']['type'])) { - return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'type'); + if ($index !== false && + isset($this->_packageInfo['contents']['dir']['file'][$index]['attribs'])) { + $this->_packageInfo['contents']['dir']['file'][$index]['attribs'][$attr] = $value; + return true; } - if (!isset($xml['attribs']['to'])) { - return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'to'); + if (!isset($this->_packageInfo['contents']['dir']['file'])) { + return false; } - if (!isset($xml['attribs']['from'])) { - return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'from'); + $files = $this->_packageInfo['contents']['dir']['file']; + if (!isset($files[0])) { + $files = array($files); + $ind = false; + } else { + $ind = true; } - if ($xml['attribs']['type'] == 'pear-config') { - if (!in_array($xml['attribs']['to'], $config->getKeys())) { - return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'], - $config->getKeys()); - } - } elseif ($xml['attribs']['type'] == 'php-const') { - if (defined($xml['attribs']['to'])) { - return true; - } else { - return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'], - array('valid PHP constant')); - } - } elseif ($xml['attribs']['type'] == 'package-info') { - if (in_array($xml['attribs']['to'], - array('name', 'summary', 'channel', 'notes', 'extends', 'description', - 'release_notes', 'license', 'release-license', 'license-uri', - 'version', 'api-version', 'state', 'api-state', 'release_date', - 'date', 'time'))) { - return true; - } else { - return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'], - array('name', 'summary', 'channel', 'notes', 'extends', 'description', - 'release_notes', 'license', 'release-license', 'license-uri', - 'version', 'api-version', 'state', 'api-state', 'release_date', - 'date', 'time')); + foreach ($files as $i => $file) { + if (isset($file['attribs'])) { + if ($file['attribs']['name'] == $filename) { + if ($ind) { + $this->_packageInfo['contents']['dir']['file'][$i]['attribs'][$attr] = $value; + } else { + $this->_packageInfo['contents']['dir']['file']['attribs'][$attr] = $value; + } + return true; + } } - } else { - return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'type', $xml['attribs']['type'], - array('pear-config', 'package-info', 'php-const')); } - return true; + return false; } - /** - * Initialize a task instance with the parameters - * @param array raw, parsed xml - * @param unused - */ - function init($xml, $attribs) + function setDirtree($path) { - $this->_replacements = isset($xml['attribs']) ? array($xml) : $xml; + if (!isset($this->_packageInfo['dirtree'])) { + $this->_packageInfo['dirtree'] = array(); + } + $this->_packageInfo['dirtree'][$path] = true; } - /** - * Do a package.xml 1.0 replacement, with additional package-info fields available - * - * See validateXml() source for the complete list of allowed fields - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @param string file contents - * @param string the eventual final file location (informational only) - * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail - * (use $this->throwError), otherwise return the new contents - */ - function startSession($pkg, $contents, $dest) + function getDirtree() { - $subst_from = $subst_to = array(); - foreach ($this->_replacements as $a) { - $a = $a['attribs']; - $to = ''; - if ($a['type'] == 'pear-config') { - if ($this->installphase == PEAR_TASK_PACKAGE) { - return false; - } - if ($a['to'] == 'master_server') { - $chan = $this->registry->getChannel($pkg->getChannel()); - if (!PEAR::isError($chan)) { - $to = $chan->getServer(); - } else { - $this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]"); - return false; - } - } else { - if ($this->config->isDefinedLayer('ftp')) { - // try the remote config file first - $to = $this->config->get($a['to'], 'ftp', $pkg->getChannel()); - if (is_null($to)) { - // then default to local - $to = $this->config->get($a['to'], null, $pkg->getChannel()); - } - } else { - $to = $this->config->get($a['to'], null, $pkg->getChannel()); - } - } - if (is_null($to)) { - $this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]"); - return false; - } - } elseif ($a['type'] == 'php-const') { - if ($this->installphase == PEAR_TASK_PACKAGE) { - return false; - } - if (defined($a['to'])) { - $to = constant($a['to']); - } else { - $this->logger->log(0, "$dest: invalid php-const replacement: $a[to]"); - return false; - } - } else { - if ($t = $pkg->packageInfo($a['to'])) { - $to = $t; - } else { - $this->logger->log(0, "$dest: invalid package-info replacement: $a[to]"); - return false; - } - } - if (!is_null($to)) { - $subst_from[] = $a['from']; - $subst_to[] = $to; - } - } - $this->logger->log(3, "doing " . sizeof($subst_from) . - " substitution(s) for $dest"); - if (sizeof($subst_from)) { - $contents = str_replace($subst_from, $subst_to, $contents); + if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { + return $this->_packageInfo['dirtree']; } - return $contents; + return false; } -} -?>PEAR-1.8.0/PEAR/Task/Unixeol.php100664 764 764 4344 100664 11077 - * - * PHP versions 4 and 5 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Unixeol.php,v 1.12 2009/02/25 00:15:49 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/** - * Base class - */ -require_once 'PEAR/Task/Common.php'; -/** - * Implements the unix line endings file task. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Task_Unixeol extends PEAR_Task_Common -{ - var $type = 'simple'; - var $phase = PEAR_TASK_PACKAGE; - var $_replacements; - /** - * Validate the raw xml at parsing-time. - * @param PEAR_PackageFile_v2 - * @param array raw, parsed xml - * @param PEAR_Config - * @static - */ - function validateXml($pkg, $xml, $config, $fileXml) + function resetDirtree() { - if ($xml != '') { - return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed'); - } - return true; + unset($this->_packageInfo['dirtree']); } /** - * Initialize a task instance with the parameters - * @param array raw, parsed xml - * @param unused + * Determines whether this package claims it is compatible with the version of + * the package that has a recommended version dependency + * @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package + * @return boolean */ - function init($xml, $attribs) + function isCompatible($pf) { + if (!isset($this->_packageInfo['compatible'])) { + return false; + } + if (!isset($this->_packageInfo['channel'])) { + return false; + } + $me = $pf->getVersion(); + $compatible = $this->_packageInfo['compatible']; + if (!isset($compatible[0])) { + $compatible = array($compatible); + } + $found = false; + foreach ($compatible as $info) { + if (strtolower($info['name']) == strtolower($pf->getPackage())) { + if (strtolower($info['channel']) == strtolower($pf->getChannel())) { + $found = true; + break; + } + } + } + if (!$found) { + return false; + } + if (isset($info['exclude'])) { + if (!isset($info['exclude'][0])) { + $info['exclude'] = array($info['exclude']); + } + foreach ($info['exclude'] as $exclude) { + if (version_compare($me, $exclude, '==')) { + return false; + } + } + } + if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) { + return true; + } + return false; } /** - * Replace all line endings with line endings customized for the current OS - * - * See validateXml() source for the complete list of allowed fields - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @param string file contents - * @param string the eventual final file location (informational only) - * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail - * (use $this->throwError), otherwise return the new contents + * @return array|false */ - function startSession($pkg, $contents, $dest) + function getCompatible() { - $this->logger->log(3, "replacing all line endings with \\n in $dest"); - return preg_replace("/\r\n|\n\r|\r|\n/", "\n", $contents); + if (isset($this->_packageInfo['compatible'])) { + return $this->_packageInfo['compatible']; + } + return false; } -} -?>PEAR-1.8.0/PEAR/Task/Windowseol.php100664 764 764 4340 100664 11602 - * - * PHP versions 4 and 5 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Windowseol.php,v 1.11 2009/02/25 00:15:49 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/** - * Base class - */ -require_once 'PEAR/Task/Common.php'; -/** - * Implements the windows line endsings file task. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Task_Windowseol extends PEAR_Task_Common -{ - var $type = 'simple'; - var $phase = PEAR_TASK_PACKAGE; - var $_replacements; - /** - * Validate the raw xml at parsing-time. - * @param PEAR_PackageFile_v2 - * @param array raw, parsed xml - * @param PEAR_Config - * @static - */ - function validateXml($pkg, $xml, $config, $fileXml) + function getDependencies() { - if ($xml != '') { - return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed'); + if (isset($this->_packageInfo['dependencies'])) { + return $this->_packageInfo['dependencies']; } - return true; + return false; } - /** - * Initialize a task instance with the parameters - * @param array raw, parsed xml - * @param unused - */ - function init($xml, $attribs) + function isSubpackageOf($p) { + return $p->isSubpackage($this); } /** - * Replace all line endings with windows line endings + * Determines whether the passed in package is a subpackage of this package. * - * See validateXml() source for the complete list of allowed fields + * No version checking is done, only name verification. * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @param string file contents - * @param string the eventual final file location (informational only) - * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail - * (use $this->throwError), otherwise return the new contents + * @return bool */ - function startSession($pkg, $contents, $dest) - { - $this->logger->log(3, "replacing all line endings with \\r\\n in $dest"); - return preg_replace("/\r\n|\n\r|\r|\n/", "\r\n", $contents); - } -} -?>PEAR-1.8.0/PEAR/Validator/PECL.php100664 764 764 4200 100664 11211 - * @copyright 1997-2006 The PHP Group - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PECL.php,v 1.10 2009/02/24 23:39:19 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a5 - */ -/** - * This is the parent class for all validators - */ -require_once 'PEAR/Validate.php'; -/** - * Channel Validator for the pecl.php.net channel - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a5 - */ -class PEAR_Validator_PECL extends PEAR_Validate -{ - function validateVersion() + function isSubpackage($p) { - if ($this->_state == PEAR_VALIDATE_PACKAGING) { - $version = $this->_packagexml->getVersion(); - $versioncomponents = explode('.', $version); - $last = array_pop($versioncomponents); - if (substr($last, 1, 2) == 'rc') { - $this->_addFailure('version', 'Release Candidate versions must have ' . - 'upper-case RC, not lower-case rc'); - return false; + $sub = array(); + if (isset($this->_packageInfo['dependencies']['required']['subpackage'])) { + $sub = $this->_packageInfo['dependencies']['required']['subpackage']; + if (!isset($sub[0])) { + $sub = array($sub); } } - return true; + if (isset($this->_packageInfo['dependencies']['optional']['subpackage'])) { + $sub1 = $this->_packageInfo['dependencies']['optional']['subpackage']; + if (!isset($sub1[0])) { + $sub1 = array($sub1); + } + $sub = array_merge($sub, $sub1); + } + if (isset($this->_packageInfo['dependencies']['group'])) { + $group = $this->_packageInfo['dependencies']['group']; + if (!isset($group[0])) { + $group = array($group); + } + foreach ($group as $deps) { + if (isset($deps['subpackage'])) { + $sub2 = $deps['subpackage']; + if (!isset($sub2[0])) { + $sub2 = array($sub2); + } + $sub = array_merge($sub, $sub2); + } + } + } + foreach ($sub as $dep) { + if (strtolower($dep['name']) == strtolower($p->getPackage())) { + if (isset($dep['channel'])) { + if (strtolower($dep['channel']) == strtolower($p->getChannel())) { + return true; + } + } else { + if ($dep['uri'] == $p->getURI()) { + return true; + } + } + } + } + return false; } - function validatePackageName() + function dependsOn($package, $channel) { - $ret = parent::validatePackageName(); - if ($this->_packagexml->getPackageType() == 'extsrc' || - $this->_packagexml->getPackageType() == 'zendextsrc') { - if (strtolower($this->_packagexml->getPackage()) != - strtolower($this->_packagexml->getProvidesExtension())) { - $this->_addWarning('providesextension', 'package name "' . - $this->_packagexml->getPackage() . '" is different from extension name "' . - $this->_packagexml->getProvidesExtension() . '"'); + if (!($deps = $this->getDependencies())) { + return false; + } + foreach (array('package', 'subpackage') as $type) { + foreach (array('required', 'optional') as $needed) { + if (isset($deps[$needed][$type])) { + if (!isset($deps[$needed][$type][0])) { + $deps[$needed][$type] = array($deps[$needed][$type]); + } + foreach ($deps[$needed][$type] as $dep) { + $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; + if (strtolower($dep['name']) == strtolower($package) && + $depchannel == $channel) { + return true; + } + } + } + } + if (isset($deps['group'])) { + if (!isset($deps['group'][0])) { + $dep['group'] = array($deps['group']); + } + foreach ($deps['group'] as $group) { + if (isset($group[$type])) { + if (!is_array($group[$type])) { + $group[$type] = array($group[$type]); + } + foreach ($group[$type] as $dep) { + $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; + if (strtolower($dep['name']) == strtolower($package) && + $depchannel == $channel) { + return true; + } + } + } + } } } - return $ret; + return false; } -} -?>PEAR-1.8.0/PEAR/Autoloader.php100664 764 764 15202 100664 10664 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Autoloader.php,v 1.15 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader - * @since File available since Release 0.1 - * @deprecated File deprecated in Release 1.4.0a1 - */ - -// /* vim: set expandtab tabstop=4 shiftwidth=4: */ - -if (!extension_loaded("overload")) { - // die hard without ext/overload - die("Rebuild PHP with the `overload' extension to use PEAR_Autoloader"); -} - -/** - * Include for PEAR_Error and PEAR classes - */ -require_once "PEAR.php"; - -/** - * This class is for objects where you want to separate the code for - * some methods into separate classes. This is useful if you have a - * class with not-frequently-used methods that contain lots of code - * that you would like to avoid always parsing. - * - * The PEAR_Autoloader class provides autoloading and aggregation. - * The autoloading lets you set up in which classes the separated - * methods are found. Aggregation is the technique used to import new - * methods, an instance of each class providing separated methods is - * stored and called every time the aggregated method is called. - * - * @category pear - * @package PEAR - * @author Stig Bakken - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader - * @since File available since Release 0.1 - * @deprecated File deprecated in Release 1.4.0a1 - */ -class PEAR_Autoloader extends PEAR -{ - // {{{ properties - - /** - * Map of methods and classes where they are defined - * - * @var array - * - * @access private - */ - var $_autoload_map = array(); - - /** - * Map of methods and aggregate objects - * - * @var array - * - * @access private - */ - var $_method_map = array(); - - // }}} - // {{{ addAutoload() - - /** - * Add one or more autoload entries. - * - * @param string $method which method to autoload - * - * @param string $classname (optional) which class to find the method in. - * If the $method parameter is an array, this - * parameter may be omitted (and will be ignored - * if not), and the $method parameter will be - * treated as an associative array with method - * names as keys and class names as values. - * - * @return void - * - * @access public - */ - function addAutoload($method, $classname = null) - { - if (is_array($method)) { - array_walk($method, create_function('$a,&$b', '$b = strtolower($b);')); - $this->_autoload_map = array_merge($this->_autoload_map, $method); - } else { - $this->_autoload_map[strtolower($method)] = $classname; - } - } - - // }}} - // {{{ removeAutoload() - - /** - * Remove an autoload entry. - * - * @param string $method which method to remove the autoload entry for - * - * @return bool TRUE if an entry was removed, FALSE if not - * - * @access public - */ - function removeAutoload($method) - { - $method = strtolower($method); - $ok = isset($this->_autoload_map[$method]); - unset($this->_autoload_map[$method]); - return $ok; - } - - // }}} - // {{{ addAggregateObject() - - /** - * Add an aggregate object to this object. If the specified class - * is not defined, loading it will be attempted following PEAR's - * file naming scheme. All the methods in the class will be - * aggregated, except private ones (name starting with an - * underscore) and constructors. - * - * @param string $classname what class to instantiate for the object. - * - * @return void - * - * @access public - */ - function addAggregateObject($classname) - { - $classname = strtolower($classname); - if (!class_exists($classname)) { - $include_file = preg_replace('/[^a-z0-9]/i', '_', $classname); - include_once $include_file; - } - $obj =& new $classname; - $methods = get_class_methods($classname); - foreach ($methods as $method) { - // don't import priviate methods and constructors - if ($method{0} != '_' && $method != $classname) { - $this->_method_map[$method] = $obj; - } - } - } - - // }}} - // {{{ removeAggregateObject() - - /** - * Remove an aggregate object. - * - * @param string $classname the class of the object to remove - * - * @return bool TRUE if an object was removed, FALSE if not - * - * @access public - */ - function removeAggregateObject($classname) - { - $ok = false; - $classname = strtolower($classname); - reset($this->_method_map); - while (list($method, $obj) = each($this->_method_map)) { - if (is_a($obj, $classname)) { - unset($this->_method_map[$method]); - $ok = true; - } - } - return $ok; - } - - // }}} - // {{{ __call() - - /** - * Overloaded object call handler, called each time an - * undefined/aggregated method is invoked. This method repeats - * the call in the right aggregate object and passes on the return - * value. - * - * @param string $method which method that was called - * - * @param string $args An array of the parameters passed in the - * original call - * - * @return mixed The return value from the aggregated method, or a PEAR - * error if the called method was unknown. - */ - function __call($method, $args, &$retval) - { - $method = strtolower($method); - if (empty($this->_method_map[$method]) && isset($this->_autoload_map[$method])) { - $this->addAggregateObject($this->_autoload_map[$method]); - } - if (isset($this->_method_map[$method])) { - $retval = call_user_func_array(array($this->_method_map[$method], $method), $args); - return true; - } - return false; - } - - // }}} -} - -overload("PEAR_Autoloader"); - -?> -PEAR-1.8.0/PEAR/Builder.php100664 764 764 40123 100664 10153 - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Builder.php,v 1.38 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - * - * TODO: log output parameters in PECL command line - * TODO: msdev path in configuration - */ - -/** - * Needed for extending PEAR_Builder - */ -require_once 'PEAR/Common.php'; -require_once 'PEAR/PackageFile.php'; - -/** - * Class to handle building (compiling) extensions. - * - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since PHP 4.0.2 - * @see http://pear.php.net/manual/en/core.ppm.pear-builder.php - */ -class PEAR_Builder extends PEAR_Common -{ - var $php_api_version = 0; - var $zend_module_api_no = 0; - var $zend_extension_api_no = 0; - - var $extensions_built = array(); - - /** - * @var string Used for reporting when it is not possible to pass function - * via extra parameter, e.g. log, msdevCallback - */ - var $current_callback = null; - - // used for msdev builds - var $_lastline = null; - var $_firstline = null; /** - * PEAR_Builder constructor. - * - * @param object $ui user interface object (instance of PEAR_Frontend_*) - * - * @access public + * Get the contents of a dependency group + * @param string + * @return array|false */ - function PEAR_Builder(&$ui) + function getDependencyGroup($name) { - parent::PEAR_Common(); - $this->setFrontendObject($ui); + $name = strtolower($name); + if (!isset($this->_packageInfo['dependencies']['group'])) { + return false; + } + $groups = $this->_packageInfo['dependencies']['group']; + if (!isset($groups[0])) { + $groups = array($groups); + } + foreach ($groups as $group) { + if (strtolower($group['attribs']['name']) == $name) { + return $group; + } + } + return false; } /** - * Build an extension from source on windows. - * requires msdev + * Retrieve a partial package.xml 1.0 representation of dependencies + * + * a very limited representation of dependencies is returned by this method. + * The tag for excluding certain versions of a dependency is + * completely ignored. In addition, dependency groups are ignored, with the + * assumption that all dependencies in dependency groups are also listed in + * the optional group that work with all dependency groups + * @param boolean return package.xml 2.0 tag + * @return array|false */ - function _build_win32($descfile, $callback = null) + function getDeps($raw = false, $nopearinstaller = false) { - if (is_object($descfile)) { - $pkg = $descfile; - $descfile = $pkg->getPackageFile(); - } else { - $pf = &new PEAR_PackageFile($this->config, $this->debug); - $pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($pkg)) { - return $pkg; + if (isset($this->_packageInfo['dependencies'])) { + if ($raw) { + return $this->_packageInfo['dependencies']; } - } - $dir = dirname($descfile); - $old_cwd = getcwd(); - - if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) { - return $this->raiseError("could not chdir to $dir"); - } - - // packages that were in a .tar have the packagefile in this directory - $vdir = $pkg->getPackage() . '-' . $pkg->getVersion(); - if (file_exists($dir) && is_dir($vdir)) { - if (!chdir($vdir)) { - return $this->raiseError("could not chdir to " . realpath($vdir)); + $ret = array(); + $map = array( + 'php' => 'php', + 'package' => 'pkg', + 'subpackage' => 'pkg', + 'extension' => 'ext', + 'os' => 'os', + 'pearinstaller' => 'pkg', + ); + foreach (array('required', 'optional') as $type) { + $optional = ($type == 'optional') ? 'yes' : 'no'; + if (!isset($this->_packageInfo['dependencies'][$type]) + || empty($this->_packageInfo['dependencies'][$type])) { + continue; + } + foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) { + if ($dtype == 'pearinstaller' && $nopearinstaller) { + continue; + } + if (!isset($deps[0])) { + $deps = array($deps); + } + foreach ($deps as $dep) { + if (!isset($map[$dtype])) { + // no support for arch type + continue; + } + if ($dtype == 'pearinstaller') { + $dep['name'] = 'PEAR'; + $dep['channel'] = 'pear.php.net'; + } + $s = array('type' => $map[$dtype]); + if (isset($dep['channel'])) { + $s['channel'] = $dep['channel']; + } + if (isset($dep['uri'])) { + $s['uri'] = $dep['uri']; + } + if (isset($dep['name'])) { + $s['name'] = $dep['name']; + } + if (isset($dep['conflicts'])) { + $s['rel'] = 'not'; + } else { + if (!isset($dep['min']) && + !isset($dep['max'])) { + $s['rel'] = 'has'; + $s['optional'] = $optional; + } elseif (isset($dep['min']) && + isset($dep['max'])) { + $s['rel'] = 'ge'; + $s1 = $s; + $s1['rel'] = 'le'; + $s['version'] = $dep['min']; + $s1['version'] = $dep['max']; + if (isset($dep['channel'])) { + $s1['channel'] = $dep['channel']; + } + if ($dtype != 'php') { + $s['name'] = $dep['name']; + $s1['name'] = $dep['name']; + } + $s['optional'] = $optional; + $s1['optional'] = $optional; + $ret[] = $s1; + } elseif (isset($dep['min'])) { + if (isset($dep['exclude']) && + $dep['exclude'] == $dep['min']) { + $s['rel'] = 'gt'; + } else { + $s['rel'] = 'ge'; + } + $s['version'] = $dep['min']; + $s['optional'] = $optional; + if ($dtype != 'php') { + $s['name'] = $dep['name']; + } + } elseif (isset($dep['max'])) { + if (isset($dep['exclude']) && + $dep['exclude'] == $dep['max']) { + $s['rel'] = 'lt'; + } else { + $s['rel'] = 'le'; + } + $s['version'] = $dep['max']; + $s['optional'] = $optional; + if ($dtype != 'php') { + $s['name'] = $dep['name']; + } + } + } + $ret[] = $s; + } + } + } + if (count($ret)) { + return $ret; } - - $dir = getcwd(); } + return false; + } - $this->log(2, "building in $dir"); - - $dsp = $pkg->getPackage().'.dsp'; - if (!file_exists("$dir/$dsp")) { - return $this->raiseError("The DSP $dsp does not exist."); + /** + * @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false + */ + function getPackageType() + { + if (isset($this->_packageInfo['phprelease'])) { + return 'php'; } - // XXX TODO: make release build type configurable - $command = 'msdev '.$dsp.' /MAKE "'.$pkg->getPackage(). ' - Release"'; - - $err = $this->_runCommand($command, array(&$this, 'msdevCallback')); - if (PEAR::isError($err)) { - return $err; + if (isset($this->_packageInfo['extsrcrelease'])) { + return 'extsrc'; } - - // figure out the build platform and type - $platform = 'Win32'; - $buildtype = 'Release'; - if (preg_match('/.*?'.$pkg->getPackage().'\s-\s(\w+)\s(.*?)-+/i',$this->_firstline,$matches)) { - $platform = $matches[1]; - $buildtype = $matches[2]; + if (isset($this->_packageInfo['extbinrelease'])) { + return 'extbin'; } - - if (preg_match('/(.*)?\s-\s(\d+).*?(\d+)/', $this->_lastline, $matches)) { - if ($matches[2]) { - // there were errors in the build - return $this->raiseError("There were errors during compilation."); - } - $out = $matches[1]; - } else { - return $this->raiseError("Did not understand the completion status returned from msdev.exe."); + if (isset($this->_packageInfo['zendextsrcrelease'])) { + return 'zendextsrc'; } + if (isset($this->_packageInfo['zendextbinrelease'])) { + return 'zendextbin'; + } + if (isset($this->_packageInfo['bundle'])) { + return 'bundle'; + } + return false; + } - // msdev doesn't tell us the output directory :/ - // open the dsp, find /out and use that directory - $dsptext = join(file($dsp),''); - - // this regex depends on the build platform and type having been - // correctly identified above. - $regex ='/.*?!IF\s+"\$\(CFG\)"\s+==\s+("'. - $pkg->getPackage().'\s-\s'. - $platform.'\s'. - $buildtype.'").*?'. - '\/out:"(.*?)"/is'; - - if ($dsptext && preg_match($regex, $dsptext, $matches)) { - // what we get back is a relative path to the output file itself. - $outfile = realpath($matches[2]); - } else { - return $this->raiseError("Could not retrieve output information from $dsp."); + /** + * @return array|false + */ + function getReleases() + { + $type = $this->getPackageType(); + if ($type != 'bundle') { + $type .= 'release'; } - // realpath returns false if the file doesn't exist - if ($outfile && copy($outfile, "$dir/$out")) { - $outfile = "$dir/$out"; + if ($this->getPackageType() && isset($this->_packageInfo[$type])) { + return $this->_packageInfo[$type]; } + return false; + } - $built_files[] = array( - 'file' => "$outfile", - 'php_api' => $this->php_api_version, - 'zend_mod_api' => $this->zend_module_api_no, - 'zend_ext_api' => $this->zend_extension_api_no, - ); + /** + * @return array + */ + function getChangelog() + { + if (isset($this->_packageInfo['changelog'])) { + return $this->_packageInfo['changelog']; + } + return false; + } - return $built_files; + function hasDeps() + { + return isset($this->_packageInfo['dependencies']); } - // }}} - // {{{ msdevCallback() - function msdevCallback($what, $data) + function getPackagexmlVersion() { - if (!$this->_firstline) - $this->_firstline = $data; - $this->_lastline = $data; - call_user_func($this->current_callback, $what, $data); + if (isset($this->_packageInfo['zendextsrcrelease'])) { + return '2.1'; + } + if (isset($this->_packageInfo['zendextbinrelease'])) { + return '2.1'; + } + return '2.0'; } /** - * @param string - * @param string - * @param array - * @access private + * @return array|false */ - function _harvestInstDir($dest_prefix, $dirname, &$built_files) + function getSourcePackage() { - $d = opendir($dirname); - if (!$d) - return false; + if (isset($this->_packageInfo['extbinrelease']) || + isset($this->_packageInfo['zendextbinrelease'])) { + return array('channel' => $this->_packageInfo['srcchannel'], + 'package' => $this->_packageInfo['srcpackage']); + } + return false; + } - $ret = true; - while (($ent = readdir($d)) !== false) { - if ($ent{0} == '.') - continue; + function getBundledPackages() + { + if (isset($this->_packageInfo['bundle'])) { + return $this->_packageInfo['contents']['bundledpackage']; + } + return false; + } - $full = $dirname . DIRECTORY_SEPARATOR . $ent; - if (is_dir($full)) { - if (!$this->_harvestInstDir( - $dest_prefix . DIRECTORY_SEPARATOR . $ent, - $full, $built_files)) { - $ret = false; - break; - } - } else { - $dest = $dest_prefix . DIRECTORY_SEPARATOR . $ent; - $built_files[] = array( - 'file' => $full, - 'dest' => $dest, - 'php_api' => $this->php_api_version, - 'zend_mod_api' => $this->zend_module_api_no, - 'zend_ext_api' => $this->zend_extension_api_no, - ); - } + function getLastModified() + { + if (isset($this->_packageInfo['_lastmodified'])) { + return $this->_packageInfo['_lastmodified']; } - closedir($d); - return $ret; + return false; } /** - * Build an extension from source. Runs "phpize" in the source - * directory, but compiles in a temporary directory - * (/var/tmp/pear-build-USER/PACKAGE-VERSION). - * - * @param string|PEAR_PackageFile_v* $descfile path to XML package description file, or - * a PEAR_PackageFile object - * - * @param mixed $callback callback function used to report output, - * see PEAR_Builder::_runCommand for details - * - * @return array an array of associative arrays with built files, - * format: - * array( array( 'file' => '/path/to/ext.so', - * 'php_api' => YYYYMMDD, - * 'zend_mod_api' => YYYYMMDD, - * 'zend_ext_api' => YYYYMMDD ), - * ... ) - * - * @access public - * - * @see PEAR_Builder::_runCommand + * Get the contents of a file listed within the package.xml + * @param string + * @return string */ - function build($descfile, $callback = null) + function getFileContents($file) { - if (preg_match('/(\\/|\\\\|^)([^\\/\\\\]+)?php(.+)?$/', - $this->config->get('php_bin'), $matches)) { - if (isset($matches[2]) && strlen($matches[2]) && - trim($matches[2]) != trim($this->config->get('php_prefix'))) { - $this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') . - ' appears to have a prefix ' . $matches[2] . ', but' . - ' config variable php_prefix does not match'); + if ($this->_archiveFile == $this->_packageFile) { // unpacked + $dir = dirname($this->_packageFile); + $file = $dir . DIRECTORY_SEPARATOR . $file; + $file = str_replace(array('/', '\\'), + array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); + if (file_exists($file) && is_readable($file)) { + return implode('', file($file)); } - if (isset($matches[3]) && strlen($matches[3]) && - trim($matches[3]) != trim($this->config->get('php_suffix'))) { - $this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') . - ' appears to have a suffix ' . $matches[3] . ', but' . - ' config variable php_suffix does not match'); + } else { // tgz + $tar = &new Archive_Tar($this->_archiveFile); + $tar->pushErrorHandling(PEAR_ERROR_RETURN); + if ($file != 'package.xml' && $file != 'package2.xml') { + $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; + } + $file = $tar->extractInString($file); + $tar->popErrorHandling(); + if (PEAR::isError($file)) { + return PEAR::raiseError("Cannot locate file '$file' in archive"); } + return $file; } + } - - $this->current_callback = $callback; - if (PEAR_OS == "Windows") { - return $this->_build_win32($descfile, $callback); - } - if (PEAR_OS != 'Unix') { - return $this->raiseError("building extensions not supported on this platform"); + function &getRW() + { + if (!class_exists('PEAR_PackageFile_v2_rw')) { + require_once 'PEAR/PackageFile/v2/rw.php'; } - if (is_object($descfile)) { - $pkg = $descfile; - $descfile = $pkg->getPackageFile(); - if (is_a($pkg, 'PEAR_PackageFile_v1')) { - $dir = dirname($descfile); - } else { - $dir = $pkg->_config->get('temp_dir') . '/' . $pkg->getName(); - // automatically delete at session end - $this->addTempFile($dir); + $a = new PEAR_PackageFile_v2_rw; + foreach (get_object_vars($this) as $name => $unused) { + if (!isset($this->$name)) { + continue; } - } else { - $pf = &new PEAR_PackageFile($this->config); - $pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($pkg)) { - return $pkg; + if ($name == '_config' || $name == '_logger'|| $name == '_registry' || + $name == '_stack') { + $a->$name = &$this->$name; + } else { + $a->$name = $this->$name; } - $dir = dirname($descfile); - } - $old_cwd = getcwd(); - if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) { - return $this->raiseError("could not chdir to $dir"); - } - $vdir = $pkg->getPackage() . '-' . $pkg->getVersion(); - if (is_dir($vdir)) { - chdir($vdir); - } - $dir = getcwd(); - $this->log(2, "building in $dir"); - putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH')); - $err = $this->_runCommand($this->config->get('php_prefix') - . "phpize" . - $this->config->get('php_suffix'), - array(&$this, 'phpizeCallback')); - if (PEAR::isError($err)) { - return $err; } - if (!$err) { - return $this->raiseError("`phpize' failed"); + return $a; + } + + function &getDefaultGenerator() + { + if (!class_exists('PEAR_PackageFile_Generator_v2')) { + require_once 'PEAR/PackageFile/Generator/v2.php'; } + $a = &new PEAR_PackageFile_Generator_v2($this); + return $a; + } - // {{{ start of interactive part - $configure_command = "$dir/configure"; - $configure_options = $pkg->getConfigureOptions(); - if ($configure_options) { - foreach ($configure_options as $o) { - $default = array_key_exists('default', $o) ? $o['default'] : null; - list($r) = $this->ui->userDialog('build', - array($o['prompt']), - array('text'), - array($default)); - if (substr($o['name'], 0, 5) == 'with-' && - ($r == 'yes' || $r == 'autodetect')) { - $configure_command .= " --$o[name]"; - } else { - $configure_command .= " --$o[name]=".trim($r); - } + function analyzeSourceCode($file, $string = false) + { + if (!isset($this->_v2Validator) || + !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { + if (!class_exists('PEAR_PackageFile_v2_Validator')) { + require_once 'PEAR/PackageFile/v2/Validator.php'; } + $this->_v2Validator = new PEAR_PackageFile_v2_Validator; } - // }}} end of interactive part + return $this->_v2Validator->analyzeSourceCode($file, $string); + } - // FIXME make configurable - if(!$user=getenv('USER')){ - $user='defaultuser'; - } - $build_basedir = "/var/tmp/pear-build-$user"; - $build_dir = "$build_basedir/$vdir"; - $inst_dir = "$build_basedir/install-$vdir"; - $this->log(1, "building in $build_dir"); - if (is_dir($build_dir)) { - System::rm(array('-rf', $build_dir)); + function validate($state = PEAR_VALIDATE_NORMAL) + { + if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { + return false; } - if (!System::mkDir(array('-p', $build_dir))) { - return $this->raiseError("could not create build dir: $build_dir"); + if (!isset($this->_v2Validator) || + !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { + if (!class_exists('PEAR_PackageFile_v2_Validator')) { + require_once 'PEAR/PackageFile/v2/Validator.php'; + } + $this->_v2Validator = new PEAR_PackageFile_v2_Validator; } - $this->addTempFile($build_dir); - if (!System::mkDir(array('-p', $inst_dir))) { - return $this->raiseError("could not create temporary install dir: $inst_dir"); + if (isset($this->_packageInfo['xsdversion'])) { + unset($this->_packageInfo['xsdversion']); } - $this->addTempFile($inst_dir); + return $this->_v2Validator->validate($this, $state); + } - if (getenv('MAKE')) { - $make_command = getenv('MAKE'); - } else { - $make_command = 'make'; - } - $to_run = array( - $configure_command, - $make_command, - "$make_command INSTALL_ROOT=\"$inst_dir\" install", - "find \"$inst_dir\" | xargs ls -dils" - ); - if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) { - return $this->raiseError("could not chdir to $build_dir"); - } - putenv('PHP_PEAR_VERSION=1.8.0'); - foreach ($to_run as $cmd) { - $err = $this->_runCommand($cmd, $callback); - if (PEAR::isError($err)) { - chdir($old_cwd); - return $err; - } - if (!$err) { - chdir($old_cwd); - return $this->raiseError("`$cmd' failed"); + function getTasksNs() + { + if (!isset($this->_tasksNs)) { + if (isset($this->_packageInfo['attribs'])) { + foreach ($this->_packageInfo['attribs'] as $name => $value) { + if ($value == 'http://pear.php.net/dtd/tasks-1.0') { + $this->_tasksNs = str_replace('xmlns:', '', $name); + break; + } + } } } - if (!($dp = opendir("modules"))) { - chdir($old_cwd); - return $this->raiseError("no `modules' directory found"); - } - $built_files = array(); - $prefix = exec($this->config->get('php_prefix') - . "php-config" . - $this->config->get('php_suffix') . " --prefix"); - $this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files); - chdir($old_cwd); - return $built_files; + return $this->_tasksNs; } /** - * Message callback function used when running the "phpize" - * program. Extracts the API numbers used. Ignores other message - * types than "cmdoutput". - * - * @param string $what the type of message - * @param mixed $data the message - * - * @return void + * Determine whether a task name is a valid task. Custom tasks may be defined + * using subdirectories by putting a "-" in the name, as in * - * @access public - */ - function phpizeCallback($what, $data) + * Note that this method will auto-load the task class file and test for the existence + * of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class + * PEAR_Task_mycustom_task + * @param string + * @return boolean + */ + function getTask($task) { - if ($what != 'cmdoutput') { - return; - } - $this->log(1, rtrim($data)); - if (preg_match('/You should update your .aclocal.m4/', $data)) { - return; + $this->getTasksNs(); + // transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace + $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task); + $taskfile = str_replace(' ', '/', ucwords($task)); + $task = str_replace(array(' ', '/'), '_', ucwords($task)); + if (class_exists("PEAR_Task_$task")) { + return "PEAR_Task_$task"; } - $matches = array(); - if (preg_match('/^\s+(\S[^:]+):\s+(\d{8})/', $data, $matches)) { - $member = preg_replace('/[^a-z]/', '_', strtolower($matches[1])); - $apino = (int)$matches[2]; - if (isset($this->$member)) { - $this->$member = $apino; - //$msg = sprintf("%-22s : %d", $matches[1], $apino); - //$this->log(1, $msg); - } + $fp = @fopen("PEAR/Task/$taskfile.php", 'r', true); + if ($fp) { + fclose($fp); + require_once "PEAR/Task/$taskfile.php"; + return "PEAR_Task_$task"; } + return false; } /** - * Run an external command, using a message callback to report - * output. The command will be run through popen and output is - * reported for every line with a "cmdoutput" message with the - * line string, including newlines, as payload. - * - * @param string $command the command to run - * - * @param mixed $callback (optional) function to use as message - * callback - * - * @return bool whether the command was successful (exit code 0 - * means success, any other means failure) - * - * @access private + * Key-friendly array_splice + * @param tagname to splice a value in before + * @param mixed the value to splice in + * @param string the new tag name */ - function _runCommand($command, $callback = null) + function _ksplice($array, $key, $value, $newkey) { - $this->log(1, "running: $command"); - $pp = popen("$command 2>&1", "r"); - if (!$pp) { - return $this->raiseError("failed to run `$command'"); - } - if ($callback && $callback[0]->debug == 1) { - $olddbg = $callback[0]->debug; - $callback[0]->debug = 2; - } + $offset = array_search($key, array_keys($array)); + $after = array_slice($array, $offset); + $before = array_slice($array, 0, $offset); + $before[$newkey] = $value; + return array_merge($before, $after); + } - while ($line = fgets($pp, 1024)) { - if ($callback) { - call_user_func($callback, 'cmdoutput', $line); - } else { - $this->log(2, rtrim($line)); + /** + * @param array a list of possible keys, in the order they may occur + * @param mixed contents of the new package.xml tag + * @param string tag name + * @access private + */ + function _insertBefore($array, $keys, $contents, $newkey) + { + foreach ($keys as $key) { + if (isset($array[$key])) { + return $array = $this->_ksplice($array, $key, $contents, $newkey); } } - if ($callback && isset($olddbg)) { - $callback[0]->debug = $olddbg; - } - - $exitcode = is_resource($pp) ? pclose($pp) : -1; - return ($exitcode == 0); + $array[$newkey] = $contents; + return $array; } - function log($level, $msg) + /** + * @param subsection of {@link $_packageInfo} + * @param array|string tag contents + * @param array format: + *
    +     * array(
    +     *   tagname => array(list of tag names that follow this one),
    +     *   childtagname => array(list of child tag names that follow this one),
    +     * )
    +     * 
    + * + * This allows construction of nested tags + * @access private + */ + function _mergeTag($manip, $contents, $order) { - if ($this->current_callback) { - if ($this->debug >= $level) { - call_user_func($this->current_callback, 'output', $msg); + if (count($order)) { + foreach ($order as $tag => $curorder) { + if (!isset($manip[$tag])) { + // ensure that the tag is set up + $manip = $this->_insertBefore($manip, $curorder, array(), $tag); + } + if (count($order) > 1) { + $manip[$tag] = $this->_mergeTag($manip[$tag], $contents, array_slice($order, 1)); + return $manip; + } } - return; + } else { + return $manip; } - return PEAR_Common::log($level, $msg); + if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) { + $manip[$tag][] = $contents; + } else { + if (!count($manip[$tag])) { + $manip[$tag] = $contents; + } else { + $manip[$tag] = array($manip[$tag]); + $manip[$tag][] = $contents; + } + } + return $manip; } -}PEAR-1.8.0/PEAR/ChannelFile.php100664 764 764 142432 100664 10763 +PEAR-1.9.0/PEAR/REST/10.php100664 764 764 77605 100664 7602 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: ChannelFile.php,v 1.84 2009/03/09 01:03:51 dufuz Exp $ + * @version CVS: $Id: 10.php 287558 2009-08-21 22:21:28Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * Needed for error handling - */ -require_once 'PEAR/ErrorStack.php'; -require_once 'PEAR/XMLParser.php'; -require_once 'PEAR/Common.php'; - -/** - * Error code if the channel.xml tag does not contain a valid version - */ -define('PEAR_CHANNELFILE_ERROR_NO_VERSION', 1); -/** - * Error code if the channel.xml tag version is not supported (version 1.0 is the only supported version, - * currently - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_VERSION', 2); - -/** - * Error code if parsing is attempted with no xml extension - */ -define('PEAR_CHANNELFILE_ERROR_NO_XML_EXT', 3); - -/** - * Error code if creating the xml parser resource fails - */ -define('PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER', 4); - -/** - * Error code used for all sax xml parsing errors - */ -define('PEAR_CHANNELFILE_ERROR_PARSER_ERROR', 5); - -/**#@+ - * Validation errors - */ -/** - * Error code when channel name is missing - */ -define('PEAR_CHANNELFILE_ERROR_NO_NAME', 6); -/** - * Error code when channel name is invalid - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_NAME', 7); -/** - * Error code when channel summary is missing - */ -define('PEAR_CHANNELFILE_ERROR_NO_SUMMARY', 8); -/** - * Error code when channel summary is multi-line - */ -define('PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY', 9); -/** - * Error code when channel server is missing for protocol - */ -define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10); -/** - * Error code when channel server is invalid for protocol - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_HOST', 11); -/** - * Error code when a mirror name is invalid - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_MIRROR', 21); -/** - * Error code when a mirror type is invalid - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE', 22); -/** - * Error code when an attempt is made to generate xml, but the parsed content is invalid - */ -define('PEAR_CHANNELFILE_ERROR_INVALID', 23); -/** - * Error code when an empty package name validate regex is passed in - */ -define('PEAR_CHANNELFILE_ERROR_EMPTY_REGEX', 24); -/** - * Error code when a tag has no version - */ -define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION', 25); -/** - * Error code when a tag has no name - */ -define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME', 26); -/** - * Error code when a tag has no name - */ -define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME', 27); -/** - * Error code when a tag has no version attribute - */ -define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION', 28); -/** - * Error code when a mirror does not exist but is called for in one of the set* - * methods. - */ -define('PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND', 32); -/** - * Error code when a server port is not numeric - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_PORT', 33); -/** - * Error code when contains no version attribute - */ -define('PEAR_CHANNELFILE_ERROR_NO_STATICVERSION', 34); -/** - * Error code when contains no type attribute in a protocol definition - */ -define('PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE', 35); -/** - * Error code when a mirror is defined and the channel.xml represents the __uri pseudo-channel - */ -define('PEAR_CHANNELFILE_URI_CANT_MIRROR', 36); -/** - * Error code when ssl attribute is present and is not "yes" + * @since File available since Release 1.4.0a12 */ -define('PEAR_CHANNELFILE_ERROR_INVALID_SSL', 37); -/**#@-*/ /** - * Mirror types allowed. Currently only internet servers are recognized. + * For downloading REST xml/txt files */ -$GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] = array('server'); - +require_once 'PEAR/REST.php'; /** - * The Channel handling class + * Implement REST 1.0 * * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 + * @since Class available since Release 1.4.0a12 */ -class PEAR_ChannelFile +class PEAR_REST_10 { /** - * @access private - * @var PEAR_ErrorStack - * @access private - */ - var $_stack; - - /** - * Supported channel.xml versions, for parsing - * @var array - * @access private - */ - var $_supportedVersions = array('1.0'); - - /** - * Parsed channel information - * @var array - * @access private + * @var PEAR_REST */ - var $_channelInfo; + var $_rest; + function PEAR_REST_10($config, $options = array()) + { + $this->_rest = &new PEAR_REST($config, $options); + } /** - * index into the subchannels array, used for parsing xml - * @var int - * @access private + * Retrieve information about a remote package to be downloaded from a REST server + * + * @param string $base The uri to prepend to all REST calls + * @param array $packageinfo an array of format: + *
    +     *  array(
    +     *   'package' => 'packagename',
    +     *   'channel' => 'channelname',
    +     *  ['state' => 'alpha' (or valid state),]
    +     *  -or-
    +     *  ['version' => '1.whatever']
    +     * 
    + * @param string $prefstate Current preferred_state config variable value + * @param bool $installed the installed version of this package to compare against + * @return array|false|PEAR_Error see {@link _returnDownloadURL()} */ - var $_subchannelIndex; + function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false) + { + $states = $this->betterStates($prefstate, true); + if (!$states) { + return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); + } - /** - * index into the mirrors array, used for parsing xml - * @var int - * @access private - */ - var $_mirrorIndex; + $channel = $packageinfo['channel']; + $package = $packageinfo['package']; + $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; + $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml'; - /** - * Flag used to determine the validity of parsed content - * @var boolean - * @access private - */ - var $_isValid = false; + $info = $this->_rest->retrieveData($restFile, false, false, $channel); + if (PEAR::isError($info)) { + return PEAR::raiseError('No releases available for package "' . + $channel . '/' . $package . '"'); + } - function PEAR_ChannelFile() - { - $this->_stack = &new PEAR_ErrorStack('PEAR_ChannelFile'); - $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); - $this->_isValid = false; - } + if (!isset($info['r'])) { + return false; + } - /** - * @return array - * @access protected - */ - function _getErrorMessage() - { - return - array( - PEAR_CHANNELFILE_ERROR_INVALID_VERSION => - 'While parsing channel.xml, an invalid version number "%version% was passed in, expecting one of %versions%', - PEAR_CHANNELFILE_ERROR_NO_VERSION => - 'No version number found in tag', - PEAR_CHANNELFILE_ERROR_NO_XML_EXT => - '%error%', - PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER => - 'Unable to create XML parser', - PEAR_CHANNELFILE_ERROR_PARSER_ERROR => - '%error%', - PEAR_CHANNELFILE_ERROR_NO_NAME => - 'Missing channel name', - PEAR_CHANNELFILE_ERROR_INVALID_NAME => - 'Invalid channel %tag% "%name%"', - PEAR_CHANNELFILE_ERROR_NO_SUMMARY => - 'Missing channel summary', - PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY => - 'Channel summary should be on one line, but is multi-line', - PEAR_CHANNELFILE_ERROR_NO_HOST => - 'Missing channel server for %type% server', - PEAR_CHANNELFILE_ERROR_INVALID_HOST => - 'Server name "%server%" is invalid for %type% server', - PEAR_CHANNELFILE_ERROR_INVALID_MIRROR => - 'Invalid mirror name "%name%", mirror type %type%', - PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE => - 'Invalid mirror type "%type%"', - PEAR_CHANNELFILE_ERROR_INVALID => - 'Cannot generate xml, contents are invalid', - PEAR_CHANNELFILE_ERROR_EMPTY_REGEX => - 'packagenameregex cannot be empty', - PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION => - '%parent% %protocol% function has no version', - PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME => - '%parent% %protocol% function has no name', - PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE => - '%parent% rest baseurl has no type', - PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME => - 'Validation package has no name in tag', - PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION => - 'Validation package "%package%" has no version', - PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND => - 'Mirror "%mirror%" does not exist', - PEAR_CHANNELFILE_ERROR_INVALID_PORT => - 'Port "%port%" must be numeric', - PEAR_CHANNELFILE_ERROR_NO_STATICVERSION => - ' tag must contain version attribute', - PEAR_CHANNELFILE_URI_CANT_MIRROR => - 'The __uri pseudo-channel cannot have mirrors', - PEAR_CHANNELFILE_ERROR_INVALID_SSL => - '%server% has invalid ssl attribute "%ssl%" can only be yes or not present', - ); - } + $release = $found = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); + } - /** - * @param string contents of package.xml file - * @return bool success of parsing - */ - function fromXmlString($data) - { - if (preg_match('/_supportedVersions)) { - $this->_stack->push(PEAR_CHANNELFILE_ERROR_INVALID_VERSION, 'error', - array('version' => $channelversion[1])); - return false; + foreach ($info['r'] as $release) { + if (!isset($this->_rest->_options['force']) && ($installed && + version_compare($release['v'], $installed, '<'))) { + continue; } - $parser = new PEAR_XMLParser; - $result = $parser->parse($data); - if ($result !== true) { - if ($result->getCode() == 1) { - $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_XML_EXT, 'error', - array('error' => $result->getMessage())); - } else { - $this->_stack->push(PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER, 'error'); + + if (isset($state)) { + // try our preferred state first + if ($release['s'] == $state) { + $found = true; + break; + } + // see if there is something newer and more stable + // bug #7221 + if (in_array($release['s'], $this->betterStates($state), true)) { + $found = true; + break; + } + } elseif (isset($version)) { + if ($release['v'] == $version) { + $found = true; + break; + } + } else { + if (in_array($release['s'], $states)) { + $found = true; + break; } - return false; } - $this->_channelInfo = $parser->getData(); - return true; - } else { - $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_VERSION, 'error', array('xml' => $data)); - return false; } + + return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel); } - /** - * @return array - */ - function toArray() + function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage, + $prefstate = 'stable', $installed = false, $channel = false) { - if (!$this->_isValid && !$this->validate()) { - return false; + $states = $this->betterStates($prefstate, true); + if (!$states) { + return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } - return $this->_channelInfo; - } - /** - * @param array - * @static - * @return PEAR_ChannelFile|false false if invalid - */ - function &fromArray($data, $compatibility = false, $stackClass = 'PEAR_ErrorStack') - { - $a = new PEAR_ChannelFile($compatibility, $stackClass); - $a->_fromArray($data); - if (!$a->validate()) { - $a = false; - return $a; + $channel = $dependency['channel']; + $package = $dependency['name']; + $state = isset($dependency['state']) ? $dependency['state'] : null; + $version = isset($dependency['version']) ? $dependency['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); + if (PEAR::isError($info)) { + return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package'] + . '" dependency "' . $channel . '/' . $package . '" has no releases'); } - return $a; - } - /** - * Unlike {@link fromArray()} this does not do any validation - * @param array - * @static - * @return PEAR_ChannelFile - */ - function &fromArrayWithErrors($data, $compatibility = false, - $stackClass = 'PEAR_ErrorStack') - { - $a = new PEAR_ChannelFile($compatibility, $stackClass); - $a->_fromArray($data); - return $a; - } + if (!is_array($info) || !isset($info['r'])) { + return false; + } - /** - * @param array - * @access private - */ - function _fromArray($data) - { - $this->_channelInfo = $data; - } - - /** - * Wrapper to {@link PEAR_ErrorStack::getErrors()} - * @param boolean determines whether to purge the error stack after retrieving - * @return array - */ - function getErrors($purge = false) - { - return $this->_stack->getErrors($purge); - } - - /** - * Unindent given string (?) - * - * @param string $str The string that has to be unindented. - * @return string - * @access private - */ - function _unIndent($str) - { - // remove leading newlines - $str = preg_replace('/^[\r\n]+/', '', $str); - // find whitespace at the beginning of the first line - $indent_len = strspn($str, " \t"); - $indent = substr($str, 0, $indent_len); - $data = ''; - // remove the same amount of whitespace from following lines - foreach (explode("\n", $str) as $line) { - if (substr($line, 0, $indent_len) == $indent) { - $data .= substr($line, $indent_len) . "\n"; + $exclude = array(); + $min = $max = $recommended = false; + if ($xsdversion == '1.0') { + switch ($dependency['rel']) { + case 'ge' : + $min = $dependency['version']; + break; + case 'gt' : + $min = $dependency['version']; + $exclude = array($dependency['version']); + break; + case 'eq' : + $recommended = $dependency['version']; + break; + case 'lt' : + $max = $dependency['version']; + $exclude = array($dependency['version']); + break; + case 'le' : + $max = $dependency['version']; + break; + case 'ne' : + $exclude = array($dependency['version']); + break; + } + } else { + $min = isset($dependency['min']) ? $dependency['min'] : false; + $max = isset($dependency['max']) ? $dependency['max'] : false; + $recommended = isset($dependency['recommended']) ? + $dependency['recommended'] : false; + if (isset($dependency['exclude'])) { + if (!isset($dependency['exclude'][0])) { + $exclude = array($dependency['exclude']); + } } } - return $data; - } - - /** - * Parse a channel.xml file. Expects the name of - * a channel xml file as input. - * - * @param string $descfile name of channel xml file - * @return bool success of parsing - */ - function fromXmlFile($descfile) - { - if (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) || - (!$fp = fopen($descfile, 'r'))) { - require_once 'PEAR.php'; - return PEAR::raiseError("Unable to open $descfile"); + $release = $found = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); } - - // read the whole thing so we only get one cdata callback - // for each block of cdata - fclose($fp); - $data = file_get_contents($descfile); - return $this->fromXmlString($data); - } - - /** - * Parse channel information from different sources - * - * This method is able to extract information about a channel - * from an .xml file or a string - * - * @access public - * @param string Filename of the source or the source itself - * @return bool - */ - function fromAny($info) - { - if (is_string($info) && file_exists($info) && strlen($info) < 255) { - $tmp = substr($info, -4); - if ($tmp == '.xml') { - $info = $this->fromXmlFile($info); - } else { - $fp = fopen($info, "r"); - $test = fread($fp, 5); - fclose($fp); - if ($test == "fromXmlFile($info); + foreach ($info['r'] as $release) { + if (!isset($this->_rest->_options['force']) && ($installed && + version_compare($release['v'], $installed, '<'))) { + continue; + } + if (in_array($release['v'], $exclude)) { // skip excluded versions + continue; + } + // allow newer releases to say "I'm OK with the dependent package" + if ($xsdversion == '2.0' && isset($release['co'])) { + if (!is_array($release['co']) || !isset($release['co'][0])) { + $release['co'] = array($release['co']); + } + foreach ($release['co'] as $entry) { + if (isset($entry['x']) && !is_array($entry['x'])) { + $entry['x'] = array($entry['x']); + } elseif (!isset($entry['x'])) { + $entry['x'] = array(); + } + if ($entry['c'] == $deppackage['channel'] && + strtolower($entry['p']) == strtolower($deppackage['package']) && + version_compare($deppackage['version'], $entry['min'], '>=') && + version_compare($deppackage['version'], $entry['max'], '<=') && + !in_array($release['v'], $entry['x'])) { + $recommended = $release['v']; + break; + } } } - if (PEAR::isError($info)) { - require_once 'PEAR.php'; - return PEAR::raiseError($info); + if ($recommended) { + if ($release['v'] != $recommended) { // if we want a specific + // version, then skip all others + continue; + } else { + if (!in_array($release['s'], $states)) { + // the stability is too low, but we must return the + // recommended version if possible + return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel); + } + } + } + if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions + continue; + } + if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions + continue; + } + if ($installed && version_compare($release['v'], $installed, '<')) { + continue; + } + if (in_array($release['s'], $states)) { // if in the preferred state... + $found = true; // ... then use it + break; } } - if (is_string($info)) { - $info = $this->fromXmlString($info); - } - return $info; + return $this->_returnDownloadURL($base, $package, $release, $info, $found, false, $channel); } /** - * Return an XML document based on previous parsing and modifications - * - * @return string XML data + * Take raw data and return the array needed for processing a download URL * - * @access public + * @param string $base REST base uri + * @param string $package Package name + * @param array $release an array of format array('v' => version, 's' => state) + * describing the release to download + * @param array $info list of all releases as defined by allreleases.xml + * @param bool|null $found determines whether the release was found or this is the next + * best alternative. If null, then versions were skipped because + * of PHP dependency + * @return array|PEAR_Error + * @access private */ - function toXml() + function _returnDownloadURL($base, $package, $release, $info, $found, $phpversion = false, $channel = false) { - if (!$this->_isValid && !$this->validate()) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID); - return false; - } - if (!isset($this->_channelInfo['attribs']['version'])) { - $this->_channelInfo['attribs']['version'] = '1.0'; - } - $channelInfo = $this->_channelInfo; - $ret = "\n"; - $ret .= " - $channelInfo[name] - " . htmlspecialchars($channelInfo['summary'])." -"; - if (isset($channelInfo['suggestedalias'])) { - $ret .= ' ' . $channelInfo['suggestedalias'] . "\n"; - } - if (isset($channelInfo['validatepackage'])) { - $ret .= ' ' . - htmlspecialchars($channelInfo['validatepackage']['_content']) . - "\n"; - } - $ret .= " \n"; - $ret .= ' _makeRestXml($channelInfo['servers']['primary']['rest'], ' '); + + $packageLower = strtolower($package); + $pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . $packageLower . '/' . + 'info.xml', false, false, $channel); + if (PEAR::isError($pinfo)) { + return PEAR::raiseError('Package "' . $package . + '" does not have REST info xml available'); } - $ret .= " \n"; - if (isset($channelInfo['servers']['mirror'])) { - $ret .= $this->_makeMirrorsXml($channelInfo); + + $releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' . + $release['v'] . '.xml', false, false, $channel); + if (PEAR::isError($releaseinfo)) { + return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . + '" does not have REST xml available'); } - $ret .= " \n"; - $ret .= ""; - return str_replace("\r", "\n", str_replace("\r\n", "\n", $ret)); - } - /** - * Generate the tag - * @access private - */ - function _makeRestXml($info, $indent) - { - $ret = $indent . "\n"; - if (!isset($info['baseurl'][0])) { - $info['baseurl'] = array($info['baseurl']); + $packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' . + 'deps.' . $release['v'] . '.txt', false, true, $channel); + if (PEAR::isError($packagexml)) { + return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . + '" does not have REST dependency information available'); } - foreach ($info['baseurl'] as $url) { - $ret .= "$indent \n"; + + $packagexml = unserialize($packagexml); + if (!$packagexml) { + $packagexml = array(); } - $ret .= $indent . "\n"; - return $ret; - } - /** - * Generate the tag - * @access private - */ - function _makeMirrorsXml($channelInfo) - { - $ret = ""; - if (!isset($channelInfo['servers']['mirror'][0])) { - $channelInfo['servers']['mirror'] = array($channelInfo['servers']['mirror']); + $allinfo = $this->_rest->retrieveData($base . 'r/' . $packageLower . + '/allreleases.xml', false, false, $channel); + if (!is_array($allinfo['r']) || !isset($allinfo['r'][0])) { + $allinfo['r'] = array($allinfo['r']); } - foreach ($channelInfo['servers']['mirror'] as $mirror) { - $ret .= ' _makeRestXml($mirror['rest'], ' '); + + $compatible = array(); + if (!is_array($release['co']) || !isset($release['co'][0])) { + $release['co'] = array($release['co']); + } + + foreach ($release['co'] as $entry) { + $comp = array(); + $comp['name'] = $entry['p']; + $comp['channel'] = $entry['c']; + $comp['min'] = $entry['min']; + $comp['max'] = $entry['max']; + if (isset($entry['x']) && !is_array($entry['x'])) { + $comp['exclude'] = $entry['x']; } - $ret .= " \n"; + + $compatible[] = $comp; + } + + if (count($compatible) == 1) { + $compatible = $compatible[0]; + } + + break; + } + + $deprecated = false; + if (isset($pinfo['dc']) && isset($pinfo['dp'])) { + if (is_array($pinfo['dp'])) { + $deprecated = array('channel' => (string) $pinfo['dc'], + 'package' => trim($pinfo['dp']['_content'])); } else { - $ret .= "/>\n"; + $deprecated = array('channel' => (string) $pinfo['dc'], + 'package' => trim($pinfo['dp'])); } } - return $ret; + + $return = array( + 'version' => $releaseinfo['v'], + 'info' => $packagexml, + 'package' => $releaseinfo['p']['_content'], + 'stability' => $releaseinfo['st'], + 'compatible' => $compatible, + 'deprecated' => $deprecated, + ); + + if ($found) { + $return['url'] = $releaseinfo['g']; + return $return; + } + + $return['php'] = $phpversion; + return $return; } - /** - * Generate the tag - * @access private - */ - function _makeFunctionsXml($functions, $indent, $rest = false) + function listPackages($base, $channel = false) { - $ret = ''; - if (!isset($functions[0])) { - $functions = array($functions); + $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; } - foreach ($functions as $function) { - $ret .= "$indent\n"; + + if (!is_array($packagelist) || !isset($packagelist['p'])) { + return array(); } - return $ret; - } - /** - * Validation error. Also marks the object contents as invalid - * @param error code - * @param array error information - * @access private - */ - function _validateError($code, $params = array()) - { - $this->_stack->push($code, 'error', $params); - $this->_isValid = false; - } + if (!is_array($packagelist['p'])) { + $packagelist['p'] = array($packagelist['p']); + } - /** - * Validation warning. Does not mark the object contents invalid. - * @param error code - * @param array error information - * @access private - */ - function _validateWarning($code, $params = array()) - { - $this->_stack->push($code, 'warning', $params); + return $packagelist['p']; } /** - * Validate parsed file. + * List all categories of a REST server * - * @access public - * @return boolean + * @param string $base base URL of the server + * @return array of categorynames */ - function validate() + function listCategories($base, $channel = false) { - $this->_isValid = true; - $info = $this->_channelInfo; - if (empty($info['name'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_NAME); - } elseif (!$this->validChannelServer($info['name'])) { - if ($info['name'] != '__uri') { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name', - 'name' => $info['name'])); - } - } - if (empty($info['summary'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY); - } elseif (strpos(trim($info['summary']), "\n") !== false) { - $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY, - array('summary' => $info['summary'])); - } - if (isset($info['suggestedalias'])) { - if (!$this->validChannelServer($info['suggestedalias'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, - array('tag' => 'suggestedalias', 'name' =>$info['suggestedalias'])); - } - } - if (isset($info['localalias'])) { - if (!$this->validChannelServer($info['localalias'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, - array('tag' => 'localalias', 'name' =>$info['localalias'])); - } - } - if (isset($info['validatepackage'])) { - if (!isset($info['validatepackage']['_content'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME); - } - if (!isset($info['validatepackage']['attribs']['version'])) { - $content = isset($info['validatepackage']['_content']) ? - $info['validatepackage']['_content'] : - null; - $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION, - array('package' => $content)); - } - } + $categories = array(); - if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['port']) && - !is_numeric($info['servers']['primary']['attribs']['port'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT, - array('port' => $info['servers']['primary']['attribs']['port'])); + // c/categories.xml does not exist; + // check for every package its category manually + // This is SLOOOWWWW : /// + $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; } - if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['ssl']) && - $info['servers']['primary']['attribs']['ssl'] != 'yes') { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL, - array('ssl' => $info['servers']['primary']['attribs']['ssl'], - 'server' => $info['name'])); + if (!is_array($packagelist) || !isset($packagelist['p'])) { + $ret = array(); + return $ret; } - if (isset($info['servers']['primary']['rest']) && - isset($info['servers']['primary']['rest']['baseurl'])) { - $this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']); + if (!is_array($packagelist['p'])) { + $packagelist['p'] = array($packagelist['p']); } - if (isset($info['servers']['mirror'])) { - if ($this->_channelInfo['name'] == '__uri') { - $this->_validateError(PEAR_CHANNELFILE_URI_CANT_MIRROR); - } - if (!isset($info['servers']['mirror'][0])) { - $info['servers']['mirror'] = array($info['servers']['mirror']); - } - foreach ($info['servers']['mirror'] as $mirror) { - if (!isset($mirror['attribs']['host'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST, - array('type' => 'mirror')); - } elseif (!$this->validChannelServer($mirror['attribs']['host'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_HOST, - array('server' => $mirror['attribs']['host'], 'type' => 'mirror')); - } - if (isset($mirror['attribs']['ssl']) && $mirror['attribs']['ssl'] != 'yes') { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL, - array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host'])); + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + foreach ($packagelist['p'] as $package) { + $inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel); + if (PEAR::isError($inf)) { + PEAR::popErrorHandling(); + return $inf; } - if (isset($mirror['rest'])) { - $this->_validateFunctions('rest', $mirror['rest']['baseurl'], - $mirror['attribs']['host']); + $cat = $inf['ca']['_content']; + if (!isset($categories[$cat])) { + $categories[$cat] = $inf['ca']; } - } } - return $this->_isValid; + + return array_values($categories); } /** - * @param string rest - protocol name this function applies to - * @param array the functions - * @param string the name of the parent element (mirror name, for instance) + * List a category of a REST server + * + * @param string $base base URL of the server + * @param string $category name of the category + * @param boolean $info also download full package info + * @return array of packagenames */ - function _validateFunctions($protocol, $functions, $parent = '') + function listCategory($base, $category, $info = false, $channel = false) { - if (!isset($functions[0])) { - $functions = array($functions); + // gives '404 Not Found' error when category doesn't exist + $packagelist = $this->_rest->retrieveData($base.'c/'.urlencode($category).'/packages.xml', false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; } - foreach ($functions as $function) { - if (!isset($function['_content']) || empty($function['_content'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME, - array('parent' => $parent, 'protocol' => $protocol)); - } - if ($protocol == 'rest') { - if (!isset($function['attribs']['type']) || - empty($function['attribs']['type'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_BASEURLTYPE, - array('parent' => $parent, 'protocol' => $protocol)); + + if (!is_array($packagelist) || !isset($packagelist['p'])) { + return array(); + } + + if (!is_array($packagelist['p']) || + !isset($packagelist['p'][0])) { // only 1 pkg + $packagelist = array($packagelist['p']); + } else { + $packagelist = $packagelist['p']; + } + + if ($info == true) { + // get individual package info + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + foreach ($packagelist as $i => $packageitem) { + $url = sprintf('%s'.'r/%s/latest.txt', + $base, + strtolower($packageitem['_content'])); + $version = $this->_rest->retrieveData($url, false, false, $channel); + if (PEAR::isError($version)) { + break; // skipit } - } else { - if (!isset($function['attribs']['version']) || - empty($function['attribs']['version'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION, - array('parent' => $parent, 'protocol' => $protocol)); + $url = sprintf('%s'.'r/%s/%s.xml', + $base, + strtolower($packageitem['_content']), + $version); + $info = $this->_rest->retrieveData($url, false, false, $channel); + if (PEAR::isError($info)) { + break; // skipit } + $packagelist[$i]['info'] = $info; } + PEAR::popErrorHandling(); } + + return $packagelist; } - /** - * Test whether a string contains a valid channel server. - * @param string $ver the package version to test - * @return bool - */ - function validChannelServer($server) + + function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false) { - if ($server == '__uri') { - return true; + $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; + } + if ($this->_rest->config->get('verbose') > 0) { + $ui = &PEAR_Frontend::singleton(); + $ui->log('Retrieving data...0%', true); + } + $ret = array(); + if (!is_array($packagelist) || !isset($packagelist['p'])) { + return $ret; + } + if (!is_array($packagelist['p'])) { + $packagelist['p'] = array($packagelist['p']); } - return (bool) preg_match(PEAR_CHANNELS_SERVER_PREG, $server); - } - /** - * @return string|false - */ - function getName() - { - if (isset($this->_channelInfo['name'])) { - return $this->_channelInfo['name']; + // only search-packagename = quicksearch ! + if ($searchpackage && (!$searchsummary || empty($searchpackage))) { + $newpackagelist = array(); + foreach ($packagelist['p'] as $package) { + if (!empty($searchpackage) && stristr($package, $searchpackage) !== false) { + $newpackagelist[] = $package; + } + } + $packagelist['p'] = $newpackagelist; } + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $next = .1; + foreach ($packagelist['p'] as $progress => $package) { + if ($this->_rest->config->get('verbose') > 0) { + if ($progress / count($packagelist['p']) >= $next) { + if ($next == .5) { + $ui->log('50%', false); + } else { + $ui->log('.', false); + } + $next += .1; + } + } - return false; + if ($basic) { // remote-list command + if ($dostable) { + $latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + '/stable.txt', false, false, $channel); + } else { + $latest = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + '/latest.txt', false, false, $channel); + } + if (PEAR::isError($latest)) { + $latest = false; + } + $info = array('stable' => $latest); + } else { // list-all command + $inf = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel); + if (PEAR::isError($inf)) { + PEAR::popErrorHandling(); + return $inf; + } + if ($searchpackage) { + $found = (!empty($searchpackage) && stristr($package, $searchpackage) !== false); + if (!$found && !(isset($searchsummary) && !empty($searchsummary) + && (stristr($inf['s'], $searchsummary) !== false + || stristr($inf['d'], $searchsummary) !== false))) + { + continue; + }; + } + $releases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + '/allreleases.xml', false, false, $channel); + if (PEAR::isError($releases)) { + continue; + } + if (!isset($releases['r'][0])) { + $releases['r'] = array($releases['r']); + } + unset($latest); + unset($unstable); + unset($stable); + unset($state); + foreach ($releases['r'] as $release) { + if (!isset($latest)) { + if ($dostable && $release['s'] == 'stable') { + $latest = $release['v']; + $state = 'stable'; + } + if (!$dostable) { + $latest = $release['v']; + $state = $release['s']; + } + } + if (!isset($stable) && $release['s'] == 'stable') { + $stable = $release['v']; + if (!isset($unstable)) { + $unstable = $stable; + } + } + if (!isset($unstable) && $release['s'] != 'stable') { + $latest = $unstable = $release['v']; + $state = $release['s']; + } + if (isset($latest) && !isset($state)) { + $state = $release['s']; + } + if (isset($latest) && isset($stable) && isset($unstable)) { + break; + } + } + $deps = array(); + if (!isset($unstable)) { + $unstable = false; + $state = 'stable'; + if (isset($stable)) { + $latest = $unstable = $stable; + } + } else { + $latest = $unstable; + } + if (!isset($latest)) { + $latest = false; + } + if ($latest) { + $d = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' . + $latest . '.txt', false, false, $channel); + if (!PEAR::isError($d)) { + $d = unserialize($d); + if ($d) { + if (isset($d['required'])) { + if (!class_exists('PEAR_PackageFile_v2')) { + require_once 'PEAR/PackageFile/v2.php'; + } + if (!isset($pf)) { + $pf = new PEAR_PackageFile_v2; + } + $pf->setDeps($d); + $tdeps = $pf->getDeps(); + } else { + $tdeps = $d; + } + foreach ($tdeps as $dep) { + if ($dep['type'] !== 'pkg') { + continue; + } + $deps[] = $dep; + } + } + } + } + if (!isset($stable)) { + $stable = '-n/a-'; + } + if (!$searchpackage) { + $info = array('stable' => $latest, 'summary' => $inf['s'], 'description' => + $inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'], + 'unstable' => $unstable, 'state' => $state); + } else { + $info = array('stable' => $stable, 'summary' => $inf['s'], 'description' => + $inf['d'], 'deps' => $deps, 'category' => $inf['ca']['_content'], + 'unstable' => $unstable, 'state' => $state); + } + } + $ret[$package] = $info; + } + PEAR::popErrorHandling(); + return $ret; } - /** - * @return string|false - */ - function getServer() + function listLatestUpgrades($base, $pref_state, $installed, $channel, &$reg) { - if (isset($this->_channelInfo['name'])) { - return $this->_channelInfo['name']; + $packagelist = $this->_rest->retrieveData($base . 'p/packages.xml', false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; } - return false; - } - - /** - * @return int|80 port number to connect to - */ - function getPort($mirror = false) - { - if ($mirror) { - if ($mir = $this->getMirror($mirror)) { - if (isset($mir['attribs']['port'])) { - return $mir['attribs']['port']; - } + $ret = array(); + if (!is_array($packagelist) || !isset($packagelist['p'])) { + return $ret; + } - if ($this->getSSL($mirror)) { - return 443; - } + if (!is_array($packagelist['p'])) { + $packagelist['p'] = array($packagelist['p']); + } - return 80; + foreach ($packagelist['p'] as $package) { + if (!isset($installed[strtolower($package)])) { + continue; } - return false; - } + $inst_version = $reg->packageInfo($package, 'version', $channel); + $inst_state = $reg->packageInfo($package, 'release_state', $channel); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + '/allreleases.xml', false, false, $channel); + PEAR::popErrorHandling(); + if (PEAR::isError($info)) { + continue; // no remote releases + } - if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) { - return $this->_channelInfo['servers']['primary']['attribs']['port']; - } + if (!isset($info['r'])) { + continue; + } - if ($this->getSSL()) { - return 443; - } + $release = $found = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); + } - return 80; - } + // $info['r'] is sorted by version number + usort($info['r'], array($this, '_sortReleasesByVersionNumber')); + foreach ($info['r'] as $release) { + if ($inst_version && version_compare($release['v'], $inst_version, '<=')) { + // not newer than the one installed + break; + } - /** - * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel - */ - function getSSL($mirror = false) - { - if ($mirror) { - if ($mir = $this->getMirror($mirror)) { - if (isset($mir['attribs']['ssl'])) { - return true; + // new version > installed version + if (!$pref_state) { + // every state is a good state + $found = true; + break; + } else { + $new_state = $release['s']; + // if new state >= installed state: go + if (in_array($new_state, $this->betterStates($inst_state, true))) { + $found = true; + break; + } else { + // only allow to lower the state of package, + // if new state >= preferred state: go + if (in_array($new_state, $this->betterStates($pref_state, true))) { + $found = true; + break; + } + } } + } - return false; + if (!$found) { + continue; } - return false; - } + $relinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . + $release['v'] . '.xml', false, false, $channel); + if (PEAR::isError($relinfo)) { + return $relinfo; + } - if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) { - return true; + $ret[$package] = array( + 'version' => $release['v'], + 'state' => $release['s'], + 'filesize' => $relinfo['f'], + ); } - return false; + return $ret; } - /** - * @return string|false - */ - function getSummary() + function packageInfo($base, $package, $channel = false) { - if (isset($this->_channelInfo['summary'])) { - return $this->_channelInfo['summary']; + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $pinfo = $this->_rest->retrieveData($base . 'p/' . strtolower($package) . '/info.xml', false, false, $channel); + if (PEAR::isError($pinfo)) { + PEAR::popErrorHandling(); + return PEAR::raiseError('Unknown package: "' . $package . '" in channel "' . $channel . '"' . "\n". 'Debug: ' . + $pinfo->getMessage()); } - return false; - } - - /** - * @param string protocol type - * @param string Mirror name - * @return array|false - */ - function getFunctions($protocol, $mirror = false) - { - if ($this->getName() == '__uri') { - return false; - } + $releases = array(); + $allreleases = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + '/allreleases.xml', false, false, $channel); + if (!PEAR::isError($allreleases)) { + if (!class_exists('PEAR_PackageFile_v2')) { + require_once 'PEAR/PackageFile/v2.php'; + } - $function = $protocol == 'rest' ? 'baseurl' : 'function'; - if ($mirror) { - if ($mir = $this->getMirror($mirror)) { - if (isset($mir[$protocol][$function])) { - return $mir[$protocol][$function]; - } + if (!is_array($allreleases['r']) || !isset($allreleases['r'][0])) { + $allreleases['r'] = array($allreleases['r']); } - return false; - } + $pf = new PEAR_PackageFile_v2; + foreach ($allreleases['r'] as $release) { + $ds = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/deps.' . + $release['v'] . '.txt', false, false, $channel); + if (PEAR::isError($ds)) { + continue; + } - if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) { - return $this->_channelInfo['servers']['primary'][$protocol][$function]; - } + if (!isset($latest)) { + $latest = $release['v']; + } - return false; - } + $pf->setDeps(unserialize($ds)); + $ds = $pf->getDeps(); + $info = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) + . '/' . $release['v'] . '.xml', false, false, $channel); - /** - * @param string Protocol type - * @param string Function name (null to return the - * first protocol of the type requested) - * @param string Mirror name, if any - * @return array - */ - function getFunction($type, $name = null, $mirror = false) - { - $protocols = $this->getFunctions($type, $mirror); - if (!$protocols) { - return false; - } + if (PEAR::isError($info)) { + continue; + } - foreach ($protocols as $protocol) { - if ($name === null) { - return $protocol; + $releases[$release['v']] = array( + 'doneby' => $info['m'], + 'license' => $info['l'], + 'summary' => $info['s'], + 'description' => $info['d'], + 'releasedate' => $info['da'], + 'releasenotes' => $info['n'], + 'state' => $release['s'], + 'deps' => $ds ? $ds : array(), + ); } + } else { + $latest = ''; + } - if ($protocol['_content'] != $name) { - continue; + PEAR::popErrorHandling(); + if (isset($pinfo['dc']) && isset($pinfo['dp'])) { + if (is_array($pinfo['dp'])) { + $deprecated = array('channel' => (string) $pinfo['dc'], + 'package' => trim($pinfo['dp']['_content'])); + } else { + $deprecated = array('channel' => (string) $pinfo['dc'], + 'package' => trim($pinfo['dp'])); } + } else { + $deprecated = false; + } - return $protocol; + if (!isset($latest)) { + $latest = ''; } - return false; - } + return array( + 'name' => $pinfo['n'], + 'channel' => $pinfo['c'], + 'category' => $pinfo['ca']['_content'], + 'stable' => $latest, + 'license' => $pinfo['l'], + 'summary' => $pinfo['s'], + 'description' => $pinfo['d'], + 'releases' => $releases, + 'deprecated' => $deprecated, + ); + } /** - * @param string protocol type - * @param string protocol name - * @param string version - * @param string mirror name - * @return boolean + * Return an array containing all of the states that are more stable than + * or equal to the passed in state + * + * @param string Release state + * @param boolean Determines whether to include $state in the list + * @return false|array False if $state is not a valid release state */ - function supports($type, $name = null, $mirror = false, $version = '1.0') + function betterStates($state, $include = false) { - $protocols = $this->getFunctions($type, $mirror); - if (!$protocols) { + static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); + $i = array_search($state, $states); + if ($i === false) { return false; } - foreach ($protocols as $protocol) { - if ($protocol['attribs']['version'] != $version) { - continue; - } - - if ($name === null) { - return true; - } - - if ($protocol['_content'] != $name) { - continue; - } - - return true; + if ($include) { + $i--; } - return false; + return array_slice($states, $i + 1); } /** - * Determines whether a channel supports Representational State Transfer (REST) protocols - * for retrieving channel information - * @param string - * @return bool + * Sort releases by version number + * + * @access private */ - function supportsREST($mirror = false) + function _sortReleasesByVersionNumber($a, $b) { - if ($mirror == $this->_channelInfo['name']) { - $mirror = false; + if (version_compare($a['v'], $b['v'], '=')) { + return 0; } - if ($mirror) { - if ($mir = $this->getMirror($mirror)) { - return isset($mir['rest']); - } - - return false; + if (version_compare($a['v'], $b['v'], '>')) { + return -1; } - return isset($this->_channelInfo['servers']['primary']['rest']); + if (version_compare($a['v'], $b['v'], '<')) { + return 1; + } } +}PEAR-1.9.0/PEAR/REST/11.php100664 764 764 26054 100664 7573 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: 11.php 286670 2009-08-02 14:16:06Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.3 + */ + +/** + * For downloading REST xml/txt files + */ +require_once 'PEAR/REST.php'; +/** + * Implement REST 1.1 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.3 + */ +class PEAR_REST_11 +{ /** - * Get the URL to access a base resource. - * - * Hyperlinks in the returned xml will be used to retrieve the proper information - * needed. This allows extreme extensibility and flexibility in implementation - * @param string Resource Type to retrieve + * @var PEAR_REST */ - function getBaseURL($resourceType, $mirror = false) - { - if ($mirror == $this->_channelInfo['name']) { - $mirror = false; - } - - if ($mirror) { - $mir = $this->getMirror($mirror); - if (!$mir) { - return false; - } + var $_rest; - $rest = $mir['rest']; - } else { - $rest = $this->_channelInfo['servers']['primary']['rest']; - } + function PEAR_REST_11($config, $options = array()) + { + $this->_rest = &new PEAR_REST($config, $options); + } - if (!isset($rest['baseurl'][0])) { - $rest['baseurl'] = array($rest['baseurl']); + function listAll($base, $dostable, $basic = true, $searchpackage = false, $searchsummary = false, $channel = false) + { + $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel); + if (PEAR::isError($categorylist)) { + return $categorylist; } - foreach ($rest['baseurl'] as $baseurl) { - if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) { - return $baseurl['_content']; - } + $ret = array(); + if (!is_array($categorylist['c']) || !isset($categorylist['c'][0])) { + $categorylist['c'] = array($categorylist['c']); } - return false; - } - - /** - * Since REST does not implement RPC, provide this as a logical wrapper around - * resetFunctions for REST - * @param string|false mirror name, if any - */ - function resetREST($mirror = false) - { - return $this->resetFunctions('rest', $mirror); - } + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - /** - * Empty all protocol definitions - * @param string protocol type - * @param string|false mirror name, if any - */ - function resetFunctions($type, $mirror = false) - { - if ($mirror) { - if (isset($this->_channelInfo['servers']['mirror'])) { - $mirrors = $this->_channelInfo['servers']['mirror']; - if (!isset($mirrors[0])) { - $mirrors = array($mirrors); - } + foreach ($categorylist['c'] as $progress => $category) { + $category = $category['_content']; + $packagesinfo = $this->_rest->retrieveData($base . + 'c/' . urlencode($category) . '/packagesinfo.xml', false, false, $channel); - foreach ($mirrors as $i => $mir) { - if ($mir['attribs']['host'] == $mirror) { - if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) { - unset($this->_channelInfo['servers']['mirror'][$i][$type]); - } + if (PEAR::isError($packagesinfo)) { + continue; + } - return true; - } - } + if (!is_array($packagesinfo) || !isset($packagesinfo['pi'])) { + continue; + } - return false; + if (!is_array($packagesinfo['pi']) || !isset($packagesinfo['pi'][0])) { + $packagesinfo['pi'] = array($packagesinfo['pi']); } - return false; - } + foreach ($packagesinfo['pi'] as $packageinfo) { + if (empty($packageinfo)) { + continue; + } - if (isset($this->_channelInfo['servers']['primary'][$type])) { - unset($this->_channelInfo['servers']['primary'][$type]); - } + $info = $packageinfo['p']; + $package = $info['n']; + $releases = isset($packageinfo['a']) ? $packageinfo['a'] : false; + unset($latest); + unset($unstable); + unset($stable); + unset($state); - return true; - } + if ($releases) { + if (!isset($releases['r'][0])) { + $releases['r'] = array($releases['r']); + } - /** - * Set a channel's protocols to the protocols supported by pearweb - */ - function setDefaultPEARProtocols($version = '1.0', $mirror = false) - { - switch ($version) { - case '1.0' : - $this->resetREST($mirror); - return true; - break; - default : - return false; - break; - } - } + foreach ($releases['r'] as $release) { + if (!isset($latest)) { + if ($dostable && $release['s'] == 'stable') { + $latest = $release['v']; + $state = 'stable'; + } + if (!$dostable) { + $latest = $release['v']; + $state = $release['s']; + } + } - /** - * @return array - */ - function getMirrors() - { - if (isset($this->_channelInfo['servers']['mirror'])) { - $mirrors = $this->_channelInfo['servers']['mirror']; - if (!isset($mirrors[0])) { - $mirrors = array($mirrors); - } + if (!isset($stable) && $release['s'] == 'stable') { + $stable = $release['v']; + if (!isset($unstable)) { + $unstable = $stable; + } + } - return $mirrors; - } + if (!isset($unstable) && $release['s'] != 'stable') { + $unstable = $release['v']; + $state = $release['s']; + } - return array(); - } + if (isset($latest) && !isset($state)) { + $state = $release['s']; + } - /** - * Get the unserialized XML representing a mirror - * @return array|false - */ - function getMirror($server) - { - foreach ($this->getMirrors() as $mirror) { - if ($mirror['attribs']['host'] == $server) { - return $mirror; - } - } + if (isset($latest) && isset($stable) && isset($unstable)) { + break; + } + } + } - return false; - } + if ($basic) { // remote-list command + if (!isset($latest)) { + $latest = false; + } - /** - * @param string - * @return string|false - * @error PEAR_CHANNELFILE_ERROR_NO_NAME - * @error PEAR_CHANNELFILE_ERROR_INVALID_NAME - */ - function setName($name) - { - return $this->setServer($name); - } + if ($dostable) { + // $state is not set if there are no releases + if (isset($state) && $state == 'stable') { + $ret[$package] = array('stable' => $latest); + } else { + $ret[$package] = array('stable' => '-n/a-'); + } + } else { + $ret[$package] = array('stable' => $latest); + } - /** - * Set the socket number (port) that is used to connect to this channel - * @param integer - * @param string|false name of the mirror server, or false for the primary - */ - function setPort($port, $mirror = false) - { - if ($mirror) { - if (!isset($this->_channelInfo['servers']['mirror'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, - array('mirror' => $mirror)); - return false; - } + continue; + } - if (isset($this->_channelInfo['servers']['mirror'][0])) { - foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { - if ($mirror == $mir['attribs']['host']) { - $this->_channelInfo['servers']['mirror'][$i]['attribs']['port'] = $port; - return true; + // list-all command + if (!isset($unstable)) { + $unstable = false; + $state = 'stable'; + if (isset($stable)) { + $latest = $unstable = $stable; } + } else { + $latest = $unstable; } - return false; - } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { - $this->_channelInfo['servers']['mirror']['attribs']['port'] = $port; - $this->_isValid = false; - return true; - } - } + if (!isset($latest)) { + $latest = false; + } - $this->_channelInfo['servers']['primary']['attribs']['port'] = $port; - $this->_isValid = false; - return true; - } + $deps = array(); + if ($latest && isset($packageinfo['deps'])) { + if (!is_array($packageinfo['deps']) || + !isset($packageinfo['deps'][0]) + ) { + $packageinfo['deps'] = array($packageinfo['deps']); + } - /** - * Set the socket number (port) that is used to connect to this channel - * @param bool Determines whether to turn on SSL support or turn it off - * @param string|false name of the mirror server, or false for the primary - */ - function setSSL($ssl = true, $mirror = false) - { - if ($mirror) { - if (!isset($this->_channelInfo['servers']['mirror'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, - array('mirror' => $mirror)); - return false; - } + $d = false; + foreach ($packageinfo['deps'] as $dep) { + if ($dep['v'] == $latest) { + $d = unserialize($dep['d']); + } + } - if (isset($this->_channelInfo['servers']['mirror'][0])) { - foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { - if ($mirror == $mir['attribs']['host']) { - if (!$ssl) { - if (isset($this->_channelInfo['servers']['mirror'][$i] - ['attribs']['ssl'])) { - unset($this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl']); + if ($d) { + if (isset($d['required'])) { + if (!class_exists('PEAR_PackageFile_v2')) { + require_once 'PEAR/PackageFile/v2.php'; + } + + if (!isset($pf)) { + $pf = new PEAR_PackageFile_v2; } + + $pf->setDeps($d); + $tdeps = $pf->getDeps(); } else { - $this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes'; + $tdeps = $d; } - return true; - } - } + foreach ($tdeps as $dep) { + if ($dep['type'] !== 'pkg') { + continue; + } - return false; - } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { - if (!$ssl) { - if (isset($this->_channelInfo['servers']['mirror']['attribs']['ssl'])) { - unset($this->_channelInfo['servers']['mirror']['attribs']['ssl']); + $deps[] = $dep; + } } - } else { - $this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes'; } - $this->_isValid = false; - return true; - } - } - - if ($ssl) { - $this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes'; - } else { - if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) { - unset($this->_channelInfo['servers']['primary']['attribs']['ssl']); + $info = array( + 'stable' => $latest, + 'summary' => $info['s'], + 'description' => $info['d'], + 'deps' => $deps, + 'category' => $info['ca']['_content'], + 'unstable' => $unstable, + 'state' => $state + ); + $ret[$package] = $info; } } - $this->_isValid = false; - return true; + PEAR::popErrorHandling(); + return $ret; } /** - * @param string - * @return string|false - * @error PEAR_CHANNELFILE_ERROR_NO_SERVER - * @error PEAR_CHANNELFILE_ERROR_INVALID_SERVER + * List all categories of a REST server + * + * @param string $base base URL of the server + * @return array of categorynames */ - function setServer($server, $mirror = false) + function listCategories($base, $channel = false) { - if (empty($server)) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SERVER); - return false; - } elseif (!$this->validChannelServer($server)) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, - array('tag' => 'name', 'name' => $server)); - return false; + $categorylist = $this->_rest->retrieveData($base . 'c/categories.xml', false, false, $channel); + if (PEAR::isError($categorylist)) { + return $categorylist; } - if ($mirror) { - $found = false; - foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { - if ($mirror == $mir['attribs']['host']) { - $found = true; - break; - } - } - - if (!$found) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, - array('mirror' => $mirror)); - return false; - } + if (!is_array($categorylist) || !isset($categorylist['c'])) { + return array(); + } - $this->_channelInfo['mirror'][$i]['attribs']['host'] = $server; - return true; + if (isset($categorylist['c']['_content'])) { + // only 1 category + $categorylist['c'] = array($categorylist['c']); } - $this->_channelInfo['name'] = $server; - return true; + return $categorylist['c']; } /** - * @param string - * @return boolean success - * @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY - * @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY + * List packages in a category of a REST server + * + * @param string $base base URL of the server + * @param string $category name of the category + * @param boolean $info also download full package info + * @return array of packagenames */ - function setSummary($summary) + function listCategory($base, $category, $info = false, $channel = false) { - if (empty($summary)) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY); - return false; - } elseif (strpos(trim($summary), "\n") !== false) { - $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY, - array('summary' => $summary)); + if ($info == false) { + $url = '%s'.'c/%s/packages.xml'; + } else { + $url = '%s'.'c/%s/packagesinfo.xml'; } + $url = sprintf($url, + $base, + urlencode($category)); - $this->_channelInfo['summary'] = $summary; - return true; - } + // gives '404 Not Found' error when category doesn't exist + $packagelist = $this->_rest->retrieveData($url, false, false, $channel); + if (PEAR::isError($packagelist)) { + return $packagelist; + } + if (!is_array($packagelist)) { + return array(); + } - /** - * @param string - * @param boolean determines whether the alias is in channel.xml or local - * @return boolean success - */ - function setAlias($alias, $local = false) - { - if (!$this->validChannelServer($alias)) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, - array('tag' => 'suggestedalias', 'name' => $alias)); - return false; + if ($info == false) { + if (!isset($packagelist['p'])) { + return array(); + } + if (!is_array($packagelist['p']) || + !isset($packagelist['p'][0])) { // only 1 pkg + $packagelist = array($packagelist['p']); + } else { + $packagelist = $packagelist['p']; + } + return $packagelist; } - if ($local) { - $this->_channelInfo['localalias'] = $alias; + // info == true + if (!isset($packagelist['pi'])) { + return array(); + } + + if (!is_array($packagelist['pi']) || + !isset($packagelist['pi'][0])) { // only 1 pkg + $packagelist_pre = array($packagelist['pi']); } else { - $this->_channelInfo['suggestedalias'] = $alias; + $packagelist_pre = $packagelist['pi']; } - return true; + $packagelist = array(); + foreach ($packagelist_pre as $i => $item) { + // compatibility with r/.xml + if (isset($item['a']['r'][0])) { + // multiple releases + $item['p']['v'] = $item['a']['r'][0]['v']; + $item['p']['st'] = $item['a']['r'][0]['s']; + } elseif (isset($item['a'])) { + // first and only release + $item['p']['v'] = $item['a']['r']['v']; + $item['p']['st'] = $item['a']['r']['s']; + } + + $packagelist[$i] = array('attribs' => $item['p']['r'], + '_content' => $item['p']['n'], + 'info' => $item['p']); + } + + return $packagelist; } /** - * @return string + * Return an array containing all of the states that are more stable than + * or equal to the passed in state + * + * @param string Release state + * @param boolean Determines whether to include $state in the list + * @return false|array False if $state is not a valid release state */ - function getAlias() + function betterStates($state, $include = false) { - if (isset($this->_channelInfo['localalias'])) { - return $this->_channelInfo['localalias']; - } - if (isset($this->_channelInfo['suggestedalias'])) { - return $this->_channelInfo['suggestedalias']; + static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); + $i = array_search($state, $states); + if ($i === false) { + return false; } - if (isset($this->_channelInfo['name'])) { - return $this->_channelInfo['name']; + if ($include) { + $i--; } - return ''; + return array_slice($states, $i + 1); } +} +?>PEAR-1.9.0/PEAR/REST/13.php100664 764 764 26544 100664 7601 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: 13.php 287110 2009-08-11 18:51:15Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a12 + */ + +/** + * For downloading REST xml/txt files + */ +require_once 'PEAR/REST.php'; +require_once 'PEAR/REST/10.php'; +/** + * Implement REST 1.3 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a12 + */ +class PEAR_REST_13 extends PEAR_REST_10 +{ /** - * Set the package validation object if it differs from PEAR's default - * The class must be includeable via changing _ in the classname to path separator, - * but no checking of this is made. - * @param string|false pass in false to reset to the default packagename regex - * @return boolean success + * Retrieve information about a remote package to be downloaded from a REST server + * + * This is smart enough to resolve the minimum PHP version dependency prior to download + * @param string $base The uri to prepend to all REST calls + * @param array $packageinfo an array of format: + *
    +     *  array(
    +     *   'package' => 'packagename',
    +     *   'channel' => 'channelname',
    +     *  ['state' => 'alpha' (or valid state),]
    +     *  -or-
    +     *  ['version' => '1.whatever']
    +     * 
    + * @param string $prefstate Current preferred_state config variable value + * @param bool $installed the installed version of this package to compare against + * @return array|false|PEAR_Error see {@link _returnDownloadURL()} */ - function setValidationPackage($validateclass, $version) + function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false) { - if (empty($validateclass)) { - unset($this->_channelInfo['validatepackage']); + $states = $this->betterStates($prefstate, true); + if (!$states) { + return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } - $this->_channelInfo['validatepackage'] = array('_content' => $validateclass); - $this->_channelInfo['validatepackage']['attribs'] = array('version' => $version); - } - /** - * Add a protocol to the provides section - * @param string protocol type - * @param string protocol version - * @param string protocol name, if any - * @param string mirror name, if this is a mirror's protocol - * @return bool - */ - function addFunction($type, $version, $name = '', $mirror = false) - { - if ($mirror) { - return $this->addMirrorFunction($mirror, $type, $version, $name); + $channel = $packageinfo['channel']; + $package = $packageinfo['package']; + $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; + $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases2.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); + if (PEAR::isError($info)) { + return PEAR::raiseError('No releases available for package "' . + $channel . '/' . $package . '"'); } - $set = array('attribs' => array('version' => $version), '_content' => $name); - if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) { - if (!isset($this->_channelInfo['servers'])) { - $this->_channelInfo['servers'] = array('primary' => - array($type => array())); - } elseif (!isset($this->_channelInfo['servers']['primary'])) { - $this->_channelInfo['servers']['primary'] = array($type => array()); - } + if (!isset($info['r'])) { + return false; + } - $this->_channelInfo['servers']['primary'][$type]['function'] = $set; - $this->_isValid = false; - return true; - } elseif (!isset($this->_channelInfo['servers']['primary'][$type]['function'][0])) { - $this->_channelInfo['servers']['primary'][$type]['function'] = array( - $this->_channelInfo['servers']['primary'][$type]['function']); + $release = $found = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); } - $this->_channelInfo['servers']['primary'][$type]['function'][] = $set; - return true; - } - /** - * Add a protocol to a mirror's provides section - * @param string mirror name (server) - * @param string protocol type - * @param string protocol version - * @param string protocol name, if any - */ - function addMirrorFunction($mirror, $type, $version, $name = '') - { - if (!isset($this->_channelInfo['servers']['mirror'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, - array('mirror' => $mirror)); - return false; - } + $skippedphp = false; + foreach ($info['r'] as $release) { + if (!isset($this->_rest->_options['force']) && ($installed && + version_compare($release['v'], $installed, '<'))) { + continue; + } - $setmirror = false; - if (isset($this->_channelInfo['servers']['mirror'][0])) { - foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { - if ($mirror == $mir['attribs']['host']) { - $setmirror = &$this->_channelInfo['servers']['mirror'][$i]; + if (isset($state)) { + // try our preferred state first + if ($release['s'] == $state) { + if (!isset($version) && version_compare($release['m'], phpversion(), '>')) { + // skip releases that require a PHP version newer than our PHP version + $skippedphp = $release; + continue; + } + $found = true; break; } - } - } else { - if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { - $setmirror = &$this->_channelInfo['servers']['mirror']; - } - } - - if (!$setmirror) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, - array('mirror' => $mirror)); - return false; - } - - $set = array('attribs' => array('version' => $version), '_content' => $name); - if (!isset($setmirror[$type]['function'])) { - $setmirror[$type]['function'] = $set; - $this->_isValid = false; - return true; - } elseif (!isset($setmirror[$type]['function'][0])) { - $setmirror[$type]['function'] = array($setmirror[$type]['function']); - } - - $setmirror[$type]['function'][] = $set; - $this->_isValid = false; - return true; - } - - /** - * @param string Resource Type this url links to - * @param string URL - * @param string|false mirror name, if this is not a primary server REST base URL - */ - function setBaseURL($resourceType, $url, $mirror = false) - { - if ($mirror) { - if (!isset($this->_channelInfo['servers']['mirror'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, - array('mirror' => $mirror)); - return false; - } - $setmirror = false; - if (isset($this->_channelInfo['servers']['mirror'][0])) { - foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { - if ($mirror == $mir['attribs']['host']) { - $setmirror = &$this->_channelInfo['servers']['mirror'][$i]; - break; + // see if there is something newer and more stable + // bug #7221 + if (in_array($release['s'], $this->betterStates($state), true)) { + if (!isset($version) && version_compare($release['m'], phpversion(), '>')) { + // skip releases that require a PHP version newer than our PHP version + $skippedphp = $release; + continue; } + $found = true; + break; + } + } elseif (isset($version)) { + if ($release['v'] == $version) { + if (!isset($this->_rest->_options['force']) && + !isset($version) && + version_compare($release['m'], phpversion(), '>')) { + // skip releases that require a PHP version newer than our PHP version + $skippedphp = $release; + continue; + } + $found = true; + break; } } else { - if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { - $setmirror = &$this->_channelInfo['servers']['mirror']; + if (in_array($release['s'], $states)) { + if (version_compare($release['m'], phpversion(), '>')) { + // skip releases that require a PHP version newer than our PHP version + $skippedphp = $release; + continue; + } + $found = true; + break; } } - } else { - $setmirror = &$this->_channelInfo['servers']['primary']; } - $set = array('attribs' => array('type' => $resourceType), '_content' => $url); - if (!isset($setmirror['rest'])) { - $setmirror['rest'] = array(); + if (!$found && $skippedphp) { + $found = null; } - if (!isset($setmirror['rest']['baseurl'])) { - $setmirror['rest']['baseurl'] = $set; - $this->_isValid = false; - return true; - } elseif (!isset($setmirror['rest']['baseurl'][0])) { - $setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']); - } + return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel); + } - foreach ($setmirror['rest']['baseurl'] as $i => $url) { - if ($url['attribs']['type'] == $resourceType) { - $this->_isValid = false; - $setmirror['rest']['baseurl'][$i] = $set; - return true; - } + function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage, + $prefstate = 'stable', $installed = false, $channel = false) + { + $states = $this->betterStates($prefstate, true); + if (!$states) { + return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } - $setmirror['rest']['baseurl'][] = $set; - $this->_isValid = false; - return true; - } + $channel = $dependency['channel']; + $package = $dependency['name']; + $state = isset($dependency['state']) ? $dependency['state'] : null; + $version = isset($dependency['version']) ? $dependency['version'] : null; + $restFile = $base . 'r/' . strtolower($package) .'/allreleases2.xml'; - /** - * @param string mirror server - * @param int mirror http port - * @return boolean - */ - function addMirror($server, $port = null) - { - if ($this->_channelInfo['name'] == '__uri') { - return false; // the __uri channel cannot have mirrors by definition + $info = $this->_rest->retrieveData($restFile, false, false, $channel); + if (PEAR::isError($info)) { + return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package'] + . '" dependency "' . $channel . '/' . $package . '" has no releases'); } - $set = array('attribs' => array('host' => $server)); - if (is_numeric($port)) { - $set['attribs']['port'] = $port; + if (!is_array($info) || !isset($info['r'])) { + return false; } - if (!isset($this->_channelInfo['servers']['mirror'])) { - $this->_channelInfo['servers']['mirror'] = $set; - return true; + $exclude = array(); + $min = $max = $recommended = false; + if ($xsdversion == '1.0') { + $pinfo['package'] = $dependency['name']; + $pinfo['channel'] = 'pear.php.net'; // this is always true - don't change this + switch ($dependency['rel']) { + case 'ge' : + $min = $dependency['version']; + break; + case 'gt' : + $min = $dependency['version']; + $exclude = array($dependency['version']); + break; + case 'eq' : + $recommended = $dependency['version']; + break; + case 'lt' : + $max = $dependency['version']; + $exclude = array($dependency['version']); + break; + case 'le' : + $max = $dependency['version']; + break; + case 'ne' : + $exclude = array($dependency['version']); + break; + } + } else { + $pinfo['package'] = $dependency['name']; + $min = isset($dependency['min']) ? $dependency['min'] : false; + $max = isset($dependency['max']) ? $dependency['max'] : false; + $recommended = isset($dependency['recommended']) ? + $dependency['recommended'] : false; + if (isset($dependency['exclude'])) { + if (!isset($dependency['exclude'][0])) { + $exclude = array($dependency['exclude']); + } + } } - if (!isset($this->_channelInfo['servers']['mirror'][0])) { - $this->_channelInfo['servers']['mirror'] = - array($this->_channelInfo['servers']['mirror']); + $skippedphp = $found = $release = false; + if (!is_array($info['r']) || !isset($info['r'][0])) { + $info['r'] = array($info['r']); } - $this->_channelInfo['servers']['mirror'][] = $set; - return true; - } + foreach ($info['r'] as $release) { + if (!isset($this->_rest->_options['force']) && ($installed && + version_compare($release['v'], $installed, '<'))) { + continue; + } - /** - * Retrieve the name of the validation package for this channel - * @return string|false - */ - function getValidationPackage() - { - if (!$this->_isValid && !$this->validate()) { - return false; - } + if (in_array($release['v'], $exclude)) { // skip excluded versions + continue; + } - if (!isset($this->_channelInfo['validatepackage'])) { - return array('attribs' => array('version' => 'default'), - '_content' => 'PEAR_Validate'); - } + // allow newer releases to say "I'm OK with the dependent package" + if ($xsdversion == '2.0' && isset($release['co'])) { + if (!is_array($release['co']) || !isset($release['co'][0])) { + $release['co'] = array($release['co']); + } - return $this->_channelInfo['validatepackage']; - } + foreach ($release['co'] as $entry) { + if (isset($entry['x']) && !is_array($entry['x'])) { + $entry['x'] = array($entry['x']); + } elseif (!isset($entry['x'])) { + $entry['x'] = array(); + } - /** - * Retrieve the object that can be used for custom validation - * @param string|false the name of the package to validate. If the package is - * the channel validation package, PEAR_Validate is returned - * @return PEAR_Validate|false false is returned if the validation package - * cannot be located - */ - function &getValidationObject($package = false) - { - if (!class_exists('PEAR_Validate')) { - require_once 'PEAR/Validate.php'; - } + if ($entry['c'] == $deppackage['channel'] && + strtolower($entry['p']) == strtolower($deppackage['package']) && + version_compare($deppackage['version'], $entry['min'], '>=') && + version_compare($deppackage['version'], $entry['max'], '<=') && + !in_array($release['v'], $entry['x'])) { + if (version_compare($release['m'], phpversion(), '>')) { + // skip dependency releases that require a PHP version + // newer than our PHP version + $skippedphp = $release; + continue; + } - if (!$this->_isValid) { - if (!$this->validate()) { - $a = false; - return $a; + $recommended = $release['v']; + break; + } + } } - } - if (isset($this->_channelInfo['validatepackage'])) { - if ($package == $this->_channelInfo['validatepackage']) { - // channel validation packages are always validated by PEAR_Validate - $val = &new PEAR_Validate; - return $val; - } + if ($recommended) { + if ($release['v'] != $recommended) { // if we want a specific + // version, then skip all others + continue; + } - if (!class_exists(str_replace('.', '_', - $this->_channelInfo['validatepackage']['_content']))) { - if ($this->isIncludeable(str_replace('_', '/', - $this->_channelInfo['validatepackage']['_content']) . '.php')) { - include_once str_replace('_', '/', - $this->_channelInfo['validatepackage']['_content']) . '.php'; - $vclass = str_replace('.', '_', - $this->_channelInfo['validatepackage']['_content']); - $val = &new $vclass; - } else { - $a = false; - return $a; + if (!in_array($release['s'], $states)) { + // the stability is too low, but we must return the + // recommended version if possible + return $this->_returnDownloadURL($base, $package, $release, $info, true, false, $channel); } - } else { - $vclass = str_replace('.', '_', - $this->_channelInfo['validatepackage']['_content']); - $val = &new $vclass; } - } else { - $val = &new PEAR_Validate; - } - return $val; - } + if ($min && version_compare($release['v'], $min, 'lt')) { // skip too old versions + continue; + } - function isIncludeable($path) - { - $possibilities = explode(PATH_SEPARATOR, ini_get('include_path')); - foreach ($possibilities as $dir) { - if (file_exists($dir . DIRECTORY_SEPARATOR . $path) - && is_readable($dir . DIRECTORY_SEPARATOR . $path)) { - return true; + if ($max && version_compare($release['v'], $max, 'gt')) { // skip too new versions + continue; } - } - return false; - } + if ($installed && version_compare($release['v'], $installed, '<')) { + continue; + } - /** - * This function is used by the channel updater and retrieves a value set by - * the registry, or the current time if it has not been set - * @return string - */ - function lastModified() - { - if (isset($this->_channelInfo['_lastmodified'])) { - return $this->_channelInfo['_lastmodified']; + if (in_array($release['s'], $states)) { // if in the preferred state... + if (version_compare($release['m'], phpversion(), '>')) { + // skip dependency releases that require a PHP version + // newer than our PHP version + $skippedphp = $release; + continue; + } + + $found = true; // ... then use it + break; + } } - return time(); + if (!$found && $skippedphp) { + $found = null; + } + + return $this->_returnDownloadURL($base, $package, $release, $info, $found, $skippedphp, $channel); } -}PEAR-1.8.0/PEAR/Command.php100664 764 764 30707 100664 10152 - read/write version * * PHP versions 4 and 5 * * @category pear * @package PEAR - * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Command.php,v 1.41 2009/02/24 23:38:22 dufuz Exp $ + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ - -/** - * Needed for error handling - */ -require_once 'PEAR.php'; -require_once 'PEAR/Frontend.php'; -require_once 'PEAR/XMLParser.php'; - -/** - * List of commands and what classes they are implemented in. - * @var array command => implementing class - */ -$GLOBALS['_PEAR_Command_commandlist'] = array(); - -/** - * List of commands and their descriptions - * @var array command => description - */ -$GLOBALS['_PEAR_Command_commanddesc'] = array(); - -/** - * List of shortcuts to common commands. - * @var array shortcut => command + * @since File available since Release 1.4.0a10 */ -$GLOBALS['_PEAR_Command_shortcuts'] = array(); - /** - * Array of command objects - * @var array class => object + * Base class */ -$GLOBALS['_PEAR_Command_objects'] = array(); - +require_once 'PEAR/Task/Postinstallscript.php'; /** - * PEAR command class, a simple factory class for administrative - * commands. - * - * How to implement command classes: - * - * - The class must be called PEAR_Command_Nnn, installed in the - * "PEAR/Common" subdir, with a method called getCommands() that - * returns an array of the commands implemented by the class (see - * PEAR/Command/Install.php for an example). - * - * - The class must implement a run() function that is called with three - * params: - * - * (string) command name - * (array) assoc array with options, freely defined by each - * command, for example: - * array('force' => true) - * (array) list of the other parameters - * - * The run() function returns a PEAR_CommandResponse object. Use - * these methods to get information: - * - * int getStatus() Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL) - * *_PARTIAL means that you need to issue at least - * one more command to complete the operation - * (used for example for validation steps). - * - * string getMessage() Returns a message for the user. Remember, - * no HTML or other interface-specific markup. - * - * If something unexpected happens, run() returns a PEAR error. - * - * - DON'T OUTPUT ANYTHING! Return text for output instead. - * - * - DON'T USE HTML! The text you return will be used from both Gtk, - * web and command-line interfaces, so for now, keep everything to - * plain text. - * - * - DON'T USE EXIT OR DIE! Always use pear errors. From static - * classes do PEAR::raiseError(), from other classes do - * $this->raiseError(). + * Abstracts the postinstallscript file task xml. * @category pear * @package PEAR - * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 + * @since Class available since Release 1.4.0a10 */ -class PEAR_Command +class PEAR_Task_Postinstallscript_rw extends PEAR_Task_Postinstallscript { - // {{{ factory() - /** - * Get the right object for executing a command. - * - * @param string $command The name of the command - * @param object $config Instance of PEAR_Config object + * parent package file object * - * @return object the command object or a PEAR error + * @var PEAR_PackageFile_v2_rw + */ + var $_pkg; + /** + * Enter description here... * - * @access public - * @static + * @param PEAR_PackageFile_v2_rw $pkg + * @param PEAR_Config $config + * @param PEAR_Frontend $logger + * @param array $fileXml + * @return PEAR_Task_Postinstallscript_rw */ - function &factory($command, &$config) + function PEAR_Task_Postinstallscript_rw(&$pkg, &$config, &$logger, $fileXml) { - if (empty($GLOBALS['_PEAR_Command_commandlist'])) { - PEAR_Command::registerCommands(); - } - if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { - $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; - } - if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { - $a = PEAR::raiseError("unknown command `$command'"); - return $a; - } - $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; - if (!class_exists($class)) { - require_once $GLOBALS['_PEAR_Command_objects'][$class]; - } - if (!class_exists($class)) { - $a = PEAR::raiseError("unknown command `$command'"); - return $a; - } - $ui =& PEAR_Command::getFrontendObject(); - $obj = &new $class($ui, $config); - return $obj; + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); } - // }}} - // {{{ & getObject() - function &getObject($command) + function validate() { - $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; - if (!class_exists($class)) { - require_once $GLOBALS['_PEAR_Command_objects'][$class]; - } - if (!class_exists($class)) { - return PEAR::raiseError("unknown command `$command'"); - } - $ui =& PEAR_Command::getFrontendObject(); - $config = &PEAR_Config::singleton(); - $obj = &new $class($ui, $config); - return $obj; + return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents); } - // }}} - // {{{ & getFrontendObject() + function getName() + { + return 'postinstallscript'; + } /** - * Get instance of frontend object. + * add a simple to the post-install script * - * @return object|PEAR_Error - * @static + * Order is significant, so call this method in the same + * sequence the users should see the paramgroups. The $params + * parameter should either be the result of a call to {@link getParam()} + * or an array of calls to getParam(). + * + * Use {@link addConditionTypeGroup()} to add a containing + * a tag + * @param string $id id as seen by the script + * @param array|false $params array of getParam() calls, or false for no params + * @param string|false $instructions */ - function &getFrontendObject() + function addParamGroup($id, $params = false, $instructions = false) { - $a = &PEAR_Frontend::singleton(); - return $a; + if ($params && isset($params[0]) && !isset($params[1])) { + $params = $params[0]; + } + $stuff = + array( + $this->_pkg->getTasksNs() . ':id' => $id, + ); + if ($instructions) { + $stuff[$this->_pkg->getTasksNs() . ':instructions'] = $instructions; + } + if ($params) { + $stuff[$this->_pkg->getTasksNs() . ':param'] = $params; + } + $this->_params[$this->_pkg->getTasksNs() . ':paramgroup'][] = $stuff; } - // }}} - // {{{ & setFrontendClass() - /** - * Load current frontend class. + * add a complex to the post-install script with conditions * - * @param string $uiclass Name of class implementing the frontend + * This inserts a with * - * @return object the frontend object, or a PEAR error - * @static - */ - function &setFrontendClass($uiclass) - { - $a = &PEAR_Frontend::setFrontendClass($uiclass); - return $a; - } - - // }}} - // {{{ setFrontendType() - - /** - * Set current frontend. - * - * @param string $uitype Name of the frontend type (for example "CLI") - * - * @return object the frontend object, or a PEAR error - * @static - */ - function setFrontendType($uitype) - { - $uiclass = 'PEAR_Frontend_' . $uitype; - return PEAR_Command::setFrontendClass($uiclass); - } - - // }}} - // {{{ registerCommands() - - /** - * Scan through the Command directory looking for classes - * and see what commands they implement. - * - * @param bool (optional) if FALSE (default), the new list of - * commands should replace the current one. If TRUE, - * new entries will be merged with old. - * - * @param string (optional) where (what directory) to look for - * classes, defaults to the Command subdirectory of - * the directory from where this file (__FILE__) is - * included. + * Order is significant, so call this method in the same + * sequence the users should see the paramgroups. The $params + * parameter should either be the result of a call to {@link getParam()} + * or an array of calls to getParam(). * - * @return bool TRUE on success, a PEAR error on failure + * Use {@link addParamGroup()} to add a simple * - * @access public - * @static + * @param string $id id as seen by the script + * @param string $oldgroup id of the section referenced by + * + * @param string $param name of the from the older section referenced + * by + * @param string $value value to match of the parameter + * @param string $conditiontype one of '=', '!=', 'preg_match' + * @param array|false $params array of getParam() calls, or false for no params + * @param string|false $instructions */ - function registerCommands($merge = false, $dir = null) + function addConditionTypeGroup($id, $oldgroup, $param, $value, $conditiontype = '=', + $params = false, $instructions = false) { - $parser = new PEAR_XMLParser; - if ($dir === null) { - $dir = dirname(__FILE__) . '/Command'; - } - if (!is_dir($dir)) { - return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory"); - } - $dp = @opendir($dir); - if (empty($dp)) { - return PEAR::raiseError("registerCommands: opendir($dir) failed"); + if ($params && isset($params[0]) && !isset($params[1])) { + $params = $params[0]; } - if (!$merge) { - $GLOBALS['_PEAR_Command_commandlist'] = array(); + $stuff = array( + $this->_pkg->getTasksNs() . ':id' => $id, + ); + if ($instructions) { + $stuff[$this->_pkg->getTasksNs() . ':instructions'] = $instructions; } - while ($entry = readdir($dp)) { - if ($entry{0} == '.' || substr($entry, -4) != '.xml') { - continue; - } - $class = "PEAR_Command_".substr($entry, 0, -4); - $file = "$dir/$entry"; - $parser->parse(file_get_contents($file)); - $implements = $parser->getData(); - // List of commands - if (empty($GLOBALS['_PEAR_Command_objects'][$class])) { - $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . substr($entry, 0, -4) . - '.php'; - } - foreach ($implements as $command => $desc) { - if ($command == 'attribs') { - continue; - } - if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { - return PEAR::raiseError('Command "' . $command . '" already registered in ' . - 'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); - } - $GLOBALS['_PEAR_Command_commandlist'][$command] = $class; - $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary']; - if (isset($desc['shortcut'])) { - $shortcut = $desc['shortcut']; - if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) { - return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' . - 'registered to command "' . $command . '" in class "' . - $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); - } - $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command; - } - if (isset($desc['options']) && $desc['options']) { - foreach ($desc['options'] as $oname => $option) { - if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) { - return PEAR::raiseError('Option "' . $oname . '" short option "' . - $option['shortopt'] . '" must be ' . - 'only 1 character in Command "' . $command . '" in class "' . - $class . '"'); - } - } - } - } + $stuff[$this->_pkg->getTasksNs() . ':name'] = $oldgroup . '::' . $param; + $stuff[$this->_pkg->getTasksNs() . ':conditiontype'] = $conditiontype; + $stuff[$this->_pkg->getTasksNs() . ':value'] = $value; + if ($params) { + $stuff[$this->_pkg->getTasksNs() . ':param'] = $params; } - ksort($GLOBALS['_PEAR_Command_shortcuts']); - ksort($GLOBALS['_PEAR_Command_commandlist']); - @closedir($dp); - return true; + $this->_params[$this->_pkg->getTasksNs() . ':paramgroup'][] = $stuff; } - // }}} - // {{{ getCommands() - - /** - * Get the list of currently supported commands, and what - * classes implement them. - * - * @return array command => implementing class - * - * @access public - * @static - */ - function getCommands() + function getXml() { - if (empty($GLOBALS['_PEAR_Command_commandlist'])) { - PEAR_Command::registerCommands(); - } - return $GLOBALS['_PEAR_Command_commandlist']; + return $this->_params; } - // }}} - // {{{ getShortcuts() - /** - * Get the list of command shortcuts. - * - * @return array shortcut => command - * - * @access public + * Use to set up a param tag for use in creating a paramgroup * @static */ - function getShortcuts() + function getParam($name, $prompt, $type = 'string', $default = null) { - if (empty($GLOBALS['_PEAR_Command_shortcuts'])) { - PEAR_Command::registerCommands(); + if ($default !== null) { + return + array( + $this->_pkg->getTasksNs() . ':name' => $name, + $this->_pkg->getTasksNs() . ':prompt' => $prompt, + $this->_pkg->getTasksNs() . ':type' => $type, + $this->_pkg->getTasksNs() . ':default' => $default + ); } - return $GLOBALS['_PEAR_Command_shortcuts']; + return + array( + $this->_pkg->getTasksNs() . ':name' => $name, + $this->_pkg->getTasksNs() . ':prompt' => $prompt, + $this->_pkg->getTasksNs() . ':type' => $type, + ); } - - // }}} - // {{{ getGetoptArgs() - - /** - * Compiles arguments for getopt. - * - * @param string $command command to get optstring for - * @param string $short_args (reference) short getopt format - * @param array $long_args (reference) long getopt format - * - * @return void - * - * @access public - * @static - */ - function getGetoptArgs($command, &$short_args, &$long_args) +} +?>PEAR-1.9.0/PEAR/Task/Replace/rw.php100664 764 764 3115 100664 11453 - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Replace.php'; +/** + * Abstracts the replace task xml. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Replace_rw extends PEAR_Task_Replace +{ + function PEAR_Task_Replace_rw(&$pkg, &$config, &$logger, $fileXml) { - if (empty($GLOBALS['_PEAR_Command_commandlist'])) { - PEAR_Command::registerCommands(); - } - if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { - $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; - } - if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { - return null; - } - $obj = &PEAR_Command::getObject($command); - return $obj->getGetoptArgs($command, $short_args, $long_args); + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); } - // }}} - // {{{ getDescription() + function validate() + { + return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents); + } - /** - * Get description for a command. - * - * @param string $command Name of the command - * - * @return string command description - * - * @access public - * @static - */ - function getDescription($command) + function setInfo($from, $to, $type) { - if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) { - return null; - } - return $GLOBALS['_PEAR_Command_commanddesc'][$command]; + $this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type)); } - // }}} - // {{{ getHelp() + function getName() + { + return 'replace'; + } - /** - * Get help for command. - * - * @param string $command Name of the command to return help for - * - * @access public - * @static - */ - function getHelp($command) + function getXml() { - $cmds = PEAR_Command::getCommands(); - if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { - $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; - } - if (isset($cmds[$command])) { - $obj = &PEAR_Command::getObject($command); - return $obj->getHelp($command); - } - return false; + return $this->_params; } - // }}} -}PEAR-1.8.0/PEAR/Common.php100664 764 764 63661 100664 10031 PEAR-1.9.0/PEAR/Task/Unixeol/rw.php100664 764 764 2535 100664 11530 - read/write version * * PHP versions 4 and 5 * * @category pear * @package PEAR - * @author Stig Bakken - * @author Tomas V. V. Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.168 2009/03/27 19:35:47 dufuz Exp $ + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1.0 - * @deprecated File deprecated since Release 1.4.0a1 + * @since File available since Release 1.4.0a10 */ - /** - * Include error handling + * Base class */ -require_once 'PEAR.php'; - +require_once 'PEAR/Task/Unixeol.php'; /** - * PEAR_Common error when an invalid PHP file is passed to PEAR_Common::analyzeSourceCode() + * Abstracts the unixeol task xml. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 */ -define('PEAR_COMMON_ERROR_INVALIDPHP', 1); -define('_PEAR_COMMON_PACKAGE_NAME_PREG', '[A-Za-z][a-zA-Z0-9_]+'); -define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/'); - -// this should allow: 1, 1.0, 1.0RC1, 1.0dev, 1.0dev123234234234, 1.0a1, 1.0b1, 1.0pl1 -define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?'); -define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '\\z/i'); - -// XXX far from perfect :-) -define('_PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '(' . _PEAR_COMMON_PACKAGE_NAME_PREG . - ')(-([.0-9a-zA-Z]+))?'); -define('PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_PACKAGE_DOWNLOAD_PREG . - '\\z/'); - -define('_PEAR_CHANNELS_NAME_PREG', '[A-Za-z][a-zA-Z0-9\.]+'); -define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '\\z/'); - -// this should allow any dns or IP address, plus a path - NO UNDERSCORES ALLOWED -define('_PEAR_CHANNELS_SERVER_PREG', '[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*(\/[a-zA-Z0-9\-]+)*'); -define('PEAR_CHANNELS_SERVER_PREG', '/^' . _PEAR_CHANNELS_SERVER_PREG . '\\z/i'); - -define('_PEAR_CHANNELS_PACKAGE_PREG', '(' ._PEAR_CHANNELS_SERVER_PREG . ')\/(' - . _PEAR_COMMON_PACKAGE_NAME_PREG . ')'); -define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '\\z/i'); - -define('_PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '(' . _PEAR_CHANNELS_NAME_PREG . ')::(' - . _PEAR_COMMON_PACKAGE_NAME_PREG . ')(-([.0-9a-zA-Z]+))?'); -define('PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_CHANNEL_DOWNLOAD_PREG . '\\z/'); +class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol +{ + function PEAR_Task_Unixeol_rw(&$pkg, &$config, &$logger, $fileXml) + { + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } -/** - * List of temporary files and directories registered by - * PEAR_Common::addTempFile(). - * @var array - */ -$GLOBALS['_PEAR_Common_tempfiles'] = array(); + function validate() + { + return true; + } -/** - * Valid maintainer roles - * @var array - */ -$GLOBALS['_PEAR_Common_maintainer_roles'] = array('lead','developer','contributor','helper'); + function getName() + { + return 'unixeol'; + } + function getXml() + { + return ''; + } +} +?>PEAR-1.9.0/PEAR/Task/Windowseol/rw.php100664 764 764 2562 100664 12237 - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 */ -$GLOBALS['_PEAR_Common_release_states'] = array('alpha','beta','stable','snapshot','devel'); - /** - * Valid dependency types - * @var array + * Base class */ -$GLOBALS['_PEAR_Common_dependency_types'] = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi'); - +require_once 'PEAR/Task/Windowseol.php'; /** - * Valid dependency relations - * @var array + * Abstracts the windowseol task xml. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 */ -$GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge','not', 'ne'); +class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol +{ + function PEAR_Task_Windowseol_rw(&$pkg, &$config, &$logger, $fileXml) + { + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } -/** - * Valid file roles - * @var array - */ -$GLOBALS['_PEAR_Common_file_roles'] = array('php','ext','test','doc','data','src','script'); + function validate() + { + return true; + } -/** - * Valid replacement types - * @var array - */ -$GLOBALS['_PEAR_Common_replacement_types'] = array('php-const', 'pear-config', 'package-info'); + function getName() + { + return 'windowseol'; + } + function getXml() + { + return ''; + } +} +?>PEAR-1.9.0/PEAR/Task/Common.php100664 764 764 13736 100664 10732 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Common.php 276394 2009-02-25 00:15:49Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 */ -$GLOBALS['_PEAR_Common_provide_types'] = array('ext', 'prog', 'class', 'function', 'feature', 'api'); - -/** - * Valid "provide" types - * @var array +/**#@+ + * Error codes for task validation routines */ -$GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'pre-uninstall', 'post-uninstall', 'pre-build', 'post-build', 'pre-configure', 'post-configure', 'pre-setup', 'post-setup'); - +define('PEAR_TASK_ERROR_NOATTRIBS', 1); +define('PEAR_TASK_ERROR_MISSING_ATTRIB', 2); +define('PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE', 3); +define('PEAR_TASK_ERROR_INVALID', 4); +/**#@-*/ +define('PEAR_TASK_PACKAGE', 1); +define('PEAR_TASK_INSTALL', 2); +define('PEAR_TASK_PACKAGEANDINSTALL', 3); /** - * Class providing common functionality for PEAR administration classes. + * A task is an operation that manipulates the contents of a file. + * + * Simple tasks operate on 1 file. Multiple tasks are executed after all files have been + * processed and installed, and are designed to operate on all files containing the task. + * The Post-install script task simply takes advantage of the fact that it will be run + * after installation, replace is a simple task. + * + * Combining tasks is possible, but ordering is significant. + * + * + * + * + * + * + * This will first replace any instance of @data-dir@ in the test.php file + * with the path to the current data directory. Then, it will include the + * test.php file and run the script it contains to configure the package post-installation. * @category pear * @package PEAR - * @author Stig Bakken - * @author Tomas V. V. Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 - * @deprecated This class will disappear, and its components will be spread - * into smaller classes, like the AT&T breakup, as of Release 1.4.0a1 + * @abstract */ -class PEAR_Common extends PEAR +class PEAR_Task_Common { /** - * User Interface object (PEAR_Frontend_* class). If null, - * the log() method uses print. - * @var object + * Valid types for this version are 'simple' and 'multiple' + * + * - simple tasks operate on the contents of a file and write out changes to disk + * - multiple tasks operate on the contents of many files and write out the + * changes directly to disk + * + * Child task classes must override this property. + * @access protected */ - var $ui = null; - + var $type = 'simple'; /** - * Configuration object (PEAR_Config). - * @var PEAR_Config + * Determines which install phase this task is executed under */ - var $config = null; - - /** stack of elements, gives some sort of XML context */ - var $element_stack = array(); - - /** name of currently parsed XML element */ - var $current_element; - - /** array of attributes of the currently parsed XML element */ - var $current_attributes = array(); - - /** assoc with information about a package */ - var $pkginfo = array(); - - var $current_path = null; - + var $phase = PEAR_TASK_INSTALL; /** - * Flag variable used to mark a valid package file - * @var boolean - * @access private + * @access protected */ - var $_validPackageFile; - + var $config; /** - * PEAR_Common constructor - * - * @access public + * @access protected */ - function PEAR_Common() - { - parent::PEAR(); - $this->config = &PEAR_Config::singleton(); - $this->debug = $this->config->get('verbose'); - } - + var $registry; /** - * PEAR_Common destructor - * - * @access private + * @access protected */ - function _PEAR_Common() - { - // doesn't work due to bug #14744 - //$tempfiles = $this->_tempfiles; - $tempfiles =& $GLOBALS['_PEAR_Common_tempfiles']; - while ($file = array_shift($tempfiles)) { - if (@is_dir($file)) { - if (!class_exists('System')) { - require_once 'System.php'; - } - - System::rm(array('-rf', $file)); - } elseif (file_exists($file)) { - unlink($file); - } - } - } - + var $logger; /** - * Register a temporary file or directory. When the destructor is - * executed, all registered temporary files and directories are - * removed. - * - * @param string $file name of file or directory - * - * @return void - * - * @access public + * @access protected */ - function addTempFile($file) - { - if (!class_exists('PEAR_Frontend')) { - require_once 'PEAR/Frontend.php'; - } - PEAR_Frontend::addTempFile($file); - } - + var $installphase; /** - * Wrapper to System::mkDir(), creates a directory as well as - * any necessary parent directories. - * - * @param string $dir directory name - * - * @return bool TRUE on success, or a PEAR error - * - * @access public + * @param PEAR_Config + * @param PEAR_Common */ - function mkDirHier($dir) + function PEAR_Task_Common(&$config, &$logger, $phase) { - // Only used in Installer - move it there ? - $this->log(2, "+ create dir $dir"); - if (!class_exists('System')) { - require_once 'System.php'; + $this->config = &$config; + $this->registry = &$config->getRegistry(); + $this->logger = &$logger; + $this->installphase = $phase; + if ($this->type == 'multiple') { + $GLOBALS['_PEAR_TASK_POSTINSTANCES'][get_class($this)][] = &$this; } - return System::mkDir(array('-p', $dir)); } /** - * Logging method. - * - * @param int $level log level (0 is quiet, higher is noisier) - * @param string $msg message to write to the log - * - * @return void + * Validate the basic contents of a task tag. + * @param PEAR_PackageFile_v2 + * @param array + * @param PEAR_Config + * @param array the entire parsed tag + * @return true|array On error, return an array in format: + * array(PEAR_TASK_ERROR_???[, param1][, param2][, ...]) * - * @access public + * For PEAR_TASK_ERROR_MISSING_ATTRIB, pass the attribute name in + * For PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, pass the attribute name and an array + * of legal values in * @static + * @abstract */ - function log($level, $msg, $append_crlf = true) + function validateXml($pkg, $xml, $config, $fileXml) { - if ($this->debug >= $level) { - if (!class_exists('PEAR_Frontend')) { - require_once 'PEAR/Frontend.php'; - } - - $ui = &PEAR_Frontend::singleton(); - if (is_a($ui, 'PEAR_Frontend')) { - $ui->log($msg, $append_crlf); - } else { - print "$msg\n"; - } - } } /** - * Create and register a temporary directory. - * - * @param string $tmpdir (optional) Directory to use as tmpdir. - * Will use system defaults (for example - * /tmp or c:\windows\temp) if not specified - * - * @return string name of created directory - * - * @access public + * Initialize a task instance with the parameters + * @param array raw, parsed xml + * @param array attributes from the tag containing this task + * @param string|null last installed version of this package + * @abstract */ - function mkTempDir($tmpdir = '') + function init($xml, $fileAttributes, $lastVersion) { - $topt = $tmpdir ? array('-t', $tmpdir) : array(); - $topt = array_merge($topt, array('-d', 'pear')); - if (!class_exists('System')) { - require_once 'System.php'; - } - - if (!$tmpdir = System::mktemp($topt)) { - return false; - } - - $this->addTempFile($tmpdir); - return $tmpdir; } /** - * Set object that represents the frontend to be used. + * Begin a task processing session. All multiple tasks will be processed after each file + * has been successfully installed, all simple tasks should perform their task here and + * return any errors using the custom throwError() method to allow forward compatibility * - * @param object Reference of the frontend object - * @return void - * @access public + * This method MUST NOT write out any changes to disk + * @param PEAR_PackageFile_v2 + * @param string file contents + * @param string the eventual final file location (informational only) + * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail + * (use $this->throwError), otherwise return the new contents + * @abstract */ - function setFrontendObject(&$ui) + function startSession($pkg, $contents, $dest) { - $this->ui = &$ui; } /** - * Return an array containing all of the states that are more stable than - * or equal to the passed in state - * - * @param string Release state - * @param boolean Determines whether to include $state in the list - * @return false|array False if $state is not a valid release state + * This method is used to process each of the tasks for a particular multiple class + * type. Simple tasks need not implement this method. + * @param array an array of tasks + * @access protected + * @static + * @abstract */ - function betterStates($state, $include = false) + function run($tasks) { - static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); - $i = array_search($state, $states); - if ($i === false) { - return false; - } - if ($include) { - $i--; - } - return array_slice($states, $i + 1); } /** - * Get the valid roles for a PEAR package maintainer - * - * @return array * @static + * @final */ - function getUserRoles() + function hasPostinstallTasks() { - return $GLOBALS['_PEAR_Common_maintainer_roles']; + return isset($GLOBALS['_PEAR_TASK_POSTINSTANCES']); } /** - * Get the valid package release states of packages - * - * @return array * @static + * @final */ - function getReleaseStates() - { - return $GLOBALS['_PEAR_Common_release_states']; + function runPostinstallTasks() + { + foreach ($GLOBALS['_PEAR_TASK_POSTINSTANCES'] as $class => $tasks) { + $err = call_user_func(array($class, 'run'), + $GLOBALS['_PEAR_TASK_POSTINSTANCES'][$class]); + if ($err) { + return PEAR_Task_Common::throwError($err); + } + } + unset($GLOBALS['_PEAR_TASK_POSTINSTANCES']); } /** - * Get the implemented dependency types (php, ext, pkg etc.) - * - * @return array - * @static + * Determines whether a role is a script + * @return bool */ - function getDependencyTypes() + function isScript() { - return $GLOBALS['_PEAR_Common_dependency_types']; + return $this->type == 'script'; } - /** - * Get the implemented dependency relations (has, lt, ge etc.) - * - * @return array - * @static - */ - function getDependencyRelations() + function throwError($msg, $code = -1) { - return $GLOBALS['_PEAR_Common_dependency_relations']; + include_once 'PEAR.php'; + return PEAR::raiseError($msg, $code); } - +} +?>PEAR-1.9.0/PEAR/Task/Postinstallscript.php100664 764 764 34122 100664 13233 + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Postinstallscript.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Common.php'; +/** + * Implements the postinstallscript file task. + * + * Note that post-install scripts are handled separately from installation, by the + * "pear run-scripts" command + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Task_Postinstallscript extends PEAR_Task_Common +{ + var $type = 'script'; + var $_class; + var $_params; + var $_obj; /** - * Get the implemented file roles * - * @return array - * @static + * @var PEAR_PackageFile_v2 */ - function getFileRoles() - { - return $GLOBALS['_PEAR_Common_file_roles']; - } + var $_pkg; + var $_contents; + var $phase = PEAR_TASK_INSTALL; /** - * Get the implemented file replacement types in + * Validate the raw xml at parsing-time. * - * @return array + * This also attempts to validate the script to make sure it meets the criteria + * for a post-install script + * @param PEAR_PackageFile_v2 + * @param array The XML contents of the tag + * @param PEAR_Config + * @param array the entire parsed tag * @static */ - function getReplacementTypes() + function validateXml($pkg, $xml, $config, $fileXml) { - return $GLOBALS['_PEAR_Common_replacement_types']; + if ($fileXml['role'] != 'php') { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" must be role="php"'); + } + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $file = $pkg->getFileContents($fileXml['name']); + if (PEAR::isError($file)) { + PEAR::popErrorHandling(); + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" is not valid: ' . + $file->getMessage()); + } elseif ($file === null) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" could not be retrieved for processing!'); + } else { + $analysis = $pkg->analyzeSourceCode($file, true); + if (!$analysis) { + PEAR::popErrorHandling(); + $warnings = ''; + foreach ($pkg->getValidationWarnings() as $warn) { + $warnings .= $warn['message'] . "\n"; + } + return array(PEAR_TASK_ERROR_INVALID, 'Analysis of post-install script "' . + $fileXml['name'] . '" failed: ' . $warnings); + } + if (count($analysis['declared_classes']) != 1) { + PEAR::popErrorHandling(); + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" must declare exactly 1 class'); + } + $class = $analysis['declared_classes'][0]; + if ($class != str_replace(array('/', '.php'), array('_', ''), + $fileXml['name']) . '_postinstall') { + PEAR::popErrorHandling(); + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" class "' . $class . '" must be named "' . + str_replace(array('/', '.php'), array('_', ''), + $fileXml['name']) . '_postinstall"'); + } + if (!isset($analysis['declared_methods'][$class])) { + PEAR::popErrorHandling(); + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" must declare methods init() and run()'); + } + $methods = array('init' => 0, 'run' => 1); + foreach ($analysis['declared_methods'][$class] as $method) { + if (isset($methods[$method])) { + unset($methods[$method]); + } + } + if (count($methods)) { + PEAR::popErrorHandling(); + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" must declare methods init() and run()'); + } + } + PEAR::popErrorHandling(); + $definedparams = array(); + $tasksNamespace = $pkg->getTasksNs() . ':'; + if (!isset($xml[$tasksNamespace . 'paramgroup']) && isset($xml['paramgroup'])) { + // in order to support the older betas, which did not expect internal tags + // to also use the namespace + $tasksNamespace = ''; + } + if (isset($xml[$tasksNamespace . 'paramgroup'])) { + $params = $xml[$tasksNamespace . 'paramgroup']; + if (!is_array($params) || !isset($params[0])) { + $params = array($params); + } + foreach ($params as $param) { + if (!isset($param[$tasksNamespace . 'id'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" must have ' . + 'an ' . $tasksNamespace . 'id> tag'); + } + if (isset($param[$tasksNamespace . 'name'])) { + if (!in_array($param[$tasksNamespace . 'name'], $definedparams)) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" ' . $tasksNamespace . + 'paramgroup> id "' . $param[$tasksNamespace . 'id'] . + '" parameter "' . $param[$tasksNamespace . 'name'] . + '" has not been previously defined'); + } + if (!isset($param[$tasksNamespace . 'conditiontype'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" ' . $tasksNamespace . + 'paramgroup> id "' . $param[$tasksNamespace . 'id'] . + '" must have a ' . $tasksNamespace . + 'conditiontype> tag containing either "=", ' . + '"!=", or "preg_match"'); + } + if (!in_array($param[$tasksNamespace . 'conditiontype'], + array('=', '!=', 'preg_match'))) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" ' . $tasksNamespace . + 'paramgroup> id "' . $param[$tasksNamespace . 'id'] . + '" must have a ' . $tasksNamespace . + 'conditiontype> tag containing either "=", ' . + '"!=", or "preg_match"'); + } + if (!isset($param[$tasksNamespace . 'value'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" ' . $tasksNamespace . + 'paramgroup> id "' . $param[$tasksNamespace . 'id'] . + '" must have a ' . $tasksNamespace . + 'value> tag containing expected parameter value'); + } + } + if (isset($param[$tasksNamespace . 'instructions'])) { + if (!is_string($param[$tasksNamespace . 'instructions'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" ' . $tasksNamespace . + 'paramgroup> id "' . $param[$tasksNamespace . 'id'] . + '" ' . $tasksNamespace . 'instructions> must be simple text'); + } + } + if (!isset($param[$tasksNamespace . 'param'])) { + continue; // is no longer required + } + $subparams = $param[$tasksNamespace . 'param']; + if (!is_array($subparams) || !isset($subparams[0])) { + $subparams = array($subparams); + } + foreach ($subparams as $subparam) { + if (!isset($subparam[$tasksNamespace . 'name'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" parameter for ' . + $tasksNamespace . 'paramgroup> id "' . + $param[$tasksNamespace . 'id'] . '" must have ' . + 'a ' . $tasksNamespace . 'name> tag'); + } + if (!preg_match('/[a-zA-Z0-9]+/', + $subparam[$tasksNamespace . 'name'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" parameter "' . + $subparam[$tasksNamespace . 'name'] . + '" for ' . $tasksNamespace . 'paramgroup> id "' . + $param[$tasksNamespace . 'id'] . + '" is not a valid name. Must contain only alphanumeric characters'); + } + if (!isset($subparam[$tasksNamespace . 'prompt'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" parameter "' . + $subparam[$tasksNamespace . 'name'] . + '" for ' . $tasksNamespace . 'paramgroup> id "' . + $param[$tasksNamespace . 'id'] . + '" must have a ' . $tasksNamespace . 'prompt> tag'); + } + if (!isset($subparam[$tasksNamespace . 'type'])) { + return array(PEAR_TASK_ERROR_INVALID, 'Post-install script "' . + $fileXml['name'] . '" parameter "' . + $subparam[$tasksNamespace . 'name'] . + '" for ' . $tasksNamespace . 'paramgroup> id "' . + $param[$tasksNamespace . 'id'] . + '" must have a ' . $tasksNamespace . 'type> tag'); + } + $definedparams[] = $param[$tasksNamespace . 'id'] . '::' . + $subparam[$tasksNamespace . 'name']; + } + } + } + return true; } /** - * Get the implemented file replacement types in - * - * @return array - * @static + * Initialize a task instance with the parameters + * @param array raw, parsed xml + * @param array attributes from the tag containing this task + * @param string|null last installed version of this package, if any (useful for upgrades) */ - function getProvideTypes() + function init($xml, $fileattribs, $lastversion) { - return $GLOBALS['_PEAR_Common_provide_types']; + $this->_class = str_replace('/', '_', $fileattribs['name']); + $this->_filename = $fileattribs['name']; + $this->_class = str_replace ('.php', '', $this->_class) . '_postinstall'; + $this->_params = $xml; + $this->_lastversion = $lastversion; } /** - * Get the implemented file replacement types in + * Strip the tasks: namespace from internal params * - * @return array - * @static + * @access private */ - function getScriptPhases() + function _stripNamespace($params = null) { - return $GLOBALS['_PEAR_Common_script_phases']; + if ($params === null) { + $params = array(); + if (!is_array($this->_params)) { + return; + } + foreach ($this->_params as $i => $param) { + if (is_array($param)) { + $param = $this->_stripNamespace($param); + } + $params[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param; + } + $this->_params = $params; + } else { + $newparams = array(); + foreach ($params as $i => $param) { + if (is_array($param)) { + $param = $this->_stripNamespace($param); + } + $newparams[str_replace($this->_pkg->getTasksNs() . ':', '', $i)] = $param; + } + return $newparams; + } } /** - * Test whether a string contains a valid package name. - * - * @param string $name the package name to test - * - * @return bool - * - * @access public + * Unlike other tasks, the installed file name is passed in instead of the file contents, + * because this task is handled post-installation + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param string file name + * @return bool|PEAR_Error false to skip this file, PEAR_Error to fail + * (use $this->throwError) */ - function validPackageName($name) + function startSession($pkg, $contents) { - return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name); - } - - /** - * Test whether a string contains a valid package version. - * - * @param string $ver the package version to test - * - * @return bool - * - * @access public + if ($this->installphase != PEAR_TASK_INSTALL) { + return false; + } + // remove the tasks: namespace if present + $this->_pkg = $pkg; + $this->_stripNamespace(); + $this->logger->log(0, 'Including external post-installation script "' . + $contents . '" - any errors are in this script'); + include_once $contents; + if (class_exists($this->_class)) { + $this->logger->log(0, 'Inclusion succeeded'); + } else { + return $this->throwError('init of post-install script class "' . $this->_class + . '" failed'); + } + $this->_obj = new $this->_class; + $this->logger->log(1, 'running post-install script "' . $this->_class . '->init()"'); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $res = $this->_obj->init($this->config, $pkg, $this->_lastversion); + PEAR::popErrorHandling(); + if ($res) { + $this->logger->log(0, 'init succeeded'); + } else { + return $this->throwError('init of post-install script "' . $this->_class . + '->init()" failed'); + } + $this->_contents = $contents; + return true; + } + + /** + * No longer used + * @see PEAR_PackageFile_v2::runPostinstallScripts() + * @param array an array of tasks + * @param string install or upgrade + * @access protected + * @static */ - function validPackageVersion($ver) + function run() { - return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); } +} +?>PEAR-1.9.0/PEAR/Task/Replace.php100664 764 764 15232 100664 11046 + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Replace.php 276394 2009-02-25 00:15:49Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Common.php'; +/** + * Implements the replace file task. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Task_Replace extends PEAR_Task_Common +{ + var $type = 'simple'; + var $phase = PEAR_TASK_PACKAGEANDINSTALL; + var $_replacements; /** - * @param string $path relative or absolute include path - * @return boolean + * Validate the raw xml at parsing-time. + * @param PEAR_PackageFile_v2 + * @param array raw, parsed xml + * @param PEAR_Config * @static */ - function isIncludeable($path) + function validateXml($pkg, $xml, $config, $fileXml) { - if (file_exists($path) && is_readable($path)) { - return true; + if (!isset($xml['attribs'])) { + return array(PEAR_TASK_ERROR_NOATTRIBS); } - - $ipath = explode(PATH_SEPARATOR, ini_get('include_path')); - foreach ($ipath as $include) { - $test = realpath($include . DIRECTORY_SEPARATOR . $path); - if (file_exists($test) && is_readable($test)) { + if (!isset($xml['attribs']['type'])) { + return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'type'); + } + if (!isset($xml['attribs']['to'])) { + return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'to'); + } + if (!isset($xml['attribs']['from'])) { + return array(PEAR_TASK_ERROR_MISSING_ATTRIB, 'from'); + } + if ($xml['attribs']['type'] == 'pear-config') { + if (!in_array($xml['attribs']['to'], $config->getKeys())) { + return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'], + $config->getKeys()); + } + } elseif ($xml['attribs']['type'] == 'php-const') { + if (defined($xml['attribs']['to'])) { + return true; + } else { + return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'], + array('valid PHP constant')); + } + } elseif ($xml['attribs']['type'] == 'package-info') { + if (in_array($xml['attribs']['to'], + array('name', 'summary', 'channel', 'notes', 'extends', 'description', + 'release_notes', 'license', 'release-license', 'license-uri', + 'version', 'api-version', 'state', 'api-state', 'release_date', + 'date', 'time'))) { return true; + } else { + return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'to', $xml['attribs']['to'], + array('name', 'summary', 'channel', 'notes', 'extends', 'description', + 'release_notes', 'license', 'release-license', 'license-uri', + 'version', 'api-version', 'state', 'api-state', 'release_date', + 'date', 'time')); } + } else { + return array(PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE, 'type', $xml['attribs']['type'], + array('pear-config', 'package-info', 'php-const')); } - - return false; + return true; } /** - * Returns information about a package file. Expects the name of - * a gzipped tar file as input. - * - * @param string $file name of .tgz file - * - * @return array array with package information - * - * @access public - * @deprecated use PEAR_PackageFile->fromTgzFile() instead - * + * Initialize a task instance with the parameters + * @param array raw, parsed xml + * @param unused */ - function infoFromTgzFile($file) + function init($xml, $attribs) { - $packagefile = &new PEAR_PackageFile($this->config); - $pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); - } - } - - return $pf; - } - - return $this->_postProcessValidPackagexml($pf); + $this->_replacements = isset($xml['attribs']) ? array($xml) : $xml; } /** - * Returns information about a package file. Expects the name of - * a package xml file as input. - * - * @param string $descfile name of package xml file - * - * @return array array with package information - * - * @access public - * @deprecated use PEAR_PackageFile->fromPackageFile() instead + * Do a package.xml 1.0 replacement, with additional package-info fields available * + * See validateXml() source for the complete list of allowed fields + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param string file contents + * @param string the eventual final file location (informational only) + * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail + * (use $this->throwError), otherwise return the new contents */ - function infoFromDescriptionFile($descfile) + function startSession($pkg, $contents, $dest) { - $packagefile = &new PEAR_PackageFile($this->config); - $pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); + $subst_from = $subst_to = array(); + foreach ($this->_replacements as $a) { + $a = $a['attribs']; + $to = ''; + if ($a['type'] == 'pear-config') { + if ($this->installphase == PEAR_TASK_PACKAGE) { + return false; + } + if ($a['to'] == 'master_server') { + $chan = $this->registry->getChannel($pkg->getChannel()); + if (!PEAR::isError($chan)) { + $to = $chan->getServer(); + } else { + $this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]"); + return false; + } + } else { + if ($this->config->isDefinedLayer('ftp')) { + // try the remote config file first + $to = $this->config->get($a['to'], 'ftp', $pkg->getChannel()); + if (is_null($to)) { + // then default to local + $to = $this->config->get($a['to'], null, $pkg->getChannel()); + } + } else { + $to = $this->config->get($a['to'], null, $pkg->getChannel()); + } + } + if (is_null($to)) { + $this->logger->log(0, "$dest: invalid pear-config replacement: $a[to]"); + return false; + } + } elseif ($a['type'] == 'php-const') { + if ($this->installphase == PEAR_TASK_PACKAGE) { + return false; + } + if (defined($a['to'])) { + $to = constant($a['to']); + } else { + $this->logger->log(0, "$dest: invalid php-const replacement: $a[to]"); + return false; + } + } else { + if ($t = $pkg->packageInfo($a['to'])) { + $to = $t; + } else { + $this->logger->log(0, "$dest: invalid package-info replacement: $a[to]"); + return false; } } - - return $pf; + if (!is_null($to)) { + $subst_from[] = $a['from']; + $subst_to[] = $to; + } } - - return $this->_postProcessValidPackagexml($pf); + $this->logger->log(3, "doing " . sizeof($subst_from) . + " substitution(s) for $dest"); + if (sizeof($subst_from)) { + $contents = str_replace($subst_from, $subst_to, $contents); + } + return $contents; } +} +?>PEAR-1.9.0/PEAR/Task/Unixeol.php100664 764 764 4341 100664 11075 + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Unixeol.php 276394 2009-02-25 00:15:49Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Common.php'; +/** + * Implements the unix line endings file task. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Task_Unixeol extends PEAR_Task_Common +{ + var $type = 'simple'; + var $phase = PEAR_TASK_PACKAGE; + var $_replacements; /** - * Returns information about a package file. Expects the contents - * of a package xml file as input. - * - * @param string $data contents of package.xml file - * - * @return array array with package information - * - * @access public - * @deprecated use PEAR_PackageFile->fromXmlstring() instead - * + * Validate the raw xml at parsing-time. + * @param PEAR_PackageFile_v2 + * @param array raw, parsed xml + * @param PEAR_Config + * @static */ - function infoFromString($data) + function validateXml($pkg, $xml, $config, $fileXml) { - $packagefile = &new PEAR_PackageFile($this->config); - $pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); - } - } - - return $pf; + if ($xml != '') { + return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed'); } - - return $this->_postProcessValidPackagexml($pf); + return true; } /** - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @return array + * Initialize a task instance with the parameters + * @param array raw, parsed xml + * @param unused */ - function _postProcessValidPackagexml(&$pf) + function init($xml, $attribs) { - if (!is_a($pf, 'PEAR_PackageFile_v2')) { - $this->pkginfo = $pf->toArray(); - return $this->pkginfo; - } - - // sort of make this into a package.xml 1.0-style array - // changelog is not converted to old format. - $arr = $pf->toArray(true); - $arr = array_merge($arr, $arr['old']); - unset($arr['old']); - unset($arr['xsdversion']); - unset($arr['contents']); - unset($arr['compatible']); - unset($arr['channel']); - unset($arr['uri']); - unset($arr['dependencies']); - unset($arr['phprelease']); - unset($arr['extsrcrelease']); - unset($arr['zendextsrcrelease']); - unset($arr['extbinrelease']); - unset($arr['zendextbinrelease']); - unset($arr['bundle']); - unset($arr['lead']); - unset($arr['developer']); - unset($arr['helper']); - unset($arr['contributor']); - $arr['filelist'] = $pf->getFilelist(); - $this->pkginfo = $arr; - return $arr; } /** - * Returns package information from different sources - * - * This method is able to extract information about a package - * from a .tgz archive or from a XML package definition file. + * Replace all line endings with line endings customized for the current OS * - * @access public - * @param string Filename of the source ('package.xml', '.tgz') - * @return string - * @deprecated use PEAR_PackageFile->fromAnyFile() instead + * See validateXml() source for the complete list of allowed fields + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param string file contents + * @param string the eventual final file location (informational only) + * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail + * (use $this->throwError), otherwise return the new contents */ - function infoFromAny($info) + function startSession($pkg, $contents, $dest) { - if (is_string($info) && file_exists($info)) { - $packagefile = &new PEAR_PackageFile($this->config); - $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); - } - } - - return $pf; - } - - return $this->_postProcessValidPackagexml($pf); - } - - return $info; + $this->logger->log(3, "replacing all line endings with \\n in $dest"); + return preg_replace("/\r\n|\n\r|\r|\n/", "\n", $contents); } +} +?>PEAR-1.9.0/PEAR/Task/Windowseol.php100664 764 764 4335 100664 11607 + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Windowseol.php 276394 2009-02-25 00:15:49Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * Base class + */ +require_once 'PEAR/Task/Common.php'; +/** + * Implements the windows line endsings file task. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Task_Windowseol extends PEAR_Task_Common +{ + var $type = 'simple'; + var $phase = PEAR_TASK_PACKAGE; + var $_replacements; /** - * Return an XML document based on the package info (as returned - * by the PEAR_Common::infoFrom* methods). - * - * @param array $pkginfo package info - * - * @return string XML data - * - * @access public - * @deprecated use a PEAR_PackageFile_v* object's generator instead + * Validate the raw xml at parsing-time. + * @param PEAR_PackageFile_v2 + * @param array raw, parsed xml + * @param PEAR_Config + * @static */ - function xmlFromInfo($pkginfo) + function validateXml($pkg, $xml, $config, $fileXml) { - $config = &PEAR_Config::singleton(); - $packagefile = &new PEAR_PackageFile($config); - $pf = &$packagefile->fromArray($pkginfo); - $gen = &$pf->getDefaultGenerator(); - return $gen->toXml(PEAR_VALIDATE_PACKAGING); + if ($xml != '') { + return array(PEAR_TASK_ERROR_INVALID, 'no attributes allowed'); + } + return true; } /** - * Validate XML package definition file. - * - * @param string $info Filename of the package archive or of the - * package definition file - * @param array $errors Array that will contain the errors - * @param array $warnings Array that will contain the warnings - * @param string $dir_prefix (optional) directory where source files - * may be found, or empty if they are not available - * @access public - * @return boolean - * @deprecated use the validation of PEAR_PackageFile objects + * Initialize a task instance with the parameters + * @param array raw, parsed xml + * @param unused */ - function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '') + function init($xml, $attribs) { - $config = &PEAR_Config::singleton(); - $packagefile = &new PEAR_PackageFile($config); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - if (strpos($info, 'fromXmlString($info, PEAR_VALIDATE_NORMAL, ''); - } else { - $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); - } - - PEAR::staticPopErrorHandling(); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - if ($error['level'] == 'error') { - $errors[] = $error['message']; - } else { - $warnings[] = $error['message']; - } - } - } - - return false; - } - - return true; } /** - * Build a "provides" array from data returned by - * analyzeSourceCode(). The format of the built array is like - * this: - * - * array( - * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), - * ... - * ) - * - * - * @param array $srcinfo array with information about a source file - * as returned by the analyzeSourceCode() method. - * - * @return void - * - * @access public + * Replace all line endings with windows line endings * + * See validateXml() source for the complete list of allowed fields + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param string file contents + * @param string the eventual final file location (informational only) + * @return string|false|PEAR_Error false to skip this file, PEAR_Error to fail + * (use $this->throwError), otherwise return the new contents */ - function buildProvidesArray($srcinfo) + function startSession($pkg, $contents, $dest) { - $file = basename($srcinfo['source_file']); - $pn = ''; - if (isset($this->_packageName)) { - $pn = $this->_packageName; - } - - $pnl = strlen($pn); - foreach ($srcinfo['declared_classes'] as $class) { - $key = "class;$class"; - if (isset($this->pkginfo['provides'][$key])) { - continue; - } - - $this->pkginfo['provides'][$key] = - array('file'=> $file, 'type' => 'class', 'name' => $class); - if (isset($srcinfo['inheritance'][$class])) { - $this->pkginfo['provides'][$key]['extends'] = - $srcinfo['inheritance'][$class]; - } - } - - foreach ($srcinfo['declared_methods'] as $class => $methods) { - foreach ($methods as $method) { - $function = "$class::$method"; - $key = "function;$function"; - if ($method{0} == '_' || !strcasecmp($method, $class) || - isset($this->pkginfo['provides'][$key])) { - continue; - } - - $this->pkginfo['provides'][$key] = - array('file'=> $file, 'type' => 'function', 'name' => $function); + $this->logger->log(3, "replacing all line endings with \\r\\n in $dest"); + return preg_replace("/\r\n|\n\r|\r|\n/", "\r\n", $contents); + } +} +?>PEAR-1.9.0/PEAR/Validator/PECL.php100664 764 764 4175 100664 11225 + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: PECL.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a5 + */ +/** + * This is the parent class for all validators + */ +require_once 'PEAR/Validate.php'; +/** + * Channel Validator for the pecl.php.net channel + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a5 + */ +class PEAR_Validator_PECL extends PEAR_Validate +{ + function validateVersion() + { + if ($this->_state == PEAR_VALIDATE_PACKAGING) { + $version = $this->_packagexml->getVersion(); + $versioncomponents = explode('.', $version); + $last = array_pop($versioncomponents); + if (substr($last, 1, 2) == 'rc') { + $this->_addFailure('version', 'Release Candidate versions must have ' . + 'upper-case RC, not lower-case rc'); + return false; } } + return true; + } - foreach ($srcinfo['declared_functions'] as $function) { - $key = "function;$function"; - if ($function{0} == '_' || isset($this->pkginfo['provides'][$key])) { - continue; - } - - if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { - $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; + function validatePackageName() + { + $ret = parent::validatePackageName(); + if ($this->_packagexml->getPackageType() == 'extsrc' || + $this->_packagexml->getPackageType() == 'zendextsrc') { + if (strtolower($this->_packagexml->getPackage()) != + strtolower($this->_packagexml->getProvidesExtension())) { + $this->_addWarning('providesextension', 'package name "' . + $this->_packagexml->getPackage() . '" is different from extension name "' . + $this->_packagexml->getProvidesExtension() . '"'); } - - $this->pkginfo['provides'][$key] = - array('file'=> $file, 'type' => 'function', 'name' => $function); } + return $ret; } +} +?>PEAR-1.9.0/PEAR/Autoloader.php100664 764 764 14645 100664 10677 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Autoloader.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader + * @since File available since Release 0.1 + * @deprecated File deprecated in Release 1.4.0a1 + */ + +// /* vim: set expandtab tabstop=4 shiftwidth=4: */ + +if (!extension_loaded("overload")) { + // die hard without ext/overload + die("Rebuild PHP with the `overload' extension to use PEAR_Autoloader"); +} + +/** + * Include for PEAR_Error and PEAR classes + */ +require_once "PEAR.php"; + +/** + * This class is for objects where you want to separate the code for + * some methods into separate classes. This is useful if you have a + * class with not-frequently-used methods that contain lots of code + * that you would like to avoid always parsing. + * + * The PEAR_Autoloader class provides autoloading and aggregation. + * The autoloading lets you set up in which classes the separated + * methods are found. Aggregation is the technique used to import new + * methods, an instance of each class providing separated methods is + * stored and called every time the aggregated method is called. + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/manual/en/core.ppm.php#core.ppm.pear-autoloader + * @since File available since Release 0.1 + * @deprecated File deprecated in Release 1.4.0a1 + */ +class PEAR_Autoloader extends PEAR +{ + // {{{ properties /** - * Analyze the source code of the given PHP file + * Map of methods and classes where they are defined + * + * @var array + * + * @access private + */ + var $_autoload_map = array(); + + /** + * Map of methods and aggregate objects + * + * @var array + * + * @access private + */ + var $_method_map = array(); + + // }}} + // {{{ addAutoload() + + /** + * Add one or more autoload entries. + * + * @param string $method which method to autoload + * + * @param string $classname (optional) which class to find the method in. + * If the $method parameter is an array, this + * parameter may be omitted (and will be ignored + * if not), and the $method parameter will be + * treated as an associative array with method + * names as keys and class names as values. + * + * @return void * - * @param string Filename of the PHP file - * @return mixed * @access public */ - function analyzeSourceCode($file) + function addAutoload($method, $classname = null) { - if (!class_exists('PEAR_PackageFile_v2_Validator')) { - require_once 'PEAR/PackageFile/v2/Validator.php'; + if (is_array($method)) { + array_walk($method, create_function('$a,&$b', '$b = strtolower($b);')); + $this->_autoload_map = array_merge($this->_autoload_map, $method); + } else { + $this->_autoload_map[strtolower($method)] = $classname; } - - $a = new PEAR_PackageFile_v2_Validator; - return $a->analyzeSourceCode($file); } - function detectDependencies($any, $status_callback = null) + // }}} + // {{{ removeAutoload() + + /** + * Remove an autoload entry. + * + * @param string $method which method to remove the autoload entry for + * + * @return bool TRUE if an entry was removed, FALSE if not + * + * @access public + */ + function removeAutoload($method) { - if (!function_exists("token_get_all")) { - return false; - } + $method = strtolower($method); + $ok = isset($this->_autoload_map[$method]); + unset($this->_autoload_map[$method]); + return $ok; + } - if (PEAR::isError($info = $this->infoFromAny($any))) { - return $this->raiseError($info); - } + // }}} + // {{{ addAggregateObject() - if (!is_array($info)) { - return false; + /** + * Add an aggregate object to this object. If the specified class + * is not defined, loading it will be attempted following PEAR's + * file naming scheme. All the methods in the class will be + * aggregated, except private ones (name starting with an + * underscore) and constructors. + * + * @param string $classname what class to instantiate for the object. + * + * @return void + * + * @access public + */ + function addAggregateObject($classname) + { + $classname = strtolower($classname); + if (!class_exists($classname)) { + $include_file = preg_replace('/[^a-z0-9]/i', '_', $classname); + include_once $include_file; } - - $deps = array(); - $used_c = $decl_c = $decl_f = $decl_m = array(); - foreach ($info['filelist'] as $file => $fa) { - $tmp = $this->analyzeSourceCode($file); - $used_c = @array_merge($used_c, $tmp['used_classes']); - $decl_c = @array_merge($decl_c, $tmp['declared_classes']); - $decl_f = @array_merge($decl_f, $tmp['declared_functions']); - $decl_m = @array_merge($decl_m, $tmp['declared_methods']); - $inheri = @array_merge($inheri, $tmp['inheritance']); + $obj =& new $classname; + $methods = get_class_methods($classname); + foreach ($methods as $method) { + // don't import priviate methods and constructors + if ($method{0} != '_' && $method != $classname) { + $this->_method_map[$method] = $obj; + } } - - $used_c = array_unique($used_c); - $decl_c = array_unique($decl_c); - $undecl_c = array_diff($used_c, $decl_c); - - return array('used_classes' => $used_c, - 'declared_classes' => $decl_c, - 'declared_methods' => $decl_m, - 'declared_functions' => $decl_f, - 'undeclared_classes' => $undecl_c, - 'inheritance' => $inheri, - ); } + // }}} + // {{{ removeAggregateObject() + /** - * Download a file through HTTP. Considers suggested file name in - * Content-disposition: header and can run a callback function for - * different events. The callback will be called with two - * parameters: the callback type, and parameters. The implemented - * callback types are: + * Remove an aggregate object. * - * 'setup' called at the very beginning, parameter is a UI object - * that should be used for all output - * 'message' the parameter is a string with an informational message - * 'saveas' may be used to save with a different file name, the - * parameter is the filename that is about to be used. - * If a 'saveas' callback returns a non-empty string, - * that file name will be used as the filename instead. - * Note that $save_dir will not be affected by this, only - * the basename of the file. - * 'start' download is starting, parameter is number of bytes - * that are expected, or -1 if unknown - * 'bytesread' parameter is the number of bytes read so far - * 'done' download is complete, parameter is the total number - * of bytes read - * 'connfailed' if the TCP connection fails, this callback is called - * with array(host,port,errno,errmsg) - * 'writefailed' if writing to disk fails, this callback is called - * with array(destfile,errmsg) + * @param string $classname the class of the object to remove * - * If an HTTP proxy has been configured (http_proxy PEAR_Config - * setting), the proxy will be used. + * @return bool TRUE if an object was removed, FALSE if not * - * @param string $url the URL to download - * @param object $ui PEAR_Frontend_* instance - * @param object $config PEAR_Config instance - * @param string $save_dir (optional) directory to save file in - * @param mixed $callback (optional) function/method to call for status - * updates + * @access public + */ + function removeAggregateObject($classname) + { + $ok = false; + $classname = strtolower($classname); + reset($this->_method_map); + while (list($method, $obj) = each($this->_method_map)) { + if (is_a($obj, $classname)) { + unset($this->_method_map[$method]); + $ok = true; + } + } + return $ok; + } + + // }}} + // {{{ __call() + + /** + * Overloaded object call handler, called each time an + * undefined/aggregated method is invoked. This method repeats + * the call in the right aggregate object and passes on the return + * value. * - * @return string Returns the full path of the downloaded file or a PEAR - * error on failure. If the error is caused by - * socket-related errors, the error object will - * have the fsockopen error code available through - * getCode(). + * @param string $method which method that was called * - * @access public - * @deprecated in favor of PEAR_Downloader::downloadHttp() + * @param string $args An array of the parameters passed in the + * original call + * + * @return mixed The return value from the aggregated method, or a PEAR + * error if the called method was unknown. */ - function downloadHttp($url, &$ui, $save_dir = '.', $callback = null) + function __call($method, $args, &$retval) { - if (!class_exists('PEAR_Downloader')) { - require_once 'PEAR/Downloader.php'; + $method = strtolower($method); + if (empty($this->_method_map[$method]) && isset($this->_autoload_map[$method])) { + $this->addAggregateObject($this->_autoload_map[$method]); } - return PEAR_Downloader::downloadHttp($url, $ui, $save_dir, $callback); + if (isset($this->_method_map[$method])) { + $retval = call_user_func_array(array($this->_method_map[$method], $method), $args); + return true; + } + return false; } + + // }}} } -require_once 'PEAR/Config.php'; -require_once 'PEAR/PackageFile.php';PEAR-1.8.0/PEAR/Config.php100664 764 764 204247 100664 10023 +PEAR-1.9.0/PEAR/Builder.php100664 764 764 40120 100664 10151 * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Config.php,v 1.157 2009/02/25 00:23:26 dufuz Exp $ + * @version CVS: $Id: Builder.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 + * + * TODO: log output parameters in PECL command line + * TODO: msdev path in configuration */ /** - * Required for error handling + * Needed for extending PEAR_Builder */ -require_once 'PEAR.php'; -require_once 'PEAR/Registry.php'; -require_once 'PEAR/Installer/Role.php'; -require_once 'System.php'; +require_once 'PEAR/Common.php'; +require_once 'PEAR/PackageFile.php'; /** - * Last created PEAR_Config instance. - * @var object + * Class to handle building (compiling) extensions. + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since PHP 4.0.2 + * @see http://pear.php.net/manual/en/core.ppm.pear-builder.php */ -$GLOBALS['_PEAR_Config_instance'] = null; -if (!defined('PEAR_INSTALL_DIR') || !PEAR_INSTALL_DIR) { - $PEAR_INSTALL_DIR = PHP_LIBDIR . DIRECTORY_SEPARATOR . 'pear'; -} else { - $PEAR_INSTALL_DIR = PEAR_INSTALL_DIR; -} - -// Below we define constants with default values for all configuration -// parameters except username/password. All of them can have their -// defaults set through environment variables. The reason we use the -// PHP_ prefix is for some security, PHP protects environment -// variables starting with PHP_*. - -// default channel and preferred mirror is based on whether we are invoked through -// the "pear" or the "pecl" command -if (!defined('PEAR_RUNTYPE')) { - define('PEAR_RUNTYPE', 'pear'); -} - -if (PEAR_RUNTYPE == 'pear') { - define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pear.php.net'); -} else { - define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pecl.php.net'); -} +class PEAR_Builder extends PEAR_Common +{ + var $php_api_version = 0; + var $zend_module_api_no = 0; + var $zend_extension_api_no = 0; -if (getenv('PHP_PEAR_SYSCONF_DIR')) { - define('PEAR_CONFIG_SYSCONFDIR', getenv('PHP_PEAR_SYSCONF_DIR')); -} elseif (getenv('SystemRoot')) { - define('PEAR_CONFIG_SYSCONFDIR', getenv('SystemRoot')); -} else { - define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR); -} + var $extensions_built = array(); -// Default for master_server -if (getenv('PHP_PEAR_MASTER_SERVER')) { - define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv('PHP_PEAR_MASTER_SERVER')); -} else { - define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net'); -} + /** + * @var string Used for reporting when it is not possible to pass function + * via extra parameter, e.g. log, msdevCallback + */ + var $current_callback = null; -// Default for http_proxy -if (getenv('PHP_PEAR_HTTP_PROXY')) { - define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('PHP_PEAR_HTTP_PROXY')); -} elseif (getenv('http_proxy')) { - define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('http_proxy')); -} else { - define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', ''); -} + // used for msdev builds + var $_lastline = null; + var $_firstline = null; -// Default for php_dir -if (getenv('PHP_PEAR_INSTALL_DIR')) { - define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR')); -} else { - if (@file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) { - define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); - } else { - define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); + /** + * PEAR_Builder constructor. + * + * @param object $ui user interface object (instance of PEAR_Frontend_*) + * + * @access public + */ + function PEAR_Builder(&$ui) + { + parent::PEAR_Common(); + $this->setFrontendObject($ui); } -} -// Default for ext_dir -if (getenv('PHP_PEAR_EXTENSION_DIR')) { - define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR')); -} else { - if (ini_get('extension_dir')) { - define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get('extension_dir')); - } elseif (defined('PEAR_EXTENSION_DIR') && - file_exists(PEAR_EXTENSION_DIR) && is_dir(PEAR_EXTENSION_DIR)) { - define('PEAR_CONFIG_DEFAULT_EXT_DIR', PEAR_EXTENSION_DIR); - } elseif (defined('PHP_EXTENSION_DIR')) { - define('PEAR_CONFIG_DEFAULT_EXT_DIR', PHP_EXTENSION_DIR); - } else { - define('PEAR_CONFIG_DEFAULT_EXT_DIR', '.'); - } -} + /** + * Build an extension from source on windows. + * requires msdev + */ + function _build_win32($descfile, $callback = null) + { + if (is_object($descfile)) { + $pkg = $descfile; + $descfile = $pkg->getPackageFile(); + } else { + $pf = &new PEAR_PackageFile($this->config, $this->debug); + $pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($pkg)) { + return $pkg; + } + } + $dir = dirname($descfile); + $old_cwd = getcwd(); -// Default for doc_dir -if (getenv('PHP_PEAR_DOC_DIR')) { - define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv('PHP_PEAR_DOC_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_DOC_DIR', - $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'docs'); -} + if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) { + return $this->raiseError("could not chdir to $dir"); + } -// Default for bin_dir -if (getenv('PHP_PEAR_BIN_DIR')) { - define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv('PHP_PEAR_BIN_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR); -} + // packages that were in a .tar have the packagefile in this directory + $vdir = $pkg->getPackage() . '-' . $pkg->getVersion(); + if (file_exists($dir) && is_dir($vdir)) { + if (!chdir($vdir)) { + return $this->raiseError("could not chdir to " . realpath($vdir)); + } -// Default for data_dir -if (getenv('PHP_PEAR_DATA_DIR')) { - define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv('PHP_PEAR_DATA_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_DATA_DIR', - $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data'); -} + $dir = getcwd(); + } -// Default for cfg_dir -if (getenv('PHP_PEAR_CFG_DIR')) { - define('PEAR_CONFIG_DEFAULT_CFG_DIR', getenv('PHP_PEAR_CFG_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_CFG_DIR', - $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'cfg'); -} + $this->log(2, "building in $dir"); -// Default for www_dir -if (getenv('PHP_PEAR_WWW_DIR')) { - define('PEAR_CONFIG_DEFAULT_WWW_DIR', getenv('PHP_PEAR_WWW_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_WWW_DIR', - $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'www'); -} + $dsp = $pkg->getPackage().'.dsp'; + if (!file_exists("$dir/$dsp")) { + return $this->raiseError("The DSP $dsp does not exist."); + } + // XXX TODO: make release build type configurable + $command = 'msdev '.$dsp.' /MAKE "'.$pkg->getPackage(). ' - Release"'; -// Default for test_dir -if (getenv('PHP_PEAR_TEST_DIR')) { - define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_TEST_DIR', - $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests'); -} + $err = $this->_runCommand($command, array(&$this, 'msdevCallback')); + if (PEAR::isError($err)) { + return $err; + } -// Default for temp_dir -if (getenv('PHP_PEAR_TEMP_DIR')) { - define('PEAR_CONFIG_DEFAULT_TEMP_DIR', getenv('PHP_PEAR_TEMP_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_TEMP_DIR', - System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . - DIRECTORY_SEPARATOR . 'temp'); -} + // figure out the build platform and type + $platform = 'Win32'; + $buildtype = 'Release'; + if (preg_match('/.*?'.$pkg->getPackage().'\s-\s(\w+)\s(.*?)-+/i',$this->_firstline,$matches)) { + $platform = $matches[1]; + $buildtype = $matches[2]; + } -// Default for cache_dir -if (getenv('PHP_PEAR_CACHE_DIR')) { - define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv('PHP_PEAR_CACHE_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_CACHE_DIR', - System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . - DIRECTORY_SEPARATOR . 'cache'); -} + if (preg_match('/(.*)?\s-\s(\d+).*?(\d+)/', $this->_lastline, $matches)) { + if ($matches[2]) { + // there were errors in the build + return $this->raiseError("There were errors during compilation."); + } + $out = $matches[1]; + } else { + return $this->raiseError("Did not understand the completion status returned from msdev.exe."); + } -// Default for download_dir -if (getenv('PHP_PEAR_DOWNLOAD_DIR')) { - define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', getenv('PHP_PEAR_DOWNLOAD_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', - System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . - DIRECTORY_SEPARATOR . 'download'); -} + // msdev doesn't tell us the output directory :/ + // open the dsp, find /out and use that directory + $dsptext = join(file($dsp),''); -// Default for php_bin -if (getenv('PHP_PEAR_PHP_BIN')) { - define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv('PHP_PEAR_PHP_BIN')); -} else { - define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR. - DIRECTORY_SEPARATOR.'php'.(OS_WINDOWS ? '.exe' : '')); -} + // this regex depends on the build platform and type having been + // correctly identified above. + $regex ='/.*?!IF\s+"\$\(CFG\)"\s+==\s+("'. + $pkg->getPackage().'\s-\s'. + $platform.'\s'. + $buildtype.'").*?'. + '\/out:"(.*?)"/is'; -// Default for verbose -if (getenv('PHP_PEAR_VERBOSE')) { - define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv('PHP_PEAR_VERBOSE')); -} else { - define('PEAR_CONFIG_DEFAULT_VERBOSE', 1); -} + if ($dsptext && preg_match($regex, $dsptext, $matches)) { + // what we get back is a relative path to the output file itself. + $outfile = realpath($matches[2]); + } else { + return $this->raiseError("Could not retrieve output information from $dsp."); + } + // realpath returns false if the file doesn't exist + if ($outfile && copy($outfile, "$dir/$out")) { + $outfile = "$dir/$out"; + } -// Default for preferred_state -if (getenv('PHP_PEAR_PREFERRED_STATE')) { - define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv('PHP_PEAR_PREFERRED_STATE')); -} else { - define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable'); -} + $built_files[] = array( + 'file' => "$outfile", + 'php_api' => $this->php_api_version, + 'zend_mod_api' => $this->zend_module_api_no, + 'zend_ext_api' => $this->zend_extension_api_no, + ); -// Default for umask -if (getenv('PHP_PEAR_UMASK')) { - define('PEAR_CONFIG_DEFAULT_UMASK', getenv('PHP_PEAR_UMASK')); -} else { - define('PEAR_CONFIG_DEFAULT_UMASK', decoct(umask())); -} + return $built_files; + } + // }}} -// Default for cache_ttl -if (getenv('PHP_PEAR_CACHE_TTL')) { - define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv('PHP_PEAR_CACHE_TTL')); -} else { - define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600); -} + // {{{ msdevCallback() + function msdevCallback($what, $data) + { + if (!$this->_firstline) + $this->_firstline = $data; + $this->_lastline = $data; + call_user_func($this->current_callback, $what, $data); + } -// Default for sig_type -if (getenv('PHP_PEAR_SIG_TYPE')) { - define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv('PHP_PEAR_SIG_TYPE')); -} else { - define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg'); -} + /** + * @param string + * @param string + * @param array + * @access private + */ + function _harvestInstDir($dest_prefix, $dirname, &$built_files) + { + $d = opendir($dirname); + if (!$d) + return false; -// Default for sig_bin -if (getenv('PHP_PEAR_SIG_BIN')) { - define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv('PHP_PEAR_SIG_BIN')); -} else { - define('PEAR_CONFIG_DEFAULT_SIG_BIN', - System::which( - 'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg')); -} + $ret = true; + while (($ent = readdir($d)) !== false) { + if ($ent{0} == '.') + continue; -// Default for sig_keydir -if (getenv('PHP_PEAR_SIG_KEYDIR')) { - define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv('PHP_PEAR_SIG_KEYDIR')); -} else { - define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', - PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys'); -} + $full = $dirname . DIRECTORY_SEPARATOR . $ent; + if (is_dir($full)) { + if (!$this->_harvestInstDir( + $dest_prefix . DIRECTORY_SEPARATOR . $ent, + $full, $built_files)) { + $ret = false; + break; + } + } else { + $dest = $dest_prefix . DIRECTORY_SEPARATOR . $ent; + $built_files[] = array( + 'file' => $full, + 'dest' => $dest, + 'php_api' => $this->php_api_version, + 'zend_mod_api' => $this->zend_module_api_no, + 'zend_ext_api' => $this->zend_extension_api_no, + ); + } + } + closedir($d); + return $ret; + } -/** - * This is a class for storing configuration data, keeping track of - * which are system-defined, user-defined or defaulted. - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 - */ -class PEAR_Config extends PEAR -{ /** - * Array of config files used. + * Build an extension from source. Runs "phpize" in the source + * directory, but compiles in a temporary directory + * (/var/tmp/pear-build-USER/PACKAGE-VERSION). * - * @var array layer => config file + * @param string|PEAR_PackageFile_v* $descfile path to XML package description file, or + * a PEAR_PackageFile object + * + * @param mixed $callback callback function used to report output, + * see PEAR_Builder::_runCommand for details + * + * @return array an array of associative arrays with built files, + * format: + * array( array( 'file' => '/path/to/ext.so', + * 'php_api' => YYYYMMDD, + * 'zend_mod_api' => YYYYMMDD, + * 'zend_ext_api' => YYYYMMDD ), + * ... ) + * + * @access public + * + * @see PEAR_Builder::_runCommand */ - var $files = array( - 'system' => '', - 'user' => '', - ); + function build($descfile, $callback = null) + { + if (preg_match('/(\\/|\\\\|^)([^\\/\\\\]+)?php(.+)?$/', + $this->config->get('php_bin'), $matches)) { + if (isset($matches[2]) && strlen($matches[2]) && + trim($matches[2]) != trim($this->config->get('php_prefix'))) { + $this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') . + ' appears to have a prefix ' . $matches[2] . ', but' . + ' config variable php_prefix does not match'); + } + if (isset($matches[3]) && strlen($matches[3]) && + trim($matches[3]) != trim($this->config->get('php_suffix'))) { + $this->log(0, 'WARNING: php_bin ' . $this->config->get('php_bin') . + ' appears to have a suffix ' . $matches[3] . ', but' . + ' config variable php_suffix does not match'); + } + } - var $layers = array(); + + $this->current_callback = $callback; + if (PEAR_OS == "Windows") { + return $this->_build_win32($descfile, $callback); + } + if (PEAR_OS != 'Unix') { + return $this->raiseError("building extensions not supported on this platform"); + } + if (is_object($descfile)) { + $pkg = $descfile; + $descfile = $pkg->getPackageFile(); + if (is_a($pkg, 'PEAR_PackageFile_v1')) { + $dir = dirname($descfile); + } else { + $dir = $pkg->_config->get('temp_dir') . '/' . $pkg->getName(); + // automatically delete at session end + $this->addTempFile($dir); + } + } else { + $pf = &new PEAR_PackageFile($this->config); + $pkg = &$pf->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($pkg)) { + return $pkg; + } + $dir = dirname($descfile); + } + $old_cwd = getcwd(); + if (!file_exists($dir) || !is_dir($dir) || !chdir($dir)) { + return $this->raiseError("could not chdir to $dir"); + } + $vdir = $pkg->getPackage() . '-' . $pkg->getVersion(); + if (is_dir($vdir)) { + chdir($vdir); + } + $dir = getcwd(); + $this->log(2, "building in $dir"); + putenv('PATH=' . $this->config->get('bin_dir') . ':' . getenv('PATH')); + $err = $this->_runCommand($this->config->get('php_prefix') + . "phpize" . + $this->config->get('php_suffix'), + array(&$this, 'phpizeCallback')); + if (PEAR::isError($err)) { + return $err; + } + if (!$err) { + return $this->raiseError("`phpize' failed"); + } + + // {{{ start of interactive part + $configure_command = "$dir/configure"; + $configure_options = $pkg->getConfigureOptions(); + if ($configure_options) { + foreach ($configure_options as $o) { + $default = array_key_exists('default', $o) ? $o['default'] : null; + list($r) = $this->ui->userDialog('build', + array($o['prompt']), + array('text'), + array($default)); + if (substr($o['name'], 0, 5) == 'with-' && + ($r == 'yes' || $r == 'autodetect')) { + $configure_command .= " --$o[name]"; + } else { + $configure_command .= " --$o[name]=".trim($r); + } + } + } + // }}} end of interactive part + + // FIXME make configurable + if(!$user=getenv('USER')){ + $user='defaultuser'; + } + $build_basedir = "/var/tmp/pear-build-$user"; + $build_dir = "$build_basedir/$vdir"; + $inst_dir = "$build_basedir/install-$vdir"; + $this->log(1, "building in $build_dir"); + if (is_dir($build_dir)) { + System::rm(array('-rf', $build_dir)); + } + if (!System::mkDir(array('-p', $build_dir))) { + return $this->raiseError("could not create build dir: $build_dir"); + } + $this->addTempFile($build_dir); + if (!System::mkDir(array('-p', $inst_dir))) { + return $this->raiseError("could not create temporary install dir: $inst_dir"); + } + $this->addTempFile($inst_dir); + + if (getenv('MAKE')) { + $make_command = getenv('MAKE'); + } else { + $make_command = 'make'; + } + $to_run = array( + $configure_command, + $make_command, + "$make_command INSTALL_ROOT=\"$inst_dir\" install", + "find \"$inst_dir\" | xargs ls -dils" + ); + if (!file_exists($build_dir) || !is_dir($build_dir) || !chdir($build_dir)) { + return $this->raiseError("could not chdir to $build_dir"); + } + putenv('PHP_PEAR_VERSION=1.9.0'); + foreach ($to_run as $cmd) { + $err = $this->_runCommand($cmd, $callback); + if (PEAR::isError($err)) { + chdir($old_cwd); + return $err; + } + if (!$err) { + chdir($old_cwd); + return $this->raiseError("`$cmd' failed"); + } + } + if (!($dp = opendir("modules"))) { + chdir($old_cwd); + return $this->raiseError("no `modules' directory found"); + } + $built_files = array(); + $prefix = exec($this->config->get('php_prefix') + . "php-config" . + $this->config->get('php_suffix') . " --prefix"); + $this->_harvestInstDir($prefix, $inst_dir . DIRECTORY_SEPARATOR . $prefix, $built_files); + chdir($old_cwd); + return $built_files; + } /** - * Configuration data, two-dimensional array where the first - * dimension is the config layer ('user', 'system' and 'default'), - * and the second dimension is keyname => value. + * Message callback function used when running the "phpize" + * program. Extracts the API numbers used. Ignores other message + * types than "cmdoutput". * - * The order in the first dimension is important! Earlier - * layers will shadow later ones when a config value is - * requested (if a 'user' value exists, it will be returned first, - * then 'system' and finally 'default'). + * @param string $what the type of message + * @param mixed $data the message * - * @var array layer => array(keyname => value, ...) + * @return void + * + * @access public */ - var $configuration = array( - 'user' => array(), - 'system' => array(), - 'default' => array(), - ); + function phpizeCallback($what, $data) + { + if ($what != 'cmdoutput') { + return; + } + $this->log(1, rtrim($data)); + if (preg_match('/You should update your .aclocal.m4/', $data)) { + return; + } + $matches = array(); + if (preg_match('/^\s+(\S[^:]+):\s+(\d{8})/', $data, $matches)) { + $member = preg_replace('/[^a-z]/', '_', strtolower($matches[1])); + $apino = (int)$matches[2]; + if (isset($this->$member)) { + $this->$member = $apino; + //$msg = sprintf("%-22s : %d", $matches[1], $apino); + //$this->log(1, $msg); + } + } + } /** - * Configuration values that can be set for a channel + * Run an external command, using a message callback to report + * output. The command will be run through popen and output is + * reported for every line with a "cmdoutput" message with the + * line string, including newlines, as payload. + * + * @param string $command the command to run + * + * @param mixed $callback (optional) function to use as message + * callback + * + * @return bool whether the command was successful (exit code 0 + * means success, any other means failure) * - * All other configuration values can only have a global value - * @var array * @access private */ - var $_channelConfigInfo = array( - 'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'cfg_dir', - 'test_dir', 'www_dir', 'php_bin', 'php_prefix', 'php_suffix', 'username', - 'password', 'verbose', 'preferred_state', 'umask', 'preferred_mirror', 'php_ini' - ); + function _runCommand($command, $callback = null) + { + $this->log(1, "running: $command"); + $pp = popen("$command 2>&1", "r"); + if (!$pp) { + return $this->raiseError("failed to run `$command'"); + } + if ($callback && $callback[0]->debug == 1) { + $olddbg = $callback[0]->debug; + $callback[0]->debug = 2; + } - /** - * Channels that can be accessed - * @see setChannels() - * @var array - * @access private - */ - var $_channels = array('pear.php.net', 'pecl.php.net', '__uri'); + while ($line = fgets($pp, 1024)) { + if ($callback) { + call_user_func($callback, 'cmdoutput', $line); + } else { + $this->log(2, rtrim($line)); + } + } + if ($callback && isset($olddbg)) { + $callback[0]->debug = $olddbg; + } - /** - * This variable is used to control the directory values returned - * @see setInstallRoot(); - * @var string|false - * @access private - */ - var $_installRoot = false; + $exitcode = is_resource($pp) ? pclose($pp) : -1; + return ($exitcode == 0); + } - /** - * If requested, this will always refer to the registry - * contained in php_dir - * @var PEAR_Registry - */ - var $_registry = array(); + function log($level, $msg) + { + if ($this->current_callback) { + if ($this->debug >= $level) { + call_user_func($this->current_callback, 'output', $msg); + } + return; + } + return PEAR_Common::log($level, $msg); + } +}PEAR-1.9.0/PEAR/ChannelFile.php100664 764 764 143353 100664 10767 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: ChannelFile.php 286951 2009-08-09 14:41:22Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ - /** - * @var array - * @access private - */ - var $_regInitialized = array(); +/** + * Needed for error handling + */ +require_once 'PEAR/ErrorStack.php'; +require_once 'PEAR/XMLParser.php'; +require_once 'PEAR/Common.php'; - /** - * @var bool - * @access private - */ - var $_noRegistry = false; +/** + * Error code if the channel.xml tag does not contain a valid version + */ +define('PEAR_CHANNELFILE_ERROR_NO_VERSION', 1); +/** + * Error code if the channel.xml tag version is not supported (version 1.0 is the only supported version, + * currently + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_VERSION', 2); - /** - * amount of errors found while parsing config - * @var integer - * @access private - */ - var $_errorsFound = 0; - var $_lastError = null; +/** + * Error code if parsing is attempted with no xml extension + */ +define('PEAR_CHANNELFILE_ERROR_NO_XML_EXT', 3); - /** - * Information about the configuration data. Stores the type, - * default value and a documentation string for each configuration - * value. - * - * @var array layer => array(infotype => value, ...) - */ - var $configuration_info = array( - // Channels/Internet Access - 'default_channel' => array( - 'type' => 'string', - 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, - 'doc' => 'the default channel to use for all non explicit commands', - 'prompt' => 'Default Channel', - 'group' => 'Internet Access', - ), - 'preferred_mirror' => array( - 'type' => 'string', - 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, - 'doc' => 'the default server or mirror to use for channel actions', - 'prompt' => 'Default Channel Mirror', - 'group' => 'Internet Access', - ), - 'remote_config' => array( - 'type' => 'password', - 'default' => '', - 'doc' => 'ftp url of remote configuration file to use for synchronized install', - 'prompt' => 'Remote Configuration File', - 'group' => 'Internet Access', - ), - 'auto_discover' => array( - 'type' => 'integer', - 'default' => 0, - 'doc' => 'whether to automatically discover new channels', - 'prompt' => 'Auto-discover new Channels', - 'group' => 'Internet Access', - ), - // Internet Access - 'master_server' => array( - 'type' => 'string', - 'default' => 'pear.php.net', - 'doc' => 'name of the main PEAR server [NOT USED IN THIS VERSION]', - 'prompt' => 'PEAR server [DEPRECATED]', - 'group' => 'Internet Access', - ), - 'http_proxy' => array( - 'type' => 'string', - 'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY, - 'doc' => 'HTTP proxy (host:port) to use when downloading packages', - 'prompt' => 'HTTP Proxy Server Address', - 'group' => 'Internet Access', - ), - // File Locations - 'php_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_PHP_DIR, - 'doc' => 'directory where .php files are installed', - 'prompt' => 'PEAR directory', - 'group' => 'File Locations', - ), - 'ext_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_EXT_DIR, - 'doc' => 'directory where loadable extensions are installed', - 'prompt' => 'PHP extension directory', - 'group' => 'File Locations', - ), - 'doc_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_DOC_DIR, - 'doc' => 'directory where documentation is installed', - 'prompt' => 'PEAR documentation directory', - 'group' => 'File Locations', - ), - 'bin_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_BIN_DIR, - 'doc' => 'directory where executables are installed', - 'prompt' => 'PEAR executables directory', - 'group' => 'File Locations', - ), - 'data_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_DATA_DIR, - 'doc' => 'directory where data files are installed', - 'prompt' => 'PEAR data directory', - 'group' => 'File Locations (Advanced)', - ), - 'cfg_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_CFG_DIR, - 'doc' => 'directory where modifiable configuration files are installed', - 'prompt' => 'PEAR configuration file directory', - 'group' => 'File Locations (Advanced)', - ), - 'www_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_WWW_DIR, - 'doc' => 'directory where www frontend files (html/js) are installed', - 'prompt' => 'PEAR www files directory', - 'group' => 'File Locations (Advanced)', - ), - 'test_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_TEST_DIR, - 'doc' => 'directory where regression tests are installed', - 'prompt' => 'PEAR test directory', - 'group' => 'File Locations (Advanced)', - ), - 'cache_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR, - 'doc' => 'directory which is used for web service cache', - 'prompt' => 'PEAR Installer cache directory', - 'group' => 'File Locations (Advanced)', - ), - 'temp_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_TEMP_DIR, - 'doc' => 'directory which is used for all temp files', - 'prompt' => 'PEAR Installer temp directory', - 'group' => 'File Locations (Advanced)', - ), - 'download_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR, - 'doc' => 'directory which is used for all downloaded files', - 'prompt' => 'PEAR Installer download directory', - 'group' => 'File Locations (Advanced)', - ), - 'php_bin' => array( - 'type' => 'file', - 'default' => PEAR_CONFIG_DEFAULT_PHP_BIN, - 'doc' => 'PHP CLI/CGI binary for executing scripts', - 'prompt' => 'PHP CLI/CGI binary', - 'group' => 'File Locations (Advanced)', - ), - 'php_prefix' => array( - 'type' => 'string', - 'default' => '', - 'doc' => '--program-prefix for php_bin\'s ./configure, used for pecl installs', - 'prompt' => '--program-prefix passed to PHP\'s ./configure', - 'group' => 'File Locations (Advanced)', - ), - 'php_suffix' => array( - 'type' => 'string', - 'default' => '', - 'doc' => '--program-suffix for php_bin\'s ./configure, used for pecl installs', - 'prompt' => '--program-suffix passed to PHP\'s ./configure', - 'group' => 'File Locations (Advanced)', - ), - 'php_ini' => array( - 'type' => 'file', - 'default' => '', - 'doc' => 'location of php.ini in which to enable PECL extensions on install', - 'prompt' => 'php.ini location', - 'group' => 'File Locations (Advanced)', - ), - // Maintainers - 'username' => array( - 'type' => 'string', - 'default' => '', - 'doc' => '(maintainers) your PEAR account name', - 'prompt' => 'PEAR username (for maintainers)', - 'group' => 'Maintainers', - ), - 'password' => array( - 'type' => 'password', - 'default' => '', - 'doc' => '(maintainers) your PEAR account password', - 'prompt' => 'PEAR password (for maintainers)', - 'group' => 'Maintainers', - ), - // Advanced - 'verbose' => array( - 'type' => 'integer', - 'default' => PEAR_CONFIG_DEFAULT_VERBOSE, - 'doc' => 'verbosity level -0: really quiet -1: somewhat quiet -2: verbose -3: debug', - 'prompt' => 'Debug Log Level', - 'group' => 'Advanced', - ), - 'preferred_state' => array( - 'type' => 'set', - 'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE, - 'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified', - 'valid_set' => array( - 'stable', 'beta', 'alpha', 'devel', 'snapshot'), - 'prompt' => 'Preferred Package State', - 'group' => 'Advanced', - ), - 'umask' => array( - 'type' => 'mask', - 'default' => PEAR_CONFIG_DEFAULT_UMASK, - 'doc' => 'umask used when creating files (Unix-like systems only)', - 'prompt' => 'Unix file mask', - 'group' => 'Advanced', - ), - 'cache_ttl' => array( - 'type' => 'integer', - 'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL, - 'doc' => 'amount of secs where the local cache is used and not updated', - 'prompt' => 'Cache TimeToLive', - 'group' => 'Advanced', - ), - 'sig_type' => array( - 'type' => 'set', - 'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE, - 'doc' => 'which package signature mechanism to use', - 'valid_set' => array('gpg'), - 'prompt' => 'Package Signature Type', - 'group' => 'Maintainers', - ), - 'sig_bin' => array( - 'type' => 'string', - 'default' => PEAR_CONFIG_DEFAULT_SIG_BIN, - 'doc' => 'which package signature mechanism to use', - 'prompt' => 'Signature Handling Program', - 'group' => 'Maintainers', - ), - 'sig_keyid' => array( - 'type' => 'string', - 'default' => '', - 'doc' => 'which key to use for signing with', - 'prompt' => 'Signature Key Id', - 'group' => 'Maintainers', - ), - 'sig_keydir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR, - 'doc' => 'directory where signature keys are located', - 'prompt' => 'Signature Key Directory', - 'group' => 'Maintainers', - ), - // __channels is reserved - used for channel-specific configuration - ); - - /** - * Constructor. - * - * @param string file to read user-defined options from - * @param string file to read system-wide defaults from - * @param bool determines whether a registry object "follows" - * the value of php_dir (is automatically created - * and moved when php_dir is changed) - * @param bool if true, fails if configuration files cannot be loaded - * - * @access public - * - * @see PEAR_Config::singleton - */ - function PEAR_Config($user_file = '', $system_file = '', $ftp_file = false, - $strict = true) - { - $this->PEAR(); - PEAR_Installer_Role::initializeConfig($this); - $sl = DIRECTORY_SEPARATOR; - if (empty($user_file)) { - if (OS_WINDOWS) { - $user_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini'; - } else { - $user_file = getenv('HOME') . $sl . '.pearrc'; - } - } - - if (empty($system_file)) { - $system_file = PEAR_CONFIG_SYSCONFDIR . $sl; - if (OS_WINDOWS) { - $system_file .= 'pearsys.ini'; - } else { - $system_file .= 'pear.conf'; - } - } - - $this->layers = array_keys($this->configuration); - $this->files['user'] = $user_file; - $this->files['system'] = $system_file; - if ($user_file && file_exists($user_file)) { - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $this->readConfigFile($user_file, 'user', $strict); - $this->popErrorHandling(); - if ($this->_errorsFound > 0) { - return; - } - } - - if ($system_file && @file_exists($system_file)) { - $this->mergeConfigFile($system_file, false, 'system', $strict); - if ($this->_errorsFound > 0) { - return; - } - - } +/** + * Error code if creating the xml parser resource fails + */ +define('PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER', 4); - if (!$ftp_file) { - $ftp_file = $this->get('remote_config'); - } +/** + * Error code used for all sax xml parsing errors + */ +define('PEAR_CHANNELFILE_ERROR_PARSER_ERROR', 5); - if ($ftp_file && defined('PEAR_REMOTEINSTALL_OK')) { - $this->readFTPConfigFile($ftp_file); - } +/**#@+ + * Validation errors + */ +/** + * Error code when channel name is missing + */ +define('PEAR_CHANNELFILE_ERROR_NO_NAME', 6); +/** + * Error code when channel name is invalid + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_NAME', 7); +/** + * Error code when channel summary is missing + */ +define('PEAR_CHANNELFILE_ERROR_NO_SUMMARY', 8); +/** + * Error code when channel summary is multi-line + */ +define('PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY', 9); +/** + * Error code when channel server is missing for protocol + */ +define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10); +/** + * Error code when channel server is invalid for protocol + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_HOST', 11); +/** + * Error code when a mirror name is invalid + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_MIRROR', 21); +/** + * Error code when a mirror type is invalid + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE', 22); +/** + * Error code when an attempt is made to generate xml, but the parsed content is invalid + */ +define('PEAR_CHANNELFILE_ERROR_INVALID', 23); +/** + * Error code when an empty package name validate regex is passed in + */ +define('PEAR_CHANNELFILE_ERROR_EMPTY_REGEX', 24); +/** + * Error code when a tag has no version + */ +define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION', 25); +/** + * Error code when a tag has no name + */ +define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME', 26); +/** + * Error code when a tag has no name + */ +define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME', 27); +/** + * Error code when a tag has no version attribute + */ +define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION', 28); +/** + * Error code when a mirror does not exist but is called for in one of the set* + * methods. + */ +define('PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND', 32); +/** + * Error code when a server port is not numeric + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_PORT', 33); +/** + * Error code when contains no version attribute + */ +define('PEAR_CHANNELFILE_ERROR_NO_STATICVERSION', 34); +/** + * Error code when contains no type attribute in a protocol definition + */ +define('PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE', 35); +/** + * Error code when a mirror is defined and the channel.xml represents the __uri pseudo-channel + */ +define('PEAR_CHANNELFILE_URI_CANT_MIRROR', 36); +/** + * Error code when ssl attribute is present and is not "yes" + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_SSL', 37); +/**#@-*/ - foreach ($this->configuration_info as $key => $info) { - $this->configuration['default'][$key] = $info['default']; - } +/** + * Mirror types allowed. Currently only internet servers are recognized. + */ +$GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] = array('server'); - $this->_registry['default'] = &new PEAR_Registry($this->configuration['default']['php_dir']); - $this->_registry['default']->setConfig($this, false); - $this->_regInitialized['default'] = false; - //$GLOBALS['_PEAR_Config_instance'] = &$this; - } +/** + * The Channel handling class + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_ChannelFile +{ /** - * Return the default locations of user and system configuration files - * @static + * @access private + * @var PEAR_ErrorStack + * @access private */ - function getDefaultConfigFiles() - { - $sl = DIRECTORY_SEPARATOR; - if (OS_WINDOWS) { - return array( - 'user' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini', - 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini' - ); - } - - return array( - 'user' => getenv('HOME') . $sl . '.pearrc', - 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf' - ); - } + var $_stack; /** - * Static singleton method. If you want to keep only one instance - * of this class in use, this method will give you a reference to - * the last created PEAR_Config object if one exists, or create a - * new object. - * - * @param string (optional) file to read user-defined options from - * @param string (optional) file to read system-wide defaults from - * - * @return object an existing or new PEAR_Config instance - * - * @access public - * - * @see PEAR_Config::PEAR_Config + * Supported channel.xml versions, for parsing + * @var array + * @access private */ - function &singleton($user_file = '', $system_file = '', $strict = true) - { - if (is_object($GLOBALS['_PEAR_Config_instance'])) { - return $GLOBALS['_PEAR_Config_instance']; - } - - $t_conf = &new PEAR_Config($user_file, $system_file, false, $strict); - if ($t_conf->_errorsFound > 0) { - return $t_conf->lastError; - } - - $GLOBALS['_PEAR_Config_instance'] = &$t_conf; - return $GLOBALS['_PEAR_Config_instance']; - } + var $_supportedVersions = array('1.0'); /** - * Determine whether any configuration files have been detected, and whether a - * registry object can be retrieved from this configuration. - * @return bool - * @since PEAR 1.4.0a1 + * Parsed channel information + * @var array + * @access private */ - function validConfiguration() - { - if ($this->isDefinedLayer('user') || $this->isDefinedLayer('system')) { - return true; - } - - return false; - } + var $_channelInfo; /** - * Reads configuration data from a file. All existing values in - * the config layer are discarded and replaced with data from the - * file. - * @param string file to read from, if NULL or not specified, the - * last-used file for the same layer (second param) is used - * @param string config layer to insert data into ('user' or 'system') - * @return bool TRUE on success or a PEAR error on failure + * index into the subchannels array, used for parsing xml + * @var int + * @access private */ - function readConfigFile($file = null, $layer = 'user', $strict = true) - { - if (empty($this->files[$layer])) { - return $this->raiseError("unknown config layer `$layer'"); - } - - if ($file === null) { - $file = $this->files[$layer]; - } - - $data = $this->_readConfigDataFrom($file); - if (PEAR::isError($data)) { - if (!$strict) { - return true; - } + var $_subchannelIndex; - $this->_errorsFound++; - $this->lastError = $data; + /** + * index into the mirrors array, used for parsing xml + * @var int + * @access private + */ + var $_mirrorIndex; - return $data; - } + /** + * Flag used to determine the validity of parsed content + * @var boolean + * @access private + */ + var $_isValid = false; - $this->files[$layer] = $file; - $this->_decodeInput($data); - $this->configuration[$layer] = $data; - $this->_setupChannels(); - if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { - $this->_registry[$layer] = &new PEAR_Registry($phpdir); - $this->_registry[$layer]->setConfig($this, false); - $this->_regInitialized[$layer] = false; - } else { - unset($this->_registry[$layer]); - } - return true; + function PEAR_ChannelFile() + { + $this->_stack = &new PEAR_ErrorStack('PEAR_ChannelFile'); + $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); + $this->_isValid = false; } /** - * @param string url to the remote config file, like ftp://www.example.com/pear/config.ini - * @return true|PEAR_Error + * @return array + * @access protected */ - function readFTPConfigFile($path) + function _getErrorMessage() { - do { // poor man's try - if (!class_exists('PEAR_FTP')) { - if (!class_exists('PEAR_Common')) { - require_once 'PEAR/Common.php'; - } - if (PEAR_Common::isIncludeable('PEAR/FTP.php')) { - require_once 'PEAR/FTP.php'; - } - } - - if (!class_exists('PEAR_FTP')) { - return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config'); - } - - $this->_ftp = &new PEAR_FTP; - $this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN); - $e = $this->_ftp->init($path); - if (PEAR::isError($e)) { - $this->_ftp->popErrorHandling(); - return $e; - } - - $tmp = System::mktemp('-d'); - PEAR_Common::addTempFile($tmp); - $e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR . - 'pear.ini', false, FTP_BINARY); - if (PEAR::isError($e)) { - $this->_ftp->popErrorHandling(); - return $e; - } + return + array( + PEAR_CHANNELFILE_ERROR_INVALID_VERSION => + 'While parsing channel.xml, an invalid version number "%version% was passed in, expecting one of %versions%', + PEAR_CHANNELFILE_ERROR_NO_VERSION => + 'No version number found in tag', + PEAR_CHANNELFILE_ERROR_NO_XML_EXT => + '%error%', + PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER => + 'Unable to create XML parser', + PEAR_CHANNELFILE_ERROR_PARSER_ERROR => + '%error%', + PEAR_CHANNELFILE_ERROR_NO_NAME => + 'Missing channel name', + PEAR_CHANNELFILE_ERROR_INVALID_NAME => + 'Invalid channel %tag% "%name%"', + PEAR_CHANNELFILE_ERROR_NO_SUMMARY => + 'Missing channel summary', + PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY => + 'Channel summary should be on one line, but is multi-line', + PEAR_CHANNELFILE_ERROR_NO_HOST => + 'Missing channel server for %type% server', + PEAR_CHANNELFILE_ERROR_INVALID_HOST => + 'Server name "%server%" is invalid for %type% server', + PEAR_CHANNELFILE_ERROR_INVALID_MIRROR => + 'Invalid mirror name "%name%", mirror type %type%', + PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE => + 'Invalid mirror type "%type%"', + PEAR_CHANNELFILE_ERROR_INVALID => + 'Cannot generate xml, contents are invalid', + PEAR_CHANNELFILE_ERROR_EMPTY_REGEX => + 'packagenameregex cannot be empty', + PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION => + '%parent% %protocol% function has no version', + PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME => + '%parent% %protocol% function has no name', + PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE => + '%parent% rest baseurl has no type', + PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME => + 'Validation package has no name in tag', + PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION => + 'Validation package "%package%" has no version', + PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND => + 'Mirror "%mirror%" does not exist', + PEAR_CHANNELFILE_ERROR_INVALID_PORT => + 'Port "%port%" must be numeric', + PEAR_CHANNELFILE_ERROR_NO_STATICVERSION => + ' tag must contain version attribute', + PEAR_CHANNELFILE_URI_CANT_MIRROR => + 'The __uri pseudo-channel cannot have mirrors', + PEAR_CHANNELFILE_ERROR_INVALID_SSL => + '%server% has invalid ssl attribute "%ssl%" can only be yes or not present', + ); + } - PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini'); - $this->_ftp->disconnect(); - $this->_ftp->popErrorHandling(); - $this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini'; - $e = $this->readConfigFile(null, 'ftp'); - if (PEAR::isError($e)) { - return $e; + /** + * @param string contents of package.xml file + * @return bool success of parsing + */ + function fromXmlString($data) + { + if (preg_match('/_supportedVersions)) { + $this->_stack->push(PEAR_CHANNELFILE_ERROR_INVALID_VERSION, 'error', + array('version' => $channelversion[1])); + return false; } - - $fail = array(); - foreach ($this->configuration_info as $key => $val) { - if (in_array($this->getGroup($key), - array('File Locations', 'File Locations (Advanced)')) && - $this->getType($key) == 'directory') { - // any directory configs must be set for this to work - if (!isset($this->configuration['ftp'][$key])) { - $fail[] = $key; - } + $parser = new PEAR_XMLParser; + $result = $parser->parse($data); + if ($result !== true) { + if ($result->getCode() == 1) { + $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_XML_EXT, 'error', + array('error' => $result->getMessage())); + } else { + $this->_stack->push(PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER, 'error'); } + return false; } - - if (!count($fail)) { - return true; - } - - $fail = '"' . implode('", "', $fail) . '"'; - unset($this->files['ftp']); - unset($this->configuration['ftp']); - return PEAR::raiseError('ERROR: Ftp configuration file must set all ' . - 'directory configuration variables. These variables were not set: ' . - $fail); - } while (false); // poor man's catch - unset($this->files['ftp']); - return PEAR::raiseError('no remote host specified'); + $this->_channelInfo = $parser->getData(); + return true; + } else { + $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_VERSION, 'error', array('xml' => $data)); + return false; + } } /** - * Reads the existing configurations and creates the _channels array from it + * @return array */ - function _setupChannels() + function toArray() { - $set = array_flip(array_values($this->_channels)); - foreach ($this->configuration as $layer => $data) { - $i = 1000; - if (isset($data['__channels']) && is_array($data['__channels'])) { - foreach ($data['__channels'] as $channel => $info) { - $set[$channel] = $i++; - } - } + if (!$this->_isValid && !$this->validate()) { + return false; } - $this->_channels = array_values(array_flip($set)); - $this->setChannels($this->_channels); + return $this->_channelInfo; } - function deleteChannel($channel) + /** + * @param array + * @static + * @return PEAR_ChannelFile|false false if invalid + */ + function &fromArray($data, $compatibility = false, $stackClass = 'PEAR_ErrorStack') { - $ch = strtolower($channel); - foreach ($this->configuration as $layer => $data) { - if (isset($data['__channels']) && isset($data['__channels'][$ch])) { - unset($this->configuration[$layer]['__channels'][$ch]); - } + $a = new PEAR_ChannelFile($compatibility, $stackClass); + $a->_fromArray($data); + if (!$a->validate()) { + $a = false; + return $a; } + return $a; + } - $this->_channels = array_flip($this->_channels); - unset($this->_channels[$ch]); - $this->_channels = array_flip($this->_channels); + /** + * Unlike {@link fromArray()} this does not do any validation + * @param array + * @static + * @return PEAR_ChannelFile + */ + function &fromArrayWithErrors($data, $compatibility = false, + $stackClass = 'PEAR_ErrorStack') + { + $a = new PEAR_ChannelFile($compatibility, $stackClass); + $a->_fromArray($data); + return $a; } /** - * Merges data into a config layer from a file. Does the same - * thing as readConfigFile, except it does not replace all - * existing values in the config layer. - * @param string file to read from - * @param bool whether to overwrite existing data (default TRUE) - * @param string config layer to insert data into ('user' or 'system') - * @param string if true, errors are returned if file opening fails - * @return bool TRUE on success or a PEAR error on failure + * @param array + * @access private */ - function mergeConfigFile($file, $override = true, $layer = 'user', $strict = true) + function _fromArray($data) { - if (empty($this->files[$layer])) { - return $this->raiseError("unknown config layer `$layer'"); - } + $this->_channelInfo = $data; + } - if ($file === null) { - $file = $this->files[$layer]; - } + /** + * Wrapper to {@link PEAR_ErrorStack::getErrors()} + * @param boolean determines whether to purge the error stack after retrieving + * @return array + */ + function getErrors($purge = false) + { + return $this->_stack->getErrors($purge); + } - $data = $this->_readConfigDataFrom($file); - if (PEAR::isError($data)) { - if (!$strict) { - return true; + /** + * Unindent given string (?) + * + * @param string $str The string that has to be unindented. + * @return string + * @access private + */ + function _unIndent($str) + { + // remove leading newlines + $str = preg_replace('/^[\r\n]+/', '', $str); + // find whitespace at the beginning of the first line + $indent_len = strspn($str, " \t"); + $indent = substr($str, 0, $indent_len); + $data = ''; + // remove the same amount of whitespace from following lines + foreach (explode("\n", $str) as $line) { + if (substr($line, 0, $indent_len) == $indent) { + $data .= substr($line, $indent_len) . "\n"; } - - $this->_errorsFound++; - $this->lastError = $data; - - return $data; } + return $data; + } - $this->_decodeInput($data); - if ($override) { - $this->configuration[$layer] = - PEAR_Config::arrayMergeRecursive($this->configuration[$layer], $data); - } else { - $this->configuration[$layer] = - PEAR_Config::arrayMergeRecursive($data, $this->configuration[$layer]); + /** + * Parse a channel.xml file. Expects the name of + * a channel xml file as input. + * + * @param string $descfile name of channel xml file + * @return bool success of parsing + */ + function fromXmlFile($descfile) + { + if (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) || + (!$fp = fopen($descfile, 'r'))) { + require_once 'PEAR.php'; + return PEAR::raiseError("Unable to open $descfile"); } - $this->_setupChannels(); - if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { - $this->_registry[$layer] = &new PEAR_Registry($phpdir); - $this->_registry[$layer]->setConfig($this, false); - $this->_regInitialized[$layer] = false; - } else { - unset($this->_registry[$layer]); - } - return true; + // read the whole thing so we only get one cdata callback + // for each block of cdata + fclose($fp); + $data = file_get_contents($descfile); + return $this->fromXmlString($data); } /** - * @param array - * @param array - * @return array - * @static + * Parse channel information from different sources + * + * This method is able to extract information about a channel + * from an .xml file or a string + * + * @access public + * @param string Filename of the source or the source itself + * @return bool */ - function arrayMergeRecursive($arr2, $arr1) + function fromAny($info) { - $ret = array(); - foreach ($arr2 as $key => $data) { - if (!isset($arr1[$key])) { - $ret[$key] = $data; - unset($arr1[$key]); - continue; - } - if (is_array($data)) { - if (!is_array($arr1[$key])) { - $ret[$key] = $arr1[$key]; - unset($arr1[$key]); - continue; + if (is_string($info) && file_exists($info) && strlen($info) < 255) { + $tmp = substr($info, -4); + if ($tmp == '.xml') { + $info = $this->fromXmlFile($info); + } else { + $fp = fopen($info, "r"); + $test = fread($fp, 5); + fclose($fp); + if ($test == "fromXmlFile($info); } - $ret[$key] = PEAR_Config::arrayMergeRecursive($arr1[$key], $arr2[$key]); - unset($arr1[$key]); + } + if (PEAR::isError($info)) { + require_once 'PEAR.php'; + return PEAR::raiseError($info); } } - - return array_merge($ret, $arr1); + if (is_string($info)) { + $info = $this->fromXmlString($info); + } + return $info; } /** - * Writes data into a config layer from a file. + * Return an XML document based on previous parsing and modifications * - * @param string|null file to read from, or null for default - * @param string config layer to insert data into ('user' or - * 'system') - * @param string|null data to write to config file or null for internal data [DEPRECATED] - * @return bool TRUE on success or a PEAR error on failure + * @return string XML data + * + * @access public */ - function writeConfigFile($file = null, $layer = 'user', $data = null) + function toXml() { - $this->_lazyChannelSetup($layer); - if ($layer == 'both' || $layer == 'all') { - foreach ($this->files as $type => $file) { - $err = $this->writeConfigFile($file, $type, $data); - if (PEAR::isError($err)) { - return $err; - } - } - return true; + if (!$this->_isValid && !$this->validate()) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID); + return false; } - - if (empty($this->files[$layer])) { - return $this->raiseError("unknown config file type `$layer'"); + if (!isset($this->_channelInfo['attribs']['version'])) { + $this->_channelInfo['attribs']['version'] = '1.0'; } - - if ($file === null) { - $file = $this->files[$layer]; + $channelInfo = $this->_channelInfo; + $ret = "\n"; + $ret .= " + $channelInfo[name] + " . htmlspecialchars($channelInfo['summary'])." +"; + if (isset($channelInfo['suggestedalias'])) { + $ret .= ' ' . $channelInfo['suggestedalias'] . "\n"; } - - $data = ($data === null) ? $this->configuration[$layer] : $data; - $this->_encodeOutput($data); - $opt = array('-p', dirname($file)); - if (!@System::mkDir($opt)) { - return $this->raiseError("could not create directory: " . dirname($file)); + if (isset($channelInfo['validatepackage'])) { + $ret .= ' ' . + htmlspecialchars($channelInfo['validatepackage']['_content']) . + "\n"; } - - if (file_exists($file) && is_file($file) && !is_writeable($file)) { - return $this->raiseError("no write access to $file!"); + $ret .= " \n"; + $ret .= ' raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed ($php_errormsg)"); + if (isset($channelInfo['servers']['primary']['attribs']['port'])) { + $ret .= ' port="' . $channelInfo['servers']['primary']['attribs']['port'] . '"'; } - - $contents = "#PEAR_Config 0.9\n" . serialize($data); - if (!@fwrite($fp, $contents)) { - return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed ($php_errormsg)"); + $ret .= ">\n"; + if (isset($channelInfo['servers']['primary']['rest'])) { + $ret .= $this->_makeRestXml($channelInfo['servers']['primary']['rest'], ' '); } - return true; + $ret .= " \n"; + if (isset($channelInfo['servers']['mirror'])) { + $ret .= $this->_makeMirrorsXml($channelInfo); + } + $ret .= " \n"; + $ret .= ""; + return str_replace("\r", "\n", str_replace("\r\n", "\n", $ret)); } /** - * Reads configuration data from a file and returns the parsed data - * in an array. - * - * @param string file to read from - * @return array configuration data or a PEAR error on failure + * Generate the tag * @access private */ - function _readConfigDataFrom($file) + function _makeRestXml($info, $indent) { - $fp = false; - if (file_exists($file)) { - $fp = @fopen($file, "r"); + $ret = $indent . "\n"; + if (isset($info['baseurl']) && !isset($info['baseurl'][0])) { + $info['baseurl'] = array($info['baseurl']); } - if (!$fp) { - return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed"); + if (isset($info['baseurl'])) { + foreach ($info['baseurl'] as $url) { + $ret .= "$indent \n"; + } } + $ret .= $indent . "\n"; + return $ret; + } - $size = filesize($file); - $rt = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - fclose($fp); - $contents = file_get_contents($file); - if (empty($contents)) { - return $this->raiseError('Configuration file "' . $file . '" is empty'); + /** + * Generate the tag + * @access private + */ + function _makeMirrorsXml($channelInfo) + { + $ret = ""; + if (!isset($channelInfo['servers']['mirror'][0])) { + $channelInfo['servers']['mirror'] = array($channelInfo['servers']['mirror']); } - - set_magic_quotes_runtime($rt); - - $version = false; - if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) { - $version = $matches[1]; - $contents = substr($contents, strlen($matches[0])); - } else { - // Museum config file - if (substr($contents,0,2) == 'a:') { - $version = '0.1'; + foreach ($channelInfo['servers']['mirror'] as $mirror) { + $ret .= ' raiseError("PEAR_Config: bad data in $file"); - return $err; - } + if (isset($mirror['attribs']['ssl'])) { + $ret .= ' ssl="' . $mirror['attribs']['ssl'] . '"'; } - if (!is_array($data)) { - if (strlen(trim($contents)) > 0) { - $error = "PEAR_Config: bad data in $file"; - $err = $this->raiseError($error); - return $err; + $ret .= ">\n"; + if (isset($mirror['rest'])) { + if (isset($mirror['rest'])) { + $ret .= $this->_makeRestXml($mirror['rest'], ' '); } - - $data = array(); + $ret .= " \n"; + } else { + $ret .= "/>\n"; } - // add parsing of newer formats here... - } else { - $err = $this->raiseError("$file: unknown version `$version'"); - return $err; } - - return $data; - } - - /** - * Gets the file used for storing the config for a layer - * - * @param string $layer 'user' or 'system' - */ - function getConfFile($layer) - { - return $this->files[$layer]; + return $ret; } /** - * @param string Configuration class name, used for detecting duplicate calls - * @param array information on a role as parsed from its xml file - * @return true|PEAR_Error + * Generate the tag * @access private */ - function _addConfigVars($class, $vars) + function _makeFunctionsXml($functions, $indent, $rest = false) { - static $called = array(); - if (isset($called[$class])) { - return; + $ret = ''; + if (!isset($functions[0])) { + $functions = array($functions); } - - $called[$class] = 1; - if (count($vars) > 3) { - return $this->raiseError('Roles can only define 3 new config variables or less'); - } - - foreach ($vars as $name => $var) { - if (!is_array($var)) { - return $this->raiseError('Configuration information must be an array'); - } - - if (!isset($var['type'])) { - return $this->raiseError('Configuration information must contain a type'); - } elseif (!in_array($var['type'], - array('string', 'mask', 'password', 'directory', 'file', 'set'))) { - return $this->raiseError( - 'Configuration type must be one of directory, file, string, ' . - 'mask, set, or password'); - } - if (!isset($var['default'])) { - return $this->raiseError( - 'Configuration information must contain a default value ("default" index)'); + foreach ($functions as $function) { + $ret .= "$indent\n"; + } + return $ret; + } - if (is_array($var['default'])) { - $real_default = ''; - foreach ($var['default'] as $config_var => $val) { - if (strpos($config_var, 'text') === 0) { - $real_default .= $val; - } elseif (strpos($config_var, 'constant') === 0) { - if (!defined($val)) { - return $this->raiseError( - 'Unknown constant "' . $val . '" requested in ' . - 'default value for configuration variable "' . - $name . '"'); - } + /** + * Validation error. Also marks the object contents as invalid + * @param error code + * @param array error information + * @access private + */ + function _validateError($code, $params = array()) + { + $this->_stack->push($code, 'error', $params); + $this->_isValid = false; + } - $real_default .= constant($val); - } elseif (isset($this->configuration_info[$config_var])) { - $real_default .= - $this->configuration_info[$config_var]['default']; - } else { - return $this->raiseError( - 'Unknown request for "' . $config_var . '" value in ' . - 'default value for configuration variable "' . - $name . '"'); - } - } - $var['default'] = $real_default; - } + /** + * Validation warning. Does not mark the object contents invalid. + * @param error code + * @param array error information + * @access private + */ + function _validateWarning($code, $params = array()) + { + $this->_stack->push($code, 'warning', $params); + } - if ($var['type'] == 'integer') { - $var['default'] = (integer) $var['default']; + /** + * Validate parsed file. + * + * @access public + * @return boolean + */ + function validate() + { + $this->_isValid = true; + $info = $this->_channelInfo; + if (empty($info['name'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_NAME); + } elseif (!$this->validChannelServer($info['name'])) { + if ($info['name'] != '__uri') { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name', + 'name' => $info['name'])); } - - if (!isset($var['doc'])) { - return $this->raiseError( - 'Configuration information must contain a summary ("doc" index)'); + } + if (empty($info['summary'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY); + } elseif (strpos(trim($info['summary']), "\n") !== false) { + $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY, + array('summary' => $info['summary'])); + } + if (isset($info['suggestedalias'])) { + if (!$this->validChannelServer($info['suggestedalias'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, + array('tag' => 'suggestedalias', 'name' =>$info['suggestedalias'])); } - - if (!isset($var['prompt'])) { - return $this->raiseError( - 'Configuration information must contain a simple prompt ("prompt" index)'); + } + if (isset($info['localalias'])) { + if (!$this->validChannelServer($info['localalias'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, + array('tag' => 'localalias', 'name' =>$info['localalias'])); } - - if (!isset($var['group'])) { - return $this->raiseError( - 'Configuration information must contain a simple group ("group" index)'); + } + if (isset($info['validatepackage'])) { + if (!isset($info['validatepackage']['_content'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME); } - - if (isset($this->configuration_info[$name])) { - return $this->raiseError('Configuration variable "' . $name . - '" already exists'); + if (!isset($info['validatepackage']['attribs']['version'])) { + $content = isset($info['validatepackage']['_content']) ? + $info['validatepackage']['_content'] : + null; + $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION, + array('package' => $content)); } + } - $this->configuration_info[$name] = $var; - // fix bug #7351: setting custom config variable in a channel fails - $this->_channelConfigInfo[] = $name; + if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['port']) && + !is_numeric($info['servers']['primary']['attribs']['port'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT, + array('port' => $info['servers']['primary']['attribs']['port'])); } - return true; - } + if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['ssl']) && + $info['servers']['primary']['attribs']['ssl'] != 'yes') { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL, + array('ssl' => $info['servers']['primary']['attribs']['ssl'], + 'server' => $info['name'])); + } - /** - * Encodes/scrambles configuration data before writing to files. - * Currently, 'password' values will be base64-encoded as to avoid - * that people spot cleartext passwords by accident. - * - * @param array (reference) array to encode values in - * @return bool TRUE on success - * @access private - */ - function _encodeOutput(&$data) - { - foreach ($data as $key => $value) { - if ($key == '__channels') { - foreach ($data['__channels'] as $channel => $blah) { - $this->_encodeOutput($data['__channels'][$channel]); - } + if (isset($info['servers']['primary']['rest']) && + isset($info['servers']['primary']['rest']['baseurl'])) { + $this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']); + } + if (isset($info['servers']['mirror'])) { + if ($this->_channelInfo['name'] == '__uri') { + $this->_validateError(PEAR_CHANNELFILE_URI_CANT_MIRROR); } - - if (!isset($this->configuration_info[$key])) { - continue; + if (!isset($info['servers']['mirror'][0])) { + $info['servers']['mirror'] = array($info['servers']['mirror']); } - - $type = $this->configuration_info[$key]['type']; - switch ($type) { - // we base64-encode passwords so they are at least - // not shown in plain by accident - case 'password': { - $data[$key] = base64_encode($data[$key]); - break; + foreach ($info['servers']['mirror'] as $mirror) { + if (!isset($mirror['attribs']['host'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST, + array('type' => 'mirror')); + } elseif (!$this->validChannelServer($mirror['attribs']['host'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_HOST, + array('server' => $mirror['attribs']['host'], 'type' => 'mirror')); } - case 'mask': { - $data[$key] = octdec($data[$key]); - break; + if (isset($mirror['attribs']['ssl']) && $mirror['attribs']['ssl'] != 'yes') { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL, + array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host'])); + } + if (isset($mirror['rest'])) { + $this->_validateFunctions('rest', $mirror['rest']['baseurl'], + $mirror['attribs']['host']); } } } - - return true; + return $this->_isValid; } /** - * Decodes/unscrambles configuration data after reading from files. - * - * @param array (reference) array to encode values in - * @return bool TRUE on success - * @access private - * - * @see PEAR_Config::_encodeOutput + * @param string rest - protocol name this function applies to + * @param array the functions + * @param string the name of the parent element (mirror name, for instance) */ - function _decodeInput(&$data) + function _validateFunctions($protocol, $functions, $parent = '') { - if (!is_array($data)) { - return true; + if (!isset($functions[0])) { + $functions = array($functions); } - foreach ($data as $key => $value) { - if ($key == '__channels') { - foreach ($data['__channels'] as $channel => $blah) { - $this->_decodeInput($data['__channels'][$channel]); - } - } - - if (!isset($this->configuration_info[$key])) { - continue; + foreach ($functions as $function) { + if (!isset($function['_content']) || empty($function['_content'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME, + array('parent' => $parent, 'protocol' => $protocol)); } - $type = $this->configuration_info[$key]['type']; - switch ($type) { - case 'password': { - $data[$key] = base64_decode($data[$key]); - break; + if ($protocol == 'rest') { + if (!isset($function['attribs']['type']) || + empty($function['attribs']['type'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE, + array('parent' => $parent, 'protocol' => $protocol)); } - case 'mask': { - $data[$key] = decoct($data[$key]); - break; + } else { + if (!isset($function['attribs']['version']) || + empty($function['attribs']['version'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION, + array('parent' => $parent, 'protocol' => $protocol)); } } } - - return true; } /** - * Retrieve the default channel. - * - * On startup, channels are not initialized, so if the default channel is not - * pear.php.net, then initialize the config. - * @param string registry layer - * @return string|false + * Test whether a string contains a valid channel server. + * @param string $ver the package version to test + * @return bool */ - function getDefaultChannel($layer = null) + function validChannelServer($server) { - $ret = false; - if ($layer === null) { - foreach ($this->layers as $layer) { - if (isset($this->configuration[$layer]['default_channel'])) { - $ret = $this->configuration[$layer]['default_channel']; - break; - } - } - } elseif (isset($this->configuration[$layer]['default_channel'])) { - $ret = $this->configuration[$layer]['default_channel']; + if ($server == '__uri') { + return true; } + return (bool) preg_match(PEAR_CHANNELS_SERVER_PREG, $server); + } - if ($ret == 'pear.php.net' && defined('PEAR_RUNTYPE') && PEAR_RUNTYPE == 'pecl') { - $ret = 'pecl.php.net'; + /** + * @return string|false + */ + function getName() + { + if (isset($this->_channelInfo['name'])) { + return $this->_channelInfo['name']; } - if ($ret) { - if ($ret != 'pear.php.net') { - $this->_lazyChannelSetup(); - } + return false; + } - return $ret; + /** + * @return string|false + */ + function getServer() + { + if (isset($this->_channelInfo['name'])) { + return $this->_channelInfo['name']; } - return PEAR_CONFIG_DEFAULT_CHANNEL; + return false; } /** - * Returns a configuration value, prioritizing layers as per the - * layers property. - * - * @param string config key - * @return mixed the config value, or NULL if not found - * @access public + * @return int|80 port number to connect to */ - function get($key, $layer = null, $channel = false) + function getPort($mirror = false) { - if (!isset($this->configuration_info[$key])) { - return null; - } + if ($mirror) { + if ($mir = $this->getMirror($mirror)) { + if (isset($mir['attribs']['port'])) { + return $mir['attribs']['port']; + } - if ($key == '__channels') { - return null; - } + if ($this->getSSL($mirror)) { + return 443; + } - if ($key == 'default_channel') { - return $this->getDefaultChannel($layer); - } + return 80; + } - if (!$channel) { - $channel = $this->getDefaultChannel(); - } elseif ($channel != 'pear.php.net') { - $this->_lazyChannelSetup(); + return false; } - $channel = strtolower($channel); - $test = (in_array($key, $this->_channelConfigInfo)) ? - $this->_getChannelValue($key, $layer, $channel) : - null; - if ($test !== null) { - if ($this->_installRoot) { - if (in_array($this->getGroup($key), - array('File Locations', 'File Locations (Advanced)')) && - $this->getType($key) == 'directory') { - return $this->_prependPath($test, $this->_installRoot); - } - } - return $test; + if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) { + return $this->_channelInfo['servers']['primary']['attribs']['port']; } - if ($layer === null) { - foreach ($this->layers as $layer) { - if (isset($this->configuration[$layer][$key])) { - $test = $this->configuration[$layer][$key]; - if ($this->_installRoot) { - if (in_array($this->getGroup($key), - array('File Locations', 'File Locations (Advanced)')) && - $this->getType($key) == 'directory') { - return $this->_prependPath($test, $this->_installRoot); - } - } + if ($this->getSSL()) { + return 443; + } - if ($key == 'preferred_mirror') { - $reg = &$this->getRegistry(); - if (is_object($reg)) { - $chan = &$reg->getChannel($channel); - if (PEAR::isError($chan)) { - return $channel; - } + return 80; + } - if (!$chan->getMirror($test) && $chan->getName() != $test) { - return $channel; // mirror does not exist - } - } - } - return $test; - } - } - } elseif (isset($this->configuration[$layer][$key])) { - $test = $this->configuration[$layer][$key]; - if ($this->_installRoot) { - if (in_array($this->getGroup($key), - array('File Locations', 'File Locations (Advanced)')) && - $this->getType($key) == 'directory') { - return $this->_prependPath($test, $this->_installRoot); + /** + * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel + */ + function getSSL($mirror = false) + { + if ($mirror) { + if ($mir = $this->getMirror($mirror)) { + if (isset($mir['attribs']['ssl'])) { + return true; } - } - - if ($key == 'preferred_mirror') { - $reg = &$this->getRegistry(); - if (is_object($reg)) { - $chan = &$reg->getChannel($channel); - if (PEAR::isError($chan)) { - return $channel; - } - if (!$chan->getMirror($test) && $chan->getName() != $test) { - return $channel; // mirror does not exist - } - } + return false; } - return $test; + return false; } - return null; + if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) { + return true; + } + + return false; } /** - * Returns a channel-specific configuration value, prioritizing layers as per the - * layers property. - * - * @param string config key - * @return mixed the config value, or NULL if not found - * @access private + * @return string|false */ - function _getChannelValue($key, $layer, $channel) + function getSummary() { - if ($key == '__channels' || $channel == 'pear.php.net') { - return null; + if (isset($this->_channelInfo['summary'])) { + return $this->_channelInfo['summary']; } - $ret = null; - if ($layer === null) { - foreach ($this->layers as $ilayer) { - if (isset($this->configuration[$ilayer]['__channels'][$channel][$key])) { - $ret = $this->configuration[$ilayer]['__channels'][$channel][$key]; - break; - } - } - } elseif (isset($this->configuration[$layer]['__channels'][$channel][$key])) { - $ret = $this->configuration[$layer]['__channels'][$channel][$key]; - } + return false; + } - if ($key != 'preferred_mirror') { - return $ret; + /** + * @param string protocol type + * @param string Mirror name + * @return array|false + */ + function getFunctions($protocol, $mirror = false) + { + if ($this->getName() == '__uri') { + return false; } - - if ($ret !== null) { - $reg = &$this->getRegistry($layer); - if (is_object($reg)) { - $chan = &$reg->getChannel($channel); - if (PEAR::isError($chan)) { - return $channel; - } - - if (!$chan->getMirror($ret) && $chan->getName() != $ret) { - return $channel; // mirror does not exist + $function = $protocol == 'rest' ? 'baseurl' : 'function'; + if ($mirror) { + if ($mir = $this->getMirror($mirror)) { + if (isset($mir[$protocol][$function])) { + return $mir[$protocol][$function]; } } - return $ret; + return false; } - if ($channel != $this->getDefaultChannel($layer)) { - return $channel; // we must use the channel name as the preferred mirror - // if the user has not chosen an alternate + if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) { + return $this->_channelInfo['servers']['primary'][$protocol][$function]; } - return $this->getDefaultChannel($layer); + return false; } /** - * Set a config value in a specific layer (defaults to 'user'). - * Enforces the types defined in the configuration_info array. An - * integer config variable will be cast to int, and a set config - * variable will be validated against its legal values. - * - * @param string config key - * @param string config value - * @param string (optional) config layer - * @param string channel to set this value for, or null for global value - * @return bool TRUE on success, FALSE on failure + * @param string Protocol type + * @param string Function name (null to return the + * first protocol of the type requested) + * @param string Mirror name, if any + * @return array */ - function set($key, $value, $layer = 'user', $channel = false) - { - if ($key == '__channels') { - return false; - } - - if (!isset($this->configuration[$layer])) { + function getFunction($type, $name = null, $mirror = false) + { + $protocols = $this->getFunctions($type, $mirror); + if (!$protocols) { return false; } - if ($key == 'default_channel') { - // can only set this value globally - $channel = 'pear.php.net'; - if ($value != 'pear.php.net') { - $this->_lazyChannelSetup($layer); - } - } - - if ($key == 'preferred_mirror') { - if ($channel == '__uri') { - return false; // can't set the __uri pseudo-channel's mirror - } - - $reg = &$this->getRegistry($layer); - if (is_object($reg)) { - $chan = &$reg->getChannel($channel ? $channel : 'pear.php.net'); - if (PEAR::isError($chan)) { - return false; - } - - if (!$chan->getMirror($value) && $chan->getName() != $value) { - return false; // mirror does not exist - } - } - } - - if (!isset($this->configuration_info[$key])) { - return false; - } - - extract($this->configuration_info[$key]); - switch ($type) { - case 'integer': - $value = (int)$value; - break; - case 'set': { - // If a valid_set is specified, require the value to - // be in the set. If there is no valid_set, accept - // any value. - if ($valid_set) { - reset($valid_set); - if ((key($valid_set) === 0 && !in_array($value, $valid_set)) || - (key($valid_set) !== 0 && empty($valid_set[$value]))) - { - return false; - } - } - break; + foreach ($protocols as $protocol) { + if ($name === null) { + return $protocol; } - } - - if (!$channel) { - $channel = $this->get('default_channel', null, 'pear.php.net'); - } - if (!in_array($channel, $this->_channels)) { - $this->_lazyChannelSetup($layer); - $reg = &$this->getRegistry($layer); - if ($reg) { - $channel = $reg->channelName($channel); + if ($protocol['_content'] != $name) { + continue; } - if (!in_array($channel, $this->_channels)) { - return false; - } + return $protocol; } - if ($channel != 'pear.php.net') { - if (in_array($key, $this->_channelConfigInfo)) { - $this->configuration[$layer]['__channels'][$channel][$key] = $value; - return true; - } + return false; + } + /** + * @param string protocol type + * @param string protocol name + * @param string version + * @param string mirror name + * @return boolean + */ + function supports($type, $name = null, $mirror = false, $version = '1.0') + { + $protocols = $this->getFunctions($type, $mirror); + if (!$protocols) { return false; } - if ($key == 'default_channel') { - if (!isset($reg)) { - $reg = &$this->getRegistry($layer); - if (!$reg) { - $reg = &$this->getRegistry(); - } + foreach ($protocols as $protocol) { + if ($protocol['attribs']['version'] != $version) { + continue; } - if ($reg) { - $value = $reg->channelName($value); + if ($name === null) { + return true; } - if (!$value) { - return false; + if ($protocol['_content'] != $name) { + continue; } - } - $this->configuration[$layer][$key] = $value; - if ($key == 'php_dir' && !$this->_noRegistry) { - if (!isset($this->_registry[$layer]) || - $value != $this->_registry[$layer]->install_dir) { - $this->_registry[$layer] = &new PEAR_Registry($value); - $this->_regInitialized[$layer] = false; - $this->_registry[$layer]->setConfig($this, false); - } + return true; } - return true; + return false; } - function _lazyChannelSetup($uselayer = false) + /** + * Determines whether a channel supports Representational State Transfer (REST) protocols + * for retrieving channel information + * @param string + * @return bool + */ + function supportsREST($mirror = false) { - if ($this->_noRegistry) { - return; + if ($mirror == $this->_channelInfo['name']) { + $mirror = false; } - $merge = false; - foreach ($this->_registry as $layer => $p) { - if ($uselayer && $uselayer != $layer) { - continue; + if ($mirror) { + if ($mir = $this->getMirror($mirror)) { + return isset($mir['rest']); } - if (!$this->_regInitialized[$layer]) { - if ($layer == 'default' && isset($this->_registry['user']) || - isset($this->_registry['system'])) { - // only use the default registry if there are no alternatives - continue; - } - - if (!is_object($this->_registry[$layer])) { - if ($phpdir = $this->get('php_dir', $layer, 'pear.php.net')) { - $this->_registry[$layer] = &new PEAR_Registry($phpdir); - $this->_registry[$layer]->setConfig($this, false); - $this->_regInitialized[$layer] = false; - } else { - unset($this->_registry[$layer]); - return; - } - } - - $this->setChannels($this->_registry[$layer]->listChannels(), $merge); - $this->_regInitialized[$layer] = true; - $merge = true; - } + return false; } + + return isset($this->_channelInfo['servers']['primary']['rest']); } /** - * Set the list of channels. + * Get the URL to access a base resource. * - * This should be set via a call to {@link PEAR_Registry::listChannels()} - * @param array - * @param bool - * @return bool success of operation + * Hyperlinks in the returned xml will be used to retrieve the proper information + * needed. This allows extreme extensibility and flexibility in implementation + * @param string Resource Type to retrieve */ - function setChannels($channels, $merge = false) + function getBaseURL($resourceType, $mirror = false) { - if (!is_array($channels)) { - return false; + if ($mirror == $this->_channelInfo['name']) { + $mirror = false; } - if ($merge) { - $this->_channels = array_merge($this->_channels, $channels); + if ($mirror) { + $mir = $this->getMirror($mirror); + if (!$mir) { + return false; + } + + $rest = $mir['rest']; } else { - $this->_channels = $channels; + $rest = $this->_channelInfo['servers']['primary']['rest']; } - foreach ($channels as $channel) { - $channel = strtolower($channel); - if ($channel == 'pear.php.net') { - continue; - } + if (!isset($rest['baseurl'][0])) { + $rest['baseurl'] = array($rest['baseurl']); + } - foreach ($this->layers as $layer) { - if (!isset($this->configuration[$layer]['__channels'])) { - $this->configuration[$layer]['__channels'] = array(); - } - if (!isset($this->configuration[$layer]['__channels'][$channel]) - || !is_array($this->configuration[$layer]['__channels'][$channel])) { - $this->configuration[$layer]['__channels'][$channel] = array(); - } + foreach ($rest['baseurl'] as $baseurl) { + if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) { + return $baseurl['_content']; } } - return true; + return false; } /** - * Get the type of a config value. - * - * @param string config key - * - * @return string type, one of "string", "integer", "file", - * "directory", "set" or "password". - * - * @access public - * + * Since REST does not implement RPC, provide this as a logical wrapper around + * resetFunctions for REST + * @param string|false mirror name, if any */ - function getType($key) + function resetREST($mirror = false) { - if (isset($this->configuration_info[$key])) { - return $this->configuration_info[$key]['type']; - } - return false; + return $this->resetFunctions('rest', $mirror); } /** - * Get the documentation for a config value. - * - * @param string config key - * @return string documentation string - * - * @access public - * + * Empty all protocol definitions + * @param string protocol type + * @param string|false mirror name, if any */ - function getDocs($key) + function resetFunctions($type, $mirror = false) { - if (isset($this->configuration_info[$key])) { - return $this->configuration_info[$key]['doc']; + if ($mirror) { + if (isset($this->_channelInfo['servers']['mirror'])) { + $mirrors = $this->_channelInfo['servers']['mirror']; + if (!isset($mirrors[0])) { + $mirrors = array($mirrors); + } + + foreach ($mirrors as $i => $mir) { + if ($mir['attribs']['host'] == $mirror) { + if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) { + unset($this->_channelInfo['servers']['mirror'][$i][$type]); + } + + return true; + } + } + + return false; + } + + return false; } - return false; + if (isset($this->_channelInfo['servers']['primary'][$type])) { + unset($this->_channelInfo['servers']['primary'][$type]); + } + + return true; } /** - * Get the short documentation for a config value. - * - * @param string config key - * @return string short documentation string - * - * @access public - * + * Set a channel's protocols to the protocols supported by pearweb */ - function getPrompt($key) + function setDefaultPEARProtocols($version = '1.0', $mirror = false) { - if (isset($this->configuration_info[$key])) { - return $this->configuration_info[$key]['prompt']; - } + switch ($version) { + case '1.0' : + $this->resetREST($mirror); - return false; + if (!isset($this->_channelInfo['servers'])) { + $this->_channelInfo['servers'] = array('primary' => + array('rest' => array())); + } elseif (!isset($this->_channelInfo['servers']['primary'])) { + $this->_channelInfo['servers']['primary'] = array('rest' => array()); + } + + return true; + break; + default : + return false; + break; + } } /** - * Get the parameter group for a config key. - * - * @param string config key - * @return string parameter group - * - * @access public - * + * @return array */ - function getGroup($key) + function getMirrors() { - if (isset($this->configuration_info[$key])) { - return $this->configuration_info[$key]['group']; + if (isset($this->_channelInfo['servers']['mirror'])) { + $mirrors = $this->_channelInfo['servers']['mirror']; + if (!isset($mirrors[0])) { + $mirrors = array($mirrors); + } + + return $mirrors; } - return false; + return array(); } /** - * Get the list of parameter groups. - * - * @return array list of parameter groups - * - * @access public - * + * Get the unserialized XML representing a mirror + * @return array|false */ - function getGroups() + function getMirror($server) { - $tmp = array(); - foreach ($this->configuration_info as $key => $info) { - $tmp[$info['group']] = 1; + foreach ($this->getMirrors() as $mirror) { + if ($mirror['attribs']['host'] == $server) { + return $mirror; + } } - return array_keys($tmp); + return false; } /** - * Get the list of the parameters in a group. - * - * @param string $group parameter group - * @return array list of parameters in $group - * - * @access public - * + * @param string + * @return string|false + * @error PEAR_CHANNELFILE_ERROR_NO_NAME + * @error PEAR_CHANNELFILE_ERROR_INVALID_NAME */ - function getGroupKeys($group) + function setName($name) { - $keys = array(); - foreach ($this->configuration_info as $key => $info) { - if ($info['group'] == $group) { - $keys[] = $key; - } - } - - return $keys; + return $this->setServer($name); } /** - * Get the list of allowed set values for a config value. Returns - * NULL for config values that are not sets. - * - * @param string config key - * @return array enumerated array of set values, or NULL if the - * config key is unknown or not a set - * - * @access public - * + * Set the socket number (port) that is used to connect to this channel + * @param integer + * @param string|false name of the mirror server, or false for the primary */ - function getSetValues($key) + function setPort($port, $mirror = false) { - if (isset($this->configuration_info[$key]) && - isset($this->configuration_info[$key]['type']) && - $this->configuration_info[$key]['type'] == 'set') - { - $valid_set = $this->configuration_info[$key]['valid_set']; - reset($valid_set); - if (key($valid_set) === 0) { - return $valid_set; + if ($mirror) { + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; } - return array_keys($valid_set); + if (isset($this->_channelInfo['servers']['mirror'][0])) { + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + $this->_channelInfo['servers']['mirror'][$i]['attribs']['port'] = $port; + return true; + } + } + + return false; + } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { + $this->_channelInfo['servers']['mirror']['attribs']['port'] = $port; + $this->_isValid = false; + return true; + } } - return null; + $this->_channelInfo['servers']['primary']['attribs']['port'] = $port; + $this->_isValid = false; + return true; } /** - * Get all the current config keys. - * - * @return array simple array of config keys - * - * @access public + * Set the socket number (port) that is used to connect to this channel + * @param bool Determines whether to turn on SSL support or turn it off + * @param string|false name of the mirror server, or false for the primary */ - function getKeys() + function setSSL($ssl = true, $mirror = false) { - $keys = array(); - foreach ($this->layers as $layer) { - $test = $this->configuration[$layer]; - if (isset($test['__channels'])) { - foreach ($test['__channels'] as $channel => $configs) { - $keys = array_merge($keys, $configs); - } + if ($mirror) { + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; } - unset($test['__channels']); - $keys = array_merge($keys, $test); + if (isset($this->_channelInfo['servers']['mirror'][0])) { + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + if (!$ssl) { + if (isset($this->_channelInfo['servers']['mirror'][$i] + ['attribs']['ssl'])) { + unset($this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl']); + } + } else { + $this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes'; + } - } - return array_keys($keys); - } + return true; + } + } - /** - * Remove the a config key from a specific config layer. - * - * @param string config key - * @param string (optional) config layer - * @return bool TRUE on success, FALSE on failure - * - * @access public - */ - function remove($key, $layer = 'user') - { - $channel = $this->getDefaultChannel(); - if ($channel !== 'pear.php.net') { - if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { - unset($this->configuration[$layer]['__channels'][$channel][$key]); + return false; + } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { + if (!$ssl) { + if (isset($this->_channelInfo['servers']['mirror']['attribs']['ssl'])) { + unset($this->_channelInfo['servers']['mirror']['attribs']['ssl']); + } + } else { + $this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes'; + } + + $this->_isValid = false; return true; } } - if (isset($this->configuration[$layer][$key])) { - unset($this->configuration[$layer][$key]); - return true; + if ($ssl) { + $this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes'; + } else { + if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) { + unset($this->_channelInfo['servers']['primary']['attribs']['ssl']); + } } - return false; + $this->_isValid = false; + return true; } /** - * Temporarily remove an entire config layer. USE WITH CARE! - * - * @param string config key - * @param string (optional) config layer - * @return bool TRUE on success, FALSE on failure - * - * @access public + * @param string + * @return string|false + * @error PEAR_CHANNELFILE_ERROR_NO_SERVER + * @error PEAR_CHANNELFILE_ERROR_INVALID_SERVER */ - function removeLayer($layer) + function setServer($server, $mirror = false) { - if (isset($this->configuration[$layer])) { - $this->configuration[$layer] = array(); - return true; + if (empty($server)) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SERVER); + return false; + } elseif (!$this->validChannelServer($server)) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, + array('tag' => 'name', 'name' => $server)); + return false; } - return false; - } + if ($mirror) { + $found = false; + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + $found = true; + break; + } + } - /** - * Stores configuration data in a layer. - * - * @param string config layer to store - * @return bool TRUE on success, or PEAR error on failure - * - * @access public - */ - function store($layer = 'user', $data = null) - { - return $this->writeConfigFile(null, $layer, $data); - } - - /** - * Tells what config layer that gets to define a key. - * - * @param string config key - * @param boolean return the defining channel - * - * @return string|array the config layer, or an empty string if not found. - * - * if $returnchannel, the return is an array array('layer' => layername, - * 'channel' => channelname), or an empty string if not found - * - * @access public - */ - function definedBy($key, $returnchannel = false) - { - foreach ($this->layers as $layer) { - $channel = $this->getDefaultChannel(); - if ($channel !== 'pear.php.net') { - if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { - if ($returnchannel) { - return array('layer' => $layer, 'channel' => $channel); - } - return $layer; - } + if (!$found) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; } - if (isset($this->configuration[$layer][$key])) { - if ($returnchannel) { - return array('layer' => $layer, 'channel' => 'pear.php.net'); - } - return $layer; - } + $this->_channelInfo['mirror'][$i]['attribs']['host'] = $server; + return true; } - return ''; + $this->_channelInfo['name'] = $server; + return true; } /** - * Tells whether a given key exists as a config value. - * - * @param string config key - * @return bool whether exists in this object - * - * @access public + * @param string + * @return boolean success + * @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY + * @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY */ - function isDefined($key) + function setSummary($summary) { - foreach ($this->layers as $layer) { - if (isset($this->configuration[$layer][$key])) { - return true; - } + if (empty($summary)) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY); + return false; + } elseif (strpos(trim($summary), "\n") !== false) { + $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY, + array('summary' => $summary)); } - return false; + $this->_channelInfo['summary'] = $summary; + return true; } /** - * Tells whether a given config layer exists. - * - * @param string config layer - * @return bool whether exists in this object - * - * @access public + * @param string + * @param boolean determines whether the alias is in channel.xml or local + * @return boolean success */ - function isDefinedLayer($layer) + function setAlias($alias, $local = false) { - return isset($this->configuration[$layer]); + if (!$this->validChannelServer($alias)) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, + array('tag' => 'suggestedalias', 'name' => $alias)); + return false; + } + + if ($local) { + $this->_channelInfo['localalias'] = $alias; + } else { + $this->_channelInfo['suggestedalias'] = $alias; + } + + return true; } /** - * Returns the layers defined (except the 'default' one) - * - * @return array of the defined layers + * @return string */ - function getLayers() + function getAlias() { - $cf = $this->configuration; - unset($cf['default']); - return array_keys($cf); + if (isset($this->_channelInfo['localalias'])) { + return $this->_channelInfo['localalias']; + } + if (isset($this->_channelInfo['suggestedalias'])) { + return $this->_channelInfo['suggestedalias']; + } + if (isset($this->_channelInfo['name'])) { + return $this->_channelInfo['name']; + } + return ''; } - function apiVersion() + /** + * Set the package validation object if it differs from PEAR's default + * The class must be includeable via changing _ in the classname to path separator, + * but no checking of this is made. + * @param string|false pass in false to reset to the default packagename regex + * @return boolean success + */ + function setValidationPackage($validateclass, $version) { - return '1.1'; + if (empty($validateclass)) { + unset($this->_channelInfo['validatepackage']); + } + $this->_channelInfo['validatepackage'] = array('_content' => $validateclass); + $this->_channelInfo['validatepackage']['attribs'] = array('version' => $version); } /** - * @return PEAR_Registry + * Add a protocol to the provides section + * @param string protocol type + * @param string protocol version + * @param string protocol name, if any + * @param string mirror name, if this is a mirror's protocol + * @return bool */ - function &getRegistry($use = null) + function addFunction($type, $version, $name = '', $mirror = false) { - $layer = $use === null ? 'user' : $use; - if (isset($this->_registry[$layer])) { - return $this->_registry[$layer]; - } elseif ($use === null && isset($this->_registry['system'])) { - return $this->_registry['system']; - } elseif ($use === null && isset($this->_registry['default'])) { - return $this->_registry['default']; - } elseif ($use) { - $a = false; - return $a; + if ($mirror) { + return $this->addMirrorFunction($mirror, $type, $version, $name); } - // only go here if null was passed in - echo "CRITICAL ERROR: Registry could not be initialized from any value"; - exit(1); - } + $set = array('attribs' => array('version' => $version), '_content' => $name); + if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) { + if (!isset($this->_channelInfo['servers'])) { + $this->_channelInfo['servers'] = array('primary' => + array($type => array())); + } elseif (!isset($this->_channelInfo['servers']['primary'])) { + $this->_channelInfo['servers']['primary'] = array($type => array()); + } + + $this->_channelInfo['servers']['primary'][$type]['function'] = $set; + $this->_isValid = false; + return true; + } elseif (!isset($this->_channelInfo['servers']['primary'][$type]['function'][0])) { + $this->_channelInfo['servers']['primary'][$type]['function'] = array( + $this->_channelInfo['servers']['primary'][$type]['function']); + } + $this->_channelInfo['servers']['primary'][$type]['function'][] = $set; + return true; + } /** - * This is to allow customization like the use of installroot - * @param PEAR_Registry - * @return bool + * Add a protocol to a mirror's provides section + * @param string mirror name (server) + * @param string protocol type + * @param string protocol version + * @param string protocol name, if any */ - function setRegistry(&$reg, $layer = 'user') + function addMirrorFunction($mirror, $type, $version, $name = '') { - if ($this->_noRegistry) { + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); return false; } - if (!in_array($layer, array('user', 'system'))) { + $setmirror = false; + if (isset($this->_channelInfo['servers']['mirror'][0])) { + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + $setmirror = &$this->_channelInfo['servers']['mirror'][$i]; + break; + } + } + } else { + if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { + $setmirror = &$this->_channelInfo['servers']['mirror']; + } + } + + if (!$setmirror) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); return false; } - $this->_registry[$layer] = &$reg; - if (is_object($reg)) { - $this->_registry[$layer]->setConfig($this, false); + $set = array('attribs' => array('version' => $version), '_content' => $name); + if (!isset($setmirror[$type]['function'])) { + $setmirror[$type]['function'] = $set; + $this->_isValid = false; + return true; + } elseif (!isset($setmirror[$type]['function'][0])) { + $setmirror[$type]['function'] = array($setmirror[$type]['function']); } + $setmirror[$type]['function'][] = $set; + $this->_isValid = false; return true; } - function noRegistry() + /** + * @param string Resource Type this url links to + * @param string URL + * @param string|false mirror name, if this is not a primary server REST base URL + */ + function setBaseURL($resourceType, $url, $mirror = false) { - $this->_noRegistry = true; + if ($mirror) { + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + $setmirror = false; + if (isset($this->_channelInfo['servers']['mirror'][0])) { + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + $setmirror = &$this->_channelInfo['servers']['mirror'][$i]; + break; + } + } + } else { + if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { + $setmirror = &$this->_channelInfo['servers']['mirror']; + } + } + } else { + $setmirror = &$this->_channelInfo['servers']['primary']; + } + + $set = array('attribs' => array('type' => $resourceType), '_content' => $url); + if (!isset($setmirror['rest'])) { + $setmirror['rest'] = array(); + } + + if (!isset($setmirror['rest']['baseurl'])) { + $setmirror['rest']['baseurl'] = $set; + $this->_isValid = false; + return true; + } elseif (!isset($setmirror['rest']['baseurl'][0])) { + $setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']); + } + + foreach ($setmirror['rest']['baseurl'] as $i => $url) { + if ($url['attribs']['type'] == $resourceType) { + $this->_isValid = false; + $setmirror['rest']['baseurl'][$i] = $set; + return true; + } + } + + $setmirror['rest']['baseurl'][] = $set; + $this->_isValid = false; + return true; } /** - * @return PEAR_REST + * @param string mirror server + * @param int mirror http port + * @return boolean */ - function &getREST($version, $options = array()) + function addMirror($server, $port = null) { - $version = str_replace('.', '', $version); - if (!class_exists($class = 'PEAR_REST_' . $version)) { - require_once 'PEAR/REST/' . $version . '.php'; + if ($this->_channelInfo['name'] == '__uri') { + return false; // the __uri channel cannot have mirrors by definition } - $remote = &new $class($this, $options); - return $remote; + $set = array('attribs' => array('host' => $server)); + if (is_numeric($port)) { + $set['attribs']['port'] = $port; + } + + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_channelInfo['servers']['mirror'] = $set; + return true; + } + + if (!isset($this->_channelInfo['servers']['mirror'][0])) { + $this->_channelInfo['servers']['mirror'] = + array($this->_channelInfo['servers']['mirror']); + } + + $this->_channelInfo['servers']['mirror'][] = $set; + return true; } /** - * The ftp server is set in {@link readFTPConfigFile()}. It exists only if a - * remote configuration file has been specified - * @return PEAR_FTP|false + * Retrieve the name of the validation package for this channel + * @return string|false */ - function &getFTP() + function getValidationPackage() { - if (isset($this->_ftp)) { - return $this->_ftp; + if (!$this->_isValid && !$this->validate()) { + return false; } - $a = false; - return $a; + if (!isset($this->_channelInfo['validatepackage'])) { + return array('attribs' => array('version' => 'default'), + '_content' => 'PEAR_Validate'); + } + + return $this->_channelInfo['validatepackage']; } - function _prependPath($path, $prepend) + /** + * Retrieve the object that can be used for custom validation + * @param string|false the name of the package to validate. If the package is + * the channel validation package, PEAR_Validate is returned + * @return PEAR_Validate|false false is returned if the validation package + * cannot be located + */ + function &getValidationObject($package = false) { - if (strlen($prepend) > 0) { - if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { - if (preg_match('/^[a-z]:/i', $prepend)) { - $prepend = substr($prepend, 2); - } elseif ($prepend{0} != '\\') { - $prepend = "\\$prepend"; + if (!class_exists('PEAR_Validate')) { + require_once 'PEAR/Validate.php'; + } + + if (!$this->_isValid) { + if (!$this->validate()) { + $a = false; + return $a; + } + } + + if (isset($this->_channelInfo['validatepackage'])) { + if ($package == $this->_channelInfo['validatepackage']) { + // channel validation packages are always validated by PEAR_Validate + $val = &new PEAR_Validate; + return $val; + } + + if (!class_exists(str_replace('.', '_', + $this->_channelInfo['validatepackage']['_content']))) { + if ($this->isIncludeable(str_replace('_', '/', + $this->_channelInfo['validatepackage']['_content']) . '.php')) { + include_once str_replace('_', '/', + $this->_channelInfo['validatepackage']['_content']) . '.php'; + $vclass = str_replace('.', '_', + $this->_channelInfo['validatepackage']['_content']); + $val = &new $vclass; + } else { + $a = false; + return $a; } - $path = substr($path, 0, 2) . $prepend . substr($path, 2); } else { - $path = $prepend . $path; + $vclass = str_replace('.', '_', + $this->_channelInfo['validatepackage']['_content']); + $val = &new $vclass; } + } else { + $val = &new PEAR_Validate; } - return $path; + + return $val; + } + + function isIncludeable($path) + { + $possibilities = explode(PATH_SEPARATOR, ini_get('include_path')); + foreach ($possibilities as $dir) { + if (file_exists($dir . DIRECTORY_SEPARATOR . $path) + && is_readable($dir . DIRECTORY_SEPARATOR . $path)) { + return true; + } + } + + return false; } /** - * @param string|false installation directory to prepend to all _dir variables, or false to - * disable + * This function is used by the channel updater and retrieves a value set by + * the registry, or the current time if it has not been set + * @return string */ - function setInstallRoot($root) + function lastModified() { - if (substr($root, -1) == DIRECTORY_SEPARATOR) { - $root = substr($root, 0, -1); - } - $old = $this->_installRoot; - $this->_installRoot = $root; - if (($old != $root) && !$this->_noRegistry) { - foreach (array_keys($this->_registry) as $layer) { - if ($layer == 'ftp' || !isset($this->_registry[$layer])) { - continue; - } - $this->_registry[$layer] = - &new PEAR_Registry($this->get('php_dir', $layer, 'pear.php.net')); - $this->_registry[$layer]->setConfig($this, false); - $this->_regInitialized[$layer] = false; - } + if (isset($this->_channelInfo['_lastmodified'])) { + return $this->_channelInfo['_lastmodified']; } + + return time(); } -} -PEAR-1.8.0/PEAR/DependencyDB.php100664 764 764 57540 100664 11064 + * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: DependencyDB.php,v 1.44 2009/03/21 15:15:26 dufuz Exp $ + * @version CVS: $Id: Command.php 286494 2009-07-29 06:57:11Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 + * @since File available since Release 0.1 */ /** * Needed for error handling */ require_once 'PEAR.php'; -require_once 'PEAR/Config.php'; +require_once 'PEAR/Frontend.php'; +require_once 'PEAR/XMLParser.php'; -$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array(); /** - * Track dependency relationships between installed packages + * List of commands and what classes they are implemented in. + * @var array command => implementing class + */ +$GLOBALS['_PEAR_Command_commandlist'] = array(); + +/** + * List of commands and their descriptions + * @var array command => description + */ +$GLOBALS['_PEAR_Command_commanddesc'] = array(); + +/** + * List of shortcuts to common commands. + * @var array shortcut => command + */ +$GLOBALS['_PEAR_Command_shortcuts'] = array(); + +/** + * Array of command objects + * @var array class => object + */ +$GLOBALS['_PEAR_Command_objects'] = array(); + +/** + * PEAR command class, a simple factory class for administrative + * commands. + * + * How to implement command classes: + * + * - The class must be called PEAR_Command_Nnn, installed in the + * "PEAR/Common" subdir, with a method called getCommands() that + * returns an array of the commands implemented by the class (see + * PEAR/Command/Install.php for an example). + * + * - The class must implement a run() function that is called with three + * params: + * + * (string) command name + * (array) assoc array with options, freely defined by each + * command, for example: + * array('force' => true) + * (array) list of the other parameters + * + * The run() function returns a PEAR_CommandResponse object. Use + * these methods to get information: + * + * int getStatus() Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL) + * *_PARTIAL means that you need to issue at least + * one more command to complete the operation + * (used for example for validation steps). + * + * string getMessage() Returns a message for the user. Remember, + * no HTML or other interface-specific markup. + * + * If something unexpected happens, run() returns a PEAR error. + * + * - DON'T OUTPUT ANYTHING! Return text for output instead. + * + * - DON'T USE HTML! The text you return will be used from both Gtk, + * web and command-line interfaces, so for now, keep everything to + * plain text. + * + * - DON'T USE EXIT OR DIE! Always use pear errors. From static + * classes do PEAR::raiseError(), from other classes do + * $this->raiseError(). * @category pear * @package PEAR + * @author Stig Bakken * @author Greg Beaver - * @author Tomas V.V.Cox * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 + * @since Class available since Release 0.1 */ -class PEAR_DependencyDB +class PEAR_Command { - // {{{ properties + // {{{ factory() /** - * This is initialized by {@link setConfig()} - * @var PEAR_Config - * @access private - */ - var $_config; - /** - * This is initialized by {@link setConfig()} - * @var PEAR_Registry - * @access private - */ - var $_registry; - /** - * Filename of the dependency DB (usually .depdb) - * @var string - * @access private - */ - var $_depdb = false; - /** - * File name of the lockfile (usually .depdblock) - * @var string - * @access private - */ - var $_lockfile = false; - /** - * Open file resource for locking the lockfile - * @var resource|false - * @access private - */ - var $_lockFp = false; - /** - * API version of this class, used to validate a file on-disk - * @var string - * @access private - */ - var $_version = '1.0'; - /** - * Cached dependency database file - * @var array|null - * @access private - */ - var $_cache; - - // }}} - // {{{ & singleton() - - /** - * Get a raw dependency database. Calls setConfig() and assertDepsDB() - * @param PEAR_Config - * @param string|false full path to the dependency database, or false to use default - * @return PEAR_DependencyDB|PEAR_Error + * Get the right object for executing a command. + * + * @param string $command The name of the command + * @param object $config Instance of PEAR_Config object + * + * @return object the command object or a PEAR error + * + * @access public * @static */ - function &singleton(&$config, $depdb = false) + function &factory($command, &$config) { - $phpdir = $config->get('php_dir', null, 'pear.php.net'); - if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir])) { - $a = new PEAR_DependencyDB; - $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir] = &$a; - $a->setConfig($config, $depdb); - $e = $a->assertDepsDB(); - if (PEAR::isError($e)) { - return $e; - } + if (empty($GLOBALS['_PEAR_Command_commandlist'])) { + PEAR_Command::registerCommands(); } - - return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir]; + if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { + $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; + } + if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { + $a = PEAR::raiseError("unknown command `$command'"); + return $a; + } + $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; + if (!class_exists($class)) { + require_once $GLOBALS['_PEAR_Command_objects'][$class]; + } + if (!class_exists($class)) { + $a = PEAR::raiseError("unknown command `$command'"); + return $a; + } + $ui =& PEAR_Command::getFrontendObject(); + $obj = &new $class($ui, $config); + return $obj; } - /** - * Set up the registry/location of dependency DB - * @param PEAR_Config|false - * @param string|false full path to the dependency database, or false to use default - */ - function setConfig(&$config, $depdb = false) + // }}} + // {{{ & getObject() + function &getObject($command) { - if (!$config) { - $this->_config = &PEAR_Config::singleton(); - } else { - $this->_config = &$config; + $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; + if (!class_exists($class)) { + require_once $GLOBALS['_PEAR_Command_objects'][$class]; } - - $this->_registry = &$this->_config->getRegistry(); - if (!$depdb) { - $this->_depdb = $this->_config->get('php_dir', null, 'pear.php.net') . - DIRECTORY_SEPARATOR . '.depdb'; - } else { - $this->_depdb = $depdb; + if (!class_exists($class)) { + return PEAR::raiseError("unknown command `$command'"); } - - $this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock'; + $ui =& PEAR_Command::getFrontendObject(); + $config = &PEAR_Config::singleton(); + $obj = &new $class($ui, $config); + return $obj; } + // }}} + // {{{ & getFrontendObject() - function hasWriteAccess() + /** + * Get instance of frontend object. + * + * @return object|PEAR_Error + * @static + */ + function &getFrontendObject() { - if (!file_exists($this->_depdb)) { - $dir = $this->_depdb; - while ($dir && $dir != '.') { - $dir = dirname($dir); // cd .. - if ($dir != '.' && file_exists($dir)) { - if (is_writeable($dir)) { - return true; - } - - return false; - } - } - - return false; - } - - return is_writeable($this->_depdb); + $a = &PEAR_Frontend::singleton(); + return $a; } - // {{{ assertDepsDB() + // }}} + // {{{ & setFrontendClass() /** - * Create the dependency database, if it doesn't exist. Error if the database is - * newer than the code reading it. - * @return void|PEAR_Error + * Load current frontend class. + * + * @param string $uiclass Name of class implementing the frontend + * + * @return object the frontend object, or a PEAR error + * @static */ - function assertDepsDB() + function &setFrontendClass($uiclass) { - if (!is_file($this->_depdb)) { - $this->rebuildDB(); - } else { - $depdb = $this->_getDepDB(); - // Datatype format has been changed, rebuild the Deps DB - if ($depdb['_version'] < $this->_version) { - $this->rebuildDB(); - } - - if ($depdb['_version']{0} > $this->_version{0}) { - return PEAR::raiseError('Dependency database is version ' . - $depdb['_version'] . ', and we are version ' . - $this->_version . ', cannot continue'); - } - } + $a = &PEAR_Frontend::setFrontendClass($uiclass); + return $a; } + // }}} + // {{{ setFrontendType() + /** - * Get a list of installed packages that depend on this package - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array - * @return array|false + * Set current frontend. + * + * @param string $uitype Name of the frontend type (for example "CLI") + * + * @return object the frontend object, or a PEAR error + * @static */ - function getDependentPackages(&$pkg) + function setFrontendType($uitype) { - $data = $this->_getDepDB(); - if (is_object($pkg)) { - $channel = strtolower($pkg->getChannel()); - $package = strtolower($pkg->getPackage()); - } else { - $channel = strtolower($pkg['channel']); - $package = strtolower($pkg['package']); - } - - if (isset($data['packages'][$channel][$package])) { - return $data['packages'][$channel][$package]; - } - - return false; + $uiclass = 'PEAR_Frontend_' . $uitype; + return PEAR_Command::setFrontendClass($uiclass); } + // }}} + // {{{ registerCommands() + /** - * Get a list of the actual dependencies of installed packages that depend on - * a package. - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array - * @return array|false + * Scan through the Command directory looking for classes + * and see what commands they implement. + * + * @param bool (optional) if FALSE (default), the new list of + * commands should replace the current one. If TRUE, + * new entries will be merged with old. + * + * @param string (optional) where (what directory) to look for + * classes, defaults to the Command subdirectory of + * the directory from where this file (__FILE__) is + * included. + * + * @return bool TRUE on success, a PEAR error on failure + * + * @access public + * @static */ - function getDependentPackageDependencies(&$pkg) + function registerCommands($merge = false, $dir = null) { - $data = $this->_getDepDB(); - if (is_object($pkg)) { - $channel = strtolower($pkg->getChannel()); - $package = strtolower($pkg->getPackage()); - } else { - $channel = strtolower($pkg['channel']); - $package = strtolower($pkg['package']); + $parser = new PEAR_XMLParser; + if ($dir === null) { + $dir = dirname(__FILE__) . '/Command'; } - - $depend = $this->getDependentPackages($pkg); - if (!$depend) { - return false; + if (!is_dir($dir)) { + return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory"); + } + $dp = @opendir($dir); + if (empty($dp)) { + return PEAR::raiseError("registerCommands: opendir($dir) failed"); + } + if (!$merge) { + $GLOBALS['_PEAR_Command_commandlist'] = array(); } - $dependencies = array(); - foreach ($depend as $info) { - $temp = $this->getDependencies($info); - foreach ($temp as $dep) { - if (isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) && - strtolower($dep['dep']['channel']) == $channel && - strtolower($dep['dep']['name']) == $package - ) { - if (!isset($dependencies[$info['channel']])) { - $dependencies[$info['channel']] = array(); + while ($file = readdir($dp)) { + if ($file{0} == '.' || substr($file, -4) != '.xml') { + continue; + } + + $f = substr($file, 0, -4); + $class = "PEAR_Command_" . $f; + // List of commands + if (empty($GLOBALS['_PEAR_Command_objects'][$class])) { + $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php'; + } + + $parser->parse(file_get_contents("$dir/$file")); + $implements = $parser->getData(); + foreach ($implements as $command => $desc) { + if ($command == 'attribs') { + continue; + } + + if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { + return PEAR::raiseError('Command "' . $command . '" already registered in ' . + 'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); + } + + $GLOBALS['_PEAR_Command_commandlist'][$command] = $class; + $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary']; + if (isset($desc['shortcut'])) { + $shortcut = $desc['shortcut']; + if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) { + return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' . + 'registered to command "' . $command . '" in class "' . + $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); } + $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command; + } - if (!isset($dependencies[$info['channel']][$info['package']])) { - $dependencies[$info['channel']][$info['package']] = array(); + if (isset($desc['options']) && $desc['options']) { + foreach ($desc['options'] as $oname => $option) { + if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) { + return PEAR::raiseError('Option "' . $oname . '" short option "' . + $option['shortopt'] . '" must be ' . + 'only 1 character in Command "' . $command . '" in class "' . + $class . '"'); + } } - $dependencies[$info['channel']][$info['package']][] = $dep; } } } - return $dependencies; + ksort($GLOBALS['_PEAR_Command_shortcuts']); + ksort($GLOBALS['_PEAR_Command_commandlist']); + @closedir($dp); + return true; } + // }}} + // {{{ getCommands() + /** - * Get a list of dependencies of this installed package - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array - * @return array|false + * Get the list of currently supported commands, and what + * classes implement them. + * + * @return array command => implementing class + * + * @access public + * @static */ - function getDependencies(&$pkg) + function getCommands() { - if (is_object($pkg)) { - $channel = strtolower($pkg->getChannel()); - $package = strtolower($pkg->getPackage()); - } else { - $channel = strtolower($pkg['channel']); - $package = strtolower($pkg['package']); - } - - $data = $this->_getDepDB(); - if (isset($data['dependencies'][$channel][$package])) { - return $data['dependencies'][$channel][$package]; + if (empty($GLOBALS['_PEAR_Command_commandlist'])) { + PEAR_Command::registerCommands(); } - - return false; + return $GLOBALS['_PEAR_Command_commandlist']; } + // }}} + // {{{ getShortcuts() + /** - * Determine whether $parent depends on $child, near or deep - * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2 - * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2 + * Get the list of command shortcuts. + * + * @return array shortcut => command + * + * @access public + * @static */ - function dependsOn($parent, $child) - { - $c = array(); - $this->_getDepDB(); - return $this->_dependsOn($parent, $child, $c); - } - - function _dependsOn($parent, $child, &$checked) + function getShortcuts() { - if (is_object($parent)) { - $channel = strtolower($parent->getChannel()); - $package = strtolower($parent->getPackage()); - } else { - $channel = strtolower($parent['channel']); - $package = strtolower($parent['package']); - } - - if (is_object($child)) { - $depchannel = strtolower($child->getChannel()); - $deppackage = strtolower($child->getPackage()); - } else { - $depchannel = strtolower($child['channel']); - $deppackage = strtolower($child['package']); + if (empty($GLOBALS['_PEAR_Command_shortcuts'])) { + PEAR_Command::registerCommands(); } + return $GLOBALS['_PEAR_Command_shortcuts']; + } - if (isset($checked[$channel][$package][$depchannel][$deppackage])) { - return false; // avoid endless recursion - } + // }}} + // {{{ getGetoptArgs() - $checked[$channel][$package][$depchannel][$deppackage] = true; - if (!isset($this->_cache['dependencies'][$channel][$package])) { - return false; + /** + * Compiles arguments for getopt. + * + * @param string $command command to get optstring for + * @param string $short_args (reference) short getopt format + * @param array $long_args (reference) long getopt format + * + * @return void + * + * @access public + * @static + */ + function getGetoptArgs($command, &$short_args, &$long_args) + { + if (empty($GLOBALS['_PEAR_Command_commandlist'])) { + PEAR_Command::registerCommands(); } - - foreach ($this->_cache['dependencies'][$channel][$package] as $info) { - if (isset($info['dep']['uri'])) { - if (is_object($child)) { - if ($info['dep']['uri'] == $child->getURI()) { - return true; - } - } elseif (isset($child['uri'])) { - if ($info['dep']['uri'] == $child['uri']) { - return true; - } - } - return false; - } - - if (strtolower($info['dep']['channel']) == $depchannel && - strtolower($info['dep']['name']) == $deppackage) { - return true; - } + if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { + $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; } - - foreach ($this->_cache['dependencies'][$channel][$package] as $info) { - if (isset($info['dep']['uri'])) { - if ($this->_dependsOn(array( - 'uri' => $info['dep']['uri'], - 'package' => $info['dep']['name']), $child, $checked)) { - return true; - } - } else { - if ($this->_dependsOn(array( - 'channel' => $info['dep']['channel'], - 'package' => $info['dep']['name']), $child, $checked)) { - return true; - } - } + if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { + return null; } - - return false; + $obj = &PEAR_Command::getObject($command); + return $obj->getGetoptArgs($command, $short_args, $long_args); } + // }}} + // {{{ getDescription() + /** - * Register dependencies of a package that is being installed or upgraded - * @param PEAR_PackageFile_v2|PEAR_PackageFile_v2 + * Get description for a command. + * + * @param string $command Name of the command + * + * @return string command description + * + * @access public + * @static */ - function installPackage(&$package) + function getDescription($command) { - $data = $this->_getDepDB(); - unset($this->_cache); - $this->_setPackageDeps($data, $package); - $this->_writeDepDB($data); + if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) { + return null; + } + return $GLOBALS['_PEAR_Command_commanddesc'][$command]; } + // }}} + // {{{ getHelp() + /** - * Remove dependencies of a package that is being uninstalled, or upgraded. + * Get help for command. * - * Upgraded packages first uninstall, then install - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have - * indices 'channel' and 'package' + * @param string $command Name of the command to return help for + * + * @access public + * @static */ - function uninstallPackage(&$pkg) + function getHelp($command) { - $data = $this->_getDepDB(); - unset($this->_cache); - if (is_object($pkg)) { - $channel = strtolower($pkg->getChannel()); - $package = strtolower($pkg->getPackage()); - } else { - $channel = strtolower($pkg['channel']); - $package = strtolower($pkg['package']); + $cmds = PEAR_Command::getCommands(); + if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { + $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; } - - if (!isset($data['dependencies'][$channel][$package])) { - return true; + if (isset($cmds[$command])) { + $obj = &PEAR_Command::getObject($command); + return $obj->getHelp($command); } + return false; + } + // }}} +}PEAR-1.9.0/PEAR/Common.php100664 764 764 62255 100664 10030 + * @author Tomas V. V. Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Common.php 282969 2009-06-28 23:09:27Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1.0 + * @deprecated File deprecated since Release 1.4.0a1 + */ - foreach ($data['dependencies'][$channel][$package] as $dep) { - $found = false; - $depchannel = isset($dep['dep']['uri']) ? '__uri' : strtolower($dep['dep']['channel']); - $depname = strtolower($dep['dep']['name']); - if (isset($data['packages'][$depchannel][$depname])) { - foreach ($data['packages'][$depchannel][$depname] as $i => $info) { - if ($info['channel'] == $channel && $info['package'] == $package) { - $found = true; - break; - } - } - } +/** + * Include error handling + */ +require_once 'PEAR.php'; - if ($found) { - unset($data['packages'][$depchannel][$depname][$i]); - if (!count($data['packages'][$depchannel][$depname])) { - unset($data['packages'][$depchannel][$depname]); - if (!count($data['packages'][$depchannel])) { - unset($data['packages'][$depchannel]); - } - } else { - $data['packages'][$depchannel][$depname] = - array_values($data['packages'][$depchannel][$depname]); - } - } - } +/** + * PEAR_Common error when an invalid PHP file is passed to PEAR_Common::analyzeSourceCode() + */ +define('PEAR_COMMON_ERROR_INVALIDPHP', 1); +define('_PEAR_COMMON_PACKAGE_NAME_PREG', '[A-Za-z][a-zA-Z0-9_]+'); +define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/'); - unset($data['dependencies'][$channel][$package]); - if (!count($data['dependencies'][$channel])) { - unset($data['dependencies'][$channel]); - } +// this should allow: 1, 1.0, 1.0RC1, 1.0dev, 1.0dev123234234234, 1.0a1, 1.0b1, 1.0pl1 +define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?'); +define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '\\z/i'); - if (!count($data['dependencies'])) { - unset($data['dependencies']); - } +// XXX far from perfect :-) +define('_PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '(' . _PEAR_COMMON_PACKAGE_NAME_PREG . + ')(-([.0-9a-zA-Z]+))?'); +define('PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_PACKAGE_DOWNLOAD_PREG . + '\\z/'); - if (!count($data['packages'])) { - unset($data['packages']); - } +define('_PEAR_CHANNELS_NAME_PREG', '[A-Za-z][a-zA-Z0-9\.]+'); +define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '\\z/'); - $this->_writeDepDB($data); - } +// this should allow any dns or IP address, plus a path - NO UNDERSCORES ALLOWED +define('_PEAR_CHANNELS_SERVER_PREG', '[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*(\/[a-zA-Z0-9\-]+)*'); +define('PEAR_CHANNELS_SERVER_PREG', '/^' . _PEAR_CHANNELS_SERVER_PREG . '\\z/i'); - /** - * Rebuild the dependency DB by reading registry entries. - * @return true|PEAR_Error - */ - function rebuildDB() - { - $depdb = array('_version' => $this->_version); - if (!$this->hasWriteAccess()) { - // allow startup for read-only with older Registry - return $depdb; - } +define('_PEAR_CHANNELS_PACKAGE_PREG', '(' ._PEAR_CHANNELS_SERVER_PREG . ')\/(' + . _PEAR_COMMON_PACKAGE_NAME_PREG . ')'); +define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '\\z/i'); - $packages = $this->_registry->listAllPackages(); - if (PEAR::isError($packages)) { - return $packages; - } +define('_PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '(' . _PEAR_CHANNELS_NAME_PREG . ')::(' + . _PEAR_COMMON_PACKAGE_NAME_PREG . ')(-([.0-9a-zA-Z]+))?'); +define('PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_CHANNEL_DOWNLOAD_PREG . '\\z/'); - foreach ($packages as $channel => $ps) { - foreach ($ps as $package) { - $package = $this->_registry->getPackage($package, $channel); - if (PEAR::isError($package)) { - return $package; - } - $this->_setPackageDeps($depdb, $package); - } - } +/** + * List of temporary files and directories registered by + * PEAR_Common::addTempFile(). + * @var array + */ +$GLOBALS['_PEAR_Common_tempfiles'] = array(); - $error = $this->_writeDepDB($depdb); - if (PEAR::isError($error)) { - return $error; - } +/** + * Valid maintainer roles + * @var array + */ +$GLOBALS['_PEAR_Common_maintainer_roles'] = array('lead','developer','contributor','helper'); - $this->_cache = $depdb; - return true; - } +/** + * Valid release states + * @var array + */ +$GLOBALS['_PEAR_Common_release_states'] = array('alpha','beta','stable','snapshot','devel'); + +/** + * Valid dependency types + * @var array + */ +$GLOBALS['_PEAR_Common_dependency_types'] = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi'); + +/** + * Valid dependency relations + * @var array + */ +$GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge','not', 'ne'); + +/** + * Valid file roles + * @var array + */ +$GLOBALS['_PEAR_Common_file_roles'] = array('php','ext','test','doc','data','src','script'); + +/** + * Valid replacement types + * @var array + */ +$GLOBALS['_PEAR_Common_replacement_types'] = array('php-const', 'pear-config', 'package-info'); +/** + * Valid "provide" types + * @var array + */ +$GLOBALS['_PEAR_Common_provide_types'] = array('ext', 'prog', 'class', 'function', 'feature', 'api'); + +/** + * Valid "provide" types + * @var array + */ +$GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'pre-uninstall', 'post-uninstall', 'pre-build', 'post-build', 'pre-configure', 'post-configure', 'pre-setup', 'post-setup'); + +/** + * Class providing common functionality for PEAR administration classes. + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V. V. Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + * @deprecated This class will disappear, and its components will be spread + * into smaller classes, like the AT&T breakup, as of Release 1.4.0a1 + */ +class PEAR_Common extends PEAR +{ /** - * Register usage of the dependency DB to prevent race conditions - * @param int one of the LOCK_* constants - * @return true|PEAR_Error - * @access private + * User Interface object (PEAR_Frontend_* class). If null, + * the log() method uses print. + * @var object */ - function _lock($mode = LOCK_EX) - { - if (stristr(php_uname(), 'Windows 9')) { - return true; - } - - if ($mode != LOCK_UN && is_resource($this->_lockFp)) { - // XXX does not check type of lock (LOCK_SH/LOCK_EX) - return true; - } + var $ui = null; - $open_mode = 'w'; - // XXX People reported problems with LOCK_SH and 'w' - if ($mode === LOCK_SH) { - if (!file_exists($this->_lockfile)) { - touch($this->_lockfile); - } elseif (!is_file($this->_lockfile)) { - return PEAR::raiseError('could not create Dependency lock file, ' . - 'it exists and is not a regular file'); - } - $open_mode = 'r'; - } + /** + * Configuration object (PEAR_Config). + * @var PEAR_Config + */ + var $config = null; - if (!is_resource($this->_lockFp)) { - $this->_lockFp = @fopen($this->_lockfile, $open_mode); - } + /** stack of elements, gives some sort of XML context */ + var $element_stack = array(); - if (!is_resource($this->_lockFp)) { - return PEAR::raiseError("could not create Dependency lock file" . - (isset($php_errormsg) ? ": " . $php_errormsg : "")); - } + /** name of currently parsed XML element */ + var $current_element; - if (!(int)flock($this->_lockFp, $mode)) { - switch ($mode) { - case LOCK_SH: $str = 'shared'; break; - case LOCK_EX: $str = 'exclusive'; break; - case LOCK_UN: $str = 'unlock'; break; - default: $str = 'unknown'; break; - } + /** array of attributes of the currently parsed XML element */ + var $current_attributes = array(); - return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)"); - } + /** assoc with information about a package */ + var $pkginfo = array(); - return true; - } + var $current_path = null; /** - * Release usage of dependency DB - * @return true|PEAR_Error + * Flag variable used to mark a valid package file + * @var boolean * @access private */ - function _unlock() - { - $ret = $this->_lock(LOCK_UN); - if (is_resource($this->_lockFp)) { - fclose($this->_lockFp); - } - $this->_lockFp = null; - return $ret; - } + var $_validPackageFile; /** - * Load the dependency database from disk, or return the cache - * @return array|PEAR_Error + * PEAR_Common constructor + * + * @access public */ - function _getDepDB() + function PEAR_Common() { - if (!$this->hasWriteAccess()) { - return array('_version' => $this->_version); - } - - if (isset($this->_cache)) { - return $this->_cache; - } - - if (!$fp = fopen($this->_depdb, 'r')) { - $err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'"); - return $err; - } - - $rt = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - clearstatcache(); - fclose($fp); - $data = unserialize(file_get_contents($this->_depdb)); - set_magic_quotes_runtime($rt); - $this->_cache = $data; - return $data; + parent::PEAR(); + $this->config = &PEAR_Config::singleton(); + $this->debug = $this->config->get('verbose'); } /** - * Write out the dependency database to disk - * @param array the database - * @return true|PEAR_Error + * PEAR_Common destructor + * * @access private */ - function _writeDepDB(&$deps) + function _PEAR_Common() { - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } + // doesn't work due to bug #14744 + //$tempfiles = $this->_tempfiles; + $tempfiles =& $GLOBALS['_PEAR_Common_tempfiles']; + while ($file = array_shift($tempfiles)) { + if (@is_dir($file)) { + if (!class_exists('System')) { + require_once 'System.php'; + } - if (!$fp = fopen($this->_depdb, 'wb')) { - $this->_unlock(); - return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing"); + System::rm(array('-rf', $file)); + } elseif (file_exists($file)) { + unlink($file); + } } - - $rt = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - fwrite($fp, serialize($deps)); - set_magic_quotes_runtime($rt); - fclose($fp); - $this->_unlock(); - $this->_cache = $deps; - return true; } /** - * Register all dependencies from a package in the dependencies database, in essence - * "installing" the package's dependency information - * @param array the database - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @access private + * Register a temporary file or directory. When the destructor is + * executed, all registered temporary files and directories are + * removed. + * + * @param string $file name of file or directory + * + * @return void + * + * @access public */ - function _setPackageDeps(&$data, &$pkg) + function addTempFile($file) { - $pkg->setConfig($this->_config); - if ($pkg->getPackagexmlVersion() == '1.0') { - $gen = &$pkg->getDefaultGenerator(); - $deps = $gen->dependenciesToV2(); - } else { - $deps = $pkg->getDeps(true); - } - - if (!$deps) { - return; - } - - if (!is_array($data)) { - $data = array(); - } - - if (!isset($data['dependencies'])) { - $data['dependencies'] = array(); - } - - $channel = strtolower($pkg->getChannel()); - $package = strtolower($pkg->getPackage()); - - if (!isset($data['dependencies'][$channel])) { - $data['dependencies'][$channel] = array(); + if (!class_exists('PEAR_Frontend')) { + require_once 'PEAR/Frontend.php'; } + PEAR_Frontend::addTempFile($file); + } - $data['dependencies'][$channel][$package] = array(); - if (isset($deps['required']['package'])) { - if (!isset($deps['required']['package'][0])) { - $deps['required']['package'] = array($deps['required']['package']); - } - - foreach ($deps['required']['package'] as $dep) { - $this->_registerDep($data, $pkg, $dep, 'required'); - } + /** + * Wrapper to System::mkDir(), creates a directory as well as + * any necessary parent directories. + * + * @param string $dir directory name + * + * @return bool TRUE on success, or a PEAR error + * + * @access public + */ + function mkDirHier($dir) + { + // Only used in Installer - move it there ? + $this->log(2, "+ create dir $dir"); + if (!class_exists('System')) { + require_once 'System.php'; } + return System::mkDir(array('-p', $dir)); + } - if (isset($deps['optional']['package'])) { - if (!isset($deps['optional']['package'][0])) { - $deps['optional']['package'] = array($deps['optional']['package']); + /** + * Logging method. + * + * @param int $level log level (0 is quiet, higher is noisier) + * @param string $msg message to write to the log + * + * @return void + * + * @access public + * @static + */ + function log($level, $msg, $append_crlf = true) + { + if ($this->debug >= $level) { + if (!class_exists('PEAR_Frontend')) { + require_once 'PEAR/Frontend.php'; } - foreach ($deps['optional']['package'] as $dep) { - $this->_registerDep($data, $pkg, $dep, 'optional'); + $ui = &PEAR_Frontend::singleton(); + if (is_a($ui, 'PEAR_Frontend')) { + $ui->log($msg, $append_crlf); + } else { + print "$msg\n"; } } + } - if (isset($deps['required']['subpackage'])) { - if (!isset($deps['required']['subpackage'][0])) { - $deps['required']['subpackage'] = array($deps['required']['subpackage']); - } - - foreach ($deps['required']['subpackage'] as $dep) { - $this->_registerDep($data, $pkg, $dep, 'required'); - } + /** + * Create and register a temporary directory. + * + * @param string $tmpdir (optional) Directory to use as tmpdir. + * Will use system defaults (for example + * /tmp or c:\windows\temp) if not specified + * + * @return string name of created directory + * + * @access public + */ + function mkTempDir($tmpdir = '') + { + $topt = $tmpdir ? array('-t', $tmpdir) : array(); + $topt = array_merge($topt, array('-d', 'pear')); + if (!class_exists('System')) { + require_once 'System.php'; } - if (isset($deps['optional']['subpackage'])) { - if (!isset($deps['optional']['subpackage'][0])) { - $deps['optional']['subpackage'] = array($deps['optional']['subpackage']); - } - - foreach ($deps['optional']['subpackage'] as $dep) { - $this->_registerDep($data, $pkg, $dep, 'optional'); - } + if (!$tmpdir = System::mktemp($topt)) { + return false; } - if (isset($deps['group'])) { - if (!isset($deps['group'][0])) { - $deps['group'] = array($deps['group']); - } - - foreach ($deps['group'] as $group) { - if (isset($group['package'])) { - if (!isset($group['package'][0])) { - $group['package'] = array($group['package']); - } - - foreach ($group['package'] as $dep) { - $this->_registerDep($data, $pkg, $dep, 'optional', - $group['attribs']['name']); - } - } + $this->addTempFile($tmpdir); + return $tmpdir; + } - if (isset($group['subpackage'])) { - if (!isset($group['subpackage'][0])) { - $group['subpackage'] = array($group['subpackage']); - } + /** + * Set object that represents the frontend to be used. + * + * @param object Reference of the frontend object + * @return void + * @access public + */ + function setFrontendObject(&$ui) + { + $this->ui = &$ui; + } - foreach ($group['subpackage'] as $dep) { - $this->_registerDep($data, $pkg, $dep, 'optional', - $group['attribs']['name']); - } - } - } + /** + * Return an array containing all of the states that are more stable than + * or equal to the passed in state + * + * @param string Release state + * @param boolean Determines whether to include $state in the list + * @return false|array False if $state is not a valid release state + */ + function betterStates($state, $include = false) + { + static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); + $i = array_search($state, $states); + if ($i === false) { + return false; } - - if ($data['dependencies'][$channel][$package] == array()) { - unset($data['dependencies'][$channel][$package]); - if (!count($data['dependencies'][$channel])) { - unset($data['dependencies'][$channel]); - } + if ($include) { + $i--; } + return array_slice($states, $i + 1); } /** - * @param array the database - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @param array the specific dependency - * @param required|optional whether this is a required or an optional dep - * @param string|false dependency group this dependency is from, or false for ordinary dep + * Get the valid roles for a PEAR package maintainer + * + * @return array + * @static */ - function _registerDep(&$data, &$pkg, $dep, $type, $group = false) + function getUserRoles() { - $info = array( - 'dep' => $dep, - 'type' => $type, - 'group' => $group - ); + return $GLOBALS['_PEAR_Common_maintainer_roles']; + } - $dep = array_map('strtolower', $dep); - $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; - if (!isset($data['dependencies'])) { - $data['dependencies'] = array(); - } - - $channel = strtolower($pkg->getChannel()); - $package = strtolower($pkg->getPackage()); - - if (!isset($data['dependencies'][$channel])) { - $data['dependencies'][$channel] = array(); - } - - if (!isset($data['dependencies'][$channel][$package])) { - $data['dependencies'][$channel][$package] = array(); - } - - $data['dependencies'][$channel][$package][] = $info; - if (isset($data['packages'][$depchannel][$dep['name']])) { - $found = false; - foreach ($data['packages'][$depchannel][$dep['name']] as $i => $p) { - if ($p['channel'] == $channel && $p['package'] == $package) { - $found = true; - break; - } - } - - if (!$found) { - $data['packages'][$depchannel][$dep['name']][] = array( - 'channel' => $channel, - 'package' => $package - ); - } - } else { - if (!isset($data['packages'])) { - $data['packages'] = array(); - } - - if (!isset($data['packages'][$depchannel])) { - $data['packages'][$depchannel] = array(); - } - - if (!isset($data['packages'][$depchannel][$dep['name']])) { - $data['packages'][$depchannel][$dep['name']] = array(); - } - - $data['packages'][$depchannel][$dep['name']][] = array( - 'channel' => $channel, - 'package' => $package - ); - } + /** + * Get the valid package release states of packages + * + * @return array + * @static + */ + function getReleaseStates() + { + return $GLOBALS['_PEAR_Common_release_states']; } -}PEAR-1.8.0/PEAR/Dependency2.php100664 764 764 142623 100664 10755 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Dependency2.php,v 1.59 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * Required for the PEAR_VALIDATE_* constants - */ -require_once 'PEAR/Validate.php'; -/** - * Dependency check for PEAR packages - * - * This class handles both version 1.0 and 2.0 dependencies - * WARNING: *any* changes to this class must be duplicated in the - * test_PEAR_Dependency2 class found in tests/PEAR_Dependency2/setup.php.inc, - * or unit tests will not actually validate the changes - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Dependency2 -{ /** - * One of the PEAR_VALIDATE_* states - * @see PEAR_VALIDATE_NORMAL - * @var integer + * Get the implemented dependency types (php, ext, pkg etc.) + * + * @return array + * @static */ - var $_state; + function getDependencyTypes() + { + return $GLOBALS['_PEAR_Common_dependency_types']; + } /** - * Command-line options to install/upgrade/uninstall commands - * @param array + * Get the implemented dependency relations (has, lt, ge etc.) + * + * @return array + * @static */ - var $_options; + function getDependencyRelations() + { + return $GLOBALS['_PEAR_Common_dependency_relations']; + } /** - * @var OS_Guess + * Get the implemented file roles + * + * @return array + * @static */ - var $_os; + function getFileRoles() + { + return $GLOBALS['_PEAR_Common_file_roles']; + } /** - * @var PEAR_Registry + * Get the implemented file replacement types in + * + * @return array + * @static */ - var $_registry; + function getReplacementTypes() + { + return $GLOBALS['_PEAR_Common_replacement_types']; + } /** - * @var PEAR_Config + * Get the implemented file replacement types in + * + * @return array + * @static */ - var $_config; + function getProvideTypes() + { + return $GLOBALS['_PEAR_Common_provide_types']; + } /** - * @var PEAR_DependencyDB + * Get the implemented file replacement types in + * + * @return array + * @static */ - var $_dependencydb; + function getScriptPhases() + { + return $GLOBALS['_PEAR_Common_script_phases']; + } /** - * Output of PEAR_Registry::parsedPackageName() - * @var array + * Test whether a string contains a valid package name. + * + * @param string $name the package name to test + * + * @return bool + * + * @access public */ - var $_currentPackage; + function validPackageName($name) + { + return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name); + } /** - * @param PEAR_Config - * @param array installation options - * @param array format of PEAR_Registry::parsedPackageName() - * @param int installation state (one of PEAR_VALIDATE_*) + * Test whether a string contains a valid package version. + * + * @param string $ver the package version to test + * + * @return bool + * + * @access public */ - function PEAR_Dependency2(&$config, $installoptions, $package, - $state = PEAR_VALIDATE_INSTALLING) + function validPackageVersion($ver) { - $this->_config = &$config; - if (!class_exists('PEAR_DependencyDB')) { - require_once 'PEAR/DependencyDB.php'; - } - - if (isset($installoptions['packagingroot'])) { - // make sure depdb is in the right location - $config->setInstallRoot($installoptions['packagingroot']); - } + return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); + } - $this->_registry = &$config->getRegistry(); - $this->_dependencydb = &PEAR_DependencyDB::singleton($config); - if (isset($installoptions['packagingroot'])) { - $config->setInstallRoot(false); + /** + * @param string $path relative or absolute include path + * @return boolean + * @static + */ + function isIncludeable($path) + { + if (file_exists($path) && is_readable($path)) { + return true; } - $this->_options = $installoptions; - $this->_state = $state; - if (!class_exists('OS_Guess')) { - require_once 'OS/Guess.php'; + $ipath = explode(PATH_SEPARATOR, ini_get('include_path')); + foreach ($ipath as $include) { + $test = realpath($include . DIRECTORY_SEPARATOR . $path); + if (file_exists($test) && is_readable($test)) { + return true; + } } - $this->_os = new OS_Guess; - $this->_currentPackage = $package; + return false; } - function _getExtraString($dep) + function _postProcessChecks($pf) { - $extra = ' ('; - if (isset($dep['uri'])) { - return ''; + if (!PEAR::isError($pf)) { + return $this->_postProcessValidPackagexml($pf); } - if (isset($dep['recommended'])) { - $extra .= 'recommended version ' . $dep['recommended']; - } else { - if (isset($dep['min'])) { - $extra .= 'version >= ' . $dep['min']; - } - - if (isset($dep['max'])) { - if ($extra != ' (') { - $extra .= ', '; - } - $extra .= 'version <= ' . $dep['max']; - } - - if (isset($dep['exclude'])) { - if (!is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); - } - - if ($extra != ' (') { - $extra .= ', '; - } - - $extra .= 'excluded versions: '; - foreach ($dep['exclude'] as $i => $exclude) { - if ($i) { - $extra .= ', '; - } - $extra .= $exclude; - } + $errs = $pf->getUserinfo(); + if (is_array($errs)) { + foreach ($errs as $error) { + $e = $this->raiseError($error['message'], $error['code'], null, null, $error); } } - $extra .= ')'; - if ($extra == ' ()') { - $extra = ''; - } - - return $extra; + return $pf; } /** - * This makes unit-testing a heck of a lot easier + * Returns information about a package file. Expects the name of + * a gzipped tar file as input. + * + * @param string $file name of .tgz file + * + * @return array array with package information + * + * @access public + * @deprecated use PEAR_PackageFile->fromTgzFile() instead + * */ - function getPHP_OS() + function infoFromTgzFile($file) { - return PHP_OS; + $packagefile = &new PEAR_PackageFile($this->config); + $pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL); + return $this->_postProcessChecks($pf); } /** - * This makes unit-testing a heck of a lot easier + * Returns information about a package file. Expects the name of + * a package xml file as input. + * + * @param string $descfile name of package xml file + * + * @return array array with package information + * + * @access public + * @deprecated use PEAR_PackageFile->fromPackageFile() instead + * */ - function getsysname() + function infoFromDescriptionFile($descfile) { - return $this->_os->getSysname(); + $packagefile = &new PEAR_PackageFile($this->config); + $pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); + return $this->_postProcessChecks($pf); } /** - * Specify a dependency on an OS. Use arch for detailed os/processor information + * Returns information about a package file. Expects the contents + * of a package xml file as input. + * + * @param string $data contents of package.xml file + * + * @return array array with package information + * + * @access public + * @deprecated use PEAR_PackageFile->fromXmlstring() instead * - * There are two generic OS dependencies that will be the most common, unix and windows. - * Other options are linux, freebsd, darwin (OS X), sunos, irix, hpux, aix */ - function validateOsDependency($dep) + function infoFromString($data) { - if ($this->_state != PEAR_VALIDATE_INSTALLING && $this->_state != PEAR_VALIDATE_DOWNLOADING) { - return true; - } + $packagefile = &new PEAR_PackageFile($this->config); + $pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false); + return $this->_postProcessChecks($pf); + } - if ($dep['name'] == '*') { - return true; + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return array + */ + function _postProcessValidPackagexml(&$pf) + { + if (!is_a($pf, 'PEAR_PackageFile_v2')) { + $this->pkginfo = $pf->toArray(); + return $this->pkginfo; } - $not = isset($dep['conflicts']) ? true : false; - switch (strtolower($dep['name'])) { - case 'windows' : - if ($not) { - if (strtolower(substr($this->getPHP_OS(), 0, 3)) == 'win') { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError("Cannot install %s on Windows"); - } - - return $this->warning("warning: Cannot install %s on Windows"); - } - } else { - if (strtolower(substr($this->getPHP_OS(), 0, 3)) != 'win') { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError("Can only install %s on Windows"); - } - - return $this->warning("warning: Can only install %s on Windows"); - } - } - break; - case 'unix' : - $unices = array('linux', 'freebsd', 'darwin', 'sunos', 'irix', 'hpux', 'aix'); - if ($not) { - if (in_array($this->getSysname(), $unices)) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError("Cannot install %s on any Unix system"); - } - - return $this->warning( "warning: Cannot install %s on any Unix system"); - } - } else { - if (!in_array($this->getSysname(), $unices)) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError("Can only install %s on a Unix system"); - } + // sort of make this into a package.xml 1.0-style array + // changelog is not converted to old format. + $arr = $pf->toArray(true); + $arr = array_merge($arr, $arr['old']); + unset($arr['old'], $arr['xsdversion'], $arr['contents'], $arr['compatible'], + $arr['channel'], $arr['uri'], $arr['dependencies'], $arr['phprelease'], + $arr['extsrcrelease'], $arr['zendextsrcrelease'], $arr['extbinrelease'], + $arr['zendextbinrelease'], $arr['bundle'], $arr['lead'], $arr['developer'], + $arr['helper'], $arr['contributor']); + $arr['filelist'] = $pf->getFilelist(); + $this->pkginfo = $arr; + return $arr; + } - return $this->warning("warning: Can only install %s on a Unix system"); + /** + * Returns package information from different sources + * + * This method is able to extract information about a package + * from a .tgz archive or from a XML package definition file. + * + * @access public + * @param string Filename of the source ('package.xml', '.tgz') + * @return string + * @deprecated use PEAR_PackageFile->fromAnyFile() instead + */ + function infoFromAny($info) + { + if (is_string($info) && file_exists($info)) { + $packagefile = &new PEAR_PackageFile($this->config); + $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($pf)) { + $errs = $pf->getUserinfo(); + if (is_array($errs)) { + foreach ($errs as $error) { + $e = $this->raiseError($error['message'], $error['code'], null, null, $error); } } - break; - default : - if ($not) { - if (strtolower($dep['name']) == strtolower($this->getSysname())) { - if (!isset($this->_options['nodeps']) && - !isset($this->_options['force'])) { - return $this->raiseError('Cannot install %s on ' . $dep['name'] . - ' operating system'); - } - return $this->warning('warning: Cannot install %s on ' . - $dep['name'] . ' operating system'); - } - } else { - if (strtolower($dep['name']) != strtolower($this->getSysname())) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('Cannot install %s on ' . - $this->getSysname() . - ' operating system, can only install on ' . $dep['name']); - } + return $pf; + } - return $this->warning('warning: Cannot install %s on ' . - $this->getSysname() . - ' operating system, can only install on ' . $dep['name']); - } - } + return $this->_postProcessValidPackagexml($pf); } - return true; + + return $info; } /** - * This makes unit-testing a heck of a lot easier + * Return an XML document based on the package info (as returned + * by the PEAR_Common::infoFrom* methods). + * + * @param array $pkginfo package info + * + * @return string XML data + * + * @access public + * @deprecated use a PEAR_PackageFile_v* object's generator instead */ - function matchSignature($pattern) + function xmlFromInfo($pkginfo) { - return $this->_os->matchSignature($pattern); + $config = &PEAR_Config::singleton(); + $packagefile = &new PEAR_PackageFile($config); + $pf = &$packagefile->fromArray($pkginfo); + $gen = &$pf->getDefaultGenerator(); + return $gen->toXml(PEAR_VALIDATE_PACKAGING); } /** - * Specify a complex dependency on an OS/processor/kernel version, - * Use OS for simple operating system dependency. + * Validate XML package definition file. * - * This is the only dependency that accepts an eregable pattern. The pattern - * will be matched against the php_uname() output parsed by OS_Guess + * @param string $info Filename of the package archive or of the + * package definition file + * @param array $errors Array that will contain the errors + * @param array $warnings Array that will contain the warnings + * @param string $dir_prefix (optional) directory where source files + * may be found, or empty if they are not available + * @access public + * @return boolean + * @deprecated use the validation of PEAR_PackageFile objects */ - function validateArchDependency($dep) + function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '') { - if ($this->_state != PEAR_VALIDATE_INSTALLING) { - return true; + $config = &PEAR_Config::singleton(); + $packagefile = &new PEAR_PackageFile($config); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (strpos($info, 'fromXmlString($info, PEAR_VALIDATE_NORMAL, ''); + } else { + $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); } - $not = isset($dep['conflicts']) ? true : false; - if (!$this->matchSignature($dep['pattern'])) { - if (!$not) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s Architecture dependency failed, does not ' . - 'match "' . $dep['pattern'] . '"'); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf)) { + $errs = $pf->getUserinfo(); + if (is_array($errs)) { + foreach ($errs as $error) { + if ($error['level'] == 'error') { + $errors[] = $error['message']; + } else { + $warnings[] = $error['message']; + } } - - return $this->warning('warning: %s Architecture dependency failed, does ' . - 'not match "' . $dep['pattern'] . '"'); - } - - return true; - } - - if ($not) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s Architecture dependency failed, required "' . - $dep['pattern'] . '"'); } - return $this->warning('warning: %s Architecture dependency failed, ' . - 'required "' . $dep['pattern'] . '"'); + return false; } return true; } /** - * This makes unit-testing a heck of a lot easier - */ - function extension_loaded($name) - { - return extension_loaded($name); - } - - /** - * This makes unit-testing a heck of a lot easier - */ - function phpversion($name = null) - { - if ($name !== null) { - return phpversion($name); - } - - return phpversion(); - } - - function validateExtensionDependency($dep, $required = true) + * Build a "provides" array from data returned by + * analyzeSourceCode(). The format of the built array is like + * this: + * + * array( + * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), + * ... + * ) + * + * + * @param array $srcinfo array with information about a source file + * as returned by the analyzeSourceCode() method. + * + * @return void + * + * @access public + * + */ + function buildProvidesArray($srcinfo) { - if ($this->_state != PEAR_VALIDATE_INSTALLING && - $this->_state != PEAR_VALIDATE_DOWNLOADING) { - return true; + $file = basename($srcinfo['source_file']); + $pn = ''; + if (isset($this->_packageName)) { + $pn = $this->_packageName; } - $loaded = $this->extension_loaded($dep['name']); - $extra = $this->_getExtraString($dep); - if (isset($dep['exclude'])) { - if (!is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); + $pnl = strlen($pn); + foreach ($srcinfo['declared_classes'] as $class) { + $key = "class;$class"; + if (isset($this->pkginfo['provides'][$key])) { + continue; } - } - - if (!isset($dep['min']) && !isset($dep['max']) && - !isset($dep['recommended']) && !isset($dep['exclude'])) { - if ($loaded) { - if (isset($dep['conflicts'])) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s conflicts with PHP extension "' . - $dep['name'] . '"' . $extra); - } - - return $this->warning('warning: %s conflicts with PHP extension "' . - $dep['name'] . '"' . $extra); - } - - return true; - } else { - if (isset($dep['conflicts'])) { - return true; - } - - if ($required) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PHP extension "' . - $dep['name'] . '"' . $extra); - } - - return $this->warning('warning: %s requires PHP extension "' . - $dep['name'] . '"' . $extra); - } - return $this->warning('%s can optionally use PHP extension "' . - $dep['name'] . '"' . $extra); + $this->pkginfo['provides'][$key] = + array('file'=> $file, 'type' => 'class', 'name' => $class); + if (isset($srcinfo['inheritance'][$class])) { + $this->pkginfo['provides'][$key]['extends'] = + $srcinfo['inheritance'][$class]; } } - if (!$loaded) { - if (isset($dep['conflicts'])) { - return true; - } - - if (!$required) { - return $this->warning('%s can optionally use PHP extension "' . - $dep['name'] . '"' . $extra); - } + foreach ($srcinfo['declared_methods'] as $class => $methods) { + foreach ($methods as $method) { + $function = "$class::$method"; + $key = "function;$function"; + if ($method{0} == '_' || !strcasecmp($method, $class) || + isset($this->pkginfo['provides'][$key])) { + continue; + } - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PHP extension "' . $dep['name'] . - '"' . $extra); + $this->pkginfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); } - - return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . - '"' . $extra); - } - - $version = (string) $this->phpversion($dep['name']); - if (empty($version)) { - $version = '0'; - } - - $fail = false; - if (isset($dep['min']) && !version_compare($version, $dep['min'], '>=')) { - $fail = true; - } - - if (isset($dep['max']) && !version_compare($version, $dep['max'], '<=')) { - $fail = true; } - if ($fail && !isset($dep['conflicts'])) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PHP extension "' . $dep['name'] . - '"' . $extra . ', installed version is ' . $version); + foreach ($srcinfo['declared_functions'] as $function) { + $key = "function;$function"; + if ($function{0} == '_' || isset($this->pkginfo['provides'][$key])) { + continue; } - return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . - '"' . $extra . ', installed version is ' . $version); - } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && isset($dep['conflicts'])) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s conflicts with PHP extension "' . - $dep['name'] . '"' . $extra . ', installed version is ' . $version); + if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { + $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; } - return $this->warning('warning: %s conflicts with PHP extension "' . - $dep['name'] . '"' . $extra . ', installed version is ' . $version); - } - - if (isset($dep['exclude'])) { - foreach ($dep['exclude'] as $exclude) { - if (version_compare($version, $exclude, '==')) { - if (isset($dep['conflicts'])) { - continue; - } - - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s is not compatible with PHP extension "' . - $dep['name'] . '" version ' . - $exclude); - } - - return $this->warning('warning: %s is not compatible with PHP extension "' . - $dep['name'] . '" version ' . - $exclude); - } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s conflicts with PHP extension "' . - $dep['name'] . '"' . $extra . ', installed version is ' . $version); - } - - return $this->warning('warning: %s conflicts with PHP extension "' . - $dep['name'] . '"' . $extra . ', installed version is ' . $version); - } - } + $this->pkginfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); } + } - if (isset($dep['recommended'])) { - if (version_compare($version, $dep['recommended'], '==')) { - return true; - } - - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s dependency: PHP extension ' . $dep['name'] . - ' version "' . $version . '"' . - ' is not the recommended version "' . $dep['recommended'] . - '", but may be compatible, use --force to install'); - } - - return $this->warning('warning: %s dependency: PHP extension ' . - $dep['name'] . ' version "' . $version . '"' . - ' is not the recommended version "' . $dep['recommended'].'"'); + /** + * Analyze the source code of the given PHP file + * + * @param string Filename of the PHP file + * @return mixed + * @access public + */ + function analyzeSourceCode($file) + { + if (!class_exists('PEAR_PackageFile_v2_Validator')) { + require_once 'PEAR/PackageFile/v2/Validator.php'; } - return true; + $a = new PEAR_PackageFile_v2_Validator; + return $a->analyzeSourceCode($file); } - function validatePhpDependency($dep) + function detectDependencies($any, $status_callback = null) { - if ($this->_state != PEAR_VALIDATE_INSTALLING && - $this->_state != PEAR_VALIDATE_DOWNLOADING) { - return true; + if (!function_exists("token_get_all")) { + return false; } - $version = $this->phpversion(); - $extra = $this->_getExtraString($dep); - if (isset($dep['exclude'])) { - if (!is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); - } + if (PEAR::isError($info = $this->infoFromAny($any))) { + return $this->raiseError($info); } - if (isset($dep['min'])) { - if (!version_compare($version, $dep['min'], '>=')) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PHP' . - $extra . ', installed version is ' . $version); - } - - return $this->warning('warning: %s requires PHP' . - $extra . ', installed version is ' . $version); - } + if (!is_array($info)) { + return false; } - if (isset($dep['max'])) { - if (!version_compare($version, $dep['max'], '<=')) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PHP' . - $extra . ', installed version is ' . $version); - } - - return $this->warning('warning: %s requires PHP' . - $extra . ', installed version is ' . $version); - } + $deps = array(); + $used_c = $decl_c = $decl_f = $decl_m = array(); + foreach ($info['filelist'] as $file => $fa) { + $tmp = $this->analyzeSourceCode($file); + $used_c = @array_merge($used_c, $tmp['used_classes']); + $decl_c = @array_merge($decl_c, $tmp['declared_classes']); + $decl_f = @array_merge($decl_f, $tmp['declared_functions']); + $decl_m = @array_merge($decl_m, $tmp['declared_methods']); + $inheri = @array_merge($inheri, $tmp['inheritance']); } - if (isset($dep['exclude'])) { - foreach ($dep['exclude'] as $exclude) { - if (version_compare($version, $exclude, '==')) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s is not compatible with PHP version ' . - $exclude); - } - - return $this->warning( - 'warning: %s is not compatible with PHP version ' . - $exclude); - } - } - } + $used_c = array_unique($used_c); + $decl_c = array_unique($decl_c); + $undecl_c = array_diff($used_c, $decl_c); - return true; + return array('used_classes' => $used_c, + 'declared_classes' => $decl_c, + 'declared_methods' => $decl_m, + 'declared_functions' => $decl_f, + 'undeclared_classes' => $undecl_c, + 'inheritance' => $inheri, + ); } /** - * This makes unit-testing a heck of a lot easier + * Download a file through HTTP. Considers suggested file name in + * Content-disposition: header and can run a callback function for + * different events. The callback will be called with two + * parameters: the callback type, and parameters. The implemented + * callback types are: + * + * 'setup' called at the very beginning, parameter is a UI object + * that should be used for all output + * 'message' the parameter is a string with an informational message + * 'saveas' may be used to save with a different file name, the + * parameter is the filename that is about to be used. + * If a 'saveas' callback returns a non-empty string, + * that file name will be used as the filename instead. + * Note that $save_dir will not be affected by this, only + * the basename of the file. + * 'start' download is starting, parameter is number of bytes + * that are expected, or -1 if unknown + * 'bytesread' parameter is the number of bytes read so far + * 'done' download is complete, parameter is the total number + * of bytes read + * 'connfailed' if the TCP connection fails, this callback is called + * with array(host,port,errno,errmsg) + * 'writefailed' if writing to disk fails, this callback is called + * with array(destfile,errmsg) + * + * If an HTTP proxy has been configured (http_proxy PEAR_Config + * setting), the proxy will be used. + * + * @param string $url the URL to download + * @param object $ui PEAR_Frontend_* instance + * @param object $config PEAR_Config instance + * @param string $save_dir (optional) directory to save file in + * @param mixed $callback (optional) function/method to call for status + * updates + * + * @return string Returns the full path of the downloaded file or a PEAR + * error on failure. If the error is caused by + * socket-related errors, the error object will + * have the fsockopen error code available through + * getCode(). + * + * @access public + * @deprecated in favor of PEAR_Downloader::downloadHttp() */ - function getPEARVersion() + function downloadHttp($url, &$ui, $save_dir = '.', $callback = null) { - return '1.8.0'; + if (!class_exists('PEAR_Downloader')) { + require_once 'PEAR/Downloader.php'; + } + return PEAR_Downloader::downloadHttp($url, $ui, $save_dir, $callback); } +} - function validatePearinstallerDependency($dep) - { - $pearversion = $this->getPEARVersion(); - $extra = $this->_getExtraString($dep); - if (isset($dep['exclude'])) { - if (!is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); - } - } +require_once 'PEAR/Config.php'; +require_once 'PEAR/PackageFile.php';PEAR-1.9.0/PEAR/Config.php100664 764 764 204452 100664 10022 + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Config.php 286480 2009-07-29 02:50:02Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ - if (version_compare($pearversion, $dep['min'], '<')) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PEAR Installer' . $extra . - ', installed version is ' . $pearversion); - } +/** + * Required for error handling + */ +require_once 'PEAR.php'; +require_once 'PEAR/Registry.php'; +require_once 'PEAR/Installer/Role.php'; +require_once 'System.php'; - return $this->warning('warning: %s requires PEAR Installer' . $extra . - ', installed version is ' . $pearversion); - } +/** + * Last created PEAR_Config instance. + * @var object + */ +$GLOBALS['_PEAR_Config_instance'] = null; +if (!defined('PEAR_INSTALL_DIR') || !PEAR_INSTALL_DIR) { + $PEAR_INSTALL_DIR = PHP_LIBDIR . DIRECTORY_SEPARATOR . 'pear'; +} else { + $PEAR_INSTALL_DIR = PEAR_INSTALL_DIR; +} - if (isset($dep['max'])) { - if (version_compare($pearversion, $dep['max'], '>')) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PEAR Installer' . $extra . - ', installed version is ' . $pearversion); - } +// Below we define constants with default values for all configuration +// parameters except username/password. All of them can have their +// defaults set through environment variables. The reason we use the +// PHP_ prefix is for some security, PHP protects environment +// variables starting with PHP_*. - return $this->warning('warning: %s requires PEAR Installer' . $extra . - ', installed version is ' . $pearversion); - } - } +// default channel and preferred mirror is based on whether we are invoked through +// the "pear" or the "pecl" command +if (!defined('PEAR_RUNTYPE')) { + define('PEAR_RUNTYPE', 'pear'); +} - if (isset($dep['exclude'])) { - if (!isset($dep['exclude'][0])) { - $dep['exclude'] = array($dep['exclude']); - } +if (PEAR_RUNTYPE == 'pear') { + define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pear.php.net'); +} else { + define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pecl.php.net'); +} - foreach ($dep['exclude'] as $exclude) { - if (version_compare($exclude, $pearversion, '==')) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s is not compatible with PEAR Installer ' . - 'version ' . $exclude); - } +if (getenv('PHP_PEAR_SYSCONF_DIR')) { + define('PEAR_CONFIG_SYSCONFDIR', getenv('PHP_PEAR_SYSCONF_DIR')); +} elseif (getenv('SystemRoot')) { + define('PEAR_CONFIG_SYSCONFDIR', getenv('SystemRoot')); +} else { + define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR); +} - return $this->warning('warning: %s is not compatible with PEAR ' . - 'Installer version ' . $exclude); - } - } - } +// Default for master_server +if (getenv('PHP_PEAR_MASTER_SERVER')) { + define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv('PHP_PEAR_MASTER_SERVER')); +} else { + define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net'); +} - return true; +// Default for http_proxy +if (getenv('PHP_PEAR_HTTP_PROXY')) { + define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('PHP_PEAR_HTTP_PROXY')); +} elseif (getenv('http_proxy')) { + define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('http_proxy')); +} else { + define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', ''); +} + +// Default for php_dir +if (getenv('PHP_PEAR_INSTALL_DIR')) { + define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR')); +} else { + if (@file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) { + define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); + } else { + define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); } +} - function validateSubpackageDependency($dep, $required, $params) - { - return $this->validatePackageDependency($dep, $required, $params); +// Default for ext_dir +if (getenv('PHP_PEAR_EXTENSION_DIR')) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR')); +} else { + if (ini_get('extension_dir')) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get('extension_dir')); + } elseif (defined('PEAR_EXTENSION_DIR') && + file_exists(PEAR_EXTENSION_DIR) && is_dir(PEAR_EXTENSION_DIR)) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', PEAR_EXTENSION_DIR); + } elseif (defined('PHP_EXTENSION_DIR')) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', PHP_EXTENSION_DIR); + } else { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', '.'); } +} - /** - * @param array dependency information (2.0 format) - * @param boolean whether this is a required dependency - * @param array a list of downloaded packages to be installed, if any - * @param boolean if true, then deps on pear.php.net that fail will also check - * against pecl.php.net packages to accomodate extensions that have - * moved to pecl.php.net from pear.php.net - */ - function validatePackageDependency($dep, $required, $params, $depv1 = false) - { - if ($this->_state != PEAR_VALIDATE_INSTALLING && - $this->_state != PEAR_VALIDATE_DOWNLOADING) { - return true; - } +// Default for doc_dir +if (getenv('PHP_PEAR_DOC_DIR')) { + define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv('PHP_PEAR_DOC_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_DOC_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'docs'); +} - if (isset($dep['providesextension'])) { - if ($this->extension_loaded($dep['providesextension'])) { - $save = $dep; - $subdep = $dep; - $subdep['name'] = $subdep['providesextension']; - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $ret = $this->validateExtensionDependency($subdep, $required); - PEAR::popErrorHandling(); - if (!PEAR::isError($ret)) { - return true; - } - } - } +// Default for bin_dir +if (getenv('PHP_PEAR_BIN_DIR')) { + define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv('PHP_PEAR_BIN_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR); +} - if ($this->_state == PEAR_VALIDATE_INSTALLING) { - return $this->_validatePackageInstall($dep, $required, $depv1); - } +// Default for data_dir +if (getenv('PHP_PEAR_DATA_DIR')) { + define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv('PHP_PEAR_DATA_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_DATA_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data'); +} - if ($this->_state == PEAR_VALIDATE_DOWNLOADING) { - return $this->_validatePackageDownload($dep, $required, $params, $depv1); - } - } +// Default for cfg_dir +if (getenv('PHP_PEAR_CFG_DIR')) { + define('PEAR_CONFIG_DEFAULT_CFG_DIR', getenv('PHP_PEAR_CFG_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_CFG_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'cfg'); +} - function _validatePackageDownload($dep, $required, $params, $depv1 = false) - { - $dep['package'] = $dep['name']; - if (isset($dep['uri'])) { - $dep['channel'] = '__uri'; - } - - $depname = $this->_registry->parsedPackageNameToString($dep, true); - $found = false; - foreach ($params as $param) { - if ($param->isEqual( - array('package' => $dep['name'], - 'channel' => $dep['channel']))) { - $found = true; - break; - } - - if ($depv1 && $dep['channel'] == 'pear.php.net') { - if ($param->isEqual( - array('package' => $dep['name'], - 'channel' => 'pecl.php.net'))) { - $found = true; - break; - } - } - } - - if (!$found && isset($dep['providesextension'])) { - foreach ($params as $param) { - if ($param->isExtension($dep['providesextension'])) { - $found = true; - break; - } - } - } - - if ($found) { - $version = $param->getVersion(); - $installed = false; - $downloaded = true; - } else { - if ($this->_registry->packageExists($dep['name'], $dep['channel'])) { - $installed = true; - $downloaded = false; - $version = $this->_registry->packageinfo($dep['name'], 'version', - $dep['channel']); - } else { - if ($dep['channel'] == 'pecl.php.net' && $this->_registry->packageExists($dep['name'], - 'pear.php.net')) { - $installed = true; - $downloaded = false; - $version = $this->_registry->packageinfo($dep['name'], 'version', - 'pear.php.net'); - } else { - $version = 'not installed or downloaded'; - $installed = false; - $downloaded = false; - } - } - } - - $extra = $this->_getExtraString($dep); - if (isset($dep['exclude']) && !is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); - } - - if (!isset($dep['min']) && !isset($dep['max']) && - !isset($dep['recommended']) && !isset($dep['exclude']) - ) { - if ($installed || $downloaded) { - $installed = $installed ? 'installed' : 'downloaded'; - if (isset($dep['conflicts'])) { - $rest = ''; - if ($version) { - $rest = ", $installed version is " . $version; - } - - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . $rest); - } - - return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . $rest); - } - - return true; - } - - if (isset($dep['conflicts'])) { - return true; - } - - if ($required) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires package "' . $depname . '"' . $extra); - } - - return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); - } - - return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); - } - - if (!$installed && !$downloaded) { - if (isset($dep['conflicts'])) { - return true; - } - - if ($required) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires package "' . $depname . '"' . $extra); - } - - return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); - } - - return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); - } - - $fail = false; - if (isset($dep['min']) && version_compare($version, $dep['min'], '<')) { - $fail = true; - } - - if (isset($dep['max']) && version_compare($version, $dep['max'], '>')) { - $fail = true; - } - - if ($fail && !isset($dep['conflicts'])) { - $installed = $installed ? 'installed' : 'downloaded'; - $dep['package'] = $dep['name']; - $dep = $this->_registry->parsedPackageNameToString($dep, true); - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires package "' . $depname . '"' . - $extra . ", $installed version is " . $version); - } - - return $this->warning('warning: %s requires package "' . $depname . '"' . - $extra . ", $installed version is " . $version); - } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && - isset($dep['conflicts']) && !isset($dep['exclude'])) { - $installed = $installed ? 'installed' : 'downloaded'; - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . - ", $installed version is " . $version); - } +// Default for www_dir +if (getenv('PHP_PEAR_WWW_DIR')) { + define('PEAR_CONFIG_DEFAULT_WWW_DIR', getenv('PHP_PEAR_WWW_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_WWW_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'www'); +} - return $this->warning('warning: %s conflicts with package "' . $depname . '"' . - $extra . ", $installed version is " . $version); - } +// Default for test_dir +if (getenv('PHP_PEAR_TEST_DIR')) { + define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_TEST_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests'); +} - if (isset($dep['exclude'])) { - $installed = $installed ? 'installed' : 'downloaded'; - foreach ($dep['exclude'] as $exclude) { - if (version_compare($version, $exclude, '==') && !isset($dep['conflicts'])) { - if (!isset($this->_options['nodeps']) && - !isset($this->_options['force']) - ) { - return $this->raiseError('%s is not compatible with ' . - $installed . ' package "' . - $depname . '" version ' . - $exclude); - } +// Default for temp_dir +if (getenv('PHP_PEAR_TEMP_DIR')) { + define('PEAR_CONFIG_DEFAULT_TEMP_DIR', getenv('PHP_PEAR_TEMP_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_TEMP_DIR', + System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . + DIRECTORY_SEPARATOR . 'temp'); +} - return $this->warning('warning: %s is not compatible with ' . - $installed . ' package "' . - $depname . '" version ' . - $exclude); - } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { - $installed = $installed ? 'installed' : 'downloaded'; - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s conflicts with package "' . $depname . '"' . - $extra . ", $installed version is " . $version); - } +// Default for cache_dir +if (getenv('PHP_PEAR_CACHE_DIR')) { + define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv('PHP_PEAR_CACHE_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_CACHE_DIR', + System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . + DIRECTORY_SEPARATOR . 'cache'); +} - return $this->warning('warning: %s conflicts with package "' . $depname . '"' . - $extra . ", $installed version is " . $version); - } - } - } +// Default for download_dir +if (getenv('PHP_PEAR_DOWNLOAD_DIR')) { + define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', getenv('PHP_PEAR_DOWNLOAD_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', + System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . + DIRECTORY_SEPARATOR . 'download'); +} - if (isset($dep['recommended'])) { - $installed = $installed ? 'installed' : 'downloaded'; - if (version_compare($version, $dep['recommended'], '==')) { - return true; - } +// Default for php_bin +if (getenv('PHP_PEAR_PHP_BIN')) { + define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv('PHP_PEAR_PHP_BIN')); +} else { + define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR. + DIRECTORY_SEPARATOR.'php'.(OS_WINDOWS ? '.exe' : '')); +} - if (!$found && $installed) { - $param = $this->_registry->getPackage($dep['name'], $dep['channel']); - } +// Default for verbose +if (getenv('PHP_PEAR_VERBOSE')) { + define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv('PHP_PEAR_VERBOSE')); +} else { + define('PEAR_CONFIG_DEFAULT_VERBOSE', 1); +} - if ($param) { - $found = false; - foreach ($params as $parent) { - if ($parent->isEqual($this->_currentPackage)) { - $found = true; - break; - } - } +// Default for preferred_state +if (getenv('PHP_PEAR_PREFERRED_STATE')) { + define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv('PHP_PEAR_PREFERRED_STATE')); +} else { + define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable'); +} - if ($found) { - if ($param->isCompatible($parent)) { - return true; - } - } else { // this is for validPackage() calls - $parent = $this->_registry->getPackage($this->_currentPackage['package'], - $this->_currentPackage['channel']); - if ($parent !== null && $param->isCompatible($parent)) { - return true; - } - } - } +// Default for umask +if (getenv('PHP_PEAR_UMASK')) { + define('PEAR_CONFIG_DEFAULT_UMASK', getenv('PHP_PEAR_UMASK')); +} else { + define('PEAR_CONFIG_DEFAULT_UMASK', decoct(umask())); +} - if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) && - !isset($this->_options['loose']) - ) { - return $this->raiseError('%s dependency package "' . $depname . - '" ' . $installed . ' version ' . $version . - ' is not the recommended version ' . $dep['recommended'] . - ', but may be compatible, use --force to install'); - } +// Default for cache_ttl +if (getenv('PHP_PEAR_CACHE_TTL')) { + define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv('PHP_PEAR_CACHE_TTL')); +} else { + define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600); +} - return $this->warning('warning: %s dependency package "' . $depname . - '" ' . $installed . ' version ' . $version . - ' is not the recommended version ' . $dep['recommended']); - } +// Default for sig_type +if (getenv('PHP_PEAR_SIG_TYPE')) { + define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv('PHP_PEAR_SIG_TYPE')); +} else { + define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg'); +} - return true; - } +// Default for sig_bin +if (getenv('PHP_PEAR_SIG_BIN')) { + define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv('PHP_PEAR_SIG_BIN')); +} else { + define('PEAR_CONFIG_DEFAULT_SIG_BIN', + System::which( + 'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg')); +} - function _validatePackageInstall($dep, $required, $depv1 = false) - { - return $this->_validatePackageDownload($dep, $required, array(), $depv1); - } +// Default for sig_keydir +if (getenv('PHP_PEAR_SIG_KEYDIR')) { + define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv('PHP_PEAR_SIG_KEYDIR')); +} else { + define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', + PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys'); +} +/** + * This is a class for storing configuration data, keeping track of + * which are system-defined, user-defined or defaulted. + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Config extends PEAR +{ /** - * Verify that uninstalling packages passed in to command line is OK. + * Array of config files used. * - * @param PEAR_Installer $dl - * @return PEAR_Error|true + * @var array layer => config file */ - function validatePackageUninstall(&$dl) - { - if (PEAR::isError($this->_dependencydb)) { - return $this->_dependencydb; - } - - $params = array(); - // construct an array of "downloaded" packages to fool the package dependency checker - // into using these to validate uninstalls of circular dependencies - $downloaded = &$dl->getUninstallPackages(); - foreach ($downloaded as $i => $pf) { - if (!class_exists('PEAR_Downloader_Package')) { - require_once 'PEAR/Downloader/Package.php'; - } - $dp = &new PEAR_Downloader_Package($dl); - $dp->setPackageFile($downloaded[$i]); - $params[$i] = &$dp; - } + var $files = array( + 'system' => '', + 'user' => '', + ); - // check cache - $memyselfandI = strtolower($this->_currentPackage['channel']) . '/' . - strtolower($this->_currentPackage['package']); - if (isset($dl->___uninstall_package_cache)) { - $badpackages = $dl->___uninstall_package_cache; - if (isset($badpackages[$memyselfandI]['warnings'])) { - foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { - $dl->log(0, $warning[0]); - } - } + var $layers = array(); - if (isset($badpackages[$memyselfandI]['errors'])) { - foreach ($badpackages[$memyselfandI]['errors'] as $error) { - if (is_array($error)) { - $dl->log(0, $error[0]); - } else { - $dl->log(0, $error->getMessage()); - } - } + /** + * Configuration data, two-dimensional array where the first + * dimension is the config layer ('user', 'system' and 'default'), + * and the second dimension is keyname => value. + * + * The order in the first dimension is important! Earlier + * layers will shadow later ones when a config value is + * requested (if a 'user' value exists, it will be returned first, + * then 'system' and finally 'default'). + * + * @var array layer => array(keyname => value, ...) + */ + var $configuration = array( + 'user' => array(), + 'system' => array(), + 'default' => array(), + ); - if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { - return $this->warning( - 'warning: %s should not be uninstalled, other installed packages depend ' . - 'on this package'); - } + /** + * Configuration values that can be set for a channel + * + * All other configuration values can only have a global value + * @var array + * @access private + */ + var $_channelConfigInfo = array( + 'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'cfg_dir', + 'test_dir', 'www_dir', 'php_bin', 'php_prefix', 'php_suffix', 'username', + 'password', 'verbose', 'preferred_state', 'umask', 'preferred_mirror', 'php_ini' + ); - return $this->raiseError( - '%s cannot be uninstalled, other installed packages depend on this package'); - } + /** + * Channels that can be accessed + * @see setChannels() + * @var array + * @access private + */ + var $_channels = array('pear.php.net', 'pecl.php.net', '__uri'); - return true; - } + /** + * This variable is used to control the directory values returned + * @see setInstallRoot(); + * @var string|false + * @access private + */ + var $_installRoot = false; - // first, list the immediate parents of each package to be uninstalled - $perpackagelist = array(); - $allparents = array(); - foreach ($params as $i => $param) { - $a = array( - 'channel' => strtolower($param->getChannel()), - 'package' => strtolower($param->getPackage()) - ); + /** + * If requested, this will always refer to the registry + * contained in php_dir + * @var PEAR_Registry + */ + var $_registry = array(); - $deps = $this->_dependencydb->getDependentPackages($a); - if ($deps) { - foreach ($deps as $d) { - $pardeps = $this->_dependencydb->getDependencies($d); - foreach ($pardeps as $dep) { - if (strtolower($dep['dep']['channel']) == $a['channel'] && - strtolower($dep['dep']['name']) == $a['package']) { - if (!isset($perpackagelist[$a['channel'] . '/' . $a['package']])) { - $perpackagelist[$a['channel'] . '/' . $a['package']] = array(); - } - $perpackagelist[$a['channel'] . '/' . $a['package']][] - = array($d['channel'] . '/' . $d['package'], $dep); - if (!isset($allparents[$d['channel'] . '/' . $d['package']])) { - $allparents[$d['channel'] . '/' . $d['package']] = array(); - } - if (!isset($allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']])) { - $allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']] = array(); - } - $allparents[$d['channel'] . '/' . $d['package']] - [$a['channel'] . '/' . $a['package']][] - = array($d, $dep); - } - } - } - } - } + /** + * @var array + * @access private + */ + var $_regInitialized = array(); - // next, remove any packages from the parents list that are not installed - $remove = array(); - foreach ($allparents as $parent => $d1) { - foreach ($d1 as $d) { - if ($this->_registry->packageExists($d[0][0]['package'], $d[0][0]['channel'])) { - continue; - } - $remove[$parent] = true; - } - } + /** + * @var bool + * @access private + */ + var $_noRegistry = false; - // next remove any packages from the parents list that are not passed in for - // uninstallation - foreach ($allparents as $parent => $d1) { - foreach ($d1 as $d) { - foreach ($params as $param) { - if (strtolower($param->getChannel()) == $d[0][0]['channel'] && - strtolower($param->getPackage()) == $d[0][0]['package']) { - // found it - continue 3; - } - } - $remove[$parent] = true; - } - } + /** + * amount of errors found while parsing config + * @var integer + * @access private + */ + var $_errorsFound = 0; + var $_lastError = null; - // remove all packages whose dependencies fail - // save which ones failed for error reporting - $badchildren = array(); - do { - $fail = false; - foreach ($remove as $package => $unused) { - if (!isset($allparents[$package])) { - continue; - } - - foreach ($allparents[$package] as $kid => $d1) { - foreach ($d1 as $depinfo) { - if ($depinfo[1]['type'] != 'optional') { - if (isset($badchildren[$kid])) { - continue; - } - $badchildren[$kid] = true; - $remove[$kid] = true; - $fail = true; - continue 2; - } - } - } - if ($fail) { - // start over, we removed some children - continue 2; - } - } - } while ($fail); - - // next, construct the list of packages that can't be uninstalled - $badpackages = array(); - $save = $this->_currentPackage; - foreach ($perpackagelist as $package => $packagedeps) { - foreach ($packagedeps as $parent) { - if (!isset($remove[$parent[0]])) { - continue; - } + /** + * Information about the configuration data. Stores the type, + * default value and a documentation string for each configuration + * value. + * + * @var array layer => array(infotype => value, ...) + */ + var $configuration_info = array( + // Channels/Internet Access + 'default_channel' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, + 'doc' => 'the default channel to use for all non explicit commands', + 'prompt' => 'Default Channel', + 'group' => 'Internet Access', + ), + 'preferred_mirror' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, + 'doc' => 'the default server or mirror to use for channel actions', + 'prompt' => 'Default Channel Mirror', + 'group' => 'Internet Access', + ), + 'remote_config' => array( + 'type' => 'password', + 'default' => '', + 'doc' => 'ftp url of remote configuration file to use for synchronized install', + 'prompt' => 'Remote Configuration File', + 'group' => 'Internet Access', + ), + 'auto_discover' => array( + 'type' => 'integer', + 'default' => 0, + 'doc' => 'whether to automatically discover new channels', + 'prompt' => 'Auto-discover new Channels', + 'group' => 'Internet Access', + ), + // Internet Access + 'master_server' => array( + 'type' => 'string', + 'default' => 'pear.php.net', + 'doc' => 'name of the main PEAR server [NOT USED IN THIS VERSION]', + 'prompt' => 'PEAR server [DEPRECATED]', + 'group' => 'Internet Access', + ), + 'http_proxy' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY, + 'doc' => 'HTTP proxy (host:port) to use when downloading packages', + 'prompt' => 'HTTP Proxy Server Address', + 'group' => 'Internet Access', + ), + // File Locations + 'php_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_PHP_DIR, + 'doc' => 'directory where .php files are installed', + 'prompt' => 'PEAR directory', + 'group' => 'File Locations', + ), + 'ext_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_EXT_DIR, + 'doc' => 'directory where loadable extensions are installed', + 'prompt' => 'PHP extension directory', + 'group' => 'File Locations', + ), + 'doc_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_DOC_DIR, + 'doc' => 'directory where documentation is installed', + 'prompt' => 'PEAR documentation directory', + 'group' => 'File Locations', + ), + 'bin_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_BIN_DIR, + 'doc' => 'directory where executables are installed', + 'prompt' => 'PEAR executables directory', + 'group' => 'File Locations', + ), + 'data_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_DATA_DIR, + 'doc' => 'directory where data files are installed', + 'prompt' => 'PEAR data directory', + 'group' => 'File Locations (Advanced)', + ), + 'cfg_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_CFG_DIR, + 'doc' => 'directory where modifiable configuration files are installed', + 'prompt' => 'PEAR configuration file directory', + 'group' => 'File Locations (Advanced)', + ), + 'www_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_WWW_DIR, + 'doc' => 'directory where www frontend files (html/js) are installed', + 'prompt' => 'PEAR www files directory', + 'group' => 'File Locations (Advanced)', + ), + 'test_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_TEST_DIR, + 'doc' => 'directory where regression tests are installed', + 'prompt' => 'PEAR test directory', + 'group' => 'File Locations (Advanced)', + ), + 'cache_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR, + 'doc' => 'directory which is used for web service cache', + 'prompt' => 'PEAR Installer cache directory', + 'group' => 'File Locations (Advanced)', + ), + 'temp_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_TEMP_DIR, + 'doc' => 'directory which is used for all temp files', + 'prompt' => 'PEAR Installer temp directory', + 'group' => 'File Locations (Advanced)', + ), + 'download_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR, + 'doc' => 'directory which is used for all downloaded files', + 'prompt' => 'PEAR Installer download directory', + 'group' => 'File Locations (Advanced)', + ), + 'php_bin' => array( + 'type' => 'file', + 'default' => PEAR_CONFIG_DEFAULT_PHP_BIN, + 'doc' => 'PHP CLI/CGI binary for executing scripts', + 'prompt' => 'PHP CLI/CGI binary', + 'group' => 'File Locations (Advanced)', + ), + 'php_prefix' => array( + 'type' => 'string', + 'default' => '', + 'doc' => '--program-prefix for php_bin\'s ./configure, used for pecl installs', + 'prompt' => '--program-prefix passed to PHP\'s ./configure', + 'group' => 'File Locations (Advanced)', + ), + 'php_suffix' => array( + 'type' => 'string', + 'default' => '', + 'doc' => '--program-suffix for php_bin\'s ./configure, used for pecl installs', + 'prompt' => '--program-suffix passed to PHP\'s ./configure', + 'group' => 'File Locations (Advanced)', + ), + 'php_ini' => array( + 'type' => 'file', + 'default' => '', + 'doc' => 'location of php.ini in which to enable PECL extensions on install', + 'prompt' => 'php.ini location', + 'group' => 'File Locations (Advanced)', + ), + // Maintainers + 'username' => array( + 'type' => 'string', + 'default' => '', + 'doc' => '(maintainers) your PEAR account name', + 'prompt' => 'PEAR username (for maintainers)', + 'group' => 'Maintainers', + ), + 'password' => array( + 'type' => 'password', + 'default' => '', + 'doc' => '(maintainers) your PEAR account password', + 'prompt' => 'PEAR password (for maintainers)', + 'group' => 'Maintainers', + ), + // Advanced + 'verbose' => array( + 'type' => 'integer', + 'default' => PEAR_CONFIG_DEFAULT_VERBOSE, + 'doc' => 'verbosity level +0: really quiet +1: somewhat quiet +2: verbose +3: debug', + 'prompt' => 'Debug Log Level', + 'group' => 'Advanced', + ), + 'preferred_state' => array( + 'type' => 'set', + 'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE, + 'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified', + 'valid_set' => array( + 'stable', 'beta', 'alpha', 'devel', 'snapshot'), + 'prompt' => 'Preferred Package State', + 'group' => 'Advanced', + ), + 'umask' => array( + 'type' => 'mask', + 'default' => PEAR_CONFIG_DEFAULT_UMASK, + 'doc' => 'umask used when creating files (Unix-like systems only)', + 'prompt' => 'Unix file mask', + 'group' => 'Advanced', + ), + 'cache_ttl' => array( + 'type' => 'integer', + 'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL, + 'doc' => 'amount of secs where the local cache is used and not updated', + 'prompt' => 'Cache TimeToLive', + 'group' => 'Advanced', + ), + 'sig_type' => array( + 'type' => 'set', + 'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE, + 'doc' => 'which package signature mechanism to use', + 'valid_set' => array('gpg'), + 'prompt' => 'Package Signature Type', + 'group' => 'Maintainers', + ), + 'sig_bin' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_SIG_BIN, + 'doc' => 'which package signature mechanism to use', + 'prompt' => 'Signature Handling Program', + 'group' => 'Maintainers', + ), + 'sig_keyid' => array( + 'type' => 'string', + 'default' => '', + 'doc' => 'which key to use for signing with', + 'prompt' => 'Signature Key Id', + 'group' => 'Maintainers', + ), + 'sig_keydir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR, + 'doc' => 'directory where signature keys are located', + 'prompt' => 'Signature Key Directory', + 'group' => 'Maintainers', + ), + // __channels is reserved - used for channel-specific configuration + ); - $packagename = $this->_registry->parsePackageName($parent[0]); - $packagename['channel'] = $this->_registry->channelAlias($packagename['channel']); - $pa = $this->_registry->getPackage($packagename['package'], $packagename['channel']); - $packagename['package'] = $pa->getPackage(); - $this->_currentPackage = $packagename; - // parent is not present in uninstall list, make sure we can actually - // uninstall it (parent dep is optional) - $parentname['channel'] = $this->_registry->channelAlias($parent[1]['dep']['channel']); - $pa = $this->_registry->getPackage($parent[1]['dep']['name'], $parent[1]['dep']['channel']); - $parentname['package'] = $pa->getPackage(); - $parent[1]['dep']['package'] = $parentname['package']; - $parent[1]['dep']['channel'] = $parentname['channel']; - if ($parent[1]['type'] == 'optional') { - $test = $this->_validatePackageUninstall($parent[1]['dep'], false, $dl); - if ($test !== true) { - $badpackages[$package]['warnings'][] = $test; - } - } else { - $test = $this->_validatePackageUninstall($parent[1]['dep'], true, $dl); - if ($test !== true) { - $badpackages[$package]['errors'][] = $test; - } - } + /** + * Constructor. + * + * @param string file to read user-defined options from + * @param string file to read system-wide defaults from + * @param bool determines whether a registry object "follows" + * the value of php_dir (is automatically created + * and moved when php_dir is changed) + * @param bool if true, fails if configuration files cannot be loaded + * + * @access public + * + * @see PEAR_Config::singleton + */ + function PEAR_Config($user_file = '', $system_file = '', $ftp_file = false, + $strict = true) + { + $this->PEAR(); + PEAR_Installer_Role::initializeConfig($this); + $sl = DIRECTORY_SEPARATOR; + if (empty($user_file)) { + if (OS_WINDOWS) { + $user_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini'; + } else { + $user_file = getenv('HOME') . $sl . '.pearrc'; } } - $this->_currentPackage = $save; - $dl->___uninstall_package_cache = $badpackages; - if (isset($badpackages[$memyselfandI])) { - if (isset($badpackages[$memyselfandI]['warnings'])) { - foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { - $dl->log(0, $warning[0]); - } + if (empty($system_file)) { + $system_file = PEAR_CONFIG_SYSCONFDIR . $sl; + if (OS_WINDOWS) { + $system_file .= 'pearsys.ini'; + } else { + $system_file .= 'pear.conf'; } + } - if (isset($badpackages[$memyselfandI]['errors'])) { - foreach ($badpackages[$memyselfandI]['errors'] as $error) { - if (is_array($error)) { - $dl->log(0, $error[0]); - } else { - $dl->log(0, $error->getMessage()); - } - } - - if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { - return $this->warning( - 'warning: %s should not be uninstalled, other installed packages depend ' . - 'on this package'); - } - - return $this->raiseError( - '%s cannot be uninstalled, other installed packages depend on this package'); + $this->layers = array_keys($this->configuration); + $this->files['user'] = $user_file; + $this->files['system'] = $system_file; + if ($user_file && file_exists($user_file)) { + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $this->readConfigFile($user_file, 'user', $strict); + $this->popErrorHandling(); + if ($this->_errorsFound > 0) { + return; } } - return true; - } + if ($system_file && @file_exists($system_file)) { + $this->mergeConfigFile($system_file, false, 'system', $strict); + if ($this->_errorsFound > 0) { + return; + } - function _validatePackageUninstall($dep, $required, $dl) - { - $depname = $this->_registry->parsedPackageNameToString($dep, true); - $version = $this->_registry->packageinfo($dep['package'], 'version', $dep['channel']); - if (!$version) { - return true; } - $extra = $this->_getExtraString($dep); - if (isset($dep['exclude']) && !is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); + if (!$ftp_file) { + $ftp_file = $this->get('remote_config'); } - if (isset($dep['conflicts'])) { - return true; // uninstall OK - these packages conflict (probably installed with --force) + if ($ftp_file && defined('PEAR_REMOTEINSTALL_OK')) { + $this->readFTPConfigFile($ftp_file); } - if (!isset($dep['min']) && !isset($dep['max'])) { - if (!$required) { - return $this->warning('"' . $depname . '" can be optionally used by ' . - 'installed package %s' . $extra); - } + foreach ($this->configuration_info as $key => $info) { + $this->configuration['default'][$key] = $info['default']; + } - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('"' . $depname . '" is required by ' . - 'installed package %s' . $extra); - } + $this->_registry['default'] = &new PEAR_Registry($this->configuration['default']['php_dir']); + $this->_registry['default']->setConfig($this, false); + $this->_regInitialized['default'] = false; + //$GLOBALS['_PEAR_Config_instance'] = &$this; + } - return $this->warning('warning: "' . $depname . '" is required by ' . - 'installed package %s' . $extra); + /** + * Return the default locations of user and system configuration files + * @static + */ + function getDefaultConfigFiles() + { + $sl = DIRECTORY_SEPARATOR; + if (OS_WINDOWS) { + return array( + 'user' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini', + 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini' + ); } - $fail = false; - if (isset($dep['min']) && version_compare($version, $dep['min'], '>=')) { - $fail = true; - } + return array( + 'user' => getenv('HOME') . $sl . '.pearrc', + 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf' + ); + } - if (isset($dep['max']) && version_compare($version, $dep['max'], '<=')) { - $fail = true; + /** + * Static singleton method. If you want to keep only one instance + * of this class in use, this method will give you a reference to + * the last created PEAR_Config object if one exists, or create a + * new object. + * + * @param string (optional) file to read user-defined options from + * @param string (optional) file to read system-wide defaults from + * + * @return object an existing or new PEAR_Config instance + * + * @access public + * + * @see PEAR_Config::PEAR_Config + */ + function &singleton($user_file = '', $system_file = '', $strict = true) + { + if (is_object($GLOBALS['_PEAR_Config_instance'])) { + return $GLOBALS['_PEAR_Config_instance']; } - // we re-use this variable, preserve the original value - $saverequired = $required; - if (!$required) { - return $this->warning($depname . $extra . ' can be optionally used by installed package' . - ' "%s"'); + $t_conf = &new PEAR_Config($user_file, $system_file, false, $strict); + if ($t_conf->_errorsFound > 0) { + return $t_conf->lastError; } - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError($depname . $extra . ' is required by installed package' . - ' "%s"'); + $GLOBALS['_PEAR_Config_instance'] = &$t_conf; + return $GLOBALS['_PEAR_Config_instance']; + } + + /** + * Determine whether any configuration files have been detected, and whether a + * registry object can be retrieved from this configuration. + * @return bool + * @since PEAR 1.4.0a1 + */ + function validConfiguration() + { + if ($this->isDefinedLayer('user') || $this->isDefinedLayer('system')) { + return true; } - return $this->raiseError('warning: ' . $depname . $extra . - ' is required by installed package "%s"'); + return false; } /** - * validate a downloaded package against installed packages - * - * As of PEAR 1.4.3, this will only validate - * - * @param array|PEAR_Downloader_Package|PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * $pkg package identifier (either - * array('package' => blah, 'channel' => blah) or an array with - * index 'info' referencing an object) - * @param PEAR_Downloader $dl - * @param array $params full list of packages to install - * @return true|PEAR_Error + * Reads configuration data from a file. All existing values in + * the config layer are discarded and replaced with data from the + * file. + * @param string file to read from, if NULL or not specified, the + * last-used file for the same layer (second param) is used + * @param string config layer to insert data into ('user' or 'system') + * @return bool TRUE on success or a PEAR error on failure */ - function validatePackage($pkg, &$dl, $params = array()) + function readConfigFile($file = null, $layer = 'user', $strict = true) { - if (is_array($pkg) && isset($pkg['info'])) { - $deps = $this->_dependencydb->getDependentPackageDependencies($pkg['info']); - } else { - $deps = $this->_dependencydb->getDependentPackageDependencies($pkg); + if (empty($this->files[$layer])) { + return $this->raiseError("unknown config layer `$layer'"); } - $fail = false; - if ($deps) { - if (!class_exists('PEAR_Downloader_Package')) { - require_once 'PEAR/Downloader/Package.php'; - } + if ($file === null) { + $file = $this->files[$layer]; + } - $dp = &new PEAR_Downloader_Package($dl); - if (is_object($pkg)) { - $dp->setPackageFile($pkg); - } else { - $dp->setDownloadURL($pkg); + $data = $this->_readConfigDataFrom($file); + if (PEAR::isError($data)) { + if (!$strict) { + return true; } - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - foreach ($deps as $channel => $info) { - foreach ($info as $package => $ds) { - foreach ($params as $packd) { - if (strtolower($packd->getPackage()) == strtolower($package) && - $packd->getChannel() == $channel) { - $dl->log(3, 'skipping installed package check of "' . - $this->_registry->parsedPackageNameToString( - array('channel' => $channel, 'package' => $package), - true) . - '", version "' . $packd->getVersion() . '" will be ' . - 'downloaded and installed'); - continue 2; // jump to next package - } - } + $this->_errorsFound++; + $this->lastError = $data; - foreach ($ds as $d) { - $checker = &new PEAR_Dependency2($this->_config, $this->_options, - array('channel' => $channel, 'package' => $package), $this->_state); - $dep = $d['dep']; - $required = $d['type'] == 'required'; - $ret = $checker->_validatePackageDownload($dep, $required, array(&$dp)); - if (is_array($ret)) { - $dl->log(0, $ret[0]); - } elseif (PEAR::isError($ret)) { - $dl->log(0, $ret->getMessage()); - $fail = true; - } - } - } - } - PEAR::popErrorHandling(); + return $data; } - if ($fail) { - return $this->raiseError( - '%s cannot be installed, conflicts with installed packages'); + $this->files[$layer] = $file; + $this->_decodeInput($data); + $this->configuration[$layer] = $data; + $this->_setupChannels(); + if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { + $this->_registry[$layer] = &new PEAR_Registry($phpdir); + $this->_registry[$layer]->setConfig($this, false); + $this->_regInitialized[$layer] = false; + } else { + unset($this->_registry[$layer]); } - return true; } /** - * validate a package.xml 1.0 dependency + * @param string url to the remote config file, like ftp://www.example.com/pear/config.ini + * @return true|PEAR_Error */ - function validateDependency1($dep, $params = array()) + function readFTPConfigFile($path) { - if (!isset($dep['optional'])) { - $dep['optional'] = 'no'; - } - - list($newdep, $type) = $this->normalizeDep($dep); - if (!$newdep) { - return $this->raiseError("Invalid Dependency"); - } - - if (method_exists($this, "validate{$type}Dependency")) { - return $this->{"validate{$type}Dependency"}($newdep, $dep['optional'] == 'no', - $params, true); - } - } + do { // poor man's try + if (!class_exists('PEAR_FTP')) { + if (!class_exists('PEAR_Common')) { + require_once 'PEAR/Common.php'; + } + if (PEAR_Common::isIncludeable('PEAR/FTP.php')) { + require_once 'PEAR/FTP.php'; + } + } - /** - * Convert a 1.0 dep into a 2.0 dep - */ - function normalizeDep($dep) - { - $types = array( - 'pkg' => 'Package', - 'ext' => 'Extension', - 'os' => 'Os', - 'php' => 'Php' - ); + if (!class_exists('PEAR_FTP')) { + return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config'); + } - if (!isset($types[$dep['type']])) { - return array(false, false); - } + $this->_ftp = &new PEAR_FTP; + $this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN); + $e = $this->_ftp->init($path); + if (PEAR::isError($e)) { + $this->_ftp->popErrorHandling(); + return $e; + } - $type = $types[$dep['type']]; + $tmp = System::mktemp('-d'); + PEAR_Common::addTempFile($tmp); + $e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR . + 'pear.ini', false, FTP_BINARY); + if (PEAR::isError($e)) { + $this->_ftp->popErrorHandling(); + return $e; + } - $newdep = array(); - switch ($type) { - case 'Package' : - $newdep['channel'] = 'pear.php.net'; - case 'Extension' : - case 'Os' : - $newdep['name'] = $dep['name']; - break; - } + PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini'); + $this->_ftp->disconnect(); + $this->_ftp->popErrorHandling(); + $this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini'; + $e = $this->readConfigFile(null, 'ftp'); + if (PEAR::isError($e)) { + return $e; + } - $dep['rel'] = PEAR_Dependency2::signOperator($dep['rel']); - switch ($dep['rel']) { - case 'has' : - return array($newdep, $type); - break; - case 'not' : - $newdep['conflicts'] = true; - break; - case '>=' : - case '>' : - $newdep['min'] = $dep['version']; - if ($dep['rel'] == '>') { - $newdep['exclude'] = $dep['version']; - } - break; - case '<=' : - case '<' : - $newdep['max'] = $dep['version']; - if ($dep['rel'] == '<') { - $newdep['exclude'] = $dep['version']; + $fail = array(); + foreach ($this->configuration_info as $key => $val) { + if (in_array($this->getGroup($key), + array('File Locations', 'File Locations (Advanced)')) && + $this->getType($key) == 'directory') { + // any directory configs must be set for this to work + if (!isset($this->configuration['ftp'][$key])) { + $fail[] = $key; + } } - break; - case 'ne' : - case '!=' : - $newdep['min'] = '0'; - $newdep['max'] = '100000'; - $newdep['exclude'] = $dep['version']; - break; - case '==' : - $newdep['min'] = $dep['version']; - $newdep['max'] = $dep['version']; - break; - } - if ($type == 'Php') { - if (!isset($newdep['min'])) { - $newdep['min'] = '4.4.0'; } - if (!isset($newdep['max'])) { - $newdep['max'] = '6.0.0'; + if (!count($fail)) { + return true; } - } - return array($newdep, $type); + + $fail = '"' . implode('", "', $fail) . '"'; + unset($this->files['ftp']); + unset($this->configuration['ftp']); + return PEAR::raiseError('ERROR: Ftp configuration file must set all ' . + 'directory configuration variables. These variables were not set: ' . + $fail); + } while (false); // poor man's catch + unset($this->files['ftp']); + return PEAR::raiseError('no remote host specified'); } /** - * Converts text comparing operators to them sign equivalents - * - * Example: 'ge' to '>=' - * - * @access public - * @param string Operator - * @return string Sign equivalent + * Reads the existing configurations and creates the _channels array from it */ - function signOperator($operator) + function _setupChannels() { - switch($operator) { - case 'lt': return '<'; - case 'le': return '<='; - case 'gt': return '>'; - case 'ge': return '>='; - case 'eq': return '=='; - case 'ne': return '!='; - default: - return $operator; + $set = array_flip(array_values($this->_channels)); + foreach ($this->configuration as $layer => $data) { + $i = 1000; + if (isset($data['__channels']) && is_array($data['__channels'])) { + foreach ($data['__channels'] as $channel => $info) { + $set[$channel] = $i++; + } + } } + $this->_channels = array_values(array_flip($set)); + $this->setChannels($this->_channels); } - function raiseError($msg) + function deleteChannel($channel) { - if (isset($this->_options['ignore-errors'])) { - return $this->warning($msg); + $ch = strtolower($channel); + foreach ($this->configuration as $layer => $data) { + if (isset($data['__channels']) && isset($data['__channels'][$ch])) { + unset($this->configuration[$layer]['__channels'][$ch]); + } } - return PEAR::raiseError(sprintf($msg, $this->_registry->parsedPackageNameToString( - $this->_currentPackage, true))); + $this->_channels = array_flip($this->_channels); + unset($this->_channels[$ch]); + $this->_channels = array_flip($this->_channels); } - function warning($msg) + /** + * Merges data into a config layer from a file. Does the same + * thing as readConfigFile, except it does not replace all + * existing values in the config layer. + * @param string file to read from + * @param bool whether to overwrite existing data (default TRUE) + * @param string config layer to insert data into ('user' or 'system') + * @param string if true, errors are returned if file opening fails + * @return bool TRUE on success or a PEAR error on failure + */ + function mergeConfigFile($file, $override = true, $layer = 'user', $strict = true) { - return array(sprintf($msg, $this->_registry->parsedPackageNameToString( - $this->_currentPackage, true))); - } -}PEAR-1.8.0/PEAR/Downloader.php100664 764 764 202344 100664 10710 - * @author Stig Bakken - * @author Tomas V. V. Cox - * @author Martin Jansen - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Downloader.php,v 1.159 2009/03/08 04:01:08 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.3.0 - */ + if (empty($this->files[$layer])) { + return $this->raiseError("unknown config layer `$layer'"); + } -/** - * Needed for constants, extending - */ -require_once 'PEAR/Common.php'; + if ($file === null) { + $file = $this->files[$layer]; + } -define('PEAR_INSTALLER_OK', 1); -define('PEAR_INSTALLER_FAILED', 0); -define('PEAR_INSTALLER_SKIPPED', -1); -define('PEAR_INSTALLER_ERROR_NO_PREF_STATE', 2); + $data = $this->_readConfigDataFrom($file); + if (PEAR::isError($data)) { + if (!$strict) { + return true; + } -/** - * Administration class used to download anything from the internet (PEAR Packages, - * static URLs, xml files) - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @author Stig Bakken - * @author Tomas V. V. Cox - * @author Martin Jansen - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.3.0 - */ -class PEAR_Downloader extends PEAR_Common -{ - /** - * @var PEAR_Registry - * @access private - */ - var $_registry; + $this->_errorsFound++; + $this->lastError = $data; - /** - * Preferred Installation State (snapshot, devel, alpha, beta, stable) - * @var string|null - * @access private - */ - var $_preferredState; + return $data; + } - /** - * Options from command-line passed to Install. - * - * Recognized options:
    - * - onlyreqdeps : install all required dependencies as well - * - alldeps : install all dependencies, including optional - * - installroot : base relative path to install files in - * - force : force a download even if warnings would prevent it - * - nocompress : download uncompressed tarballs - * @see PEAR_Command_Install - * @access private - * @var array - */ - var $_options; + $this->_decodeInput($data); + if ($override) { + $this->configuration[$layer] = + PEAR_Config::arrayMergeRecursive($this->configuration[$layer], $data); + } else { + $this->configuration[$layer] = + PEAR_Config::arrayMergeRecursive($data, $this->configuration[$layer]); + } - /** - * Downloaded Packages after a call to download(). - * - * Format of each entry: - * - * - * array('pkg' => 'package_name', 'file' => '/path/to/local/file', - * 'info' => array() // parsed package.xml - * ); - * - * @access private - * @var array - */ - var $_downloadedPackages = array(); + $this->_setupChannels(); + if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { + $this->_registry[$layer] = &new PEAR_Registry($phpdir); + $this->_registry[$layer]->setConfig($this, false); + $this->_regInitialized[$layer] = false; + } else { + unset($this->_registry[$layer]); + } + return true; + } /** - * Packages slated for download. - * - * This is used to prevent downloading a package more than once should it be a dependency - * for two packages to be installed. - * Format of each entry: - * - *
    -     * array('package_name1' => parsed package.xml, 'package_name2' => parsed package.xml,
    -     * );
    -     * 
    - * @access private - * @var array + * @param array + * @param array + * @return array + * @static */ - var $_toDownload = array(); + function arrayMergeRecursive($arr2, $arr1) + { + $ret = array(); + foreach ($arr2 as $key => $data) { + if (!isset($arr1[$key])) { + $ret[$key] = $data; + unset($arr1[$key]); + continue; + } + if (is_array($data)) { + if (!is_array($arr1[$key])) { + $ret[$key] = $arr1[$key]; + unset($arr1[$key]); + continue; + } + $ret[$key] = PEAR_Config::arrayMergeRecursive($arr1[$key], $arr2[$key]); + unset($arr1[$key]); + } + } - /** - * Array of every package installed, with names lower-cased. - * - * Format: - * - * array('package1' => 0, 'package2' => 1, ); - * - * @var array - */ - var $_installed = array(); + return array_merge($ret, $arr1); + } /** - * @var array - * @access private + * Writes data into a config layer from a file. + * + * @param string|null file to read from, or null for default + * @param string config layer to insert data into ('user' or + * 'system') + * @param string|null data to write to config file or null for internal data [DEPRECATED] + * @return bool TRUE on success or a PEAR error on failure */ - var $_errorStack = array(); + function writeConfigFile($file = null, $layer = 'user', $data = null) + { + $this->_lazyChannelSetup($layer); + if ($layer == 'both' || $layer == 'all') { + foreach ($this->files as $type => $file) { + $err = $this->writeConfigFile($file, $type, $data); + if (PEAR::isError($err)) { + return $err; + } + } + return true; + } - /** - * @var boolean - * @access private - */ - var $_internalDownload = false; + if (empty($this->files[$layer])) { + return $this->raiseError("unknown config file type `$layer'"); + } - /** - * Temporary variable used in sorting packages by dependency in {@link sortPkgDeps()} - * @var array - * @access private - */ - var $_packageSortTree; + if ($file === null) { + $file = $this->files[$layer]; + } - /** - * Temporary directory, or configuration value where downloads will occur - * @var string - */ - var $_downloadDir; - // {{{ PEAR_Downloader() + $data = ($data === null) ? $this->configuration[$layer] : $data; + $this->_encodeOutput($data); + $opt = array('-p', dirname($file)); + if (!@System::mkDir($opt)) { + return $this->raiseError("could not create directory: " . dirname($file)); + } - /** - * @param PEAR_Frontend_* - * @param array - * @param PEAR_Config - */ - function PEAR_Downloader(&$ui, $options, &$config) - { - parent::PEAR_Common(); - $this->_options = $options; - $this->config = &$config; - $this->_preferredState = $this->config->get('preferred_state'); - $this->ui = &$ui; - if (!$this->_preferredState) { - // don't inadvertantly use a non-set preferred_state - $this->_preferredState = null; + if (file_exists($file) && is_file($file) && !is_writeable($file)) { + return $this->raiseError("no write access to $file!"); } - if (isset($this->_options['installroot'])) { - $this->config->setInstallRoot($this->_options['installroot']); + $fp = @fopen($file, "w"); + if (!$fp) { + return $this->raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed ($php_errormsg)"); } - $this->_registry = &$config->getRegistry(); - if (isset($this->_options['alldeps']) || isset($this->_options['onlyreqdeps'])) { - $this->_installed = $this->_registry->listAllPackages(); - foreach ($this->_installed as $key => $unused) { - if (!count($unused)) { - continue; - } - $strtolower = create_function('$a','return strtolower($a);'); - array_walk($this->_installed[$key], $strtolower); - } + $contents = "#PEAR_Config 0.9\n" . serialize($data); + if (!@fwrite($fp, $contents)) { + return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed ($php_errormsg)"); } + return true; } /** - * Attempt to discover a channel's remote capabilities from - * its server name - * @param string - * @return boolean + * Reads configuration data from a file and returns the parsed data + * in an array. + * + * @param string file to read from + * @return array configuration data or a PEAR error on failure + * @access private */ - function discover($channel) + function _readConfigDataFrom($file) { - $this->log(1, 'Attempting to discover channel "' . $channel . '"...'); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $callback = $this->ui ? array(&$this, '_downloadCallback') : null; - if (!class_exists('System')) { - require_once 'System.php'; + $fp = false; + if (file_exists($file)) { + $fp = @fopen($file, "r"); } - $tmp = System::mktemp(array('-d')); - $a = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false); - PEAR::popErrorHandling(); - if (PEAR::isError($a)) { - // Attempt to fallback to https automatically. - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $this->log(1, 'Attempting fallback to https instead of http on channel "' . $channel . '"...'); - $a = $this->downloadHttp('https://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false); - PEAR::popErrorHandling(); - if (PEAR::isError($a)) { - return false; - } + if (!$fp) { + return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed"); } - list($a, $lastmodified) = $a; - if (!class_exists('PEAR_ChannelFile')) { - require_once 'PEAR/ChannelFile.php'; + $size = filesize($file); + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + fclose($fp); + $contents = file_get_contents($file); + if (empty($contents)) { + return $this->raiseError('Configuration file "' . $file . '" is empty'); } - $b = new PEAR_ChannelFile; - if ($b->fromXmlFile($a)) { - unlink($a); - if ($this->config->get('auto_discover')) { - $this->_registry->addChannel($b, $lastmodified); - $alias = $b->getName(); - if ($b->getName() == $this->_registry->channelName($b->getAlias())) { - $alias = $b->getAlias(); - } + set_magic_quotes_runtime($rt); - $this->log(1, 'Auto-discovered channel "' . $channel . - '", alias "' . $alias . '", adding to registry'); + $version = false; + if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) { + $version = $matches[1]; + $contents = substr($contents, strlen($matches[0])); + } else { + // Museum config file + if (substr($contents,0,2) == 'a:') { + $version = '0.1'; } + } - return true; + if ($version && version_compare("$version", '1', '<')) { + // no '@', it is possible that unserialize + // raises a notice but it seems to block IO to + // STDOUT if a '@' is used and a notice is raise + $data = unserialize($contents); + + if (!is_array($data) && !$data) { + if ($contents == serialize(false)) { + $data = array(); + } else { + $err = $this->raiseError("PEAR_Config: bad data in $file"); + return $err; + } + } + if (!is_array($data)) { + if (strlen(trim($contents)) > 0) { + $error = "PEAR_Config: bad data in $file"; + $err = $this->raiseError($error); + return $err; + } + + $data = array(); + } + // add parsing of newer formats here... + } else { + $err = $this->raiseError("$file: unknown version `$version'"); + return $err; } - unlink($a); - return false; + return $data; } /** - * For simpler unit-testing - * @param PEAR_Downloader - * @return PEAR_Downloader_Package - */ - function &newDownloaderPackage(&$t) + * Gets the file used for storing the config for a layer + * + * @param string $layer 'user' or 'system' + */ + function getConfFile($layer) { - if (!class_exists('PEAR_Downloader_Package')) { - require_once 'PEAR/Downloader/Package.php'; - } - $a = &new PEAR_Downloader_Package($t); - return $a; + return $this->files[$layer]; } /** - * For simpler unit-testing - * @param PEAR_Config - * @param array - * @param array - * @param int + * @param string Configuration class name, used for detecting duplicate calls + * @param array information on a role as parsed from its xml file + * @return true|PEAR_Error + * @access private */ - function &getDependency2Object(&$c, $i, $p, $s) - { - if (!class_exists('PEAR_Dependency2')) { - require_once 'PEAR/Dependency2.php'; - } - $z = &new PEAR_Dependency2($c, $i, $p, $s); - return $z; - } - - function &download($params) + function _addConfigVars($class, $vars) { - if (!count($params)) { - $a = array(); - return $a; + static $called = array(); + if (isset($called[$class])) { + return; } - if (!isset($this->_registry)) { - $this->_registry = &$this->config->getRegistry(); + $called[$class] = 1; + if (count($vars) > 3) { + return $this->raiseError('Roles can only define 3 new config variables or less'); } - $channelschecked = array(); - // convert all parameters into PEAR_Downloader_Package objects - foreach ($params as $i => $param) { - $params[$i] = &$this->newDownloaderPackage($this); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $err = $params[$i]->initialize($param); - PEAR::staticPopErrorHandling(); - if (!$err) { - // skip parameters that were missed by preferred_state - continue; + foreach ($vars as $name => $var) { + if (!is_array($var)) { + return $this->raiseError('Configuration information must be an array'); } - if (PEAR::isError($err)) { - if (!isset($this->_options['soft']) && $err->getMessage() !== '') { - $this->log(0, $err->getMessage()); - } - - $params[$i] = false; - if (is_object($param)) { - $param = $param->getChannel() . '/' . $param->getPackage(); - } - - if (!isset($this->_options['soft'])) { - $this->log(2, 'Package "' . $param . '" is not valid'); - } - - // Message logged above in a specific verbose mode, passing null to not show up on CLI - $this->pushError(null, PEAR_INSTALLER_SKIPPED); - } else { - do { - if ($params[$i] && $params[$i]->getType() == 'local') { - // bug #7090 skip channel.xml check for local packages - break; - } + if (!isset($var['type'])) { + return $this->raiseError('Configuration information must contain a type'); + } elseif (!in_array($var['type'], + array('string', 'mask', 'password', 'directory', 'file', 'set'))) { + return $this->raiseError( + 'Configuration type must be one of directory, file, string, ' . + 'mask, set, or password'); + } + if (!isset($var['default'])) { + return $this->raiseError( + 'Configuration information must contain a default value ("default" index)'); + } - if ($params[$i] && !isset($channelschecked[$params[$i]->getChannel()]) && - !isset($this->_options['offline'])) { - $channelschecked[$params[$i]->getChannel()] = true; - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - if (!class_exists('System')) { - require_once 'System.php'; + if (is_array($var['default'])) { + $real_default = ''; + foreach ($var['default'] as $config_var => $val) { + if (strpos($config_var, 'text') === 0) { + $real_default .= $val; + } elseif (strpos($config_var, 'constant') === 0) { + if (!defined($val)) { + return $this->raiseError( + 'Unknown constant "' . $val . '" requested in ' . + 'default value for configuration variable "' . + $name . '"'); } - $curchannel = &$this->_registry->getChannel($params[$i]->getChannel()); - if (PEAR::isError($curchannel)) { - PEAR::staticPopErrorHandling(); - return $this->raiseError($curchannel); - } + $real_default .= constant($val); + } elseif (isset($this->configuration_info[$config_var])) { + $real_default .= + $this->configuration_info[$config_var]['default']; + } else { + return $this->raiseError( + 'Unknown request for "' . $config_var . '" value in ' . + 'default value for configuration variable "' . + $name . '"'); + } + } + $var['default'] = $real_default; + } - if (PEAR::isError($dir = $this->getDownloadDir())) { - PEAR::staticPopErrorHandling(); - break; - } + if ($var['type'] == 'integer') { + $var['default'] = (integer) $var['default']; + } - $mirror = $this->config->get('preferred_mirror', null, - $params[$i]->getChannel()); - $a = $this->downloadHttp('http://' . $mirror . - '/channel.xml', $this->ui, $dir, null, $curchannel->lastModified()); + if (!isset($var['doc'])) { + return $this->raiseError( + 'Configuration information must contain a summary ("doc" index)'); + } - PEAR::staticPopErrorHandling(); - if (PEAR::isError($a) || !$a) { - // Attempt fallback to https automatically - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $a = $this->downloadHttp('https://' . $mirror . - '/channel.xml', $this->ui, $dir, null, $curchannel->lastModified()); + if (!isset($var['prompt'])) { + return $this->raiseError( + 'Configuration information must contain a simple prompt ("prompt" index)'); + } - PEAR::staticPopErrorHandling(); - if (PEAR::isError($a) || !$a) { - break; - } - } - $this->log(0, 'WARNING: channel "' . $params[$i]->getChannel() . '" has ' . - 'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $params[$i]->getChannel() . - '" to update'); - } - } while (false); + if (!isset($var['group'])) { + return $this->raiseError( + 'Configuration information must contain a simple group ("group" index)'); + } - if ($params[$i] && !isset($this->_options['downloadonly'])) { - if (isset($this->_options['packagingroot'])) { - $checkdir = $this->_prependPath( - $this->config->get('php_dir', null, $params[$i]->getChannel()), - $this->_options['packagingroot']); - } else { - $checkdir = $this->config->get('php_dir', - null, $params[$i]->getChannel()); - } + if (isset($this->configuration_info[$name])) { + return $this->raiseError('Configuration variable "' . $name . + '" already exists'); + } - while ($checkdir && $checkdir != '/' && !file_exists($checkdir)) { - $checkdir = dirname($checkdir); - } + $this->configuration_info[$name] = $var; + // fix bug #7351: setting custom config variable in a channel fails + $this->_channelConfigInfo[] = $name; + } - if ($checkdir == '.') { - $checkdir = '/'; - } + return true; + } - if (!is_writeable($checkdir)) { - return PEAR::raiseError('Cannot install, php_dir for channel "' . - $params[$i]->getChannel() . '" is not writeable by the current user'); - } + /** + * Encodes/scrambles configuration data before writing to files. + * Currently, 'password' values will be base64-encoded as to avoid + * that people spot cleartext passwords by accident. + * + * @param array (reference) array to encode values in + * @return bool TRUE on success + * @access private + */ + function _encodeOutput(&$data) + { + foreach ($data as $key => $value) { + if ($key == '__channels') { + foreach ($data['__channels'] as $channel => $blah) { + $this->_encodeOutput($data['__channels'][$channel]); } } - } - unset($channelschecked); - PEAR_Downloader_Package::removeDuplicates($params); - if (!count($params)) { - $a = array(); - return $a; - } + if (!isset($this->configuration_info[$key])) { + continue; + } - if (!isset($this->_options['nodeps']) && !isset($this->_options['offline'])) { - $reverify = true; - while ($reverify) { - $reverify = false; - foreach ($params as $i => $param) { - //PHP Bug 40768 / PEAR Bug #10944 - //Nested foreaches fail in PHP 5.2.1 - key($params); - $ret = $params[$i]->detectDependencies($params); - if (PEAR::isError($ret)) { - $reverify = true; - $params[$i] = false; - PEAR_Downloader_Package::removeDuplicates($params); - if (!isset($this->_options['soft'])) { - $this->log(0, $ret->getMessage()); - } - continue 2; - } + $type = $this->configuration_info[$key]['type']; + switch ($type) { + // we base64-encode passwords so they are at least + // not shown in plain by accident + case 'password': { + $data[$key] = base64_encode($data[$key]); + break; + } + case 'mask': { + $data[$key] = octdec($data[$key]); + break; } } } - if (isset($this->_options['offline'])) { - $this->log(3, 'Skipping dependency download check, --offline specified'); - } + return true; + } - if (!count($params)) { - $a = array(); - return $a; + /** + * Decodes/unscrambles configuration data after reading from files. + * + * @param array (reference) array to encode values in + * @return bool TRUE on success + * @access private + * + * @see PEAR_Config::_encodeOutput + */ + function _decodeInput(&$data) + { + if (!is_array($data)) { + return true; } - while (PEAR_Downloader_Package::mergeDependencies($params)); - PEAR_Downloader_Package::removeDuplicates($params, true); - $errorparams = array(); - if (PEAR_Downloader_Package::detectStupidDuplicates($params, $errorparams)) { - if (count($errorparams)) { - foreach ($errorparams as $param) { - $name = $this->_registry->parsedPackageNameToString($param->getParsedPackage()); - $this->pushError('Duplicate package ' . $name . ' found', PEAR_INSTALLER_FAILED); + foreach ($data as $key => $value) { + if ($key == '__channels') { + foreach ($data['__channels'] as $channel => $blah) { + $this->_decodeInput($data['__channels'][$channel]); } - $a = array(); - return $a; } - } - PEAR_Downloader_Package::removeInstalled($params); - if (!count($params)) { - $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED); - $a = array(); - return $a; - } + if (!isset($this->configuration_info[$key])) { + continue; + } - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $err = $this->analyzeDependencies($params); - PEAR::popErrorHandling(); - if (!count($params)) { - $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED); - $a = array(); - return $a; + $type = $this->configuration_info[$key]['type']; + switch ($type) { + case 'password': { + $data[$key] = base64_decode($data[$key]); + break; + } + case 'mask': { + $data[$key] = decoct($data[$key]); + break; + } + } } - $ret = array(); - $newparams = array(); - if (isset($this->_options['pretend'])) { - return $params; - } + return true; + } - $somefailed = false; - foreach ($params as $i => $package) { - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $pf = &$params[$i]->download(); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($pf)) { - if (!isset($this->_options['soft'])) { - $this->log(1, $pf->getMessage()); - $this->log(0, 'Error: cannot download "' . - $this->_registry->parsedPackageNameToString($package->getParsedPackage(), - true) . - '"'); + /** + * Retrieve the default channel. + * + * On startup, channels are not initialized, so if the default channel is not + * pear.php.net, then initialize the config. + * @param string registry layer + * @return string|false + */ + function getDefaultChannel($layer = null) + { + $ret = false; + if ($layer === null) { + foreach ($this->layers as $layer) { + if (isset($this->configuration[$layer]['default_channel'])) { + $ret = $this->configuration[$layer]['default_channel']; + break; } - $somefailed = true; - continue; } + } elseif (isset($this->configuration[$layer]['default_channel'])) { + $ret = $this->configuration[$layer]['default_channel']; + } - $newparams[] = &$params[$i]; - $ret[] = array( - 'file' => $pf->getArchiveFile(), - 'info' => &$pf, - 'pkg' => $pf->getPackage() - ); + if ($ret == 'pear.php.net' && defined('PEAR_RUNTYPE') && PEAR_RUNTYPE == 'pecl') { + $ret = 'pecl.php.net'; } - if ($somefailed) { - // remove params that did not download successfully - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $err = $this->analyzeDependencies($newparams, true); - PEAR::popErrorHandling(); - if (!count($newparams)) { - $this->pushError('Download failed', PEAR_INSTALLER_FAILED); - $a = array(); - return $a; + if ($ret) { + if ($ret != 'pear.php.net') { + $this->_lazyChannelSetup(); } + + return $ret; } - $this->_downloadedPackages = $ret; - return $newparams; + return PEAR_CONFIG_DEFAULT_CHANNEL; } /** - * @param array all packages to be installed + * Returns a configuration value, prioritizing layers as per the + * layers property. + * + * @param string config key + * @return mixed the config value, or NULL if not found + * @access public */ - function analyzeDependencies(&$params, $force = false) + function get($key, $layer = null, $channel = false) { - $hasfailed = $failed = false; - if (isset($this->_options['downloadonly'])) { - return; + if (!isset($this->configuration_info[$key])) { + return null; } - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $redo = true; - $reset = false; - while ($redo) { - $redo = false; - foreach ($params as $i => $param) { - $deps = $param->getDeps(); - if (!$deps) { - $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(), - $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); - $send = $param->getPackageFile(); - - $installcheck = $depchecker->validatePackage($send, $this, $params); - if (PEAR::isError($installcheck)) { - if (!isset($this->_options['soft'])) { - $this->log(0, $installcheck->getMessage()); - } - $hasfailed = true; - $params[$i] = false; - $reset = true; - $redo = true; - $failed = false; - PEAR_Downloader_Package::removeDuplicates($params); - continue 2; - } - continue; - } + if ($key == '__channels') { + return null; + } - if (!$reset && $param->alreadyValidated() && !$force) { - continue; - } + if ($key == 'default_channel') { + return $this->getDefaultChannel($layer); + } - if (count($deps)) { - $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(), - $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); - $send = $param->getPackageFile(); - if ($send === null) { - $send = $param->getDownloadURL(); - } + if (!$channel) { + $channel = $this->getDefaultChannel(); + } elseif ($channel != 'pear.php.net') { + $this->_lazyChannelSetup(); + } + $channel = strtolower($channel); - $installcheck = $depchecker->validatePackage($send, $this, $params); - if (PEAR::isError($installcheck)) { - if (!isset($this->_options['soft'])) { - $this->log(0, $installcheck->getMessage()); - } - $hasfailed = true; - $params[$i] = false; - $reset = true; - $redo = true; - $failed = false; - PEAR_Downloader_Package::removeDuplicates($params); - continue 2; - } - - $failed = false; - if (isset($deps['required'])) { - foreach ($deps['required'] as $type => $dep) { - // note: Dependency2 will never return a PEAR_Error if ignore-errors - // is specified, so soft is needed to turn off logging - if (!isset($dep[0])) { - if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep, - true, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } else { - foreach ($dep as $d) { - if (PEAR::isError($e = - $depchecker->{"validate{$type}Dependency"}($d, - true, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } - } - } + $test = (in_array($key, $this->_channelConfigInfo)) ? + $this->_getChannelValue($key, $layer, $channel) : + null; + if ($test !== null) { + if ($this->_installRoot) { + if (in_array($this->getGroup($key), + array('File Locations', 'File Locations (Advanced)')) && + $this->getType($key) == 'directory') { + return $this->_prependPath($test, $this->_installRoot); + } + } + return $test; + } - if (isset($deps['optional'])) { - foreach ($deps['optional'] as $type => $dep) { - if (!isset($dep[0])) { - if (PEAR::isError($e = - $depchecker->{"validate{$type}Dependency"}($dep, - false, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } else { - foreach ($dep as $d) { - if (PEAR::isError($e = - $depchecker->{"validate{$type}Dependency"}($d, - false, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } - } - } + if ($layer === null) { + foreach ($this->layers as $layer) { + if (isset($this->configuration[$layer][$key])) { + $test = $this->configuration[$layer][$key]; + if ($this->_installRoot) { + if (in_array($this->getGroup($key), + array('File Locations', 'File Locations (Advanced)')) && + $this->getType($key) == 'directory') { + return $this->_prependPath($test, $this->_installRoot); } + } - $groupname = $param->getGroup(); - if (isset($deps['group']) && $groupname) { - if (!isset($deps['group'][0])) { - $deps['group'] = array($deps['group']); - } - - $found = false; - foreach ($deps['group'] as $group) { - if ($group['attribs']['name'] == $groupname) { - $found = true; - break; - } + if ($key == 'preferred_mirror') { + $reg = &$this->getRegistry(); + if (is_object($reg)) { + $chan = &$reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $channel; } - if ($found) { - unset($group['attribs']); - foreach ($group as $type => $dep) { - if (!isset($dep[0])) { - if (PEAR::isError($e = - $depchecker->{"validate{$type}Dependency"}($dep, - false, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } else { - foreach ($dep as $d) { - if (PEAR::isError($e = - $depchecker->{"validate{$type}Dependency"}($d, - false, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } - } - } - } - } - } else { - foreach ($deps as $dep) { - if (PEAR::isError($e = $depchecker->validateDependency1($dep, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } + if (!$chan->getMirror($test) && $chan->getName() != $test) { + return $channel; // mirror does not exist } } } - $params[$i]->setValidated(); + return $test; } - - if ($failed) { - $hasfailed = true; - $params[$i] = false; - $reset = true; - $redo = true; - $failed = false; - PEAR_Downloader_Package::removeDuplicates($params); - continue 2; + } + } elseif (isset($this->configuration[$layer][$key])) { + $test = $this->configuration[$layer][$key]; + if ($this->_installRoot) { + if (in_array($this->getGroup($key), + array('File Locations', 'File Locations (Advanced)')) && + $this->getType($key) == 'directory') { + return $this->_prependPath($test, $this->_installRoot); } } - } - PEAR::staticPopErrorHandling(); - if ($hasfailed && (isset($this->_options['ignore-errors']) || - isset($this->_options['nodeps']))) { - // this is probably not needed, but just in case - if (!isset($this->_options['soft'])) { - $this->log(0, 'WARNING: dependencies failed'); + + if ($key == 'preferred_mirror') { + $reg = &$this->getRegistry(); + if (is_object($reg)) { + $chan = &$reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $channel; + } + + if (!$chan->getMirror($test) && $chan->getName() != $test) { + return $channel; // mirror does not exist + } + } } + + return $test; } + + return null; } /** - * Retrieve the directory that downloads will happen in + * Returns a channel-specific configuration value, prioritizing layers as per the + * layers property. + * + * @param string config key + * @return mixed the config value, or NULL if not found * @access private - * @return string */ - function getDownloadDir() + function _getChannelValue($key, $layer, $channel) { - if (isset($this->_downloadDir)) { - return $this->_downloadDir; - } - $downloaddir = $this->config->get('download_dir'); - if (empty($downloaddir) || (is_dir($downloaddir) && !is_writable($downloaddir))) { - if (is_dir($downloaddir) && !is_writable($downloaddir)) { - $this->log(0, 'WARNING: configuration download directory "' . $downloaddir . - '" is not writeable. Change download_dir config variable to ' . - 'a writeable dir to avoid this warning'); - } - if (!class_exists('System')) { - require_once 'System.php'; - } - if (PEAR::isError($downloaddir = System::mktemp('-d'))) { - return $downloaddir; - } - $this->log(3, '+ tmp dir created at ' . $downloaddir); - } - if (!is_writable($downloaddir)) { - if (PEAR::isError(System::mkdir(array('-p', $downloaddir))) || - !is_writable($downloaddir)) { - return PEAR::raiseError('download directory "' . $downloaddir . - '" is not writeable. Change download_dir config variable to ' . - 'a writeable dir'); - } + if ($key == '__channels' || $channel == 'pear.php.net') { + return null; } - return $this->_downloadDir = $downloaddir; - } - function setDownloadDir($dir) - { - if (!@is_writable($dir)) { - if (PEAR::isError(System::mkdir(array('-p', $dir)))) { - return PEAR::raiseError('download directory "' . $dir . - '" is not writeable. Change download_dir config variable to ' . - 'a writeable dir'); + $ret = null; + if ($layer === null) { + foreach ($this->layers as $ilayer) { + if (isset($this->configuration[$ilayer]['__channels'][$channel][$key])) { + $ret = $this->configuration[$ilayer]['__channels'][$channel][$key]; + break; + } } + } elseif (isset($this->configuration[$layer]['__channels'][$channel][$key])) { + $ret = $this->configuration[$layer]['__channels'][$channel][$key]; } - $this->_downloadDir = $dir; - } - // }}} - // {{{ configSet() - function configSet($key, $value, $layer = 'user', $channel = false) - { - $this->config->set($key, $value, $layer, $channel); - $this->_preferredState = $this->config->get('preferred_state', null, $channel); - if (!$this->_preferredState) { - // don't inadvertantly use a non-set preferred_state - $this->_preferredState = null; + if ($key != 'preferred_mirror') { + return $ret; } - } - // }}} - // {{{ setOptions() - function setOptions($options) - { - $this->_options = $options; - } - // }}} - // {{{ setOptions() - function getOptions() - { - return $this->_options; - } + if ($ret !== null) { + $reg = &$this->getRegistry($layer); + if (is_object($reg)) { + $chan = &$reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $channel; + } - // }}} + if (!$chan->getMirror($ret) && $chan->getName() != $ret) { + return $channel; // mirror does not exist + } + } - /** - * For simpler unit-testing - * @param PEAR_Config - * @param int - * @param string - */ - function &getPackagefileObject(&$c, $d, $t = false) - { - if (!class_exists('PEAR_PackageFile')) { - require_once 'PEAR/PackageFile.php'; + return $ret; + } + + if ($channel != $this->getDefaultChannel($layer)) { + return $channel; // we must use the channel name as the preferred mirror + // if the user has not chosen an alternate } - $a = &new PEAR_PackageFile($c, $d, $t); - return $a; - } - // {{{ _getPackageDownloadUrl() + return $this->getDefaultChannel($layer); + } /** - * @param array output of {@link parsePackageName()} - * @access private + * Set a config value in a specific layer (defaults to 'user'). + * Enforces the types defined in the configuration_info array. An + * integer config variable will be cast to int, and a set config + * variable will be validated against its legal values. + * + * @param string config key + * @param string config value + * @param string (optional) config layer + * @param string channel to set this value for, or null for global value + * @return bool TRUE on success, FALSE on failure */ - function _getPackageDownloadUrl($parr) + function set($key, $value, $layer = 'user', $channel = false) { - $curchannel = $this->config->get('default_channel'); - $this->configSet('default_channel', $parr['channel']); - // getDownloadURL returns an array. On error, it only contains information - // on the latest release as array(version, info). On success it contains - // array(version, info, download url string) - $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state'); - if (!$this->_registry->channelExists($parr['channel'])) { - do { - if ($this->config->get('auto_discover') && $this->discover($parr['channel'])) { - break; - } - - $this->configSet('default_channel', $curchannel); - return PEAR::raiseError('Unknown remote channel: ' . $parr['channel']); - } while (false); - } - - $chan = &$this->_registry->getChannel($parr['channel']); - if (PEAR::isError($chan)) { - return $chan; + if ($key == '__channels') { + return false; } - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $version = $this->_registry->packageInfo($parr['package'], 'version', $parr['channel']); - $stability = $this->_registry->packageInfo($parr['package'], 'stability', $parr['channel']); - // package is installed - use the installed release stability level - if (!isset($parr['state']) && $stability !== null) { - $state = $stability['release']; + if (!isset($this->configuration[$layer])) { + return false; } - PEAR::staticPopErrorHandling(); - $base2 = false; - $preferred_mirror = $this->config->get('preferred_mirror'); - if (!$chan->supportsREST($preferred_mirror) || - ( - !($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror)) - && - !($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) - ) - ) { - return $this->raiseError($parr['channel'] . ' is using a unsupported protocal - This should never happen.'); + if ($key == 'default_channel') { + // can only set this value globally + $channel = 'pear.php.net'; + if ($value != 'pear.php.net') { + $this->_lazyChannelSetup($layer); + } } - if ($base2) { - $rest = &$this->config->getREST('1.3', $this->_options); - $base = $base2; - } else { - $rest = &$this->config->getREST('1.0', $this->_options); - } + if ($key == 'preferred_mirror') { + if ($channel == '__uri') { + return false; // can't set the __uri pseudo-channel's mirror + } - if (!isset($parr['version']) && !isset($parr['state']) && $version - && !PEAR::isError($version) - && !isset($this->_options['downloadonly'])) { - $url = $rest->getDownloadURL($base, $parr, $state, $version, $chan->getName()); - } else { - $url = $rest->getDownloadURL($base, $parr, $state, false, $chan->getName()); - } + $reg = &$this->getRegistry($layer); + if (is_object($reg)) { + $chan = &$reg->getChannel($channel ? $channel : 'pear.php.net'); + if (PEAR::isError($chan)) { + return false; + } - if (PEAR::isError($url)) { - $this->configSet('default_channel', $curchannel); - return $url; + if (!$chan->getMirror($value) && $chan->getName() != $value) { + return false; // mirror does not exist + } + } } - if ($parr['channel'] != $curchannel) { - $this->configSet('default_channel', $curchannel); + if (!isset($this->configuration_info[$key])) { + return false; } - if (!is_array($url)) { - return $url; + extract($this->configuration_info[$key]); + switch ($type) { + case 'integer': + $value = (int)$value; + break; + case 'set': { + // If a valid_set is specified, require the value to + // be in the set. If there is no valid_set, accept + // any value. + if ($valid_set) { + reset($valid_set); + if ((key($valid_set) === 0 && !in_array($value, $valid_set)) || + (key($valid_set) !== 0 && empty($valid_set[$value]))) + { + return false; + } + } + break; + } } - $url['raw'] = false; // no checking is necessary for REST - if (!is_array($url['info'])) { - return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . - 'this should never happen'); + if (!$channel) { + $channel = $this->get('default_channel', null, 'pear.php.net'); } - if (!isset($this->_options['force']) && - !isset($this->_options['downloadonly']) && - $version && - !PEAR::isError($version) && - !isset($parr['group']) - ) { - if (version_compare($version, $url['version'], '=')) { - return PEAR::raiseError($this->_registry->parsedPackageNameToString( - $parr, true) . ' is already installed and is the same as the ' . - 'released version ' . $url['version'], -976); + if (!in_array($channel, $this->_channels)) { + $this->_lazyChannelSetup($layer); + $reg = &$this->getRegistry($layer); + if ($reg) { + $channel = $reg->channelName($channel); } - if (version_compare($version, $url['version'], '>')) { - return PEAR::raiseError($this->_registry->parsedPackageNameToString( - $parr, true) . ' is already installed and is newer than detected ' . - 'released version ' . $url['version'], -976); + if (!in_array($channel, $this->_channels)) { + return false; } } - if (isset($url['info']['required']) || $url['compatible']) { - require_once 'PEAR/PackageFile/v2.php'; - $pf = new PEAR_PackageFile_v2; - $pf->setRawChannel($parr['channel']); - if ($url['compatible']) { - $pf->setRawCompatible($url['compatible']); + if ($channel != 'pear.php.net') { + if (in_array($key, $this->_channelConfigInfo)) { + $this->configuration[$layer]['__channels'][$channel][$key] = $value; + return true; } - } else { - require_once 'PEAR/PackageFile/v1.php'; - $pf = new PEAR_PackageFile_v1; - } - $pf->setRawPackage($url['package']); - $pf->setDeps($url['info']); - if ($url['compatible']) { - $pf->setCompatible($url['compatible']); + return false; } - $pf->setRawState($url['stability']); - $url['info'] = &$pf; - if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) { - $ext = '.tar'; - } else { - $ext = '.tgz'; + if ($key == 'default_channel') { + if (!isset($reg)) { + $reg = &$this->getRegistry($layer); + if (!$reg) { + $reg = &$this->getRegistry(); + } + } + + if ($reg) { + $value = $reg->channelName($value); + } + + if (!$value) { + return false; + } } - if (is_array($url) && isset($url['url'])) { - $url['url'] .= $ext; + $this->configuration[$layer][$key] = $value; + if ($key == 'php_dir' && !$this->_noRegistry) { + if (!isset($this->_registry[$layer]) || + $value != $this->_registry[$layer]->install_dir) { + $this->_registry[$layer] = &new PEAR_Registry($value); + $this->_regInitialized[$layer] = false; + $this->_registry[$layer]->setConfig($this, false); + } } - return $url; + return true; } - // }}} - // {{{ getDepPackageDownloadUrl() - /** - * @param array dependency array - * @access private - */ - function _getDepPackageDownloadUrl($dep, $parr) + function _lazyChannelSetup($uselayer = false) { - $xsdversion = isset($dep['rel']) ? '1.0' : '2.0'; - $curchannel = $this->config->get('default_channel'); - if (isset($dep['uri'])) { - $xsdversion = '2.0'; - $chan = &$this->_registry->getChannel('__uri'); - if (PEAR::isError($chan)) { - return $chan; - } + if ($this->_noRegistry) { + return; + } - $version = $this->_registry->packageInfo($dep['name'], 'version', '__uri'); - $this->configSet('default_channel', '__uri'); - } else { - if (isset($dep['channel'])) { - $remotechannel = $dep['channel']; - } else { - $remotechannel = 'pear.php.net'; + $merge = false; + foreach ($this->_registry as $layer => $p) { + if ($uselayer && $uselayer != $layer) { + continue; } - if (!$this->_registry->channelExists($remotechannel)) { - do { - if ($this->config->get('auto_discover')) { - if ($this->discover($remotechannel)) { - break; - } + if (!$this->_regInitialized[$layer]) { + if ($layer == 'default' && isset($this->_registry['user']) || + isset($this->_registry['system'])) { + // only use the default registry if there are no alternatives + continue; + } + + if (!is_object($this->_registry[$layer])) { + if ($phpdir = $this->get('php_dir', $layer, 'pear.php.net')) { + $this->_registry[$layer] = &new PEAR_Registry($phpdir); + $this->_registry[$layer]->setConfig($this, false); + $this->_regInitialized[$layer] = false; + } else { + unset($this->_registry[$layer]); + return; } - return PEAR::raiseError('Unknown remote channel: ' . $remotechannel); - } while (false); - } + } - $chan = &$this->_registry->getChannel($remotechannel); - if (PEAR::isError($chan)) { - return $chan; + $this->setChannels($this->_registry[$layer]->listChannels(), $merge); + $this->_regInitialized[$layer] = true; + $merge = true; } + } + } - $version = $this->_registry->packageInfo($dep['name'], 'version', $remotechannel); - $this->configSet('default_channel', $remotechannel); + /** + * Set the list of channels. + * + * This should be set via a call to {@link PEAR_Registry::listChannels()} + * @param array + * @param bool + * @return bool success of operation + */ + function setChannels($channels, $merge = false) + { + if (!is_array($channels)) { + return false; } - $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state'); - if (isset($parr['state']) && isset($parr['version'])) { - unset($parr['state']); + if ($merge) { + $this->_channels = array_merge($this->_channels, $channels); + } else { + $this->_channels = $channels; } - if (isset($dep['uri'])) { - $info = &$this->newDownloaderPackage($this); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $err = $info->initialize($dep); - PEAR::staticPopErrorHandling(); - if (!$err) { - // skip parameters that were missed by preferred_state - return PEAR::raiseError('Cannot initialize dependency'); + foreach ($channels as $channel) { + $channel = strtolower($channel); + if ($channel == 'pear.php.net') { + continue; } - if (PEAR::isError($err)) { - if (!isset($this->_options['soft'])) { - $this->log(0, $err->getMessage()); + foreach ($this->layers as $layer) { + if (!isset($this->configuration[$layer]['__channels'])) { + $this->configuration[$layer]['__channels'] = array(); } - - if (is_object($info)) { - $param = $info->getChannel() . '/' . $info->getPackage(); + if (!isset($this->configuration[$layer]['__channels'][$channel]) + || !is_array($this->configuration[$layer]['__channels'][$channel])) { + $this->configuration[$layer]['__channels'][$channel] = array(); } - return PEAR::raiseError('Package "' . $param . '" is not valid'); - } - return $info; - } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) - && $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror')) - ) { - $rest = &$this->config->getREST('1.0', $this->_options); - $url = $rest->getDepDownloadURL($base, $xsdversion, $dep, $parr, - $state, $version, $chan->getName()); - if (PEAR::isError($url)) { - return $url; - } - - if ($parr['channel'] != $curchannel) { - $this->configSet('default_channel', $curchannel); } + } - if (!is_array($url)) { - return $url; - } + return true; + } - $url['raw'] = false; // no checking is necessary for REST - if (!is_array($url['info'])) { - return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . - 'this should never happen'); - } + /** + * Get the type of a config value. + * + * @param string config key + * + * @return string type, one of "string", "integer", "file", + * "directory", "set" or "password". + * + * @access public + * + */ + function getType($key) + { + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['type']; + } + return false; + } - if (isset($url['info']['required'])) { - if (!class_exists('PEAR_PackageFile_v2')) { - require_once 'PEAR/PackageFile/v2.php'; - } - $pf = new PEAR_PackageFile_v2; - $pf->setRawChannel($remotechannel); - } else { - if (!class_exists('PEAR_PackageFile_v1')) { - require_once 'PEAR/PackageFile/v1.php'; - } - $pf = new PEAR_PackageFile_v1; + /** + * Get the documentation for a config value. + * + * @param string config key + * @return string documentation string + * + * @access public + * + */ + function getDocs($key) + { + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['doc']; + } - } - $pf->setRawPackage($url['package']); - $pf->setDeps($url['info']); - if ($url['compatible']) { - $pf->setCompatible($url['compatible']); - } + return false; + } - $pf->setRawState($url['stability']); - $url['info'] = &$pf; - if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) { - $ext = '.tar'; - } else { - $ext = '.tgz'; - } + /** + * Get the short documentation for a config value. + * + * @param string config key + * @return string short documentation string + * + * @access public + * + */ + function getPrompt($key) + { + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['prompt']; + } - if (is_array($url) && isset($url['url'])) { - $url['url'] .= $ext; - } + return false; + } - return $url; + /** + * Get the parameter group for a config key. + * + * @param string config key + * @return string parameter group + * + * @access public + * + */ + function getGroup($key) + { + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['group']; } - return $this->raiseError($parr['channel'] . ' is using a unsupported protocal - This should never happen.'); + return false; } - // }}} - // {{{ getPackageDownloadUrl() /** - * @deprecated in favor of _getPackageDownloadUrl + * Get the list of parameter groups. + * + * @return array list of parameter groups + * + * @access public + * */ - function getPackageDownloadUrl($package, $version = null, $channel = false) + function getGroups() { - if ($version) { - $package .= "-$version"; - } - if ($this === null || $this->_registry === null) { - $package = "http://pear.php.net/get/$package"; - } else { - $chan = $this->_registry->getChannel($channel); - if (PEAR::isError($chan)) { - return ''; - } - $package = "http://" . $chan->getServer() . "/get/$package"; - } - if (!extension_loaded("zlib")) { - $package .= '?uncompress=yes'; + $tmp = array(); + foreach ($this->configuration_info as $key => $info) { + $tmp[$info['group']] = 1; } - return $package; - } - // }}} - // {{{ getDownloadedPackages() + return array_keys($tmp); + } /** - * Retrieve a list of downloaded packages after a call to {@link download()}. + * Get the list of the parameters in a group. + * + * @param string $group parameter group + * @return array list of parameters in $group + * + * @access public * - * Also resets the list of downloaded packages. - * @return array */ - function getDownloadedPackages() + function getGroupKeys($group) { - $ret = $this->_downloadedPackages; - $this->_downloadedPackages = array(); - $this->_toDownload = array(); - return $ret; - } + $keys = array(); + foreach ($this->configuration_info as $key => $info) { + if ($info['group'] == $group) { + $keys[] = $key; + } + } - // }}} - // {{{ _downloadCallback() + return $keys; + } - function _downloadCallback($msg, $params = null) + /** + * Get the list of allowed set values for a config value. Returns + * NULL for config values that are not sets. + * + * @param string config key + * @return array enumerated array of set values, or NULL if the + * config key is unknown or not a set + * + * @access public + * + */ + function getSetValues($key) { - switch ($msg) { - case 'saveas': - $this->log(1, "downloading $params ..."); - break; - case 'done': - $this->log(1, '...done: ' . number_format($params, 0, '', ',') . ' bytes'); - break; - case 'bytesread': - static $bytes; - if (empty($bytes)) { - $bytes = 0; - } - if (!($bytes % 10240)) { - $this->log(1, '.', false); - } - $bytes += $params; - break; - case 'start': - if($params[1] == -1) { - $length = "Unknown size"; - } else { - $length = number_format($params[1], 0, '', ',')." bytes"; - } - $this->log(1, "Starting to download {$params[0]} ($length)"); - break; + if (isset($this->configuration_info[$key]) && + isset($this->configuration_info[$key]['type']) && + $this->configuration_info[$key]['type'] == 'set') + { + $valid_set = $this->configuration_info[$key]['valid_set']; + reset($valid_set); + if (key($valid_set) === 0) { + return $valid_set; + } + + return array_keys($valid_set); } - if (method_exists($this->ui, '_downloadCallback')) - $this->ui->_downloadCallback($msg, $params); - } - // }}} - // {{{ _prependPath($path, $prepend) + return null; + } - function _prependPath($path, $prepend) + /** + * Get all the current config keys. + * + * @return array simple array of config keys + * + * @access public + */ + function getKeys() { - if (strlen($prepend) > 0) { - if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { - if (preg_match('/^[a-z]:/i', $prepend)) { - $prepend = substr($prepend, 2); - } elseif ($prepend{0} != '\\') { - $prepend = "\\$prepend"; + $keys = array(); + foreach ($this->layers as $layer) { + $test = $this->configuration[$layer]; + if (isset($test['__channels'])) { + foreach ($test['__channels'] as $channel => $configs) { + $keys = array_merge($keys, $configs); } - $path = substr($path, 0, 2) . $prepend . substr($path, 2); - } else { - $path = $prepend . $path; } + + unset($test['__channels']); + $keys = array_merge($keys, $test); + } - return $path; + return array_keys($keys); } - // }}} - // {{{ pushError($errmsg, $code) /** - * @param string - * @param integer + * Remove the a config key from a specific config layer. + * + * @param string config key + * @param string (optional) config layer + * @param string (optional) channel (defaults to default channel) + * @return bool TRUE on success, FALSE on failure + * + * @access public */ - function pushError($errmsg, $code = -1) + function remove($key, $layer = 'user', $channel = null) { - array_push($this->_errorStack, array($errmsg, $code)); - } + if ($channel === null) { + $channel = $this->getDefaultChannel(); + } - // }}} - // {{{ getErrorMsgs() + if ($channel !== 'pear.php.net') { + if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { + unset($this->configuration[$layer]['__channels'][$channel][$key]); + return true; + } + } - function getErrorMsgs() - { - $msgs = array(); - $errs = $this->_errorStack; - foreach ($errs as $err) { - $msgs[] = $err[0]; + if (isset($this->configuration[$layer][$key])) { + unset($this->configuration[$layer][$key]); + return true; } - $this->_errorStack = array(); - return $msgs; - } - // }}} + return false; + } /** - * for BC + * Temporarily remove an entire config layer. USE WITH CARE! + * + * @param string config key + * @param string (optional) config layer + * @return bool TRUE on success, FALSE on failure + * + * @access public */ - function sortPkgDeps(&$packages, $uninstall = false) + function removeLayer($layer) { - $uninstall ? - $this->sortPackagesForUninstall($packages) : - $this->sortPackagesForInstall($packages); + if (isset($this->configuration[$layer])) { + $this->configuration[$layer] = array(); + return true; + } + + return false; } /** - * Sort a list of arrays of array(downloaded packagefilename) by dependency. + * Stores configuration data in a layer. * - * This uses the topological sort method from graph theory, and the - * Structures_Graph package to properly sort dependencies for installation. - * @param array an array of downloaded PEAR_Downloader_Packages - * @return array array of array(packagefilename, package.xml contents) + * @param string config layer to store + * @return bool TRUE on success, or PEAR error on failure + * + * @access public */ - function sortPackagesForInstall(&$packages) + function store($layer = 'user', $data = null) { - require_once 'Structures/Graph.php'; - require_once 'Structures/Graph/Node.php'; - require_once 'Structures/Graph/Manipulator/TopologicalSorter.php'; - $depgraph = new Structures_Graph(true); - $nodes = array(); - $reg = &$this->config->getRegistry(); - foreach ($packages as $i => $package) { - $pname = $reg->parsedPackageNameToString( - array( - 'channel' => $package->getChannel(), - 'package' => strtolower($package->getPackage()), - )); - $nodes[$pname] = new Structures_Graph_Node; - $nodes[$pname]->setData($packages[$i]); - $depgraph->addNode($nodes[$pname]); - } - - $deplinks = array(); - foreach ($nodes as $package => $node) { - $pf = &$node->getData(); - $pdeps = $pf->getDeps(true); - if (!$pdeps) { - continue; - } + return $this->writeConfigFile(null, $layer, $data); + } - if ($pf->getPackagexmlVersion() == '1.0') { - foreach ($pdeps as $dep) { - if ($dep['type'] != 'pkg' || - (isset($dep['optional']) && $dep['optional'] == 'yes')) { - continue; + /** + * Tells what config layer that gets to define a key. + * + * @param string config key + * @param boolean return the defining channel + * + * @return string|array the config layer, or an empty string if not found. + * + * if $returnchannel, the return is an array array('layer' => layername, + * 'channel' => channelname), or an empty string if not found + * + * @access public + */ + function definedBy($key, $returnchannel = false) + { + foreach ($this->layers as $layer) { + $channel = $this->getDefaultChannel(); + if ($channel !== 'pear.php.net') { + if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { + if ($returnchannel) { + return array('layer' => $layer, 'channel' => $channel); } + return $layer; + } + } - $dname = $reg->parsedPackageNameToString( - array( - 'channel' => 'pear.php.net', - 'package' => strtolower($dep['name']), - )); + if (isset($this->configuration[$layer][$key])) { + if ($returnchannel) { + return array('layer' => $layer, 'channel' => 'pear.php.net'); + } + return $layer; + } + } - if (isset($nodes[$dname])) { - if (!isset($deplinks[$dname])) { - $deplinks[$dname] = array(); - } + return ''; + } - $deplinks[$dname][$package] = 1; - // dependency is in installed packages - continue; - } - - $dname = $reg->parsedPackageNameToString( - array( - 'channel' => 'pecl.php.net', - 'package' => strtolower($dep['name']), - )); - - if (isset($nodes[$dname])) { - if (!isset($deplinks[$dname])) { - $deplinks[$dname] = array(); - } + /** + * Tells whether a given key exists as a config value. + * + * @param string config key + * @return bool whether exists in this object + * + * @access public + */ + function isDefined($key) + { + foreach ($this->layers as $layer) { + if (isset($this->configuration[$layer][$key])) { + return true; + } + } - $deplinks[$dname][$package] = 1; - // dependency is in installed packages - continue; - } - } - } else { - // the only ordering we care about is: - // 1) subpackages must be installed before packages that depend on them - // 2) required deps must be installed before packages that depend on them - if (isset($pdeps['required']['subpackage'])) { - $t = $pdeps['required']['subpackage']; - if (!isset($t[0])) { - $t = array($t); - } + return false; + } - $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); - } + /** + * Tells whether a given config layer exists. + * + * @param string config layer + * @return bool whether exists in this object + * + * @access public + */ + function isDefinedLayer($layer) + { + return isset($this->configuration[$layer]); + } - if (isset($pdeps['group'])) { - if (!isset($pdeps['group'][0])) { - $pdeps['group'] = array($pdeps['group']); - } + /** + * Returns the layers defined (except the 'default' one) + * + * @return array of the defined layers + */ + function getLayers() + { + $cf = $this->configuration; + unset($cf['default']); + return array_keys($cf); + } - foreach ($pdeps['group'] as $group) { - if (isset($group['subpackage'])) { - $t = $group['subpackage']; - if (!isset($t[0])) { - $t = array($t); - } + function apiVersion() + { + return '1.1'; + } - $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); - } - } - } + /** + * @return PEAR_Registry + */ + function &getRegistry($use = null) + { + $layer = $use === null ? 'user' : $use; + if (isset($this->_registry[$layer])) { + return $this->_registry[$layer]; + } elseif ($use === null && isset($this->_registry['system'])) { + return $this->_registry['system']; + } elseif ($use === null && isset($this->_registry['default'])) { + return $this->_registry['default']; + } elseif ($use) { + $a = false; + return $a; + } - if (isset($pdeps['optional']['subpackage'])) { - $t = $pdeps['optional']['subpackage']; - if (!isset($t[0])) { - $t = array($t); - } + // only go here if null was passed in + echo "CRITICAL ERROR: Registry could not be initialized from any value"; + exit(1); + } - $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); - } + /** + * This is to allow customization like the use of installroot + * @param PEAR_Registry + * @return bool + */ + function setRegistry(&$reg, $layer = 'user') + { + if ($this->_noRegistry) { + return false; + } - if (isset($pdeps['required']['package'])) { - $t = $pdeps['required']['package']; - if (!isset($t[0])) { - $t = array($t); - } + if (!in_array($layer, array('user', 'system'))) { + return false; + } - $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); - } + $this->_registry[$layer] = &$reg; + if (is_object($reg)) { + $this->_registry[$layer]->setConfig($this, false); + } - if (isset($pdeps['group'])) { - if (!isset($pdeps['group'][0])) { - $pdeps['group'] = array($pdeps['group']); - } + return true; + } - foreach ($pdeps['group'] as $group) { - if (isset($group['package'])) { - $t = $group['package']; - if (!isset($t[0])) { - $t = array($t); - } + function noRegistry() + { + $this->_noRegistry = true; + } - $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); - } - } - } - } + /** + * @return PEAR_REST + */ + function &getREST($version, $options = array()) + { + $version = str_replace('.', '', $version); + if (!class_exists($class = 'PEAR_REST_' . $version)) { + require_once 'PEAR/REST/' . $version . '.php'; } - $this->_detectDepCycle($deplinks); - foreach ($deplinks as $dependent => $parents) { - foreach ($parents as $parent => $unused) { - $nodes[$dependent]->connectTo($nodes[$parent]); - } - } + $remote = &new $class($this, $options); + return $remote; + } - $installOrder = Structures_Graph_Manipulator_TopologicalSorter::sort($depgraph); - $ret = array(); - for ($i = 0; $i < count($installOrder); $i++) { - foreach ($installOrder[$i] as $index => $sortedpackage) { - $data = &$installOrder[$i][$index]->getData(); - $ret[] = &$nodes[$reg->parsedPackageNameToString( - array( - 'channel' => $data->getChannel(), - 'package' => strtolower($data->getPackage()), - ))]->getData(); - } + /** + * The ftp server is set in {@link readFTPConfigFile()}. It exists only if a + * remote configuration file has been specified + * @return PEAR_FTP|false + */ + function &getFTP() + { + if (isset($this->_ftp)) { + return $this->_ftp; } - $packages = $ret; - return; + $a = false; + return $a; } - /** - * Detect recursive links between dependencies and break the cycles - * - * @param array - * @access private - */ - function _detectDepCycle(&$deplinks) + function _prependPath($path, $prepend) { - do { - $keepgoing = false; - foreach ($deplinks as $dep => $parents) { - foreach ($parents as $parent => $unused) { - // reset the parent cycle detector - $this->_testCycle(null, null, null); - if ($this->_testCycle($dep, $deplinks, $parent)) { - $keepgoing = true; - unset($deplinks[$dep][$parent]); - if (count($deplinks[$dep]) == 0) { - unset($deplinks[$dep]); - } - continue 3; - } + if (strlen($prepend) > 0) { + if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { + if (preg_match('/^[a-z]:/i', $prepend)) { + $prepend = substr($prepend, 2); + } elseif ($prepend{0} != '\\') { + $prepend = "\\$prepend"; } + $path = substr($path, 0, 2) . $prepend . substr($path, 2); + } else { + $path = $prepend . $path; } - } while ($keepgoing); + } + return $path; } - function _testCycle($test, $deplinks, $dep) + /** + * @param string|false installation directory to prepend to all _dir variables, or false to + * disable + */ + function setInstallRoot($root) { - static $visited = array(); - if ($test === null) { - $visited = array(); - return; - } - // this happens when a parent has a dep cycle on another dependency - // but the child is not part of the cycle - if (isset($visited[$dep])) { - return false; - } - $visited[$dep] = 1; - if ($test == $dep) { - return true; + if (substr($root, -1) == DIRECTORY_SEPARATOR) { + $root = substr($root, 0, -1); } - if (isset($deplinks[$dep])) { - if (in_array($test, array_keys($deplinks[$dep]), true)) { - return true; - } - foreach ($deplinks[$dep] as $parent => $unused) { - if ($this->_testCycle($test, $deplinks, $parent)) { - return true; + $old = $this->_installRoot; + $this->_installRoot = $root; + if (($old != $root) && !$this->_noRegistry) { + foreach (array_keys($this->_registry) as $layer) { + if ($layer == 'ftp' || !isset($this->_registry[$layer])) { + continue; } + $this->_registry[$layer] = + &new PEAR_Registry($this->get('php_dir', $layer, 'pear.php.net')); + $this->_registry[$layer]->setConfig($this, false); + $this->_regInitialized[$layer] = false; } } - return false; } +} +PEAR-1.9.0/PEAR/DependencyDB.php100664 764 764 57256 100664 11071 + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: DependencyDB.php 286686 2009-08-02 17:38:57Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Needed for error handling + */ +require_once 'PEAR.php'; +require_once 'PEAR/Config.php'; + +$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array(); +/** + * Track dependency relationships between installed packages + * @category pear + * @package PEAR + * @author Greg Beaver + * @author Tomas V.V.Cox + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_DependencyDB +{ + // {{{ properties /** - * Set up the dependency for installation parsing - * - * @param array $t dependency information - * @param PEAR_Registry $reg - * @param array $deplinks list of dependency links already established - * @param array $nodes all existing package nodes - * @param string $package parent package name + * This is initialized by {@link setConfig()} + * @var PEAR_Config * @access private */ - function _setupGraph($t, $reg, &$deplinks, &$nodes, $package) - { - foreach ($t as $dep) { - $depchannel = !isset($dep['channel']) ? '__uri': $dep['channel']; - $dname = $reg->parsedPackageNameToString( - array( - 'channel' => $depchannel, - 'package' => strtolower($dep['name']), - )); + var $_config; + /** + * This is initialized by {@link setConfig()} + * @var PEAR_Registry + * @access private + */ + var $_registry; + /** + * Filename of the dependency DB (usually .depdb) + * @var string + * @access private + */ + var $_depdb = false; + /** + * File name of the lockfile (usually .depdblock) + * @var string + * @access private + */ + var $_lockfile = false; + /** + * Open file resource for locking the lockfile + * @var resource|false + * @access private + */ + var $_lockFp = false; + /** + * API version of this class, used to validate a file on-disk + * @var string + * @access private + */ + var $_version = '1.0'; + /** + * Cached dependency database file + * @var array|null + * @access private + */ + var $_cache; - if (isset($nodes[$dname])) { - if (!isset($deplinks[$dname])) { - $deplinks[$dname] = array(); - } - $deplinks[$dname][$package] = 1; + // }}} + // {{{ & singleton() + + /** + * Get a raw dependency database. Calls setConfig() and assertDepsDB() + * @param PEAR_Config + * @param string|false full path to the dependency database, or false to use default + * @return PEAR_DependencyDB|PEAR_Error + * @static + */ + function &singleton(&$config, $depdb = false) + { + $phpdir = $config->get('php_dir', null, 'pear.php.net'); + if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir])) { + $a = new PEAR_DependencyDB; + $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir] = &$a; + $a->setConfig($config, $depdb); + $e = $a->assertDepsDB(); + if (PEAR::isError($e)) { + return $e; } } - } - function _dependsOn($a, $b) - { - return $this->_checkDepTree(strtolower($a->getChannel()), strtolower($a->getPackage()), $b); + return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir]; } - function _checkDepTree($channel, $package, $b, $checked = array()) + /** + * Set up the registry/location of dependency DB + * @param PEAR_Config|false + * @param string|false full path to the dependency database, or false to use default + */ + function setConfig(&$config, $depdb = false) { - $checked[$channel][$package] = true; - if (!isset($this->_depTree[$channel][$package])) { - return false; + if (!$config) { + $this->_config = &PEAR_Config::singleton(); + } else { + $this->_config = &$config; } - if (isset($this->_depTree[$channel][$package][strtolower($b->getChannel())] - [strtolower($b->getPackage())])) { - return true; + $this->_registry = &$this->_config->getRegistry(); + if (!$depdb) { + $this->_depdb = $this->_config->get('php_dir', null, 'pear.php.net') . + DIRECTORY_SEPARATOR . '.depdb'; + } else { + $this->_depdb = $depdb; } - foreach ($this->_depTree[$channel][$package] as $ch => $packages) { - foreach ($packages as $pa => $true) { - if ($this->_checkDepTree($ch, $pa, $b, $checked)) { - return true; + $this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock'; + } + // }}} + + function hasWriteAccess() + { + if (!file_exists($this->_depdb)) { + $dir = $this->_depdb; + while ($dir && $dir != '.') { + $dir = dirname($dir); // cd .. + if ($dir != '.' && file_exists($dir)) { + if (is_writeable($dir)) { + return true; + } + + return false; } } + + return false; } - return false; + return is_writeable($this->_depdb); } - function _sortInstall($a, $b) + // {{{ assertDepsDB() + + /** + * Create the dependency database, if it doesn't exist. Error if the database is + * newer than the code reading it. + * @return void|PEAR_Error + */ + function assertDepsDB() { - if (!$a->getDeps() && !$b->getDeps()) { - return 0; // neither package has dependencies, order is insignificant + if (!is_file($this->_depdb)) { + $this->rebuildDB(); + return; } - if ($a->getDeps() && !$b->getDeps()) { - return 1; // $a must be installed after $b because $a has dependencies + + $depdb = $this->_getDepDB(); + // Datatype format has been changed, rebuild the Deps DB + if ($depdb['_version'] < $this->_version) { + $this->rebuildDB(); } - if (!$a->getDeps() && $b->getDeps()) { - return -1; // $b must be installed after $a because $b has dependencies + + if ($depdb['_version']{0} > $this->_version{0}) { + return PEAR::raiseError('Dependency database is version ' . + $depdb['_version'] . ', and we are version ' . + $this->_version . ', cannot continue'); } - // both packages have dependencies - if ($this->_dependsOn($a, $b)) { - return 1; + } + + /** + * Get a list of installed packages that depend on this package + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array + * @return array|false + */ + function getDependentPackages(&$pkg) + { + $data = $this->_getDepDB(); + if (is_object($pkg)) { + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + } else { + $channel = strtolower($pkg['channel']); + $package = strtolower($pkg['package']); } - if ($this->_dependsOn($b, $a)) { - return -1; + + if (isset($data['packages'][$channel][$package])) { + return $data['packages'][$channel][$package]; } - return 0; + + return false; } /** - * Download a file through HTTP. Considers suggested file name in - * Content-disposition: header and can run a callback function for - * different events. The callback will be called with two - * parameters: the callback type, and parameters. The implemented - * callback types are: - * - * 'setup' called at the very beginning, parameter is a UI object - * that should be used for all output - * 'message' the parameter is a string with an informational message - * 'saveas' may be used to save with a different file name, the - * parameter is the filename that is about to be used. - * If a 'saveas' callback returns a non-empty string, - * that file name will be used as the filename instead. - * Note that $save_dir will not be affected by this, only - * the basename of the file. - * 'start' download is starting, parameter is number of bytes - * that are expected, or -1 if unknown - * 'bytesread' parameter is the number of bytes read so far - * 'done' download is complete, parameter is the total number - * of bytes read - * 'connfailed' if the TCP/SSL connection fails, this callback is called - * with array(host,port,errno,errmsg) - * 'writefailed' if writing to disk fails, this callback is called - * with array(destfile,errmsg) - * - * If an HTTP proxy has been configured (http_proxy PEAR_Config - * setting), the proxy will be used. - * - * @param string $url the URL to download - * @param object $ui PEAR_Frontend_* instance - * @param object $config PEAR_Config instance - * @param string $save_dir directory to save file in - * @param mixed $callback function/method to call for status - * updates - * @param false|string|array $lastmodified header values to check against for caching - * use false to return the header values from this download - * @param false|array $accept Accept headers to send - * @param false|string $channel Channel to use for retrieving authentication - * @return string|array Returns the full path of the downloaded file or a PEAR - * error on failure. If the error is caused by - * socket-related errors, the error object will - * have the fsockopen error code available through - * getCode(). If caching is requested, then return the header - * values. - * - * @access public + * Get a list of the actual dependencies of installed packages that depend on + * a package. + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array + * @return array|false */ - function downloadHttp($url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null, - $accept = false, $channel = false) + function getDependentPackageDependencies(&$pkg) { - static $redirect = 0; - // always reset , so we are clean case of error - $wasredirect = $redirect; - $redirect = 0; - if ($callback) { - call_user_func($callback, 'setup', array(&$ui)); + $data = $this->_getDepDB(); + if (is_object($pkg)) { + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + } else { + $channel = strtolower($pkg['channel']); + $package = strtolower($pkg['package']); } - $info = parse_url($url); - if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) { - return PEAR::raiseError('Cannot download non-http URL "' . $url . '"'); + $depend = $this->getDependentPackages($pkg); + if (!$depend) { + return false; } - if (!isset($info['host'])) { - return PEAR::raiseError('Cannot download from non-URL "' . $url . '"'); + $dependencies = array(); + foreach ($depend as $info) { + $temp = $this->getDependencies($info); + foreach ($temp as $dep) { + if ( + isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) && + strtolower($dep['dep']['channel']) == $channel && + strtolower($dep['dep']['name']) == $package + ) { + if (!isset($dependencies[$info['channel']])) { + $dependencies[$info['channel']] = array(); + } + + if (!isset($dependencies[$info['channel']][$info['package']])) { + $dependencies[$info['channel']][$info['package']] = array(); + } + $dependencies[$info['channel']][$info['package']][] = $dep; + } + } } - $host = isset($info['host']) ? $info['host'] : null; - $port = isset($info['port']) ? $info['port'] : null; - $path = isset($info['path']) ? $info['path'] : null; + return $dependencies; + } - if (isset($this)) { - $config = &$this->config; + /** + * Get a list of dependencies of this installed package + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array + * @return array|false + */ + function getDependencies(&$pkg) + { + if (is_object($pkg)) { + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); } else { - $config = &PEAR_Config::singleton(); + $channel = strtolower($pkg['channel']); + $package = strtolower($pkg['package']); } - $proxy_host = $proxy_port = $proxy_user = $proxy_pass = ''; - if ($config->get('http_proxy') && - $proxy = parse_url($config->get('http_proxy'))) { - $proxy_host = isset($proxy['host']) ? $proxy['host'] : null; - if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') { - $proxy_host = 'ssl://' . $proxy_host; - } - $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080; - $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null; - $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null; + $data = $this->_getDepDB(); + if (isset($data['dependencies'][$channel][$package])) { + return $data['dependencies'][$channel][$package]; + } - if ($callback) { - call_user_func($callback, 'message', "Using HTTP proxy $host:$port"); - } + return false; + } + + /** + * Determine whether $parent depends on $child, near or deep + * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2 + * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2 + */ + function dependsOn($parent, $child) + { + $c = array(); + $this->_getDepDB(); + return $this->_dependsOn($parent, $child, $c); + } + + function _dependsOn($parent, $child, &$checked) + { + if (is_object($parent)) { + $channel = strtolower($parent->getChannel()); + $package = strtolower($parent->getPackage()); + } else { + $channel = strtolower($parent['channel']); + $package = strtolower($parent['package']); } - if (empty($port)) { - $port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80; + if (is_object($child)) { + $depchannel = strtolower($child->getChannel()); + $deppackage = strtolower($child->getPackage()); + } else { + $depchannel = strtolower($child['channel']); + $deppackage = strtolower($child['package']); } - $scheme = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http'; + if (isset($checked[$channel][$package][$depchannel][$deppackage])) { + return false; // avoid endless recursion + } - if ($proxy_host != '') { - $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr); - if (!$fp) { - if ($callback) { - call_user_func($callback, 'connfailed', array($proxy_host, $proxy_port, - $errno, $errstr)); + $checked[$channel][$package][$depchannel][$deppackage] = true; + if (!isset($this->_cache['dependencies'][$channel][$package])) { + return false; + } + + foreach ($this->_cache['dependencies'][$channel][$package] as $info) { + if (isset($info['dep']['uri'])) { + if (is_object($child)) { + if ($info['dep']['uri'] == $child->getURI()) { + return true; + } + } elseif (isset($child['uri'])) { + if ($info['dep']['uri'] == $child['uri']) { + return true; + } } - return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", $errno); + return false; } - if ($lastmodified === false || $lastmodified) { - $request = "GET $url HTTP/1.1\r\n"; - $request .= "Host: $host:$port\r\n"; - } else { - $request = "GET $url HTTP/1.0\r\n"; - $request .= "Host: $host\r\n"; - } - } else { - $network_host = $host; - if (isset($info['scheme']) && $info['scheme'] == 'https') { - $network_host = 'ssl://' . $host; + if (strtolower($info['dep']['channel']) == $depchannel && + strtolower($info['dep']['name']) == $deppackage) { + return true; } + } - $fp = @fsockopen($network_host, $port, $errno, $errstr); - if (!$fp) { - if ($callback) { - call_user_func($callback, 'connfailed', array($host, $port, - $errno, $errstr)); + foreach ($this->_cache['dependencies'][$channel][$package] as $info) { + if (isset($info['dep']['uri'])) { + if ($this->_dependsOn(array( + 'uri' => $info['dep']['uri'], + 'package' => $info['dep']['name']), $child, $checked)) { + return true; } - return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); - } - - if ($lastmodified === false || $lastmodified) { - $request = "GET $path HTTP/1.1\r\n"; - $request .= "Host: $host:$port\r\n"; } else { - $request = "GET $path HTTP/1.0\r\n"; - $request .= "Host: $host\r\n"; + if ($this->_dependsOn(array( + 'channel' => $info['dep']['channel'], + 'package' => $info['dep']['name']), $child, $checked)) { + return true; + } } } - $ifmodifiedsince = ''; - if (is_array($lastmodified)) { - if (isset($lastmodified['Last-Modified'])) { - $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n"; - } + return false; + } - if (isset($lastmodified['ETag'])) { - $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n"; - } + /** + * Register dependencies of a package that is being installed or upgraded + * @param PEAR_PackageFile_v2|PEAR_PackageFile_v2 + */ + function installPackage(&$package) + { + $data = $this->_getDepDB(); + unset($this->_cache); + $this->_setPackageDeps($data, $package); + $this->_writeDepDB($data); + } + + /** + * Remove dependencies of a package that is being uninstalled, or upgraded. + * + * Upgraded packages first uninstall, then install + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have + * indices 'channel' and 'package' + */ + function uninstallPackage(&$pkg) + { + $data = $this->_getDepDB(); + unset($this->_cache); + if (is_object($pkg)) { + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); } else { - $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : ''); + $channel = strtolower($pkg['channel']); + $package = strtolower($pkg['package']); } - $request .= $ifmodifiedsince . - "User-Agent: PEAR/1.8.0/PHP/" . PHP_VERSION . "\r\n"; + if (!isset($data['dependencies'][$channel][$package])) { + return true; + } - if (isset($this)) { // only pass in authentication for non-static calls - $username = $config->get('username', null, $channel); - $password = $config->get('password', null, $channel); - if ($username && $password) { - $tmp = base64_encode("$username:$password"); - $request .= "Authorization: Basic $tmp\r\n"; + foreach ($data['dependencies'][$channel][$package] as $dep) { + $found = false; + $depchannel = isset($dep['dep']['uri']) ? '__uri' : strtolower($dep['dep']['channel']); + $depname = strtolower($dep['dep']['name']); + if (isset($data['packages'][$depchannel][$depname])) { + foreach ($data['packages'][$depchannel][$depname] as $i => $info) { + if ($info['channel'] == $channel && $info['package'] == $package) { + $found = true; + break; + } + } + } + + if ($found) { + unset($data['packages'][$depchannel][$depname][$i]); + if (!count($data['packages'][$depchannel][$depname])) { + unset($data['packages'][$depchannel][$depname]); + if (!count($data['packages'][$depchannel])) { + unset($data['packages'][$depchannel]); + } + } else { + $data['packages'][$depchannel][$depname] = + array_values($data['packages'][$depchannel][$depname]); + } } } - if ($proxy_host != '' && $proxy_user != '') { - $request .= 'Proxy-Authorization: Basic ' . - base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n"; + unset($data['dependencies'][$channel][$package]); + if (!count($data['dependencies'][$channel])) { + unset($data['dependencies'][$channel]); } - if ($accept) { - $request .= 'Accept: ' . implode(', ', $accept) . "\r\n"; + if (!count($data['dependencies'])) { + unset($data['dependencies']); } - $request .= "Connection: close\r\n"; - $request .= "\r\n"; - fwrite($fp, $request); - $headers = array(); - $reply = 0; - while (trim($line = fgets($fp, 1024))) { - if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) { - $headers[strtolower($matches[1])] = trim($matches[2]); - } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { - $reply = (int)$matches[1]; - if ($reply == 304 && ($lastmodified || ($lastmodified === false))) { - return false; - } + if (!count($data['packages'])) { + unset($data['packages']); + } - if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) { - return PEAR::raiseError("File $scheme://$host:$port$path not valid (received: $line)"); + $this->_writeDepDB($data); + } + + /** + * Rebuild the dependency DB by reading registry entries. + * @return true|PEAR_Error + */ + function rebuildDB() + { + $depdb = array('_version' => $this->_version); + if (!$this->hasWriteAccess()) { + // allow startup for read-only with older Registry + return $depdb; + } + + $packages = $this->_registry->listAllPackages(); + if (PEAR::isError($packages)) { + return $packages; + } + + foreach ($packages as $channel => $ps) { + foreach ($ps as $package) { + $package = $this->_registry->getPackage($package, $channel); + if (PEAR::isError($package)) { + return $package; } + $this->_setPackageDeps($depdb, $package); } } - if ($reply != 200) { - if (!isset($headers['location'])) { - return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirected but no location)"); - } + $error = $this->_writeDepDB($depdb); + if (PEAR::isError($error)) { + return $error; + } - if ($wasredirect > 4) { - return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirection looped more than 5 times)"); - } + $this->_cache = $depdb; + return true; + } - $redirect = $wasredirect + 1; - return $this->downloadHttp($headers['location'], - $ui, $save_dir, $callback, $lastmodified, $accept); + /** + * Register usage of the dependency DB to prevent race conditions + * @param int one of the LOCK_* constants + * @return true|PEAR_Error + * @access private + */ + function _lock($mode = LOCK_EX) + { + if (stristr(php_uname(), 'Windows 9')) { + return true; } - if (isset($headers['content-disposition']) && - preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|\\z)/', $headers['content-disposition'], $matches)) { - $save_as = basename($matches[1]); - } else { - $save_as = basename($url); + if ($mode != LOCK_UN && is_resource($this->_lockFp)) { + // XXX does not check type of lock (LOCK_SH/LOCK_EX) + return true; } - if ($callback) { - $tmp = call_user_func($callback, 'saveas', $save_as); - if ($tmp) { - $save_as = $tmp; + $open_mode = 'w'; + // XXX People reported problems with LOCK_SH and 'w' + if ($mode === LOCK_SH) { + if (!file_exists($this->_lockfile)) { + touch($this->_lockfile); + } elseif (!is_file($this->_lockfile)) { + return PEAR::raiseError('could not create Dependency lock file, ' . + 'it exists and is not a regular file'); } + $open_mode = 'r'; } - $dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as; - if (!$wp = @fopen($dest_file, 'wb')) { - fclose($fp); - if ($callback) { - call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); + if (!is_resource($this->_lockFp)) { + $this->_lockFp = @fopen($this->_lockfile, $open_mode); + } + + if (!is_resource($this->_lockFp)) { + return PEAR::raiseError("could not create Dependency lock file" . + (isset($php_errormsg) ? ": " . $php_errormsg : "")); + } + + if (!(int)flock($this->_lockFp, $mode)) { + switch ($mode) { + case LOCK_SH: $str = 'shared'; break; + case LOCK_EX: $str = 'exclusive'; break; + case LOCK_UN: $str = 'unlock'; break; + default: $str = 'unknown'; break; } - return PEAR::raiseError("could not open $dest_file for writing"); + + return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)"); } - $length = isset($headers['content-length']) ? $headers['content-length'] : -1; + return true; + } - $bytes = 0; - if ($callback) { - call_user_func($callback, 'start', array(basename($dest_file), $length)); + /** + * Release usage of dependency DB + * @return true|PEAR_Error + * @access private + */ + function _unlock() + { + $ret = $this->_lock(LOCK_UN); + if (is_resource($this->_lockFp)) { + fclose($this->_lockFp); + } + $this->_lockFp = null; + return $ret; + } + + /** + * Load the dependency database from disk, or return the cache + * @return array|PEAR_Error + */ + function _getDepDB() + { + if (!$this->hasWriteAccess()) { + return array('_version' => $this->_version); } - while ($data = fread($fp, 1024)) { - $bytes += strlen($data); - if ($callback) { - call_user_func($callback, 'bytesread', $bytes); - } - if (!@fwrite($wp, $data)) { - fclose($fp); - if ($callback) { - call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); - } - return PEAR::raiseError("$dest_file: write failed ($php_errormsg)"); - } + if (isset($this->_cache)) { + return $this->_cache; + } + + if (!$fp = fopen($this->_depdb, 'r')) { + $err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'"); + return $err; } + + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + clearstatcache(); fclose($fp); - fclose($wp); - if ($callback) { - call_user_func($callback, 'done', $bytes); + $data = unserialize(file_get_contents($this->_depdb)); + set_magic_quotes_runtime($rt); + $this->_cache = $data; + return $data; + } + + /** + * Write out the dependency database to disk + * @param array the database + * @return true|PEAR_Error + * @access private + */ + function _writeDepDB(&$deps) + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; } - if ($lastmodified === false || $lastmodified) { - if (isset($headers['etag'])) { - $lastmodified = array('ETag' => $headers['etag']); - } - if (isset($headers['last-modified'])) { - if (is_array($lastmodified)) { - $lastmodified['Last-Modified'] = $headers['last-modified']; - } else { - $lastmodified = $headers['last-modified']; - } - } - return array($dest_file, $lastmodified, $headers); + if (!$fp = fopen($this->_depdb, 'wb')) { + $this->_unlock(); + return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing"); } - return $dest_file; + + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + fwrite($fp, serialize($deps)); + set_magic_quotes_runtime($rt); + fclose($fp); + $this->_unlock(); + $this->_cache = $deps; + return true; } -} -// }}}PEAR-1.8.0/PEAR/ErrorStack.php100664 764 764 104210 100664 10662 - * @copyright 2004-2008 Greg Beaver - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: ErrorStack.php,v 1.29 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR_ErrorStack - */ - -/** - * Singleton storage - * - * Format: - *
    - * array(
    - *  'package1' => PEAR_ErrorStack object,
    - *  'package2' => PEAR_ErrorStack object,
    - *  ...
    - * )
    - * 
    - * @access private - * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] - */ -$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array(); - -/** - * Global error callback (default) - * - * This is only used if set to non-false. * is the default callback for - * all packages, whereas specific packages may set a default callback - * for all instances, regardless of whether they are a singleton or not. - * - * To exclude non-singletons, only set the local callback for the singleton - * @see PEAR_ErrorStack::setDefaultCallback() - * @access private - * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] - */ -$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array( - '*' => false, -); - -/** - * Global Log object (default) - * - * This is only used if set to non-false. Use to set a default log object for - * all stacks, regardless of instantiation order or location - * @see PEAR_ErrorStack::setDefaultLogger() - * @access private - * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] - */ -$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false; - -/** - * Global Overriding Callback - * - * This callback will override any error callbacks that specific loggers have set. - * Use with EXTREME caution - * @see PEAR_ErrorStack::staticPushCallback() - * @access private - * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] - */ -$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); - -/**#@+ - * One of four possible return values from the error Callback - * @see PEAR_ErrorStack::_errorCallback() - */ -/** - * If this is returned, then the error will be both pushed onto the stack - * and logged. - */ -define('PEAR_ERRORSTACK_PUSHANDLOG', 1); -/** - * If this is returned, then the error will only be pushed onto the stack, - * and not logged. - */ -define('PEAR_ERRORSTACK_PUSH', 2); -/** - * If this is returned, then the error will only be logged, but not pushed - * onto the error stack. - */ -define('PEAR_ERRORSTACK_LOG', 3); -/** - * If this is returned, then the error is completely ignored. - */ -define('PEAR_ERRORSTACK_IGNORE', 4); -/** - * If this is returned, then the error is logged and die() is called. - */ -define('PEAR_ERRORSTACK_DIE', 5); -/**#@-*/ - -/** - * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in - * the singleton method. - */ -define('PEAR_ERRORSTACK_ERR_NONCLASS', 1); - -/** - * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()} - * that has no __toString() method - */ -define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2); -/** - * Error Stack Implementation - * - * Usage: - * - * // global error stack - * $global_stack = &PEAR_ErrorStack::singleton('MyPackage'); - * // local error stack - * $local_stack = new PEAR_ErrorStack('MyPackage'); - * - * @author Greg Beaver - * @version 1.8.0 - * @package PEAR_ErrorStack - * @category Debugging - * @copyright 2004-2008 Greg Beaver - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: ErrorStack.php,v 1.29 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR_ErrorStack - */ -class PEAR_ErrorStack { - /** - * Errors are stored in the order that they are pushed on the stack. - * @since 0.4alpha Errors are no longer organized by error level. - * This renders pop() nearly unusable, and levels could be more easily - * handled in a callback anyway - * @var array - * @access private - */ - var $_errors = array(); - - /** - * Storage of errors by level. - * - * Allows easy retrieval and deletion of only errors from a particular level - * @since PEAR 1.4.0dev - * @var array - * @access private - */ - var $_errorsByLevel = array(); - - /** - * Package name this error stack represents - * @var string - * @access protected - */ - var $_package; - - /** - * Determines whether a PEAR_Error is thrown upon every error addition - * @var boolean - * @access private - */ - var $_compat = false; - - /** - * If set to a valid callback, this will be used to generate the error - * message from the error code, otherwise the message passed in will be - * used - * @var false|string|array - * @access private - */ - var $_msgCallback = false; - - /** - * If set to a valid callback, this will be used to generate the error - * context for an error. For PHP-related errors, this will be a file - * and line number as retrieved from debug_backtrace(), but can be - * customized for other purposes. The error might actually be in a separate - * configuration file, or in a database query. - * @var false|string|array - * @access protected - */ - var $_contextCallback = false; - - /** - * If set to a valid callback, this will be called every time an error - * is pushed onto the stack. The return value will be used to determine - * whether to allow an error to be pushed or logged. - * - * The return value must be one an PEAR_ERRORSTACK_* constant - * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG - * @var false|string|array - * @access protected - */ - var $_errorCallback = array(); - - /** - * PEAR::Log object for logging errors - * @var false|Log - * @access protected - */ - var $_logger = false; - - /** - * Error messages - designed to be overridden - * @var array - * @abstract - */ - var $_errorMsgs = array(); - - /** - * Set up a new error stack - * - * @param string $package name of the package this error stack represents - * @param callback $msgCallback callback used for error message generation - * @param callback $contextCallback callback used for context generation, - * defaults to {@link getFileLine()} - * @param boolean $throwPEAR_Error - */ - function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false, - $throwPEAR_Error = false) - { - $this->_package = $package; - $this->setMessageCallback($msgCallback); - $this->setContextCallback($contextCallback); - $this->_compat = $throwPEAR_Error; - } - - /** - * Return a single error stack for this package. - * - * Note that all parameters are ignored if the stack for package $package - * has already been instantiated - * @param string $package name of the package this error stack represents - * @param callback $msgCallback callback used for error message generation - * @param callback $contextCallback callback used for context generation, - * defaults to {@link getFileLine()} - * @param boolean $throwPEAR_Error - * @param string $stackClass class to instantiate - * @static - * @return PEAR_ErrorStack - */ - function &singleton($package, $msgCallback = false, $contextCallback = false, - $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack') - { - if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { - return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; - } - if (!class_exists($stackClass)) { - if (function_exists('debug_backtrace')) { - $trace = debug_backtrace(); - } - PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS, - 'exception', array('stackclass' => $stackClass), - 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)', - false, $trace); - } - $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] = - new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error); - - return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; - } - - /** - * Internal error handler for PEAR_ErrorStack class - * - * Dies if the error is an exception (and would have died anyway) - * @access private - */ - function _handleError($err) - { - if ($err['level'] == 'exception') { - $message = $err['message']; - if (isset($_SERVER['REQUEST_URI'])) { - echo '
    '; - } else { - echo "\n"; - } - var_dump($err['context']); - die($message); - } - } - - /** - * Set up a PEAR::Log object for all error stacks that don't have one - * @param Log $log - * @static - */ - function setDefaultLogger(&$log) - { - if (is_object($log) && method_exists($log, 'log') ) { - $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; - } elseif (is_callable($log)) { - $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; - } - } - - /** - * Set up a PEAR::Log object for this error stack - * @param Log $log - */ - function setLogger(&$log) - { - if (is_object($log) && method_exists($log, 'log') ) { - $this->_logger = &$log; - } elseif (is_callable($log)) { - $this->_logger = &$log; - } - } - - /** - * Set an error code => error message mapping callback - * - * This method sets the callback that can be used to generate error - * messages for any instance - * @param array|string Callback function/method - */ - function setMessageCallback($msgCallback) - { - if (!$msgCallback) { - $this->_msgCallback = array(&$this, 'getErrorMessage'); - } else { - if (is_callable($msgCallback)) { - $this->_msgCallback = $msgCallback; - } - } - } - - /** - * Get an error code => error message mapping callback - * - * This method returns the current callback that can be used to generate error - * messages - * @return array|string|false Callback function/method or false if none - */ - function getMessageCallback() - { - return $this->_msgCallback; - } - - /** - * Sets a default callback to be used by all error stacks - * - * This method sets the callback that can be used to generate error - * messages for a singleton - * @param array|string Callback function/method - * @param string Package name, or false for all packages - * @static - */ - function setDefaultCallback($callback = false, $package = false) - { - if (!is_callable($callback)) { - $callback = false; - } - $package = $package ? $package : '*'; - $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback; - } - - /** - * Set a callback that generates context information (location of error) for an error stack - * - * This method sets the callback that can be used to generate context - * information for an error. Passing in NULL will disable context generation - * and remove the expensive call to debug_backtrace() - * @param array|string|null Callback function/method - */ - function setContextCallback($contextCallback) - { - if ($contextCallback === null) { - return $this->_contextCallback = false; - } - if (!$contextCallback) { - $this->_contextCallback = array(&$this, 'getFileLine'); - } else { - if (is_callable($contextCallback)) { - $this->_contextCallback = $contextCallback; - } - } - } - - /** - * Set an error Callback - * If set to a valid callback, this will be called every time an error - * is pushed onto the stack. The return value will be used to determine - * whether to allow an error to be pushed or logged. - * - * The return value must be one of the ERRORSTACK_* constants. - * - * This functionality can be used to emulate PEAR's pushErrorHandling, and - * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of - * the error stack or logging - * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG - * @see popCallback() - * @param string|array $cb - */ - function pushCallback($cb) - { - array_push($this->_errorCallback, $cb); - } - - /** - * Remove a callback from the error callback stack - * @see pushCallback() - * @return array|string|false - */ - function popCallback() - { - if (!count($this->_errorCallback)) { - return false; - } - return array_pop($this->_errorCallback); - } - - /** - * Set a temporary overriding error callback for every package error stack - * - * Use this to temporarily disable all existing callbacks (can be used - * to emulate the @ operator, for instance) - * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG - * @see staticPopCallback(), pushCallback() - * @param string|array $cb - * @static - */ - function staticPushCallback($cb) - { - array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb); - } - - /** - * Remove a temporary overriding error callback - * @see staticPushCallback() - * @return array|string|false - * @static - */ - function staticPopCallback() - { - $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']); - if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) { - $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); - } - return $ret; - } - - /** - * Add an error to the stack - * - * If the message generator exists, it is called with 2 parameters. - * - the current Error Stack object - * - an array that is in the same format as an error. Available indices - * are 'code', 'package', 'time', 'params', 'level', and 'context' - * - * Next, if the error should contain context information, this is - * handled by the context grabbing method. - * Finally, the error is pushed onto the proper error stack - * @param int $code Package-specific error code - * @param string $level Error level. This is NOT spell-checked - * @param array $params associative array of error parameters - * @param string $msg Error message, or a portion of it if the message - * is to be generated - * @param array $repackage If this error re-packages an error pushed by - * another package, place the array returned from - * {@link pop()} in this parameter - * @param array $backtrace Protected parameter: use this to pass in the - * {@link debug_backtrace()} that should be used - * to find error context - * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also - * thrown. If a PEAR_Error is returned, the userinfo - * property is set to the following array: - * - * - * array( - * 'code' => $code, - * 'params' => $params, - * 'package' => $this->_package, - * 'level' => $level, - * 'time' => time(), - * 'context' => $context, - * 'message' => $msg, - * //['repackage' => $err] repackaged error array/Exception class - * ); - * - * - * Normally, the previous array is returned. - */ - function push($code, $level = 'error', $params = array(), $msg = false, - $repackage = false, $backtrace = false) - { - $context = false; - // grab error context - if ($this->_contextCallback) { - if (!$backtrace) { - $backtrace = debug_backtrace(); - } - $context = call_user_func($this->_contextCallback, $code, $params, $backtrace); - } - - // save error - $time = explode(' ', microtime()); - $time = $time[1] + $time[0]; - $err = array( - 'code' => $code, - 'params' => $params, - 'package' => $this->_package, - 'level' => $level, - 'time' => $time, - 'context' => $context, - 'message' => $msg, - ); - - if ($repackage) { - $err['repackage'] = $repackage; - } - - // set up the error message, if necessary - if ($this->_msgCallback) { - $msg = call_user_func_array($this->_msgCallback, - array(&$this, $err)); - $err['message'] = $msg; - } - $push = $log = true; - $die = false; - // try the overriding callback first - $callback = $this->staticPopCallback(); - if ($callback) { - $this->staticPushCallback($callback); - } - if (!is_callable($callback)) { - // try the local callback next - $callback = $this->popCallback(); - if (is_callable($callback)) { - $this->pushCallback($callback); - } else { - // try the default callback - $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ? - $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] : - $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*']; - } - } - if (is_callable($callback)) { - switch(call_user_func($callback, $err)){ - case PEAR_ERRORSTACK_IGNORE: - return $err; - break; - case PEAR_ERRORSTACK_PUSH: - $log = false; - break; - case PEAR_ERRORSTACK_LOG: - $push = false; - break; - case PEAR_ERRORSTACK_DIE: - $die = true; - break; - // anything else returned has the same effect as pushandlog - } - } - if ($push) { - array_unshift($this->_errors, $err); - if (!isset($this->_errorsByLevel[$err['level']])) { - $this->_errorsByLevel[$err['level']] = array(); - } - $this->_errorsByLevel[$err['level']][] = &$this->_errors[0]; - } - if ($log) { - if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) { - $this->_log($err); - } - } - if ($die) { - die(); - } - if ($this->_compat && $push) { - return $this->raiseError($msg, $code, null, null, $err); - } - return $err; - } - - /** - * Static version of {@link push()} - * - * @param string $package Package name this error belongs to - * @param int $code Package-specific error code - * @param string $level Error level. This is NOT spell-checked - * @param array $params associative array of error parameters - * @param string $msg Error message, or a portion of it if the message - * is to be generated - * @param array $repackage If this error re-packages an error pushed by - * another package, place the array returned from - * {@link pop()} in this parameter - * @param array $backtrace Protected parameter: use this to pass in the - * {@link debug_backtrace()} that should be used - * to find error context - * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also - * thrown. see docs for {@link push()} - * @static - */ - function staticPush($package, $code, $level = 'error', $params = array(), - $msg = false, $repackage = false, $backtrace = false) - { - $s = &PEAR_ErrorStack::singleton($package); - if ($s->_contextCallback) { - if (!$backtrace) { - if (function_exists('debug_backtrace')) { - $backtrace = debug_backtrace(); - } - } - } - return $s->push($code, $level, $params, $msg, $repackage, $backtrace); - } - - /** - * Log an error using PEAR::Log - * @param array $err Error array - * @param array $levels Error level => Log constant map - * @access protected - */ - function _log($err) - { - if ($this->_logger) { - $logger = &$this->_logger; - } else { - $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']; - } - if (is_a($logger, 'Log')) { - $levels = array( - 'exception' => PEAR_LOG_CRIT, - 'alert' => PEAR_LOG_ALERT, - 'critical' => PEAR_LOG_CRIT, - 'error' => PEAR_LOG_ERR, - 'warning' => PEAR_LOG_WARNING, - 'notice' => PEAR_LOG_NOTICE, - 'info' => PEAR_LOG_INFO, - 'debug' => PEAR_LOG_DEBUG); - if (isset($levels[$err['level']])) { - $level = $levels[$err['level']]; - } else { - $level = PEAR_LOG_INFO; - } - $logger->log($err['message'], $level, $err); - } else { // support non-standard logs - call_user_func($logger, $err); - } - } - - - /** - * Pop an error off of the error stack - * - * @return false|array - * @since 0.4alpha it is no longer possible to specify a specific error - * level to return - the last error pushed will be returned, instead - */ - function pop() - { - $err = @array_shift($this->_errors); - if (!is_null($err)) { - @array_pop($this->_errorsByLevel[$err['level']]); - if (!count($this->_errorsByLevel[$err['level']])) { - unset($this->_errorsByLevel[$err['level']]); - } - } - return $err; - } - - /** - * Pop an error off of the error stack, static method - * - * @param string package name - * @return boolean - * @since PEAR1.5.0a1 - */ - function staticPop($package) - { - if ($package) { - if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { - return false; - } - return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop(); - } - } - - /** - * Determine whether there are any errors on the stack - * @param string|array Level name. Use to determine if any errors - * of level (string), or levels (array) have been pushed - * @return boolean - */ - function hasErrors($level = false) - { - if ($level) { - return isset($this->_errorsByLevel[$level]); - } - return count($this->_errors); - } - - /** - * Retrieve all errors since last purge - * - * @param boolean set in order to empty the error stack - * @param string level name, to return only errors of a particular severity - * @return array - */ - function getErrors($purge = false, $level = false) - { - if (!$purge) { - if ($level) { - if (!isset($this->_errorsByLevel[$level])) { - return array(); - } else { - return $this->_errorsByLevel[$level]; - } - } else { - return $this->_errors; - } - } - if ($level) { - $ret = $this->_errorsByLevel[$level]; - foreach ($this->_errorsByLevel[$level] as $i => $unused) { - // entries are references to the $_errors array - $this->_errorsByLevel[$level][$i] = false; - } - // array_filter removes all entries === false - $this->_errors = array_filter($this->_errors); - unset($this->_errorsByLevel[$level]); - return $ret; - } - $ret = $this->_errors; - $this->_errors = array(); - $this->_errorsByLevel = array(); - return $ret; - } - - /** - * Determine whether there are any errors on a single error stack, or on any error stack - * - * The optional parameter can be used to test the existence of any errors without the need of - * singleton instantiation - * @param string|false Package name to check for errors - * @param string Level name to check for a particular severity - * @return boolean - * @static - */ - function staticHasErrors($package = false, $level = false) - { - if ($package) { - if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { - return false; - } - return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level); - } - foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { - if ($obj->hasErrors($level)) { - return true; - } - } - return false; - } - - /** - * Get a list of all errors since last purge, organized by package - * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be - * @param boolean $purge Set to purge the error stack of existing errors - * @param string $level Set to a level name in order to retrieve only errors of a particular level - * @param boolean $merge Set to return a flat array, not organized by package - * @param array $sortfunc Function used to sort a merged array - default - * sorts by time, and should be good for most cases - * @static - * @return array - */ - function staticGetErrors($purge = false, $level = false, $merge = false, - $sortfunc = array('PEAR_ErrorStack', '_sortErrors')) - { - $ret = array(); - if (!is_callable($sortfunc)) { - $sortfunc = array('PEAR_ErrorStack', '_sortErrors'); - } - foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { - $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level); - if ($test) { - if ($merge) { - $ret = array_merge($ret, $test); - } else { - $ret[$package] = $test; - } - } - } - if ($merge) { - usort($ret, $sortfunc); - } - return $ret; - } - - /** - * Error sorting function, sorts by time - * @access private - */ - function _sortErrors($a, $b) - { - if ($a['time'] == $b['time']) { - return 0; - } - if ($a['time'] < $b['time']) { - return 1; - } - return -1; - } - - /** - * Standard file/line number/function/class context callback - * - * This function uses a backtrace generated from {@link debug_backtrace()} - * and so will not work at all in PHP < 4.3.0. The frame should - * reference the frame that contains the source of the error. - * @return array|false either array('file' => file, 'line' => line, - * 'function' => function name, 'class' => class name) or - * if this doesn't work, then false - * @param unused - * @param integer backtrace frame. - * @param array Results of debug_backtrace() - * @static - */ - function getFileLine($code, $params, $backtrace = null) - { - if ($backtrace === null) { - return false; - } - $frame = 0; - $functionframe = 1; - if (!isset($backtrace[1])) { - $functionframe = 0; - } else { - while (isset($backtrace[$functionframe]['function']) && - $backtrace[$functionframe]['function'] == 'eval' && - isset($backtrace[$functionframe + 1])) { - $functionframe++; - } - } - if (isset($backtrace[$frame])) { - if (!isset($backtrace[$frame]['file'])) { - $frame++; - } - $funcbacktrace = $backtrace[$functionframe]; - $filebacktrace = $backtrace[$frame]; - $ret = array('file' => $filebacktrace['file'], - 'line' => $filebacktrace['line']); - // rearrange for eval'd code or create function errors - if (strpos($filebacktrace['file'], '(') && - preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'], - $matches)) { - $ret['file'] = $matches[1]; - $ret['line'] = $matches[2] + 0; - } - if (isset($funcbacktrace['function']) && isset($backtrace[1])) { - if ($funcbacktrace['function'] != 'eval') { - if ($funcbacktrace['function'] == '__lambda_func') { - $ret['function'] = 'create_function() code'; - } else { - $ret['function'] = $funcbacktrace['function']; - } - } - } - if (isset($funcbacktrace['class']) && isset($backtrace[1])) { - $ret['class'] = $funcbacktrace['class']; - } - return $ret; - } - return false; - } - - /** - * Standard error message generation callback - * - * This method may also be called by a custom error message generator - * to fill in template values from the params array, simply - * set the third parameter to the error message template string to use - * - * The special variable %__msg% is reserved: use it only to specify - * where a message passed in by the user should be placed in the template, - * like so: - * - * Error message: %msg% - internal error - * - * If the message passed like so: - * - * - * $stack->push(ERROR_CODE, 'error', array(), 'server error 500'); - * - * - * The returned error message will be "Error message: server error 500 - - * internal error" - * @param PEAR_ErrorStack - * @param array - * @param string|false Pre-generated error message template - * @static - * @return string - */ - function getErrorMessage(&$stack, $err, $template = false) - { - if ($template) { - $mainmsg = $template; - } else { - $mainmsg = $stack->getErrorMessageTemplate($err['code']); - } - $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg); - if (is_array($err['params']) && count($err['params'])) { - foreach ($err['params'] as $name => $val) { - if (is_array($val)) { - // @ is needed in case $val is a multi-dimensional array - $val = @implode(', ', $val); - } - if (is_object($val)) { - if (method_exists($val, '__toString')) { - $val = $val->__toString(); - } else { - PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING, - 'warning', array('obj' => get_class($val)), - 'object %obj% passed into getErrorMessage, but has no __toString() method'); - $val = 'Object'; - } - } - $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg); - } - } - return $mainmsg; - } - - /** - * Standard Error Message Template generator from code - * @return string - */ - function getErrorMessageTemplate($code) - { - if (!isset($this->_errorMsgs[$code])) { - return '%__msg%'; - } - return $this->_errorMsgs[$code]; - } - - /** - * Set the Error Message Template array - * - * The array format must be: - *
    -     * array(error code => 'message template',...)
    -     * 
    - * - * Error message parameters passed into {@link push()} will be used as input - * for the error message. If the template is 'message %foo% was %bar%', and the - * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will - * be 'message one was six' - * @return string - */ - function setErrorMessageTemplate($template) - { - $this->_errorMsgs = $template; - } - - - /** - * emulate PEAR::raiseError() - * - * @return PEAR_Error - */ - function raiseError() - { - require_once 'PEAR.php'; - $args = func_get_args(); - return call_user_func_array(array('PEAR', 'raiseError'), $args); - } -} -$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack'); -$stack->pushCallback(array('PEAR_ErrorStack', '_handleError')); -?> -PEAR-1.8.0/PEAR/Exception.php100664 764 764 33642 100664 10533 - * @author Hans Lellelid - * @author Bertrand Mansion - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Exception.php,v 1.30 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.3.3 - */ - - -/** - * Base PEAR_Exception Class - * - * 1) Features: - * - * - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception)) - * - Definable triggers, shot when exceptions occur - * - Pretty and informative error messages - * - Added more context info available (like class, method or cause) - * - cause can be a PEAR_Exception or an array of mixed - * PEAR_Exceptions/PEAR_ErrorStack warnings - * - callbacks for specific exception classes and their children - * - * 2) Ideas: - * - * - Maybe a way to define a 'template' for the output - * - * 3) Inherited properties from PHP Exception Class: - * - * protected $message - * protected $code - * protected $line - * protected $file - * private $trace - * - * 4) Inherited methods from PHP Exception Class: - * - * __clone - * __construct - * getMessage - * getCode - * getFile - * getLine - * getTraceSafe - * getTraceSafeAsString - * __toString - * - * 5) Usage example - * - * - * require_once 'PEAR/Exception.php'; - * - * class Test { - * function foo() { - * throw new PEAR_Exception('Error Message', ERROR_CODE); - * } - * } - * - * function myLogger($pear_exception) { - * echo $pear_exception->getMessage(); - * } - * // each time a exception is thrown the 'myLogger' will be called - * // (its use is completely optional) - * PEAR_Exception::addObserver('myLogger'); - * $test = new Test; - * try { - * $test->foo(); - * } catch (PEAR_Exception $e) { - * print $e; - * } - * - * - * @category pear - * @package PEAR - * @author Tomas V.V.Cox - * @author Hans Lellelid - * @author Bertrand Mansion - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.3.3 - * - */ -class PEAR_Exception extends Exception -{ - const OBSERVER_PRINT = -2; - const OBSERVER_TRIGGER = -4; - const OBSERVER_DIE = -8; - protected $cause; - private static $_observers = array(); - private static $_uniqueid = 0; - private $_trace; - - /** - * Supported signatures: - * - PEAR_Exception(string $message); - * - PEAR_Exception(string $message, int $code); - * - PEAR_Exception(string $message, Exception $cause); - * - PEAR_Exception(string $message, Exception $cause, int $code); - * - PEAR_Exception(string $message, PEAR_Error $cause); - * - PEAR_Exception(string $message, PEAR_Error $cause, int $code); - * - PEAR_Exception(string $message, array $causes); - * - PEAR_Exception(string $message, array $causes, int $code); - * @param string exception message - * @param int|Exception|PEAR_Error|array|null exception cause - * @param int|null exception code or null - */ - public function __construct($message, $p2 = null, $p3 = null) - { - if (is_int($p2)) { - $code = $p2; - $this->cause = null; - } elseif (is_object($p2) || is_array($p2)) { - // using is_object allows both Exception and PEAR_Error - if (is_object($p2) && !($p2 instanceof Exception)) { - if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) { - throw new PEAR_Exception('exception cause must be Exception, ' . - 'array, or PEAR_Error'); - } - } - $code = $p3; - if (is_array($p2) && isset($p2['message'])) { - // fix potential problem of passing in a single warning - $p2 = array($p2); - } - $this->cause = $p2; - } else { - $code = null; - $this->cause = null; - } - parent::__construct($message, $code); - $this->signal(); - } - - /** - * @param mixed $callback - A valid php callback, see php func is_callable() - * - A PEAR_Exception::OBSERVER_* constant - * - An array(const PEAR_Exception::OBSERVER_*, - * mixed $options) - * @param string $label The name of the observer. Use this if you want - * to remove it later with removeObserver() - */ - public static function addObserver($callback, $label = 'default') - { - self::$_observers[$label] = $callback; - } - - public static function removeObserver($label = 'default') - { - unset(self::$_observers[$label]); - } - - /** - * @return int unique identifier for an observer - */ - public static function getUniqueId() - { - return self::$_uniqueid++; - } - - private function signal() - { - foreach (self::$_observers as $func) { - if (is_callable($func)) { - call_user_func($func, $this); - continue; - } - settype($func, 'array'); - switch ($func[0]) { - case self::OBSERVER_PRINT : - $f = (isset($func[1])) ? $func[1] : '%s'; - printf($f, $this->getMessage()); - break; - case self::OBSERVER_TRIGGER : - $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE; - trigger_error($this->getMessage(), $f); - break; - case self::OBSERVER_DIE : - $f = (isset($func[1])) ? $func[1] : '%s'; - die(printf($f, $this->getMessage())); - break; - default: - trigger_error('invalid observer type', E_USER_WARNING); - } - } - } - - /** - * Return specific error information that can be used for more detailed - * error messages or translation. - * - * This method may be overridden in child exception classes in order - * to add functionality not present in PEAR_Exception and is a placeholder - * to define API - * - * The returned array must be an associative array of parameter => value like so: - *
    -     * array('name' => $name, 'context' => array(...))
    -     * 
    - * @return array - */ - public function getErrorData() - { - return array(); - } - - /** - * Returns the exception that caused this exception to be thrown - * @access public - * @return Exception|array The context of the exception - */ - public function getCause() - { - return $this->cause; - } - - /** - * Function must be public to call on caused exceptions - * @param array - */ - public function getCauseMessage(&$causes) - { - $trace = $this->getTraceSafe(); - $cause = array('class' => get_class($this), - 'message' => $this->message, - 'file' => 'unknown', - 'line' => 'unknown'); - if (isset($trace[0])) { - if (isset($trace[0]['file'])) { - $cause['file'] = $trace[0]['file']; - $cause['line'] = $trace[0]['line']; - } - } - $causes[] = $cause; - if ($this->cause instanceof PEAR_Exception) { - $this->cause->getCauseMessage($causes); - } elseif ($this->cause instanceof Exception) { - $causes[] = array('class' => get_class($this->cause), - 'message' => $this->cause->getMessage(), - 'file' => $this->cause->getFile(), - 'line' => $this->cause->getLine()); - } elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) { - $causes[] = array('class' => get_class($this->cause), - 'message' => $this->cause->getMessage(), - 'file' => 'unknown', - 'line' => 'unknown'); - } elseif (is_array($this->cause)) { - foreach ($this->cause as $cause) { - if ($cause instanceof PEAR_Exception) { - $cause->getCauseMessage($causes); - } elseif ($cause instanceof Exception) { - $causes[] = array('class' => get_class($cause), - 'message' => $cause->getMessage(), - 'file' => $cause->getFile(), - 'line' => $cause->getLine()); - } elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) { - $causes[] = array('class' => get_class($cause), - 'message' => $cause->getMessage(), - 'file' => 'unknown', - 'line' => 'unknown'); - } elseif (is_array($cause) && isset($cause['message'])) { - // PEAR_ErrorStack warning - $causes[] = array( - 'class' => $cause['package'], - 'message' => $cause['message'], - 'file' => isset($cause['context']['file']) ? - $cause['context']['file'] : - 'unknown', - 'line' => isset($cause['context']['line']) ? - $cause['context']['line'] : - 'unknown', - ); - } - } - } - } - - public function getTraceSafe() - { - if (!isset($this->_trace)) { - $this->_trace = $this->getTrace(); - if (empty($this->_trace)) { - $backtrace = debug_backtrace(); - $this->_trace = array($backtrace[count($backtrace)-1]); - } - } - return $this->_trace; - } - - public function getErrorClass() - { - $trace = $this->getTraceSafe(); - return $trace[0]['class']; - } - - public function getErrorMethod() - { - $trace = $this->getTraceSafe(); - return $trace[0]['function']; - } - - public function __toString() - { - if (isset($_SERVER['REQUEST_URI'])) { - return $this->toHtml(); - } - return $this->toText(); - } - - public function toHtml() - { - $trace = $this->getTraceSafe(); - $causes = array(); - $this->getCauseMessage($causes); - $html = '' . "\n"; - foreach ($causes as $i => $cause) { - $html .= '\n"; - } - $html .= '' . "\n" - . '' - . '' - . '' . "\n"; - - foreach ($trace as $k => $v) { - $html .= '' - . '' - . '' . "\n"; - } - $html .= '' - . '' - . '' . "\n" - . '
    ' - . str_repeat('-', $i) . ' ' . $cause['class'] . ': ' - . htmlspecialchars($cause['message']) . ' in ' . $cause['file'] . ' ' - . 'on line ' . $cause['line'] . '' - . "
    Exception trace
    #FunctionLocation
    ' . $k . ''; - if (!empty($v['class'])) { - $html .= $v['class'] . $v['type']; - } - $html .= $v['function']; - $args = array(); - if (!empty($v['args'])) { - foreach ($v['args'] as $arg) { - if (is_null($arg)) $args[] = 'null'; - elseif (is_array($arg)) $args[] = 'Array'; - elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')'; - elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false'; - elseif (is_int($arg) || is_double($arg)) $args[] = $arg; - else { - $arg = (string)$arg; - $str = htmlspecialchars(substr($arg, 0, 16)); - if (strlen($arg) > 16) $str .= '…'; - $args[] = "'" . $str . "'"; - } - } - } - $html .= '(' . implode(', ',$args) . ')' - . '' . (isset($v['file']) ? $v['file'] : 'unknown') - . ':' . (isset($v['line']) ? $v['line'] : 'unknown') - . '
    ' . ($k+1) . '{main} 
    '; - return $html; - } - - public function toText() - { - $causes = array(); - $this->getCauseMessage($causes); - $causeMsg = ''; - foreach ($causes as $i => $cause) { - $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': ' - . $cause['message'] . ' in ' . $cause['file'] - . ' on line ' . $cause['line'] . "\n"; - } - return $causeMsg . $this->getTraceAsString(); - } -} - -?>PEAR-1.8.0/PEAR/FixPHP5PEARWarnings.php100777 764 764 231 100777 12077 PEAR-1.8.0/PEAR/Frontend.php100664 764 764 15445 100664 10355 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Frontend.php,v 1.18 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * Include error handling - */ -//require_once 'PEAR.php'; - -/** - * Which user interface class is being used. - * @var string class name - */ -$GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI'; - -/** - * Instance of $_PEAR_Command_uiclass. - * @var object - */ -$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null; - -/** - * Singleton-based frontend for PEAR user input/output - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Frontend extends PEAR -{ - /** - * Retrieve the frontend object - * @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk - * @static - */ - function &singleton($type = null) - { - if ($type === null) { - if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) { - $a = false; - return $a; - } - return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; - } - - $a = PEAR_Frontend::setFrontendClass($type); - return $a; - } - - /** - * Set the frontend class that will be used by calls to {@link singleton()} - * - * Frontends are expected to conform to the PEAR naming standard of - * _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php) - * @param string $uiclass full class name - * @return PEAR_Frontend - * @static - */ - function &setFrontendClass($uiclass) - { - if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && - is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) { - return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; - } - - if (!class_exists($uiclass)) { - $file = str_replace('_', '/', $uiclass) . '.php'; - if (PEAR_Frontend::isIncludeable($file)) { - include_once $file; - } - } - - if (class_exists($uiclass)) { - $obj = &new $uiclass; - // quick test to see if this class implements a few of the most - // important frontend methods - if (is_a($obj, 'PEAR_Frontend')) { - $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj; - $GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass; - return $obj; - } - - $err = PEAR::raiseError("not a frontend class: $uiclass"); - return $err; - } - - $err = PEAR::raiseError("no such class: $uiclass"); - return $err; - } - - /** - * Set the frontend class that will be used by calls to {@link singleton()} - * - * Frontends are expected to be a descendant of PEAR_Frontend - * @param PEAR_Frontend - * @return PEAR_Frontend - * @static - */ - function &setFrontendObject($uiobject) - { - if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && - is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) { - return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; - } - - if (!is_a($uiobject, 'PEAR_Frontend')) { - $err = PEAR::raiseError('not a valid frontend class: (' . - get_class($uiobject) . ')'); - return $err; - } - - $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject; - $GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject); - return $uiobject; - } - - /** - * @param string $path relative or absolute include path - * @return boolean - * @static - */ - function isIncludeable($path) - { - if (file_exists($path) && is_readable($path)) { - return true; - } - - $fp = @fopen($path, 'r', true); - if ($fp) { - fclose($fp); - return true; - } - - return false; - } - - /** - * @param PEAR_Config - */ - function setConfig(&$config) - { - } - - /** - * This can be overridden to allow session-based temporary file management - * - * By default, all files are deleted at the end of a session. The web installer - * needs to be able to sustain a list over many sessions in order to support - * user interaction with install scripts - */ - function addTempFile($file) - { - $GLOBALS['_PEAR_Common_tempfiles'][] = $file; - } - - /** - * Log an action - * - * @param string $msg the message to log - * @param boolean $append_crlf - * @return boolean true - * @abstract - */ - function log($msg, $append_crlf = true) - { - } - - /** - * Run a post-installation script - * - * @param array $scripts array of post-install scripts - * @abstract - */ - function runPostinstallScripts(&$scripts) - { - } - - /** - * Display human-friendly output formatted depending on the - * $command parameter. - * - * This should be able to handle basic output data with no command - * @param mixed $data data structure containing the information to display - * @param string $command command from which this method was called - * @abstract - */ - function outputData($data, $command = '_default') - { - } - - /** - * Display a modal form dialog and return the given input - * - * A frontend that requires multiple requests to retrieve and process - * data must take these needs into account, and implement the request - * handling code. - * @param string $command command from which this method was called - * @param array $prompts associative array. keys are the input field names - * and values are the description - * @param array $types array of input field types (text, password, - * etc.) keys have to be the same like in $prompts - * @param array $defaults array of default values. again keys have - * to be the same like in $prompts. Do not depend - * on a default value being set. - * @return array input sent by the user - * @abstract - */ - function userDialog($command, $prompts, $types = array(), $defaults = array()) - { - } -}PEAR-1.8.0/PEAR/Installer.php100664 764 764 211556 100664 10554 setConfig($this->_config); + if ($pkg->getPackagexmlVersion() == '1.0') { + $gen = &$pkg->getDefaultGenerator(); + $deps = $gen->dependenciesToV2(); + } else { + $deps = $pkg->getDeps(true); + } + + if (!$deps) { + return; + } + + if (!is_array($data)) { + $data = array(); + } + + if (!isset($data['dependencies'])) { + $data['dependencies'] = array(); + } + + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + + if (!isset($data['dependencies'][$channel])) { + $data['dependencies'][$channel] = array(); + } + + $data['dependencies'][$channel][$package] = array(); + if (isset($deps['required']['package'])) { + if (!isset($deps['required']['package'][0])) { + $deps['required']['package'] = array($deps['required']['package']); + } + + foreach ($deps['required']['package'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'required'); + } + } + + if (isset($deps['optional']['package'])) { + if (!isset($deps['optional']['package'][0])) { + $deps['optional']['package'] = array($deps['optional']['package']); + } + + foreach ($deps['optional']['package'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'optional'); + } + } + + if (isset($deps['required']['subpackage'])) { + if (!isset($deps['required']['subpackage'][0])) { + $deps['required']['subpackage'] = array($deps['required']['subpackage']); + } + + foreach ($deps['required']['subpackage'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'required'); + } + } + + if (isset($deps['optional']['subpackage'])) { + if (!isset($deps['optional']['subpackage'][0])) { + $deps['optional']['subpackage'] = array($deps['optional']['subpackage']); + } + + foreach ($deps['optional']['subpackage'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'optional'); + } + } + + if (isset($deps['group'])) { + if (!isset($deps['group'][0])) { + $deps['group'] = array($deps['group']); + } + + foreach ($deps['group'] as $group) { + if (isset($group['package'])) { + if (!isset($group['package'][0])) { + $group['package'] = array($group['package']); + } + + foreach ($group['package'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'optional', + $group['attribs']['name']); + } + } + + if (isset($group['subpackage'])) { + if (!isset($group['subpackage'][0])) { + $group['subpackage'] = array($group['subpackage']); + } + + foreach ($group['subpackage'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'optional', + $group['attribs']['name']); + } + } + } + } + + if ($data['dependencies'][$channel][$package] == array()) { + unset($data['dependencies'][$channel][$package]); + if (!count($data['dependencies'][$channel])) { + unset($data['dependencies'][$channel]); + } + } + } + + /** + * @param array the database + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param array the specific dependency + * @param required|optional whether this is a required or an optional dep + * @param string|false dependency group this dependency is from, or false for ordinary dep + */ + function _registerDep(&$data, &$pkg, $dep, $type, $group = false) + { + $info = array( + 'dep' => $dep, + 'type' => $type, + 'group' => $group + ); + + $dep = array_map('strtolower', $dep); + $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; + if (!isset($data['dependencies'])) { + $data['dependencies'] = array(); + } + + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + + if (!isset($data['dependencies'][$channel])) { + $data['dependencies'][$channel] = array(); + } + + if (!isset($data['dependencies'][$channel][$package])) { + $data['dependencies'][$channel][$package] = array(); + } + + $data['dependencies'][$channel][$package][] = $info; + if (isset($data['packages'][$depchannel][$dep['name']])) { + $found = false; + foreach ($data['packages'][$depchannel][$dep['name']] as $i => $p) { + if ($p['channel'] == $channel && $p['package'] == $package) { + $found = true; + break; + } + } + } else { + if (!isset($data['packages'])) { + $data['packages'] = array(); + } + + if (!isset($data['packages'][$depchannel])) { + $data['packages'][$depchannel] = array(); + } + + if (!isset($data['packages'][$depchannel][$dep['name']])) { + $data['packages'][$depchannel][$dep['name']] = array(); + } + + $found = false; + } + + if (!$found) { + $data['packages'][$depchannel][$dep['name']][] = array( + 'channel' => $channel, + 'package' => $package + ); + } + } +}PEAR-1.9.0/PEAR/Dependency2.php100664 764 764 142517 100664 10760 - * @author Tomas V.V. Cox - * @author Martin Jansen * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Installer.php,v 1.259 2009/04/09 00:55:07 dufuz Exp $ + * @version CVS: $Id: Dependency2.php 286494 2009-07-29 06:57:11Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 + * @since File available since Release 1.4.0a1 */ /** - * Used for installation groups in package.xml 2.0 and platform exceptions + * Required for the PEAR_VALIDATE_* constants */ -require_once 'OS/Guess.php'; -require_once 'PEAR/Downloader.php'; +require_once 'PEAR/Validate.php'; -define('PEAR_INSTALLER_NOBINARY', -240); /** - * Administration class used to install PEAR packages and maintain the - * installed package database. + * Dependency check for PEAR packages * + * This class handles both version 1.0 and 2.0 dependencies + * WARNING: *any* changes to this class must be duplicated in the + * test_PEAR_Dependency2 class found in tests/PEAR_Dependency2/setup.php.inc, + * or unit tests will not actually validate the changes * @category pear * @package PEAR - * @author Stig Bakken - * @author Tomas V.V. Cox - * @author Martin Jansen * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 + * @since Class available since Release 1.4.0a1 */ -class PEAR_Installer extends PEAR_Downloader +class PEAR_Dependency2 { - // {{{ properties - - /** name of the package directory, for example Foo-1.0 - * @var string - */ - var $pkgdir; - - /** directory where PHP code files go - * @var string - */ - var $phpdir; - - /** directory where PHP extension files go - * @var string - */ - var $extdir; - - /** directory where documentation goes - * @var string + /** + * One of the PEAR_VALIDATE_* states + * @see PEAR_VALIDATE_NORMAL + * @var integer */ - var $docdir; + var $_state; - /** installation root directory (ala PHP's INSTALL_ROOT or - * automake's DESTDIR - * @var string + /** + * Command-line options to install/upgrade/uninstall commands + * @param array */ - var $installroot = ''; + var $_options; - /** debug level - * @var int + /** + * @var OS_Guess */ - var $debug = 1; + var $_os; - /** temporary directory - * @var string + /** + * @var PEAR_Registry */ - var $tmpdir; + var $_registry; /** - * PEAR_Registry object used by the installer - * @var PEAR_Registry + * @var PEAR_Config */ - var $registry; + var $_config; /** - * array of PEAR_Downloader_Packages - * @var array + * @var PEAR_DependencyDB */ - var $_downloadedPackages; + var $_dependencydb; - /** List of file transactions queued for an install/upgrade/uninstall. - * - * Format: - * array( - * 0 => array("rename => array("from-file", "to-file")), - * 1 => array("delete" => array("file-to-delete")), - * ... - * ) - * + /** + * Output of PEAR_Registry::parsedPackageName() * @var array */ - var $file_operations = array(); - - // }}} - - // {{{ constructor + var $_currentPackage; /** - * PEAR_Installer constructor. - * - * @param object $ui user interface object (instance of PEAR_Frontend_*) - * - * @access public + * @param PEAR_Config + * @param array installation options + * @param array format of PEAR_Registry::parsedPackageName() + * @param int installation state (one of PEAR_VALIDATE_*) */ - function PEAR_Installer(&$ui) + function PEAR_Dependency2(&$config, $installoptions, $package, + $state = PEAR_VALIDATE_INSTALLING) { - parent::PEAR_Common(); - $this->setFrontendObject($ui); - $this->debug = $this->config->get('verbose'); - } + $this->_config = &$config; + if (!class_exists('PEAR_DependencyDB')) { + require_once 'PEAR/DependencyDB.php'; + } - function setOptions($options) - { - $this->_options = $options; - } + if (isset($installoptions['packagingroot'])) { + // make sure depdb is in the right location + $config->setInstallRoot($installoptions['packagingroot']); + } - function setConfig(&$config) - { - $this->config = &$config; $this->_registry = &$config->getRegistry(); - } - - // }}} + $this->_dependencydb = &PEAR_DependencyDB::singleton($config); + if (isset($installoptions['packagingroot'])) { + $config->setInstallRoot(false); + } - function _removeBackups($files) - { - foreach ($files as $path) { - $this->addFileOperation('removebackup', array($path)); + $this->_options = $installoptions; + $this->_state = $state; + if (!class_exists('OS_Guess')) { + require_once 'OS/Guess.php'; } - } - // {{{ _deletePackageFiles() + $this->_os = new OS_Guess; + $this->_currentPackage = $package; + } - /** - * Delete a package's installed files, does not remove empty directories. - * - * @param string package name - * @param string channel name - * @param bool if true, then files are backed up first - * @return bool TRUE on success, or a PEAR error on failure - * @access protected - */ - function _deletePackageFiles($package, $channel = false, $backup = false) + function _getExtraString($dep) { - if (!$channel) { - $channel = 'pear.php.net'; + $extra = ' ('; + if (isset($dep['uri'])) { + return ''; } - if (!strlen($package)) { - return $this->raiseError("No package to uninstall given"); - } + if (isset($dep['recommended'])) { + $extra .= 'recommended version ' . $dep['recommended']; + } else { + if (isset($dep['min'])) { + $extra .= 'version >= ' . $dep['min']; + } - if (strtolower($package) == 'pear' && $channel == 'pear.php.net') { - // to avoid race conditions, include all possible needed files - require_once 'PEAR/Task/Common.php'; - require_once 'PEAR/Task/Replace.php'; - require_once 'PEAR/Task/Unixeol.php'; - require_once 'PEAR/Task/Windowseol.php'; - require_once 'PEAR/PackageFile/v1.php'; - require_once 'PEAR/PackageFile/v2.php'; - require_once 'PEAR/PackageFile/Generator/v1.php'; - require_once 'PEAR/PackageFile/Generator/v2.php'; - } + if (isset($dep['max'])) { + if ($extra != ' (') { + $extra .= ', '; + } + $extra .= 'version <= ' . $dep['max']; + } - $filelist = $this->_registry->packageInfo($package, 'filelist', $channel); - if ($filelist == null) { - return $this->raiseError("$channel/$package not installed"); - } + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } - $ret = array(); - foreach ($filelist as $file => $props) { - if (empty($props['installed_as'])) { - continue; - } + if ($extra != ' (') { + $extra .= ', '; + } - $path = $props['installed_as']; - if ($backup) { - $this->addFileOperation('backup', array($path)); - $ret[] = $path; + $extra .= 'excluded versions: '; + foreach ($dep['exclude'] as $i => $exclude) { + if ($i) { + $extra .= ', '; + } + $extra .= $exclude; + } } - - $this->addFileOperation('delete', array($path)); } - if ($backup) { - return $ret; + $extra .= ')'; + if ($extra == ' ()') { + $extra = ''; } - return true; + return $extra; } - // }}} - // {{{ _installFile() - /** - * @param string filename - * @param array attributes from tag in package.xml - * @param string path to install the file in - * @param array options from command-line - * @access private + * This makes unit-testing a heck of a lot easier */ - function _installFile($file, $atts, $tmp_path, $options) + function getPHP_OS() { - // {{{ return if this file is meant for another platform - static $os; - if (!isset($this->_registry)) { - $this->_registry = &$this->config->getRegistry(); - } + return PHP_OS; + } - if (isset($atts['platform'])) { - if (empty($os)) { - $os = new OS_Guess(); - } + /** + * This makes unit-testing a heck of a lot easier + */ + function getsysname() + { + return $this->_os->getSysname(); + } - if (strlen($atts['platform']) && $atts['platform']{0} == '!') { - $negate = true; - $platform = substr($atts['platform'], 1); - } else { - $negate = false; - $platform = $atts['platform']; - } + /** + * Specify a dependency on an OS. Use arch for detailed os/processor information + * + * There are two generic OS dependencies that will be the most common, unix and windows. + * Other options are linux, freebsd, darwin (OS X), sunos, irix, hpux, aix + */ + function validateOsDependency($dep) + { + if ($this->_state != PEAR_VALIDATE_INSTALLING && $this->_state != PEAR_VALIDATE_DOWNLOADING) { + return true; + } - if ((bool) $os->matchSignature($platform) === $negate) { - $this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")"); - return PEAR_INSTALLER_SKIPPED; - } + if ($dep['name'] == '*') { + return true; } - // }}} - $channel = $this->pkginfo->getChannel(); - // {{{ assemble the destination paths - switch ($atts['role']) { - case 'src': - case 'extsrc': - $this->source_files++; - return; - case 'doc': - case 'data': - case 'test': - $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel) . - DIRECTORY_SEPARATOR . $this->pkginfo->getPackage(); - unset($atts['baseinstalldir']); - break; - case 'ext': - case 'php': - $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel); - break; - case 'script': - $dest_dir = $this->config->get('bin_dir', null, $channel); - break; - default: - return $this->raiseError("Invalid role `$atts[role]' for file $file"); - } + $not = isset($dep['conflicts']) ? true : false; + switch (strtolower($dep['name'])) { + case 'windows' : + if ($not) { + if (strtolower(substr($this->getPHP_OS(), 0, 3)) == 'win') { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError("Cannot install %s on Windows"); + } - $save_destdir = $dest_dir; - if (!empty($atts['baseinstalldir'])) { - $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; - } + return $this->warning("warning: Cannot install %s on Windows"); + } + } else { + if (strtolower(substr($this->getPHP_OS(), 0, 3)) != 'win') { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError("Can only install %s on Windows"); + } - if (dirname($file) != '.' && empty($atts['install-as'])) { - $dest_dir .= DIRECTORY_SEPARATOR . dirname($file); - } + return $this->warning("warning: Can only install %s on Windows"); + } + } + break; + case 'unix' : + $unices = array('linux', 'freebsd', 'darwin', 'sunos', 'irix', 'hpux', 'aix'); + if ($not) { + if (in_array($this->getSysname(), $unices)) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError("Cannot install %s on any Unix system"); + } - if (empty($atts['install-as'])) { - $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); - } else { - $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as']; + return $this->warning( "warning: Cannot install %s on any Unix system"); + } + } else { + if (!in_array($this->getSysname(), $unices)) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError("Can only install %s on a Unix system"); + } + + return $this->warning("warning: Can only install %s on a Unix system"); + } + } + break; + default : + if ($not) { + if (strtolower($dep['name']) == strtolower($this->getSysname())) { + if (!isset($this->_options['nodeps']) && + !isset($this->_options['force'])) { + return $this->raiseError('Cannot install %s on ' . $dep['name'] . + ' operating system'); + } + + return $this->warning('warning: Cannot install %s on ' . + $dep['name'] . ' operating system'); + } + } else { + if (strtolower($dep['name']) != strtolower($this->getSysname())) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('Cannot install %s on ' . + $this->getSysname() . + ' operating system, can only install on ' . $dep['name']); + } + + return $this->warning('warning: Cannot install %s on ' . + $this->getSysname() . + ' operating system, can only install on ' . $dep['name']); + } + } } - $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file; + return true; + } - // Clean up the DIRECTORY_SEPARATOR mess - $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; - list($dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), - array(DIRECTORY_SEPARATOR, - DIRECTORY_SEPARATOR, - DIRECTORY_SEPARATOR), - array($dest_file, $orig_file)); - $final_dest_file = $installed_as = $dest_file; - if (isset($this->_options['packagingroot'])) { - $installedas_dest_dir = dirname($final_dest_file); - $installedas_dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); - $final_dest_file = $this->_prependPath($final_dest_file, $this->_options['packagingroot']); - } else { - $installedas_dest_dir = dirname($final_dest_file); - $installedas_dest_file = $installedas_dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + /** + * This makes unit-testing a heck of a lot easier + */ + function matchSignature($pattern) + { + return $this->_os->matchSignature($pattern); + } + + /** + * Specify a complex dependency on an OS/processor/kernel version, + * Use OS for simple operating system dependency. + * + * This is the only dependency that accepts an eregable pattern. The pattern + * will be matched against the php_uname() output parsed by OS_Guess + */ + function validateArchDependency($dep) + { + if ($this->_state != PEAR_VALIDATE_INSTALLING) { + return true; } - $dest_dir = dirname($final_dest_file); - $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); - if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { - return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); + $not = isset($dep['conflicts']) ? true : false; + if (!$this->matchSignature($dep['pattern'])) { + if (!$not) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s Architecture dependency failed, does not ' . + 'match "' . $dep['pattern'] . '"'); + } + + return $this->warning('warning: %s Architecture dependency failed, does ' . + 'not match "' . $dep['pattern'] . '"'); + } + + return true; } - // }}} - if (empty($this->_options['register-only']) && - (!file_exists($dest_dir) || !is_dir($dest_dir))) { - if (!$this->mkDirHier($dest_dir)) { - return $this->raiseError("failed to mkdir $dest_dir", - PEAR_INSTALLER_FAILED); + if ($not) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s Architecture dependency failed, required "' . + $dep['pattern'] . '"'); } - $this->log(3, "+ mkdir $dest_dir"); + + return $this->warning('warning: %s Architecture dependency failed, ' . + 'required "' . $dep['pattern'] . '"'); } - // pretty much nothing happens if we are only registering the install - if (empty($this->_options['register-only'])) { - if (empty($atts['replacements'])) { - if (!file_exists($orig_file)) { - return $this->raiseError("file $orig_file does not exist", - PEAR_INSTALLER_FAILED); - } + return true; + } - if (!@copy($orig_file, $dest_file)) { - return $this->raiseError("failed to write $dest_file: $php_errormsg", - PEAR_INSTALLER_FAILED); - } + /** + * This makes unit-testing a heck of a lot easier + */ + function extension_loaded($name) + { + return extension_loaded($name); + } - $this->log(3, "+ cp $orig_file $dest_file"); - if (isset($atts['md5sum'])) { - $md5sum = md5_file($dest_file); - } - } else { - // {{{ file with replacements - if (!file_exists($orig_file)) { - return $this->raiseError("file does not exist", - PEAR_INSTALLER_FAILED); - } + /** + * This makes unit-testing a heck of a lot easier + */ + function phpversion($name = null) + { + if ($name !== null) { + return phpversion($name); + } - $contents = file_get_contents($orig_file); - if ($contents === false) { - $contents = ''; - } + return phpversion(); + } - if (isset($atts['md5sum'])) { - $md5sum = md5($contents); - } + function validateExtensionDependency($dep, $required = true) + { + if ($this->_state != PEAR_VALIDATE_INSTALLING && + $this->_state != PEAR_VALIDATE_DOWNLOADING) { + return true; + } - $subst_from = $subst_to = array(); - foreach ($atts['replacements'] as $a) { - $to = ''; - if ($a['type'] == 'php-const') { - if (preg_match('/^[a-z0-9_]+\\z/i', $a['to'])) { - eval("\$to = $a[to];"); - } else { - if (!isset($options['soft'])) { - $this->log(0, "invalid php-const replacement: $a[to]"); - } - continue; - } - } elseif ($a['type'] == 'pear-config') { - if ($a['to'] == 'master_server') { - $chan = $this->_registry->getChannel($channel); - if (!PEAR::isError($chan)) { - $to = $chan->getServer(); - } else { - $to = $this->config->get($a['to'], null, $channel); - } - } else { - $to = $this->config->get($a['to'], null, $channel); - } - if (is_null($to)) { - if (!isset($options['soft'])) { - $this->log(0, "invalid pear-config replacement: $a[to]"); - } - continue; - } - } elseif ($a['type'] == 'package-info') { - if ($t = $this->pkginfo->packageInfo($a['to'])) { - $to = $t; - } else { - if (!isset($options['soft'])) { - $this->log(0, "invalid package-info replacement: $a[to]"); - } - continue; - } - } - if (!is_null($to)) { - $subst_from[] = $a['from']; - $subst_to[] = $to; + $loaded = $this->extension_loaded($dep['name']); + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + } + + if (!isset($dep['min']) && !isset($dep['max']) && + !isset($dep['recommended']) && !isset($dep['exclude']) + ) { + if ($loaded) { + if (isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra); } - } - $this->log(3, "doing ".sizeof($subst_from)." substitution(s) for $final_dest_file"); - if (sizeof($subst_from)) { - $contents = str_replace($subst_from, $subst_to, $contents); + return $this->warning('warning: %s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra); } - $wp = @fopen($dest_file, "wb"); - if (!is_resource($wp)) { - return $this->raiseError("failed to create $dest_file: $php_errormsg", - PEAR_INSTALLER_FAILED); - } + return true; + } - if (@fwrite($wp, $contents) === false) { - return $this->raiseError("failed writing to $dest_file: $php_errormsg", - PEAR_INSTALLER_FAILED); + if (isset($dep['conflicts'])) { + return true; + } + + if ($required) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP extension "' . + $dep['name'] . '"' . $extra); } - fclose($wp); - // }}} + return $this->warning('warning: %s requires PHP extension "' . + $dep['name'] . '"' . $extra); } - // {{{ check the md5 - if (isset($md5sum)) { - if (strtolower($md5sum) === strtolower($atts['md5sum'])) { - $this->log(2, "md5sum ok: $final_dest_file"); - } else { - if (empty($options['force'])) { - // delete the file - if (file_exists($dest_file)) { - unlink($dest_file); - } - - if (!isset($options['ignore-errors'])) { - return $this->raiseError("bad md5sum for file $final_dest_file", - PEAR_INSTALLER_FAILED); - } + return $this->warning('%s can optionally use PHP extension "' . + $dep['name'] . '"' . $extra); + } - if (!isset($options['soft'])) { - $this->log(0, "warning : bad md5sum for file $final_dest_file"); - } - } else { - if (!isset($options['soft'])) { - $this->log(0, "warning : bad md5sum for file $final_dest_file"); - } - } - } + if (!$loaded) { + if (isset($dep['conflicts'])) { + return true; } - // }}} - // {{{ set file permissions - if (!OS_WINDOWS) { - if ($atts['role'] == 'script') { - $mode = 0777 & ~(int)octdec($this->config->get('umask')); - $this->log(3, "+ chmod +x $dest_file"); - } else { - $mode = 0666 & ~(int)octdec($this->config->get('umask')); - } - if ($atts['role'] != 'src') { - $this->addFileOperation("chmod", array($mode, $dest_file)); - if (!@chmod($dest_file, $mode)) { - if (!isset($options['soft'])) { - $this->log(0, "failed to change mode of $dest_file: $php_errormsg"); - } - } - } + if (!$required) { + return $this->warning('%s can optionally use PHP extension "' . + $dep['name'] . '"' . $extra); } - // }}} - if ($atts['role'] == 'src') { - rename($dest_file, $final_dest_file); - $this->log(2, "renamed source file $dest_file to $final_dest_file"); - } else { - $this->addFileOperation("rename", array($dest_file, $final_dest_file, - $atts['role'] == 'ext')); + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP extension "' . $dep['name'] . + '"' . $extra); } - } - // Store the full path where the file was installed for easy unistall - if ($atts['role'] != 'script') { - $loc = $this->config->get($atts['role'] . '_dir'); - } else { - $loc = $this->config->get('bin_dir'); + return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . + '"' . $extra); } - if ($atts['role'] != 'src') { - $this->addFileOperation("installed_as", array($file, $installed_as, - $loc, - dirname(substr($installedas_dest_file, strlen($loc))))); + $version = (string) $this->phpversion($dep['name']); + if (empty($version)) { + $version = '0'; } - //$this->log(2, "installed: $dest_file"); - return PEAR_INSTALLER_OK; - } - - // }}} - // {{{ _installFile2() - - /** - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @param string filename - * @param array attributes from tag in package.xml - * @param string path to install the file in - * @param array options from command-line - * @access private - */ - function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options) - { - $atts = $real_atts; - if (!isset($this->_registry)) { - $this->_registry = &$this->config->getRegistry(); + $fail = false; + if (isset($dep['min']) && !version_compare($version, $dep['min'], '>=')) { + $fail = true; } - $channel = $pkg->getChannel(); - // {{{ assemble the destination paths - if (!in_array($atts['attribs']['role'], - PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { - return $this->raiseError('Invalid role `' . $atts['attribs']['role'] . - "' for file $file"); + if (isset($dep['max']) && !version_compare($version, $dep['max'], '<=')) { + $fail = true; } - $role = &PEAR_Installer_Role::factory($pkg, $atts['attribs']['role'], $this->config); - $err = $role->setup($this, $pkg, $atts['attribs'], $file); - if (PEAR::isError($err)) { - return $err; - } + if ($fail && !isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP extension "' . $dep['name'] . + '"' . $extra . ', installed version is ' . $version); + } - if (!$role->isInstallable()) { - return; - } + return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . + '"' . $extra . ', installed version is ' . $version); + } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra . ', installed version is ' . $version); + } - $info = $role->processInstallation($pkg, $atts['attribs'], $file, $tmp_path); - if (PEAR::isError($info)) { - return $info; + return $this->warning('warning: %s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra . ', installed version is ' . $version); } - list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info; - if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { - return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); - } + if (isset($dep['exclude'])) { + foreach ($dep['exclude'] as $exclude) { + if (version_compare($version, $exclude, '==')) { + if (isset($dep['conflicts'])) { + continue; + } - $final_dest_file = $installed_as = $dest_file; - if (isset($this->_options['packagingroot'])) { - $final_dest_file = $this->_prependPath($final_dest_file, - $this->_options['packagingroot']); - } + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s is not compatible with PHP extension "' . + $dep['name'] . '" version ' . + $exclude); + } - $dest_dir = dirname($final_dest_file); - $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); - // }}} + return $this->warning('warning: %s is not compatible with PHP extension "' . + $dep['name'] . '" version ' . + $exclude); + } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra . ', installed version is ' . $version); + } - if (empty($this->_options['register-only'])) { - if (!file_exists($dest_dir) || !is_dir($dest_dir)) { - if (!$this->mkDirHier($dest_dir)) { - return $this->raiseError("failed to mkdir $dest_dir", - PEAR_INSTALLER_FAILED); + return $this->warning('warning: %s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra . ', installed version is ' . $version); } - $this->log(3, "+ mkdir $dest_dir"); } } - $attribs = $atts['attribs']; - unset($atts['attribs']); - // pretty much nothing happens if we are only registering the install - if (empty($this->_options['register-only'])) { - if (!count($atts)) { // no tasks - if (!file_exists($orig_file)) { - return $this->raiseError("file $orig_file does not exist", - PEAR_INSTALLER_FAILED); - } + if (isset($dep['recommended'])) { + if (version_compare($version, $dep['recommended'], '==')) { + return true; + } - if (!@copy($orig_file, $dest_file)) { - return $this->raiseError("failed to write $dest_file: $php_errormsg", - PEAR_INSTALLER_FAILED); - } + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s dependency: PHP extension ' . $dep['name'] . + ' version "' . $version . '"' . + ' is not the recommended version "' . $dep['recommended'] . + '", but may be compatible, use --force to install'); + } - $this->log(3, "+ cp $orig_file $dest_file"); - if (isset($attribs['md5sum'])) { - $md5sum = md5_file($dest_file); - } - } else { // file with tasks - if (!file_exists($orig_file)) { - return $this->raiseError("file $orig_file does not exist", - PEAR_INSTALLER_FAILED); - } + return $this->warning('warning: %s dependency: PHP extension ' . + $dep['name'] . ' version "' . $version . '"' . + ' is not the recommended version "' . $dep['recommended'].'"'); + } - $contents = file_get_contents($orig_file); - if ($contents === false) { - $contents = ''; - } + return true; + } - if (isset($attribs['md5sum'])) { - $md5sum = md5($contents); - } + function validatePhpDependency($dep) + { + if ($this->_state != PEAR_VALIDATE_INSTALLING && + $this->_state != PEAR_VALIDATE_DOWNLOADING) { + return true; + } - foreach ($atts as $tag => $raw) { - $tag = str_replace(array($pkg->getTasksNs() . ':', '-'), array('', '_'), $tag); - $task = "PEAR_Task_$tag"; - $task = &new $task($this->config, $this, PEAR_TASK_INSTALL); - if (!$task->isScript()) { // scripts are only handled after installation - $task->init($raw, $attribs, $pkg->getLastInstalledVersion()); - $res = $task->startSession($pkg, $contents, $final_dest_file); - if ($res === false) { - continue; // skip this file - } + $version = $this->phpversion(); + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + } - if (PEAR::isError($res)) { - return $res; - } + if (isset($dep['min'])) { + if (!version_compare($version, $dep['min'], '>=')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP' . + $extra . ', installed version is ' . $version); + } - $contents = $res; // save changes - } + return $this->warning('warning: %s requires PHP' . + $extra . ', installed version is ' . $version); + } + } - $wp = @fopen($dest_file, "wb"); - if (!is_resource($wp)) { - return $this->raiseError("failed to create $dest_file: $php_errormsg", - PEAR_INSTALLER_FAILED); - } + if (isset($dep['max'])) { + if (!version_compare($version, $dep['max'], '<=')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP' . + $extra . ', installed version is ' . $version); + } - if (fwrite($wp, $contents) === false) { - return $this->raiseError("failed writing to $dest_file: $php_errormsg", - PEAR_INSTALLER_FAILED); + return $this->warning('warning: %s requires PHP' . + $extra . ', installed version is ' . $version); + } + } + + if (isset($dep['exclude'])) { + foreach ($dep['exclude'] as $exclude) { + if (version_compare($version, $exclude, '==')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s is not compatible with PHP version ' . + $exclude); } - fclose($wp); + return $this->warning( + 'warning: %s is not compatible with PHP version ' . + $exclude); } } + } - // {{{ check the md5 - if (isset($md5sum)) { - // Make sure the original md5 sum matches with expected - if (strtolower($md5sum) === strtolower($attribs['md5sum'])) { - $this->log(2, "md5sum ok: $final_dest_file"); + return true; + } - if (isset($contents)) { - // set md5 sum based on $content in case any tasks were run. - $real_atts['attribs']['md5sum'] = md5($contents); - } - } else { - if (empty($options['force'])) { - // delete the file - if (file_exists($dest_file)) { - unlink($dest_file); - } + /** + * This makes unit-testing a heck of a lot easier + */ + function getPEARVersion() + { + return '1.9.0'; + } - if (!isset($options['ignore-errors'])) { - return $this->raiseError("bad md5sum for file $final_dest_file", - PEAR_INSTALLER_FAILED); - } + function validatePearinstallerDependency($dep) + { + $pearversion = $this->getPEARVersion(); + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + } - if (!isset($options['soft'])) { - $this->log(0, "warning : bad md5sum for file $final_dest_file"); - } - } else { - if (!isset($options['soft'])) { - $this->log(0, "warning : bad md5sum for file $final_dest_file"); - } - } - } - } else { - $real_atts['attribs']['md5sum'] = md5_file($dest_file); + if (version_compare($pearversion, $dep['min'], '<')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PEAR Installer' . $extra . + ', installed version is ' . $pearversion); } - // }}} - // {{{ set file permissions - if (!OS_WINDOWS) { - if ($role->isExecutable()) { - $mode = 0777 & ~(int)octdec($this->config->get('umask')); - $this->log(3, "+ chmod +x $dest_file"); - } else { - $mode = 0666 & ~(int)octdec($this->config->get('umask')); - } + return $this->warning('warning: %s requires PEAR Installer' . $extra . + ', installed version is ' . $pearversion); + } - if ($attribs['role'] != 'src') { - $this->addFileOperation("chmod", array($mode, $dest_file)); - if (!@chmod($dest_file, $mode)) { - if (!isset($options['soft'])) { - $this->log(0, "failed to change mode of $dest_file: $php_errormsg"); - } - } + if (isset($dep['max'])) { + if (version_compare($pearversion, $dep['max'], '>')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PEAR Installer' . $extra . + ', installed version is ' . $pearversion); } - } - // }}} - if ($attribs['role'] == 'src') { - rename($dest_file, $final_dest_file); - $this->log(2, "renamed source file $dest_file to $final_dest_file"); - } else { - $this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension())); + return $this->warning('warning: %s requires PEAR Installer' . $extra . + ', installed version is ' . $pearversion); } } - // Store the full path where the file was installed for easy uninstall - if ($attribs['role'] != 'src') { - $loc = $this->config->get($role->getLocationConfig(), null, $channel); - $this->addFileOperation('installed_as', array($file, $installed_as, - $loc, - dirname(substr($installed_as, strlen($loc))))); + if (isset($dep['exclude'])) { + if (!isset($dep['exclude'][0])) { + $dep['exclude'] = array($dep['exclude']); + } + + foreach ($dep['exclude'] as $exclude) { + if (version_compare($exclude, $pearversion, '==')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s is not compatible with PEAR Installer ' . + 'version ' . $exclude); + } + + return $this->warning('warning: %s is not compatible with PEAR ' . + 'Installer version ' . $exclude); + } + } } - //$this->log(2, "installed: $dest_file"); - return PEAR_INSTALLER_OK; + return true; } - // }}} - // {{{ addFileOperation() + function validateSubpackageDependency($dep, $required, $params) + { + return $this->validatePackageDependency($dep, $required, $params); + } /** - * Add a file operation to the current file transaction. - * - * @see startFileTransaction() - * @param string $type This can be one of: - * - rename: rename a file ($data has 3 values) - * - backup: backup an existing file ($data has 1 value) - * - removebackup: clean up backups created during install ($data has 1 value) - * - chmod: change permissions on a file ($data has 2 values) - * - delete: delete a file ($data has 1 value) - * - rmdir: delete a directory if empty ($data has 1 value) - * - installed_as: mark a file as installed ($data has 4 values). - * @param array $data For all file operations, this array must contain the - * full path to the file or directory that is being operated on. For - * the rename command, the first parameter must be the file to rename, - * the second its new name, the third whether this is a PHP extension. - * - * The installed_as operation contains 4 elements in this order: - * 1. Filename as listed in the filelist element from package.xml - * 2. Full path to the installed file - * 3. Full path from the php_dir configuration variable used in this - * installation - * 4. Relative path from the php_dir that this file is installed in + * @param array dependency information (2.0 format) + * @param boolean whether this is a required dependency + * @param array a list of downloaded packages to be installed, if any + * @param boolean if true, then deps on pear.php.net that fail will also check + * against pecl.php.net packages to accomodate extensions that have + * moved to pecl.php.net from pear.php.net */ - function addFileOperation($type, $data) + function validatePackageDependency($dep, $required, $params, $depv1 = false) { - if (!is_array($data)) { - return $this->raiseError('Internal Error: $data in addFileOperation' - . ' must be an array, was ' . gettype($data)); + if ($this->_state != PEAR_VALIDATE_INSTALLING && + $this->_state != PEAR_VALIDATE_DOWNLOADING) { + return true; } - if ($type == 'chmod') { - $octmode = decoct($data[0]); - $this->log(3, "adding to transaction: $type $octmode $data[1]"); - } else { - $this->log(3, "adding to transaction: $type " . implode(" ", $data)); + if (isset($dep['providesextension'])) { + if ($this->extension_loaded($dep['providesextension'])) { + $save = $dep; + $subdep = $dep; + $subdep['name'] = $subdep['providesextension']; + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $ret = $this->validateExtensionDependency($subdep, $required); + PEAR::popErrorHandling(); + if (!PEAR::isError($ret)) { + return true; + } + } } - $this->file_operations[] = array($type, $data); - } - // }}} - // {{{ startFileTransaction() + if ($this->_state == PEAR_VALIDATE_INSTALLING) { + return $this->_validatePackageInstall($dep, $required, $depv1); + } - function startFileTransaction($rollback_in_case = false) - { - if (count($this->file_operations) && $rollback_in_case) { - $this->rollbackFileTransaction(); + if ($this->_state == PEAR_VALIDATE_DOWNLOADING) { + return $this->_validatePackageDownload($dep, $required, $params, $depv1); } - $this->file_operations = array(); } - // }}} - // {{{ commitFileTransaction() - - function commitFileTransaction() + function _validatePackageDownload($dep, $required, $params, $depv1 = false) { - $n = count($this->file_operations); - $this->log(2, "about to commit $n file operations"); - // {{{ first, check permissions and such manually - $errors = array(); - foreach ($this->file_operations as $tr) { - list($type, $data) = $tr; - switch ($type) { - case 'rename': - if (!file_exists($data[0])) { - $errors[] = "cannot rename file $data[0], doesn't exist"; - } + $dep['package'] = $dep['name']; + if (isset($dep['uri'])) { + $dep['channel'] = '__uri'; + } - // check that dest dir. is writable - if (!is_writable(dirname($data[1]))) { - $errors[] = "permission denied ($type): $data[1]"; - } - break; - case 'chmod': - // check that file is writable - if (!is_writable($data[1])) { - $errors[] = "permission denied ($type): $data[1] " . decoct($data[0]); - } - break; - case 'delete': - if (!file_exists($data[0])) { - $this->log(2, "warning: file $data[0] doesn't exist, can't be deleted"); - } - // check that directory is writable - if (file_exists($data[0])) { - if (!is_writable(dirname($data[0]))) { - $errors[] = "permission denied ($type): $data[0]"; - } else { - // make sure the file to be deleted can be opened for writing - $fp = false; - if (!is_dir($data[0]) && - (!is_writable($data[0]) || !($fp = @fopen($data[0], 'a')))) { - $errors[] = "permission denied ($type): $data[0]"; - } elseif ($fp) { - fclose($fp); - } - } - } - break; + $depname = $this->_registry->parsedPackageNameToString($dep, true); + $found = false; + foreach ($params as $param) { + if ($param->isEqual( + array('package' => $dep['name'], + 'channel' => $dep['channel']))) { + $found = true; + break; } - } - // }}} - $m = count($errors); - if ($m > 0) { - foreach ($errors as $error) { - if (!isset($this->_options['soft'])) { - $this->log(1, $error); + if ($depv1 && $dep['channel'] == 'pear.php.net') { + if ($param->isEqual( + array('package' => $dep['name'], + 'channel' => 'pecl.php.net'))) { + $found = true; + break; } } + } - if (!isset($this->_options['ignore-errors'])) { - return false; + if (!$found && isset($dep['providesextension'])) { + foreach ($params as $param) { + if ($param->isExtension($dep['providesextension'])) { + $found = true; + break; + } } } - $this->_dirtree = array(); - // {{{ really commit the transaction - foreach ($this->file_operations as $i => $tr) { - if (!$tr) { - // support removal of non-existing backups - continue; + if ($found) { + $version = $param->getVersion(); + $installed = false; + $downloaded = true; + } else { + if ($this->_registry->packageExists($dep['name'], $dep['channel'])) { + $installed = true; + $downloaded = false; + $version = $this->_registry->packageinfo($dep['name'], 'version', + $dep['channel']); + } else { + if ($dep['channel'] == 'pecl.php.net' && $this->_registry->packageExists($dep['name'], + 'pear.php.net')) { + $installed = true; + $downloaded = false; + $version = $this->_registry->packageinfo($dep['name'], 'version', + 'pear.php.net'); + } else { + $version = 'not installed or downloaded'; + $installed = false; + $downloaded = false; + } } + } - list($type, $data) = $tr; - switch ($type) { - case 'backup': - if (!file_exists($data[0])) { - $this->file_operations[$i] = false; - break; - } + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude']) && !is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } - if (!@copy($data[0], $data[0] . '.bak')) { - $this->log(1, 'Could not copy ' . $data[0] . ' to ' . $data[0] . - '.bak ' . $php_errormsg); - return false; - } - $this->log(3, "+ backup $data[0] to $data[0].bak"); - break; - case 'removebackup': - if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { - unlink($data[0] . '.bak'); - $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); + if (!isset($dep['min']) && !isset($dep['max']) && + !isset($dep['recommended']) && !isset($dep['exclude']) + ) { + if ($installed || $downloaded) { + $installed = $installed ? 'installed' : 'downloaded'; + if (isset($dep['conflicts'])) { + $rest = ''; + if ($version) { + $rest = ", $installed version is " . $version; } - break; - case 'rename': - $test = file_exists($data[1]) ? @unlink($data[1]) : null; - if (!$test && file_exists($data[1])) { - if ($data[2]) { - $extra = ', this extension must be installed manually. Rename to "' . - basename($data[1]) . '"'; - } else { - $extra = ''; - } - - if (!isset($this->_options['soft'])) { - $this->log(1, 'Could not delete ' . $data[1] . ', cannot rename ' . - $data[0] . $extra); - } - if (!isset($this->_options['ignore-errors'])) { - return false; - } + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . $rest); } - // permissions issues with rename - copy() is far superior - $perms = @fileperms($data[0]); - if (!@copy($data[0], $data[1])) { - $this->log(1, 'Could not rename ' . $data[0] . ' to ' . $data[1] . - ' ' . $php_errormsg); - return false; - } + return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . $rest); + } - // copy over permissions, otherwise they are lost - @chmod($data[1], $perms); - @unlink($data[0]); - $this->log(3, "+ mv $data[0] $data[1]"); - break; - case 'chmod': - if (!@chmod($data[1], $data[0])) { - $this->log(1, 'Could not chmod ' . $data[1] . ' to ' . - decoct($data[0]) . ' ' . $php_errormsg); - return false; - } + return true; + } - $octmode = decoct($data[0]); - $this->log(3, "+ chmod $octmode $data[1]"); - break; - case 'delete': - if (file_exists($data[0])) { - if (!@unlink($data[0])) { - $this->log(1, 'Could not delete ' . $data[0] . ' ' . - $php_errormsg); - return false; - } - $this->log(3, "+ rm $data[0]"); - } - break; - case 'rmdir': - if (file_exists($data[0])) { - do { - $testme = opendir($data[0]); - while (false !== ($entry = readdir($testme))) { - if ($entry == '.' || $entry == '..') { - continue; - } - closedir($testme); - break 2; // this directory is not empty and can't be - // deleted - } + if (isset($dep['conflicts'])) { + return true; + } - closedir($testme); - if (!@rmdir($data[0])) { - $this->log(1, 'Could not rmdir ' . $data[0] . ' ' . - $php_errormsg); - return false; - } - $this->log(3, "+ rmdir $data[0]"); - } while (false); - } - break; - case 'installed_as': - $this->pkginfo->setInstalledAs($data[0], $data[1]); - if (!isset($this->_dirtree[dirname($data[1])])) { - $this->_dirtree[dirname($data[1])] = true; - $this->pkginfo->setDirtree(dirname($data[1])); + if ($required) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires package "' . $depname . '"' . $extra); + } - while(!empty($data[3]) && dirname($data[3]) != $data[3] && - $data[3] != '/' && $data[3] != '\\') { - $this->pkginfo->setDirtree($pp = - $this->_prependPath($data[3], $data[2])); - $this->_dirtree[$pp] = true; - $data[3] = dirname($data[3]); - } - } - break; + return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); } + + return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); } - // }}} - $this->log(2, "successfully committed $n file operations"); - $this->file_operations = array(); - return true; - } - // }}} - // {{{ rollbackFileTransaction() + if (!$installed && !$downloaded) { + if (isset($dep['conflicts'])) { + return true; + } - function rollbackFileTransaction() - { - $n = count($this->file_operations); - $this->log(2, "rolling back $n file operations"); - foreach ($this->file_operations as $tr) { - list($type, $data) = $tr; - switch ($type) { - case 'backup': - if (file_exists($data[0] . '.bak')) { - if (file_exists($data[0] && is_writable($data[0]))) { - unlink($data[0]); - } - @copy($data[0] . '.bak', $data[0]); - $this->log(3, "+ restore $data[0] from $data[0].bak"); - } - break; - case 'removebackup': - if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { - unlink($data[0] . '.bak'); - $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); - } - break; - case 'rename': - @unlink($data[0]); - $this->log(3, "+ rm $data[0]"); - break; - case 'mkdir': - @rmdir($data[0]); - $this->log(3, "+ rmdir $data[0]"); - break; - case 'chmod': - break; - case 'delete': - break; - case 'installed_as': - $this->pkginfo->setInstalledAs($data[0], false); - break; + if ($required) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires package "' . $depname . '"' . $extra); + } + + return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); } + + return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); } - $this->pkginfo->resetDirtree(); - $this->file_operations = array(); - } - // }}} - // {{{ mkDirHier($dir) + $fail = false; + if (isset($dep['min']) && version_compare($version, $dep['min'], '<')) { + $fail = true; + } - function mkDirHier($dir) - { - $this->addFileOperation('mkdir', array($dir)); - return parent::mkDirHier($dir); - } + if (isset($dep['max']) && version_compare($version, $dep['max'], '>')) { + $fail = true; + } - // }}} - // {{{ download() + if ($fail && !isset($dep['conflicts'])) { + $installed = $installed ? 'installed' : 'downloaded'; + $dep['package'] = $dep['name']; + $dep = $this->_registry->parsedPackageNameToString($dep, true); + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } - /** - * Download any files and their dependencies, if necessary - * - * @param array a mixed list of package names, local files, or package.xml - * @param PEAR_Config - * @param array options from the command line - * @param array this is the array that will be populated with packages to - * install. Format of each entry: - * - * - * array('pkg' => 'package_name', 'file' => '/path/to/local/file', - * 'info' => array() // parsed package.xml - * ); - * - * @param array this will be populated with any error messages - * @param false private recursion variable - * @param false private recursion variable - * @param false private recursion variable - * @deprecated in favor of PEAR_Downloader - */ - function download($packages, $options, &$config, &$installpackages, - &$errors, $installed = false, $willinstall = false, $state = false) - { - // trickiness: initialize here - parent::PEAR_Downloader($this->ui, $options, $config); - $ret = parent::download($packages); - $errors = $this->getErrorMsgs(); - $installpackages = $this->getDownloadedPackages(); - trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " . - "in favor of PEAR_Downloader class", E_USER_WARNING); - return $ret; - } + return $this->warning('warning: %s requires package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && + isset($dep['conflicts']) && !isset($dep['exclude'])) { + $installed = $installed ? 'installed' : 'downloaded'; + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . + ", $installed version is " . $version); + } - // }}} - // {{{ _parsePackageXml() + return $this->warning('warning: %s conflicts with package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } - function _parsePackageXml(&$descfile, &$tmpdir) - { - if (substr($descfile, -4) == '.xml') { - $tmpdir = false; - } else { - // {{{ Decompress pack in tmp dir ------------------------------------- + if (isset($dep['exclude'])) { + $installed = $installed ? 'installed' : 'downloaded'; + foreach ($dep['exclude'] as $exclude) { + if (version_compare($version, $exclude, '==') && !isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && + !isset($this->_options['force']) + ) { + return $this->raiseError('%s is not compatible with ' . + $installed . ' package "' . + $depname . '" version ' . + $exclude); + } - // To allow relative package file names - $descfile = realpath($descfile); + return $this->warning('warning: %s is not compatible with ' . + $installed . ' package "' . + $depname . '" version ' . + $exclude); + } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { + $installed = $installed ? 'installed' : 'downloaded'; + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } - if (PEAR::isError($tmpdir = System::mktemp('-d'))) { - return $tmpdir; + return $this->warning('warning: %s conflicts with package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } } - $this->log(3, '+ tmp dir created at ' . $tmpdir); - // }}} } - // Parse xml file ----------------------------------------------- - $pkg = new PEAR_PackageFile($this->config, $this->debug, $tmpdir); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $p = &$pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($p)) { - if (is_array($p->getUserInfo())) { - foreach ($p->getUserInfo() as $err) { - $loglevel = $err['level'] == 'error' ? 0 : 1; - if (!isset($this->_options['soft'])) { - $this->log($loglevel, ucfirst($err['level']) . ': ' . $err['message']); + if (isset($dep['recommended'])) { + $installed = $installed ? 'installed' : 'downloaded'; + if (version_compare($version, $dep['recommended'], '==')) { + return true; + } + + if (!$found && $installed) { + $param = $this->_registry->getPackage($dep['name'], $dep['channel']); + } + + if ($param) { + $found = false; + foreach ($params as $parent) { + if ($parent->isEqual($this->_currentPackage)) { + $found = true; + break; + } + } + + if ($found) { + if ($param->isCompatible($parent)) { + return true; + } + } else { // this is for validPackage() calls + $parent = $this->_registry->getPackage($this->_currentPackage['package'], + $this->_currentPackage['channel']); + if ($parent !== null && $param->isCompatible($parent)) { + return true; } } } - return $this->raiseError('Installation failed: invalid package file'); - } - $descfile = $p->getPackageFile(); - return $p; - } + if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) && + !isset($this->_options['loose']) + ) { + return $this->raiseError('%s dependency package "' . $depname . + '" ' . $installed . ' version ' . $version . + ' is not the recommended version ' . $dep['recommended'] . + ', but may be compatible, use --force to install'); + } - // }}} - /** - * Set the list of PEAR_Downloader_Package objects to allow more sane - * dependency validation - * @param array - */ - function setDownloadedPackages(&$pkgs) - { - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $err = $this->analyzeDependencies($pkgs); - PEAR::popErrorHandling(); - if (PEAR::isError($err)) { - return $err; + return $this->warning('warning: %s dependency package "' . $depname . + '" ' . $installed . ' version ' . $version . + ' is not the recommended version ' . $dep['recommended']); } - $this->_downloadedPackages = &$pkgs; - } - /** - * Set the list of PEAR_Downloader_Package objects to allow more sane - * dependency validation - * @param array - */ - function setUninstallPackages(&$pkgs) - { - $this->_downloadedPackages = &$pkgs; + return true; } - function getInstallPackages() + function _validatePackageInstall($dep, $required, $depv1 = false) { - return $this->_downloadedPackages; + return $this->_validatePackageDownload($dep, $required, array(), $depv1); } - // {{{ install() - /** - * Installs the files within the package file specified. - * - * @param string|PEAR_Downloader_Package $pkgfile path to the package file, - * or a pre-initialized packagefile object - * @param array $options - * recognized options: - * - installroot : optional prefix directory for installation - * - force : force installation - * - register-only : update registry but don't install files - * - upgrade : upgrade existing install - * - soft : fail silently - * - nodeps : ignore dependency conflicts/missing dependencies - * - alldeps : install all dependencies - * - onlyreqdeps : install only required dependencies + * Verify that uninstalling packages passed in to command line is OK. * - * @return array|PEAR_Error package info if successful + * @param PEAR_Installer $dl + * @return PEAR_Error|true */ - - function install($pkgfile, $options = array()) + function validatePackageUninstall(&$dl) { - $this->_options = $options; - $this->_registry = &$this->config->getRegistry(); - if (is_object($pkgfile)) { - $dlpkg = &$pkgfile; - $pkg = $pkgfile->getPackageFile(); - $pkgfile = $pkg->getArchiveFile(); - $descfile = $pkg->getPackageFile(); - $tmpdir = dirname($descfile); - } else { - $descfile = $pkgfile; - $tmpdir = ''; - $pkg = &$this->_parsePackageXml($descfile, $tmpdir); - if (PEAR::isError($pkg)) { - return $pkg; - } + if (PEAR::isError($this->_dependencydb)) { + return $this->_dependencydb; } - if (realpath($descfile) != realpath($pkgfile)) { - $tar = new Archive_Tar($pkgfile); - if (!$tar->extract($tmpdir)) { - return $this->raiseError("unable to unpack $pkgfile"); + $params = array(); + // construct an array of "downloaded" packages to fool the package dependency checker + // into using these to validate uninstalls of circular dependencies + $downloaded = &$dl->getUninstallPackages(); + foreach ($downloaded as $i => $pf) { + if (!class_exists('PEAR_Downloader_Package')) { + require_once 'PEAR/Downloader/Package.php'; } + $dp = &new PEAR_Downloader_Package($dl); + $dp->setPackageFile($downloaded[$i]); + $params[$i] = &$dp; } - $pkgname = $pkg->getName(); - $channel = $pkg->getChannel(); - if (isset($this->_options['packagingroot'])) { - $regdir = $this->_prependPath( - $this->config->get('php_dir', null, 'pear.php.net'), - $this->_options['packagingroot']); - - $packrootphp_dir = $this->_prependPath( - $this->config->get('php_dir', null, $channel), - $this->_options['packagingroot']); - } - - if (isset($options['installroot'])) { - $this->config->setInstallRoot($options['installroot']); - $this->_registry = &$this->config->getRegistry(); - $installregistry = &$this->_registry; - $this->installroot = ''; // all done automagically now - $php_dir = $this->config->get('php_dir', null, $channel); - } else { - $this->config->setInstallRoot(false); - $this->_registry = &$this->config->getRegistry(); - if (isset($this->_options['packagingroot'])) { - $installregistry = &new PEAR_Registry($regdir); - if (!$installregistry->channelExists($channel, true)) { - // we need to fake a channel-discover of this channel - $chanobj = $this->_registry->getChannel($channel, true); - $installregistry->addChannel($chanobj); + // check cache + $memyselfandI = strtolower($this->_currentPackage['channel']) . '/' . + strtolower($this->_currentPackage['package']); + if (isset($dl->___uninstall_package_cache)) { + $badpackages = $dl->___uninstall_package_cache; + if (isset($badpackages[$memyselfandI]['warnings'])) { + foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { + $dl->log(0, $warning[0]); } - $php_dir = $packrootphp_dir; - } else { - $installregistry = &$this->_registry; - $php_dir = $this->config->get('php_dir', null, $channel); } - $this->installroot = ''; - } - // {{{ checks to do when not in "force" mode - if (empty($options['force']) && - (file_exists($this->config->get('php_dir')) && - is_dir($this->config->get('php_dir')))) { - $testp = $channel == 'pear.php.net' ? $pkgname : array($channel, $pkgname); - $instfilelist = $pkg->getInstallationFileList(true); - if (PEAR::isError($instfilelist)) { - return $instfilelist; - } + if (isset($badpackages[$memyselfandI]['errors'])) { + foreach ($badpackages[$memyselfandI]['errors'] as $error) { + if (is_array($error)) { + $dl->log(0, $error[0]); + } else { + $dl->log(0, $error->getMessage()); + } + } - // ensure we have the most accurate registry - $installregistry->flushFileMap(); - $test = $installregistry->checkFileMap($instfilelist, $testp, '1.1'); - if (PEAR::isError($test)) { - return $test; + if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { + return $this->warning( + 'warning: %s should not be uninstalled, other installed packages depend ' . + 'on this package'); + } + + return $this->raiseError( + '%s cannot be uninstalled, other installed packages depend on this package'); } - if (sizeof($test)) { - $pkgs = $this->getInstallPackages(); - $found = false; - foreach ($pkgs as $param) { - if ($pkg->isSubpackageOf($param)) { - $found = true; - break; - } - } + return true; + } - if ($found) { - // subpackages can conflict with earlier versions of parent packages - $parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel()); - $tmp = $test; - foreach ($tmp as $file => $info) { - if (is_array($info)) { - if (strtolower($info[1]) == strtolower($param->getPackage()) && - strtolower($info[0]) == strtolower($param->getChannel()) - ) { - if (isset($parentreg['filelist'][$file])) { - unset($parentreg['filelist'][$file]); - } else{ - $pos = strpos($file, '/'); - $basedir = substr($file, 0, $pos); - $file2 = substr($file, $pos + 1); - if (isset($parentreg['filelist'][$file2]['baseinstalldir']) - && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir - ) { - unset($parentreg['filelist'][$file2]); - } - } + // first, list the immediate parents of each package to be uninstalled + $perpackagelist = array(); + $allparents = array(); + foreach ($params as $i => $param) { + $a = array( + 'channel' => strtolower($param->getChannel()), + 'package' => strtolower($param->getPackage()) + ); - unset($test[$file]); + $deps = $this->_dependencydb->getDependentPackages($a); + if ($deps) { + foreach ($deps as $d) { + $pardeps = $this->_dependencydb->getDependencies($d); + foreach ($pardeps as $dep) { + if (strtolower($dep['dep']['channel']) == $a['channel'] && + strtolower($dep['dep']['name']) == $a['package']) { + if (!isset($perpackagelist[$a['channel'] . '/' . $a['package']])) { + $perpackagelist[$a['channel'] . '/' . $a['package']] = array(); } - } else { - if (strtolower($param->getChannel()) != 'pear.php.net') { - continue; + $perpackagelist[$a['channel'] . '/' . $a['package']][] + = array($d['channel'] . '/' . $d['package'], $dep); + if (!isset($allparents[$d['channel'] . '/' . $d['package']])) { + $allparents[$d['channel'] . '/' . $d['package']] = array(); } - - if (strtolower($info) == strtolower($param->getPackage())) { - if (isset($parentreg['filelist'][$file])) { - unset($parentreg['filelist'][$file]); - } else{ - $pos = strpos($file, '/'); - $basedir = substr($file, 0, $pos); - $file2 = substr($file, $pos + 1); - if (isset($parentreg['filelist'][$file2]['baseinstalldir']) - && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir - ) { - unset($parentreg['filelist'][$file2]); - } - } - - unset($test[$file]); + if (!isset($allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']])) { + $allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']] = array(); } + $allparents[$d['channel'] . '/' . $d['package']] + [$a['channel'] . '/' . $a['package']][] + = array($d, $dep); } } - - $pfk = &new PEAR_PackageFile($this->config); - $parentpkg = &$pfk->fromArray($parentreg); - $installregistry->updatePackage2($parentpkg); } + } + } - if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) { - $tmp = $test; - foreach ($tmp as $file => $info) { - if (is_string($info)) { - // pear.php.net packages are always stored as strings - if (strtolower($info) == strtolower($param->getPackage())) { - // upgrading existing package - unset($test[$file]); - } - } - } + // next, remove any packages from the parents list that are not installed + $remove = array(); + foreach ($allparents as $parent => $d1) { + foreach ($d1 as $d) { + if ($this->_registry->packageExists($d[0][0]['package'], $d[0][0]['channel'])) { + continue; } + $remove[$parent] = true; + } + } - if (count($test)) { - $msg = "$channel/$pkgname: conflicting files found:\n"; - $longest = max(array_map("strlen", array_keys($test))); - $fmt = "%${longest}s (%s)\n"; - foreach ($test as $file => $info) { - if (!is_array($info)) { - $info = array('pear.php.net', $info); - } - $info = $info[0] . '/' . $info[1]; - $msg .= sprintf($fmt, $file, $info); - } - - if (!isset($options['ignore-errors'])) { - return $this->raiseError($msg); - } - - if (!isset($options['soft'])) { - $this->log(0, "WARNING: $msg"); + // next remove any packages from the parents list that are not passed in for + // uninstallation + foreach ($allparents as $parent => $d1) { + foreach ($d1 as $d) { + foreach ($params as $param) { + if (strtolower($param->getChannel()) == $d[0][0]['channel'] && + strtolower($param->getPackage()) == $d[0][0]['package']) { + // found it + continue 3; } } + $remove[$parent] = true; } } - // }}} - - $this->startFileTransaction(); - if (empty($options['upgrade']) && empty($options['soft'])) { - // checks to do only when installing new packages - if ($channel == 'pecl.php.net') { - $test = $installregistry->packageExists($pkgname, $channel); - if (!$test) { - $test = $installregistry->packageExists($pkgname, 'pear.php.net'); + // remove all packages whose dependencies fail + // save which ones failed for error reporting + $badchildren = array(); + do { + $fail = false; + foreach ($remove as $package => $unused) { + if (!isset($allparents[$package])) { + continue; } - } else { - $test = $installregistry->packageExists($pkgname, $channel); - } - if (empty($options['force']) && $test) { - return $this->raiseError("$channel/$pkgname is already installed"); - } - } else { - $usechannel = $channel; - if ($channel == 'pecl.php.net') { - $test = $installregistry->packageExists($pkgname, $channel); - if (!$test) { - $test = $installregistry->packageExists($pkgname, 'pear.php.net'); - $usechannel = 'pear.php.net'; + foreach ($allparents[$package] as $kid => $d1) { + foreach ($d1 as $depinfo) { + if ($depinfo[1]['type'] != 'optional') { + if (isset($badchildren[$kid])) { + continue; + } + $badchildren[$kid] = true; + $remove[$kid] = true; + $fail = true; + continue 2; + } + } + } + if ($fail) { + // start over, we removed some children + continue 2; } - } else { - $test = $installregistry->packageExists($pkgname, $channel); } + } while ($fail); - if ($test) { - $v1 = $installregistry->packageInfo($pkgname, 'version', $usechannel); - $v2 = $pkg->getVersion(); - $cmp = version_compare("$v1", "$v2", 'gt'); - if (empty($options['force']) && !version_compare("$v2", "$v1", 'gt')) { - return $this->raiseError("upgrade to a newer version ($v2 is not newer than $v1)"); + // next, construct the list of packages that can't be uninstalled + $badpackages = array(); + $save = $this->_currentPackage; + foreach ($perpackagelist as $package => $packagedeps) { + foreach ($packagedeps as $parent) { + if (!isset($remove[$parent[0]])) { + continue; } - if (empty($options['register-only'])) { - // when upgrading, remove old release's files first: - if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel, - true))) { - if (!isset($options['ignore-errors'])) { - return $this->raiseError($err); - } - - if (!isset($options['soft'])) { - $this->log(0, 'WARNING: ' . $err->getMessage()); - } - } else { - $backedup = $err; + $packagename = $this->_registry->parsePackageName($parent[0]); + $packagename['channel'] = $this->_registry->channelAlias($packagename['channel']); + $pa = $this->_registry->getPackage($packagename['package'], $packagename['channel']); + $packagename['package'] = $pa->getPackage(); + $this->_currentPackage = $packagename; + // parent is not present in uninstall list, make sure we can actually + // uninstall it (parent dep is optional) + $parentname['channel'] = $this->_registry->channelAlias($parent[1]['dep']['channel']); + $pa = $this->_registry->getPackage($parent[1]['dep']['name'], $parent[1]['dep']['channel']); + $parentname['package'] = $pa->getPackage(); + $parent[1]['dep']['package'] = $parentname['package']; + $parent[1]['dep']['channel'] = $parentname['channel']; + if ($parent[1]['type'] == 'optional') { + $test = $this->_validatePackageUninstall($parent[1]['dep'], false, $dl); + if ($test !== true) { + $badpackages[$package]['warnings'][] = $test; + } + } else { + $test = $this->_validatePackageUninstall($parent[1]['dep'], true, $dl); + if ($test !== true) { + $badpackages[$package]['errors'][] = $test; } } } } - // {{{ Copy files to dest dir --------------------------------------- + $this->_currentPackage = $save; + $dl->___uninstall_package_cache = $badpackages; + if (isset($badpackages[$memyselfandI])) { + if (isset($badpackages[$memyselfandI]['warnings'])) { + foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { + $dl->log(0, $warning[0]); + } + } - // info from the package it self we want to access from _installFile - $this->pkginfo = &$pkg; - // used to determine whether we should build any C code - $this->source_files = 0; + if (isset($badpackages[$memyselfandI]['errors'])) { + foreach ($badpackages[$memyselfandI]['errors'] as $error) { + if (is_array($error)) { + $dl->log(0, $error[0]); + } else { + $dl->log(0, $error->getMessage()); + } + } - $savechannel = $this->config->get('default_channel'); - if (empty($options['register-only']) && !is_dir($php_dir)) { - if (PEAR::isError(System::mkdir(array('-p'), $php_dir))) { - return $this->raiseError("no installation destination directory '$php_dir'\n"); - } - } + if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { + return $this->warning( + 'warning: %s should not be uninstalled, other installed packages depend ' . + 'on this package'); + } - $tmp_path = dirname($descfile); - if (substr($pkgfile, -4) != '.xml') { - $tmp_path .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion(); + return $this->raiseError( + '%s cannot be uninstalled, other installed packages depend on this package'); + } } - $this->configSet('default_channel', $channel); - // {{{ install files + return true; + } - $ver = $pkg->getPackagexmlVersion(); - if (version_compare($ver, '2.0', '>=')) { - $filelist = $pkg->getInstallationFilelist(); - } else { - $filelist = $pkg->getFileList(); + function _validatePackageUninstall($dep, $required, $dl) + { + $depname = $this->_registry->parsedPackageNameToString($dep, true); + $version = $this->_registry->packageinfo($dep['package'], 'version', $dep['channel']); + if (!$version) { + return true; } - if (PEAR::isError($filelist)) { - return $filelist; + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude']) && !is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); } - $p = &$installregistry->getPackage($pkgname, $channel); - if (empty($options['register-only']) && $p) { - $dirtree = $p->getDirTree(); - } else { - $dirtree = false; + if (isset($dep['conflicts'])) { + return true; // uninstall OK - these packages conflict (probably installed with --force) } - $pkg->resetFilelist(); - $pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(), - 'version', $pkg->getChannel())); - foreach ($filelist as $file => $atts) { - $this->expectError(PEAR_INSTALLER_FAILED); - if ($pkg->getPackagexmlVersion() == '1.0') { - $res = $this->_installFile($file, $atts, $tmp_path, $options); - } else { - $res = $this->_installFile2($pkg, $file, $atts, $tmp_path, $options); + if (!isset($dep['min']) && !isset($dep['max'])) { + if (!$required) { + return $this->warning('"' . $depname . '" can be optionally used by ' . + 'installed package %s' . $extra); } - $this->popExpect(); - - if (PEAR::isError($res)) { - if (empty($options['ignore-errors'])) { - $this->rollbackFileTransaction(); - if ($res->getMessage() == "file does not exist") { - $this->raiseError("file $file in package.xml does not exist"); - } - return $this->raiseError($res); - } - - if (!isset($options['soft'])) { - $this->log(0, "Warning: " . $res->getMessage()); - } + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('"' . $depname . '" is required by ' . + 'installed package %s' . $extra); } - $real = isset($atts['attribs']) ? $atts['attribs'] : $atts; - if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') { - // Register files that were installed - $pkg->installedFile($file, $atts); - } + return $this->warning('warning: "' . $depname . '" is required by ' . + 'installed package %s' . $extra); } - // }}} - // {{{ compile and install source files - if ($this->source_files > 0 && empty($options['nobuild'])) { - if (PEAR::isError($err = - $this->_compileSourceFiles($savechannel, $pkg))) { - return $err; - } + $fail = false; + if (isset($dep['min']) && version_compare($version, $dep['min'], '>=')) { + $fail = true; } - // }}} - if (isset($backedup)) { - $this->_removeBackups($backedup); + if (isset($dep['max']) && version_compare($version, $dep['max'], '<=')) { + $fail = true; } - if (!$this->commitFileTransaction()) { - $this->rollbackFileTransaction(); - $this->configSet('default_channel', $savechannel); - return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED); + // we re-use this variable, preserve the original value + $saverequired = $required; + if (!$required) { + return $this->warning($depname . $extra . ' can be optionally used by installed package' . + ' "%s"'); } - // }}} - $ret = false; - $installphase = 'install'; - $oldversion = false; - // {{{ Register that the package is installed ----------------------- - if (empty($options['upgrade'])) { - // if 'force' is used, replace the info in registry - $usechannel = $channel; - if ($channel == 'pecl.php.net') { - $test = $installregistry->packageExists($pkgname, $channel); - if (!$test) { - $test = $installregistry->packageExists($pkgname, 'pear.php.net'); - $usechannel = 'pear.php.net'; - } - } else { - $test = $installregistry->packageExists($pkgname, $channel); - } + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError($depname . $extra . ' is required by installed package' . + ' "%s"'); + } - if (!empty($options['force']) && $test) { - $oldversion = $installregistry->packageInfo($pkgname, 'version', $usechannel); - $installregistry->deletePackage($pkgname, $usechannel); - } - $ret = $installregistry->addPackage2($pkg); + return $this->raiseError('warning: ' . $depname . $extra . + ' is required by installed package "%s"'); + } + + /** + * validate a downloaded package against installed packages + * + * As of PEAR 1.4.3, this will only validate + * + * @param array|PEAR_Downloader_Package|PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * $pkg package identifier (either + * array('package' => blah, 'channel' => blah) or an array with + * index 'info' referencing an object) + * @param PEAR_Downloader $dl + * @param array $params full list of packages to install + * @return true|PEAR_Error + */ + function validatePackage($pkg, &$dl, $params = array()) + { + if (is_array($pkg) && isset($pkg['info'])) { + $deps = $this->_dependencydb->getDependentPackageDependencies($pkg['info']); } else { - if ($dirtree) { - $this->startFileTransaction(); - // attempt to delete empty directories - uksort($dirtree, array($this, '_sortDirs')); - foreach($dirtree as $dir => $notused) { - $this->addFileOperation('rmdir', array($dir)); - } - $this->commitFileTransaction(); + $deps = $this->_dependencydb->getDependentPackageDependencies($pkg); + } + + $fail = false; + if ($deps) { + if (!class_exists('PEAR_Downloader_Package')) { + require_once 'PEAR/Downloader/Package.php'; } - $usechannel = $channel; - if ($channel == 'pecl.php.net') { - $test = $installregistry->packageExists($pkgname, $channel); - if (!$test) { - $test = $installregistry->packageExists($pkgname, 'pear.php.net'); - $usechannel = 'pear.php.net'; - } + $dp = &new PEAR_Downloader_Package($dl); + if (is_object($pkg)) { + $dp->setPackageFile($pkg); } else { - $test = $installregistry->packageExists($pkgname, $channel); + $dp->setDownloadURL($pkg); } - // new: upgrade installs a package if it isn't installed - if (!$test) { - $ret = $installregistry->addPackage2($pkg); - } else { - if ($usechannel != $channel) { - $installregistry->deletePackage($pkgname, $usechannel); - $ret = $installregistry->addPackage2($pkg); - } else { - $ret = $installregistry->updatePackage2($pkg); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + foreach ($deps as $channel => $info) { + foreach ($info as $package => $ds) { + foreach ($params as $packd) { + if (strtolower($packd->getPackage()) == strtolower($package) && + $packd->getChannel() == $channel) { + $dl->log(3, 'skipping installed package check of "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $channel, 'package' => $package), + true) . + '", version "' . $packd->getVersion() . '" will be ' . + 'downloaded and installed'); + continue 2; // jump to next package + } + } + + foreach ($ds as $d) { + $checker = &new PEAR_Dependency2($this->_config, $this->_options, + array('channel' => $channel, 'package' => $package), $this->_state); + $dep = $d['dep']; + $required = $d['type'] == 'required'; + $ret = $checker->_validatePackageDownload($dep, $required, array(&$dp)); + if (is_array($ret)) { + $dl->log(0, $ret[0]); + } elseif (PEAR::isError($ret)) { + $dl->log(0, $ret->getMessage()); + $fail = true; + } + } } - $installphase = 'upgrade'; } + PEAR::popErrorHandling(); } - if (!$ret) { - $this->configSet('default_channel', $savechannel); - return $this->raiseError("Adding package $channel/$pkgname to registry failed"); - } - // }}} - - $this->configSet('default_channel', $savechannel); - if (class_exists('PEAR_Task_Common')) { // this is auto-included if any tasks exist - if (PEAR_Task_Common::hasPostinstallTasks()) { - PEAR_Task_Common::runPostinstallTasks($installphase); - } + if ($fail) { + return $this->raiseError( + '%s cannot be installed, conflicts with installed packages'); } - return $pkg->toArray(true); + return true; } - // }}} - - // {{{ _compileSourceFiles() /** - * @param string - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * validate a package.xml 1.0 dependency */ - function _compileSourceFiles($savechannel, &$filelist) + function validateDependency1($dep, $params = array()) { - require_once 'PEAR/Builder.php'; - $this->log(1, "$this->source_files source files, building"); - $bob = &new PEAR_Builder($this->ui); - $bob->debug = $this->debug; - $built = $bob->build($filelist, array(&$this, '_buildCallback')); - if (PEAR::isError($built)) { - $this->rollbackFileTransaction(); - $this->configSet('default_channel', $savechannel); - return $built; + if (!isset($dep['optional'])) { + $dep['optional'] = 'no'; } - $this->log(1, "\nBuild process completed successfully"); - foreach ($built as $ext) { - $bn = basename($ext['file']); - list($_ext_name, $_ext_suff) = explode('.', $bn); - if ($_ext_suff == '.so' || $_ext_suff == '.dll') { - if (extension_loaded($_ext_name)) { - $this->raiseError("Extension '$_ext_name' already loaded. " . - 'Please unload it in your php.ini file ' . - 'prior to install or upgrade'); - } - $role = 'ext'; - } else { - $role = 'src'; - } + list($newdep, $type) = $this->normalizeDep($dep); + if (!$newdep) { + return $this->raiseError("Invalid Dependency"); + } - $dest = $ext['dest']; - $packagingroot = ''; - if (isset($this->_options['packagingroot'])) { - $packagingroot = $this->_options['packagingroot']; - } + if (method_exists($this, "validate{$type}Dependency")) { + return $this->{"validate{$type}Dependency"}($newdep, $dep['optional'] == 'no', + $params, true); + } + } - $copyto = $this->_prependPath($dest, $packagingroot); - if ($copyto != $dest) { - $this->log(1, "Installing '$dest' as '$copyto'"); - } else { - $this->log(1, "Installing '$dest'"); - } + /** + * Convert a 1.0 dep into a 2.0 dep + */ + function normalizeDep($dep) + { + $types = array( + 'pkg' => 'Package', + 'ext' => 'Extension', + 'os' => 'Os', + 'php' => 'Php' + ); - $copydir = dirname($copyto); - // pretty much nothing happens if we are only registering the install - if (empty($this->_options['register-only'])) { - if (!file_exists($copydir) || !is_dir($copydir)) { - if (!$this->mkDirHier($copydir)) { - return $this->raiseError("failed to mkdir $copydir", - PEAR_INSTALLER_FAILED); - } + if (!isset($types[$dep['type']])) { + return array(false, false); + } - $this->log(3, "+ mkdir $copydir"); - } + $type = $types[$dep['type']]; - if (!@copy($ext['file'], $copyto)) { - return $this->raiseError("failed to write $copyto ($php_errormsg)", PEAR_INSTALLER_FAILED); - } + $newdep = array(); + switch ($type) { + case 'Package' : + $newdep['channel'] = 'pear.php.net'; + case 'Extension' : + case 'Os' : + $newdep['name'] = $dep['name']; + break; + } - $this->log(3, "+ cp $ext[file] $copyto"); - $this->addFileOperation('rename', array($ext['file'], $copyto)); - if (!OS_WINDOWS) { - $mode = 0666 & ~(int)octdec($this->config->get('umask')); - $this->addFileOperation('chmod', array($mode, $copyto)); - if (!@chmod($copyto, $mode)) { - $this->log(0, "failed to change mode of $copyto ($php_errormsg)"); - } + $dep['rel'] = PEAR_Dependency2::signOperator($dep['rel']); + switch ($dep['rel']) { + case 'has' : + return array($newdep, $type); + break; + case 'not' : + $newdep['conflicts'] = true; + break; + case '>=' : + case '>' : + $newdep['min'] = $dep['version']; + if ($dep['rel'] == '>') { + $newdep['exclude'] = $dep['version']; + } + break; + case '<=' : + case '<' : + $newdep['max'] = $dep['version']; + if ($dep['rel'] == '<') { + $newdep['exclude'] = $dep['version']; } + break; + case 'ne' : + case '!=' : + $newdep['min'] = '0'; + $newdep['max'] = '100000'; + $newdep['exclude'] = $dep['version']; + break; + case '==' : + $newdep['min'] = $dep['version']; + $newdep['max'] = $dep['version']; + break; + } + if ($type == 'Php') { + if (!isset($newdep['min'])) { + $newdep['min'] = '4.4.0'; } - if ($filelist->getPackageXmlVersion() == '1.0') { - $filelist->installedFile($bn, array( - 'role' => $role, - 'name' => $bn, - 'installed_as' => $dest, - 'php_api' => $ext['php_api'], - 'zend_mod_api' => $ext['zend_mod_api'], - 'zend_ext_api' => $ext['zend_ext_api'], - )); - } else { - $filelist->installedFile($bn, array('attribs' => array( - 'role' => $role, - 'name' => $bn, - 'installed_as' => $dest, - 'php_api' => $ext['php_api'], - 'zend_mod_api' => $ext['zend_mod_api'], - 'zend_ext_api' => $ext['zend_ext_api'], - ))); + if (!isset($newdep['max'])) { + $newdep['max'] = '6.0.0'; } } + return array($newdep, $type); } - // }}} - function &getUninstallPackages() - { - return $this->_downloadedPackages; - } - // {{{ uninstall() - /** - * Uninstall a package + * Converts text comparing operators to them sign equivalents * - * This method removes all files installed by the application, and then - * removes any empty directories. - * @param string package name - * @param array Command-line options. Possibilities include: + * Example: 'ge' to '>=' * - * - installroot: base installation dir, if not the default - * - register-only : update registry but don't remove files - * - nodeps: do not process dependencies of other packages to ensure - * uninstallation does not break things + * @access public + * @param string Operator + * @return string Sign equivalent */ - function uninstall($package, $options = array()) + function signOperator($operator) { - if (isset($options['installroot'])) { - $this->config->setInstallRoot($options['installroot']); - } else { - $this->config->setInstallRoot(''); + switch($operator) { + case 'lt': return '<'; + case 'le': return '<='; + case 'gt': return '>'; + case 'ge': return '>='; + case 'eq': return '=='; + case 'ne': return '!='; + default: + return $operator; } + } - $this->installroot = ''; - $this->_registry = &$this->config->getRegistry(); - if (is_object($package)) { - $channel = $package->getChannel(); - $pkg = $package; - $package = $pkg->getPackage(); - } else { - $pkg = false; - $info = $this->_registry->parsePackageName($package, - $this->config->get('default_channel')); - $channel = $info['channel']; - $package = $info['package']; + function raiseError($msg) + { + if (isset($this->_options['ignore-errors'])) { + return $this->warning($msg); } - $savechannel = $this->config->get('default_channel'); - $this->configSet('default_channel', $channel); - if (!is_object($pkg)) { - $pkg = $this->_registry->getPackage($package, $channel); - } - - if (!$pkg) { - $this->configSet('default_channel', $savechannel); - return $this->raiseError($this->_registry->parsedPackageNameToString( - array( - 'channel' => $channel, - 'package' => $package - ), true) . ' not installed'); - } - - if ($pkg->getInstalledBinary()) { - // this is just an alias for a binary package - return $this->_registry->deletePackage($package, $channel); - } - - $filelist = $pkg->getFilelist(); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - if (!class_exists('PEAR_Dependency2')) { - require_once 'PEAR/Dependency2.php'; - } - - $depchecker = &new PEAR_Dependency2($this->config, $options, - array('channel' => $channel, 'package' => $package), - PEAR_VALIDATE_UNINSTALLING); - $e = $depchecker->validatePackageUninstall($this); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($e)) { - if (!isset($options['ignore-errors'])) { - return $this->raiseError($e); - } - - if (!isset($options['soft'])) { - $this->log(0, 'WARNING: ' . $e->getMessage()); - } - } elseif (is_array($e)) { - if (!isset($options['soft'])) { - $this->log(0, $e[0]); - } - } - - $this->pkginfo = &$pkg; - // pretty much nothing happens if we are only registering the uninstall - if (empty($options['register-only'])) { - // {{{ Delete the files - $this->startFileTransaction(); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - if (PEAR::isError($err = $this->_deletePackageFiles($package, $channel))) { - PEAR::popErrorHandling(); - $this->rollbackFileTransaction(); - $this->configSet('default_channel', $savechannel); - if (!isset($options['ignore-errors'])) { - return $this->raiseError($err); - } - - if (!isset($options['soft'])) { - $this->log(0, 'WARNING: ' . $err->getMessage()); - } - } else { - PEAR::popErrorHandling(); - } - - if (!$this->commitFileTransaction()) { - $this->rollbackFileTransaction(); - if (!isset($options['ignore-errors'])) { - return $this->raiseError("uninstall failed"); - } - - if (!isset($options['soft'])) { - $this->log(0, 'WARNING: uninstall failed'); - } - } else { - $this->startFileTransaction(); - if ($dirtree = $pkg->getDirTree()) { - // attempt to delete empty directories - uksort($dirtree, array($this, '_sortDirs')); - foreach($dirtree as $dir => $notused) { - $this->addFileOperation('rmdir', array($dir)); - } - } else { - $this->configSet('default_channel', $savechannel); - return $this->_registry->deletePackage($package, $channel); - } - - if (!$this->commitFileTransaction()) { - $this->rollbackFileTransaction(); - if (!isset($options['ignore-errors'])) { - return $this->raiseError("uninstall failed"); - } - - if (!isset($options['soft'])) { - $this->log(0, 'WARNING: uninstall failed'); - } - } - } - // }}} - } - - $this->configSet('default_channel', $savechannel); - // Register that the package is no longer installed - return $this->_registry->deletePackage($package, $channel); - } - - /** - * Sort a list of arrays of array(downloaded packagefilename) by dependency. - * - * It also removes duplicate dependencies - * @param array an array of PEAR_PackageFile_v[1/2] objects - * @return array|PEAR_Error array of array(packagefilename, package.xml contents) - */ - function sortPackagesForUninstall(&$packages) - { - $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->config); - if (PEAR::isError($this->_dependencyDB)) { - return $this->_dependencyDB; - } - usort($packages, array(&$this, '_sortUninstall')); - } - - function _sortUninstall($a, $b) - { - if (!$a->getDeps() && !$b->getDeps()) { - return 0; // neither package has dependencies, order is insignificant - } - if ($a->getDeps() && !$b->getDeps()) { - return -1; // $a must be installed after $b because $a has dependencies - } - if (!$a->getDeps() && $b->getDeps()) { - return 1; // $b must be installed after $a because $b has dependencies - } - // both packages have dependencies - if ($this->_dependencyDB->dependsOn($a, $b)) { - return -1; - } - if ($this->_dependencyDB->dependsOn($b, $a)) { - return 1; - } - return 0; - } - - // }}} - // {{{ _sortDirs() - function _sortDirs($a, $b) - { - if (strnatcmp($a, $b) == -1) return 1; - if (strnatcmp($a, $b) == 1) return -1; - return 0; + return PEAR::raiseError(sprintf($msg, $this->_registry->parsedPackageNameToString( + $this->_currentPackage, true))); } - // }}} - - // {{{ _buildCallback() - - function _buildCallback($what, $data) + function warning($msg) { - if (($what == 'cmdoutput' && $this->debug > 1) || - ($what == 'output' && $this->debug > 0)) { - $this->ui->outputData(rtrim($data), 'build'); - } + return array(sprintf($msg, $this->_registry->parsedPackageNameToString( + $this->_currentPackage, true))); } - - // }}} -}PEAR-1.8.0/PEAR/PackageFile.php100664 764 764 37507 100664 10734 + * @author Stig Bakken + * @author Tomas V. V. Cox + * @author Martin Jansen * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PackageFile.php,v 1.48 2009/04/09 22:16:26 dufuz Exp $ + * @version CVS: $Id: Downloader.php 287109 2009-08-11 18:50:30Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 + * @since File available since Release 1.3.0 */ /** - * needed for PEAR_VALIDATE_* constants - */ -require_once 'PEAR/Validate.php'; -/** - * Error code if the package.xml tag does not contain a valid version - */ -define('PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION', 1); -/** - * Error code if the package.xml tag version is not supported (version 1.0 and 1.1 are the only supported versions, - * currently + * Needed for constants, extending */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2); +require_once 'PEAR/Common.php'; + +define('PEAR_INSTALLER_OK', 1); +define('PEAR_INSTALLER_FAILED', 0); +define('PEAR_INSTALLER_SKIPPED', -1); +define('PEAR_INSTALLER_ERROR_NO_PREF_STATE', 2); + /** - * Abstraction for the package.xml package description file + * Administration class used to download anything from the internet (PEAR Packages, + * static URLs, xml files) * * @category pear * @package PEAR * @author Greg Beaver + * @author Stig Bakken + * @author Tomas V. V. Cox + * @author Martin Jansen * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 + * @since Class available since Release 1.3.0 */ -class PEAR_PackageFile +class PEAR_Downloader extends PEAR_Common { /** - * @var PEAR_Config + * @var PEAR_Registry + * @access private */ - var $_config; - var $_debug; + var $_registry; + /** - * Temp directory for uncompressing tgz files. - * @var string|false + * Preferred Installation State (snapshot, devel, alpha, beta, stable) + * @var string|null + * @access private */ - var $_tmpdir; - var $_logger = false; + var $_preferredState; + /** - * @var boolean + * Options from command-line passed to Install. + * + * Recognized options:
    + * - onlyreqdeps : install all required dependencies as well + * - alldeps : install all dependencies, including optional + * - installroot : base relative path to install files in + * - force : force a download even if warnings would prevent it + * - nocompress : download uncompressed tarballs + * @see PEAR_Command_Install + * @access private + * @var array */ - var $_rawReturn = false; + var $_options; /** + * Downloaded Packages after a call to download(). * - * @param PEAR_Config $config - * @param ? $debug - * @param string @tmpdir Optional temporary directory for uncompressing - * files + * Format of each entry: + * + * + * array('pkg' => 'package_name', 'file' => '/path/to/local/file', + * 'info' => array() // parsed package.xml + * ); + * + * @access private + * @var array */ - function PEAR_PackageFile(&$config, $debug = false, $tmpdir = false) - { - $this->_config = $config; - $this->_debug = $debug; - $this->_tmpdir = $tmpdir; - } + var $_downloadedPackages = array(); /** - * Turn off validation - return a parsed package.xml without checking it + * Packages slated for download. * - * This is used by the package-validate command + * This is used to prevent downloading a package more than once should it be a dependency + * for two packages to be installed. + * Format of each entry: + * + *
    +     * array('package_name1' => parsed package.xml, 'package_name2' => parsed package.xml,
    +     * );
    +     * 
    + * @access private + * @var array */ - function rawReturn() - { - $this->_rawReturn = true; - } + var $_toDownload = array(); - function setLogger(&$l) - { - $this->_logger = &$l; - } + /** + * Array of every package installed, with names lower-cased. + * + * Format: + * + * array('package1' => 0, 'package2' => 1, ); + * + * @var array + */ + var $_installed = array(); /** - * Create a PEAR_PackageFile_Parser_v* of a given version. - * @param int $version - * @return PEAR_PackageFile_Parser_v1|PEAR_PackageFile_Parser_v1 + * @var array + * @access private */ - function &parserFactory($version) - { - if (!in_array($version{0}, array('1', '2'))) { - $a = false; - return $a; - } + var $_errorStack = array(); - include_once 'PEAR/PackageFile/Parser/v' . $version{0} . '.php'; - $version = $version{0}; - $class = "PEAR_PackageFile_Parser_v$version"; - $a = new $class; - return $a; - } + /** + * @var boolean + * @access private + */ + var $_internalDownload = false; /** - * For simpler unit-testing - * @return string + * Temporary variable used in sorting packages by dependency in {@link sortPkgDeps()} + * @var array + * @access private */ - function getClassPrefix() - { - return 'PEAR_PackageFile_v'; - } + var $_packageSortTree; /** - * Create a PEAR_PackageFile_v* of a given version. - * @param int $version - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v1 + * Temporary directory, or configuration value where downloads will occur + * @var string */ - function &factory($version) + var $_downloadDir; + + /** + * @param PEAR_Frontend_* + * @param array + * @param PEAR_Config + */ + function PEAR_Downloader(&$ui, $options, &$config) { - if (!in_array($version{0}, array('1', '2'))) { - $a = false; - return $a; + parent::PEAR_Common(); + $this->_options = $options; + $this->config = &$config; + $this->_preferredState = $this->config->get('preferred_state'); + $this->ui = &$ui; + if (!$this->_preferredState) { + // don't inadvertantly use a non-set preferred_state + $this->_preferredState = null; } - include_once 'PEAR/PackageFile/v' . $version{0} . '.php'; - $version = $version{0}; - $class = $this->getClassPrefix() . $version; - $a = new $class; - return $a; + if (isset($this->_options['installroot'])) { + $this->config->setInstallRoot($this->_options['installroot']); + } + $this->_registry = &$config->getRegistry(); + + if (isset($this->_options['alldeps']) || isset($this->_options['onlyreqdeps'])) { + $this->_installed = $this->_registry->listAllPackages(); + foreach ($this->_installed as $key => $unused) { + if (!count($unused)) { + continue; + } + $strtolower = create_function('$a','return strtolower($a);'); + array_walk($this->_installed[$key], $strtolower); + } + } } /** - * Create a PEAR_PackageFile_v* from its toArray() method - * - * WARNING: no validation is performed, the array is assumed to be valid, - * always parse from xml if you want validation. - * @param array $arr - * @return PEAR_PackageFileManager_v1|PEAR_PackageFileManager_v2 - * @uses factory() to construct the returned object. + * Attempt to discover a channel's remote capabilities from + * its server name + * @param string + * @return boolean */ - function &fromArray($arr) + function discover($channel) { - if (isset($arr['xsdversion'])) { - $obj = &$this->factory($arr['xsdversion']); - if ($this->_logger) { - $obj->setLogger($this->_logger); - } + $this->log(1, 'Attempting to discover channel "' . $channel . '"...'); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $callback = $this->ui ? array(&$this, '_downloadCallback') : null; + if (!class_exists('System')) { + require_once 'System.php'; + } - $obj->setConfig($this->_config); - $obj->fromArray($arr); - return $obj; + $tmp = System::mktemp(array('-d')); + $a = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false); + PEAR::popErrorHandling(); + if (PEAR::isError($a)) { + // Attempt to fallback to https automatically. + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $this->log(1, 'Attempting fallback to https instead of http on channel "' . $channel . '"...'); + $a = $this->downloadHttp('https://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false); + PEAR::popErrorHandling(); + if (PEAR::isError($a)) { + return false; + } } - if (isset($arr['package']['attribs']['version'])) { - $obj = &$this->factory($arr['package']['attribs']['version']); - } else { - $obj = &$this->factory('1.0'); + list($a, $lastmodified) = $a; + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; } - if ($this->_logger) { - $obj->setLogger($this->_logger); + $b = new PEAR_ChannelFile; + if ($b->fromXmlFile($a)) { + unlink($a); + if ($this->config->get('auto_discover')) { + $this->_registry->addChannel($b, $lastmodified); + $alias = $b->getName(); + if ($b->getName() == $this->_registry->channelName($b->getAlias())) { + $alias = $b->getAlias(); + } + + $this->log(1, 'Auto-discovered channel "' . $channel . + '", alias "' . $alias . '", adding to registry'); + } + + return true; } - $obj->setConfig($this->_config); - $obj->fromArray($arr); - return $obj; + unlink($a); + return false; } /** - * Create a PEAR_PackageFile_v* from an XML string. - * @access public - * @param string $data contents of package.xml file - * @param int $state package state (one of PEAR_VALIDATE_* constants) - * @param string $file full path to the package.xml file (and the files - * it references) - * @param string $archive optional name of the archive that the XML was - * extracted from, if any - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @uses parserFactory() to construct a parser to load the package. + * For simpler unit-testing + * @param PEAR_Downloader + * @return PEAR_Downloader_Package */ - function &fromXmlString($data, $state, $file, $archive = false) + function &newDownloaderPackage(&$t) { - if (preg_match('/]+version="([0-9]+\.[0-9]+)"/', $data, $packageversion)) { - if (!in_array($packageversion[1], array('1.0', '2.0', '2.1'))) { - return PEAR::raiseError('package.xml version "' . $packageversion[1] . - '" is not supported, only 1.0, 2.0, and 2.1 are supported.'); - } + if (!class_exists('PEAR_Downloader_Package')) { + require_once 'PEAR/Downloader/Package.php'; + } + $a = &new PEAR_Downloader_Package($t); + return $a; + } - $object = &$this->parserFactory($packageversion[1]); - if ($this->_logger) { - $object->setLogger($this->_logger); - } + /** + * For simpler unit-testing + * @param PEAR_Config + * @param array + * @param array + * @param int + */ + function &getDependency2Object(&$c, $i, $p, $s) + { + if (!class_exists('PEAR_Dependency2')) { + require_once 'PEAR/Dependency2.php'; + } + $z = &new PEAR_Dependency2($c, $i, $p, $s); + return $z; + } - $object->setConfig($this->_config); - $pf = $object->parse($data, $file, $archive); - if (PEAR::isError($pf)) { - return $pf; - } + function &download($params) + { + if (!count($params)) { + $a = array(); + return $a; + } - if ($this->_rawReturn) { - return $pf; + if (!isset($this->_registry)) { + $this->_registry = &$this->config->getRegistry(); + } + + $channelschecked = array(); + // convert all parameters into PEAR_Downloader_Package objects + foreach ($params as $i => $param) { + $params[$i] = &$this->newDownloaderPackage($this); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $err = $params[$i]->initialize($param); + PEAR::staticPopErrorHandling(); + if (!$err) { + // skip parameters that were missed by preferred_state + continue; } - if (!$pf->validate($state)) { - if ($this->_config->get('verbose') > 0 - && $this->_logger && $pf->getValidationWarnings(false)) { - foreach ($pf->getValidationWarnings(false) as $warning) { - $this->_logger->log(0, 'ERROR: ' . $warning['message']); - } + if (PEAR::isError($err)) { + if (!isset($this->_options['soft']) && $err->getMessage() !== '') { + $this->log(0, $err->getMessage()); } - $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', - 2, null, null, $pf->getValidationWarnings()); - return $a; - } - - if ($this->_logger && $pf->getValidationWarnings(false)) { - foreach ($pf->getValidationWarnings() as $warning) { - $this->_logger->log(0, 'WARNING: ' . $warning['message']); + $params[$i] = false; + if (is_object($param)) { + $param = $param->getChannel() . '/' . $param->getPackage(); } - } - - if (method_exists($pf, 'flattenFilelist')) { - $pf->flattenFilelist(); // for v2 - } - - return $pf; - } elseif (preg_match('/]+version="([^"]+)"/', $data, $packageversion)) { - $a = PEAR::raiseError('package.xml file "' . $file . - '" has unsupported package.xml version "' . $packageversion[1] . '"'); - return $a; - } else { - if (!class_exists('PEAR_ErrorStack')) { - require_once 'PEAR/ErrorStack.php'; - } - PEAR_ErrorStack::staticPush('PEAR_PackageFile', - PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION, - 'warning', array('xml' => $data), 'package.xml "' . $file . - '" has no package.xml version'); - $object = &$this->parserFactory('1.0'); - $object->setConfig($this->_config); - $pf = $object->parse($data, $file, $archive); - if (PEAR::isError($pf)) { - return $pf; - } + if (!isset($this->_options['soft'])) { + $this->log(2, 'Package "' . $param . '" is not valid'); + } - if ($this->_rawReturn) { - return $pf; - } + // Message logged above in a specific verbose mode, passing null to not show up on CLI + $this->pushError(null, PEAR_INSTALLER_SKIPPED); + } else { + do { + if ($params[$i] && $params[$i]->getType() == 'local') { + // bug #7090 skip channel.xml check for local packages + break; + } - if (!$pf->validate($state)) { - $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', - 2, null, null, $pf->getValidationWarnings()); - return $a; - } + if ($params[$i] && !isset($channelschecked[$params[$i]->getChannel()]) && + !isset($this->_options['offline']) + ) { + $channelschecked[$params[$i]->getChannel()] = true; + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (!class_exists('System')) { + require_once 'System.php'; + } - if ($this->_logger && $pf->getValidationWarnings(false)) { - foreach ($pf->getValidationWarnings() as $warning) { - $this->_logger->log(0, 'WARNING: ' . $warning['message']); - } - } + $curchannel = &$this->_registry->getChannel($params[$i]->getChannel()); + if (PEAR::isError($curchannel)) { + PEAR::staticPopErrorHandling(); + return $this->raiseError($curchannel); + } - if (method_exists($pf, 'flattenFilelist')) { - $pf->flattenFilelist(); // for v2 - } + if (PEAR::isError($dir = $this->getDownloadDir())) { + PEAR::staticPopErrorHandling(); + break; + } - return $pf; - } - } + $mirror = $this->config->get('preferred_mirror', null, $params[$i]->getChannel()); + $url = 'http://' . $mirror . '/channel.xml'; + $a = $this->downloadHttp($url, $this->ui, $dir, null, $curchannel->lastModified()); - /** - * Register a temporary file or directory. When the destructor is - * executed, all registered temporary files and directories are - * removed. - * - * @param string $file name of file or directory - * @return void - */ - function addTempFile($file) - { - $GLOBALS['_PEAR_Common_tempfiles'][] = $file; - } + PEAR::staticPopErrorHandling(); + if (PEAR::isError($a) || !$a) { + // Attempt fallback to https automatically + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $a = $this->downloadHttp('https://' . $mirror . + '/channel.xml', $this->ui, $dir, null, $curchannel->lastModified()); - /** - * Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file. - * @access public - * @param string contents of package.xml file - * @param int package state (one of PEAR_VALIDATE_* constants) - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @using Archive_Tar to extract the files - * @using fromPackageFile() to load the package after the package.xml - * file is extracted. - */ - function &fromTgzFile($file, $state) - { - if (!class_exists('Archive_Tar')) { - require_once 'Archive/Tar.php'; - } + PEAR::staticPopErrorHandling(); + if (PEAR::isError($a) || !$a) { + break; + } + } + $this->log(0, 'WARNING: channel "' . $params[$i]->getChannel() . '" has ' . + 'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $params[$i]->getChannel() . + '" to update'); + } + } while (false); - $tar = new Archive_Tar($file); - if ($this->_debug <= 1) { - $tar->pushErrorHandling(PEAR_ERROR_RETURN); - } + if ($params[$i] && !isset($this->_options['downloadonly'])) { + if (isset($this->_options['packagingroot'])) { + $checkdir = $this->_prependPath( + $this->config->get('php_dir', null, $params[$i]->getChannel()), + $this->_options['packagingroot']); + } else { + $checkdir = $this->config->get('php_dir', + null, $params[$i]->getChannel()); + } - $content = $tar->listContent(); - if ($this->_debug <= 1) { - $tar->popErrorHandling(); - } + while ($checkdir && $checkdir != '/' && !file_exists($checkdir)) { + $checkdir = dirname($checkdir); + } - if (!is_array($content)) { - if (is_string($file) && strlen($file < 255) && - (!file_exists($file) || !@is_file($file))) { - $ret = PEAR::raiseError("could not open file \"$file\""); - return $ret; - } + if ($checkdir == '.') { + $checkdir = '/'; + } - $file = realpath($file); - $ret = PEAR::raiseError("Could not get contents of package \"$file\"". - '. Invalid tgz file.'); - return $ret; - } else { - if (!count($content) && !@is_file($file)) { - $ret = PEAR::raiseError("could not open file \"$file\""); - return $ret; + if (!is_writeable($checkdir)) { + return PEAR::raiseError('Cannot install, php_dir for channel "' . + $params[$i]->getChannel() . '" is not writeable by the current user'); + } + } } } - $xml = null; - $origfile = $file; - foreach ($content as $file) { - $name = $file['filename']; - if ($name == 'package2.xml') { // allow a .tgz to distribute both versions - $xml = $name; - break; - } + unset($channelschecked); + PEAR_Downloader_Package::removeDuplicates($params); + if (!count($params)) { + $a = array(); + return $a; + } - if ($name == 'package.xml') { - $xml = $name; - break; - } elseif (preg_match('/package.xml$/', $name, $match)) { - $xml = $name; - break; + if (!isset($this->_options['nodeps']) && !isset($this->_options['offline'])) { + $reverify = true; + while ($reverify) { + $reverify = false; + foreach ($params as $i => $param) { + //PHP Bug 40768 / PEAR Bug #10944 + //Nested foreaches fail in PHP 5.2.1 + key($params); + $ret = $params[$i]->detectDependencies($params); + if (PEAR::isError($ret)) { + $reverify = true; + $params[$i] = false; + PEAR_Downloader_Package::removeDuplicates($params); + if (!isset($this->_options['soft'])) { + $this->log(0, $ret->getMessage()); + } + continue 2; + } + } } } - if ($this->_tmpdir) { - $tmpdir = $this->_tmpdir; - } else { - $tmpdir = System::mkTemp(array('-t', $this->_config->get('temp_dir'), '-d', 'pear')); - if ($tmpdir === false) { - $ret = PEAR::raiseError("there was a problem with getting the configured temp directory"); - return $ret; - } + if (isset($this->_options['offline'])) { + $this->log(3, 'Skipping dependency download check, --offline specified'); + } - PEAR_PackageFile::addTempFile($tmpdir); + if (!count($params)) { + $a = array(); + return $a; } - $this->_extractErrors(); - PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors')); - if (!$xml || !$tar->extractList(array($xml), $tmpdir)) { - $extra = implode("\n", $this->_extractErrors()); - if ($extra) { - $extra = ' ' . $extra; + while (PEAR_Downloader_Package::mergeDependencies($params)); + PEAR_Downloader_Package::removeDuplicates($params, true); + $errorparams = array(); + if (PEAR_Downloader_Package::detectStupidDuplicates($params, $errorparams)) { + if (count($errorparams)) { + foreach ($errorparams as $param) { + $name = $this->_registry->parsedPackageNameToString($param->getParsedPackage()); + $this->pushError('Duplicate package ' . $name . ' found', PEAR_INSTALLER_FAILED); + } + $a = array(); + return $a; } - - PEAR::staticPopErrorHandling(); - $ret = PEAR::raiseError('could not extract the package.xml file from "' . - $origfile . '"' . $extra); - return $ret; } - PEAR::staticPopErrorHandling(); - $ret = &PEAR_PackageFile::fromPackageFile("$tmpdir/$xml", $state, $origfile); - return $ret; - } - - /** - * helper for extracting Archive_Tar errors - * @var array - * @access private - */ - var $_extractErrors = array(); - - /** - * helper callback for extracting Archive_Tar errors - * - * @param PEAR_Error|null $err - * @return array - * @access private - */ - function _extractErrors($err = null) - { - static $errors = array(); - if ($err === null) { - $e = $errors; - $errors = array(); - return $e; + PEAR_Downloader_Package::removeInstalled($params); + if (!count($params)) { + $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED); + $a = array(); + return $a; } - $errors[] = $err->getMessage(); - } - /** - * Create a PEAR_PackageFile_v* from a package.xml file. - * - * @access public - * @param string $descfile name of package xml file - * @param int $state package state (one of PEAR_VALIDATE_* constants) - * @param string|false $archive name of the archive this package.xml came - * from, if any - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @uses PEAR_PackageFile::fromXmlString to create the oject after the - * XML is loaded from the package.xml file. - */ - function &fromPackageFile($descfile, $state, $archive = false) - { - $fp = false; - if (is_string($descfile) && strlen($descfile) < 255 && - ( - !file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) - || (!$fp = @fopen($descfile, 'r')) - ) - ) { - $a = PEAR::raiseError("Unable to open $descfile"); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->analyzeDependencies($params); + PEAR::popErrorHandling(); + if (!count($params)) { + $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED); + $a = array(); return $a; } - // read the whole thing so we only get one cdata callback - // for each block of cdata - fclose($fp); - $data = file_get_contents($descfile); - $ret = &PEAR_PackageFile::fromXmlString($data, $state, $descfile, $archive); - return $ret; - } - + $ret = array(); + $newparams = array(); + if (isset($this->_options['pretend'])) { + return $params; + } - /** - * Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file. - * - * This method is able to extract information about a package from a .tgz - * archive or from a XML package definition file. - * - * @access public - * @param string $info file name - * @param int $state package state (one of PEAR_VALIDATE_* constants) - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @uses fromPackageFile() if the file appears to be XML - * @uses fromTgzFile() to load all non-XML files - */ - function &fromAnyFile($info, $state) - { - if (is_dir($info)) { - $dir_name = realpath($info); - if (file_exists($dir_name . '/package.xml')) { - $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package.xml', $state); - } elseif (file_exists($dir_name . '/package2.xml')) { - $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package2.xml', $state); - } else { - $info = PEAR::raiseError("No package definition found in '$info' directory"); + $somefailed = false; + foreach ($params as $i => $package) { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $pf = &$params[$i]->download(); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf)) { + if (!isset($this->_options['soft'])) { + $this->log(1, $pf->getMessage()); + $this->log(0, 'Error: cannot download "' . + $this->_registry->parsedPackageNameToString($package->getParsedPackage(), + true) . + '"'); + } + $somefailed = true; + continue; } - return $info; + $newparams[] = &$params[$i]; + $ret[] = array( + 'file' => $pf->getArchiveFile(), + 'info' => &$pf, + 'pkg' => $pf->getPackage() + ); } - $fp = false; - if (is_string($info) && strlen($info) < 255 && - (file_exists($info) || ($fp = @fopen($info, 'r'))) - ) { - - if ($fp) { - fclose($fp); - } - - $tmp = substr($info, -4); - if ($tmp == '.xml') { - $info = &PEAR_PackageFile::fromPackageFile($info, $state); - } elseif ($tmp == '.tar' || $tmp == '.tgz') { - $info = &PEAR_PackageFile::fromTgzFile($info, $state); - } else { - $fp = fopen($info, 'r'); - $test = fread($fp, 5); - fclose($fp); - if ($test == 'analyzeDependencies($newparams, true); + PEAR::popErrorHandling(); + if (!count($newparams)) { + $this->pushError('Download failed', PEAR_INSTALLER_FAILED); + $a = array(); + return $a; } - - return $info; } - $info = PEAR::raiseError("Cannot open '$info' for parsing"); - return $info; + $this->_downloadedPackages = $ret; + return $newparams; } -}PEAR-1.8.0/PEAR/Packager.php100664 764 764 15603 100664 10307 - * @author Tomas V. V. Cox - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Packager.php,v 1.75 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ - -/** - * base class - */ -require_once 'PEAR/Common.php'; -require_once 'PEAR/PackageFile.php'; -require_once 'System.php'; -/** - * Administration class used to make a PEAR release tarball. - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 - */ -class PEAR_Packager extends PEAR_Common -{ /** - * @var PEAR_Registry + * @param array all packages to be installed */ - var $_registry; - - function package($pkgfile = null, $compress = true, $pkg2 = null) + function analyzeDependencies(&$params, $force = false) { - // {{{ validate supplied package.xml file - if (empty($pkgfile)) { - $pkgfile = 'package.xml'; + $hasfailed = $failed = false; + if (isset($this->_options['downloadonly'])) { + return; } PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $pkg = &new PEAR_PackageFile($this->config, $this->debug); - $pf = &$pkg->fromPackageFile($pkgfile, PEAR_VALIDATE_NORMAL); - $main = &$pf; - PEAR::staticPopErrorHandling(); - if (PEAR::isError($pf)) { - if (is_array($pf->getUserInfo())) { - foreach ($pf->getUserInfo() as $error) { - $this->log(0, 'Error: ' . $error['message']); - } - } - - $this->log(0, $pf->getMessage()); - return $this->raiseError("Cannot package, errors in package file"); - } - - foreach ($pf->getValidationWarnings() as $warning) { - $this->log(1, 'Warning: ' . $warning['message']); - } + $redo = true; + $reset = false; + while ($redo) { + $redo = false; + foreach ($params as $i => $param) { + $deps = $param->getDeps(); + if (!$deps) { + $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(), + $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); + $send = $param->getPackageFile(); - // }}} - if ($pkg2) { - $this->log(0, 'Attempting to process the second package file'); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $pf2 = &$pkg->fromPackageFile($pkg2, PEAR_VALIDATE_NORMAL); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($pf2)) { - if (is_array($pf2->getUserInfo())) { - foreach ($pf2->getUserInfo() as $error) { - $this->log(0, 'Error: ' . $error['message']); + $installcheck = $depchecker->validatePackage($send, $this, $params); + if (PEAR::isError($installcheck)) { + if (!isset($this->_options['soft'])) { + $this->log(0, $installcheck->getMessage()); + } + $hasfailed = true; + $params[$i] = false; + $reset = true; + $redo = true; + $failed = false; + PEAR_Downloader_Package::removeDuplicates($params); + continue 2; } + continue; } - $this->log(0, $pf2->getMessage()); - return $this->raiseError("Cannot package, errors in second package file"); - } - - foreach ($pf2->getValidationWarnings() as $warning) { - $this->log(1, 'Warning: ' . $warning['message']); - } - if ($pf2->getPackagexmlVersion() == '2.0' || - $pf2->getPackagexmlVersion() == '2.1' - ) { - $main = &$pf2; - $other = &$pf; - } else { - $main = &$pf; - $other = &$pf2; - } + if (!$reset && $param->alreadyValidated() && !$force) { + continue; + } - if ($main->getPackagexmlVersion() != '2.0' && - $main->getPackagexmlVersion() != '2.1') { - return PEAR::raiseError('Error: cannot package two package.xml version 1.0, can ' . - 'only package together a package.xml 1.0 and package.xml 2.0'); + if (count($deps)) { + $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(), + $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); + $send = $param->getPackageFile(); + if ($send === null) { + $send = $param->getDownloadURL(); + } + + $installcheck = $depchecker->validatePackage($send, $this, $params); + if (PEAR::isError($installcheck)) { + if (!isset($this->_options['soft'])) { + $this->log(0, $installcheck->getMessage()); + } + $hasfailed = true; + $params[$i] = false; + $reset = true; + $redo = true; + $failed = false; + PEAR_Downloader_Package::removeDuplicates($params); + continue 2; + } + + $failed = false; + if (isset($deps['required'])) { + foreach ($deps['required'] as $type => $dep) { + // note: Dependency2 will never return a PEAR_Error if ignore-errors + // is specified, so soft is needed to turn off logging + if (!isset($dep[0])) { + if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep, + true, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } else { + foreach ($dep as $d) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($d, + true, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } + } + } + + if (isset($deps['optional'])) { + foreach ($deps['optional'] as $type => $dep) { + if (!isset($dep[0])) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($dep, + false, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } else { + foreach ($dep as $d) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($d, + false, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } + } + } + } + + $groupname = $param->getGroup(); + if (isset($deps['group']) && $groupname) { + if (!isset($deps['group'][0])) { + $deps['group'] = array($deps['group']); + } + + $found = false; + foreach ($deps['group'] as $group) { + if ($group['attribs']['name'] == $groupname) { + $found = true; + break; + } + } + + if ($found) { + unset($group['attribs']); + foreach ($group as $type => $dep) { + if (!isset($dep[0])) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($dep, + false, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } else { + foreach ($dep as $d) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($d, + false, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } + } + } + } + } + } else { + foreach ($deps as $dep) { + if (PEAR::isError($e = $depchecker->validateDependency1($dep, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } + } + $params[$i]->setValidated(); + } + + if ($failed) { + $hasfailed = true; + $params[$i] = false; + $reset = true; + $redo = true; + $failed = false; + PEAR_Downloader_Package::removeDuplicates($params); + continue 2; + } + } + } + PEAR::staticPopErrorHandling(); + if ($hasfailed && (isset($this->_options['ignore-errors']) || + isset($this->_options['nodeps']))) { + // this is probably not needed, but just in case + if (!isset($this->_options['soft'])) { + $this->log(0, 'WARNING: dependencies failed'); } + } + } - if ($other->getPackagexmlVersion() != '1.0') { - return PEAR::raiseError('Error: cannot package two package.xml version 2.0, can ' . - 'only package together a package.xml 1.0 and package.xml 2.0'); + /** + * Retrieve the directory that downloads will happen in + * @access private + * @return string + */ + function getDownloadDir() + { + if (isset($this->_downloadDir)) { + return $this->_downloadDir; + } + $downloaddir = $this->config->get('download_dir'); + if (empty($downloaddir) || (is_dir($downloaddir) && !is_writable($downloaddir))) { + if (is_dir($downloaddir) && !is_writable($downloaddir)) { + $this->log(0, 'WARNING: configuration download directory "' . $downloaddir . + '" is not writeable. Change download_dir config variable to ' . + 'a writeable dir to avoid this warning'); + } + if (!class_exists('System')) { + require_once 'System.php'; + } + if (PEAR::isError($downloaddir = System::mktemp('-d'))) { + return $downloaddir; + } + $this->log(3, '+ tmp dir created at ' . $downloaddir); + } + if (!is_writable($downloaddir)) { + if (PEAR::isError(System::mkdir(array('-p', $downloaddir))) || + !is_writable($downloaddir)) { + return PEAR::raiseError('download directory "' . $downloaddir . + '" is not writeable. Change download_dir config variable to ' . + 'a writeable dir'); } } + return $this->_downloadDir = $downloaddir; + } - $main->setLogger($this); - if (!$main->validate(PEAR_VALIDATE_PACKAGING)) { - foreach ($main->getValidationWarnings() as $warning) { - $this->log(0, 'Error: ' . $warning['message']); + function setDownloadDir($dir) + { + if (!@is_writable($dir)) { + if (PEAR::isError(System::mkdir(array('-p', $dir)))) { + return PEAR::raiseError('download directory "' . $dir . + '" is not writeable. Change download_dir config variable to ' . + 'a writeable dir'); } - return $this->raiseError("Cannot package, errors in package"); } + $this->_downloadDir = $dir; + } - foreach ($main->getValidationWarnings() as $warning) { - $this->log(1, 'Warning: ' . $warning['message']); + function configSet($key, $value, $layer = 'user', $channel = false) + { + $this->config->set($key, $value, $layer, $channel); + $this->_preferredState = $this->config->get('preferred_state', null, $channel); + if (!$this->_preferredState) { + // don't inadvertantly use a non-set preferred_state + $this->_preferredState = null; } + } - if ($pkg2) { - $other->setLogger($this); - $a = false; - if (!$other->validate(PEAR_VALIDATE_NORMAL) || $a = !$main->isEquivalent($other)) { - foreach ($other->getValidationWarnings() as $warning) { - $this->log(0, 'Error: ' . $warning['message']); - } + function setOptions($options) + { + $this->_options = $options; + } - foreach ($main->getValidationWarnings() as $warning) { - $this->log(0, 'Error: ' . $warning['message']); - } + // }}} + // {{{ setOptions() + function getOptions() + { + return $this->_options; + } - if ($a) { - return $this->raiseError('The two package.xml files are not equivalent!'); + /** + * For simpler unit-testing + * @param PEAR_Config + * @param int + * @param string + */ + function &getPackagefileObject(&$c, $d, $t = false) + { + if (!class_exists('PEAR_PackageFile')) { + require_once 'PEAR/PackageFile.php'; + } + $a = &new PEAR_PackageFile($c, $d, $t); + return $a; + } + + /** + * @param array output of {@link parsePackageName()} + * @access private + */ + function _getPackageDownloadUrl($parr) + { + $curchannel = $this->config->get('default_channel'); + $this->configSet('default_channel', $parr['channel']); + // getDownloadURL returns an array. On error, it only contains information + // on the latest release as array(version, info). On success it contains + // array(version, info, download url string) + $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state'); + if (!$this->_registry->channelExists($parr['channel'])) { + do { + if ($this->config->get('auto_discover') && $this->discover($parr['channel'])) { + break; } - return $this->raiseError("Cannot package, errors in package"); + $this->configSet('default_channel', $curchannel); + return PEAR::raiseError('Unknown remote channel: ' . $parr['channel']); + } while (false); + } + + $chan = &$this->_registry->getChannel($parr['channel']); + if (PEAR::isError($chan)) { + return $chan; + } + + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $version = $this->_registry->packageInfo($parr['package'], 'version', $parr['channel']); + $stability = $this->_registry->packageInfo($parr['package'], 'stability', $parr['channel']); + // package is installed - use the installed release stability level + if (!isset($parr['state']) && $stability !== null) { + $state = $stability['release']; + } + PEAR::staticPopErrorHandling(); + $base2 = false; + + $preferred_mirror = $this->config->get('preferred_mirror'); + if (!$chan->supportsREST($preferred_mirror) || + ( + !($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror)) + && + !($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) + ) + ) { + return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.'); + } + + if ($base2) { + $rest = &$this->config->getREST('1.3', $this->_options); + $base = $base2; + } else { + $rest = &$this->config->getREST('1.0', $this->_options); + } + + $downloadVersion = false; + if (!isset($parr['version']) && !isset($parr['state']) && $version + && !PEAR::isError($version) + && !isset($this->_options['downloadonly']) + ) { + $downloadVersion = $version; + } + + $url = $rest->getDownloadURL($base, $parr, $state, $downloadVersion, $chan->getName()); + if (PEAR::isError($url)) { + $this->configSet('default_channel', $curchannel); + return $url; + } + + if ($parr['channel'] != $curchannel) { + $this->configSet('default_channel', $curchannel); + } + + if (!is_array($url)) { + return $url; + } + + $url['raw'] = false; // no checking is necessary for REST + if (!is_array($url['info'])) { + return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . + 'this should never happen'); + } + + if (!isset($this->_options['force']) && + !isset($this->_options['downloadonly']) && + $version && + !PEAR::isError($version) && + !isset($parr['group']) + ) { + if (version_compare($version, $url['version'], '=')) { + return PEAR::raiseError($this->_registry->parsedPackageNameToString( + $parr, true) . ' is already installed and is the same as the ' . + 'released version ' . $url['version'], -976); } - foreach ($other->getValidationWarnings() as $warning) { - $this->log(1, 'Warning: ' . $warning['message']); + if (version_compare($version, $url['version'], '>')) { + return PEAR::raiseError($this->_registry->parsedPackageNameToString( + $parr, true) . ' is already installed and is newer than detected ' . + 'released version ' . $url['version'], -976); } + } - $gen = &$main->getDefaultGenerator(); - $tgzfile = $gen->toTgz2($this, $other, $compress); - if (PEAR::isError($tgzfile)) { - return $tgzfile; + if (isset($url['info']['required']) || $url['compatible']) { + require_once 'PEAR/PackageFile/v2.php'; + $pf = new PEAR_PackageFile_v2; + $pf->setRawChannel($parr['channel']); + if ($url['compatible']) { + $pf->setRawCompatible($url['compatible']); } + } else { + require_once 'PEAR/PackageFile/v1.php'; + $pf = new PEAR_PackageFile_v1; + } - $dest_package = basename($tgzfile); - $pkgdir = dirname($pkgfile); + $pf->setRawPackage($url['package']); + $pf->setDeps($url['info']); + if ($url['compatible']) { + $pf->setCompatible($url['compatible']); + } - // TAR the Package ------------------------------------------- - $this->log(1, "Package $dest_package done"); - if (file_exists("$pkgdir/CVS/Root")) { - $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion()); - $cvstag = "RELEASE_$cvsversion"; - $this->log(1, 'Tag the released code with "pear cvstag ' . - $main->getPackageFile() . '"'); - $this->log(1, "(or set the CVS tag $cvstag by hand)"); + $pf->setRawState($url['stability']); + $url['info'] = &$pf; + if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) { + $ext = '.tar'; + } else { + $ext = '.tgz'; + } + + if (is_array($url) && isset($url['url'])) { + $url['url'] .= $ext; + } + + return $url; + } + + /** + * @param array dependency array + * @access private + */ + function _getDepPackageDownloadUrl($dep, $parr) + { + $xsdversion = isset($dep['rel']) ? '1.0' : '2.0'; + $curchannel = $this->config->get('default_channel'); + if (isset($dep['uri'])) { + $xsdversion = '2.0'; + $chan = &$this->_registry->getChannel('__uri'); + if (PEAR::isError($chan)) { + return $chan; } - } else { // this branch is executed for single packagefile packaging - $gen = &$pf->getDefaultGenerator(); - $tgzfile = $gen->toTgz($this, $compress); - if (PEAR::isError($tgzfile)) { - $this->log(0, $tgzfile->getMessage()); - return $this->raiseError("Cannot package, errors in package"); + + $version = $this->_registry->packageInfo($dep['name'], 'version', '__uri'); + $this->configSet('default_channel', '__uri'); + } else { + if (isset($dep['channel'])) { + $remotechannel = $dep['channel']; + } else { + $remotechannel = 'pear.php.net'; } - $dest_package = basename($tgzfile); - $pkgdir = dirname($pkgfile); + if (!$this->_registry->channelExists($remotechannel)) { + do { + if ($this->config->get('auto_discover')) { + if ($this->discover($remotechannel)) { + break; + } + } + return PEAR::raiseError('Unknown remote channel: ' . $remotechannel); + } while (false); + } - // TAR the Package ------------------------------------------- - $this->log(1, "Package $dest_package done"); - if (file_exists("$pkgdir/CVS/Root")) { - $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion()); - $cvstag = "RELEASE_$cvsversion"; - $this->log(1, "Tag the released code with `pear cvstag $pkgfile'"); - $this->log(1, "(or set the CVS tag $cvstag by hand)"); + $chan = &$this->_registry->getChannel($remotechannel); + if (PEAR::isError($chan)) { + return $chan; } + + $version = $this->_registry->packageInfo($dep['name'], 'version', $remotechannel); + $this->configSet('default_channel', $remotechannel); } - return $dest_package; - } -}PEAR-1.8.0/PEAR/Registry.php100664 764 764 226577 100664 10440 - * @author Tomas V. V. Cox - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Registry.php,v 1.179 2009/04/10 19:42:18 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ - -/** - * for PEAR_Error - */ -require_once 'PEAR.php'; -require_once 'PEAR/DependencyDB.php'; - -define('PEAR_REGISTRY_ERROR_LOCK', -2); -define('PEAR_REGISTRY_ERROR_FORMAT', -3); -define('PEAR_REGISTRY_ERROR_FILE', -4); -define('PEAR_REGISTRY_ERROR_CONFLICT', -5); -define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6); - -/** - * Administration class used to maintain the installed package database. - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Tomas V. V. Cox - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Registry extends PEAR -{ - /** - * File containing all channel information. - * @var string - */ - var $channels = ''; - - /** Directory where registry files are stored. - * @var string - */ - var $statedir = ''; - - /** File where the file map is stored - * @var string - */ - var $filemap = ''; - - /** Directory where registry files for channels are stored. - * @var string - */ - var $channelsdir = ''; - - /** Name of file used for locking the registry - * @var string - */ - var $lockfile = ''; - - /** File descriptor used during locking - * @var resource - */ - var $lock_fp = null; - - /** Mode used during locking - * @var int - */ - var $lock_mode = 0; // XXX UNUSED - - /** Cache of package information. Structure: - * array( - * 'package' => array('id' => ... ), - * ... ) - * @var array - */ - var $pkginfo_cache = array(); - - /** Cache of file map. Structure: - * array( '/path/to/file' => 'package', ... ) - * @var array - */ - var $filemap_cache = array(); - - /** - * @var false|PEAR_ChannelFile - */ - var $_pearChannel; - - /** - * @var false|PEAR_ChannelFile - */ - var $_peclChannel; - - /** - * @var false|PEAR_ChannelFile - */ - var $_docChannel; - - /** - * @var PEAR_DependencyDB - */ - var $_dependencyDB; - - /** - * @var PEAR_Config - */ - var $_config; - - /** - * PEAR_Registry constructor. - * - * @param string (optional) PEAR install directory (for .php files) - * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PEAR channel, if - * default values are not desired. Only used the very first time a PEAR - * repository is initialized - * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PECL channel, if - * default values are not desired. Only used the very first time a PEAR - * repository is initialized - * - * @access public - */ - function PEAR_Registry($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false, - $pecl_channel = false) - { - parent::PEAR(); - $this->setInstallDir($pear_install_dir); - $this->_pearChannel = $pear_channel; - $this->_peclChannel = $pecl_channel; - $this->_config = false; - } - - function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR) - { - $ds = DIRECTORY_SEPARATOR; - $this->install_dir = $pear_install_dir; - $this->channelsdir = $pear_install_dir.$ds.'.channels'; - $this->statedir = $pear_install_dir.$ds.'.registry'; - $this->filemap = $pear_install_dir.$ds.'.filemap'; - $this->lockfile = $pear_install_dir.$ds.'.lock'; - } - - function hasWriteAccess() - { - if (!file_exists($this->install_dir)) { - $dir = $this->install_dir; - while ($dir && $dir != '.') { - $olddir = $dir; - $dir = dirname($dir); - if ($dir != '.' && file_exists($dir)) { - if (is_writeable($dir)) { - return true; - } - - return false; - } - - if ($dir == $olddir) { // this can happen in safe mode - return @is_writable($dir); - } - } - - return false; - } - - return is_writeable($this->install_dir); - } - - function setConfig(&$config, $resetInstallDir = true) - { - $this->_config = &$config; - if ($resetInstallDir) { - $this->setInstallDir($config->get('php_dir')); - } - } - - function _initializeChannelDirs() - { - static $running = false; - if (!$running) { - $running = true; - $ds = DIRECTORY_SEPARATOR; - if (!is_dir($this->channelsdir) || - !file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || - !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || - !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || - !file_exists($this->channelsdir . $ds . '__uri.reg')) { - if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { - $pear_channel = $this->_pearChannel; - if (!is_a($pear_channel, 'PEAR_ChannelFile') || !$pear_channel->validate()) { - if (!class_exists('PEAR_ChannelFile')) { - require_once 'PEAR/ChannelFile.php'; - } - - $pear_channel = new PEAR_ChannelFile; - $pear_channel->setName('pear.php.net'); - $pear_channel->setAlias('pear'); - $pear_channel->setServer('pear.php.net'); - $pear_channel->setSummary('PHP Extension and Application Repository'); - $pear_channel->setDefaultPEARProtocols(); - $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); - $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); - } else { - $pear_channel->setName('pear.php.net'); - $pear_channel->setAlias('pear'); - } - - $pear_channel->validate(); - $this->_addChannel($pear_channel); - } - - if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) { - $pecl_channel = $this->_peclChannel; - if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) { - if (!class_exists('PEAR_ChannelFile')) { - require_once 'PEAR/ChannelFile.php'; - } - - $pecl_channel = new PEAR_ChannelFile; - $pecl_channel->setName('pecl.php.net'); - $pecl_channel->setAlias('pecl'); - $pecl_channel->setServer('pecl.php.net'); - $pecl_channel->setSummary('PHP Extension Community Library'); - $pecl_channel->setDefaultPEARProtocols(); - $pecl_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); - $pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); - $pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); - } else { - $pecl_channel->setName('pecl.php.net'); - $pecl_channel->setAlias('pecl'); - } - - $pecl_channel->validate(); - $this->_addChannel($pecl_channel); - } - - if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) { - $doc_channel = $this->_docChannel; - if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) { - if (!class_exists('PEAR_ChannelFile')) { - require_once 'PEAR/ChannelFile.php'; - } - - $doc_channel = new PEAR_ChannelFile; - $doc_channel->setName('doc.php.net'); - $doc_channel->setAlias('phpdocs'); - $doc_channel->setServer('doc.php.net'); - $doc_channel->setSummary('PHP Documentation Team'); - $doc_channel->setDefaultPEARProtocols(); - $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/Chiara_PEAR_Server_REST/'); - $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/Chiara_PEAR_Server_REST/'); - } else { - $doc_channel->setName('doc.php.net'); - $doc_channel->setAlias('doc'); - } - - $doc_channel->validate(); - $this->_addChannel($doc_channel); - } - - if (!file_exists($this->channelsdir . $ds . '__uri.reg')) { - if (!class_exists('PEAR_ChannelFile')) { - require_once 'PEAR/ChannelFile.php'; - } - - $private = new PEAR_ChannelFile; - $private->setName('__uri'); - $private->setDefaultPEARProtocols(); - $private->setBaseURL('REST1.0', '****'); - $private->setSummary('Pseudo-channel for static packages'); - $this->_addChannel($private); - } - $this->_rebuildFileMap(); - } - - $running = false; - } - } - - function _initializeDirs() - { - $ds = DIRECTORY_SEPARATOR; - // XXX Compatibility code should be removed in the future - // rename all registry files if any to lowercase - if (!OS_WINDOWS && file_exists($this->statedir) && is_dir($this->statedir) && - $handle = opendir($this->statedir)) { - $dest = $this->statedir . $ds; - while (false !== ($file = readdir($handle))) { - if (preg_match('/^.*[A-Z].*\.reg\\z/', $file)) { - rename($dest . $file, $dest . strtolower($file)); - } - } - closedir($handle); - } - - $this->_initializeChannelDirs(); - if (!file_exists($this->filemap)) { - $this->_rebuildFileMap(); - } - $this->_initializeDepDB(); - } - - function _initializeDepDB() - { - if (!isset($this->_dependencyDB)) { - static $initializing = false; - if (!$initializing) { - $initializing = true; - if (!$this->_config) { // never used? - $file = OS_WINDOWS ? 'pear.ini' : '.pearrc'; - $this->_config = &new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR . - $file); - $this->_config->setRegistry($this); - $this->_config->set('php_dir', $this->install_dir); - } - - $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); - if (PEAR::isError($this->_dependencyDB)) { - // attempt to recover by removing the dep db - if (file_exists($this->_config->get('php_dir', null, 'pear.php.net') . - DIRECTORY_SEPARATOR . '.depdb')) { - @unlink($this->_config->get('php_dir', null, 'pear.php.net') . - DIRECTORY_SEPARATOR . '.depdb'); - } - - $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); - if (PEAR::isError($this->_dependencyDB)) { - echo $this->_dependencyDB->getMessage(); - echo 'Unrecoverable error'; - exit(1); - } - } - - $initializing = false; - } - } - } - - /** - * PEAR_Registry destructor. Makes sure no locks are forgotten. - * - * @access private - */ - function _PEAR_Registry() - { - parent::_PEAR(); - if (is_resource($this->lock_fp)) { - $this->_unlock(); - } - } - - /** - * Make sure the directory where we keep registry files exists. - * - * @return bool TRUE if directory exists, FALSE if it could not be - * created - * - * @access private - */ - function _assertStateDir($channel = false) - { - if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { - return $this->_assertChannelStateDir($channel); - } - - static $init = false; - if (!file_exists($this->statedir)) { - if (!$this->hasWriteAccess()) { - return false; - } - - require_once 'System.php'; - if (!System::mkdir(array('-p', $this->statedir))) { - return $this->raiseError("could not create directory '{$this->statedir}'"); - } - $init = true; - } elseif (!is_dir($this->statedir)) { - return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' . - 'it already exists and is not a directory'); - } - - $ds = DIRECTORY_SEPARATOR; - if (!file_exists($this->channelsdir)) { - if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || - !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || - !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || - !file_exists($this->channelsdir . $ds . '__uri.reg')) { - $init = true; - } - } elseif (!is_dir($this->channelsdir)) { - return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' . - 'it already exists and is not a directory'); - } - - if ($init) { - static $running = false; - if (!$running) { - $running = true; - $this->_initializeDirs(); - $running = false; - $init = false; - } - } else { - $this->_initializeDepDB(); - } - - return true; - } - - /** - * Make sure the directory where we keep registry files exists for a non-standard channel. - * - * @param string channel name - * @return bool TRUE if directory exists, FALSE if it could not be - * created - * - * @access private - */ - function _assertChannelStateDir($channel) - { - $ds = DIRECTORY_SEPARATOR; - if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { - if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { - $this->_initializeChannelDirs(); - } - return $this->_assertStateDir($channel); - } - - $channelDir = $this->_channelDirectoryName($channel); - if (!is_dir($this->channelsdir) || - !file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { - $this->_initializeChannelDirs(); - } - - if (!file_exists($channelDir)) { - if (!$this->hasWriteAccess()) { - return false; - } - - require_once 'System.php'; - if (!System::mkdir(array('-p', $channelDir))) { - return $this->raiseError("could not create directory '" . $channelDir . - "'"); - } - } elseif (!is_dir($channelDir)) { - return $this->raiseError("could not create directory '" . $channelDir . - "', already exists and is not a directory"); - } - - return true; - } - - /** - * Make sure the directory where we keep registry files for channels exists - * - * @return bool TRUE if directory exists, FALSE if it could not be - * created - * - * @access private - */ - function _assertChannelDir() - { - if (!file_exists($this->channelsdir)) { - if (!$this->hasWriteAccess()) { - return false; - } - - require_once 'System.php'; - if (!System::mkdir(array('-p', $this->channelsdir))) { - return $this->raiseError("could not create directory '{$this->channelsdir}'"); - } - } elseif (!is_dir($this->channelsdir)) { - return $this->raiseError("could not create directory '{$this->channelsdir}" . - "', it already exists and is not a directory"); - } - - if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { - if (!$this->hasWriteAccess()) { - return false; - } - - require_once 'System.php'; - if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) { - return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'"); - } - } elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { - return $this->raiseError("could not create directory '{$this->channelsdir}" . - "/.alias', it already exists and is not a directory"); - } - - return true; - } - - /** - * Get the name of the file where data for a given package is stored. - * - * @param string channel name, or false if this is a PEAR package - * @param string package name - * - * @return string registry file name - * - * @access public - */ - function _packageFileName($package, $channel = false) - { - if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { - return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR . - strtolower($package) . '.reg'; - } - - return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg'; - } - - /** - * Get the name of the file where data for a given channel is stored. - * @param string channel name - * @return string registry file name - */ - function _channelFileName($channel, $noaliases = false) - { - if (!$noaliases) { - if (file_exists($this->_getChannelAliasFileName($channel))) { - $channel = implode('', file($this->_getChannelAliasFileName($channel))); - } - } - return $this->channelsdir . DIRECTORY_SEPARATOR . str_replace('/', '_', - strtolower($channel)) . '.reg'; - } - - /** - * @param string - * @return string - */ - function _getChannelAliasFileName($alias) - { - return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' . - DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt'; - } - - /** - * Get the name of a channel from its alias - */ - function _getChannelFromAlias($channel) - { - if (!$this->_channelExists($channel)) { - if ($channel == 'pear.php.net') { - return 'pear.php.net'; - } - - if ($channel == 'pecl.php.net') { - return 'pecl.php.net'; - } - - if ($channel == 'doc.php.net') { - return 'doc.php.net'; - } - - if ($channel == '__uri') { - return '__uri'; - } - - return false; - } - - $channel = strtolower($channel); - if (file_exists($this->_getChannelAliasFileName($channel))) { - // translate an alias to an actual channel - return implode('', file($this->_getChannelAliasFileName($channel))); - } - - return $channel; - } - - /** - * Get the alias of a channel from its alias or its name - */ - function _getAlias($channel) - { - if (!$this->_channelExists($channel)) { - if ($channel == 'pear.php.net') { - return 'pear'; - } - - if ($channel == 'pecl.php.net') { - return 'pecl'; - } - - if ($channel == 'doc.php.net') { - return 'phpdocs'; - } - - return false; - } - - $channel = $this->_getChannel($channel); - if (PEAR::isError($channel)) { - return $channel; - } - - return $channel->getAlias(); - } - - /** - * Get the name of the file where data for a given package is stored. - * - * @param string channel name, or false if this is a PEAR package - * @param string package name - * - * @return string registry file name - * - * @access public - */ - function _channelDirectoryName($channel) - { - if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { - return $this->statedir; - } - - $ch = $this->_getChannelFromAlias($channel); - if (!$ch) { - $ch = $channel; - } - - return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' . - str_replace('/', '_', $ch)); - } - - function _openPackageFile($package, $mode, $channel = false) - { - if (!$this->_assertStateDir($channel)) { - return null; - } - - if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { - return null; - } - - $file = $this->_packageFileName($package, $channel); - if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { - return null; - } - - $fp = @fopen($file, $mode); - if (!$fp) { - return null; - } - - return $fp; - } - - function _closePackageFile($fp) - { - fclose($fp); - } - - function _openChannelFile($channel, $mode) - { - if (!$this->_assertChannelDir()) { - return null; - } - - if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { - return null; - } - - $file = $this->_channelFileName($channel); - if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { - return null; - } - - $fp = @fopen($file, $mode); - if (!$fp) { - return null; - } - - return $fp; - } - - function _closeChannelFile($fp) - { - fclose($fp); - } - - function _rebuildFileMap() - { - if (!class_exists('PEAR_Installer_Role')) { - require_once 'PEAR/Installer/Role.php'; - } - - $channels = $this->_listAllPackages(); - $files = array(); - foreach ($channels as $channel => $packages) { - foreach ($packages as $package) { - $version = $this->_packageInfo($package, 'version', $channel); - $filelist = $this->_packageInfo($package, 'filelist', $channel); - if (!is_array($filelist)) { - continue; - } - - foreach ($filelist as $name => $attrs) { - if (isset($attrs['attribs'])) { - $attrs = $attrs['attribs']; - } - - // it is possible for conflicting packages in different channels to - // conflict with data files/doc files - if ($name == 'dirtree') { - continue; - } - - if (isset($attrs['role']) && !in_array($attrs['role'], - PEAR_Installer_Role::getInstallableRoles())) { - // these are not installed - continue; - } - - if (isset($attrs['role']) && !in_array($attrs['role'], - PEAR_Installer_Role::getBaseinstallRoles())) { - $attrs['baseinstalldir'] = $package; - } - - if (isset($attrs['baseinstalldir'])) { - $file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name; - } else { - $file = $name; - } - - $file = preg_replace(',^/+,', '', $file); - if ($channel != 'pear.php.net') { - if (!isset($files[$attrs['role']])) { - $files[$attrs['role']] = array(); - } - $files[$attrs['role']][$file] = array(strtolower($channel), - strtolower($package)); - } else { - if (!isset($files[$attrs['role']])) { - $files[$attrs['role']] = array(); - } - $files[$attrs['role']][$file] = strtolower($package); - } - } - } - } - - - $this->_assertStateDir(); - if (!$this->hasWriteAccess()) { - return false; - } - - $fp = @fopen($this->filemap, 'wb'); - if (!$fp) { - return false; - } - - $this->filemap_cache = $files; - fwrite($fp, serialize($files)); - fclose($fp); - return true; - } - - function _readFileMap() - { - if (!file_exists($this->filemap)) { - return array(); - } - - $fp = @fopen($this->filemap, 'r'); - if (!$fp) { - return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg); - } - - clearstatcache(); - $rt = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - $fsize = filesize($this->filemap); - fclose($fp); - $data = file_get_contents($this->filemap); - set_magic_quotes_runtime($rt); - $tmp = unserialize($data); - if (!$tmp && $fsize > 7) { - return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data); - } - - $this->filemap_cache = $tmp; - return true; - } - - /** - * Lock the registry. - * - * @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN. - * See flock manual for more information. - * - * @return bool TRUE on success, FALSE if locking failed, or a - * PEAR error if some other error occurs (such as the - * lock file not being writable). - * - * @access private - */ - function _lock($mode = LOCK_EX) - { - if (stristr(php_uname(), 'Windows 9')) { - return true; - } - - if ($mode != LOCK_UN && is_resource($this->lock_fp)) { - // XXX does not check type of lock (LOCK_SH/LOCK_EX) - return true; - } - - if (!$this->_assertStateDir()) { - if ($mode == LOCK_EX) { - return $this->raiseError('Registry directory is not writeable by the current user'); - } - - return true; - } - - $open_mode = 'w'; - // XXX People reported problems with LOCK_SH and 'w' - if ($mode === LOCK_SH || $mode === LOCK_UN) { - if (!file_exists($this->lockfile)) { - touch($this->lockfile); - } - $open_mode = 'r'; - } - - if (!is_resource($this->lock_fp)) { - $this->lock_fp = @fopen($this->lockfile, $open_mode); - } - - if (!is_resource($this->lock_fp)) { - $this->lock_fp = null; - return $this->raiseError("could not create lock file" . - (isset($php_errormsg) ? ": " . $php_errormsg : "")); - } - - if (!(int)flock($this->lock_fp, $mode)) { - switch ($mode) { - case LOCK_SH: $str = 'shared'; break; - case LOCK_EX: $str = 'exclusive'; break; - case LOCK_UN: $str = 'unlock'; break; - default: $str = 'unknown'; break; - } - - //is resource at this point, close it on error. - fclose($this->lock_fp); - $this->lock_fp = null; - return $this->raiseError("could not acquire $str lock ($this->lockfile)", - PEAR_REGISTRY_ERROR_LOCK); - } - - return true; - } - - function _unlock() - { - $ret = $this->_lock(LOCK_UN); - if (is_resource($this->lock_fp)) { - fclose($this->lock_fp); - } - - $this->lock_fp = null; - return $ret; - } - - function _packageExists($package, $channel = false) - { - return file_exists($this->_packageFileName($package, $channel)); - } - - /** - * Determine whether a channel exists in the registry - * @param string Channel name - * @param bool if true, then aliases will be ignored - * @return boolean - */ - function _channelExists($channel, $noaliases = false) - { - $a = file_exists($this->_channelFileName($channel, $noaliases)); - if (!$a && $channel == 'pear.php.net') { - return true; - } - - if (!$a && $channel == 'pecl.php.net') { - return true; - } - - if (!$a && $channel == 'doc.php.net') { - return true; - } - - return $a; - } - - /** - * @param PEAR_ChannelFile Channel object - * @param donotuse - * @param string Last-Modified HTTP tag from remote request - * @return boolean|PEAR_Error True on creation, false if it already exists - */ - function _addChannel($channel, $update = false, $lastmodified = false) - { - if (!is_a($channel, 'PEAR_ChannelFile')) { - return false; - } - - if (!$channel->validate()) { - return false; - } - - if (file_exists($this->_channelFileName($channel->getName()))) { - if (!$update) { - return false; - } - - $checker = $this->_getChannel($channel->getName()); - if (PEAR::isError($checker)) { - return $checker; - } - - if ($channel->getAlias() != $checker->getAlias()) { - if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) { - @unlink($this->_getChannelAliasFileName($checker->getAlias())); - } - } - } else { - if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net', 'doc.php.net'))) { - return false; - } - } - - $ret = $this->_assertChannelDir(); - if (PEAR::isError($ret)) { - return $ret; - } - - $ret = $this->_assertChannelStateDir($channel->getName()); - if (PEAR::isError($ret)) { - return $ret; - } - - if ($channel->getAlias() != $channel->getName()) { - if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) && - $this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) { - $channel->setAlias($channel->getName()); - } - - if (!$this->hasWriteAccess()) { - return false; - } - - $fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w'); - if (!$fp) { - return false; - } - - fwrite($fp, $channel->getName()); - fclose($fp); - } - - if (!$this->hasWriteAccess()) { - return false; - } - - $fp = @fopen($this->_channelFileName($channel->getName()), 'wb'); - if (!$fp) { - return false; - } - - $info = $channel->toArray(); - if ($lastmodified) { - $info['_lastmodified'] = $lastmodified; - } else { - $info['_lastmodified'] = date('r'); - } - - fwrite($fp, serialize($info)); - fclose($fp); - return true; - } - - /** - * Deletion fails if there are any packages installed from the channel - * @param string|PEAR_ChannelFile channel name - * @return boolean|PEAR_Error True on deletion, false if it doesn't exist - */ - function _deleteChannel($channel) - { - if (!is_string($channel)) { - if (!is_a($channel, 'PEAR_ChannelFile')) { - return false; - } - - if (!$channel->validate()) { - return false; - } - $channel = $channel->getName(); - } - - if ($this->_getChannelFromAlias($channel) == '__uri') { - return false; - } - - if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { - return false; - } - - if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { - return false; - } - - if (!$this->_channelExists($channel)) { - return false; - } - - if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { - return false; - } - - $channel = $this->_getChannelFromAlias($channel); - if ($channel == 'pear.php.net') { - return false; - } - - $test = $this->_listChannelPackages($channel); - if (count($test)) { - return false; - } - - $test = @rmdir($this->_channelDirectoryName($channel)); - if (!$test) { - return false; - } - - $file = $this->_getChannelAliasFileName($this->_getAlias($channel)); - if (file_exists($file)) { - $test = @unlink($file); - if (!$test) { - return false; - } - } - - $file = $this->_channelFileName($channel); - $ret = true; - if (file_exists($file)) { - $ret = @unlink($file); - } - - return $ret; - } - - /** - * Determine whether a channel exists in the registry - * @param string Channel Alias - * @return boolean - */ - function _isChannelAlias($alias) - { - return file_exists($this->_getChannelAliasFileName($alias)); - } - - /** - * @param string|null - * @param string|null - * @param string|null - * @return array|null - * @access private - */ - function _packageInfo($package = null, $key = null, $channel = 'pear.php.net') - { - if ($package === null) { - if ($channel === null) { - $channels = $this->_listChannels(); - $ret = array(); - foreach ($channels as $channel) { - $channel = strtolower($channel); - $ret[$channel] = array(); - $packages = $this->_listPackages($channel); - foreach ($packages as $package) { - $ret[$channel][] = $this->_packageInfo($package, null, $channel); - } - } - - return $ret; - } - - $ps = $this->_listPackages($channel); - if (!count($ps)) { - return array(); - } - return array_map(array(&$this, '_packageInfo'), - $ps, array_fill(0, count($ps), null), - array_fill(0, count($ps), $channel)); - } - - $fp = $this->_openPackageFile($package, 'r', $channel); - if ($fp === null) { - return null; - } - - $rt = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - clearstatcache(); - $this->_closePackageFile($fp); - $data = file_get_contents($this->_packageFileName($package, $channel)); - set_magic_quotes_runtime($rt); - $data = unserialize($data); - if ($key === null) { - return $data; - } - - // compatibility for package.xml version 2.0 - if (isset($data['old'][$key])) { - return $data['old'][$key]; - } - - if (isset($data[$key])) { - return $data[$key]; - } - - return null; - } - - /** - * @param string Channel name - * @param bool whether to strictly retrieve info of channels, not just aliases - * @return array|null - */ - function _channelInfo($channel, $noaliases = false) - { - if (!$this->_channelExists($channel, $noaliases)) { - return null; - } - - $fp = $this->_openChannelFile($channel, 'r'); - if ($fp === null) { - return null; - } - - $rt = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - clearstatcache(); - $this->_closeChannelFile($fp); - $data = file_get_contents($this->_channelFileName($channel)); - set_magic_quotes_runtime($rt); - $data = unserialize($data); - return $data; - } - - function _listChannels() - { - $channellist = array(); - if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) { - return array('pear.php.net', 'pecl.php.net', 'doc.php.net', '__uri'); - } - - $dp = opendir($this->channelsdir); - while ($ent = readdir($dp)) { - if ($ent{0} == '.' || substr($ent, -4) != '.reg') { - continue; - } - - if ($ent == '__uri.reg') { - $channellist[] = '__uri'; - continue; - } - - $channellist[] = str_replace('_', '/', substr($ent, 0, -4)); - } - - closedir($dp); - if (!in_array('pear.php.net', $channellist)) { - $channellist[] = 'pear.php.net'; - } - - if (!in_array('pecl.php.net', $channellist)) { - $channellist[] = 'pecl.php.net'; - } - - if (!in_array('doc.php.net', $channellist)) { - $channellist[] = 'doc.php.net'; - } - - - if (!in_array('__uri', $channellist)) { - $channellist[] = '__uri'; - } - - natsort($channellist); - return $channellist; - } - - function _listPackages($channel = false) - { - if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { - return $this->_listChannelPackages($channel); - } - - if (!file_exists($this->statedir) || !is_dir($this->statedir)) { - return array(); - } - - $pkglist = array(); - $dp = opendir($this->statedir); - if (!$dp) { - return $pkglist; - } - - while ($ent = readdir($dp)) { - if ($ent{0} == '.' || substr($ent, -4) != '.reg') { - continue; - } - - $pkglist[] = substr($ent, 0, -4); - } - closedir($dp); - return $pkglist; - } - - function _listChannelPackages($channel) - { - $pkglist = array(); - if (!file_exists($this->_channelDirectoryName($channel)) || - !is_dir($this->_channelDirectoryName($channel))) { - return array(); - } - - $dp = opendir($this->_channelDirectoryName($channel)); - if (!$dp) { - return $pkglist; - } - - while ($ent = readdir($dp)) { - if ($ent{0} == '.' || substr($ent, -4) != '.reg') { - continue; - } - $pkglist[] = substr($ent, 0, -4); - } - - closedir($dp); - return $pkglist; - } - - function _listAllPackages() - { - $ret = array(); - foreach ($this->_listChannels() as $channel) { - $ret[$channel] = $this->_listPackages($channel); - } - - return $ret; - } - - /** - * Add an installed package to the registry - * @param string package name - * @param array package info (parsed by PEAR_Common::infoFrom*() methods) - * @return bool success of saving - * @access private - */ - function _addPackage($package, $info) - { - if ($this->_packageExists($package)) { - return false; - } - - $fp = $this->_openPackageFile($package, 'wb'); - if ($fp === null) { - return false; - } - - $info['_lastmodified'] = time(); - fwrite($fp, serialize($info)); - $this->_closePackageFile($fp); - if (isset($info['filelist'])) { - $this->_rebuildFileMap(); - } - - return true; - } - - /** - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @return bool - * @access private - */ - function _addPackage2($info) - { - if (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) { - return false; - } - - if (!$info->validate()) { - if (class_exists('PEAR_Common')) { - $ui = PEAR_Frontend::singleton(); - if ($ui) { - foreach ($info->getValidationWarnings() as $err) { - $ui->log($err['message'], true); - } - } - } - return false; - } - - $channel = $info->getChannel(); - $package = $info->getPackage(); - $save = $info; - if ($this->_packageExists($package, $channel)) { - return false; - } - - if (!$this->_channelExists($channel, true)) { - return false; - } - - $info = $info->toArray(true); - if (!$info) { - return false; - } - - $fp = $this->_openPackageFile($package, 'wb', $channel); - if ($fp === null) { - return false; - } - - $info['_lastmodified'] = time(); - fwrite($fp, serialize($info)); - $this->_closePackageFile($fp); - $this->_rebuildFileMap(); - return true; - } - - /** - * @param string Package name - * @param array parsed package.xml 1.0 - * @param bool this parameter is only here for BC. Don't use it. - * @access private - */ - function _updatePackage($package, $info, $merge = true) - { - $oldinfo = $this->_packageInfo($package); - if (empty($oldinfo)) { - return false; - } - - $fp = $this->_openPackageFile($package, 'w'); - if ($fp === null) { - return false; - } - - if (is_object($info)) { - $info = $info->toArray(); - } - $info['_lastmodified'] = time(); - - $newinfo = $info; - if ($merge) { - $info = array_merge($oldinfo, $info); - } else { - $diff = $info; - } - - fwrite($fp, serialize($info)); - $this->_closePackageFile($fp); - if (isset($newinfo['filelist'])) { - $this->_rebuildFileMap(); - } - - return true; - } - - /** - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @return bool - * @access private - */ - function _updatePackage2($info) - { - if (!$this->_packageExists($info->getPackage(), $info->getChannel())) { - return false; - } - - $fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel()); - if ($fp === null) { - return false; - } - - $save = $info; - $info = $save->getArray(true); - $info['_lastmodified'] = time(); - fwrite($fp, serialize($info)); - $this->_closePackageFile($fp); - $this->_rebuildFileMap(); - return true; - } - - /** - * @param string Package name - * @param string Channel name - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null - * @access private - */ - function &_getPackage($package, $channel = 'pear.php.net') - { - $info = $this->_packageInfo($package, null, $channel); - if ($info === null) { - return $info; - } - - $a = $this->_config; - if (!$a) { - $this->_config = &new PEAR_Config; - $this->_config->set('php_dir', $this->statedir); - } - - if (!class_exists('PEAR_PackageFile')) { - require_once 'PEAR/PackageFile.php'; - } - - $pkg = &new PEAR_PackageFile($this->_config); - $pf = &$pkg->fromArray($info); - return $pf; - } - - /** - * @param string channel name - * @param bool whether to strictly retrieve channel names - * @return PEAR_ChannelFile|PEAR_Error - * @access private - */ - function &_getChannel($channel, $noaliases = false) - { - $ch = false; - if ($this->_channelExists($channel, $noaliases)) { - $chinfo = $this->_channelInfo($channel, $noaliases); - if ($chinfo) { - if (!class_exists('PEAR_ChannelFile')) { - require_once 'PEAR/ChannelFile.php'; - } - - $ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo); - } - } - - if ($ch) { - if ($ch->validate()) { - return $ch; - } - - foreach ($ch->getErrors(true) as $err) { - $message = $err['message'] . "\n"; - } - - $ch = PEAR::raiseError($message); - return $ch; - } - - if ($this->_getChannelFromAlias($channel) == 'pear.php.net') { - // the registry is not properly set up, so use defaults - if (!class_exists('PEAR_ChannelFile')) { - require_once 'PEAR/ChannelFile.php'; - } - - $pear_channel = new PEAR_ChannelFile; - $pear_channel->setName('pear.php.net'); - $pear_channel->setAlias('pear'); - $pear_channel->setSummary('PHP Extension and Application Repository'); - $pear_channel->setDefaultPEARProtocols(); - $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); - $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); - return $pear_channel; - } - - if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { - // the registry is not properly set up, so use defaults - if (!class_exists('PEAR_ChannelFile')) { - require_once 'PEAR/ChannelFile.php'; - } - $pear_channel = new PEAR_ChannelFile; - $pear_channel->setName('pecl.php.net'); - $pear_channel->setAlias('pecl'); - $pear_channel->setSummary('PHP Extension Community Library'); - $pear_channel->setDefaultPEARProtocols(); - $pear_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); - $pear_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); - $pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); - return $pear_channel; - } - - if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { - // the registry is not properly set up, so use defaults - if (!class_exists('PEAR_ChannelFile')) { - require_once 'PEAR/ChannelFile.php'; - } - - $doc_channel = new PEAR_ChannelFile; - $doc_channel->setName('doc.php.net'); - $doc_channel->setAlias('phpdocs'); - $doc_channel->setSummary('PHP Documentation Team'); - $doc_channel->setDefaultPEARProtocols(); - $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/Chiara_PEAR_Server_REST/'); - $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/Chiara_PEAR_Server_REST/'); - return $doc_channel; - } - - - if ($this->_getChannelFromAlias($channel) == '__uri') { - // the registry is not properly set up, so use defaults - if (!class_exists('PEAR_ChannelFile')) { - require_once 'PEAR/ChannelFile.php'; - } - - $private = new PEAR_ChannelFile; - $private->setName('__uri'); - $private->setDefaultPEARProtocols(); - $private->setBaseURL('REST1.0', '****'); - $private->setSummary('Pseudo-channel for static packages'); - return $private; - } - - return $ch; - } - - /** - * @param string Package name - * @param string Channel name - * @return bool - */ - function packageExists($package, $channel = 'pear.php.net') - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_packageExists($package, $channel); - $this->_unlock(); - return $ret; - } - - // }}} - - // {{{ channelExists() - - /** - * @param string channel name - * @param bool if true, then aliases will be ignored - * @return bool - */ - function channelExists($channel, $noaliases = false) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_channelExists($channel, $noaliases); - $this->_unlock(); - return $ret; - } - - // }}} - - // {{{ isAlias() - - /** - * Determines whether the parameter is an alias of a channel - * @param string - * @return bool - */ - function isAlias($alias) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_isChannelAlias($alias); - $this->_unlock(); - return $ret; - } - - // }}} - // {{{ packageInfo() - - /** - * @param string|null - * @param string|null - * @param string - * @return array|null - */ - function packageInfo($package = null, $key = null, $channel = 'pear.php.net') - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_packageInfo($package, $key, $channel); - $this->_unlock(); - return $ret; - } - - // }}} - // {{{ channelInfo() - - /** - * Retrieve a raw array of channel data. - * - * Do not use this, instead use {@link getChannel()} for normal - * operations. Array structure is undefined in this method - * @param string channel name - * @param bool whether to strictly retrieve information only on non-aliases - * @return array|null|PEAR_Error - */ - function channelInfo($channel = null, $noaliases = false) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_channelInfo($channel, $noaliases); - $this->_unlock(); - return $ret; - } - - // }}} - - /** - * @param string - */ - function channelName($channel) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_getChannelFromAlias($channel); - $this->_unlock(); - return $ret; - } - - /** - * @param string - */ - function channelAlias($channel) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_getAlias($channel); - $this->_unlock(); - return $ret; - } - // {{{ listPackages() - - function listPackages($channel = false) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_listPackages($channel); - $this->_unlock(); - return $ret; - } - - // }}} - // {{{ listAllPackages() - - function listAllPackages() - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_listAllPackages(); - $this->_unlock(); - return $ret; - } - - // }}} - // {{{ listChannel() - - function listChannels() - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_listChannels(); - $this->_unlock(); - return $ret; - } - - // }}} - // {{{ addPackage() - - /** - * Add an installed package to the registry - * @param string|PEAR_PackageFile_v1|PEAR_PackageFile_v2 package name or object - * that will be passed to {@link addPackage2()} - * @param array package info (parsed by PEAR_Common::infoFrom*() methods) - * @return bool success of saving - */ - function addPackage($package, $info) - { - if (is_object($info)) { - return $this->addPackage2($info); - } - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - $ret = $this->_addPackage($package, $info); - $this->_unlock(); - if ($ret) { - if (!class_exists('PEAR_PackageFile_v1')) { - require_once 'PEAR/PackageFile/v1.php'; - } - $pf = new PEAR_PackageFile_v1; - $pf->setConfig($this->_config); - $pf->fromArray($info); - $this->_dependencyDB->uninstallPackage($pf); - $this->_dependencyDB->installPackage($pf); - } - return $ret; - } - - // }}} - // {{{ addPackage2() - - function addPackage2($info) - { - if (!is_object($info)) { - return $this->addPackage($info['package'], $info); - } - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - $ret = $this->_addPackage2($info); - $this->_unlock(); - if ($ret) { - $this->_dependencyDB->uninstallPackage($info); - $this->_dependencyDB->installPackage($info); - } - return $ret; - } - - // }}} - // {{{ updateChannel() - - /** - * For future expandibility purposes, separate this - * @param PEAR_ChannelFile - */ - function updateChannel($channel, $lastmodified = null) - { - if ($channel->getName() == '__uri') { - return false; - } - return $this->addChannel($channel, $lastmodified, true); - } - - // }}} - // {{{ deleteChannel() - - /** - * Deletion fails if there are any packages installed from the channel - * @param string|PEAR_ChannelFile channel name - * @return boolean|PEAR_Error True on deletion, false if it doesn't exist - */ - function deleteChannel($channel) - { - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - $ret = $this->_deleteChannel($channel); - $this->_unlock(); - if ($ret && is_a($this->_config, 'PEAR_Config')) { - $this->_config->setChannels($this->listChannels()); - } - return $ret; - } - - // }}} - // {{{ addChannel() - - /** - * @param PEAR_ChannelFile Channel object - * @param string Last-Modified header from HTTP for caching - * @return boolean|PEAR_Error True on creation, false if it already exists - */ - function addChannel($channel, $lastmodified = false, $update = false) - { - if (!is_a($channel, 'PEAR_ChannelFile')) { - return false; - } - if (!$channel->validate()) { - return false; - } - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - $ret = $this->_addChannel($channel, $update, $lastmodified); - $this->_unlock(); - if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) { - $this->_config->setChannels($this->listChannels()); - } - return $ret; - } - - // }}} - // {{{ deletePackage() - - function deletePackage($package, $channel = 'pear.php.net') - { - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - $file = $this->_packageFileName($package, $channel); - if (file_exists($file)) { - $ret = @unlink($file); - } else { - $ret = false; - } - $this->_rebuildFileMap(); - $this->_unlock(); - $p = array('channel' => $channel, 'package' => $package); - $this->_dependencyDB->uninstallPackage($p); - return $ret; - } - - // }}} - // {{{ updatePackage() - - function updatePackage($package, $info, $merge = true) - { - if (is_object($info)) { - return $this->updatePackage2($info, $merge); - } - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - $ret = $this->_updatePackage($package, $info, $merge); - $this->_unlock(); - if ($ret) { - if (!class_exists('PEAR_PackageFile_v1')) { - require_once 'PEAR/PackageFile/v1.php'; - } - $pf = new PEAR_PackageFile_v1; - $pf->setConfig($this->_config); - $pf->fromArray($this->packageInfo($package)); - $this->_dependencyDB->uninstallPackage($pf); - $this->_dependencyDB->installPackage($pf); - } - return $ret; - } - - // }}} - // {{{ updatePackage2() - - function updatePackage2($info) - { - - if (!is_object($info)) { - return $this->updatePackage($info['package'], $info, $merge); - } - - if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) { - return false; - } - - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - - $ret = $this->_updatePackage2($info); - $this->_unlock(); - if ($ret) { - $this->_dependencyDB->uninstallPackage($info); - $this->_dependencyDB->installPackage($info); - } - - return $ret; - } - - // }}} - // {{{ getChannel() - /** - * @param string channel name - * @param bool whether to strictly return raw channels (no aliases) - * @return PEAR_ChannelFile|PEAR_Error - */ - function &getChannel($channel, $noaliases = false) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = &$this->_getChannel($channel, $noaliases); - $this->_unlock(); - if (!$ret) { - return PEAR::raiseError('Unknown channel: ' . $channel); - } - return $ret; - } - - // }}} - // {{{ getPackage() - /** - * @param string package name - * @param string channel name - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null - */ - function &getPackage($package, $channel = 'pear.php.net') - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $pf = &$this->_getPackage($package, $channel); - $this->_unlock(); - return $pf; - } - - // }}} - - /** - * Get PEAR_PackageFile_v[1/2] objects representing the contents of - * a dependency group that are installed. - * - * This is used at uninstall-time - * @param array - * @return array|false - */ - function getInstalledGroup($group) - { - $ret = array(); - if (isset($group['package'])) { - if (!isset($group['package'][0])) { - $group['package'] = array($group['package']); - } - foreach ($group['package'] as $package) { - $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; - $p = &$this->getPackage($package['name'], $depchannel); - if ($p) { - $save = &$p; - $ret[] = &$save; - } - } - } - if (isset($group['subpackage'])) { - if (!isset($group['subpackage'][0])) { - $group['subpackage'] = array($group['subpackage']); - } - foreach ($group['subpackage'] as $package) { - $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; - $p = &$this->getPackage($package['name'], $depchannel); - if ($p) { - $save = &$p; - $ret[] = &$save; - } - } - } - if (!count($ret)) { - return false; - } - return $ret; - } - - // {{{ getChannelValidator() - /** - * @param string channel name - * @return PEAR_Validate|false - */ - function &getChannelValidator($channel) - { - $chan = $this->getChannel($channel); - if (PEAR::isError($chan)) { - return $chan; - } - $val = $chan->getValidationObject(); - return $val; - } - // }}} - // {{{ getChannels() - /** - * @param string channel name - * @return array an array of PEAR_ChannelFile objects representing every installed channel - */ - function &getChannels() - { - $ret = array(); - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - foreach ($this->_listChannels() as $channel) { - $e = &$this->_getChannel($channel); - if (!$e || PEAR::isError($e)) { - continue; - } - $ret[] = $e; - } - $this->_unlock(); - return $ret; - } - - // }}} - // {{{ checkFileMap() - - /** - * Test whether a file or set of files belongs to a package. - * - * If an array is passed in - * @param string|array file path, absolute or relative to the pear - * install dir - * @param string|array name of PEAR package or array('package' => name, 'channel' => - * channel) of a package that will be ignored - * @param string API version - 1.1 will exclude any files belonging to a package - * @param array private recursion variable - * @return array|false which package and channel the file belongs to, or an empty - * string if the file does not belong to an installed package, - * or belongs to the second parameter's package - */ - function checkFileMap($path, $package = false, $api = '1.0', $attrs = false) - { - if (is_array($path)) { - static $notempty; - if (empty($notempty)) { - if (!class_exists('PEAR_Installer_Role')) { - require_once 'PEAR/Installer/Role.php'; - } - $notempty = create_function('$a','return !empty($a);'); - } - $package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1])) - : strtolower($package); - $pkgs = array(); - foreach ($path as $name => $attrs) { - if (is_array($attrs)) { - if (isset($attrs['install-as'])) { - $name = $attrs['install-as']; - } - if (!in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) { - // these are not installed - continue; - } - if (!in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) { - $attrs['baseinstalldir'] = is_array($package) ? $package[1] : $package; - } - if (isset($attrs['baseinstalldir'])) { - $name = $attrs['baseinstalldir'] . DIRECTORY_SEPARATOR . $name; - } - } - $pkgs[$name] = $this->checkFileMap($name, $package, $api, $attrs); - if (PEAR::isError($pkgs[$name])) { - return $pkgs[$name]; - } - } - return array_filter($pkgs, $notempty); - } - if (empty($this->filemap_cache)) { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $err = $this->_readFileMap(); - $this->_unlock(); - if (PEAR::isError($err)) { - return $err; - } - } - if (!$attrs) { - $attrs = array('role' => 'php'); // any old call would be for PHP role only - } - if (isset($this->filemap_cache[$attrs['role']][$path])) { - if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { - return false; - } - return $this->filemap_cache[$attrs['role']][$path]; - } - $l = strlen($this->install_dir); - if (substr($path, 0, $l) == $this->install_dir) { - $path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l)); - } - if (isset($this->filemap_cache[$attrs['role']][$path])) { - if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { - return false; - } - return $this->filemap_cache[$attrs['role']][$path]; - } - return false; - } - - // }}} - // {{{ flush() - /** - * Force a reload of the filemap - * @since 1.5.0RC3 - */ - function flushFileMap() - { - $this->filemap_cache = null; - clearstatcache(); // ensure that the next read gets the full, current filemap - } - - // }}} - // {{{ apiVersion() - /** - * Get the expected API version. Channels API is version 1.1, as it is backwards - * compatible with 1.0 - * @return string - */ - function apiVersion() - { - return '1.1'; - } - // }}} - - - /** - * Parse a package name, or validate a parsed package name array - * @param string|array pass in an array of format - * array( - * 'package' => 'pname', - * ['channel' => 'channame',] - * ['version' => 'version',] - * ['state' => 'state',] - * ['group' => 'groupname']) - * or a string of format - * [channel://][channame/]pname[-version|-state][/group=groupname] - * @return array|PEAR_Error - */ - function parsePackageName($param, $defaultchannel = 'pear.php.net') - { - $saveparam = $param; - if (is_array($param)) { - // convert to string for error messages - $saveparam = $this->parsedPackageNameToString($param); - // process the array - if (!isset($param['package'])) { - return PEAR::raiseError('parsePackageName(): array $param ' . - 'must contain a valid package name in index "param"', - 'package', null, null, $param); - } - if (!isset($param['uri'])) { - if (!isset($param['channel'])) { - $param['channel'] = $defaultchannel; - } - } else { - $param['channel'] = '__uri'; - } - } else { - $components = @parse_url((string) $param); - if (isset($components['scheme'])) { - if ($components['scheme'] == 'http') { - // uri package - $param = array('uri' => $param, 'channel' => '__uri'); - } elseif($components['scheme'] != 'channel') { - return PEAR::raiseError('parsePackageName(): only channel:// uris may ' . - 'be downloaded, not "' . $param . '"', 'invalid', null, null, $param); - } - } - if (!isset($components['path'])) { - return PEAR::raiseError('parsePackageName(): array $param ' . - 'must contain a valid package name in "' . $param . '"', - 'package', null, null, $param); - } - if (isset($components['host'])) { - // remove the leading "/" - $components['path'] = substr($components['path'], 1); - } - if (!isset($components['scheme'])) { - if (strpos($components['path'], '/') !== false) { - if ($components['path']{0} == '/') { - return PEAR::raiseError('parsePackageName(): this is not ' . - 'a package name, it begins with "/" in "' . $param . '"', - 'invalid', null, null, $param); - } - $parts = explode('/', $components['path']); - $components['host'] = array_shift($parts); - if (count($parts) > 1) { - $components['path'] = array_pop($parts); - $components['host'] .= '/' . implode('/', $parts); - } else { - $components['path'] = implode('/', $parts); - } - } else { - $components['host'] = $defaultchannel; - } - } else { - if (strpos($components['path'], '/')) { - $parts = explode('/', $components['path']); - $components['path'] = array_pop($parts); - $components['host'] .= '/' . implode('/', $parts); - } - } - - if (is_array($param)) { - $param['package'] = $components['path']; - } else { - $param = array( - 'package' => $components['path'] - ); - if (isset($components['host'])) { - $param['channel'] = $components['host']; - } - } - if (isset($components['fragment'])) { - $param['group'] = $components['fragment']; - } - if (isset($components['user'])) { - $param['user'] = $components['user']; - } - if (isset($components['pass'])) { - $param['pass'] = $components['pass']; - } - if (isset($components['query'])) { - parse_str($components['query'], $param['opts']); - } - // check for extension - $pathinfo = pathinfo($param['package']); - if (isset($pathinfo['extension']) && - in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) { - $param['extension'] = $pathinfo['extension']; - $param['package'] = substr($pathinfo['basename'], 0, - strlen($pathinfo['basename']) - 4); - } - // check for version - if (strpos($param['package'], '-')) { - $test = explode('-', $param['package']); - if (count($test) != 2) { - return PEAR::raiseError('parsePackageName(): only one version/state ' . - 'delimiter "-" is allowed in "' . $saveparam . '"', - 'version', null, null, $param); - } - list($param['package'], $param['version']) = $test; - } - } - // validation - $info = $this->channelExists($param['channel']); - if (PEAR::isError($info)) { - return $info; - } - if (!$info) { - return PEAR::raiseError('unknown channel "' . $param['channel'] . - '" in "' . $saveparam . '"', 'channel', null, null, $param); - } - $chan = $this->getChannel($param['channel']); - if (PEAR::isError($chan)) { - return $chan; - } - if (!$chan) { - return PEAR::raiseError("Exception: corrupt registry, could not " . - "retrieve channel " . $param['channel'] . " information", - 'registry', null, null, $param); - } - $param['channel'] = $chan->getName(); - $validate = $chan->getValidationObject(); - $vpackage = $chan->getValidationPackage(); - // validate package name - if (!$validate->validPackageName($param['package'], $vpackage['_content'])) { - return PEAR::raiseError('parsePackageName(): invalid package name "' . - $param['package'] . '" in "' . $saveparam . '"', - 'package', null, null, $param); - } - if (isset($param['group'])) { - if (!PEAR_Validate::validGroupName($param['group'])) { - return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] . - '" is not a valid group name in "' . $saveparam . '"', 'group', null, null, - $param); - } - } - if (isset($param['state'])) { - if (!in_array(strtolower($param['state']), $validate->getValidStates())) { - return PEAR::raiseError('parsePackageName(): state "' . $param['state'] - . '" is not a valid state in "' . $saveparam . '"', - 'state', null, null, $param); - } - } - if (isset($param['version'])) { - if (isset($param['state'])) { - return PEAR::raiseError('parsePackageName(): cannot contain both ' . - 'a version and a stability (state) in "' . $saveparam . '"', - 'version/state', null, null, $param); - } - // check whether version is actually a state - if (in_array(strtolower($param['version']), $validate->getValidStates())) { - $param['state'] = strtolower($param['version']); - unset($param['version']); - } else { - if (!$validate->validVersion($param['version'])) { - return PEAR::raiseError('parsePackageName(): "' . $param['version'] . - '" is neither a valid version nor a valid state in "' . - $saveparam . '"', 'version/state', null, null, $param); - } - } - } - return $param; - } - - /** - * @param array - * @return string - */ - function parsedPackageNameToString($parsed, $brief = false) - { - if (is_string($parsed)) { - return $parsed; - } - if (is_object($parsed)) { - $p = $parsed; - $parsed = array( - 'package' => $p->getPackage(), - 'channel' => $p->getChannel(), - 'version' => $p->getVersion(), - ); - } - if (isset($parsed['uri'])) { - return $parsed['uri']; - } - if ($brief) { - if ($channel = $this->channelAlias($parsed['channel'])) { - return $channel . '/' . $parsed['package']; - } - } - $upass = ''; - if (isset($parsed['user'])) { - $upass = $parsed['user']; - if (isset($parsed['pass'])) { - $upass .= ':' . $parsed['pass']; - } - $upass = "$upass@"; - } - $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package']; - if (isset($parsed['version']) || isset($parsed['state'])) { - $ver = isset($parsed['version']) ? $parsed['version'] : ''; - $ver .= isset($parsed['state']) ? $parsed['state'] : ''; - $ret .= '-' . $ver; - } - if (isset($parsed['extension'])) { - $ret .= '.' . $parsed['extension']; - } - if (isset($parsed['opts'])) { - $ret .= '?'; - foreach ($parsed['opts'] as $name => $value) { - $parsed['opts'][$name] = "$name=$value"; - } - $ret .= implode('&', $parsed['opts']); - } - if (isset($parsed['group'])) { - $ret .= '#' . $parsed['group']; - } - return $ret; - } -}PEAR-1.8.0/PEAR/REST.php100664 764 764 36152 100664 7351 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: REST.php,v 1.40 2009/03/26 23:12:46 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * For downloading xml files - */ -require_once 'PEAR.php'; -require_once 'PEAR/XMLParser.php'; - -/** - * Intelligently retrieve data, following hyperlinks if necessary, and re-directing - * as well - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_REST -{ - var $config; - var $_options; - - function PEAR_REST(&$config, $options = array()) - { - $this->config = &$config; - $this->_options = $options; - } - - /** - * Retrieve REST data, but always retrieve the local cache if it is available. - * - * This is useful for elements that should never change, such as information on a particular - * release - * @param string full URL to this resource - * @param array|false contents of the accept-encoding header - * @param boolean if true, xml will be returned as a string, otherwise, xml will be - * parsed using PEAR_XMLParser - * @return string|array - */ - function retrieveCacheFirst($url, $accept = false, $forcestring = false, $channel = false) - { - - $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . - md5($url) . 'rest.cachefile'; - - if (file_exists($cachefile)) { - return unserialize(implode('', file($cachefile))); - } - - return $this->retrieveData($url, $accept, $forcestring, $channel); - } - - /** - * Retrieve a remote REST resource - * @param string full URL to this resource - * @param array|false contents of the accept-encoding header - * @param boolean if true, xml will be returned as a string, otherwise, xml will be - * parsed using PEAR_XMLParser - * @return string|array - */ - function retrieveData($url, $accept = false, $forcestring = false, $channel = false) - { - $cacheId = $this->getCacheId($url); - if ($ret = $this->useLocalCache($url, $cacheId)) { - return $ret; - } - - $file = $trieddownload = false; - if (!isset($this->_options['offline'])) { - $trieddownload = true; - $file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept, $channel); + $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state'); + if (isset($parr['state']) && isset($parr['version'])) { + unset($parr['state']); } - if (PEAR::isError($file)) { - if ($file->getCode() !== -9276) { - return $file; + if (isset($dep['uri'])) { + $info = &$this->newDownloaderPackage($this); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $err = $info->initialize($dep); + PEAR::staticPopErrorHandling(); + if (!$err) { + // skip parameters that were missed by preferred_state + return PEAR::raiseError('Cannot initialize dependency'); } - $trieddownload = false; - $file = false; // use local copy if available on socket connect error - } + if (PEAR::isError($err)) { + if (!isset($this->_options['soft'])) { + $this->log(0, $err->getMessage()); + } - if (!$file) { - $ret = $this->getCache($url); - if (!PEAR::isError($ret) && $trieddownload) { - // reset the age of the cache if the server says it was unmodified - $this->saveCache($url, $ret, null, true, $cacheId); + if (is_object($info)) { + $param = $info->getChannel() . '/' . $info->getPackage(); + } + return PEAR::raiseError('Package "' . $param . '" is not valid'); + } + return $info; + } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) + && $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror')) + ) { + $rest = &$this->config->getREST('1.0', $this->_options); + $url = $rest->getDepDownloadURL($base, $xsdversion, $dep, $parr, + $state, $version, $chan->getName()); + if (PEAR::isError($url)) { + return $url; } - return $ret; - } + if ($parr['channel'] != $curchannel) { + $this->configSet('default_channel', $curchannel); + } - if (is_array($file)) { - $headers = $file[2]; - $lastmodified = $file[1]; - $content = $file[0]; - } else { - $headers = array(); - $lastmodified = false; - $content = $file; - } + if (!is_array($url)) { + return $url; + } - if ($forcestring) { - $this->saveCache($url, $content, $lastmodified, false, $cacheId); - return $content; - } + $url['raw'] = false; // no checking is necessary for REST + if (!is_array($url['info'])) { + return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . + 'this should never happen'); + } - if (isset($headers['content-type'])) { - switch ($headers['content-type']) { - case 'text/xml' : - case 'application/xml' : - case 'text/plain' : - if ($headers['content-type'] === 'text/plain') { - $check = substr($content, 0, 5); - if ($check !== 'setRawChannel($remotechannel); + } else { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; - $parser = new PEAR_XMLParser; - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $err = $parser->parse($content); - PEAR::popErrorHandling(); - if (PEAR::isError($err)) { - return PEAR::raiseError('Invalid xml downloaded from "' . $url . '": ' . - $err->getMessage()); - } - $content = $parser->getData(); - case 'text/html' : - default : - // use it as a string } - } else { - // assume XML - $parser = new PEAR_XMLParser; - $parser->parse($content); - $content = $parser->getData(); - } - - $this->saveCache($url, $content, $lastmodified, false, $cacheId); - return $content; - } + $pf->setRawPackage($url['package']); + $pf->setDeps($url['info']); + if ($url['compatible']) { + $pf->setCompatible($url['compatible']); + } - function useLocalCache($url, $cacheid = null) - { - if ($cacheid === null) { - $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . - md5($url) . 'rest.cacheid'; - if (!file_exists($cacheidfile)) { - return false; + $pf->setRawState($url['stability']); + $url['info'] = &$pf; + if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) { + $ext = '.tar'; + } else { + $ext = '.tgz'; } - $cacheid = unserialize(implode('', file($cacheidfile))); - } + if (is_array($url) && isset($url['url'])) { + $url['url'] .= $ext; + } - $cachettl = $this->config->get('cache_ttl'); - // If cache is newer than $cachettl seconds, we use the cache! - if (time() - $cacheid['age'] < $cachettl) { - return $this->getCache($url); + return $url; } - return false; + return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.'); } - function getCacheId($url) + /** + * @deprecated in favor of _getPackageDownloadUrl + */ + function getPackageDownloadUrl($package, $version = null, $channel = false) { - $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . - md5($url) . 'rest.cacheid'; - - if (!file_exists($cacheidfile)) { - return false; + if ($version) { + $package .= "-$version"; } - - $ret = unserialize(implode('', file($cacheidfile))); - return $ret; - } - - function getCache($url) - { - $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . - md5($url) . 'rest.cachefile'; - - if (!file_exists($cachefile)) { - return PEAR::raiseError('No cached content available for "' . $url . '"'); + if ($this === null || $this->_registry === null) { + $package = "http://pear.php.net/get/$package"; + } else { + $chan = $this->_registry->getChannel($channel); + if (PEAR::isError($chan)) { + return ''; + } + $package = "http://" . $chan->getServer() . "/get/$package"; } - - return unserialize(implode('', file($cachefile))); + if (!extension_loaded("zlib")) { + $package .= '?uncompress=yes'; + } + return $package; } /** - * @param string full URL to REST resource - * @param string original contents of the REST resource - * @param array HTTP Last-Modified and ETag headers - * @param bool if true, then the cache id file should be regenerated to - * trigger a new time-to-live value + * Retrieve a list of downloaded packages after a call to {@link download()}. + * + * Also resets the list of downloaded packages. + * @return array */ - function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null) + function getDownloadedPackages() { - $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . - md5($url) . 'rest.cacheid'; + $ret = $this->_downloadedPackages; + $this->_downloadedPackages = array(); + $this->_toDownload = array(); + return $ret; + } - $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . - md5($url) . 'rest.cachefile'; + function _downloadCallback($msg, $params = null) + { + switch ($msg) { + case 'saveas': + $this->log(1, "downloading $params ..."); + break; + case 'done': + $this->log(1, '...done: ' . number_format($params, 0, '', ',') . ' bytes'); + break; + case 'bytesread': + static $bytes; + if (empty($bytes)) { + $bytes = 0; + } + if (!($bytes % 10240)) { + $this->log(1, '.', false); + } + $bytes += $params; + break; + case 'start': + if($params[1] == -1) { + $length = "Unknown size"; + } else { + $length = number_format($params[1], 0, '', ',')." bytes"; + } + $this->log(1, "Starting to download {$params[0]} ($length)"); + break; + } + if (method_exists($this->ui, '_downloadCallback')) + $this->ui->_downloadCallback($msg, $params); + } - if ($cacheid === null && $nochange) { - $cacheid = unserialize(implode('', file($cacheidfile))); + function _prependPath($path, $prepend) + { + if (strlen($prepend) > 0) { + if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { + if (preg_match('/^[a-z]:/i', $prepend)) { + $prepend = substr($prepend, 2); + } elseif ($prepend{0} != '\\') { + $prepend = "\\$prepend"; + } + $path = substr($path, 0, 2) . $prepend . substr($path, 2); + } else { + $path = $prepend . $path; + } } + return $path; + } - $fp = @fopen($cacheidfile, 'wb'); - if (!$fp) { - $cache_dir = $this->config->get('cache_dir'); - if (is_dir($cache_dir)) { - return false; + /** + * @param string + * @param integer + */ + function pushError($errmsg, $code = -1) + { + array_push($this->_errorStack, array($errmsg, $code)); + } + + function getErrorMsgs() + { + $msgs = array(); + $errs = $this->_errorStack; + foreach ($errs as $err) { + $msgs[] = $err[0]; + } + $this->_errorStack = array(); + return $msgs; + } + + /** + * for BC + * + * @deprecated + */ + function sortPkgDeps(&$packages, $uninstall = false) + { + $uninstall ? + $this->sortPackagesForUninstall($packages) : + $this->sortPackagesForInstall($packages); + } + + /** + * Sort a list of arrays of array(downloaded packagefilename) by dependency. + * + * This uses the topological sort method from graph theory, and the + * Structures_Graph package to properly sort dependencies for installation. + * @param array an array of downloaded PEAR_Downloader_Packages + * @return array array of array(packagefilename, package.xml contents) + */ + function sortPackagesForInstall(&$packages) + { + require_once 'Structures/Graph.php'; + require_once 'Structures/Graph/Node.php'; + require_once 'Structures/Graph/Manipulator/TopologicalSorter.php'; + $depgraph = new Structures_Graph(true); + $nodes = array(); + $reg = &$this->config->getRegistry(); + foreach ($packages as $i => $package) { + $pname = $reg->parsedPackageNameToString( + array( + 'channel' => $package->getChannel(), + 'package' => strtolower($package->getPackage()), + )); + $nodes[$pname] = new Structures_Graph_Node; + $nodes[$pname]->setData($packages[$i]); + $depgraph->addNode($nodes[$pname]); + } + + $deplinks = array(); + foreach ($nodes as $package => $node) { + $pf = &$node->getData(); + $pdeps = $pf->getDeps(true); + if (!$pdeps) { + continue; } - System::mkdir(array('-p', $cache_dir)); - $fp = @fopen($cacheidfile, 'wb'); - if (!$fp) { - return false; + if ($pf->getPackagexmlVersion() == '1.0') { + foreach ($pdeps as $dep) { + if ($dep['type'] != 'pkg' || + (isset($dep['optional']) && $dep['optional'] == 'yes')) { + continue; + } + + $dname = $reg->parsedPackageNameToString( + array( + 'channel' => 'pear.php.net', + 'package' => strtolower($dep['name']), + )); + + if (isset($nodes[$dname])) { + if (!isset($deplinks[$dname])) { + $deplinks[$dname] = array(); + } + + $deplinks[$dname][$package] = 1; + // dependency is in installed packages + continue; + } + + $dname = $reg->parsedPackageNameToString( + array( + 'channel' => 'pecl.php.net', + 'package' => strtolower($dep['name']), + )); + + if (isset($nodes[$dname])) { + if (!isset($deplinks[$dname])) { + $deplinks[$dname] = array(); + } + + $deplinks[$dname][$package] = 1; + // dependency is in installed packages + continue; + } + } + } else { + // the only ordering we care about is: + // 1) subpackages must be installed before packages that depend on them + // 2) required deps must be installed before packages that depend on them + if (isset($pdeps['required']['subpackage'])) { + $t = $pdeps['required']['subpackage']; + if (!isset($t[0])) { + $t = array($t); + } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + + if (isset($pdeps['group'])) { + if (!isset($pdeps['group'][0])) { + $pdeps['group'] = array($pdeps['group']); + } + + foreach ($pdeps['group'] as $group) { + if (isset($group['subpackage'])) { + $t = $group['subpackage']; + if (!isset($t[0])) { + $t = array($t); + } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + } + } + + if (isset($pdeps['optional']['subpackage'])) { + $t = $pdeps['optional']['subpackage']; + if (!isset($t[0])) { + $t = array($t); + } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + + if (isset($pdeps['required']['package'])) { + $t = $pdeps['required']['package']; + if (!isset($t[0])) { + $t = array($t); + } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + + if (isset($pdeps['group'])) { + if (!isset($pdeps['group'][0])) { + $pdeps['group'] = array($pdeps['group']); + } + + foreach ($pdeps['group'] as $group) { + if (isset($group['package'])) { + $t = $group['package']; + if (!isset($t[0])) { + $t = array($t); + } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + } + } } } - if ($nochange) { - fwrite($fp, serialize(array( - 'age' => time(), - 'lastChange' => $cacheid['lastChange'], - )) - ); + $this->_detectDepCycle($deplinks); + foreach ($deplinks as $dependent => $parents) { + foreach ($parents as $parent => $unused) { + $nodes[$dependent]->connectTo($nodes[$parent]); + } + } - fclose($fp); + $installOrder = Structures_Graph_Manipulator_TopologicalSorter::sort($depgraph); + $ret = array(); + for ($i = 0, $count = count($installOrder); $i < $count; $i++) { + foreach ($installOrder[$i] as $index => $sortedpackage) { + $data = &$installOrder[$i][$index]->getData(); + $ret[] = &$nodes[$reg->parsedPackageNameToString( + array( + 'channel' => $data->getChannel(), + 'package' => strtolower($data->getPackage()), + ))]->getData(); + } + } + + $packages = $ret; + return; + } + + /** + * Detect recursive links between dependencies and break the cycles + * + * @param array + * @access private + */ + function _detectDepCycle(&$deplinks) + { + do { + $keepgoing = false; + foreach ($deplinks as $dep => $parents) { + foreach ($parents as $parent => $unused) { + // reset the parent cycle detector + $this->_testCycle(null, null, null); + if ($this->_testCycle($dep, $deplinks, $parent)) { + $keepgoing = true; + unset($deplinks[$dep][$parent]); + if (count($deplinks[$dep]) == 0) { + unset($deplinks[$dep]); + } + + continue 3; + } + } + } + } while ($keepgoing); + } + + function _testCycle($test, $deplinks, $dep) + { + static $visited = array(); + if ($test === null) { + $visited = array(); + return; + } + + // this happens when a parent has a dep cycle on another dependency + // but the child is not part of the cycle + if (isset($visited[$dep])) { + return false; + } + + $visited[$dep] = 1; + if ($test == $dep) { return true; } - fwrite($fp, serialize(array( - 'age' => time(), - 'lastChange' => $lastmodified, - )) - ); + if (isset($deplinks[$dep])) { + if (in_array($test, array_keys($deplinks[$dep]), true)) { + return true; + } - fclose($fp); - $fp = @fopen($cachefile, 'wb'); - if (!$fp) { - if (file_exists($cacheidfile)) { - @unlink($cacheidfile); + foreach ($deplinks[$dep] as $parent => $unused) { + if ($this->_testCycle($test, $deplinks, $parent)) { + return true; + } + } + } + + return false; + } + + /** + * Set up the dependency for installation parsing + * + * @param array $t dependency information + * @param PEAR_Registry $reg + * @param array $deplinks list of dependency links already established + * @param array $nodes all existing package nodes + * @param string $package parent package name + * @access private + */ + function _setupGraph($t, $reg, &$deplinks, &$nodes, $package) + { + foreach ($t as $dep) { + $depchannel = !isset($dep['channel']) ? '__uri': $dep['channel']; + $dname = $reg->parsedPackageNameToString( + array( + 'channel' => $depchannel, + 'package' => strtolower($dep['name']), + )); + + if (isset($nodes[$dname])) { + if (!isset($deplinks[$dname])) { + $deplinks[$dname] = array(); + } + $deplinks[$dname][$package] = 1; } + } + } + + function _dependsOn($a, $b) + { + return $this->_checkDepTree(strtolower($a->getChannel()), strtolower($a->getPackage()), $b); + } + function _checkDepTree($channel, $package, $b, $checked = array()) + { + $checked[$channel][$package] = true; + if (!isset($this->_depTree[$channel][$package])) { return false; } - fwrite($fp, serialize($contents)); - fclose($fp); - return true; + if (isset($this->_depTree[$channel][$package][strtolower($b->getChannel())] + [strtolower($b->getPackage())])) { + return true; + } + + foreach ($this->_depTree[$channel][$package] as $ch => $packages) { + foreach ($packages as $pa => $true) { + if ($this->_checkDepTree($ch, $pa, $b, $checked)) { + return true; + } + } + } + + return false; + } + + function _sortInstall($a, $b) + { + if (!$a->getDeps() && !$b->getDeps()) { + return 0; // neither package has dependencies, order is insignificant + } + if ($a->getDeps() && !$b->getDeps()) { + return 1; // $a must be installed after $b because $a has dependencies + } + if (!$a->getDeps() && $b->getDeps()) { + return -1; // $b must be installed after $a because $b has dependencies + } + // both packages have dependencies + if ($this->_dependsOn($a, $b)) { + return 1; + } + if ($this->_dependsOn($b, $a)) { + return -1; + } + return 0; } /** - * Efficiently Download a file through HTTP. Returns downloaded file as a string in-memory - * This is best used for small files + * Download a file through HTTP. Considers suggested file name in + * Content-disposition: header and can run a callback function for + * different events. The callback will be called with two + * parameters: the callback type, and parameters. The implemented + * callback types are: + * + * 'setup' called at the very beginning, parameter is a UI object + * that should be used for all output + * 'message' the parameter is a string with an informational message + * 'saveas' may be used to save with a different file name, the + * parameter is the filename that is about to be used. + * If a 'saveas' callback returns a non-empty string, + * that file name will be used as the filename instead. + * Note that $save_dir will not be affected by this, only + * the basename of the file. + * 'start' download is starting, parameter is number of bytes + * that are expected, or -1 if unknown + * 'bytesread' parameter is the number of bytes read so far + * 'done' download is complete, parameter is the total number + * of bytes read + * 'connfailed' if the TCP/SSL connection fails, this callback is called + * with array(host,port,errno,errmsg) + * 'writefailed' if writing to disk fails, this callback is called + * with array(destfile,errmsg) * * If an HTTP proxy has been configured (http_proxy PEAR_Config * setting), the proxy will be used. * * @param string $url the URL to download + * @param object $ui PEAR_Frontend_* instance + * @param object $config PEAR_Config instance * @param string $save_dir directory to save file in + * @param mixed $callback function/method to call for status + * updates * @param false|string|array $lastmodified header values to check against for caching * use false to return the header values from this download * @param false|array $accept Accept headers to send - * @return string|array Returns the contents of the downloaded file or a PEAR + * @param false|string $channel Channel to use for retrieving authentication + * @return string|array Returns the full path of the downloaded file or a PEAR * error on failure. If the error is caused by * socket-related errors, the error object will * have the fsockopen error code available through @@ -48711,12 +42238,16 @@ class PEAR_REST * * @access public */ - function downloadHttp($url, $lastmodified = null, $accept = false, $channel = false) + function downloadHttp($url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null, + $accept = false, $channel = false) { static $redirect = 0; // always reset , so we are clean case of error $wasredirect = $redirect; $redirect = 0; + if ($callback) { + call_user_func($callback, 'setup', array(&$ui)); + } $info = parse_url($url); if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) { @@ -48727,37 +42258,79 @@ class PEAR_REST return PEAR::raiseError('Cannot download from non-URL "' . $url . '"'); } - $host = isset($info['host']) ? $info['host'] : null; - $port = isset($info['port']) ? $info['port'] : null; - $path = isset($info['path']) ? $info['path'] : null; - $schema = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http'; + $host = isset($info['host']) ? $info['host'] : null; + $port = isset($info['port']) ? $info['port'] : null; + $path = isset($info['path']) ? $info['path'] : null; + + if (isset($this)) { + $config = &$this->config; + } else { + $config = &PEAR_Config::singleton(); + } $proxy_host = $proxy_port = $proxy_user = $proxy_pass = ''; - if ($this->config->get('http_proxy')&& - $proxy = parse_url($this->config->get('http_proxy')) - ) { + if ($config->get('http_proxy') && + $proxy = parse_url($config->get('http_proxy'))) { $proxy_host = isset($proxy['host']) ? $proxy['host'] : null; - if ($schema === 'https') { + if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') { $proxy_host = 'ssl://' . $proxy_host; } + $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080; + $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null; + $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null; - $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080; - $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null; - $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null; - $proxy_schema = (isset($proxy['scheme']) && $proxy['scheme'] == 'https') ? 'https' : 'http'; + if ($callback) { + call_user_func($callback, 'message', "Using HTTP proxy $host:$port"); + } } if (empty($port)) { - $port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80; + $port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80; } - if (isset($proxy['host'])) { - $request = "GET $url HTTP/1.1\r\n"; + $scheme = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http'; + + if ($proxy_host != '') { + $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr); + if (!$fp) { + if ($callback) { + call_user_func($callback, 'connfailed', array($proxy_host, $proxy_port, + $errno, $errstr)); + } + return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", $errno); + } + + if ($lastmodified === false || $lastmodified) { + $request = "GET $url HTTP/1.1\r\n"; + $request .= "Host: $host:$port\r\n"; + } else { + $request = "GET $url HTTP/1.0\r\n"; + $request .= "Host: $host\r\n"; + } } else { - $request = "GET $path HTTP/1.1\r\n"; + $network_host = $host; + if (isset($info['scheme']) && $info['scheme'] == 'https') { + $network_host = 'ssl://' . $host; + } + + $fp = @fsockopen($network_host, $port, $errno, $errstr); + if (!$fp) { + if ($callback) { + call_user_func($callback, 'connfailed', array($host, $port, + $errno, $errstr)); + } + return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); + } + + if ($lastmodified === false || $lastmodified) { + $request = "GET $path HTTP/1.1\r\n"; + $request .= "Host: $host:$port\r\n"; + } else { + $request = "GET $path HTTP/1.0\r\n"; + $request .= "Host: $host\r\n"; + } } - $request .= "Host: $host:$port\r\n"; $ifmodifiedsince = ''; if (is_array($lastmodified)) { if (isset($lastmodified['Last-Modified'])) { @@ -48772,14 +42345,15 @@ class PEAR_REST } $request .= $ifmodifiedsince . - "User-Agent: PEAR/1.8.0/PHP/" . PHP_VERSION . "\r\n"; + "User-Agent: PEAR/1.9.0/PHP/" . PHP_VERSION . "\r\n"; - $username = $this->config->get('username', null, $channel); - $password = $this->config->get('password', null, $channel); - - if ($username && $password) { - $tmp = base64_encode("$username:$password"); - $request .= "Authorization: Basic $tmp\r\n"; + if (isset($this)) { // only pass in authentication for non-static calls + $username = $config->get('username', null, $channel); + $password = $config->get('password', null, $channel); + if ($username && $password) { + $tmp = base64_encode("$username:$password"); + $request .= "Authorization: Basic $tmp\r\n"; + } } if ($proxy_host != '' && $proxy_user != '') { @@ -48791,31 +42365,12 @@ class PEAR_REST $request .= 'Accept: ' . implode(', ', $accept) . "\r\n"; } - $request .= "Accept-Encoding:\r\n"; $request .= "Connection: close\r\n"; $request .= "\r\n"; - - if ($proxy_host != '') { - $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 15); - if (!$fp) { - return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", -9276); - } - } else { - if ($schema === 'https') { - $host = 'ssl://' . $host; - } - - $fp = @fsockopen($host, $port, $errno, $errstr); - if (!$fp) { - return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); - } - } - fwrite($fp, $request); - $headers = array(); - $reply = 0; - while ($line = trim(fgets($fp, 1024))) { + $reply = 0; + while (trim($line = fgets($fp, 1024))) { if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) { $headers[strtolower($matches[1])] = trim($matches[2]); } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { @@ -48825,31 +42380,74 @@ class PEAR_REST } if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) { - return PEAR::raiseError("File $schema://$host:$port$path not valid (received: $line)"); + return PEAR::raiseError("File $scheme://$host:$port$path not valid (received: $line)"); } } } if ($reply != 200) { if (!isset($headers['location'])) { - return PEAR::raiseError("File $schema://$host:$port$path not valid (redirected but no location)"); + return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirected but no location)"); } if ($wasredirect > 4) { - return PEAR::raiseError("File $schema://$host:$port$path not valid (redirection looped more than 5 times)"); + return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirection looped more than 5 times)"); } $redirect = $wasredirect + 1; - return $this->downloadHttp($headers['location'], $lastmodified, $accept, $channel); + return $this->downloadHttp($headers['location'], + $ui, $save_dir, $callback, $lastmodified, $accept); + } + + if (isset($headers['content-disposition']) && + preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|\\z)/', $headers['content-disposition'], $matches)) { + $save_as = basename($matches[1]); + } else { + $save_as = basename($url); + } + + if ($callback) { + $tmp = call_user_func($callback, 'saveas', $save_as); + if ($tmp) { + $save_as = $tmp; + } + } + + $dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as; + if (!$wp = @fopen($dest_file, 'wb')) { + fclose($fp); + if ($callback) { + call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); + } + return PEAR::raiseError("could not open $dest_file for writing"); } $length = isset($headers['content-length']) ? $headers['content-length'] : -1; - $data = ''; - while ($chunk = @fread($fp, 8192)) { - $data .= $chunk; + $bytes = 0; + if ($callback) { + call_user_func($callback, 'start', array(basename($dest_file), $length)); + } + + while ($data = fread($fp, 1024)) { + $bytes += strlen($data); + if ($callback) { + call_user_func($callback, 'bytesread', $bytes); + } + if (!@fwrite($wp, $data)) { + fclose($fp); + if ($callback) { + call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); + } + return PEAR::raiseError("$dest_file: write failed ($php_errormsg)"); + } } + fclose($fp); + fclose($wp); + if ($callback) { + call_user_func($callback, 'done', $bytes); + } if ($lastmodified === false || $lastmodified) { if (isset($headers['etag'])) { @@ -48863,4841 +42461,11822 @@ class PEAR_REST $lastmodified = $headers['last-modified']; } } - - return array($data, $lastmodified, $headers); + return array($dest_file, $lastmodified, $headers); } - - return $data; + return $dest_file; } -}PEAR-1.8.0/PEAR/RunTest.php100664 764 764 104653 100664 10222 + * Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can + * still be done quite handily in an error callback or by manipulating the returned array + * @category Debugging + * @package PEAR_ErrorStack * @author Greg Beaver - * @copyright 1997-2009 The Authors + * @copyright 2004-2008 Greg Beaver * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: RunTest.php,v 1.74 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.3.3 + * @version CVS: $Id: ErrorStack.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR_ErrorStack */ /** - * for error handling + * Singleton storage + * + * Format: + *
    + * array(
    + *  'package1' => PEAR_ErrorStack object,
    + *  'package2' => PEAR_ErrorStack object,
    + *  ...
    + * )
    + * 
    + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] */ -require_once 'PEAR.php'; -require_once 'PEAR/Config.php'; - -define('DETAILED', 1); -putenv("PHP_PEAR_RUNTESTS=1"); +$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array(); /** - * Simplified version of PHP's test suite - * - * Try it with: - * - * $ php -r 'include "../PEAR/RunTest.php"; $t=new PEAR_RunTest; $o=$t->run("./pear_system.phpt");print_r($o);' + * Global error callback (default) + * + * This is only used if set to non-false. * is the default callback for + * all packages, whereas specific packages may set a default callback + * for all instances, regardless of whether they are a singleton or not. * + * To exclude non-singletons, only set the local callback for the singleton + * @see PEAR_ErrorStack::setDefaultCallback() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] + */ +$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array( + '*' => false, +); + +/** + * Global Log object (default) + * + * This is only used if set to non-false. Use to set a default log object for + * all stacks, regardless of instantiation order or location + * @see PEAR_ErrorStack::setDefaultLogger() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] + */ +$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false; + +/** + * Global Overriding Callback + * + * This callback will override any error callbacks that specific loggers have set. + * Use with EXTREME caution + * @see PEAR_ErrorStack::staticPushCallback() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] + */ +$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); + +/**#@+ + * One of four possible return values from the error Callback + * @see PEAR_ErrorStack::_errorCallback() + */ +/** + * If this is returned, then the error will be both pushed onto the stack + * and logged. + */ +define('PEAR_ERRORSTACK_PUSHANDLOG', 1); +/** + * If this is returned, then the error will only be pushed onto the stack, + * and not logged. + */ +define('PEAR_ERRORSTACK_PUSH', 2); +/** + * If this is returned, then the error will only be logged, but not pushed + * onto the error stack. + */ +define('PEAR_ERRORSTACK_LOG', 3); +/** + * If this is returned, then the error is completely ignored. + */ +define('PEAR_ERRORSTACK_IGNORE', 4); +/** + * If this is returned, then the error is logged and die() is called. + */ +define('PEAR_ERRORSTACK_DIE', 5); +/**#@-*/ + +/** + * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in + * the singleton method. + */ +define('PEAR_ERRORSTACK_ERR_NONCLASS', 1); + +/** + * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()} + * that has no __toString() method + */ +define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2); +/** + * Error Stack Implementation * - * @category pear - * @package PEAR - * @author Tomas V.V.Cox + * Usage: + * + * // global error stack + * $global_stack = &PEAR_ErrorStack::singleton('MyPackage'); + * // local error stack + * $local_stack = new PEAR_ErrorStack('MyPackage'); + * * @author Greg Beaver - * @copyright 1997-2009 The Authors + * @version 1.9.0 + * @package PEAR_ErrorStack + * @category Debugging + * @copyright 2004-2008 Greg Beaver * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.3.3 + * @version CVS: $Id: ErrorStack.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR_ErrorStack */ -class PEAR_RunTest -{ - var $_headers = array(); - var $_logger; - var $_options; - var $_php; - var $tests_count; - var $xdebug_loaded; +class PEAR_ErrorStack { /** - * Saved value of php executable, used to reset $_php when we - * have a test that uses cgi + * Errors are stored in the order that they are pushed on the stack. + * @since 0.4alpha Errors are no longer organized by error level. + * This renders pop() nearly unusable, and levels could be more easily + * handled in a callback anyway + * @var array + * @access private + */ + var $_errors = array(); + + /** + * Storage of errors by level. * - * @var unknown_type + * Allows easy retrieval and deletion of only errors from a particular level + * @since PEAR 1.4.0dev + * @var array + * @access private */ - var $_savephp; - var $ini_overwrites = array( - 'output_handler=', - 'open_basedir=', - 'safe_mode=0', - 'disable_functions=', - 'output_buffering=Off', - 'display_errors=1', - 'log_errors=0', - 'html_errors=0', - 'track_errors=1', - 'report_memleaks=0', - 'report_zend_debug=0', - 'docref_root=', - 'docref_ext=.html', - 'error_prepend_string=', - 'error_append_string=', - 'auto_prepend_file=', - 'auto_append_file=', - 'magic_quotes_runtime=0', - 'xdebug.default_enable=0', - 'allow_url_fopen=1', - ); + var $_errorsByLevel = array(); /** - * An object that supports the PEAR_Common->log() signature, or null - * @param PEAR_Common|null + * Package name this error stack represents + * @var string + * @access protected */ - function PEAR_RunTest($logger = null, $options = array()) + var $_package; + + /** + * Determines whether a PEAR_Error is thrown upon every error addition + * @var boolean + * @access private + */ + var $_compat = false; + + /** + * If set to a valid callback, this will be used to generate the error + * message from the error code, otherwise the message passed in will be + * used + * @var false|string|array + * @access private + */ + var $_msgCallback = false; + + /** + * If set to a valid callback, this will be used to generate the error + * context for an error. For PHP-related errors, this will be a file + * and line number as retrieved from debug_backtrace(), but can be + * customized for other purposes. The error might actually be in a separate + * configuration file, or in a database query. + * @var false|string|array + * @access protected + */ + var $_contextCallback = false; + + /** + * If set to a valid callback, this will be called every time an error + * is pushed onto the stack. The return value will be used to determine + * whether to allow an error to be pushed or logged. + * + * The return value must be one an PEAR_ERRORSTACK_* constant + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @var false|string|array + * @access protected + */ + var $_errorCallback = array(); + + /** + * PEAR::Log object for logging errors + * @var false|Log + * @access protected + */ + var $_logger = false; + + /** + * Error messages - designed to be overridden + * @var array + * @abstract + */ + var $_errorMsgs = array(); + + /** + * Set up a new error stack + * + * @param string $package name of the package this error stack represents + * @param callback $msgCallback callback used for error message generation + * @param callback $contextCallback callback used for context generation, + * defaults to {@link getFileLine()} + * @param boolean $throwPEAR_Error + */ + function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false, + $throwPEAR_Error = false) { - if (!defined('E_DEPRECATED')) { - define('E_DEPRECATED', 0); - } - if (!defined('E_STRICT')) { - define('E_STRICT', 0); + $this->_package = $package; + $this->setMessageCallback($msgCallback); + $this->setContextCallback($contextCallback); + $this->_compat = $throwPEAR_Error; + } + + /** + * Return a single error stack for this package. + * + * Note that all parameters are ignored if the stack for package $package + * has already been instantiated + * @param string $package name of the package this error stack represents + * @param callback $msgCallback callback used for error message generation + * @param callback $contextCallback callback used for context generation, + * defaults to {@link getFileLine()} + * @param boolean $throwPEAR_Error + * @param string $stackClass class to instantiate + * @static + * @return PEAR_ErrorStack + */ + function &singleton($package, $msgCallback = false, $contextCallback = false, + $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack') + { + if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; } - $this->ini_overwrites[] = 'error_reporting=' . (E_ALL & ~(E_DEPRECATED | E_STRICT)); - if (is_null($logger)) { - require_once 'PEAR/Common.php'; - $logger = new PEAR_Common; + if (!class_exists($stackClass)) { + if (function_exists('debug_backtrace')) { + $trace = debug_backtrace(); + } + PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS, + 'exception', array('stackclass' => $stackClass), + 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)', + false, $trace); } - $this->_logger = $logger; - $this->_options = $options; + $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] = + new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error); - $conf = &PEAR_Config::singleton(); - $this->_php = $conf->get('php_bin'); + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; } /** - * Taken from php-src/run-tests.php - * - * @param string $commandline command name - * @param array $env - * @param string $stdin standard input to pass to the command - * @return unknown + * Internal error handler for PEAR_ErrorStack class + * + * Dies if the error is an exception (and would have died anyway) + * @access private */ - function system_with_timeout($commandline, $env = null, $stdin = null) + function _handleError($err) { - $data = ''; - if (version_compare(phpversion(), '5.0.0', '<')) { - $proc = proc_open($commandline, array( - 0 => array('pipe', 'r'), - 1 => array('pipe', 'w'), - 2 => array('pipe', 'w') - ), $pipes); - } else { - $proc = proc_open($commandline, array( - 0 => array('pipe', 'r'), - 1 => array('pipe', 'w'), - 2 => array('pipe', 'w') - ), $pipes, null, $env, array('suppress_errors' => true)); - } - - if (!$proc) { - return false; + if ($err['level'] == 'exception') { + $message = $err['message']; + if (isset($_SERVER['REQUEST_URI'])) { + echo '
    '; + } else { + echo "\n"; + } + var_dump($err['context']); + die($message); } - - if (is_string($stdin)) { - fwrite($pipes[0], $stdin); + } + + /** + * Set up a PEAR::Log object for all error stacks that don't have one + * @param Log $log + * @static + */ + function setDefaultLogger(&$log) + { + if (is_object($log) && method_exists($log, 'log') ) { + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + } elseif (is_callable($log)) { + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + } + } + + /** + * Set up a PEAR::Log object for this error stack + * @param Log $log + */ + function setLogger(&$log) + { + if (is_object($log) && method_exists($log, 'log') ) { + $this->_logger = &$log; + } elseif (is_callable($log)) { + $this->_logger = &$log; } - fclose($pipes[0]); - - while (true) { - /* hide errors from interrupted syscalls */ - $r = $pipes; - $e = $w = null; - $n = @stream_select($r, $w, $e, 60); - - if ($n === 0) { - /* timed out */ - $data .= "\n ** ERROR: process timed out **\n"; - proc_terminate($proc); - return array(1234567890, $data); - } else if ($n > 0) { - $line = fread($pipes[1], 8192); - if (strlen($line) == 0) { - /* EOF */ - break; - } - $data .= $line; + } + + /** + * Set an error code => error message mapping callback + * + * This method sets the callback that can be used to generate error + * messages for any instance + * @param array|string Callback function/method + */ + function setMessageCallback($msgCallback) + { + if (!$msgCallback) { + $this->_msgCallback = array(&$this, 'getErrorMessage'); + } else { + if (is_callable($msgCallback)) { + $this->_msgCallback = $msgCallback; } } - if (function_exists('proc_get_status')) { - $stat = proc_get_status($proc); - if ($stat['signaled']) { - $data .= "\nTermsig=".$stat['stopsig']; + } + + /** + * Get an error code => error message mapping callback + * + * This method returns the current callback that can be used to generate error + * messages + * @return array|string|false Callback function/method or false if none + */ + function getMessageCallback() + { + return $this->_msgCallback; + } + + /** + * Sets a default callback to be used by all error stacks + * + * This method sets the callback that can be used to generate error + * messages for a singleton + * @param array|string Callback function/method + * @param string Package name, or false for all packages + * @static + */ + function setDefaultCallback($callback = false, $package = false) + { + if (!is_callable($callback)) { + $callback = false; + } + $package = $package ? $package : '*'; + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback; + } + + /** + * Set a callback that generates context information (location of error) for an error stack + * + * This method sets the callback that can be used to generate context + * information for an error. Passing in NULL will disable context generation + * and remove the expensive call to debug_backtrace() + * @param array|string|null Callback function/method + */ + function setContextCallback($contextCallback) + { + if ($contextCallback === null) { + return $this->_contextCallback = false; + } + if (!$contextCallback) { + $this->_contextCallback = array(&$this, 'getFileLine'); + } else { + if (is_callable($contextCallback)) { + $this->_contextCallback = $contextCallback; } } - $code = proc_close($proc); - if (function_exists('proc_get_status')) { - $code = $stat['exitcode']; + } + + /** + * Set an error Callback + * If set to a valid callback, this will be called every time an error + * is pushed onto the stack. The return value will be used to determine + * whether to allow an error to be pushed or logged. + * + * The return value must be one of the ERRORSTACK_* constants. + * + * This functionality can be used to emulate PEAR's pushErrorHandling, and + * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of + * the error stack or logging + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @see popCallback() + * @param string|array $cb + */ + function pushCallback($cb) + { + array_push($this->_errorCallback, $cb); + } + + /** + * Remove a callback from the error callback stack + * @see pushCallback() + * @return array|string|false + */ + function popCallback() + { + if (!count($this->_errorCallback)) { + return false; } - return array($code, $data); + return array_pop($this->_errorCallback); } - + /** - * Turns a PHP INI string into an array - * - * Turns -d "include_path=/foo/bar" into this: - * array( - * 'include_path' => array( - * 'operator' => '-d', - * 'value' => '/foo/bar', - * ) - * ) - * Works both with quotes and without + * Set a temporary overriding error callback for every package error stack * - * @param string an PHP INI string, -d "include_path=/foo/bar" - * @return array + * Use this to temporarily disable all existing callbacks (can be used + * to emulate the @ operator, for instance) + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @see staticPopCallback(), pushCallback() + * @param string|array $cb + * @static */ - function iniString2array($ini_string) + function staticPushCallback($cb) { - if (!$ini_string) { - return array(); + array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb); + } + + /** + * Remove a temporary overriding error callback + * @see staticPushCallback() + * @return array|string|false + * @static + */ + function staticPopCallback() + { + $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']); + if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) { + $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); } - $split = preg_split('/[\s]|=/', $ini_string, -1, PREG_SPLIT_NO_EMPTY); - $key = $split[1][0] == '"' ? substr($split[1], 1) : $split[1]; - $value = $split[2][strlen($split[2]) - 1] == '"' ? substr($split[2], 0, -1) : $split[2]; - // FIXME review if this is really the struct to go with - $array = array($key => array('operator' => $split[0], 'value' => $value)); - return $array; + return $ret; } - - function settings2array($settings, $ini_settings) + + /** + * Add an error to the stack + * + * If the message generator exists, it is called with 2 parameters. + * - the current Error Stack object + * - an array that is in the same format as an error. Available indices + * are 'code', 'package', 'time', 'params', 'level', and 'context' + * + * Next, if the error should contain context information, this is + * handled by the context grabbing method. + * Finally, the error is pushed onto the proper error stack + * @param int $code Package-specific error code + * @param string $level Error level. This is NOT spell-checked + * @param array $params associative array of error parameters + * @param string $msg Error message, or a portion of it if the message + * is to be generated + * @param array $repackage If this error re-packages an error pushed by + * another package, place the array returned from + * {@link pop()} in this parameter + * @param array $backtrace Protected parameter: use this to pass in the + * {@link debug_backtrace()} that should be used + * to find error context + * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also + * thrown. If a PEAR_Error is returned, the userinfo + * property is set to the following array: + * + * + * array( + * 'code' => $code, + * 'params' => $params, + * 'package' => $this->_package, + * 'level' => $level, + * 'time' => time(), + * 'context' => $context, + * 'message' => $msg, + * //['repackage' => $err] repackaged error array/Exception class + * ); + * + * + * Normally, the previous array is returned. + */ + function push($code, $level = 'error', $params = array(), $msg = false, + $repackage = false, $backtrace = false) { - foreach ($settings as $setting) { - if (strpos($setting, '=') !== false) { - $setting = explode('=', $setting, 2); - $name = trim(strtolower($setting[0])); - $value = trim($setting[1]); - $ini_settings[$name] = $value; + $context = false; + // grab error context + if ($this->_contextCallback) { + if (!$backtrace) { + $backtrace = debug_backtrace(); } + $context = call_user_func($this->_contextCallback, $code, $params, $backtrace); } - return $ini_settings; + + // save error + $time = explode(' ', microtime()); + $time = $time[1] + $time[0]; + $err = array( + 'code' => $code, + 'params' => $params, + 'package' => $this->_package, + 'level' => $level, + 'time' => $time, + 'context' => $context, + 'message' => $msg, + ); + + if ($repackage) { + $err['repackage'] = $repackage; + } + + // set up the error message, if necessary + if ($this->_msgCallback) { + $msg = call_user_func_array($this->_msgCallback, + array(&$this, $err)); + $err['message'] = $msg; + } + $push = $log = true; + $die = false; + // try the overriding callback first + $callback = $this->staticPopCallback(); + if ($callback) { + $this->staticPushCallback($callback); + } + if (!is_callable($callback)) { + // try the local callback next + $callback = $this->popCallback(); + if (is_callable($callback)) { + $this->pushCallback($callback); + } else { + // try the default callback + $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ? + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] : + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*']; + } + } + if (is_callable($callback)) { + switch(call_user_func($callback, $err)){ + case PEAR_ERRORSTACK_IGNORE: + return $err; + break; + case PEAR_ERRORSTACK_PUSH: + $log = false; + break; + case PEAR_ERRORSTACK_LOG: + $push = false; + break; + case PEAR_ERRORSTACK_DIE: + $die = true; + break; + // anything else returned has the same effect as pushandlog + } + } + if ($push) { + array_unshift($this->_errors, $err); + if (!isset($this->_errorsByLevel[$err['level']])) { + $this->_errorsByLevel[$err['level']] = array(); + } + $this->_errorsByLevel[$err['level']][] = &$this->_errors[0]; + } + if ($log) { + if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) { + $this->_log($err); + } + } + if ($die) { + die(); + } + if ($this->_compat && $push) { + return $this->raiseError($msg, $code, null, null, $err); + } + return $err; } - - function settings2params($ini_settings) + + /** + * Static version of {@link push()} + * + * @param string $package Package name this error belongs to + * @param int $code Package-specific error code + * @param string $level Error level. This is NOT spell-checked + * @param array $params associative array of error parameters + * @param string $msg Error message, or a portion of it if the message + * is to be generated + * @param array $repackage If this error re-packages an error pushed by + * another package, place the array returned from + * {@link pop()} in this parameter + * @param array $backtrace Protected parameter: use this to pass in the + * {@link debug_backtrace()} that should be used + * to find error context + * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also + * thrown. see docs for {@link push()} + * @static + */ + function staticPush($package, $code, $level = 'error', $params = array(), + $msg = false, $repackage = false, $backtrace = false) { - $settings = ''; - foreach ($ini_settings as $name => $value) { - if (is_array($value)) { - $operator = $value['operator']; - $value = $value['value']; - } else { - $operator = '-d'; + $s = &PEAR_ErrorStack::singleton($package); + if ($s->_contextCallback) { + if (!$backtrace) { + if (function_exists('debug_backtrace')) { + $backtrace = debug_backtrace(); + } } - $value = addslashes($value); - $settings .= " $operator \"$name=$value\""; } - return $settings; + return $s->push($code, $level, $params, $msg, $repackage, $backtrace); } - - function _preparePhpBin($php, $file, $ini_settings) + + /** + * Log an error using PEAR::Log + * @param array $err Error array + * @param array $levels Error level => Log constant map + * @access protected + */ + function _log($err) { - $file = escapeshellarg($file); - // This was fixed in php 5.3 and is not needed after that - if (OS_WINDOWS && version_compare(PHP_VERSION, '5.3', '<')) { - $cmd = '"'.escapeshellarg($php).' '.$ini_settings.' -f ' . $file .'"'; + if ($this->_logger) { + $logger = &$this->_logger; } else { - $cmd = $php . $ini_settings . ' -f ' . $file; + $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']; + } + if (is_a($logger, 'Log')) { + $levels = array( + 'exception' => PEAR_LOG_CRIT, + 'alert' => PEAR_LOG_ALERT, + 'critical' => PEAR_LOG_CRIT, + 'error' => PEAR_LOG_ERR, + 'warning' => PEAR_LOG_WARNING, + 'notice' => PEAR_LOG_NOTICE, + 'info' => PEAR_LOG_INFO, + 'debug' => PEAR_LOG_DEBUG); + if (isset($levels[$err['level']])) { + $level = $levels[$err['level']]; + } else { + $level = PEAR_LOG_INFO; + } + $logger->log($err['message'], $level, $err); + } else { // support non-standard logs + call_user_func($logger, $err); } - - return $cmd; } - function runPHPUnit($file, $ini_settings = '') + + /** + * Pop an error off of the error stack + * + * @return false|array + * @since 0.4alpha it is no longer possible to specify a specific error + * level to return - the last error pushed will be returned, instead + */ + function pop() { - if (!file_exists($file) && file_exists(getcwd() . DIRECTORY_SEPARATOR . $file)) { - $file = realpath(getcwd() . DIRECTORY_SEPARATOR . $file); - break; - } elseif (file_exists($file)) { - $file = realpath($file); - } - - $cmd = $this->_preparePhpBin($this->_php, $file. $ini_settings); - if (isset($this->_logger)) { - $this->_logger->log(2, 'Running command "' . $cmd . '"'); + $err = @array_shift($this->_errors); + if (!is_null($err)) { + @array_pop($this->_errorsByLevel[$err['level']]); + if (!count($this->_errorsByLevel[$err['level']])) { + unset($this->_errorsByLevel[$err['level']]); + } } - - $savedir = getcwd(); // in case the test moves us around - chdir(dirname($file)); - echo `$cmd`; - chdir($savedir); - return 'PASSED'; // we have no way of knowing this information so assume passing + return $err; } /** - * Runs an individual test case. - * - * @param string The filename of the test - * @param array|string INI settings to be applied to the test run - * @param integer Number what the current running test is of the - * whole test suite being runned. + * Pop an error off of the error stack, static method * - * @return string|object Returns PASSED, WARNED, FAILED depending on how the - * test came out. - * PEAR Error when the tester it self fails + * @param string package name + * @return boolean + * @since PEAR1.5.0a1 */ - function run($file, $ini_settings = array(), $test_number = 1) + function staticPop($package) { - if (isset($this->_savephp)) { - $this->_php = $this->_savephp; - unset($this->_savephp); + if ($package) { + if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return false; + } + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop(); } - if (empty($this->_options['cgi'])) { - // try to see if php-cgi is in the path - $res = $this->system_with_timeout('php-cgi -v'); - if (false !== $res && !(is_array($res) && $res === array(127, ''))) { - $this->_options['cgi'] = 'php-cgi'; + } + + /** + * Determine whether there are any errors on the stack + * @param string|array Level name. Use to determine if any errors + * of level (string), or levels (array) have been pushed + * @return boolean + */ + function hasErrors($level = false) + { + if ($level) { + return isset($this->_errorsByLevel[$level]); + } + return count($this->_errors); + } + + /** + * Retrieve all errors since last purge + * + * @param boolean set in order to empty the error stack + * @param string level name, to return only errors of a particular severity + * @return array + */ + function getErrors($purge = false, $level = false) + { + if (!$purge) { + if ($level) { + if (!isset($this->_errorsByLevel[$level])) { + return array(); + } else { + return $this->_errorsByLevel[$level]; + } + } else { + return $this->_errors; } } - if (1 < $len = strlen($this->tests_count)) { - $test_number = str_pad($test_number, $len, ' ', STR_PAD_LEFT); - $test_nr = "[$test_number/$this->tests_count] "; - } else { - $test_nr = ''; + if ($level) { + $ret = $this->_errorsByLevel[$level]; + foreach ($this->_errorsByLevel[$level] as $i => $unused) { + // entries are references to the $_errors array + $this->_errorsByLevel[$level][$i] = false; + } + // array_filter removes all entries === false + $this->_errors = array_filter($this->_errors); + unset($this->_errorsByLevel[$level]); + return $ret; } - - $file = realpath($file); - $section_text = $this->_readFile($file); - if (PEAR::isError($section_text)) { - return $section_text; + $ret = $this->_errors; + $this->_errors = array(); + $this->_errorsByLevel = array(); + return $ret; + } + + /** + * Determine whether there are any errors on a single error stack, or on any error stack + * + * The optional parameter can be used to test the existence of any errors without the need of + * singleton instantiation + * @param string|false Package name to check for errors + * @param string Level name to check for a particular severity + * @return boolean + * @static + */ + function staticHasErrors($package = false, $level = false) + { + if ($package) { + if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return false; + } + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level); + } + foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { + if ($obj->hasErrors($level)) { + return true; + } + } + return false; + } + + /** + * Get a list of all errors since last purge, organized by package + * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be + * @param boolean $purge Set to purge the error stack of existing errors + * @param string $level Set to a level name in order to retrieve only errors of a particular level + * @param boolean $merge Set to return a flat array, not organized by package + * @param array $sortfunc Function used to sort a merged array - default + * sorts by time, and should be good for most cases + * @static + * @return array + */ + function staticGetErrors($purge = false, $level = false, $merge = false, + $sortfunc = array('PEAR_ErrorStack', '_sortErrors')) + { + $ret = array(); + if (!is_callable($sortfunc)) { + $sortfunc = array('PEAR_ErrorStack', '_sortErrors'); + } + foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { + $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level); + if ($test) { + if ($merge) { + $ret = array_merge($ret, $test); + } else { + $ret[$package] = $test; + } + } + } + if ($merge) { + usort($ret, $sortfunc); + } + return $ret; + } + + /** + * Error sorting function, sorts by time + * @access private + */ + function _sortErrors($a, $b) + { + if ($a['time'] == $b['time']) { + return 0; + } + if ($a['time'] < $b['time']) { + return 1; } + return -1; + } - if (isset($section_text['POST_RAW']) && isset($section_text['UPLOAD'])) { - return PEAR::raiseError("Cannot contain both POST_RAW and UPLOAD in test file: $file"); + /** + * Standard file/line number/function/class context callback + * + * This function uses a backtrace generated from {@link debug_backtrace()} + * and so will not work at all in PHP < 4.3.0. The frame should + * reference the frame that contains the source of the error. + * @return array|false either array('file' => file, 'line' => line, + * 'function' => function name, 'class' => class name) or + * if this doesn't work, then false + * @param unused + * @param integer backtrace frame. + * @param array Results of debug_backtrace() + * @static + */ + function getFileLine($code, $params, $backtrace = null) + { + if ($backtrace === null) { + return false; + } + $frame = 0; + $functionframe = 1; + if (!isset($backtrace[1])) { + $functionframe = 0; + } else { + while (isset($backtrace[$functionframe]['function']) && + $backtrace[$functionframe]['function'] == 'eval' && + isset($backtrace[$functionframe + 1])) { + $functionframe++; + } + } + if (isset($backtrace[$frame])) { + if (!isset($backtrace[$frame]['file'])) { + $frame++; + } + $funcbacktrace = $backtrace[$functionframe]; + $filebacktrace = $backtrace[$frame]; + $ret = array('file' => $filebacktrace['file'], + 'line' => $filebacktrace['line']); + // rearrange for eval'd code or create function errors + if (strpos($filebacktrace['file'], '(') && + preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'], + $matches)) { + $ret['file'] = $matches[1]; + $ret['line'] = $matches[2] + 0; + } + if (isset($funcbacktrace['function']) && isset($backtrace[1])) { + if ($funcbacktrace['function'] != 'eval') { + if ($funcbacktrace['function'] == '__lambda_func') { + $ret['function'] = 'create_function() code'; + } else { + $ret['function'] = $funcbacktrace['function']; + } + } + } + if (isset($funcbacktrace['class']) && isset($backtrace[1])) { + $ret['class'] = $funcbacktrace['class']; + } + return $ret; + } + return false; + } + + /** + * Standard error message generation callback + * + * This method may also be called by a custom error message generator + * to fill in template values from the params array, simply + * set the third parameter to the error message template string to use + * + * The special variable %__msg% is reserved: use it only to specify + * where a message passed in by the user should be placed in the template, + * like so: + * + * Error message: %msg% - internal error + * + * If the message passed like so: + * + * + * $stack->push(ERROR_CODE, 'error', array(), 'server error 500'); + * + * + * The returned error message will be "Error message: server error 500 - + * internal error" + * @param PEAR_ErrorStack + * @param array + * @param string|false Pre-generated error message template + * @static + * @return string + */ + function getErrorMessage(&$stack, $err, $template = false) + { + if ($template) { + $mainmsg = $template; + } else { + $mainmsg = $stack->getErrorMessageTemplate($err['code']); + } + $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg); + if (is_array($err['params']) && count($err['params'])) { + foreach ($err['params'] as $name => $val) { + if (is_array($val)) { + // @ is needed in case $val is a multi-dimensional array + $val = @implode(', ', $val); + } + if (is_object($val)) { + if (method_exists($val, '__toString')) { + $val = $val->__toString(); + } else { + PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING, + 'warning', array('obj' => get_class($val)), + 'object %obj% passed into getErrorMessage, but has no __toString() method'); + $val = 'Object'; + } + } + $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg); + } } + return $mainmsg; + } + + /** + * Standard Error Message Template generator from code + * @return string + */ + function getErrorMessageTemplate($code) + { + if (!isset($this->_errorMsgs[$code])) { + return '%__msg%'; + } + return $this->_errorMsgs[$code]; + } + + /** + * Set the Error Message Template array + * + * The array format must be: + *
    +     * array(error code => 'message template',...)
    +     * 
    + * + * Error message parameters passed into {@link push()} will be used as input + * for the error message. If the template is 'message %foo% was %bar%', and the + * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will + * be 'message one was six' + * @return string + */ + function setErrorMessageTemplate($template) + { + $this->_errorMsgs = $template; + } + + + /** + * emulate PEAR::raiseError() + * + * @return PEAR_Error + */ + function raiseError() + { + require_once 'PEAR.php'; + $args = func_get_args(); + return call_user_func_array(array('PEAR', 'raiseError'), $args); + } +} +$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack'); +$stack->pushCallback(array('PEAR_ErrorStack', '_handleError')); +?> +PEAR-1.9.0/PEAR/Exception.php100664 764 764 33031 100664 10524 + * @author Hans Lellelid + * @author Bertrand Mansion + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Exception.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.3.3 + */ - $cwd = getcwd(); - $pass_options = ''; - if (!empty($this->_options['ini'])) { - $pass_options = $this->_options['ini']; +/** + * Base PEAR_Exception Class + * + * 1) Features: + * + * - Nestable exceptions (throw new PEAR_Exception($msg, $prev_exception)) + * - Definable triggers, shot when exceptions occur + * - Pretty and informative error messages + * - Added more context info available (like class, method or cause) + * - cause can be a PEAR_Exception or an array of mixed + * PEAR_Exceptions/PEAR_ErrorStack warnings + * - callbacks for specific exception classes and their children + * + * 2) Ideas: + * + * - Maybe a way to define a 'template' for the output + * + * 3) Inherited properties from PHP Exception Class: + * + * protected $message + * protected $code + * protected $line + * protected $file + * private $trace + * + * 4) Inherited methods from PHP Exception Class: + * + * __clone + * __construct + * getMessage + * getCode + * getFile + * getLine + * getTraceSafe + * getTraceSafeAsString + * __toString + * + * 5) Usage example + * + * + * require_once 'PEAR/Exception.php'; + * + * class Test { + * function foo() { + * throw new PEAR_Exception('Error Message', ERROR_CODE); + * } + * } + * + * function myLogger($pear_exception) { + * echo $pear_exception->getMessage(); + * } + * // each time a exception is thrown the 'myLogger' will be called + * // (its use is completely optional) + * PEAR_Exception::addObserver('myLogger'); + * $test = new Test; + * try { + * $test->foo(); + * } catch (PEAR_Exception $e) { + * print $e; + * } + * + * + * @category pear + * @package PEAR + * @author Tomas V.V.Cox + * @author Hans Lellelid + * @author Bertrand Mansion + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.3.3 + * + */ +class PEAR_Exception extends Exception +{ + const OBSERVER_PRINT = -2; + const OBSERVER_TRIGGER = -4; + const OBSERVER_DIE = -8; + protected $cause; + private static $_observers = array(); + private static $_uniqueid = 0; + private $_trace; + + /** + * Supported signatures: + * - PEAR_Exception(string $message); + * - PEAR_Exception(string $message, int $code); + * - PEAR_Exception(string $message, Exception $cause); + * - PEAR_Exception(string $message, Exception $cause, int $code); + * - PEAR_Exception(string $message, PEAR_Error $cause); + * - PEAR_Exception(string $message, PEAR_Error $cause, int $code); + * - PEAR_Exception(string $message, array $causes); + * - PEAR_Exception(string $message, array $causes, int $code); + * @param string exception message + * @param int|Exception|PEAR_Error|array|null exception cause + * @param int|null exception code or null + */ + public function __construct($message, $p2 = null, $p3 = null) + { + if (is_int($p2)) { + $code = $p2; + $this->cause = null; + } elseif (is_object($p2) || is_array($p2)) { + // using is_object allows both Exception and PEAR_Error + if (is_object($p2) && !($p2 instanceof Exception)) { + if (!class_exists('PEAR_Error') || !($p2 instanceof PEAR_Error)) { + throw new PEAR_Exception('exception cause must be Exception, ' . + 'array, or PEAR_Error'); + } + } + $code = $p3; + if (is_array($p2) && isset($p2['message'])) { + // fix potential problem of passing in a single warning + $p2 = array($p2); + } + $this->cause = $p2; + } else { + $code = null; + $this->cause = null; } + parent::__construct($message, $code); + $this->signal(); + } - if (is_string($ini_settings)) { - $ini_settings = $this->iniString2array($ini_settings); - } + /** + * @param mixed $callback - A valid php callback, see php func is_callable() + * - A PEAR_Exception::OBSERVER_* constant + * - An array(const PEAR_Exception::OBSERVER_*, + * mixed $options) + * @param string $label The name of the observer. Use this if you want + * to remove it later with removeObserver() + */ + public static function addObserver($callback, $label = 'default') + { + self::$_observers[$label] = $callback; + } - $ini_settings = $this->settings2array($this->ini_overwrites, $ini_settings); - if ($section_text['INI']) { - if (strpos($section_text['INI'], '{PWD}') !== false) { - $section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']); - } - $ini = preg_split( "/[\n\r]+/", $section_text['INI']); - $ini_settings = $this->settings2array($ini, $ini_settings); - } - $ini_settings = $this->settings2params($ini_settings); - $shortname = str_replace($cwd . DIRECTORY_SEPARATOR, '', $file); + public static function removeObserver($label = 'default') + { + unset(self::$_observers[$label]); + } - $tested = trim($section_text['TEST']); - $tested.= !isset($this->_options['simple']) ? "[$shortname]" : ' '; + /** + * @return int unique identifier for an observer + */ + public static function getUniqueId() + { + return self::$_uniqueid++; + } - if (!empty($section_text['POST']) || !empty($section_text['POST_RAW']) || - !empty($section_text['UPLOAD']) || !empty($section_text['GET']) || - !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) { - if (empty($this->_options['cgi'])) { - if (!isset($this->_options['quiet'])) { - $this->_logger->log(0, "SKIP $test_nr$tested (reason: --cgi option needed for this test, type 'pear help run-tests')"); - } - if (isset($this->_options['tapoutput'])) { - return array('ok', ' # skip --cgi option needed for this test, "pear help run-tests" for info'); - } - return 'SKIPPED'; + private function signal() + { + foreach (self::$_observers as $func) { + if (is_callable($func)) { + call_user_func($func, $this); + continue; + } + settype($func, 'array'); + switch ($func[0]) { + case self::OBSERVER_PRINT : + $f = (isset($func[1])) ? $func[1] : '%s'; + printf($f, $this->getMessage()); + break; + case self::OBSERVER_TRIGGER : + $f = (isset($func[1])) ? $func[1] : E_USER_NOTICE; + trigger_error($this->getMessage(), $f); + break; + case self::OBSERVER_DIE : + $f = (isset($func[1])) ? $func[1] : '%s'; + die(printf($f, $this->getMessage())); + break; + default: + trigger_error('invalid observer type', E_USER_WARNING); } - $this->_savephp = $this->_php; - $this->_php = $this->_options['cgi']; } + } - $temp_dir = realpath(dirname($file)); - $main_file_name = basename($file, 'phpt'); - $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'diff'; - $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'log'; - $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'exp'; - $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'out'; - $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'mem'; - $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'php'; - $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php'; - $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php'; - $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.'); + /** + * Return specific error information that can be used for more detailed + * error messages or translation. + * + * This method may be overridden in child exception classes in order + * to add functionality not present in PEAR_Exception and is a placeholder + * to define API + * + * The returned array must be an associative array of parameter => value like so: + *
    +     * array('name' => $name, 'context' => array(...))
    +     * 
    + * @return array + */ + public function getErrorData() + { + return array(); + } - // unlink old test results - $this->_cleanupOldFiles($file); + /** + * Returns the exception that caused this exception to be thrown + * @access public + * @return Exception|array The context of the exception + */ + public function getCause() + { + return $this->cause; + } - // Check if test should be skipped. - $res = $this->_runSkipIf($section_text, $temp_skipif, $tested, $ini_settings); - if (count($res) != 2) { - return $res; + /** + * Function must be public to call on caused exceptions + * @param array + */ + public function getCauseMessage(&$causes) + { + $trace = $this->getTraceSafe(); + $cause = array('class' => get_class($this), + 'message' => $this->message, + 'file' => 'unknown', + 'line' => 'unknown'); + if (isset($trace[0])) { + if (isset($trace[0]['file'])) { + $cause['file'] = $trace[0]['file']; + $cause['line'] = $trace[0]['line']; + } + } + $causes[] = $cause; + if ($this->cause instanceof PEAR_Exception) { + $this->cause->getCauseMessage($causes); + } elseif ($this->cause instanceof Exception) { + $causes[] = array('class' => get_class($this->cause), + 'message' => $this->cause->getMessage(), + 'file' => $this->cause->getFile(), + 'line' => $this->cause->getLine()); + } elseif (class_exists('PEAR_Error') && $this->cause instanceof PEAR_Error) { + $causes[] = array('class' => get_class($this->cause), + 'message' => $this->cause->getMessage(), + 'file' => 'unknown', + 'line' => 'unknown'); + } elseif (is_array($this->cause)) { + foreach ($this->cause as $cause) { + if ($cause instanceof PEAR_Exception) { + $cause->getCauseMessage($causes); + } elseif ($cause instanceof Exception) { + $causes[] = array('class' => get_class($cause), + 'message' => $cause->getMessage(), + 'file' => $cause->getFile(), + 'line' => $cause->getLine()); + } elseif (class_exists('PEAR_Error') && $cause instanceof PEAR_Error) { + $causes[] = array('class' => get_class($cause), + 'message' => $cause->getMessage(), + 'file' => 'unknown', + 'line' => 'unknown'); + } elseif (is_array($cause) && isset($cause['message'])) { + // PEAR_ErrorStack warning + $causes[] = array( + 'class' => $cause['package'], + 'message' => $cause['message'], + 'file' => isset($cause['context']['file']) ? + $cause['context']['file'] : + 'unknown', + 'line' => isset($cause['context']['line']) ? + $cause['context']['line'] : + 'unknown', + ); + } + } } - $info = $res['info']; - $warn = $res['warn']; + } - // We've satisfied the preconditions - run the test! - if (isset($this->_options['coverage']) && $this->xdebug_loaded) { - $xdebug_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'xdebug'; - $text = '_trace)) { + $this->_trace = $this->getTrace(); + if (empty($this->_trace)) { + $backtrace = debug_backtrace(); + $this->_trace = array($backtrace[count($backtrace)-1]); } + } + return $this->_trace; + } - $text .= "\n" . 'xdebug_stop_code_coverage();' . - "\n" . '} // end coverage_shutdown()' . - "\n" . 'register_shutdown_function("coverage_shutdown");'; - $text .= "\n" . 'xdebug_start_code_coverage(XDEBUG_CC_UNUSED | XDEBUG_CC_DEAD_CODE);' . "\n?>"; + public function getErrorClass() + { + $trace = $this->getTraceSafe(); + return $trace[0]['class']; + } - $len_f = 5; - if (substr($section_text['FILE'], 0, 5) != 'getTraceSafe(); + return $trace[0]['function']; + } - $this->save_text($temp_file, $text); - } else { - $this->save_text($temp_file, $section_text['FILE']); + public function __toString() + { + if (isset($_SERVER['REQUEST_URI'])) { + return $this->toHtml(); } + return $this->toText(); + } - $args = $section_text['ARGS'] ? ' -- '.$section_text['ARGS'] : ''; - $cmd = $this->_preparePhpBin($this->_php, $temp_file, $ini_settings); - $cmd.= "$args 2>&1"; - if (isset($this->_logger)) { - $this->_logger->log(2, 'Running command "' . $cmd . '"'); + public function toHtml() + { + $trace = $this->getTraceSafe(); + $causes = array(); + $this->getCauseMessage($causes); + $html = '' . "\n"; + foreach ($causes as $i => $cause) { + $html .= '\n"; } + $html .= '' . "\n" + . '' + . '' + . '' . "\n"; - // Reset environment from any previous test. - $env = $this->_resetEnv($section_text, $temp_file); + foreach ($trace as $k => $v) { + $html .= '' + . '' + . '' . "\n"; + } + $html .= '' + . '' + . '' . "\n" + . '
    ' + . str_repeat('-', $i) . ' ' . $cause['class'] . ': ' + . htmlspecialchars($cause['message']) . ' in ' . $cause['file'] . ' ' + . 'on line ' . $cause['line'] . '' + . "
    Exception trace
    #FunctionLocation
    ' . $k . ''; + if (!empty($v['class'])) { + $html .= $v['class'] . $v['type']; + } + $html .= $v['function']; + $args = array(); + if (!empty($v['args'])) { + foreach ($v['args'] as $arg) { + if (is_null($arg)) $args[] = 'null'; + elseif (is_array($arg)) $args[] = 'Array'; + elseif (is_object($arg)) $args[] = 'Object('.get_class($arg).')'; + elseif (is_bool($arg)) $args[] = $arg ? 'true' : 'false'; + elseif (is_int($arg) || is_double($arg)) $args[] = $arg; + else { + $arg = (string)$arg; + $str = htmlspecialchars(substr($arg, 0, 16)); + if (strlen($arg) > 16) $str .= '…'; + $args[] = "'" . $str . "'"; + } + } + } + $html .= '(' . implode(', ',$args) . ')' + . '' . (isset($v['file']) ? $v['file'] : 'unknown') + . ':' . (isset($v['line']) ? $v['line'] : 'unknown') + . '
    ' . ($k+1) . '{main} 
    '; + return $html; + } - $section_text = $this->_processUpload($section_text, $file); - if (PEAR::isError($section_text)) { - return $section_text; + public function toText() + { + $causes = array(); + $this->getCauseMessage($causes); + $causeMsg = ''; + foreach ($causes as $i => $cause) { + $causeMsg .= str_repeat(' ', $i) . $cause['class'] . ': ' + . $cause['message'] . ' in ' . $cause['file'] + . ' on line ' . $cause['line'] . "\n"; } + return $causeMsg . $this->getTraceAsString(); + } +} - if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) { - $post = trim($section_text['POST_RAW']); - $raw_lines = explode("\n", $post); +?>PEAR-1.9.0/PEAR/FixPHP5PEARWarnings.php100664 764 764 231 100664 12066 PEAR-1.9.0/PEAR/Frontend.php100664 764 764 15077 100664 10357 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Frontend.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ - $request = ''; - $started = false; - foreach ($raw_lines as $i => $line) { - if (empty($env['CONTENT_TYPE']) && - preg_match('/^Content-Type:(.*)/i', $line, $res)) { - $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1])); - continue; - } - if ($started) { - $request .= "\n"; - } - $started = true; - $request .= $line; - } +/** + * Include error handling + */ +//require_once 'PEAR.php'; - $env['CONTENT_LENGTH'] = strlen($request); - $env['REQUEST_METHOD'] = 'POST'; +/** + * Which user interface class is being used. + * @var string class name + */ +$GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI'; - $this->save_text($tmp_post, $request); - $cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post"; - } elseif (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) { - $post = trim($section_text['POST']); - $this->save_text($tmp_post, $post); - $content_length = strlen($post); +/** + * Instance of $_PEAR_Command_uiclass. + * @var object + */ +$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null; - $env['REQUEST_METHOD'] = 'POST'; - $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; - $env['CONTENT_LENGTH'] = $content_length; +/** + * Singleton-based frontend for PEAR user input/output + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Frontend extends PEAR +{ + /** + * Retrieve the frontend object + * @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk + * @static + */ + function &singleton($type = null) + { + if ($type === null) { + if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) { + $a = false; + return $a; + } + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } - $cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post"; - } else { - $env['REQUEST_METHOD'] = 'GET'; - $env['CONTENT_TYPE'] = ''; - $env['CONTENT_LENGTH'] = ''; + $a = PEAR_Frontend::setFrontendClass($type); + return $a; + } + + /** + * Set the frontend class that will be used by calls to {@link singleton()} + * + * Frontends are expected to conform to the PEAR naming standard of + * _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php) + * @param string $uiclass full class name + * @return PEAR_Frontend + * @static + */ + function &setFrontendClass($uiclass) + { + if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && + is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) { + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; } - if (OS_WINDOWS && isset($section_text['RETURNS'])) { - ob_start(); - system($cmd, $return_value); - $out = ob_get_contents(); - ob_end_clean(); - $section_text['RETURNS'] = (int) trim($section_text['RETURNS']); - $returnfail = ($return_value != $section_text['RETURNS']); - } else { - $returnfail = false; - $stdin = isset($section_text['STDIN']) ? $section_text['STDIN'] : null; - $out = $this->system_with_timeout($cmd, $env, $stdin); - $return_value = $out[0]; - $out = $out[1]; + if (!class_exists($uiclass)) { + $file = str_replace('_', '/', $uiclass) . '.php'; + if (PEAR_Frontend::isIncludeable($file)) { + include_once $file; + } } - $output = preg_replace('/\r\n/', "\n", trim($out)); + if (class_exists($uiclass)) { + $obj = &new $uiclass; + // quick test to see if this class implements a few of the most + // important frontend methods + if (is_a($obj, 'PEAR_Frontend')) { + $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj; + $GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass; + return $obj; + } - if (isset($tmp_post) && realpath($tmp_post) && file_exists($tmp_post)) { - @unlink(realpath($tmp_post)); + $err = PEAR::raiseError("not a frontend class: $uiclass"); + return $err; } - chdir($cwd); // in case the test moves us around - $this->_testCleanup($section_text, $temp_clean); + $err = PEAR::raiseError("no such class: $uiclass"); + return $err; + } - /* when using CGI, strip the headers from the output */ - $output = $this->_stripHeadersCGI($output); + /** + * Set the frontend class that will be used by calls to {@link singleton()} + * + * Frontends are expected to be a descendant of PEAR_Frontend + * @param PEAR_Frontend + * @return PEAR_Frontend + * @static + */ + function &setFrontendObject($uiobject) + { + if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && + is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) { + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } - if (isset($section_text['EXPECTHEADERS'])) { - $testheaders = $this->_processHeaders($section_text['EXPECTHEADERS']); - $missing = array_diff_assoc($testheaders, $this->_headers); - $changed = ''; - foreach ($missing as $header => $value) { - if (isset($this->_headers[$header])) { - $changed .= "-$header: $value\n+$header: "; - $changed .= $this->_headers[$header]; - } else { - $changed .= "-$header: $value\n"; - } - } - if ($missing) { - // tack on failed headers to output: - $output .= "\n====EXPECTHEADERS FAILURE====:\n$changed"; - } + if (!is_a($uiobject, 'PEAR_Frontend')) { + $err = PEAR::raiseError('not a valid frontend class: (' . + get_class($uiobject) . ')'); + return $err; } - // Does the output match what is expected? - do { - if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) { - if (isset($section_text['EXPECTF'])) { - $wanted = trim($section_text['EXPECTF']); - } else { - $wanted = trim($section_text['EXPECTREGEX']); - } - $wanted_re = preg_replace('/\r\n/', "\n", $wanted); - if (isset($section_text['EXPECTF'])) { - $wanted_re = preg_quote($wanted_re, '/'); - // Stick to basics - $wanted_re = str_replace("%s", ".+?", $wanted_re); //not greedy - $wanted_re = str_replace("%i", "[+\-]?[0-9]+", $wanted_re); - $wanted_re = str_replace("%d", "[0-9]+", $wanted_re); - $wanted_re = str_replace("%x", "[0-9a-fA-F]+", $wanted_re); - $wanted_re = str_replace("%f", "[+\-]?\.?[0-9]+\.?[0-9]*(E-?[0-9]+)?", $wanted_re); - $wanted_re = str_replace("%c", ".", $wanted_re); - // %f allows two points "-.0.0" but that is the best *simple* expression - } - /* DEBUG YOUR REGEX HERE - var_dump($wanted_re); - print(str_repeat('=', 80) . "\n"); - var_dump($output); - */ - if (!$returnfail && preg_match("/^$wanted_re\$/s", $output)) { - if (file_exists($temp_file)) { - unlink($temp_file); - } - if (array_key_exists('FAIL', $section_text)) { - break; - } - if (!isset($this->_options['quiet'])) { - $this->_logger->log(0, "PASS $test_nr$tested$info"); - } - if (isset($this->_options['tapoutput'])) { - return array('ok', ' - ' . $tested); - } - return 'PASSED'; - } - } else { - if (isset($section_text['EXPECTFILE'])) { - $f = $temp_dir . '/' . trim($section_text['EXPECTFILE']); - if (!($fp = @fopen($f, 'rb'))) { - return PEAR::raiseError('--EXPECTFILE-- section file ' . - $f . ' not found'); - } - fclose($fp); - $section_text['EXPECT'] = file_get_contents($f); - } - $wanted = preg_replace('/\r\n/', "\n", trim($section_text['EXPECT'])); - // compare and leave on success - if (!$returnfail && 0 == strcmp($output, $wanted)) { - if (file_exists($temp_file)) { - unlink($temp_file); - } - if (array_key_exists('FAIL', $section_text)) { - break; - } - if (!isset($this->_options['quiet'])) { - $this->_logger->log(0, "PASS $test_nr$tested$info"); - } - if (isset($this->_options['tapoutput'])) { - return array('ok', ' - ' . $tested); - } - return 'PASSED'; - } - } - } while (false); - - if (array_key_exists('FAIL', $section_text)) { - // we expect a particular failure - // this is only used for testing PEAR_RunTest - $expectf = isset($section_text['EXPECTF']) ? $wanted_re : null; - $faildiff = $this->generate_diff($wanted, $output, null, $expectf); - $faildiff = preg_replace('/\r/', '', $faildiff); - $wanted = preg_replace('/\r/', '', trim($section_text['FAIL'])); - if ($faildiff == $wanted) { - if (!isset($this->_options['quiet'])) { - $this->_logger->log(0, "PASS $test_nr$tested$info"); - } - if (isset($this->_options['tapoutput'])) { - return array('ok', ' - ' . $tested); - } - return 'PASSED'; - } - unset($section_text['EXPECTF']); - $output = $faildiff; - if (isset($section_text['RETURNS'])) { - return PEAR::raiseError('Cannot have both RETURNS and FAIL in the same test: ' . - $file); - } - } - - // Test failed so we need to report details. - $txt = $warn ? 'WARN ' : 'FAIL '; - $this->_logger->log(0, $txt . $test_nr . $tested . $info); - - // write .exp - $res = $this->_writeLog($exp_filename, $wanted); - if (PEAR::isError($res)) { - return $res; - } - - // write .out - $res = $this->_writeLog($output_filename, $output); - if (PEAR::isError($res)) { - return $res; - } - - // write .diff - $returns = isset($section_text['RETURNS']) ? - array(trim($section_text['RETURNS']), $return_value) : null; - $expectf = isset($section_text['EXPECTF']) ? $wanted_re : null; - $data = $this->generate_diff($wanted, $output, $returns, $expectf); - $res = $this->_writeLog($diff_filename, $data); - if (PEAR::isError($res)) { - return $res; - } - - // write .log - $data = " ----- EXPECTED OUTPUT -$wanted ----- ACTUAL OUTPUT -$output ----- FAILED -"; - - if ($returnfail) { - $data .= " ----- EXPECTED RETURN -$section_text[RETURNS] ----- ACTUAL RETURN -$return_value -"; - } - - $res = $this->_writeLog($log_filename, $data); - if (PEAR::isError($res)) { - return $res; - } - - if (isset($this->_options['tapoutput'])) { - $wanted = explode("\n", $wanted); - $wanted = "# Expected output:\n#\n#" . implode("\n#", $wanted); - $output = explode("\n", $output); - $output = "#\n#\n# Actual output:\n#\n#" . implode("\n#", $output); - return array($wanted . $output . 'not ok', ' - ' . $tested); - } - return $warn ? 'WARNED' : 'FAILED'; - } - - function generate_diff($wanted, $output, $rvalue, $wanted_re) - { - $w = explode("\n", $wanted); - $o = explode("\n", $output); - $wr = explode("\n", $wanted_re); - $w1 = array_diff_assoc($w, $o); - $o1 = array_diff_assoc($o, $w); - $o2 = $w2 = array(); - foreach ($w1 as $idx => $val) { - if (!$wanted_re || !isset($wr[$idx]) || !isset($o1[$idx]) || - !preg_match('/^' . $wr[$idx] . '\\z/', $o1[$idx])) { - $w2[sprintf("%03d<", $idx)] = sprintf("%03d- ", $idx + 1) . $val; - } - } - foreach ($o1 as $idx => $val) { - if (!$wanted_re || !isset($wr[$idx]) || - !preg_match('/^' . $wr[$idx] . '\\z/', $val)) { - $o2[sprintf("%03d>", $idx)] = sprintf("%03d+ ", $idx + 1) . $val; - } - } - $diff = array_merge($w2, $o2); - ksort($diff); - $extra = $rvalue ? "##EXPECTED: $rvalue[0]\r\n##RETURNED: $rvalue[1]" : ''; - return implode("\r\n", $diff) . $extra; + $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject; + $GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject); + return $uiobject; } - // Write the given text to a temporary file, and return the filename. - function save_text($filename, $text) + /** + * @param string $path relative or absolute include path + * @return boolean + * @static + */ + function isIncludeable($path) { - if (!$fp = fopen($filename, 'w')) { - return PEAR::raiseError("Cannot open file '" . $filename . "' (save_text)"); + if (file_exists($path) && is_readable($path)) { + return true; } - fwrite($fp, $text); - fclose($fp); - if (1 < DETAILED) echo " -FILE $filename {{{ -$text -}}} -"; - } - - function _cleanupOldFiles($file) - { - $temp_dir = realpath(dirname($file)); - $mainFileName = basename($file, 'phpt'); - $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'diff'; - $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'log'; - $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'exp'; - $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'out'; - $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'mem'; - $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'php'; - $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'skip.php'; - $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'clean.php'; - $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.'); - - // unlink old test results - @unlink($diff_filename); - @unlink($log_filename); - @unlink($exp_filename); - @unlink($output_filename); - @unlink($memcheck_filename); - @unlink($temp_file); - @unlink($temp_skipif); - @unlink($tmp_post); - @unlink($temp_clean); - } - - function _runSkipIf($section_text, $temp_skipif, $tested, $ini_settings) - { - $info = ''; - $warn = false; - if (array_key_exists('SKIPIF', $section_text) && trim($section_text['SKIPIF'])) { - $this->save_text($temp_skipif, $section_text['SKIPIF']); - $output = $this->system_with_timeout("$this->_php$ini_settings -f \"$temp_skipif\""); - $output = $output[1]; - $loutput = ltrim($output); - unlink($temp_skipif); - if (!strncasecmp('skip', $loutput, 4)) { - $skipreason = "SKIP $tested"; - if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) { - $skipreason .= '(reason: ' . $m[1] . ')'; - } - if (!isset($this->_options['quiet'])) { - $this->_logger->log(0, $skipreason); - } - if (isset($this->_options['tapoutput'])) { - return array('ok', ' # skip ' . $reason); - } - return 'SKIPPED'; - } - - if (!strncasecmp('info', $loutput, 4) - && preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) { - $info = " (info: $m[1])"; - } - if (!strncasecmp('warn', $loutput, 4) - && preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) { - $warn = true; /* only if there is a reason */ - $info = " (warn: $m[1])"; - } + $fp = @fopen($path, 'r', true); + if ($fp) { + fclose($fp); + return true; } - return array('warn' => $warn, 'info' => $info); + return false; } - function _stripHeadersCGI($output) + /** + * @param PEAR_Config + */ + function setConfig(&$config) { - $this->headers = array(); - if (!empty($this->_options['cgi']) && - $this->_php == $this->_options['cgi'] && - preg_match("/^(.*?)(?:\n\n(.*)|\\z)/s", $output, $match)) { - $output = isset($match[2]) ? trim($match[2]) : ''; - $this->_headers = $this->_processHeaders($match[1]); - } - - return $output; } /** - * Return an array that can be used with array_diff() to compare headers + * This can be overridden to allow session-based temporary file management * - * @param string $text + * By default, all files are deleted at the end of a session. The web installer + * needs to be able to sustain a list over many sessions in order to support + * user interaction with install scripts */ - function _processHeaders($text) - { - $headers = array(); - $rh = preg_split("/[\n\r]+/", $text); - foreach ($rh as $line) { - if (strpos($line, ':')!== false) { - $line = explode(':', $line, 2); - $headers[trim($line[0])] = trim($line[1]); - } - } - return $headers; - } - - function _readFile($file) + function addTempFile($file) { - // Load the sections of the test file. - $section_text = array( - 'TEST' => '(unnamed test)', - 'SKIPIF' => '', - 'GET' => '', - 'COOKIE' => '', - 'POST' => '', - 'ARGS' => '', - 'INI' => '', - 'CLEAN' => '', - ); - - if (!is_file($file) || !$fp = fopen($file, "r")) { - return PEAR::raiseError("Cannot open test file: $file"); - } - - $section = ''; - while (!feof($fp)) { - $line = fgets($fp); - - // Match the beginning of a section. - if (preg_match('/^--([_A-Z]+)--/', $line, $r)) { - $section = $r[1]; - $section_text[$section] = ''; - continue; - } elseif (empty($section)) { - fclose($fp); - return PEAR::raiseError("Invalid sections formats in test file: $file"); - } - - // Add to the section text. - $section_text[$section] .= $line; - } - fclose($fp); - - return $section_text; + $GLOBALS['_PEAR_Common_tempfiles'][] = $file; } - function _writeLog($logname, $data) + /** + * Log an action + * + * @param string $msg the message to log + * @param boolean $append_crlf + * @return boolean true + * @abstract + */ + function log($msg, $append_crlf = true) { - if (!$log = fopen($logname, 'w')) { - return PEAR::raiseError("Cannot create test log - $logname"); - } - fwrite($log, $data); - fclose($log); } - function _resetEnv($section_text, $temp_file) + /** + * Run a post-installation script + * + * @param array $scripts array of post-install scripts + * @abstract + */ + function runPostinstallScripts(&$scripts) { - $env = $_ENV; - $env['REDIRECT_STATUS'] = ''; - $env['QUERY_STRING'] = ''; - $env['PATH_TRANSLATED'] = ''; - $env['SCRIPT_FILENAME'] = ''; - $env['REQUEST_METHOD'] = ''; - $env['CONTENT_TYPE'] = ''; - $env['CONTENT_LENGTH'] = ''; - if (!empty($section_text['ENV'])) { - if (strpos($section_text['ENV'], '{PWD}') !== false) { - $section_text['ENV'] = str_replace('{PWD}', dirname($temp_file), $section_text['ENV']); - } - foreach (explode("\n", trim($section_text['ENV'])) as $e) { - $e = explode('=', trim($e), 2); - if (!empty($e[0]) && isset($e[1])) { - $env[$e[0]] = $e[1]; - } - } - } - if (array_key_exists('GET', $section_text)) { - $env['QUERY_STRING'] = trim($section_text['GET']); - } else { - $env['QUERY_STRING'] = ''; - } - if (array_key_exists('COOKIE', $section_text)) { - $env['HTTP_COOKIE'] = trim($section_text['COOKIE']); - } else { - $env['HTTP_COOKIE'] = ''; - } - $env['REDIRECT_STATUS'] = '1'; - $env['PATH_TRANSLATED'] = $temp_file; - $env['SCRIPT_FILENAME'] = $temp_file; - - return $env; } - function _processUpload($section_text, $file) + /** + * Display human-friendly output formatted depending on the + * $command parameter. + * + * This should be able to handle basic output data with no command + * @param mixed $data data structure containing the information to display + * @param string $command command from which this method was called + * @abstract + */ + function outputData($data, $command = '_default') { - if (array_key_exists('UPLOAD', $section_text) && !empty($section_text['UPLOAD'])) { - $upload_files = trim($section_text['UPLOAD']); - $upload_files = explode("\n", $upload_files); - - $request = "Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737\n" . - "-----------------------------20896060251896012921717172737\n"; - foreach ($upload_files as $fileinfo) { - $fileinfo = explode('=', $fileinfo); - if (count($fileinfo) != 2) { - return PEAR::raiseError("Invalid UPLOAD section in test file: $file"); - } - if (!realpath(dirname($file) . '/' . $fileinfo[1])) { - return PEAR::raiseError("File for upload does not exist: $fileinfo[1] " . - "in test file: $file"); - } - $file_contents = file_get_contents(dirname($file) . '/' . $fileinfo[1]); - $fileinfo[1] = basename($fileinfo[1]); - $request .= "Content-Disposition: form-data; name=\"$fileinfo[0]\"; filename=\"$fileinfo[1]\"\n"; - $request .= "Content-Type: text/plain\n\n"; - $request .= $file_contents . "\n" . - "-----------------------------20896060251896012921717172737\n"; - } - - if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) { - // encode POST raw - $post = trim($section_text['POST']); - $post = explode('&', $post); - foreach ($post as $i => $post_info) { - $post_info = explode('=', $post_info); - if (count($post_info) != 2) { - return PEAR::raiseError("Invalid POST data in test file: $file"); - } - $post_info[0] = rawurldecode($post_info[0]); - $post_info[1] = rawurldecode($post_info[1]); - $post[$i] = $post_info; - } - foreach ($post as $post_info) { - $request .= "Content-Disposition: form-data; name=\"$post_info[0]\"\n\n"; - $request .= $post_info[1] . "\n" . - "-----------------------------20896060251896012921717172737\n"; - } - unset($section_text['POST']); - } - $section_text['POST_RAW'] = $request; - } - - return $section_text; } - function _testCleanup($section_text, $temp_clean) + /** + * Display a modal form dialog and return the given input + * + * A frontend that requires multiple requests to retrieve and process + * data must take these needs into account, and implement the request + * handling code. + * @param string $command command from which this method was called + * @param array $prompts associative array. keys are the input field names + * and values are the description + * @param array $types array of input field types (text, password, + * etc.) keys have to be the same like in $prompts + * @param array $defaults array of default values. again keys have + * to be the same like in $prompts. Do not depend + * on a default value being set. + * @return array input sent by the user + * @abstract + */ + function userDialog($command, $prompts, $types = array(), $defaults = array()) { - if ($section_text['CLEAN']) { - // perform test cleanup - $this->save_text($temp_clean, $section_text['CLEAN']); - $this->system_with_timeout("$this->_php $temp_clean"); - if (file_exists($temp_clean)) { - unlink($temp_clean); - } - } } -}PEAR-1.8.0/PEAR/Validate.php100664 764 764 53060 100664 10322 + * @author Tomas V.V. Cox + * @author Martin Jansen * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Validate.php,v 1.54 2009/02/24 23:38:23 dufuz Exp $ + * @version CVS: $Id: Installer.php 287446 2009-08-18 11:45:05Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 + * @since File available since Release 0.1 */ -/**#@+ - * Constants for install stage + +/** + * Used for installation groups in package.xml 2.0 and platform exceptions */ -define('PEAR_VALIDATE_INSTALLING', 1); -define('PEAR_VALIDATE_UNINSTALLING', 2); // this is not bit-mapped like the others -define('PEAR_VALIDATE_NORMAL', 3); -define('PEAR_VALIDATE_DOWNLOADING', 4); // this is not bit-mapped like the others -define('PEAR_VALIDATE_PACKAGING', 7); -/**#@-*/ -require_once 'PEAR/Common.php'; -require_once 'PEAR/Validator/PECL.php'; +require_once 'OS/Guess.php'; +require_once 'PEAR/Downloader.php'; +define('PEAR_INSTALLER_NOBINARY', -240); /** - * Validation class for package.xml - channel-level advanced validation + * Administration class used to install PEAR packages and maintain the + * installed package database. + * * @category pear * @package PEAR + * @author Stig Bakken + * @author Tomas V.V. Cox + * @author Martin Jansen * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 + * @since Class available since Release 0.1 */ -class PEAR_Validate +class PEAR_Installer extends PEAR_Downloader { - var $packageregex = _PEAR_COMMON_PACKAGE_NAME_PREG; - /** - * @var PEAR_PackageFile_v1|PEAR_PackageFile_v2 + // {{{ properties + + /** name of the package directory, for example Foo-1.0 + * @var string */ - var $_packagexml; - /** - * @var int one of the PEAR_VALIDATE_* constants + var $pkgdir; + + /** directory where PHP code files go + * @var string */ - var $_state = PEAR_VALIDATE_NORMAL; - /** - * Format: ('error' => array('field' => name, 'reason' => reason), 'warning' => same) - * @var array - * @access private + var $phpdir; + + /** directory where PHP extension files go + * @var string */ - var $_failures = array('error' => array(), 'warning' => array()); + var $extdir; - /** - * Override this method to handle validation of normal package names - * @param string - * @return bool - * @access protected + /** directory where documentation goes + * @var string */ - function _validPackageName($name) - { - return (bool) preg_match('/^' . $this->packageregex . '\\z/', $name); - } + var $docdir; - /** - * @param string package name to validate - * @param string name of channel-specific validation package - * @final + /** installation root directory (ala PHP's INSTALL_ROOT or + * automake's DESTDIR + * @var string */ - function validPackageName($name, $validatepackagename = false) - { - if ($validatepackagename) { - if (strtolower($name) == strtolower($validatepackagename)) { - return (bool) preg_match('/^[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*\\z/', $name); - } - } - return $this->_validPackageName($name); - } + var $installroot = ''; + + /** debug level + * @var int + */ + var $debug = 1; + + /** temporary directory + * @var string + */ + var $tmpdir; /** - * This validates a bundle name, and bundle names must conform - * to the PEAR naming convention, so the method is final and static. - * @param string - * @final - * @static + * PEAR_Registry object used by the installer + * @var PEAR_Registry */ - function validGroupName($name) - { - return (bool) preg_match('/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/', $name); - } + var $registry; /** - * Determine whether $state represents a valid stability level - * @param string - * @return bool - * @static - * @final + * array of PEAR_Downloader_Packages + * @var array */ - function validState($state) - { - return in_array($state, array('snapshot', 'devel', 'alpha', 'beta', 'stable')); - } + var $_downloadedPackages; - /** - * Get a list of valid stability levels - * @return array - * @static - * @final + /** List of file transactions queued for an install/upgrade/uninstall. + * + * Format: + * array( + * 0 => array("rename => array("from-file", "to-file")), + * 1 => array("delete" => array("file-to-delete")), + * ... + * ) + * + * @var array */ - function getValidStates() - { - return array('snapshot', 'devel', 'alpha', 'beta', 'stable'); - } + var $file_operations = array(); - /** - * Determine whether a version is a properly formatted version number that can be used - * by version_compare - * @param string - * @return bool - * @static - * @final - */ - function validVersion($ver) - { - return (bool) preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); - } + // }}} - /** - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - */ - function setPackageFile(&$pf) - { - $this->_packagexml = &$pf; - } + // {{{ constructor /** - * @access private + * PEAR_Installer constructor. + * + * @param object $ui user interface object (instance of PEAR_Frontend_*) + * + * @access public */ - function _addFailure($field, $reason) + function PEAR_Installer(&$ui) { - $this->_failures['errors'][] = array('field' => $field, 'reason' => $reason); + parent::PEAR_Common(); + $this->setFrontendObject($ui); + $this->debug = $this->config->get('verbose'); } - /** - * @access private - */ - function _addWarning($field, $reason) + function setOptions($options) { - $this->_failures['warnings'][] = array('field' => $field, 'reason' => $reason); + $this->_options = $options; } - function getFailures() + function setConfig(&$config) { - $failures = $this->_failures; - $this->_failures = array('warnings' => array(), 'errors' => array()); - return $failures; + $this->config = &$config; + $this->_registry = &$config->getRegistry(); } - /** - * @param int one of the PEAR_VALIDATE_* constants - */ - function validate($state = null) - { - if (!isset($this->_packagexml)) { - return false; - } - if ($state !== null) { - $this->_state = $state; - } - $this->_failures = array('warnings' => array(), 'errors' => array()); - $this->validatePackageName(); - $this->validateVersion(); - $this->validateMaintainers(); - $this->validateDate(); - $this->validateSummary(); - $this->validateDescription(); - $this->validateLicense(); - $this->validateNotes(); - if ($this->_packagexml->getPackagexmlVersion() == '1.0') { - $this->validateState(); - $this->validateFilelist(); - } elseif ($this->_packagexml->getPackagexmlVersion() == '2.0' || - $this->_packagexml->getPackagexmlVersion() == '2.1') { - $this->validateTime(); - $this->validateStability(); - $this->validateDeps(); - $this->validateMainFilelist(); - $this->validateReleaseFilelist(); - //$this->validateGlobalTasks(); - $this->validateChangelog(); - } - return !((bool) count($this->_failures['errors'])); - } + // }}} - /** - * @access protected - */ - function validatePackageName() + function _removeBackups($files) { - if ($this->_state == PEAR_VALIDATE_PACKAGING || - $this->_state == PEAR_VALIDATE_NORMAL) { - if (($this->_packagexml->getPackagexmlVersion() == '2.0' || - $this->_packagexml->getPackagexmlVersion() == '2.1') && - $this->_packagexml->getExtends()) { - $version = $this->_packagexml->getVersion() . ''; - $name = $this->_packagexml->getPackage(); - $test = array_shift($a = explode('.', $version)); - if ($test == '0') { - return true; - } - $vlen = strlen($test); - $majver = substr($name, strlen($name) - $vlen); - while ($majver && !is_numeric($majver{0})) { - $majver = substr($majver, 1); - } - if ($majver != $test) { - $this->_addWarning('package', "package $name extends package " . - $this->_packagexml->getExtends() . ' and so the name should ' . - 'have a postfix equal to the major version like "' . - $this->_packagexml->getExtends() . $test . '"'); - return true; - } elseif (substr($name, 0, strlen($name) - $vlen) != - $this->_packagexml->getExtends()) { - $this->_addWarning('package', "package $name extends package " . - $this->_packagexml->getExtends() . ' and so the name must ' . - 'be an extension like "' . $this->_packagexml->getExtends() . - $test . '"'); - return true; - } - } - } - if (!$this->validPackageName($this->_packagexml->getPackage())) { - $this->_addFailure('name', 'package name "' . - $this->_packagexml->getPackage() . '" is invalid'); - return false; + foreach ($files as $path) { + $this->addFileOperation('removebackup', array($path)); } } + // {{{ _deletePackageFiles() + /** + * Delete a package's installed files, does not remove empty directories. + * + * @param string package name + * @param string channel name + * @param bool if true, then files are backed up first + * @return bool TRUE on success, or a PEAR error on failure * @access protected */ - function validateVersion() + function _deletePackageFiles($package, $channel = false, $backup = false) { - if ($this->_state != PEAR_VALIDATE_PACKAGING) { - if (!$this->validVersion($this->_packagexml->getVersion())) { - $this->_addFailure('version', - 'Invalid version number "' . $this->_packagexml->getVersion() . '"'); - } - return false; - } - $version = $this->_packagexml->getVersion(); - $versioncomponents = explode('.', $version); - if (count($versioncomponents) != 3) { - $this->_addWarning('version', - 'A version number should have 3 decimals (x.y.z)'); - return true; + if (!$channel) { + $channel = 'pear.php.net'; } - $name = $this->_packagexml->getPackage(); - // version must be based upon state - switch ($this->_packagexml->getState()) { - case 'snapshot' : - return true; - case 'devel' : - if ($versioncomponents[0] . 'a' == '0a') { - return true; - } - if ($versioncomponents[0] == 0) { - $versioncomponents[0] = '0'; - $this->_addWarning('version', - 'version "' . $version . '" should be "' . - implode('.' ,$versioncomponents) . '"'); - } else { - $this->_addWarning('version', - 'packages with devel stability must be < version 1.0.0'); - } - return true; - break; - case 'alpha' : - case 'beta' : - // check for a package that extends a package, - // like Foo and Foo2 - if ($this->_state == PEAR_VALIDATE_PACKAGING) { - if (substr($versioncomponents[2], 1, 2) == 'rc') { - $this->_addFailure('version', 'Release Candidate versions ' . - 'must have capital RC, not lower-case rc'); - return false; - } - } - if (!$this->_packagexml->getExtends()) { - if ($versioncomponents[0] == '1') { - if ($versioncomponents[2]{0} == '0') { - if ($versioncomponents[2] == '0') { - // version 1.*.0000 - $this->_addWarning('version', - 'version 1.' . $versioncomponents[1] . - '.0 probably should not be alpha or beta'); - return true; - } elseif (strlen($versioncomponents[2]) > 1) { - // version 1.*.0RC1 or 1.*.0beta24 etc. - return true; - } else { - // version 1.*.0 - $this->_addWarning('version', - 'version 1.' . $versioncomponents[1] . - '.0 probably should not be alpha or beta'); - return true; - } - } else { - $this->_addWarning('version', - 'bugfix versions (1.3.x where x > 0) probably should ' . - 'not be alpha or beta'); - return true; - } - } elseif ($versioncomponents[0] != '0') { - $this->_addWarning('version', - 'major versions greater than 1 are not allowed for packages ' . - 'without an tag or an identical postfix (foo2 v2.0.0)'); - return true; - } - if ($versioncomponents[0] . 'a' == '0a') { - return true; - } - if ($versioncomponents[0] == 0) { - $versioncomponents[0] = '0'; - $this->_addWarning('version', - 'version "' . $version . '" should be "' . - implode('.' ,$versioncomponents) . '"'); - } - } else { - $vlen = strlen($versioncomponents[0] . ''); - $majver = substr($name, strlen($name) - $vlen); - while ($majver && !is_numeric($majver{0})) { - $majver = substr($majver, 1); - } - if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) { - $this->_addWarning('version', 'first version number "' . - $versioncomponents[0] . '" must match the postfix of ' . - 'package name "' . $name . '" (' . - $majver . ')'); - return true; - } - if ($versioncomponents[0] == $majver) { - if ($versioncomponents[2]{0} == '0') { - if ($versioncomponents[2] == '0') { - // version 2.*.0000 - $this->_addWarning('version', - "version $majver." . $versioncomponents[1] . - '.0 probably should not be alpha or beta'); - return false; - } elseif (strlen($versioncomponents[2]) > 1) { - // version 2.*.0RC1 or 2.*.0beta24 etc. - return true; - } else { - // version 2.*.0 - $this->_addWarning('version', - "version $majver." . $versioncomponents[1] . - '.0 cannot be alpha or beta'); - return true; - } - } else { - $this->_addWarning('version', - "bugfix versions ($majver.x.y where y > 0) should " . - 'not be alpha or beta'); - return true; - } - } elseif ($versioncomponents[0] != '0') { - $this->_addWarning('version', - "only versions 0.x.y and $majver.x.y are allowed for alpha/beta releases"); - return true; - } - if ($versioncomponents[0] . 'a' == '0a') { - return true; - } - if ($versioncomponents[0] == 0) { - $versioncomponents[0] = '0'; - $this->_addWarning('version', - 'version "' . $version . '" should be "' . - implode('.' ,$versioncomponents) . '"'); - } - } - return true; - break; - case 'stable' : - if ($versioncomponents[0] == '0') { - $this->_addWarning('version', 'versions less than 1.0.0 cannot ' . - 'be stable'); - return true; - } - if (!is_numeric($versioncomponents[2])) { - if (preg_match('/\d+(rc|a|alpha|b|beta)\d*/i', - $versioncomponents[2])) { - $this->_addWarning('version', 'version "' . $version . '" or any ' . - 'RC/beta/alpha version cannot be stable'); - return true; - } - } - // check for a package that extends a package, - // like Foo and Foo2 - if ($this->_packagexml->getExtends()) { - $vlen = strlen($versioncomponents[0] . ''); - $majver = substr($name, strlen($name) - $vlen); - while ($majver && !is_numeric($majver{0})) { - $majver = substr($majver, 1); - } - if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) { - $this->_addWarning('version', 'first version number "' . - $versioncomponents[0] . '" must match the postfix of ' . - 'package name "' . $name . '" (' . - $majver . ')'); - return true; - } - } elseif ($versioncomponents[0] > 1) { - $this->_addWarning('version', 'major version x in x.y.z may not be greater than ' . - '1 for any package that does not have an tag'); - } - return true; - break; - default : - return false; - break; + + if (!strlen($package)) { + return $this->raiseError("No package to uninstall given"); } - } - /** - * @access protected - */ - function validateMaintainers() - { - // maintainers can only be truly validated server-side for most channels - // but allow this customization for those who wish it - return true; - } + if (strtolower($package) == 'pear' && $channel == 'pear.php.net') { + // to avoid race conditions, include all possible needed files + require_once 'PEAR/Task/Common.php'; + require_once 'PEAR/Task/Replace.php'; + require_once 'PEAR/Task/Unixeol.php'; + require_once 'PEAR/Task/Windowseol.php'; + require_once 'PEAR/PackageFile/v1.php'; + require_once 'PEAR/PackageFile/v2.php'; + require_once 'PEAR/PackageFile/Generator/v1.php'; + require_once 'PEAR/PackageFile/Generator/v2.php'; + } - /** - * @access protected - */ - function validateDate() - { - if ($this->_state == PEAR_VALIDATE_NORMAL || - $this->_state == PEAR_VALIDATE_PACKAGING) { + $filelist = $this->_registry->packageInfo($package, 'filelist', $channel); + if ($filelist == null) { + return $this->raiseError("$channel/$package not installed"); + } - if (!preg_match('/(\d\d\d\d)\-(\d\d)\-(\d\d)/', - $this->_packagexml->getDate(), $res) || - count($res) < 4 - || !checkdate($res[2], $res[3], $res[1]) - ) { - $this->_addFailure('date', 'invalid release date "' . - $this->_packagexml->getDate() . '"'); - return false; + $ret = array(); + foreach ($filelist as $file => $props) { + if (empty($props['installed_as'])) { + continue; } - if ($this->_state == PEAR_VALIDATE_PACKAGING && - $this->_packagexml->getDate() != date('Y-m-d')) { - $this->_addWarning('date', 'Release Date "' . - $this->_packagexml->getDate() . '" is not today'); + $path = $props['installed_as']; + if ($backup) { + $this->addFileOperation('backup', array($path)); + $ret[] = $path; } + + $this->addFileOperation('delete', array($path)); + } + + if ($backup) { + return $ret; } + return true; } + // }}} + // {{{ _installFile() + /** - * @access protected + * @param string filename + * @param array attributes from tag in package.xml + * @param string path to install the file in + * @param array options from command-line + * @access private */ - function validateTime() + function _installFile($file, $atts, $tmp_path, $options) { - if (!$this->_packagexml->getTime()) { - // default of no time value set - return true; + // {{{ return if this file is meant for another platform + static $os; + if (!isset($this->_registry)) { + $this->_registry = &$this->config->getRegistry(); } - // packager automatically sets time, so only validate if pear validate is called - if ($this->_state = PEAR_VALIDATE_NORMAL) { - if (!preg_match('/\d\d:\d\d:\d\d/', - $this->_packagexml->getTime())) { - $this->_addFailure('time', 'invalid release time "' . - $this->_packagexml->getTime() . '"'); - return false; + if (isset($atts['platform'])) { + if (empty($os)) { + $os = new OS_Guess(); } - $result = preg_match('|\d{2}\:\d{2}\:\d{2}|', $this->_packagexml->getTime(), $matches); - if ($result === false || empty($matches)) { - $this->_addFailure('time', 'invalid release time "' . - $this->_packagexml->getTime() . '"'); - return false; + if (strlen($atts['platform']) && $atts['platform']{0} == '!') { + $negate = true; + $platform = substr($atts['platform'], 1); + } else { + $negate = false; + $platform = $atts['platform']; + } + + if ((bool) $os->matchSignature($platform) === $negate) { + $this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")"); + return PEAR_INSTALLER_SKIPPED; } } + // }}} - return true; - } + $channel = $this->pkginfo->getChannel(); + // {{{ assemble the destination paths + switch ($atts['role']) { + case 'src': + case 'extsrc': + $this->source_files++; + return; + case 'doc': + case 'data': + case 'test': + $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel) . + DIRECTORY_SEPARATOR . $this->pkginfo->getPackage(); + unset($atts['baseinstalldir']); + break; + case 'ext': + case 'php': + $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel); + break; + case 'script': + $dest_dir = $this->config->get('bin_dir', null, $channel); + break; + default: + return $this->raiseError("Invalid role `$atts[role]' for file $file"); + } - /** - * @access protected - */ - function validateState() - { - // this is the closest to "final" php4 can get - if (!PEAR_Validate::validState($this->_packagexml->getState())) { - if (strtolower($this->_packagexml->getState() == 'rc')) { - $this->_addFailure('state', 'RC is not a state, it is a version ' . - 'postfix, use ' . $this->_packagexml->getVersion() . 'RC1, state beta'); - } - $this->_addFailure('state', 'invalid release state "' . - $this->_packagexml->getState() . '", must be one of: ' . - implode(', ', PEAR_Validate::getValidStates())); - return false; + $save_destdir = $dest_dir; + if (!empty($atts['baseinstalldir'])) { + $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; } - return true; - } - /** - * @access protected - */ - function validateStability() - { - $ret = true; - $packagestability = $this->_packagexml->getState(); - $apistability = $this->_packagexml->getState('api'); - if (!PEAR_Validate::validState($packagestability)) { - $this->_addFailure('state', 'invalid release stability "' . - $this->_packagexml->getState() . '", must be one of: ' . - implode(', ', PEAR_Validate::getValidStates())); - $ret = false; + if (dirname($file) != '.' && empty($atts['install-as'])) { + $dest_dir .= DIRECTORY_SEPARATOR . dirname($file); } - $apistates = PEAR_Validate::getValidStates(); - array_shift($apistates); // snapshot is not allowed - if (!in_array($apistability, $apistates)) { - $this->_addFailure('state', 'invalid API stability "' . - $this->_packagexml->getState('api') . '", must be one of: ' . - implode(', ', $apistates)); - $ret = false; - } - return $ret; - } - /** - * @access protected - */ - function validateSummary() - { - return true; - } + if (empty($atts['install-as'])) { + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); + } else { + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as']; + } + $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file; - /** - * @access protected - */ - function validateDescription() - { - return true; - } + // Clean up the DIRECTORY_SEPARATOR mess + $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; + list($dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), + array(DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR), + array($dest_file, $orig_file)); + $final_dest_file = $installed_as = $dest_file; + if (isset($this->_options['packagingroot'])) { + $installedas_dest_dir = dirname($final_dest_file); + $installedas_dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + $final_dest_file = $this->_prependPath($final_dest_file, $this->_options['packagingroot']); + } else { + $installedas_dest_dir = dirname($final_dest_file); + $installedas_dest_file = $installedas_dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + } - /** - * @access protected - */ - function validateLicense() - { - return true; - } + $dest_dir = dirname($final_dest_file); + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { + return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); + } + // }}} - /** - * @access protected - */ - function validateNotes() - { - return true; - } + if (empty($this->_options['register-only']) && + (!file_exists($dest_dir) || !is_dir($dest_dir))) { + if (!$this->mkDirHier($dest_dir)) { + return $this->raiseError("failed to mkdir $dest_dir", + PEAR_INSTALLER_FAILED); + } + $this->log(3, "+ mkdir $dest_dir"); + } - /** - * for package.xml 2.0 only - channels can't use package.xml 1.0 - * @access protected - */ - function validateDependencies() - { - return true; - } + // pretty much nothing happens if we are only registering the install + if (empty($this->_options['register-only'])) { + if (empty($atts['replacements'])) { + if (!file_exists($orig_file)) { + return $this->raiseError("file $orig_file does not exist", + PEAR_INSTALLER_FAILED); + } - /** - * for package.xml 1.0 only - * @access private - */ - function _validateFilelist() - { - return true; // placeholder for now - } + if (!@copy($orig_file, $dest_file)) { + return $this->raiseError("failed to write $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } - /** - * for package.xml 2.0 only - * @access protected - */ - function validateMainFilelist() - { - return true; // placeholder for now - } + $this->log(3, "+ cp $orig_file $dest_file"); + if (isset($atts['md5sum'])) { + $md5sum = md5_file($dest_file); + } + } else { + // {{{ file with replacements + if (!file_exists($orig_file)) { + return $this->raiseError("file does not exist", + PEAR_INSTALLER_FAILED); + } - /** - * for package.xml 2.0 only - * @access protected - */ - function validateReleaseFilelist() - { - return true; // placeholder for now - } + $contents = file_get_contents($orig_file); + if ($contents === false) { + $contents = ''; + } - /** - * @access protected - */ - function validateChangelog() - { - return true; - } + if (isset($atts['md5sum'])) { + $md5sum = md5($contents); + } - /** - * @access protected - */ - function validateFilelist() - { - return true; - } + $subst_from = $subst_to = array(); + foreach ($atts['replacements'] as $a) { + $to = ''; + if ($a['type'] == 'php-const') { + if (preg_match('/^[a-z0-9_]+\\z/i', $a['to'])) { + eval("\$to = $a[to];"); + } else { + if (!isset($options['soft'])) { + $this->log(0, "invalid php-const replacement: $a[to]"); + } + continue; + } + } elseif ($a['type'] == 'pear-config') { + if ($a['to'] == 'master_server') { + $chan = $this->_registry->getChannel($channel); + if (!PEAR::isError($chan)) { + $to = $chan->getServer(); + } else { + $to = $this->config->get($a['to'], null, $channel); + } + } else { + $to = $this->config->get($a['to'], null, $channel); + } + if (is_null($to)) { + if (!isset($options['soft'])) { + $this->log(0, "invalid pear-config replacement: $a[to]"); + } + continue; + } + } elseif ($a['type'] == 'package-info') { + if ($t = $this->pkginfo->packageInfo($a['to'])) { + $to = $t; + } else { + if (!isset($options['soft'])) { + $this->log(0, "invalid package-info replacement: $a[to]"); + } + continue; + } + } + if (!is_null($to)) { + $subst_from[] = $a['from']; + $subst_to[] = $to; + } + } - /** - * @access protected - */ - function validateDeps() - { - return true; - } -}PEAR-1.8.0/PEAR/XMLParser.php100664 764 764 16252 100664 10410 - * @author Stephan Schmidt (original XML_Unserializer code) - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version CVS: $Id: XMLParser.php,v 1.22 2009/03/08 00:45:39 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ + $this->log(3, "doing ".sizeof($subst_from)." substitution(s) for $final_dest_file"); + if (sizeof($subst_from)) { + $contents = str_replace($subst_from, $subst_to, $contents); + } -/** - * Parser for any xml file - * @category pear - * @package PEAR - * @author Greg Beaver - * @author Stephan Schmidt (original XML_Unserializer code) - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_XMLParser -{ - /** - * unserilialized data - * @var string $_serializedData - */ - var $_unserializedData = null; + $wp = @fopen($dest_file, "wb"); + if (!is_resource($wp)) { + return $this->raiseError("failed to create $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } - /** - * name of the root tag - * @var string $_root - */ - var $_root = null; + if (@fwrite($wp, $contents) === false) { + return $this->raiseError("failed writing to $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } - /** - * stack for all data that is found - * @var array $_dataStack - */ - var $_dataStack = array(); + fclose($wp); + // }}} + } - /** - * stack for all values that are generated - * @var array $_valStack - */ - var $_valStack = array(); + // {{{ check the md5 + if (isset($md5sum)) { + if (strtolower($md5sum) === strtolower($atts['md5sum'])) { + $this->log(2, "md5sum ok: $final_dest_file"); + } else { + if (empty($options['force'])) { + // delete the file + if (file_exists($dest_file)) { + unlink($dest_file); + } - /** - * current tag depth - * @var int $_depth - */ - var $_depth = 0; + if (!isset($options['ignore-errors'])) { + return $this->raiseError("bad md5sum for file $final_dest_file", + PEAR_INSTALLER_FAILED); + } - /** - * The XML encoding to use - * @var string $encoding - */ - var $encoding = 'ISO-8859-1'; + if (!isset($options['soft'])) { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); + } + } else { + if (!isset($options['soft'])) { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); + } + } + } + } + // }}} + // {{{ set file permissions + if (!OS_WINDOWS) { + if ($atts['role'] == 'script') { + $mode = 0777 & ~(int)octdec($this->config->get('umask')); + $this->log(3, "+ chmod +x $dest_file"); + } else { + $mode = 0666 & ~(int)octdec($this->config->get('umask')); + } - /** - * @return array - */ - function getData() - { - return $this->_unserializedData; - } + if ($atts['role'] != 'src') { + $this->addFileOperation("chmod", array($mode, $dest_file)); + if (!@chmod($dest_file, $mode)) { + if (!isset($options['soft'])) { + $this->log(0, "failed to change mode of $dest_file: $php_errormsg"); + } + } + } + } + // }}} - /** - * @param string xml content - * @return true|PEAR_Error - */ - function parse($data) - { - if (!extension_loaded('xml')) { - include_once 'PEAR.php'; - return PEAR::raiseError("XML Extension not found", 1); + if ($atts['role'] == 'src') { + rename($dest_file, $final_dest_file); + $this->log(2, "renamed source file $dest_file to $final_dest_file"); + } else { + $this->addFileOperation("rename", array($dest_file, $final_dest_file, + $atts['role'] == 'ext')); + } } - $this->_valStack = array(); - $this->_dataStack = array(); - $this->_depth = 0; - if ( - strpos($data, 'encoding="UTF-8"') - || strpos($data, 'encoding="utf-8"') - || strpos($data, "encoding='UTF-8'") - || strpos($data, "encoding='utf-8'") - ) { - $this->encoding = 'UTF-8'; + // Store the full path where the file was installed for easy unistall + if ($atts['role'] != 'script') { + $loc = $this->config->get($atts['role'] . '_dir'); + } else { + $loc = $this->config->get('bin_dir'); } - if (version_compare(phpversion(), '5.0.0', 'lt') && $this->encoding == 'UTF-8') { - $data = utf8_decode($data); + if ($atts['role'] != 'src') { + $this->addFileOperation("installed_as", array($file, $installed_as, + $loc, + dirname(substr($installedas_dest_file, strlen($loc))))); } - $xp = xml_parser_create($this->encoding); - xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, 0); - xml_set_object($xp, $this); - xml_set_element_handler($xp, 'startHandler', 'endHandler'); - xml_set_character_data_handler($xp, 'cdataHandler'); - if (!xml_parse($xp, $data)) { - $msg = xml_error_string(xml_get_error_code($xp)); - $line = xml_get_current_line_number($xp); - xml_parser_free($xp); - include_once 'PEAR.php'; - return PEAR::raiseError("XML Error: '$msg' on line '$line'", 2); - } - xml_parser_free($xp); - return true; + //$this->log(2, "installed: $dest_file"); + return PEAR_INSTALLER_OK; } + // }}} + // {{{ _installFile2() + /** - * Start element handler for XML parser - * + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param string filename + * @param array attributes from tag in package.xml + * @param string path to install the file in + * @param array options from command-line * @access private - * @param object $parser XML parser object - * @param string $element XML element - * @param array $attribs attributes of XML tag - * @return void */ - function startHandler($parser, $element, $attribs) + function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options) { - $type = 'string'; + $atts = $real_atts; + if (!isset($this->_registry)) { + $this->_registry = &$this->config->getRegistry(); + } - $this->_depth++; - $this->_dataStack[$this->_depth] = null; + $channel = $pkg->getChannel(); + // {{{ assemble the destination paths + if (!in_array($atts['attribs']['role'], + PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { + return $this->raiseError('Invalid role `' . $atts['attribs']['role'] . + "' for file $file"); + } - $val = array( - 'name' => $element, - 'value' => null, - 'type' => $type, - 'childrenKeys' => array(), - 'aggregKeys' => array() - ); + $role = &PEAR_Installer_Role::factory($pkg, $atts['attribs']['role'], $this->config); + $err = $role->setup($this, $pkg, $atts['attribs'], $file); + if (PEAR::isError($err)) { + return $err; + } - if (count($attribs) > 0) { - $val['children'] = array(); - $val['type'] = 'array'; + if (!$role->isInstallable()) { + return; + } - $val['children']['attribs'] = $attribs; + $info = $role->processInstallation($pkg, $atts['attribs'], $file, $tmp_path); + if (PEAR::isError($info)) { + return $info; + } + list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info; + if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { + return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); } - array_push($this->_valStack, $val); - } + $final_dest_file = $installed_as = $dest_file; + if (isset($this->_options['packagingroot'])) { + $final_dest_file = $this->_prependPath($final_dest_file, + $this->_options['packagingroot']); + } - /** - * post-process data - * - * @param string $data - * @param string $element element name - */ - function postProcess($data, $element) - { - return trim($data); - } + $dest_dir = dirname($final_dest_file); + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + // }}} - /** - * End element handler for XML parser - * - * @access private - * @param object XML parser object - * @param string - * @return void - */ - function endHandler($parser, $element) - { - $value = array_pop($this->_valStack); - $data = $this->postProcess($this->_dataStack[$this->_depth], $element); + if (empty($this->_options['register-only'])) { + if (!file_exists($dest_dir) || !is_dir($dest_dir)) { + if (!$this->mkDirHier($dest_dir)) { + return $this->raiseError("failed to mkdir $dest_dir", + PEAR_INSTALLER_FAILED); + } + $this->log(3, "+ mkdir $dest_dir"); + } + } - // adjust type of the value - switch(strtolower($value['type'])) { + $attribs = $atts['attribs']; + unset($atts['attribs']); + // pretty much nothing happens if we are only registering the install + if (empty($this->_options['register-only'])) { + if (!count($atts)) { // no tasks + if (!file_exists($orig_file)) { + return $this->raiseError("file $orig_file does not exist", + PEAR_INSTALLER_FAILED); + } - // unserialize an array - case 'array': - if ($data !== '') { - $value['children']['_content'] = $data; + if (!@copy($orig_file, $dest_file)) { + return $this->raiseError("failed to write $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); } - if (isset($value['children'])) { - $value['value'] = $value['children']; - } else { - $value['value'] = array(); + + $this->log(3, "+ cp $orig_file $dest_file"); + if (isset($attribs['md5sum'])) { + $md5sum = md5_file($dest_file); + } + } else { // file with tasks + if (!file_exists($orig_file)) { + return $this->raiseError("file $orig_file does not exist", + PEAR_INSTALLER_FAILED); } - break; - /* - * unserialize a null value - */ - case 'null': - $data = null; - break; + $contents = file_get_contents($orig_file); + if ($contents === false) { + $contents = ''; + } - /* - * unserialize any scalar value - */ - default: - settype($data, $value['type']); - $value['value'] = $data; - break; - } + if (isset($attribs['md5sum'])) { + $md5sum = md5($contents); + } - $parent = array_pop($this->_valStack); - if ($parent === null) { - $this->_unserializedData = &$value['value']; - $this->_root = &$value['name']; - return true; - } + foreach ($atts as $tag => $raw) { + $tag = str_replace(array($pkg->getTasksNs() . ':', '-'), array('', '_'), $tag); + $task = "PEAR_Task_$tag"; + $task = &new $task($this->config, $this, PEAR_TASK_INSTALL); + if (!$task->isScript()) { // scripts are only handled after installation + $task->init($raw, $attribs, $pkg->getLastInstalledVersion()); + $res = $task->startSession($pkg, $contents, $final_dest_file); + if ($res === false) { + continue; // skip this file + } - // parent has to be an array - if (!isset($parent['children']) || !is_array($parent['children'])) { - $parent['children'] = array(); - if ($parent['type'] != 'array') { - $parent['type'] = 'array'; + if (PEAR::isError($res)) { + return $res; + } + + $contents = $res; // save changes + } + + $wp = @fopen($dest_file, "wb"); + if (!is_resource($wp)) { + return $this->raiseError("failed to create $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + + if (fwrite($wp, $contents) === false) { + return $this->raiseError("failed writing to $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + + fclose($wp); + } } - } - if (!empty($value['name'])) { - // there already has been a tag with this name - if (in_array($value['name'], $parent['childrenKeys'])) { - // no aggregate has been created for this tag - if (!in_array($value['name'], $parent['aggregKeys'])) { - if (isset($parent['children'][$value['name']])) { - $parent['children'][$value['name']] = array($parent['children'][$value['name']]); + // {{{ check the md5 + if (isset($md5sum)) { + // Make sure the original md5 sum matches with expected + if (strtolower($md5sum) === strtolower($attribs['md5sum'])) { + $this->log(2, "md5sum ok: $final_dest_file"); + + if (isset($contents)) { + // set md5 sum based on $content in case any tasks were run. + $real_atts['attribs']['md5sum'] = md5($contents); + } + } else { + if (empty($options['force'])) { + // delete the file + if (file_exists($dest_file)) { + unlink($dest_file); + } + + if (!isset($options['ignore-errors'])) { + return $this->raiseError("bad md5sum for file $final_dest_file", + PEAR_INSTALLER_FAILED); + } + + if (!isset($options['soft'])) { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); + } } else { - $parent['children'][$value['name']] = array(); + if (!isset($options['soft'])) { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); + } } - array_push($parent['aggregKeys'], $value['name']); } - array_push($parent['children'][$value['name']], $value['value']); } else { - $parent['children'][$value['name']] = &$value['value']; - array_push($parent['childrenKeys'], $value['name']); + $real_atts['attribs']['md5sum'] = md5_file($dest_file); + } + + // }}} + // {{{ set file permissions + if (!OS_WINDOWS) { + if ($role->isExecutable()) { + $mode = 0777 & ~(int)octdec($this->config->get('umask')); + $this->log(3, "+ chmod +x $dest_file"); + } else { + $mode = 0666 & ~(int)octdec($this->config->get('umask')); + } + + if ($attribs['role'] != 'src') { + $this->addFileOperation("chmod", array($mode, $dest_file)); + if (!@chmod($dest_file, $mode)) { + if (!isset($options['soft'])) { + $this->log(0, "failed to change mode of $dest_file: $php_errormsg"); + } + } + } + } + // }}} + + if ($attribs['role'] == 'src') { + rename($dest_file, $final_dest_file); + $this->log(2, "renamed source file $dest_file to $final_dest_file"); + } else { + $this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension())); } - } else { - array_push($parent['children'],$value['value']); } - array_push($this->_valStack, $parent); - $this->_depth--; + // Store the full path where the file was installed for easy uninstall + if ($attribs['role'] != 'src') { + $loc = $this->config->get($role->getLocationConfig(), null, $channel); + $this->addFileOperation('installed_as', array($file, $installed_as, + $loc, + dirname(substr($installed_as, strlen($loc))))); + } + + //$this->log(2, "installed: $dest_file"); + return PEAR_INSTALLER_OK; } + // }}} + // {{{ addFileOperation() + /** - * Handler for character data + * Add a file operation to the current file transaction. * - * @access private - * @param object XML parser object - * @param string CDATA - * @return void + * @see startFileTransaction() + * @param string $type This can be one of: + * - rename: rename a file ($data has 3 values) + * - backup: backup an existing file ($data has 1 value) + * - removebackup: clean up backups created during install ($data has 1 value) + * - chmod: change permissions on a file ($data has 2 values) + * - delete: delete a file ($data has 1 value) + * - rmdir: delete a directory if empty ($data has 1 value) + * - installed_as: mark a file as installed ($data has 4 values). + * @param array $data For all file operations, this array must contain the + * full path to the file or directory that is being operated on. For + * the rename command, the first parameter must be the file to rename, + * the second its new name, the third whether this is a PHP extension. + * + * The installed_as operation contains 4 elements in this order: + * 1. Filename as listed in the filelist element from package.xml + * 2. Full path to the installed file + * 3. Full path from the php_dir configuration variable used in this + * installation + * 4. Relative path from the php_dir that this file is installed in */ - function cdataHandler($parser, $cdata) + function addFileOperation($type, $data) { - $this->_dataStack[$this->_depth] .= $cdata; + if (!is_array($data)) { + return $this->raiseError('Internal Error: $data in addFileOperation' + . ' must be an array, was ' . gettype($data)); + } + + if ($type == 'chmod') { + $octmode = decoct($data[0]); + $this->log(3, "adding to transaction: $type $octmode $data[1]"); + } else { + $this->log(3, "adding to transaction: $type " . implode(" ", $data)); + } + $this->file_operations[] = array($type, $data); } -}PEAR-1.8.0/scripts/pear.bat100777 764 764 11102 100777 10440 @ECHO OFF - -REM ---------------------------------------------------------------------- -REM PHP version 5 -REM ---------------------------------------------------------------------- -REM Copyright (c) 1997-2004 The PHP Group -REM ---------------------------------------------------------------------- -REM This source file is subject to version 3.0 of the PHP license, -REM that is bundled with this package in the file LICENSE, and is -REM available at through the world-wide-web at -REM http://www.php.net/license/3_0.txt. -REM If you did not receive a copy of the PHP license and are unable to -REM obtain it through the world-wide-web, please send a note to -REM license@php.net so we can mail you a copy immediately. -REM ---------------------------------------------------------------------- -REM Authors: Alexander Merz (alexmerz@php.net) -REM ---------------------------------------------------------------------- -REM -REM Last updated 12/29/2004 ($Id$ is not replaced if the file is binary) - -REM change this lines to match the paths of your system -REM ------------------- - - -REM Test to see if this is a raw pear.bat (uninstalled version) -SET TMPTMPTMPTMPT=@includ -SET PMTPMTPMT=%TMPTMPTMPTMPT%e_path@ -FOR %%x IN ("@include_path@") DO (if %%x=="%PMTPMTPMT%" GOTO :NOTINSTALLED) - -REM Check PEAR global ENV, set them if they do not exist -IF "%PHP_PEAR_INSTALL_DIR%"=="" SET "PHP_PEAR_INSTALL_DIR=@include_path@" -IF "%PHP_PEAR_BIN_DIR%"=="" SET "PHP_PEAR_BIN_DIR=@bin_dir@" -IF "%PHP_PEAR_PHP_BIN%"=="" SET "PHP_PEAR_PHP_BIN=@php_bin@" -GOTO :INSTALLED - -:NOTINSTALLED -ECHO WARNING: This is a raw, uninstalled pear.bat - -REM Check to see if we can grab the directory of this file (Windows NT+) -IF %~n0 == pear ( -FOR %%x IN (cli\php.exe php.exe) DO (if "%%~$PATH:x" NEQ "" ( -SET "PHP_PEAR_PHP_BIN=%%~$PATH:x" -echo Using PHP Executable "%PHP_PEAR_PHP_BIN%" -"%PHP_PEAR_PHP_BIN%" -v -GOTO :NEXTTEST -)) -GOTO :FAILAUTODETECT -:NEXTTEST -IF "%PHP_PEAR_PHP_BIN%" NEQ "" ( - -REM We can use this PHP to run a temporary php file to get the dirname of pear - -echo ^ > ~~getloc.php -"%PHP_PEAR_PHP_BIN%" ~~getloc.php -set /p PHP_PEAR_BIN_DIR=fakeprompt < ~a.a -DEL ~a.a -DEL ~~getloc.php -set "PHP_PEAR_INSTALL_DIR=%PHP_PEAR_BIN_DIR%pear" - -REM Make sure there is a pearcmd.php at our disposal - -IF NOT EXIST %PHP_PEAR_INSTALL_DIR%\pearcmd.php ( -IF EXIST %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php COPY %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php -IF EXIST pearcmd.php COPY pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php -IF EXIST %~dp0\scripts\pearcmd.php COPY %~dp0\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php -) -) -GOTO :INSTALLED -) ELSE ( -REM Windows Me/98 cannot succeed, so allow the batch to fail -) -:FAILAUTODETECT -echo WARNING: failed to auto-detect pear information -:INSTALLED - -REM Check Folders and files -IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%" GOTO PEAR_INSTALL_ERROR -IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" GOTO PEAR_INSTALL_ERROR2 -IF NOT EXIST "%PHP_PEAR_BIN_DIR%" GOTO PEAR_BIN_ERROR -IF NOT EXIST "%PHP_PEAR_PHP_BIN%" GOTO PEAR_PHPBIN_ERROR -REM launch pearcmd -GOTO RUN -:PEAR_INSTALL_ERROR -ECHO PHP_PEAR_INSTALL_DIR is not set correctly. -ECHO Please fix it using your environment variable or modify -ECHO the default value in pear.bat -ECHO The current value is: -ECHO %PHP_PEAR_INSTALL_DIR% -GOTO END -:PEAR_INSTALL_ERROR2 -ECHO PHP_PEAR_INSTALL_DIR is not set correctly. -ECHO pearcmd.php could not be found there. -ECHO Please fix it using your environment variable or modify -ECHO the default value in pear.bat -ECHO The current value is: -ECHO %PHP_PEAR_INSTALL_DIR% -GOTO END -:PEAR_BIN_ERROR -ECHO PHP_PEAR_BIN_DIR is not set correctly. -ECHO Please fix it using your environment variable or modify -ECHO the default value in pear.bat -ECHO The current value is: -ECHO %PHP_PEAR_BIN_DIR% -GOTO END -:PEAR_PHPBIN_ERROR -ECHO PHP_PEAR_PHP_BIN is not set correctly. -ECHO Please fix it using your environment variable or modify -ECHO the default value in pear.bat -ECHO The current value is: -ECHO %PHP_PEAR_PHP_BIN% -GOTO END -:RUN -"%PHP_PEAR_PHP_BIN%" -C -d output_buffering=1 -d safe_mode=0 -d open_basedir="" -d auto_prepend_file="" -d auto_append_file="" -d variables_order=EGPCS -d register_argc_argv="On" -d include_path="%PHP_PEAR_INSTALL_DIR%" -f "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" -- %1 %2 %3 %4 %5 %6 %7 %8 %9 -:END -@ECHO ONPEAR-1.8.0/scripts/peardev.bat100777 764 764 11112 100777 11140 @ECHO OFF - -REM ---------------------------------------------------------------------- -REM PHP version 5 -REM ---------------------------------------------------------------------- -REM Copyright (c) 1997-2004 The PHP Group -REM ---------------------------------------------------------------------- -REM This source file is subject to version 3.0 of the PHP license, -REM that is bundled with this package in the file LICENSE, and is -REM available at through the world-wide-web at -REM http://www.php.net/license/3_0.txt. -REM If you did not receive a copy of the PHP license and are unable to -REM obtain it through the world-wide-web, please send a note to -REM license@php.net so we can mail you a copy immediately. -REM ---------------------------------------------------------------------- -REM Authors: Alexander Merz (alexmerz@php.net) -REM ---------------------------------------------------------------------- -REM -REM $Id: peardev.bat,v 1.6 2007/09/03 03:00:17 cellog Exp $ - -REM change this lines to match the paths of your system -REM ------------------- - - -REM Test to see if this is a raw pear.bat (uninstalled version) -SET TMPTMPTMPTMPT=@includ -SET PMTPMTPMT=%TMPTMPTMPTMPT%e_path@ -FOR %%x IN ("@include_path@") DO (if %%x=="%PMTPMTPMT%" GOTO :NOTINSTALLED) - -REM Check PEAR global ENV, set them if they do not exist -IF "%PHP_PEAR_INSTALL_DIR%"=="" SET "PHP_PEAR_INSTALL_DIR=@include_path@" -IF "%PHP_PEAR_BIN_DIR%"=="" SET "PHP_PEAR_BIN_DIR=@bin_dir@" -IF "%PHP_PEAR_PHP_BIN%"=="" SET "PHP_PEAR_PHP_BIN=@php_bin@" -GOTO :INSTALLED - -:NOTINSTALLED -ECHO WARNING: This is a raw, uninstalled pear.bat - -REM Check to see if we can grab the directory of this file (Windows NT+) -IF %~n0 == pear ( -FOR %%x IN (cli\php.exe php.exe) DO (if "%%~$PATH:x" NEQ "" ( -SET "PHP_PEAR_PHP_BIN=%%~$PATH:x" -echo Using PHP Executable "%PHP_PEAR_PHP_BIN%" -"%PHP_PEAR_PHP_BIN%" -v -GOTO :NEXTTEST -)) -GOTO :FAILAUTODETECT -:NEXTTEST -IF "%PHP_PEAR_PHP_BIN%" NEQ "" ( - -REM We can use this PHP to run a temporary php file to get the dirname of pear - -echo ^ > ~~getloc.php -"%PHP_PEAR_PHP_BIN%" ~~getloc.php -set /p PHP_PEAR_BIN_DIR=fakeprompt < ~a.a -DEL ~a.a -DEL ~~getloc.php -set "PHP_PEAR_INSTALL_DIR=%PHP_PEAR_BIN_DIR%pear" - -REM Make sure there is a pearcmd.php at our disposal - -IF NOT EXIST %PHP_PEAR_INSTALL_DIR%\pearcmd.php ( -IF EXIST %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php COPY %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php -IF EXIST pearcmd.php COPY pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php -IF EXIST %~dp0\scripts\pearcmd.php COPY %~dp0\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php -) -) -GOTO :INSTALLED -) ELSE ( -REM Windows Me/98 cannot succeed, so allow the batch to fail -) -:FAILAUTODETECT -echo WARNING: failed to auto-detect pear information -:INSTALLED - -REM Check Folders and files -IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%" GOTO PEAR_INSTALL_ERROR -IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" GOTO PEAR_INSTALL_ERROR2 -IF NOT EXIST "%PHP_PEAR_BIN_DIR%" GOTO PEAR_BIN_ERROR -IF NOT EXIST "%PHP_PEAR_PHP_BIN%" GOTO PEAR_PHPBIN_ERROR -REM launch pearcmd -GOTO RUN -:PEAR_INSTALL_ERROR -ECHO PHP_PEAR_INSTALL_DIR is not set correctly. -ECHO Please fix it using your environment variable or modify -ECHO the default value in pear.bat -ECHO The current value is: -ECHO %PHP_PEAR_INSTALL_DIR% -GOTO END -:PEAR_INSTALL_ERROR2 -ECHO PHP_PEAR_INSTALL_DIR is not set correctly. -ECHO pearcmd.php could not be found there. -ECHO Please fix it using your environment variable or modify -ECHO the default value in pear.bat -ECHO The current value is: -ECHO %PHP_PEAR_INSTALL_DIR% -GOTO END -:PEAR_BIN_ERROR -ECHO PHP_PEAR_BIN_DIR is not set correctly. -ECHO Please fix it using your environment variable or modify -ECHO the default value in pear.bat -ECHO The current value is: -ECHO %PHP_PEAR_BIN_DIR% -GOTO END -:PEAR_PHPBIN_ERROR -ECHO PHP_PEAR_PHP_BIN is not set correctly. -ECHO Please fix it using your environment variable or modify -ECHO the default value in pear.bat -ECHO The current value is: -ECHO %PHP_PEAR_PHP_BIN% -GOTO END -:RUN -"%PHP_PEAR_PHP_BIN%" -C -d memory_limit="-1" -d safe_mode=0 -d register_argc_argv="On" -d auto_prepend_file="" -d auto_append_file="" -d variables_order=EGPCS -d open_basedir="" -d output_buffering=1 -d include_path="%PHP_PEAR_INSTALL_DIR%" -f "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" -- %1 %2 %3 %4 %5 %6 %7 %8 %9 -:END -@ECHO ONPEAR-1.8.0/scripts/pecl.bat100777 764 764 11003 100777 10434 @ECHO OFF - -REM ---------------------------------------------------------------------- -REM PHP version 5 -REM ---------------------------------------------------------------------- -REM Copyright (c) 1997-2004 The PHP Group -REM ---------------------------------------------------------------------- -REM This source file is subject to version 3.0 of the PHP license, -REM that is bundled with this package in the file LICENSE, and is -REM available at through the world-wide-web at -REM http://www.php.net/license/3_0.txt. -REM If you did not receive a copy of the PHP license and are unable to -REM obtain it through the world-wide-web, please send a note to -REM license@php.net so we can mail you a copy immediately. -REM ---------------------------------------------------------------------- -REM Authors: Alexander Merz (alexmerz@php.net) -REM ---------------------------------------------------------------------- -REM -REM Last updated 02/08/2004 ($Id$ is not replaced if the file is binary) - -REM change this lines to match the paths of your system -REM ------------------- - - -REM Test to see if this is a raw pear.bat (uninstalled version) -SET TMPTMPTMPTMPT=@includ -SET PMTPMTPMT=%TMPTMPTMPTMPT%e_path@ -FOR %%x IN ("@include_path@") DO (if %%x=="%PMTPMTPMT%" GOTO :NOTINSTALLED) - -REM Check PEAR global ENV, set them if they do not exist -IF "%PHP_PEAR_INSTALL_DIR%"=="" SET "PHP_PEAR_INSTALL_DIR=@include_path@" -IF "%PHP_PEAR_BIN_DIR%"=="" SET "PHP_PEAR_BIN_DIR=@bin_dir@" -IF "%PHP_PEAR_PHP_BIN%"=="" SET "PHP_PEAR_PHP_BIN=@php_bin@" -GOTO :INSTALLED - -:NOTINSTALLED -ECHO WARNING: This is a raw, uninstalled pear.bat - -REM Check to see if we can grab the directory of this file (Windows NT+) -IF %~n0 == pear ( -FOR %%x IN (cli\php.exe php.exe) DO (if "%%~$PATH:x" NEQ "" ( -SET "PHP_PEAR_PHP_BIN=%%~$PATH:x" -echo Using PHP Executable "%PHP_PEAR_PHP_BIN%" -"%PHP_PEAR_PHP_BIN%" -v -GOTO :NEXTTEST -)) -GOTO :FAILAUTODETECT -:NEXTTEST -IF "%PHP_PEAR_PHP_BIN%" NEQ "" ( - -REM We can use this PHP to run a temporary php file to get the dirname of pear - -echo ^ > ~~getloc.php -"%PHP_PEAR_PHP_BIN%" ~~getloc.php -set /p PHP_PEAR_BIN_DIR=fakeprompt < ~a.a -DEL ~a.a -DEL ~~getloc.php -set "PHP_PEAR_INSTALL_DIR=%PHP_PEAR_BIN_DIR%pear" - -REM Make sure there is a pearcmd.php at our disposal - -IF NOT EXIST %PHP_PEAR_INSTALL_DIR%\pearcmd.php ( -IF EXIST %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php COPY %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php -IF EXIST pearcmd.php COPY pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php -IF EXIST %~dp0\scripts\pearcmd.php COPY %~dp0\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php -) -) -GOTO :INSTALLED -) ELSE ( -REM Windows Me/98 cannot succeed, so allow the batch to fail -) -:FAILAUTODETECT -echo WARNING: failed to auto-detect pear information -:INSTALLED - -REM Check Folders and files -IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%" GOTO PEAR_INSTALL_ERROR -IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" GOTO PEAR_INSTALL_ERROR2 -IF NOT EXIST "%PHP_PEAR_BIN_DIR%" GOTO PEAR_BIN_ERROR -IF NOT EXIST "%PHP_PEAR_PHP_BIN%" GOTO PEAR_PHPBIN_ERROR -REM launch pearcmd -GOTO RUN -:PEAR_INSTALL_ERROR -ECHO PHP_PEAR_INSTALL_DIR is not set correctly. -ECHO Please fix it using your environment variable or modify -ECHO the default value in pear.bat -ECHO The current value is: -ECHO %PHP_PEAR_INSTALL_DIR% -GOTO END -:PEAR_INSTALL_ERROR2 -ECHO PHP_PEAR_INSTALL_DIR is not set correctly. -ECHO pearcmd.php could not be found there. -ECHO Please fix it using your environment variable or modify -ECHO the default value in pear.bat -ECHO The current value is: -ECHO %PHP_PEAR_INSTALL_DIR% -GOTO END -:PEAR_BIN_ERROR -ECHO PHP_PEAR_BIN_DIR is not set correctly. -ECHO Please fix it using your environment variable or modify -ECHO the default value in pear.bat -ECHO The current value is: -ECHO %PHP_PEAR_BIN_DIR% -GOTO END -:PEAR_PHPBIN_ERROR -ECHO PHP_PEAR_PHP_BIN is not set correctly. -ECHO Please fix it using your environment variable or modify -ECHO the default value in pear.bat -ECHO The current value is: -ECHO %PHP_PEAR_PHP_BIN% -GOTO END -:RUN -"%PHP_PEAR_PHP_BIN%" -C -n -d output_buffering=1 -d safe_mode=0 -d include_path="%PHP_PEAR_INSTALL_DIR%" -d register_argc_argv="On" -d variables_order=EGPCS -f "%PHP_PEAR_INSTALL_DIR%\peclcmd.php" -- %1 %2 %3 %4 %5 %6 %7 %8 %9 -:END -@ECHO ONPEAR-1.8.0/scripts/pear.sh100777 764 764 1362 100777 10273 #!/bin/sh -# first find which PHP binary to use -if test "x$PHP_PEAR_PHP_BIN" != "x"; then - PHP="$PHP_PEAR_PHP_BIN" -else - if test "@php_bin@" = '@'php_bin'@'; then - PHP=php - else - PHP="@php_bin@" - fi -fi + // }}} + // {{{ startFileTransaction() -# then look for the right pear include dir -if test "x$PHP_PEAR_INSTALL_DIR" != "x"; then - INCDIR=$PHP_PEAR_INSTALL_DIR - INCARG="-d include_path=$PHP_PEAR_INSTALL_DIR" -else - if test "@php_dir@" = '@'php_dir'@'; then - INCDIR=`dirname $0` - INCARG="" - else - INCDIR="@php_dir@" - INCARG="-d include_path=@php_dir@" - fi -fi + function startFileTransaction($rollback_in_case = false) + { + if (count($this->file_operations) && $rollback_in_case) { + $this->rollbackFileTransaction(); + } + $this->file_operations = array(); + } -exec $PHP -C -q $INCARG -d output_buffering=1 -d variables_order=EGPCS -d open_basedir="" -d safe_mode=0 -d register_argc_argv="On" -d auto_prepend_file="" -d auto_append_file="" $INCDIR/pearcmd.php "$@" -PEAR-1.8.0/scripts/peardev.sh100777 764 764 1407 100777 10772 #!/bin/sh + // }}} + // {{{ commitFileTransaction() -# first find which PHP binary to use -if test "x$PHP_PEAR_PHP_BIN" != "x"; then - PHP="$PHP_PEAR_PHP_BIN" -else - if test "@php_bin@" = '@'php_bin'@'; then - PHP=php - else - PHP="@php_bin@" - fi -fi + function commitFileTransaction() + { + $n = count($this->file_operations); + $this->log(2, "about to commit $n file operations"); + // {{{ first, check permissions and such manually + $errors = array(); + foreach ($this->file_operations as $tr) { + list($type, $data) = $tr; + switch ($type) { + case 'rename': + if (!file_exists($data[0])) { + $errors[] = "cannot rename file $data[0], doesn't exist"; + } -# then look for the right pear include dir -if test "x$PHP_PEAR_INSTALL_DIR" != "x"; then - INCDIR=$PHP_PEAR_INSTALL_DIR - INCARG="-d include_path=$PHP_PEAR_INSTALL_DIR" -else - if test "@php_dir@" = '@'php_dir'@'; then - INCDIR=`dirname $0` - INCARG="" - else - INCDIR="@php_dir@" - INCARG="-d include_path=@php_dir@" - fi -fi + // check that dest dir. is writable + if (!is_writable(dirname($data[1]))) { + $errors[] = "permission denied ($type): $data[1]"; + } + break; + case 'chmod': + // check that file is writable + if (!is_writable($data[1])) { + $errors[] = "permission denied ($type): $data[1] " . decoct($data[0]); + } + break; + case 'delete': + if (!file_exists($data[0])) { + $this->log(2, "warning: file $data[0] doesn't exist, can't be deleted"); + } + // check that directory is writable + if (file_exists($data[0])) { + if (!is_writable(dirname($data[0]))) { + $errors[] = "permission denied ($type): $data[0]"; + } else { + // make sure the file to be deleted can be opened for writing + $fp = false; + if (!is_dir($data[0]) && + (!is_writable($data[0]) || !($fp = @fopen($data[0], 'a')))) { + $errors[] = "permission denied ($type): $data[0]"; + } elseif ($fp) { + fclose($fp); + } + } + } + break; + } -exec $PHP -d memory_limit="-1" -C -q $INCARG -d output_buffering=1 -d open_basedir="" -d safe_mode=0 -d register_argc_argv="On" -d auto_prepend_file="" -d variables_order=EGPCS -d auto_append_file="" $INCDIR/pearcmd.php "$@" -PEAR-1.8.0/scripts/pecl.sh100777 764 764 1263 100777 10267 #!/bin/sh + } + // }}} + $m = count($errors); + if ($m > 0) { + foreach ($errors as $error) { + if (!isset($this->_options['soft'])) { + $this->log(1, $error); + } + } -# first find which PHP binary to use -if test "x$PHP_PEAR_PHP_BIN" != "x"; then - PHP="$PHP_PEAR_PHP_BIN" -else - if test "@php_bin@" = '@'php_bin'@'; then - PHP=php - else - PHP="@php_bin@" - fi -fi + if (!isset($this->_options['ignore-errors'])) { + return false; + } + } -# then look for the right pear include dir -if test "x$PHP_PEAR_INSTALL_DIR" != "x"; then - INCDIR=$PHP_PEAR_INSTALL_DIR - INCARG="-d include_path=$PHP_PEAR_INSTALL_DIR" -else - if test "@php_dir@" = '@'php_dir'@'; then - INCDIR=`dirname $0` - INCARG="" - else - INCDIR="@php_dir@" - INCARG="-d include_path=@php_dir@" - fi -fi + $this->_dirtree = array(); + // {{{ really commit the transaction + foreach ($this->file_operations as $i => $tr) { + if (!$tr) { + // support removal of non-existing backups + continue; + } -exec $PHP -C -n -q $INCARG -d output_buffering=1 -d variables_order=EGPCS -d safe_mode=0 -d register_argc_argv="On" $INCDIR/peclcmd.php "$@" -PEAR-1.8.0/scripts/pearcmd.php100664 764 764 34617 100664 11153 - * @author Tomas V.V.Cox - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: pearcmd.php,v 1.41 2009/03/04 20:05:56 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - */ + list($type, $data) = $tr; + switch ($type) { + case 'backup': + if (!file_exists($data[0])) { + $this->file_operations[$i] = false; + break; + } -ob_end_clean(); -if (!defined('PEAR_RUNTYPE')) { - // this is defined in peclcmd.php as 'pecl' - define('PEAR_RUNTYPE', 'pear'); -} -define('PEAR_IGNORE_BACKTRACE', 1); -/** - * @nodep Gtk - */ -if ('@include_path@' != '@'.'include_path'.'@') { - ini_set('include_path', '@include_path@'); - $raw = false; -} else { - // this is a raw, uninstalled pear, either a cvs checkout, or php distro - $raw = true; -} -@ini_set('allow_url_fopen', true); -if (!ini_get('safe_mode')) { - @set_time_limit(0); -} -ob_implicit_flush(true); -@ini_set('track_errors', true); -@ini_set('html_errors', false); -@ini_set('magic_quotes_runtime', false); -$_PEAR_PHPDIR = '#$%^&*'; -set_error_handler('error_handler'); + if (!@copy($data[0], $data[0] . '.bak')) { + $this->log(1, 'Could not copy ' . $data[0] . ' to ' . $data[0] . + '.bak ' . $php_errormsg); + return false; + } + $this->log(3, "+ backup $data[0] to $data[0].bak"); + break; + case 'removebackup': + if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { + unlink($data[0] . '.bak'); + $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); + } + break; + case 'rename': + $test = file_exists($data[1]) ? @unlink($data[1]) : null; + if (!$test && file_exists($data[1])) { + if ($data[2]) { + $extra = ', this extension must be installed manually. Rename to "' . + basename($data[1]) . '"'; + } else { + $extra = ''; + } -$pear_package_version = "@pear_version@"; + if (!isset($this->_options['soft'])) { + $this->log(1, 'Could not delete ' . $data[1] . ', cannot rename ' . + $data[0] . $extra); + } -require_once 'PEAR.php'; -require_once 'PEAR/Frontend.php'; -require_once 'PEAR/Config.php'; -require_once 'PEAR/Command.php'; -require_once 'Console/Getopt.php'; + if (!isset($this->_options['ignore-errors'])) { + return false; + } + } + // permissions issues with rename - copy() is far superior + $perms = @fileperms($data[0]); + if (!@copy($data[0], $data[1])) { + $this->log(1, 'Could not rename ' . $data[0] . ' to ' . $data[1] . + ' ' . $php_errormsg); + return false; + } -PEAR_Command::setFrontendType('CLI'); -$all_commands = PEAR_Command::getCommands(); + // copy over permissions, otherwise they are lost + @chmod($data[1], $perms); + @unlink($data[0]); + $this->log(3, "+ mv $data[0] $data[1]"); + break; + case 'chmod': + if (!@chmod($data[1], $data[0])) { + $this->log(1, 'Could not chmod ' . $data[1] . ' to ' . + decoct($data[0]) . ' ' . $php_errormsg); + return false; + } -// remove this next part when we stop supporting that crap-ass PHP 4.2 -if (!isset($_SERVER['argv']) && !isset($argv) && !isset($HTTP_SERVER_VARS['argv'])) { - echo 'ERROR: either use the CLI php executable, or set register_argc_argv=On in php.ini'; - exit(1); -} -$argv = Console_Getopt::readPHPArgv(); -// fix CGI sapi oddity - the -- in pear.bat/pear is not removed -if (php_sapi_name() != 'cli' && isset($argv[1]) && $argv[1] == '--') { - unset($argv[1]); - $argv = array_values($argv); -} -$progname = PEAR_RUNTYPE; -if (in_array('getopt2', get_class_methods('Console_Getopt'))) { - array_shift($argv); - $options = Console_Getopt::getopt2($argv, "c:C:d:D:Gh?sSqu:vV"); -} else { - $options = Console_Getopt::getopt($argv, "c:C:d:D:Gh?sSqu:vV"); -} -if (PEAR::isError($options)) { - usage($options); -} + $octmode = decoct($data[0]); + $this->log(3, "+ chmod $octmode $data[1]"); + break; + case 'delete': + if (file_exists($data[0])) { + if (!@unlink($data[0])) { + $this->log(1, 'Could not delete ' . $data[0] . ' ' . + $php_errormsg); + return false; + } + $this->log(3, "+ rm $data[0]"); + } + break; + case 'rmdir': + if (file_exists($data[0])) { + do { + $testme = opendir($data[0]); + while (false !== ($entry = readdir($testme))) { + if ($entry == '.' || $entry == '..') { + continue; + } + closedir($testme); + break 2; // this directory is not empty and can't be + // deleted + } -$opts = $options[0]; + closedir($testme); + if (!@rmdir($data[0])) { + $this->log(1, 'Could not rmdir ' . $data[0] . ' ' . + $php_errormsg); + return false; + } + $this->log(3, "+ rmdir $data[0]"); + } while (false); + } + break; + case 'installed_as': + $this->pkginfo->setInstalledAs($data[0], $data[1]); + if (!isset($this->_dirtree[dirname($data[1])])) { + $this->_dirtree[dirname($data[1])] = true; + $this->pkginfo->setDirtree(dirname($data[1])); -$fetype = 'CLI'; -if ($progname == 'gpear' || $progname == 'pear-gtk') { - $fetype = 'Gtk'; -} else { - foreach ($opts as $opt) { - if ($opt[0] == 'G') { - $fetype = 'Gtk'; + while(!empty($data[3]) && dirname($data[3]) != $data[3] && + $data[3] != '/' && $data[3] != '\\') { + $this->pkginfo->setDirtree($pp = + $this->_prependPath($data[3], $data[2])); + $this->_dirtree[$pp] = true; + $data[3] = dirname($data[3]); + } + } + break; + } } + // }}} + $this->log(2, "successfully committed $n file operations"); + $this->file_operations = array(); + return true; } -} -//Check if Gtk and PHP >= 5.1.0 -if ($fetype == 'Gtk' && version_compare(phpversion(), '5.1.0', '>=')) { - $fetype = 'Gtk2'; -} -$pear_user_config = ''; -$pear_system_config = ''; -$store_user_config = false; -$store_system_config = false; -$verbose = 1; + // }}} + // {{{ rollbackFileTransaction() -foreach ($opts as $opt) { - switch ($opt[0]) { - case 'c': - $pear_user_config = $opt[1]; - break; - case 'C': - $pear_system_config = $opt[1]; - break; + function rollbackFileTransaction() + { + $n = count($this->file_operations); + $this->log(2, "rolling back $n file operations"); + foreach ($this->file_operations as $tr) { + list($type, $data) = $tr; + switch ($type) { + case 'backup': + if (file_exists($data[0] . '.bak')) { + if (file_exists($data[0] && is_writable($data[0]))) { + unlink($data[0]); + } + @copy($data[0] . '.bak', $data[0]); + $this->log(3, "+ restore $data[0] from $data[0].bak"); + } + break; + case 'removebackup': + if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { + unlink($data[0] . '.bak'); + $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); + } + break; + case 'rename': + @unlink($data[0]); + $this->log(3, "+ rm $data[0]"); + break; + case 'mkdir': + @rmdir($data[0]); + $this->log(3, "+ rmdir $data[0]"); + break; + case 'chmod': + break; + case 'delete': + break; + case 'installed_as': + $this->pkginfo->setInstalledAs($data[0], false); + break; + } + } + $this->pkginfo->resetDirtree(); + $this->file_operations = array(); } -} -PEAR_Command::setFrontendType($fetype); -$ui = &PEAR_Command::getFrontendObject(); -$config = &PEAR_Config::singleton($pear_user_config, $pear_system_config); + // }}} + // {{{ mkDirHier($dir) -if (PEAR::isError($config)) { - $_file = ''; - if ($pear_user_config !== false) { - $_file .= $pear_user_config; - } - if ($pear_system_config !== false) { - $_file .= '/' . $pear_system_config; + function mkDirHier($dir) + { + $this->addFileOperation('mkdir', array($dir)); + return parent::mkDirHier($dir); } - if ($_file == '/') { - $_file = 'The default config file'; + + // }}} + // {{{ download() + + /** + * Download any files and their dependencies, if necessary + * + * @param array a mixed list of package names, local files, or package.xml + * @param PEAR_Config + * @param array options from the command line + * @param array this is the array that will be populated with packages to + * install. Format of each entry: + * + * + * array('pkg' => 'package_name', 'file' => '/path/to/local/file', + * 'info' => array() // parsed package.xml + * ); + * + * @param array this will be populated with any error messages + * @param false private recursion variable + * @param false private recursion variable + * @param false private recursion variable + * @deprecated in favor of PEAR_Downloader + */ + function download($packages, $options, &$config, &$installpackages, + &$errors, $installed = false, $willinstall = false, $state = false) + { + // trickiness: initialize here + parent::PEAR_Downloader($this->ui, $options, $config); + $ret = parent::download($packages); + $errors = $this->getErrorMsgs(); + $installpackages = $this->getDownloadedPackages(); + trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " . + "in favor of PEAR_Downloader class", E_USER_WARNING); + return $ret; } - $config->getMessage(); - $ui->outputData("ERROR: $_file is not a valid config file or is corrupted."); - // We stop, we have no idea where we are :) - exit(1); -} -// this is used in the error handler to retrieve a relative path -$_PEAR_PHPDIR = $config->get('php_dir'); -$ui->setConfig($config); -PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError")); -if (ini_get('safe_mode')) { - $ui->outputData('WARNING: running in safe mode requires that all files created ' . - 'be the same uid as the current script. PHP reports this script is uid: ' . - @getmyuid() . ', and current user is: ' . @get_current_user()); -} + // }}} + // {{{ _parsePackageXml() -$verbose = $config->get("verbose"); -$cmdopts = array(); + function _parsePackageXml(&$descfile, &$tmpdir) + { + if (substr($descfile, -4) == '.xml') { + $tmpdir = false; + } else { + // {{{ Decompress pack in tmp dir ------------------------------------- -if ($raw) { - if (!$config->isDefinedLayer('user') && !$config->isDefinedLayer('system')) { - $found = false; - foreach ($opts as $opt) { - if ($opt[0] == 'd' || $opt[0] == 'D') { - $found = true; // the user knows what they are doing, and are setting config values + // To allow relative package file names + $descfile = realpath($descfile); + + if (PEAR::isError($tmpdir = System::mktemp('-d'))) { + return $tmpdir; } + $this->log(3, '+ tmp dir created at ' . $tmpdir); + // }}} } - if (!$found) { - // no prior runs, try to install PEAR - if (strpos(dirname(__FILE__), 'scripts')) { - $packagexml = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'package2.xml'; - $pearbase = dirname(dirname(__FILE__)); - } else { - $packagexml = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'package2.xml'; - $pearbase = dirname(__FILE__); - } - if (file_exists($packagexml)) { - $options[1] = array( - 'install', - $packagexml - ); - $config->set('php_dir', $pearbase . DIRECTORY_SEPARATOR . 'php'); - $config->set('data_dir', $pearbase . DIRECTORY_SEPARATOR . 'data'); - $config->set('doc_dir', $pearbase . DIRECTORY_SEPARATOR . 'docs'); - $config->set('test_dir', $pearbase . DIRECTORY_SEPARATOR . 'tests'); - $config->set('ext_dir', $pearbase . DIRECTORY_SEPARATOR . 'extensions'); - $config->set('bin_dir', $pearbase); - $config->mergeConfigFile($pearbase . 'pear.ini', false); - $config->store(); - $config->set('auto_discover', 1); + + // Parse xml file ----------------------------------------------- + $pkg = new PEAR_PackageFile($this->config, $this->debug, $tmpdir); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $p = &$pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($p)) { + if (is_array($p->getUserInfo())) { + foreach ($p->getUserInfo() as $err) { + $loglevel = $err['level'] == 'error' ? 0 : 1; + if (!isset($this->_options['soft'])) { + $this->log($loglevel, ucfirst($err['level']) . ': ' . $err['message']); + } + } } + return $this->raiseError('Installation failed: invalid package file'); } - } -} -foreach ($opts as $opt) { - $param = !empty($opt[1]) ? $opt[1] : true; - switch ($opt[0]) { - case 'd': - if ($param === true) { - die('Invalid usage of "-d" option, expected -d config_value=value, ' . - 'received "-d"' . "\n"); - } - $possible = explode('=', $param); - if (count($possible) != 2) { - die('Invalid usage of "-d" option, expected -d config_value=value, received "' . - $param . '"' . "\n"); - } - list($key, $value) = explode('=', $param); - $config->set($key, $value, 'user'); - break; - case 'D': - if ($param === true) { - die('Invalid usage of "-d" option, expected -d config_value=value, ' . - 'received "-d"' . "\n"); - } - $possible = explode('=', $param); - if (count($possible) != 2) { - die('Invalid usage of "-d" option, expected -d config_value=value, received "' . - $param . '"' . "\n"); - } - list($key, $value) = explode('=', $param); - $config->set($key, $value, 'system'); - break; - case 's': - $store_user_config = true; - break; - case 'S': - $store_system_config = true; - break; - case 'u': - $config->remove($param, 'user'); - break; - case 'v': - $config->set('verbose', $config->get('verbose') + 1); - break; - case 'q': - $config->set('verbose', $config->get('verbose') - 1); - break; - case 'V': - usage(null, 'version'); - case 'c': - case 'C': - break; - default: - // all non pear params goes to the command - $cmdopts[$opt[0]] = $param; - break; - } -} - -if ($store_system_config) { - $config->store('system'); -} -if ($store_user_config) { - $config->store('user'); -} - -$command = (isset($options[1][0])) ? $options[1][0] : null; - -if (empty($command) && ($store_user_config || $store_system_config)) { - exit; -} - -if ($fetype == 'Gtk' || $fetype == 'Gtk2') { - if (!$config->validConfiguration()) { - PEAR::raiseError('CRITICAL ERROR: no existing valid configuration files found in files ' . - "'$pear_user_config' or '$pear_system_config', please copy an existing configuration" . - 'file to one of these locations, or use the -c and -s options to create one'); - } - Gtk::main(); -} else do { - if ($command == 'help') { - usage(null, @$options[1][1]); - } - if (!$config->validConfiguration()) { - PEAR::raiseError('CRITICAL ERROR: no existing valid configuration files found in files ' . - "'$pear_user_config' or '$pear_system_config', please copy an existing configuration" . - 'file to one of these locations, or use the -c and -s options to create one'); - } - - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $cmd = PEAR_Command::factory($command, $config); - PEAR::popErrorHandling(); - if (PEAR::isError($cmd)) { - usage(null, @$options[1][0]); + $descfile = $p->getPackageFile(); + return $p; } - $short_args = $long_args = null; - PEAR_Command::getGetoptArgs($command, $short_args, $long_args); - if (in_array('getopt2', get_class_methods('Console_Getopt'))) { - array_shift($options[1]); - $tmp = Console_Getopt::getopt2($options[1], $short_args, $long_args); - } else { - $tmp = Console_Getopt::getopt($options[1], $short_args, $long_args); - } - if (PEAR::isError($tmp)) { - break; - } - list($tmpopt, $params) = $tmp; - $opts = array(); - foreach ($tmpopt as $foo => $tmp2) { - list($opt, $value) = $tmp2; - if ($value === null) { - $value = true; // options without args - } - if (strlen($opt) == 1) { - $cmdoptions = $cmd->getOptions($command); - foreach ($cmdoptions as $o => $d) { - if (isset($d['shortopt']) && $d['shortopt'] == $opt) { - $opts[$o] = $value; - } - } - } else { - if (substr($opt, 0, 2) == '--') { - $opts[substr($opt, 2)] = $value; - } + // }}} + /** + * Set the list of PEAR_Downloader_Package objects to allow more sane + * dependency validation + * @param array + */ + function setDownloadedPackages(&$pkgs) + { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->analyzeDependencies($pkgs); + PEAR::popErrorHandling(); + if (PEAR::isError($err)) { + return $err; } + $this->_downloadedPackages = &$pkgs; } - $ok = $cmd->run($command, $opts, $params); - if ($ok === false) { - PEAR::raiseError("unknown command `$command'"); + + /** + * Set the list of PEAR_Downloader_Package objects to allow more sane + * dependency validation + * @param array + */ + function setUninstallPackages(&$pkgs) + { + $this->_downloadedPackages = &$pkgs; } - if (PEAR::isError($ok)) { - PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError")); - PEAR::raiseError($ok); + + function getInstallPackages() + { + return $this->_downloadedPackages; } -} while (false); -// {{{ usage() + // {{{ install() -function usage($error = null, $helpsubject = null) -{ - global $progname, $all_commands; - $stderr = fopen('php://stderr', 'w'); - if (PEAR::isError($error)) { - fputs($stderr, $error->getMessage() . "\n"); - } elseif ($error !== null) { - fputs($stderr, "$error\n"); - } - if ($helpsubject != null) { - $put = cmdHelp($helpsubject); - } else { - $put = - "Commands:\n"; - $maxlen = max(array_map("strlen", $all_commands)); - $formatstr = "%-{$maxlen}s %s\n"; - ksort($all_commands); - foreach ($all_commands as $cmd => $class) { - $put .= sprintf($formatstr, $cmd, PEAR_Command::getDescription($cmd)); + /** + * Installs the files within the package file specified. + * + * @param string|PEAR_Downloader_Package $pkgfile path to the package file, + * or a pre-initialized packagefile object + * @param array $options + * recognized options: + * - installroot : optional prefix directory for installation + * - force : force installation + * - register-only : update registry but don't install files + * - upgrade : upgrade existing install + * - soft : fail silently + * - nodeps : ignore dependency conflicts/missing dependencies + * - alldeps : install all dependencies + * - onlyreqdeps : install only required dependencies + * + * @return array|PEAR_Error package info if successful + */ + function install($pkgfile, $options = array()) + { + $this->_options = $options; + $this->_registry = &$this->config->getRegistry(); + if (is_object($pkgfile)) { + $dlpkg = &$pkgfile; + $pkg = $pkgfile->getPackageFile(); + $pkgfile = $pkg->getArchiveFile(); + $descfile = $pkg->getPackageFile(); + $tmpdir = dirname($descfile); + } else { + $descfile = $pkgfile; + $tmpdir = ''; + $pkg = $this->_parsePackageXml($descfile, $tmpdir); + if (PEAR::isError($pkg)) { + return $pkg; + } } - $put .= - "Usage: $progname [options] command [command-options] \n". - "Type \"$progname help options\" to list all options.\n". - "Type \"$progname help shortcuts\" to list all command shortcuts.\n". - "Type \"$progname help \" to get the help for the specified command."; - } - fputs($stderr, "$put\n"); - fclose($stderr); - exit(1); -} -function cmdHelp($command) -{ - global $progname, $all_commands, $config; - if ($command == "options") { - return - "Options:\n". - " -v increase verbosity level (default 1)\n". - " -q be quiet, decrease verbosity level\n". - " -c file find user configuration in `file'\n". - " -C file find system configuration in `file'\n". - " -d foo=bar set user config variable `foo' to `bar'\n". - " -D foo=bar set system config variable `foo' to `bar'\n". - " -G start in graphical (Gtk) mode\n". - " -s store user configuration\n". - " -S store system configuration\n". - " -u foo unset `foo' in the user configuration\n". - " -h, -? display help/usage (this message)\n". - " -V version information\n"; - } elseif ($command == "shortcuts") { - $sc = PEAR_Command::getShortcuts(); - $ret = "Shortcuts:\n"; - foreach ($sc as $s => $c) { - $ret .= sprintf(" %-8s %s\n", $s, $c); + if (realpath($descfile) != realpath($pkgfile)) { + $tar = new Archive_Tar($pkgfile); + if (!$tar->extract($tmpdir)) { + return $this->raiseError("unable to unpack $pkgfile"); + } } - return $ret; - } elseif ($command == "version") { - return "PEAR Version: ".$GLOBALS['pear_package_version']. - "\nPHP Version: ".phpversion(). - "\nZend Engine Version: ".zend_version(). - "\nRunning on: ".php_uname(); + $pkgname = $pkg->getName(); + $channel = $pkg->getChannel(); + if (isset($this->_options['packagingroot'])) { + $regdir = $this->_prependPath( + $this->config->get('php_dir', null, 'pear.php.net'), + $this->_options['packagingroot']); - } elseif ($help = PEAR_Command::getHelp($command)) { - if (is_string($help)) { - return "$progname $command [options] $help\n"; + $packrootphp_dir = $this->_prependPath( + $this->config->get('php_dir', null, $channel), + $this->_options['packagingroot']); } - if ($help[1] === null) { - return "$progname $command $help[0]"; + + if (isset($options['installroot'])) { + $this->config->setInstallRoot($options['installroot']); + $this->_registry = &$this->config->getRegistry(); + $installregistry = &$this->_registry; + $this->installroot = ''; // all done automagically now + $php_dir = $this->config->get('php_dir', null, $channel); } else { - return "$progname $command [options] $help[0]\n$help[1]"; + $this->config->setInstallRoot(false); + $this->_registry = &$this->config->getRegistry(); + if (isset($this->_options['packagingroot'])) { + $installregistry = &new PEAR_Registry($regdir); + if (!$installregistry->channelExists($channel, true)) { + // we need to fake a channel-discover of this channel + $chanobj = $this->_registry->getChannel($channel, true); + $installregistry->addChannel($chanobj); + } + $php_dir = $packrootphp_dir; + } else { + $installregistry = &$this->_registry; + $php_dir = $this->config->get('php_dir', null, $channel); + } + $this->installroot = ''; } - } - return "Command '$command' is not valid, try '$progname help'"; -} - -// }}} -function error_handler($errno, $errmsg, $file, $line, $vars) { - if ((defined('E_STRICT') && $errno & E_STRICT) || (defined('E_DEPRECATED') && - $errno & E_DEPRECATED) || !error_reporting()) { - if (defined('E_STRICT') && $errno & E_STRICT) { - return; // E_STRICT - } - if (defined('E_DEPRECATED') && $errno & E_DEPRECATED) { - return; // E_DEPRECATED - } - if ($GLOBALS['config']->get('verbose') < 4) { - return false; // @silenced error, show all if debug is high enough - } - } - $errortype = array ( - E_ERROR => "Error", - E_WARNING => "Warning", - E_PARSE => "Parsing Error", - E_NOTICE => "Notice", - E_CORE_ERROR => "Core Error", - E_CORE_WARNING => "Core Warning", - E_COMPILE_ERROR => "Compile Error", - E_COMPILE_WARNING => "Compile Warning", - E_USER_ERROR => "User Error", - E_USER_WARNING => "User Warning", - E_USER_NOTICE => "User Notice" - ); - $prefix = $errortype[$errno]; - global $_PEAR_PHPDIR; - if (stristr($file, $_PEAR_PHPDIR)) { - $file = substr($file, strlen($_PEAR_PHPDIR) + 1); - } else { - $file = basename($file); - } - print "\n$prefix: $errmsg in $file on line $line\n"; - return false; -} + // {{{ checks to do when not in "force" mode + if (empty($options['force']) && + (file_exists($this->config->get('php_dir')) && + is_dir($this->config->get('php_dir')))) { + $testp = $channel == 'pear.php.net' ? $pkgname : array($channel, $pkgname); + $instfilelist = $pkg->getInstallationFileList(true); + if (PEAR::isError($instfilelist)) { + return $instfilelist; + } + // ensure we have the most accurate registry + $installregistry->flushFileMap(); + $test = $installregistry->checkFileMap($instfilelist, $testp, '1.1'); + if (PEAR::isError($test)) { + return $test; + } -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * indent-tabs-mode: nil - * mode: php - * End: - */ -// vim600:syn=phpPEAR-1.8.0/scripts/peclcmd.php100664 764 764 1640 100664 11115 - * @author Tomas V.V.Cox - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: peclcmd.php,v 1.2 2009/02/25 00:06:23 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - */ + if (sizeof($test)) { + $pkgs = $this->getInstallPackages(); + $found = false; + foreach ($pkgs as $param) { + if ($pkg->isSubpackageOf($param)) { + $found = true; + break; + } + } -/** - * @nodep Gtk - */ -if ('@include_path@' != '@'.'include_path'.'@') { - ini_set('include_path', '@include_path@'); - $raw = false; -} else { - // this is a raw, uninstalled pear, either a cvs checkout, or php distro - $raw = true; -} -define('PEAR_RUNTYPE', 'pecl'); -require_once 'pearcmd.php'; -/* - * Local variables: - * tab-width: 4 - * c-basic-offset: 4 - * indent-tabs-mode: nil - * mode: php - * End: - */ -// vim600:syn=php + if ($found) { + // subpackages can conflict with earlier versions of parent packages + $parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel()); + $tmp = $test; + foreach ($tmp as $file => $info) { + if (is_array($info)) { + if (strtolower($info[1]) == strtolower($param->getPackage()) && + strtolower($info[0]) == strtolower($param->getChannel()) + ) { + if (isset($parentreg['filelist'][$file])) { + unset($parentreg['filelist'][$file]); + } else{ + $pos = strpos($file, '/'); + $basedir = substr($file, 0, $pos); + $file2 = substr($file, $pos + 1); + if (isset($parentreg['filelist'][$file2]['baseinstalldir']) + && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir + ) { + unset($parentreg['filelist'][$file2]); + } + } -?> -PEAR-1.8.0/LICENSE100664 764 764 2705 100664 6316 Copyright (c) 1997-2009, - Stig Bakken , - Gregory Beaver , - Helgi Þormar Þorbjörnsson , - Tomas V.V.Cox , - Martin Jansen . -All rights reserved. + unset($test[$file]); + } + } else { + if (strtolower($param->getChannel()) != 'pear.php.net') { + continue; + } -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: + if (strtolower($info) == strtolower($param->getPackage())) { + if (isset($parentreg['filelist'][$file])) { + unset($parentreg['filelist'][$file]); + } else{ + $pos = strpos($file, '/'); + $basedir = substr($file, 0, $pos); + $file2 = substr($file, $pos + 1); + if (isset($parentreg['filelist'][$file2]['baseinstalldir']) + && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir + ) { + unset($parentreg['filelist'][$file2]); + } + } - * Redistributions of source code must retain the above copyright notice, - this list of conditions and the following disclaimer. - * 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. + unset($test[$file]); + } + } + } -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 OWNER 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. -PEAR-1.8.0/INSTALL100777 764 764 3643 100777 6356 PEAR - The PEAR Installer -========================= -Installing the PEAR Installer. + $pfk = &new PEAR_PackageFile($this->config); + $parentpkg = &$pfk->fromArray($parentreg); + $installregistry->updatePackage2($parentpkg); + } -You should install PEAR on a local development machine first. Installing -PEAR on a remote production machine should only be done after you are -familiar with PEAR and have tested code using PEAR on your development -machine. + if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) { + $tmp = $test; + foreach ($tmp as $file => $info) { + if (is_string($info)) { + // pear.php.net packages are always stored as strings + if (strtolower($info) == strtolower($param->getPackage())) { + // upgrading existing package + unset($test[$file]); + } + } + } + } -There are two methods of installing PEAR - - PEAR bundled in PHP - - go-pear + if (count($test)) { + $msg = "$channel/$pkgname: conflicting files found:\n"; + $longest = max(array_map("strlen", array_keys($test))); + $fmt = "%${longest}s (%s)\n"; + foreach ($test as $file => $info) { + if (!is_array($info)) { + $info = array('pear.php.net', $info); + } + $info = $info[0] . '/' . $info[1]; + $msg .= sprintf($fmt, $file, $info); + } -We will first examine how to install PEAR that is bundled with PHP. + if (!isset($options['ignore-errors'])) { + return $this->raiseError($msg); + } -Microsoft Windows -================= -If you are running PHP 5.2.0 or newer, simply download and -run the windows installer (.msi) and PEAR can be automatically -installed. - -Otherwise, for older PHP versions, download the .zip of windows, -there is a script included with your PHP distribution that is called -"go-pear". You must open a command box in order to run it. Click -"start" then click "Run..." and type "cmd.exe" to open a command box. -Use "cd" to change directory to the location of PHP where you unzipped it, -and run the go-pear command. - -Unix -==== -make sure you have enabled default extensions, and if you want faster -downloads, enable the zlib extension. You must also enable the CLI -SAPI with the --enable-cli extension directive. After this, simply run: - -make install-pear + if (!isset($options['soft'])) { + $this->log(0, "WARNING: $msg"); + } + } + } + } + // }}} -and PEAR will be automatically configured for you. + $this->startFileTransaction(); -go-pear -======= -For users who cannot perform the above steps, or who wish to obtain the -latest PEAR with a slightly higher risk of failure, use go-pear. go-pear -is obtained by downloading http://go-pear.org and saving it as go-pear.php. -After downloading, simply run "php go-pear.php" or open it in a web browser -(windows only) to download and install PEAR. + if (empty($options['upgrade']) && empty($options['soft'])) { + // checks to do only when installing new packages + if ($channel == 'pecl.php.net') { + $test = $installregistry->packageExists($pkgname, $channel); + if (!$test) { + $test = $installregistry->packageExists($pkgname, 'pear.php.net'); + } + } else { + $test = $installregistry->packageExists($pkgname, $channel); + } -You can always ask general installation questions on pear-general@lists.php.net, -a public mailing list devoted to support for PEAR packages and installation- -related issues. + if (empty($options['force']) && $test) { + return $this->raiseError("$channel/$pkgname is already installed"); + } + } else { + $usechannel = $channel; + if ($channel == 'pecl.php.net') { + $test = $installregistry->packageExists($pkgname, $channel); + if (!$test) { + $test = $installregistry->packageExists($pkgname, 'pear.php.net'); + $usechannel = 'pear.php.net'; + } + } else { + $test = $installregistry->packageExists($pkgname, $channel); + } -Happy PHPing, we hope PEAR will be a great tool for your development work! + if ($test) { + $v1 = $installregistry->packageInfo($pkgname, 'version', $usechannel); + $v2 = $pkg->getVersion(); + $cmp = version_compare("$v1", "$v2", 'gt'); + if (empty($options['force']) && !version_compare("$v2", "$v1", 'gt')) { + return $this->raiseError("upgrade to a newer version ($v2 is not newer than $v1)"); + } -$Id: INSTALL,v 1.1 2006/09/22 03:31:36 cellog Exp $PEAR-1.8.0/package.dtd100777 764 764 6477 100777 7425 - - - + $this->configSet('default_channel', $channel); + // {{{ install files - + $ver = $pkg->getPackagexmlVersion(); + if (version_compare($ver, '2.0', '>=')) { + $filelist = $pkg->getInstallationFilelist(); + } else { + $filelist = $pkg->getFileList(); + } - + if (PEAR::isError($filelist)) { + return $filelist; + } - + $p = &$installregistry->getPackage($pkgname, $channel); + $dirtree = (empty($options['register-only']) && $p) ? $p->getDirTree() : false; - + $pkg->resetFilelist(); + $pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(), + 'version', $pkg->getChannel())); + foreach ($filelist as $file => $atts) { + $this->expectError(PEAR_INSTALLER_FAILED); + if ($pkg->getPackagexmlVersion() == '1.0') { + $res = $this->_installFile($file, $atts, $tmp_path, $options); + } else { + $res = $this->_installFile2($pkg, $file, $atts, $tmp_path, $options); + } + $this->popExpect(); - + if (PEAR::isError($res)) { + if (empty($options['ignore-errors'])) { + $this->rollbackFileTransaction(); + if ($res->getMessage() == "file does not exist") { + $this->raiseError("file $file in package.xml does not exist"); + } - + return $this->raiseError($res); + } - + if (!isset($options['soft'])) { + $this->log(0, "Warning: " . $res->getMessage()); + } + } - + $real = isset($atts['attribs']) ? $atts['attribs'] : $atts; + if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') { + // Register files that were installed + $pkg->installedFile($file, $atts); + } + } + // }}} - + // {{{ compile and install source files + if ($this->source_files > 0 && empty($options['nobuild'])) { + if (PEAR::isError($err = + $this->_compileSourceFiles($savechannel, $pkg))) { + return $err; + } + } + // }}} - + if (isset($backedup)) { + $this->_removeBackups($backedup); + } - + if (!$this->commitFileTransaction()) { + $this->rollbackFileTransaction(); + $this->configSet('default_channel', $savechannel); + return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED); + } + // }}} - + $ret = false; + $installphase = 'install'; + $oldversion = false; + // {{{ Register that the package is installed ----------------------- + if (empty($options['upgrade'])) { + // if 'force' is used, replace the info in registry + $usechannel = $channel; + if ($channel == 'pecl.php.net') { + $test = $installregistry->packageExists($pkgname, $channel); + if (!$test) { + $test = $installregistry->packageExists($pkgname, 'pear.php.net'); + $usechannel = 'pear.php.net'; + } + } else { + $test = $installregistry->packageExists($pkgname, $channel); + } - + if (!empty($options['force']) && $test) { + $oldversion = $installregistry->packageInfo($pkgname, 'version', $usechannel); + $installregistry->deletePackage($pkgname, $usechannel); + } + $ret = $installregistry->addPackage2($pkg); + } else { + if ($dirtree) { + $this->startFileTransaction(); + // attempt to delete empty directories + uksort($dirtree, array($this, '_sortDirs')); + foreach($dirtree as $dir => $notused) { + $this->addFileOperation('rmdir', array($dir)); + } + $this->commitFileTransaction(); + } - + $usechannel = $channel; + if ($channel == 'pecl.php.net') { + $test = $installregistry->packageExists($pkgname, $channel); + if (!$test) { + $test = $installregistry->packageExists($pkgname, 'pear.php.net'); + $usechannel = 'pear.php.net'; + } + } else { + $test = $installregistry->packageExists($pkgname, $channel); + } - + // new: upgrade installs a package if it isn't installed + if (!$test) { + $ret = $installregistry->addPackage2($pkg); + } else { + if ($usechannel != $channel) { + $installregistry->deletePackage($pkgname, $usechannel); + $ret = $installregistry->addPackage2($pkg); + } else { + $ret = $installregistry->updatePackage2($pkg); + } + $installphase = 'upgrade'; + } + } - + if (!$ret) { + $this->configSet('default_channel', $savechannel); + return $this->raiseError("Adding package $channel/$pkgname to registry failed"); + } + // }}} - + $this->configSet('default_channel', $savechannel); + if (class_exists('PEAR_Task_Common')) { // this is auto-included if any tasks exist + if (PEAR_Task_Common::hasPostinstallTasks()) { + PEAR_Task_Common::runPostinstallTasks($installphase); + } + } - - + return $pkg->toArray(true); + } - + // }}} - - + // {{{ _compileSourceFiles() + /** + * @param string + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + */ + function _compileSourceFiles($savechannel, &$filelist) + { + require_once 'PEAR/Builder.php'; + $this->log(1, "$this->source_files source files, building"); + $bob = &new PEAR_Builder($this->ui); + $bob->debug = $this->debug; + $built = $bob->build($filelist, array(&$this, '_buildCallback')); + if (PEAR::isError($built)) { + $this->rollbackFileTransaction(); + $this->configSet('default_channel', $savechannel); + return $built; + } - - - + $this->log(1, "\nBuild process completed successfully"); + foreach ($built as $ext) { + $bn = basename($ext['file']); + list($_ext_name, $_ext_suff) = explode('.', $bn); + if ($_ext_suff == '.so' || $_ext_suff == '.dll') { + if (extension_loaded($_ext_name)) { + $this->raiseError("Extension '$_ext_name' already loaded. " . + 'Please unload it in your php.ini file ' . + 'prior to install or upgrade'); + } + $role = 'ext'; + } else { + $role = 'src'; + } - - + $dest = $ext['dest']; + $packagingroot = ''; + if (isset($this->_options['packagingroot'])) { + $packagingroot = $this->_options['packagingroot']; + } - - + $copyto = $this->_prependPath($dest, $packagingroot); + $extra = $copyto != $dest ? " as '$copyto'" : ''; + $this->log(1, "Installing '$dest'$extra"); - - + $copydir = dirname($copyto); + // pretty much nothing happens if we are only registering the install + if (empty($this->_options['register-only'])) { + if (!file_exists($copydir) || !is_dir($copydir)) { + if (!$this->mkDirHier($copydir)) { + return $this->raiseError("failed to mkdir $copydir", + PEAR_INSTALLER_FAILED); + } + $this->log(3, "+ mkdir $copydir"); + } -PEAR-1.8.0/PEAR.php100664 764 764 105707 100664 6617 - * @author Stig Bakken - * @author Tomas V.V.Cox - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PEAR.php,v 1.111 2009/04/08 23:32:04 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ + if (!@copy($ext['file'], $copyto)) { + return $this->raiseError("failed to write $copyto ($php_errormsg)", PEAR_INSTALLER_FAILED); + } -/**#@+ - * ERROR constants - */ -define('PEAR_ERROR_RETURN', 1); -define('PEAR_ERROR_PRINT', 2); -define('PEAR_ERROR_TRIGGER', 4); -define('PEAR_ERROR_DIE', 8); -define('PEAR_ERROR_CALLBACK', 16); -/** - * WARNING: obsolete - * @deprecated - */ -define('PEAR_ERROR_EXCEPTION', 32); -/**#@-*/ -define('PEAR_ZE2', (function_exists('version_compare') && - version_compare(zend_version(), "2-dev", "ge"))); + $this->log(3, "+ cp $ext[file] $copyto"); + $this->addFileOperation('rename', array($ext['file'], $copyto)); + if (!OS_WINDOWS) { + $mode = 0666 & ~(int)octdec($this->config->get('umask')); + $this->addFileOperation('chmod', array($mode, $copyto)); + if (!@chmod($copyto, $mode)) { + $this->log(0, "failed to change mode of $copyto ($php_errormsg)"); + } + } + } -if (substr(PHP_OS, 0, 3) == 'WIN') { - define('OS_WINDOWS', true); - define('OS_UNIX', false); - define('PEAR_OS', 'Windows'); -} else { - define('OS_WINDOWS', false); - define('OS_UNIX', true); - define('PEAR_OS', 'Unix'); // blatant assumption -} -$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; -$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; -$GLOBALS['_PEAR_destructor_object_list'] = array(); -$GLOBALS['_PEAR_shutdown_funcs'] = array(); -$GLOBALS['_PEAR_error_handler_stack'] = array(); + $data = array( + 'role' => $role, + 'name' => $bn, + 'installed_as' => $dest, + 'php_api' => $ext['php_api'], + 'zend_mod_api' => $ext['zend_mod_api'], + 'zend_ext_api' => $ext['zend_ext_api'], + ); -@ini_set('track_errors', true); + if ($filelist->getPackageXmlVersion() == '1.0') { + $filelist->installedFile($bn, $data); + } else { + $filelist->installedFile($bn, array('attribs' => $data)); + } + } + } -/** - * Base class for other PEAR classes. Provides rudimentary - * emulation of destructors. - * - * If you want a destructor in your class, inherit PEAR and make a - * destructor method called _yourclassname (same name as the - * constructor, but with a "_" prefix). Also, in your constructor you - * have to call the PEAR constructor: $this->PEAR();. - * The destructor method will be called without parameters. Note that - * at in some SAPI implementations (such as Apache), any output during - * the request shutdown (in which destructors are called) seems to be - * discarded. If you need to get any debug information from your - * destructor, use error_log(), syslog() or something similar. - * - * IMPORTANT! To use the emulated destructors you need to create the - * objects by reference: $obj =& new PEAR_child; - * - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Tomas V.V. Cox - * @author Greg Beaver - * @copyright 1997-2006 The PHP Group - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @see PEAR_Error - * @since Class available since PHP 4.0.2 - * @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear - */ -class PEAR -{ - // {{{ properties + // }}} + function &getUninstallPackages() + { + return $this->_downloadedPackages; + } + // {{{ uninstall() /** - * Whether to enable internal debug messages. + * Uninstall a package * - * @var bool - * @access private - */ - var $_debug = false; - - /** - * Default error mode for this object. + * This method removes all files installed by the application, and then + * removes any empty directories. + * @param string package name + * @param array Command-line options. Possibilities include: * - * @var int - * @access private + * - installroot: base installation dir, if not the default + * - register-only : update registry but don't remove files + * - nodeps: do not process dependencies of other packages to ensure + * uninstallation does not break things */ - var $_default_error_mode = null; + function uninstall($package, $options = array()) + { + $installRoot = isset($options['installroot']) ? $options['installroot'] : ''; + $this->config->setInstallRoot($installRoot); - /** - * Default error options used for this object when error mode - * is PEAR_ERROR_TRIGGER. - * - * @var int - * @access private - */ - var $_default_error_options = null; + $this->installroot = ''; + $this->_registry = &$this->config->getRegistry(); + if (is_object($package)) { + $channel = $package->getChannel(); + $pkg = $package; + $package = $pkg->getPackage(); + } else { + $pkg = false; + $info = $this->_registry->parsePackageName($package, + $this->config->get('default_channel')); + $channel = $info['channel']; + $package = $info['package']; + } - /** - * Default error handler (callback) for this object, if error mode is - * PEAR_ERROR_CALLBACK. - * - * @var string - * @access private - */ - var $_default_error_handler = ''; + $savechannel = $this->config->get('default_channel'); + $this->configSet('default_channel', $channel); + if (!is_object($pkg)) { + $pkg = $this->_registry->getPackage($package, $channel); + } - /** - * Which class to use for error objects. - * - * @var string - * @access private - */ - var $_error_class = 'PEAR_Error'; + if (!$pkg) { + $this->configSet('default_channel', $savechannel); + return $this->raiseError($this->_registry->parsedPackageNameToString( + array( + 'channel' => $channel, + 'package' => $package + ), true) . ' not installed'); + } - /** - * An array of expected errors. - * - * @var array - * @access private - */ - var $_expected_errors = array(); + if ($pkg->getInstalledBinary()) { + // this is just an alias for a binary package + return $this->_registry->deletePackage($package, $channel); + } - // }}} + $filelist = $pkg->getFilelist(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (!class_exists('PEAR_Dependency2')) { + require_once 'PEAR/Dependency2.php'; + } - // {{{ constructor + $depchecker = &new PEAR_Dependency2($this->config, $options, + array('channel' => $channel, 'package' => $package), + PEAR_VALIDATE_UNINSTALLING); + $e = $depchecker->validatePackageUninstall($this); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($e)) { + if (!isset($options['ignore-errors'])) { + return $this->raiseError($e); + } - /** - * Constructor. Registers this object in - * $_PEAR_destructor_object_list for destructor emulation if a - * destructor object exists. - * - * @param string $error_class (optional) which class to use for - * error objects, defaults to PEAR_Error. - * @access public - * @return void - */ - function PEAR($error_class = null) - { - $classname = strtolower(get_class($this)); - if ($this->_debug) { - print "PEAR constructor called, class=$classname\n"; - } - if ($error_class !== null) { - $this->_error_class = $error_class; + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: ' . $e->getMessage()); + } + } elseif (is_array($e)) { + if (!isset($options['soft'])) { + $this->log(0, $e[0]); + } } - while ($classname && strcasecmp($classname, "pear")) { - $destructor = "_$classname"; - if (method_exists($this, $destructor)) { - global $_PEAR_destructor_object_list; - $_PEAR_destructor_object_list[] = &$this; - if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { - register_shutdown_function("_PEAR_call_destructors"); - $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; + + $this->pkginfo = &$pkg; + // pretty much nothing happens if we are only registering the uninstall + if (empty($options['register-only'])) { + // {{{ Delete the files + $this->startFileTransaction(); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + if (PEAR::isError($err = $this->_deletePackageFiles($package, $channel))) { + PEAR::popErrorHandling(); + $this->rollbackFileTransaction(); + $this->configSet('default_channel', $savechannel); + if (!isset($options['ignore-errors'])) { + return $this->raiseError($err); + } + + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: ' . $err->getMessage()); } - break; } else { - $classname = get_parent_class($classname); + PEAR::popErrorHandling(); + } + + if (!$this->commitFileTransaction()) { + $this->rollbackFileTransaction(); + if (!isset($options['ignore-errors'])) { + return $this->raiseError("uninstall failed"); + } + + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: uninstall failed'); + } + } else { + $this->startFileTransaction(); + $dirtree = $pkg->getDirTree(); + if ($dirtree === false) { + $this->configSet('default_channel', $savechannel); + return $this->_registry->deletePackage($package, $channel); + } + + // attempt to delete empty directories + uksort($dirtree, array($this, '_sortDirs')); + foreach($dirtree as $dir => $notused) { + $this->addFileOperation('rmdir', array($dir)); + } + + if (!$this->commitFileTransaction()) { + $this->rollbackFileTransaction(); + if (!isset($options['ignore-errors'])) { + return $this->raiseError("uninstall failed"); + } + + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: uninstall failed'); + } + } } + // }}} } - } - // }}} - // {{{ destructor + $this->configSet('default_channel', $savechannel); + // Register that the package is no longer installed + return $this->_registry->deletePackage($package, $channel); + } /** - * Destructor (the emulated type of...). Does nothing right now, - * but is included for forward compatibility, so subclass - * destructors should always call it. - * - * See the note in the class desciption about output from - * destructors. + * Sort a list of arrays of array(downloaded packagefilename) by dependency. * - * @access public - * @return void + * It also removes duplicate dependencies + * @param array an array of PEAR_PackageFile_v[1/2] objects + * @return array|PEAR_Error array of array(packagefilename, package.xml contents) */ - function _PEAR() { - if ($this->_debug) { - printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); + function sortPackagesForUninstall(&$packages) + { + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->config); + if (PEAR::isError($this->_dependencyDB)) { + return $this->_dependencyDB; } + usort($packages, array(&$this, '_sortUninstall')); } - // }}} - // {{{ getStaticProperty() - - /** - * If you have a class that's mostly/entirely static, and you need static - * properties, you can use this method to simulate them. Eg. in your method(s) - * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); - * You MUST use a reference, or they will not persist! - * - * @access public - * @param string $class The calling classname, to prevent clashes - * @param string $var The variable to retrieve. - * @return mixed A reference to the variable. If not set it will be - * auto initialised to NULL. - */ - function &getStaticProperty($class, $var) + function _sortUninstall($a, $b) { - static $properties; - if (!isset($properties[$class])) { - $properties[$class] = array(); + if (!$a->getDeps() && !$b->getDeps()) { + return 0; // neither package has dependencies, order is insignificant } - - if (!array_key_exists($var, $properties[$class])) { - $properties[$class][$var] = null; + if ($a->getDeps() && !$b->getDeps()) { + return -1; // $a must be installed after $b because $a has dependencies + } + if (!$a->getDeps() && $b->getDeps()) { + return 1; // $b must be installed after $a because $b has dependencies + } + // both packages have dependencies + if ($this->_dependencyDB->dependsOn($a, $b)) { + return -1; } + if ($this->_dependencyDB->dependsOn($b, $a)) { + return 1; + } + return 0; + } - return $properties[$class][$var]; + // }}} + // {{{ _sortDirs() + function _sortDirs($a, $b) + { + if (strnatcmp($a, $b) == -1) return 1; + if (strnatcmp($a, $b) == 1) return -1; + return 0; } // }}} - // {{{ registerShutdownFunc() - /** - * Use this function to register a shutdown method for static - * classes. - * - * @access public - * @param mixed $func The function name (or array of class/method) to call - * @param mixed $args The arguments to pass to the function - * @return void - */ - function registerShutdownFunc($func, $args = array()) + // {{{ _buildCallback() + + function _buildCallback($what, $data) { - // if we are called statically, there is a potential - // that no shutdown func is registered. Bug #6445 - if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { - register_shutdown_function("_PEAR_call_destructors"); - $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; + if (($what == 'cmdoutput' && $this->debug > 1) || + ($what == 'output' && $this->debug > 0)) { + $this->ui->outputData(rtrim($data), 'build'); } - $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); } // }}} - // {{{ isError() +}PEAR-1.9.0/PEAR/PackageFile.php100664 764 764 37466 100664 10741 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: PackageFile.php 286670 2009-08-02 14:16:06Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * needed for PEAR_VALIDATE_* constants + */ +require_once 'PEAR/Validate.php'; +/** + * Error code if the package.xml tag does not contain a valid version + */ +define('PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION', 1); +/** + * Error code if the package.xml tag version is not supported (version 1.0 and 1.1 are the only supported versions, + * currently + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2); +/** + * Abstraction for the package.xml package description file + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile +{ + /** + * @var PEAR_Config + */ + var $_config; + var $_debug; + /** + * Temp directory for uncompressing tgz files. + * @var string|false + */ + var $_tmpdir; + var $_logger = false; + /** + * @var boolean + */ + var $_rawReturn = false; /** - * Tell whether a value is a PEAR error. * - * @param mixed $data the value to test - * @param int $code if $data is an error object, return true - * only if $code is a string and - * $obj->getMessage() == $code or - * $code is an integer and $obj->getCode() == $code - * @access public - * @return bool true if parameter is an error + * @param PEAR_Config $config + * @param ? $debug + * @param string @tmpdir Optional temporary directory for uncompressing + * files */ - function isError($data, $code = null) + function PEAR_PackageFile(&$config, $debug = false, $tmpdir = false) { - if (!is_a($data, 'PEAR_Error')) { - return false; - } - - if (is_null($code)) { - return true; - } elseif (is_string($code)) { - return $data->getMessage() == $code; - } - - return $data->getCode() == $code; + $this->_config = $config; + $this->_debug = $debug; + $this->_tmpdir = $tmpdir; } - // }}} - // {{{ setErrorHandling() - /** - * Sets how errors generated by this object should be handled. - * Can be invoked both in objects and statically. If called - * statically, setErrorHandling sets the default behaviour for all - * PEAR objects. If called in an object, setErrorHandling sets - * the default behaviour for that object. - * - * @param int $mode - * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, - * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, - * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. - * - * @param mixed $options - * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one - * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). - * - * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected - * to be the callback function or method. A callback - * function is a string with the name of the function, a - * callback method is an array of two elements: the element - * at index 0 is the object, and the element at index 1 is - * the name of the method to call in the object. - * - * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is - * a printf format string used when printing the error - * message. - * - * @access public - * @return void - * @see PEAR_ERROR_RETURN - * @see PEAR_ERROR_PRINT - * @see PEAR_ERROR_TRIGGER - * @see PEAR_ERROR_DIE - * @see PEAR_ERROR_CALLBACK - * @see PEAR_ERROR_EXCEPTION + * Turn off validation - return a parsed package.xml without checking it * - * @since PHP 4.0.5 + * This is used by the package-validate command */ - - function setErrorHandling($mode = null, $options = null) + function rawReturn() { - if (isset($this) && is_a($this, 'PEAR')) { - $setmode = &$this->_default_error_mode; - $setoptions = &$this->_default_error_options; - } else { - $setmode = &$GLOBALS['_PEAR_default_error_mode']; - $setoptions = &$GLOBALS['_PEAR_default_error_options']; - } - - switch ($mode) { - case PEAR_ERROR_EXCEPTION: - case PEAR_ERROR_RETURN: - case PEAR_ERROR_PRINT: - case PEAR_ERROR_TRIGGER: - case PEAR_ERROR_DIE: - case null: - $setmode = $mode; - $setoptions = $options; - break; - - case PEAR_ERROR_CALLBACK: - $setmode = $mode; - // class/object method callback - if (is_callable($options)) { - $setoptions = $options; - } else { - trigger_error("invalid error callback", E_USER_WARNING); - } - break; - - default: - trigger_error("invalid error mode", E_USER_WARNING); - break; - } + $this->_rawReturn = true; } - // }}} - // {{{ expectError() + function setLogger(&$l) + { + $this->_logger = &$l; + } /** - * This method is used to tell which errors you expect to get. - * Expected errors are always returned with error mode - * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, - * and this method pushes a new element onto it. The list of - * expected errors are in effect until they are popped off the - * stack with the popExpect() method. - * - * Note that this method can not be called statically - * - * @param mixed $code a single error code or an array of error codes to expect - * - * @return int the new depth of the "expected errors" stack - * @access public + * Create a PEAR_PackageFile_Parser_v* of a given version. + * @param int $version + * @return PEAR_PackageFile_Parser_v1|PEAR_PackageFile_Parser_v1 */ - function expectError($code = '*') + function &parserFactory($version) { - if (is_array($code)) { - array_push($this->_expected_errors, $code); - } else { - array_push($this->_expected_errors, array($code)); + if (!in_array($version{0}, array('1', '2'))) { + $a = false; + return $a; } - return sizeof($this->_expected_errors); - } - // }}} - // {{{ popExpect() + include_once 'PEAR/PackageFile/Parser/v' . $version{0} . '.php'; + $version = $version{0}; + $class = "PEAR_PackageFile_Parser_v$version"; + $a = new $class; + return $a; + } /** - * This method pops one element off the expected error codes - * stack. - * - * @return array the list of error codes that were popped + * For simpler unit-testing + * @return string */ - function popExpect() + function getClassPrefix() { - return array_pop($this->_expected_errors); + return 'PEAR_PackageFile_v'; } - // }}} - // {{{ _checkDelExpect() - /** - * This method checks unsets an error code if available - * - * @param mixed error code - * @return bool true if the error code was unset, false otherwise - * @access private - * @since PHP 4.3.0 + * Create a PEAR_PackageFile_v* of a given version. + * @param int $version + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v1 */ - function _checkDelExpect($error_code) + function &factory($version) { - $deleted = false; - - foreach ($this->_expected_errors AS $key => $error_array) { - if (in_array($error_code, $error_array)) { - unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); - $deleted = true; - } - - // clean up empty arrays - if (0 == count($this->_expected_errors[$key])) { - unset($this->_expected_errors[$key]); - } + if (!in_array($version{0}, array('1', '2'))) { + $a = false; + return $a; } - return $deleted; - } - // }}} - // {{{ delExpect() + include_once 'PEAR/PackageFile/v' . $version{0} . '.php'; + $version = $version{0}; + $class = $this->getClassPrefix() . $version; + $a = new $class; + return $a; + } /** - * This method deletes all occurences of the specified element from - * the expected error codes stack. + * Create a PEAR_PackageFile_v* from its toArray() method * - * @param mixed $error_code error code that should be deleted - * @return mixed list of error codes that were deleted or error - * @access public - * @since PHP 4.3.0 + * WARNING: no validation is performed, the array is assumed to be valid, + * always parse from xml if you want validation. + * @param array $arr + * @return PEAR_PackageFileManager_v1|PEAR_PackageFileManager_v2 + * @uses factory() to construct the returned object. */ - function delExpect($error_code) + function &fromArray($arr) { - $deleted = false; - if ((is_array($error_code) && (0 != count($error_code)))) { - // $error_code is a non-empty array here; - // we walk through it trying to unset all - // values - foreach($error_code as $key => $error) { - if ($this->_checkDelExpect($error)) { - $deleted = true; - } else { - $deleted = false; - } - } - return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME - } elseif (!empty($error_code)) { - // $error_code comes alone, trying to unset it - if ($this->_checkDelExpect($error_code)) { - return true; - } else { - return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + if (isset($arr['xsdversion'])) { + $obj = &$this->factory($arr['xsdversion']); + if ($this->_logger) { + $obj->setLogger($this->_logger); } + + $obj->setConfig($this->_config); + $obj->fromArray($arr); + return $obj; } - // $error_code is empty - return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME - } + if (isset($arr['package']['attribs']['version'])) { + $obj = &$this->factory($arr['package']['attribs']['version']); + } else { + $obj = &$this->factory('1.0'); + } - // }}} - // {{{ raiseError() + if ($this->_logger) { + $obj->setLogger($this->_logger); + } + + $obj->setConfig($this->_config); + $obj->fromArray($arr); + return $obj; + } /** - * This method is a wrapper that returns an instance of the - * configured error class with this object's default error - * handling applied. If the $mode and $options parameters are not - * specified, the object's defaults are used. - * - * @param mixed $message a text error message or a PEAR error object - * - * @param int $code a numeric error code (it is up to your class - * to define these if you want to use codes) - * - * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, - * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, - * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. - * - * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter - * specifies the PHP-internal error level (one of - * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). - * If $mode is PEAR_ERROR_CALLBACK, this - * parameter specifies the callback function or - * method. In other error modes this parameter - * is ignored. - * - * @param string $userinfo If you need to pass along for example debug - * information, this parameter is meant for that. - * - * @param string $error_class The returned error object will be - * instantiated from this class, if specified. - * - * @param bool $skipmsg If true, raiseError will only pass error codes, - * the error message parameter will be dropped. - * - * @access public - * @return object a PEAR error object - * @see PEAR::setErrorHandling - * @since PHP 4.0.5 + * Create a PEAR_PackageFile_v* from an XML string. + * @access public + * @param string $data contents of package.xml file + * @param int $state package state (one of PEAR_VALIDATE_* constants) + * @param string $file full path to the package.xml file (and the files + * it references) + * @param string $archive optional name of the archive that the XML was + * extracted from, if any + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @uses parserFactory() to construct a parser to load the package. */ - function &raiseError($message = null, - $code = null, - $mode = null, - $options = null, - $userinfo = null, - $error_class = null, - $skipmsg = false) + function &fromXmlString($data, $state, $file, $archive = false) { - // The error is yet a PEAR error object - if (is_object($message)) { - $code = $message->getCode(); - $userinfo = $message->getUserInfo(); - $error_class = $message->getType(); - $message->error_message_prefix = ''; - $message = $message->getMessage(); - } + if (preg_match('/]+version="([0-9]+\.[0-9]+)"/', $data, $packageversion)) { + if (!in_array($packageversion[1], array('1.0', '2.0', '2.1'))) { + return PEAR::raiseError('package.xml version "' . $packageversion[1] . + '" is not supported, only 1.0, 2.0, and 2.1 are supported.'); + } - if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) { - if ($exp[0] == "*" || - (is_int(reset($exp)) && in_array($code, $exp)) || - (is_string(reset($exp)) && in_array($message, $exp))) { - $mode = PEAR_ERROR_RETURN; + $object = &$this->parserFactory($packageversion[1]); + if ($this->_logger) { + $object->setLogger($this->_logger); } - } - // No mode given, try global ones - if ($mode === null) { - // Class error handler - if (isset($this) && isset($this->_default_error_mode)) { - $mode = $this->_default_error_mode; - $options = $this->_default_error_options; - // Global error handler - } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { - $mode = $GLOBALS['_PEAR_default_error_mode']; - $options = $GLOBALS['_PEAR_default_error_options']; + $object->setConfig($this->_config); + $pf = $object->parse($data, $file, $archive); + if (PEAR::isError($pf)) { + return $pf; } - } - if ($error_class !== null) { - $ec = $error_class; - } elseif (isset($this) && isset($this->_error_class)) { - $ec = $this->_error_class; - } else { - $ec = 'PEAR_Error'; - } + if ($this->_rawReturn) { + return $pf; + } - if (intval(PHP_VERSION) < 5) { - // little non-eval hack to fix bug #12147 - include 'PEAR/FixPHP5PEARWarnings.php'; - return $a; - } + if (!$pf->validate($state)) {; + if ($this->_config->get('verbose') > 0 + && $this->_logger && $pf->getValidationWarnings(false) + ) { + foreach ($pf->getValidationWarnings(false) as $warning) { + $this->_logger->log(0, 'ERROR: ' . $warning['message']); + } + } - if ($skipmsg) { - $a = new $ec($code, $mode, $options, $userinfo); + $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', + 2, null, null, $pf->getValidationWarnings()); + return $a; + } + + if ($this->_logger && $pf->getValidationWarnings(false)) { + foreach ($pf->getValidationWarnings() as $warning) { + $this->_logger->log(0, 'WARNING: ' . $warning['message']); + } + } + + if (method_exists($pf, 'flattenFilelist')) { + $pf->flattenFilelist(); // for v2 + } + + return $pf; + } elseif (preg_match('/]+version="([^"]+)"/', $data, $packageversion)) { + $a = PEAR::raiseError('package.xml file "' . $file . + '" has unsupported package.xml version "' . $packageversion[1] . '"'); + return $a; } else { - $a = new $ec($message, $code, $mode, $options, $userinfo); - } + if (!class_exists('PEAR_ErrorStack')) { + require_once 'PEAR/ErrorStack.php'; + } - return $a; - } + PEAR_ErrorStack::staticPush('PEAR_PackageFile', + PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION, + 'warning', array('xml' => $data), 'package.xml "' . $file . + '" has no package.xml version'); + $object = &$this->parserFactory('1.0'); + $object->setConfig($this->_config); + $pf = $object->parse($data, $file, $archive); + if (PEAR::isError($pf)) { + return $pf; + } - // }}} - // {{{ throwError() + if ($this->_rawReturn) { + return $pf; + } + + if (!$pf->validate($state)) { + $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', + 2, null, null, $pf->getValidationWarnings()); + return $a; + } + + if ($this->_logger && $pf->getValidationWarnings(false)) { + foreach ($pf->getValidationWarnings() as $warning) { + $this->_logger->log(0, 'WARNING: ' . $warning['message']); + } + } + + if (method_exists($pf, 'flattenFilelist')) { + $pf->flattenFilelist(); // for v2 + } + + return $pf; + } + } /** - * Simpler form of raiseError with fewer options. In most cases - * message, code and userinfo are enough. - * - * @param string $message + * Register a temporary file or directory. When the destructor is + * executed, all registered temporary files and directories are + * removed. * + * @param string $file name of file or directory + * @return void */ - function &throwError($message = null, - $code = null, - $userinfo = null) + function addTempFile($file) { - if (isset($this) && is_a($this, 'PEAR')) { - $a = &$this->raiseError($message, $code, null, null, $userinfo); - return $a; - } - - $a = &PEAR::raiseError($message, $code, null, null, $userinfo); - return $a; + $GLOBALS['_PEAR_Common_tempfiles'][] = $file; } - // }}} - function staticPushErrorHandling($mode, $options = null) + /** + * Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file. + * @access public + * @param string contents of package.xml file + * @param int package state (one of PEAR_VALIDATE_* constants) + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @using Archive_Tar to extract the files + * @using fromPackageFile() to load the package after the package.xml + * file is extracted. + */ + function &fromTgzFile($file, $state) { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - $def_mode = &$GLOBALS['_PEAR_default_error_mode']; - $def_options = &$GLOBALS['_PEAR_default_error_options']; - $stack[] = array($def_mode, $def_options); - switch ($mode) { - case PEAR_ERROR_EXCEPTION: - case PEAR_ERROR_RETURN: - case PEAR_ERROR_PRINT: - case PEAR_ERROR_TRIGGER: - case PEAR_ERROR_DIE: - case null: - $def_mode = $mode; - $def_options = $options; - break; + if (!class_exists('Archive_Tar')) { + require_once 'Archive/Tar.php'; + } - case PEAR_ERROR_CALLBACK: - $def_mode = $mode; - // class/object method callback - if (is_callable($options)) { - $def_options = $options; - } else { - trigger_error("invalid error callback", E_USER_WARNING); - } - break; + $tar = new Archive_Tar($file); + if ($this->_debug <= 1) { + $tar->pushErrorHandling(PEAR_ERROR_RETURN); + } - default: - trigger_error("invalid error mode", E_USER_WARNING); - break; + $content = $tar->listContent(); + if ($this->_debug <= 1) { + $tar->popErrorHandling(); } - $stack[] = array($mode, $options); - return true; - } - function staticPopErrorHandling() - { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - $setmode = &$GLOBALS['_PEAR_default_error_mode']; - $setoptions = &$GLOBALS['_PEAR_default_error_options']; - array_pop($stack); - list($mode, $options) = $stack[sizeof($stack) - 1]; - array_pop($stack); - switch ($mode) { - case PEAR_ERROR_EXCEPTION: - case PEAR_ERROR_RETURN: - case PEAR_ERROR_PRINT: - case PEAR_ERROR_TRIGGER: - case PEAR_ERROR_DIE: - case null: - $setmode = $mode; - $setoptions = $options; - break; + if (!is_array($content)) { + if (is_string($file) && strlen($file < 255) && + (!file_exists($file) || !@is_file($file))) { + $ret = PEAR::raiseError("could not open file \"$file\""); + return $ret; + } - case PEAR_ERROR_CALLBACK: - $setmode = $mode; - // class/object method callback - if (is_callable($options)) { - $setoptions = $options; - } else { - trigger_error("invalid error callback", E_USER_WARNING); - } + $file = realpath($file); + $ret = PEAR::raiseError("Could not get contents of package \"$file\"". + '. Invalid tgz file.'); + return $ret; + } + + if (!count($content) && !@is_file($file)) { + $ret = PEAR::raiseError("could not open file \"$file\""); + return $ret; + } + + $xml = null; + $origfile = $file; + foreach ($content as $file) { + $name = $file['filename']; + if ($name == 'package2.xml') { // allow a .tgz to distribute both versions + $xml = $name; break; + } - default: - trigger_error("invalid error mode", E_USER_WARNING); + if ($name == 'package.xml') { + $xml = $name; + break; + } elseif (preg_match('/package.xml$/', $name, $match)) { + $xml = $name; break; + } } - return true; - } - // {{{ pushErrorHandling() - - /** - * Push a new error handler on top of the error handler options stack. With this - * you can easily override the actual error handler for some code and restore - * it later with popErrorHandling. - * - * @param mixed $mode (same as setErrorHandling) - * @param mixed $options (same as setErrorHandling) - * - * @return bool Always true - * - * @see PEAR::setErrorHandling - */ - function pushErrorHandling($mode, $options = null) - { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - if (isset($this) && is_a($this, 'PEAR')) { - $def_mode = &$this->_default_error_mode; - $def_options = &$this->_default_error_options; + if ($this->_tmpdir) { + $tmpdir = $this->_tmpdir; } else { - $def_mode = &$GLOBALS['_PEAR_default_error_mode']; - $def_options = &$GLOBALS['_PEAR_default_error_options']; + $tmpdir = System::mkTemp(array('-t', $this->_config->get('temp_dir'), '-d', 'pear')); + if ($tmpdir === false) { + $ret = PEAR::raiseError("there was a problem with getting the configured temp directory"); + return $ret; + } + + PEAR_PackageFile::addTempFile($tmpdir); } - $stack[] = array($def_mode, $def_options); - if (isset($this) && is_a($this, 'PEAR')) { - $this->setErrorHandling($mode, $options); - } else { - PEAR::setErrorHandling($mode, $options); + $this->_extractErrors(); + PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors')); + if (!$xml || !$tar->extractList(array($xml), $tmpdir)) { + $extra = implode("\n", $this->_extractErrors()); + if ($extra) { + $extra = ' ' . $extra; + } + + PEAR::staticPopErrorHandling(); + $ret = PEAR::raiseError('could not extract the package.xml file from "' . + $origfile . '"' . $extra); + return $ret; } - $stack[] = array($mode, $options); - return true; + + PEAR::staticPopErrorHandling(); + $ret = &PEAR_PackageFile::fromPackageFile("$tmpdir/$xml", $state, $origfile); + return $ret; } - // }}} - // {{{ popErrorHandling() + /** + * helper for extracting Archive_Tar errors + * @var array + * @access private + */ + var $_extractErrors = array(); /** - * Pop the last error handler used - * - * @return bool Always true - * - * @see PEAR::pushErrorHandling - */ - function popErrorHandling() + * helper callback for extracting Archive_Tar errors + * + * @param PEAR_Error|null $err + * @return array + * @access private + */ + function _extractErrors($err = null) { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - array_pop($stack); - list($mode, $options) = $stack[sizeof($stack) - 1]; - array_pop($stack); - if (isset($this) && is_a($this, 'PEAR')) { - $this->setErrorHandling($mode, $options); - } else { - PEAR::setErrorHandling($mode, $options); + static $errors = array(); + if ($err === null) { + $e = $errors; + $errors = array(); + return $e; } - return true; + $errors[] = $err->getMessage(); } - // }}} - // {{{ loadExtension() - /** - * OS independant PHP extension load. Remember to take care - * on the correct extension name for case sensitive OSes. - * - * @param string $ext The extension name - * @return bool Success or not on the dl() call - */ - function loadExtension($ext) + * Create a PEAR_PackageFile_v* from a package.xml file. + * + * @access public + * @param string $descfile name of package xml file + * @param int $state package state (one of PEAR_VALIDATE_* constants) + * @param string|false $archive name of the archive this package.xml came + * from, if any + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @uses PEAR_PackageFile::fromXmlString to create the oject after the + * XML is loaded from the package.xml file. + */ + function &fromPackageFile($descfile, $state, $archive = false) { - if (!extension_loaded($ext)) { - // if either returns true dl() will produce a FATAL error, stop that - if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) { - return false; - } - - if (OS_WINDOWS) { - $suffix = '.dll'; - } elseif (PHP_OS == 'HP-UX') { - $suffix = '.sl'; - } elseif (PHP_OS == 'AIX') { - $suffix = '.a'; - } elseif (PHP_OS == 'OSX') { - $suffix = '.bundle'; - } else { - $suffix = '.so'; - } - - return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); + $fp = false; + if (is_string($descfile) && strlen($descfile) < 255 && + ( + !file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) + || (!$fp = @fopen($descfile, 'r')) + ) + ) { + $a = PEAR::raiseError("Unable to open $descfile"); + return $a; } - return true; + // read the whole thing so we only get one cdata callback + // for each block of cdata + fclose($fp); + $data = file_get_contents($descfile); + $ret = &PEAR_PackageFile::fromXmlString($data, $state, $descfile, $archive); + return $ret; } - // }}} -} -if (PEAR_ZE2) { /** - * This is only meant for PHP 5 to get rid of certain strict warning - * that doesn't get hidden since it's in the shutdown function + * Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file. + * + * This method is able to extract information about a package from a .tgz + * archive or from a XML package definition file. + * + * @access public + * @param string $info file name + * @param int $state package state (one of PEAR_VALIDATE_* constants) + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @uses fromPackageFile() if the file appears to be XML + * @uses fromTgzFile() to load all non-XML files */ - class PEAR5 + function &fromAnyFile($info, $state) { - /** - * If you have a class that's mostly/entirely static, and you need static - * properties, you can use this method to simulate them. Eg. in your method(s) - * do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar'); - * You MUST use a reference, or they will not persist! - * - * @access public - * @param string $class The calling classname, to prevent clashes - * @param string $var The variable to retrieve. - * @return mixed A reference to the variable. If not set it will be - * auto initialised to NULL. - */ - static function &getStaticProperty($class, $var) - { - static $properties; - if (!isset($properties[$class])) { - $properties[$class] = array(); - } - - if (!array_key_exists($var, $properties[$class])) { - $properties[$class][$var] = null; + if (is_dir($info)) { + $dir_name = realpath($info); + if (file_exists($dir_name . '/package.xml')) { + $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package.xml', $state); + } elseif (file_exists($dir_name . '/package2.xml')) { + $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package2.xml', $state); + } else { + $info = PEAR::raiseError("No package definition found in '$info' directory"); } - return $properties[$class][$var]; + return $info; } - } -} -// {{{ _PEAR_call_destructors() + $fp = false; + if (is_string($info) && strlen($info) < 255 && + (file_exists($info) || ($fp = @fopen($info, 'r'))) + ) { -function _PEAR_call_destructors() -{ - global $_PEAR_destructor_object_list; - if (is_array($_PEAR_destructor_object_list) && - sizeof($_PEAR_destructor_object_list)) - { - reset($_PEAR_destructor_object_list); - if (PEAR_ZE2) { - $destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo'); - } else { - $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); - } - - if ($destructLifoExists) { - $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); - } + if ($fp) { + fclose($fp); + } - while (list($k, $objref) = each($_PEAR_destructor_object_list)) { - $classname = get_class($objref); - while ($classname) { - $destructor = "_$classname"; - if (method_exists($objref, $destructor)) { - $objref->$destructor(); - break; + $tmp = substr($info, -4); + if ($tmp == '.xml') { + $info = &PEAR_PackageFile::fromPackageFile($info, $state); + } elseif ($tmp == '.tar' || $tmp == '.tgz') { + $info = &PEAR_PackageFile::fromTgzFile($info, $state); + } else { + $fp = fopen($info, 'r'); + $test = fread($fp, 5); + fclose($fp); + if ($test == ' - * @author Tomas V.V. Cox - * @author Gregory Beaver - * @copyright 1997-2006 The PHP Group + * @author Tomas V. V. Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/manual/en/core.pear.pear-error.php - * @see PEAR::raiseError(), PEAR::throwError() - * @since Class available since PHP 4.0.2 + * @version CVS: $Id: Packager.php 286809 2009-08-04 15:10:26Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 */ -class PEAR_Error -{ - // {{{ properties - - var $error_message_prefix = ''; - var $mode = PEAR_ERROR_RETURN; - var $level = E_USER_NOTICE; - var $code = -1; - var $message = ''; - var $userinfo = ''; - var $backtrace = null; - // }}} - // {{{ constructor +/** + * base class + */ +require_once 'PEAR/Common.php'; +require_once 'PEAR/PackageFile.php'; +require_once 'System.php'; +/** + * Administration class used to make a PEAR release tarball. + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Packager extends PEAR_Common +{ /** - * PEAR_Error constructor - * - * @param string $message message - * - * @param int $code (optional) error code - * - * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, - * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, - * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION - * - * @param mixed $options (optional) error level, _OR_ in the case of - * PEAR_ERROR_CALLBACK, the callback function or object/method - * tuple. - * - * @param string $userinfo (optional) additional user/debug info - * - * @access public - * + * @var PEAR_Registry */ - function PEAR_Error($message = 'unknown error', $code = null, - $mode = null, $options = null, $userinfo = null) + var $_registry; + + function package($pkgfile = null, $compress = true, $pkg2 = null) { - if ($mode === null) { - $mode = PEAR_ERROR_RETURN; + // {{{ validate supplied package.xml file + if (empty($pkgfile)) { + $pkgfile = 'package.xml'; } - $this->message = $message; - $this->code = $code; - $this->mode = $mode; - $this->userinfo = $userinfo; - if (PEAR_ZE2) { - $skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace'); - } else { - $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $pkg = &new PEAR_PackageFile($this->config, $this->debug); + $pf = &$pkg->fromPackageFile($pkgfile, PEAR_VALIDATE_NORMAL); + $main = &$pf; + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf)) { + if (is_array($pf->getUserInfo())) { + foreach ($pf->getUserInfo() as $error) { + $this->log(0, 'Error: ' . $error['message']); + } + } + + $this->log(0, $pf->getMessage()); + return $this->raiseError("Cannot package, errors in package file"); } - if (!$skiptrace) { - $this->backtrace = debug_backtrace(); - if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) { - unset($this->backtrace[0]['object']); - } + foreach ($pf->getValidationWarnings() as $warning) { + $this->log(1, 'Warning: ' . $warning['message']); } - if ($mode & PEAR_ERROR_CALLBACK) { - $this->level = E_USER_NOTICE; - $this->callback = $options; - } else { - if ($options === null) { - $options = E_USER_NOTICE; + + // }}} + if ($pkg2) { + $this->log(0, 'Attempting to process the second package file'); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $pf2 = &$pkg->fromPackageFile($pkg2, PEAR_VALIDATE_NORMAL); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf2)) { + if (is_array($pf2->getUserInfo())) { + foreach ($pf2->getUserInfo() as $error) { + $this->log(0, 'Error: ' . $error['message']); + } + } + $this->log(0, $pf2->getMessage()); + return $this->raiseError("Cannot package, errors in second package file"); } - $this->level = $options; - $this->callback = null; - } - if ($this->mode & PEAR_ERROR_PRINT) { - if (is_null($options) || is_int($options)) { - $format = "%s"; + + foreach ($pf2->getValidationWarnings() as $warning) { + $this->log(1, 'Warning: ' . $warning['message']); + } + + if ($pf2->getPackagexmlVersion() == '2.0' || + $pf2->getPackagexmlVersion() == '2.1' + ) { + $main = &$pf2; + $other = &$pf; } else { - $format = $options; + $main = &$pf; + $other = &$pf2; + } + + if ($main->getPackagexmlVersion() != '2.0' && + $main->getPackagexmlVersion() != '2.1') { + return PEAR::raiseError('Error: cannot package two package.xml version 1.0, can ' . + 'only package together a package.xml 1.0 and package.xml 2.0'); + } + + if ($other->getPackagexmlVersion() != '1.0') { + return PEAR::raiseError('Error: cannot package two package.xml version 2.0, can ' . + 'only package together a package.xml 1.0 and package.xml 2.0'); } - printf($format, $this->getMessage()); } - if ($this->mode & PEAR_ERROR_TRIGGER) { - trigger_error($this->getMessage(), $this->level); + + $main->setLogger($this); + if (!$main->validate(PEAR_VALIDATE_PACKAGING)) { + foreach ($main->getValidationWarnings() as $warning) { + $this->log(0, 'Error: ' . $warning['message']); + } + return $this->raiseError("Cannot package, errors in package"); } - if ($this->mode & PEAR_ERROR_DIE) { - $msg = $this->getMessage(); - if (is_null($options) || is_int($options)) { - $format = "%s"; - if (substr($msg, -1) != "\n") { - $msg .= "\n"; + + foreach ($main->getValidationWarnings() as $warning) { + $this->log(1, 'Warning: ' . $warning['message']); + } + + if ($pkg2) { + $other->setLogger($this); + $a = false; + if (!$other->validate(PEAR_VALIDATE_NORMAL) || $a = !$main->isEquivalent($other)) { + foreach ($other->getValidationWarnings() as $warning) { + $this->log(0, 'Error: ' . $warning['message']); } - } else { - $format = $options; + + foreach ($main->getValidationWarnings() as $warning) { + $this->log(0, 'Error: ' . $warning['message']); + } + + if ($a) { + return $this->raiseError('The two package.xml files are not equivalent!'); + } + + return $this->raiseError("Cannot package, errors in package"); } - die(sprintf($format, $msg)); - } - if ($this->mode & PEAR_ERROR_CALLBACK) { - if (is_callable($this->callback)) { - call_user_func($this->callback, $this); + + foreach ($other->getValidationWarnings() as $warning) { + $this->log(1, 'Warning: ' . $warning['message']); + } + + $gen = &$main->getDefaultGenerator(); + $tgzfile = $gen->toTgz2($this, $other, $compress); + if (PEAR::isError($tgzfile)) { + return $tgzfile; + } + + $dest_package = basename($tgzfile); + $pkgdir = dirname($pkgfile); + + // TAR the Package ------------------------------------------- + $this->log(1, "Package $dest_package done"); + if (file_exists("$pkgdir/CVS/Root")) { + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion()); + $cvstag = "RELEASE_$cvsversion"; + $this->log(1, 'Tag the released code with "pear cvstag ' . + $main->getPackageFile() . '"'); + $this->log(1, "(or set the CVS tag $cvstag by hand)"); + } elseif (file_exists("$pkgdir/.svn")) { + $svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion()); + $svntag = $pf->getName() . "-$svnversion"; + $this->log(1, 'Tag the released code with "pear svntag ' . + $main->getPackageFile() . '"'); + $this->log(1, "(or set the SVN tag $svntag by hand)"); + } + } else { // this branch is executed for single packagefile packaging + $gen = &$pf->getDefaultGenerator(); + $tgzfile = $gen->toTgz($this, $compress); + if (PEAR::isError($tgzfile)) { + $this->log(0, $tgzfile->getMessage()); + return $this->raiseError("Cannot package, errors in package"); + } + + $dest_package = basename($tgzfile); + $pkgdir = dirname($pkgfile); + + // TAR the Package ------------------------------------------- + $this->log(1, "Package $dest_package done"); + if (file_exists("$pkgdir/CVS/Root")) { + $cvsversion = preg_replace('/[^a-z0-9]/i', '_', $pf->getVersion()); + $cvstag = "RELEASE_$cvsversion"; + $this->log(1, "Tag the released code with `pear cvstag $pkgfile'"); + $this->log(1, "(or set the CVS tag $cvstag by hand)"); + } elseif (file_exists("$pkgdir/.svn")) { + $svnversion = preg_replace('/[^a-z0-9]/i', '.', $pf->getVersion()); + $svntag = $pf->getName() . "-$svnversion"; + $this->log(1, "Tag the released code with `pear svntag $pkgfile'"); + $this->log(1, "(or set the SVN tag $svntag by hand)"); } } - if ($this->mode & PEAR_ERROR_EXCEPTION) { - trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); - eval('$e = new Exception($this->message, $this->code);throw($e);'); - } + + return $dest_package; } +}PEAR-1.9.0/PEAR/Registry.php100664 764 764 224124 100664 10423 + * @author Tomas V. V. Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Registry.php 287555 2009-08-21 21:27:27Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ - // }}} - // {{{ getMode() +/** + * for PEAR_Error + */ +require_once 'PEAR.php'; +require_once 'PEAR/DependencyDB.php'; + +define('PEAR_REGISTRY_ERROR_LOCK', -2); +define('PEAR_REGISTRY_ERROR_FORMAT', -3); +define('PEAR_REGISTRY_ERROR_FILE', -4); +define('PEAR_REGISTRY_ERROR_CONFLICT', -5); +define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6); +/** + * Administration class used to maintain the installed package database. + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V. V. Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Registry extends PEAR +{ /** - * Get the error mode from an error object. - * - * @return int error mode - * @access public + * File containing all channel information. + * @var string */ - function getMode() { - return $this->mode; - } + var $channels = ''; - // }}} - // {{{ getCallback() + /** Directory where registry files are stored. + * @var string + */ + var $statedir = ''; - /** - * Get the callback function/method from an error object. - * - * @return mixed callback function or object/method array - * @access public + /** File where the file map is stored + * @var string */ - function getCallback() { - return $this->callback; - } + var $filemap = ''; - // }}} - // {{{ getMessage() + /** Directory where registry files for channels are stored. + * @var string + */ + var $channelsdir = ''; + /** Name of file used for locking the registry + * @var string + */ + var $lockfile = ''; - /** - * Get the error message from an error object. - * - * @return string full error message - * @access public + /** File descriptor used during locking + * @var resource */ - function getMessage() - { - return ($this->error_message_prefix . $this->message); - } + var $lock_fp = null; + /** Mode used during locking + * @var int + */ + var $lock_mode = 0; // XXX UNUSED - // }}} - // {{{ getCode() + /** Cache of package information. Structure: + * array( + * 'package' => array('id' => ... ), + * ... ) + * @var array + */ + var $pkginfo_cache = array(); - /** - * Get error code from an error object - * - * @return int error code - * @access public + /** Cache of file map. Structure: + * array( '/path/to/file' => 'package', ... ) + * @var array */ - function getCode() - { - return $this->code; - } + var $filemap_cache = array(); - // }}} - // {{{ getType() + /** + * @var false|PEAR_ChannelFile + */ + var $_pearChannel; /** - * Get the name of this error/exception. - * - * @return string error/exception name (type) - * @access public + * @var false|PEAR_ChannelFile */ - function getType() - { - return get_class($this); - } + var $_peclChannel; - // }}} - // {{{ getUserInfo() + /** + * @var false|PEAR_ChannelFile + */ + var $_docChannel; /** - * Get additional user-supplied information. - * - * @return string user-supplied information - * @access public + * @var PEAR_DependencyDB */ - function getUserInfo() - { - return $this->userinfo; - } + var $_dependencyDB; - // }}} - // {{{ getDebugInfo() + /** + * @var PEAR_Config + */ + var $_config; /** - * Get additional debug information supplied by the application. + * PEAR_Registry constructor. + * + * @param string (optional) PEAR install directory (for .php files) + * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PEAR channel, if + * default values are not desired. Only used the very first time a PEAR + * repository is initialized + * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PECL channel, if + * default values are not desired. Only used the very first time a PEAR + * repository is initialized * - * @return string debug information * @access public */ - function getDebugInfo() + function PEAR_Registry($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false, + $pecl_channel = false) { - return $this->getUserInfo(); + parent::PEAR(); + $this->setInstallDir($pear_install_dir); + $this->_pearChannel = $pear_channel; + $this->_peclChannel = $pecl_channel; + $this->_config = false; } - // }}} - // {{{ getBacktrace() + function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR) + { + $ds = DIRECTORY_SEPARATOR; + $this->install_dir = $pear_install_dir; + $this->channelsdir = $pear_install_dir.$ds.'.channels'; + $this->statedir = $pear_install_dir.$ds.'.registry'; + $this->filemap = $pear_install_dir.$ds.'.filemap'; + $this->lockfile = $pear_install_dir.$ds.'.lock'; + } - /** - * Get the call backtrace from where the error was generated. - * Supported with PHP 4.3.0 or newer. - * - * @param int $frame (optional) what frame to fetch - * @return array Backtrace, or NULL if not available. - * @access public - */ - function getBacktrace($frame = null) + function hasWriteAccess() { - if (defined('PEAR_IGNORE_BACKTRACE')) { - return null; - } - if ($frame === null) { - return $this->backtrace; + if (!file_exists($this->install_dir)) { + $dir = $this->install_dir; + while ($dir && $dir != '.') { + $olddir = $dir; + $dir = dirname($dir); + if ($dir != '.' && file_exists($dir)) { + if (is_writeable($dir)) { + return true; + } + + return false; + } + + if ($dir == $olddir) { // this can happen in safe mode + return @is_writable($dir); + } + } + + return false; } - return $this->backtrace[$frame]; + + return is_writeable($this->install_dir); } - // }}} - // {{{ addUserInfo() + function setConfig(&$config, $resetInstallDir = true) + { + $this->_config = &$config; + if ($resetInstallDir) { + $this->setInstallDir($config->get('php_dir')); + } + } + + function _initializeChannelDirs() + { + static $running = false; + if (!$running) { + $running = true; + $ds = DIRECTORY_SEPARATOR; + if (!is_dir($this->channelsdir) || + !file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || + !file_exists($this->channelsdir . $ds . '__uri.reg')) { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $pear_channel = $this->_pearChannel; + if (!is_a($pear_channel, 'PEAR_ChannelFile') || !$pear_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } - function addUserInfo($info) + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setAlias('pear'); + $pear_channel->setServer('pear.php.net'); + $pear_channel->setSummary('PHP Extension and Application Repository'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/'); + //$pear_channel->setBaseURL('REST1.4', 'http://pear.php.net/rest/'); + } else { + $pear_channel->setServer('pear.php.net'); + $pear_channel->setAlias('pear'); + } + + $pear_channel->validate(); + $this->_addChannel($pear_channel); + } + + if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) { + $pecl_channel = $this->_peclChannel; + if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $pecl_channel = new PEAR_ChannelFile; + $pecl_channel->setAlias('pecl'); + $pecl_channel->setServer('pecl.php.net'); + $pecl_channel->setSummary('PHP Extension Community Library'); + $pecl_channel->setDefaultPEARProtocols(); + $pecl_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); + $pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); + $pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); + } else { + $pecl_channel->setServer('pecl.php.net'); + $pecl_channel->setAlias('pecl'); + } + + $pecl_channel->validate(); + $this->_addChannel($pecl_channel); + } + + if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) { + $doc_channel = $this->_docChannel; + if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $doc_channel = new PEAR_ChannelFile; + $doc_channel->setAlias('phpdocs'); + $doc_channel->setServer('doc.php.net'); + $doc_channel->setSummary('PHP Documentation Team'); + $doc_channel->setDefaultPEARProtocols(); + $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/'); + } else { + $doc_channel->setServer('doc.php.net'); + $doc_channel->setAlias('doc'); + } + + $doc_channel->validate(); + $this->_addChannel($doc_channel); + } + + if (!file_exists($this->channelsdir . $ds . '__uri.reg')) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $private = new PEAR_ChannelFile; + $private->setName('__uri'); + $private->setDefaultPEARProtocols(); + $private->setBaseURL('REST1.0', '****'); + $private->setSummary('Pseudo-channel for static packages'); + $this->_addChannel($private); + } + $this->_rebuildFileMap(); + } + + $running = false; + } + } + + function _initializeDirs() { - if (empty($this->userinfo)) { - $this->userinfo = $info; - } else { - $this->userinfo .= " ** $info"; + $ds = DIRECTORY_SEPARATOR; + // XXX Compatibility code should be removed in the future + // rename all registry files if any to lowercase + if (!OS_WINDOWS && file_exists($this->statedir) && is_dir($this->statedir) && + $handle = opendir($this->statedir)) { + $dest = $this->statedir . $ds; + while (false !== ($file = readdir($handle))) { + if (preg_match('/^.*[A-Z].*\.reg\\z/', $file)) { + rename($dest . $file, $dest . strtolower($file)); + } + } + closedir($handle); + } + + $this->_initializeChannelDirs(); + if (!file_exists($this->filemap)) { + $this->_rebuildFileMap(); } + $this->_initializeDepDB(); } - // }}} - // {{{ toString() - function __toString() + function _initializeDepDB() { - return $this->getMessage(); + if (!isset($this->_dependencyDB)) { + static $initializing = false; + if (!$initializing) { + $initializing = true; + if (!$this->_config) { // never used? + $file = OS_WINDOWS ? 'pear.ini' : '.pearrc'; + $this->_config = &new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR . + $file); + $this->_config->setRegistry($this); + $this->_config->set('php_dir', $this->install_dir); + } + + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); + if (PEAR::isError($this->_dependencyDB)) { + // attempt to recover by removing the dep db + if (file_exists($this->_config->get('php_dir', null, 'pear.php.net') . + DIRECTORY_SEPARATOR . '.depdb')) { + @unlink($this->_config->get('php_dir', null, 'pear.php.net') . + DIRECTORY_SEPARATOR . '.depdb'); + } + + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); + if (PEAR::isError($this->_dependencyDB)) { + echo $this->_dependencyDB->getMessage(); + echo 'Unrecoverable error'; + exit(1); + } + } + + $initializing = false; + } + } } - // }}} - // {{{ toString() /** - * Make a string representation of this object. + * PEAR_Registry destructor. Makes sure no locks are forgotten. * - * @return string a string with an object summary - * @access public + * @access private */ - function toString() { - $modes = array(); - $levels = array(E_USER_NOTICE => 'notice', - E_USER_WARNING => 'warning', - E_USER_ERROR => 'error'); - if ($this->mode & PEAR_ERROR_CALLBACK) { - if (is_array($this->callback)) { - $callback = (is_object($this->callback[0]) ? - strtolower(get_class($this->callback[0])) : - $this->callback[0]) . '::' . - $this->callback[1]; - } else { - $callback = $this->callback; - } - return sprintf('[%s: message="%s" code=%d mode=callback '. - 'callback=%s prefix="%s" info="%s"]', - strtolower(get_class($this)), $this->message, $this->code, - $callback, $this->error_message_prefix, - $this->userinfo); - } - if ($this->mode & PEAR_ERROR_PRINT) { - $modes[] = 'print'; - } - if ($this->mode & PEAR_ERROR_TRIGGER) { - $modes[] = 'trigger'; - } - if ($this->mode & PEAR_ERROR_DIE) { - $modes[] = 'die'; - } - if ($this->mode & PEAR_ERROR_RETURN) { - $modes[] = 'return'; + function _PEAR_Registry() + { + parent::_PEAR(); + if (is_resource($this->lock_fp)) { + $this->_unlock(); } - return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. - 'prefix="%s" info="%s"]', - strtolower(get_class($this)), $this->message, $this->code, - implode("|", $modes), $levels[$this->level], - $this->error_message_prefix, - $this->userinfo); } - // }}} -} - -/* - * Local Variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * End: - */PEAR-1.8.0/README100777 764 764 2251 100777 6177 PEAR - The PEAR Installer -========================= - -What is the PEAR Installer? What is PEAR? - -PEAR is the PHP Extension and Application Repository, found at -http://pear.php.net. The PEAR Installer is this software, which -contains executable files and PHP code that is used to download -and install PEAR code from pear.php.net. - -PEAR contains useful software libraries and applications such as -MDB2 (database abstraction), HTML_QuickForm (HTML forms management), -PhpDocumentor (auto-documentation generator), DB_DataObject -(Data Access Abstraction), and many hundreds more. Browse all -available packages at http://pear.php.net, the list is constantly -growing and updating to reflect improvements in the PHP language. - -DOCUMENTATION -============= - -Documentation for PEAR can be found at http://pear.php.net/manual/. -Installation documentation can be found in the INSTALL file included -in this tarball. - -WARNING: DO NOT RUN PEAR WITHOUT INSTALLING IT - if you downloaded this -tarball manually, you MUST install it. Read the instructions in INSTALL -prior to use. - - -Happy PHPing, we hope PEAR will be a great tool for your development work! - -$Id: README,v 1.11 2006/09/22 03:31:36 cellog Exp $PEAR-1.8.0/System.php100664 764 764 47002 100664 7325 - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: System.php,v 1.66 2009/02/24 23:52:56 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ - -/** - * base class - */ -require_once 'PEAR.php'; -require_once 'Console/Getopt.php'; - -$GLOBALS['_System_temp_files'] = array(); - -/** -* System offers cross plattform compatible system functions -* -* Static functions for different operations. Should work under -* Unix and Windows. The names and usage has been taken from its respectively -* GNU commands. The functions will return (bool) false on error and will -* trigger the error with the PHP trigger_error() function (you can silence -* the error by prefixing a '@' sign after the function call, but this -* is not recommended practice. Instead use an error handler with -* {@link set_error_handler()}). -* -* Documentation on this class you can find in: -* http://pear.php.net/manual/ -* -* Example usage: -* if (!@System::rm('-r file1 dir1')) { -* print "could not delete file1 or dir1"; -* } -* -* In case you need to to pass file names with spaces, -* pass the params as an array: -* -* System::rm(array('-r', $file1, $dir1)); -* -* @category pear -* @package System -* @author Tomas V.V. Cox -* @copyright 1997-2006 The PHP Group -* @license http://opensource.org/licenses/bsd-license.php New BSD License -* @version Release: 1.8.0 -* @link http://pear.php.net/package/PEAR -* @since Class available since Release 0.1 -* @static -*/ -class System -{ /** - * returns the commandline arguments of a function + * Make sure the directory where we keep registry files exists. + * + * @return bool TRUE if directory exists, FALSE if it could not be + * created * - * @param string $argv the commandline - * @param string $short_options the allowed option short-tags - * @param string $long_options the allowed option long-tags - * @return array the given options and there values - * @static * @access private */ - function _parseArgs($argv, $short_options, $long_options = null) + function _assertStateDir($channel = false) { - if (!is_array($argv) && $argv !== null) { - $argv = preg_split('/\s+/', $argv, -1, PREG_SPLIT_NO_EMPTY); + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_assertChannelStateDir($channel); } - return Console_Getopt::getopt2($argv, $short_options); + + static $init = false; + if (!file_exists($this->statedir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'System.php'; + if (!System::mkdir(array('-p', $this->statedir))) { + return $this->raiseError("could not create directory '{$this->statedir}'"); + } + $init = true; + } elseif (!is_dir($this->statedir)) { + return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' . + 'it already exists and is not a directory'); + } + + $ds = DIRECTORY_SEPARATOR; + if (!file_exists($this->channelsdir)) { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || + !file_exists($this->channelsdir . $ds . '__uri.reg')) { + $init = true; + } + } elseif (!is_dir($this->channelsdir)) { + return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' . + 'it already exists and is not a directory'); + } + + if ($init) { + static $running = false; + if (!$running) { + $running = true; + $this->_initializeDirs(); + $running = false; + $init = false; + } + } else { + $this->_initializeDepDB(); + } + + return true; } /** - * Output errors with PHP trigger_error(). You can silence the errors - * with prefixing a "@" sign to the function call: @System::mkdir(..); + * Make sure the directory where we keep registry files exists for a non-standard channel. + * + * @param string channel name + * @return bool TRUE if directory exists, FALSE if it could not be + * created * - * @param mixed $error a PEAR error or a string with the error message - * @return bool false - * @static * @access private */ - function raiseError($error) + function _assertChannelStateDir($channel) { - if (PEAR::isError($error)) { - $error = $error->getMessage(); + $ds = DIRECTORY_SEPARATOR; + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $this->_initializeChannelDirs(); + } + return $this->_assertStateDir($channel); } - trigger_error($error, E_USER_WARNING); - return false; + + $channelDir = $this->_channelDirectoryName($channel); + if (!is_dir($this->channelsdir) || + !file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $this->_initializeChannelDirs(); + } + + if (!file_exists($channelDir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'System.php'; + if (!System::mkdir(array('-p', $channelDir))) { + return $this->raiseError("could not create directory '" . $channelDir . + "'"); + } + } elseif (!is_dir($channelDir)) { + return $this->raiseError("could not create directory '" . $channelDir . + "', already exists and is not a directory"); + } + + return true; } /** - * Creates a nested array representing the structure of a directory + * Make sure the directory where we keep registry files for channels exists * - * System::_dirToStruct('dir1', 0) => - * Array - * ( - * [dirs] => Array - * ( - * [0] => dir1 - * ) + * @return bool TRUE if directory exists, FALSE if it could not be + * created * - * [files] => Array - * ( - * [0] => dir1/file2 - * [1] => dir1/file3 - * ) - * ) - * @param string $sPath Name of the directory - * @param integer $maxinst max. deep of the lookup - * @param integer $aktinst starting deep of the lookup - * @param bool $silent if true, do not emit errors. - * @return array the structure of the dir - * @static - * @access private + * @access private */ - function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false) + function _assertChannelDir() { - $struct = array('dirs' => array(), 'files' => array()); - if (($dir = @opendir($sPath)) === false) { - if (!$silent) { - System::raiseError("Could not open dir $sPath"); + if (!file_exists($this->channelsdir)) { + if (!$this->hasWriteAccess()) { + return false; } - return $struct; // XXX could not open error - } - $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ? - $list = array(); - while (false !== ($file = readdir($dir))) { - if ($file != '.' && $file != '..') { - $list[] = $file; + require_once 'System.php'; + if (!System::mkdir(array('-p', $this->channelsdir))) { + return $this->raiseError("could not create directory '{$this->channelsdir}'"); } + } elseif (!is_dir($this->channelsdir)) { + return $this->raiseError("could not create directory '{$this->channelsdir}" . + "', it already exists and is not a directory"); } - closedir($dir); - natsort($list); - if ($aktinst < $maxinst || $maxinst == 0) { - foreach ($list as $val) { - $path = $sPath . DIRECTORY_SEPARATOR . $val; - if (is_dir($path) && !is_link($path)) { - $tmp = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent); - $struct = array_merge_recursive($struct, $tmp); - } else { - $struct['files'][] = $path; - } + if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { + if (!$this->hasWriteAccess()) { + return false; } + + require_once 'System.php'; + if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) { + return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'"); + } + } elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { + return $this->raiseError("could not create directory '{$this->channelsdir}" . + "/.alias', it already exists and is not a directory"); } - return $struct; + return true; } /** - * Creates a nested array representing the structure of a directory and files + * Get the name of the file where data for a given package is stored. * - * @param array $files Array listing files and dirs - * @return array - * @static - * @see System::_dirToStruct() + * @param string channel name, or false if this is a PEAR package + * @param string package name + * + * @return string registry file name + * + * @access public */ - function _multipleToStruct($files) + function _packageFileName($package, $channel = false) { - $struct = array('dirs' => array(), 'files' => array()); - settype($files, 'array'); - foreach ($files as $file) { - if (is_dir($file) && !is_link($file)) { - $tmp = System::_dirToStruct($file, 0); - $struct = array_merge_recursive($tmp, $struct); - } else { - if (!in_array($file, $struct['files'])) { - $struct['files'][] = $file; - } - } + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR . + strtolower($package) . '.reg'; } - return $struct; + + return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg'; } /** - * The rm command for removing files. - * Supports multiple files and dirs and also recursive deletes - * - * @param string $args the arguments for rm - * @return mixed PEAR_Error or true for success - * @static - * @access public + * Get the name of the file where data for a given channel is stored. + * @param string channel name + * @return string registry file name */ - function rm($args) + function _channelFileName($channel, $noaliases = false) { - $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-) - if (PEAR::isError($opts)) { - return System::raiseError($opts); - } - foreach ($opts[0] as $opt) { - if ($opt[0] == 'r') { - $do_recursive = true; - } - } - $ret = true; - if (isset($do_recursive)) { - $struct = System::_multipleToStruct($opts[1]); - foreach ($struct['files'] as $file) { - if (!@unlink($file)) { - $ret = false; - } - } - - rsort($struct['dirs']); - foreach ($struct['dirs'] as $dir) { - if (!@rmdir($dir)) { - $ret = false; - } - } - } else { - foreach ($opts[1] as $file) { - $delete = (is_dir($file)) ? 'rmdir' : 'unlink'; - if (!@$delete($file)) { - $ret = false; - } + if (!$noaliases) { + if (file_exists($this->_getChannelAliasFileName($channel))) { + $channel = implode('', file($this->_getChannelAliasFileName($channel))); } } - return $ret; + return $this->channelsdir . DIRECTORY_SEPARATOR . str_replace('/', '_', + strtolower($channel)) . '.reg'; } /** - * Make directories. - * - * The -p option will create parent directories - * @param string $args the name of the director(y|ies) to create - * @return bool True for success - * @static - * @access public + * @param string + * @return string */ - function mkDir($args) + function _getChannelAliasFileName($alias) { - $opts = System::_parseArgs($args, 'pm:'); - if (PEAR::isError($opts)) { - return System::raiseError($opts); - } + return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' . + DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt'; + } - $mode = 0777; // default mode - foreach ($opts[0] as $opt) { - if ($opt[0] == 'p') { - $create_parents = true; - } elseif ($opt[0] == 'm') { - // if the mode is clearly an octal number (starts with 0) - // convert it to decimal - if (strlen($opt[1]) && $opt[1]{0} == '0') { - $opt[1] = octdec($opt[1]); - } else { - // convert to int - $opt[1] += 0; - } - $mode = $opt[1]; + /** + * Get the name of a channel from its alias + */ + function _getChannelFromAlias($channel) + { + if (!$this->_channelExists($channel)) { + if ($channel == 'pear.php.net') { + return 'pear.php.net'; } - } - - $ret = true; - if (isset($create_parents)) { - foreach ($opts[1] as $dir) { - $dirstack = array(); - while ((!file_exists($dir) || !is_dir($dir)) && - $dir != DIRECTORY_SEPARATOR) { - array_unshift($dirstack, $dir); - $dir = dirname($dir); - } - while ($newdir = array_shift($dirstack)) { - if (!is_writeable(dirname($newdir))) { - $ret = false; - break; - } + if ($channel == 'pecl.php.net') { + return 'pecl.php.net'; + } - if (!mkdir($newdir, $mode)) { - $ret = false; - } - } + if ($channel == 'doc.php.net') { + return 'doc.php.net'; } - } else { - foreach($opts[1] as $dir) { - if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) { - $ret = false; - } + + if ($channel == '__uri') { + return '__uri'; } + + return false; } - return $ret; + $channel = strtolower($channel); + if (file_exists($this->_getChannelAliasFileName($channel))) { + // translate an alias to an actual channel + return implode('', file($this->_getChannelAliasFileName($channel))); + } + + return $channel; } /** - * Concatenate files - * - * Usage: - * 1) $var = System::cat('sample.txt test.txt'); - * 2) System::cat('sample.txt test.txt > final.txt'); - * 3) System::cat('sample.txt test.txt >> final.txt'); - * - * Note: as the class use fopen, urls should work also (test that) - * - * @param string $args the arguments - * @return boolean true on success - * @static - * @access public + * Get the alias of a channel from its alias or its name */ - function &cat($args) + function _getAlias($channel) { - $ret = null; - $files = array(); - if (!is_array($args)) { - $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); - } - - $count_args = count($args); - for ($i = 0; $i < $count_args; $i++) { - if ($args[$i] == '>') { - $mode = 'wb'; - $outputfile = $args[$i+1]; - break; - } elseif ($args[$i] == '>>') { - $mode = 'ab+'; - $outputfile = $args[$i+1]; - break; - } else { - $files[] = $args[$i]; - } - } - $outputfd = false; - if (isset($mode)) { - if (!$outputfd = fopen($outputfile, $mode)) { - $err = System::raiseError("Could not open $outputfile"); - return $err; + if (!$this->_channelExists($channel)) { + if ($channel == 'pear.php.net') { + return 'pear'; } - $ret = true; - } - foreach ($files as $file) { - if (!$fd = fopen($file, 'r')) { - System::raiseError("Could not open $file"); - continue; + + if ($channel == 'pecl.php.net') { + return 'pecl'; } - while ($cont = fread($fd, 2048)) { - if (is_resource($outputfd)) { - fwrite($outputfd, $cont); - } else { - $ret .= $cont; - } + + if ($channel == 'doc.php.net') { + return 'phpdocs'; } - fclose($fd); + + return false; } - if (is_resource($outputfd)) { - fclose($outputfd); + + $channel = $this->_getChannel($channel); + if (PEAR::isError($channel)) { + return $channel; } - return $ret; + + return $channel->getAlias(); } /** - * Creates temporary files or directories. This function will remove - * the created files when the scripts finish its execution. + * Get the name of the file where data for a given package is stored. * - * Usage: - * 1) $tempfile = System::mktemp("prefix"); - * 2) $tempdir = System::mktemp("-d prefix"); - * 3) $tempfile = System::mktemp(); - * 4) $tempfile = System::mktemp("-t /var/tmp prefix"); + * @param string channel name, or false if this is a PEAR package + * @param string package name * - * prefix -> The string that will be prepended to the temp name - * (defaults to "tmp"). - * -d -> A temporary dir will be created instead of a file. - * -t -> The target dir where the temporary (file|dir) will be created. If - * this param is missing by default the env vars TMP on Windows or - * TMPDIR in Unix will be used. If these vars are also missing - * c:\windows\temp or /tmp will be used. + * @return string registry file name * - * @param string $args The arguments - * @return mixed the full path of the created (file|dir) or false - * @see System::tmpdir() - * @static - * @access public + * @access public */ - function mktemp($args = null) + function _channelDirectoryName($channel) { - static $first_time = true; - $opts = System::_parseArgs($args, 't:d'); - if (PEAR::isError($opts)) { - return System::raiseError($opts); + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + return $this->statedir; } - foreach ($opts[0] as $opt) { - if ($opt[0] == 'd') { - $tmp_is_dir = true; - } elseif ($opt[0] == 't') { - $tmpdir = $opt[1]; - } + $ch = $this->_getChannelFromAlias($channel); + if (!$ch) { + $ch = $channel; } - $prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp'; - if (!isset($tmpdir)) { - $tmpdir = System::tmpdir(); - } + return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' . + str_replace('/', '_', $ch)); + } - if (!System::mkDir(array('-p', $tmpdir))) { - return false; + function _openPackageFile($package, $mode, $channel = false) + { + if (!$this->_assertStateDir($channel)) { + return null; } - $tmp = tempnam($tmpdir, $prefix); - if (isset($tmp_is_dir)) { - unlink($tmp); // be careful possible race condition here - if (!mkdir($tmp, 0700)) { - return System::raiseError("Unable to create temporary directory $tmpdir"); - } + if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { + return null; } - $GLOBALS['_System_temp_files'][] = $tmp; - if (isset($tmp_is_dir)) { - //$GLOBALS['_System_temp_files'][] = dirname($tmp); + $file = $this->_packageFileName($package, $channel); + if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { + return null; } - if ($first_time) { - PEAR::registerShutdownFunc(array('System', '_removeTmpFiles')); - $first_time = false; + $fp = @fopen($file, $mode); + if (!$fp) { + return null; } - return $tmp; + return $fp; } - /** - * Remove temporary files created my mkTemp. This function is executed - * at script shutdown time - * - * @static - * @access private - */ - function _removeTmpFiles() + function _closePackageFile($fp) { - if (count($GLOBALS['_System_temp_files'])) { - $delete = $GLOBALS['_System_temp_files']; - array_unshift($delete, '-r'); - System::rm($delete); - $GLOBALS['_System_temp_files'] = array(); - } + fclose($fp); } - /** - * Get the path of the temporal directory set in the system - * by looking in its environments variables. - * Note: php.ini-recommended removes the "E" from the variables_order setting, - * making unavaible the $_ENV array, that s why we do tests with _ENV + function _openChannelFile($channel, $mode) + { + if (!$this->_assertChannelDir()) { + return null; + } + + if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { + return null; + } + + $file = $this->_channelFileName($channel); + if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { + return null; + } + + $fp = @fopen($file, $mode); + if (!$fp) { + return null; + } + + return $fp; + } + + function _closeChannelFile($fp) + { + fclose($fp); + } + + function _rebuildFileMap() + { + if (!class_exists('PEAR_Installer_Role')) { + require_once 'PEAR/Installer/Role.php'; + } + + $channels = $this->_listAllPackages(); + $files = array(); + foreach ($channels as $channel => $packages) { + foreach ($packages as $package) { + $version = $this->_packageInfo($package, 'version', $channel); + $filelist = $this->_packageInfo($package, 'filelist', $channel); + if (!is_array($filelist)) { + continue; + } + + foreach ($filelist as $name => $attrs) { + if (isset($attrs['attribs'])) { + $attrs = $attrs['attribs']; + } + + // it is possible for conflicting packages in different channels to + // conflict with data files/doc files + if ($name == 'dirtree') { + continue; + } + + if (isset($attrs['role']) && !in_array($attrs['role'], + PEAR_Installer_Role::getInstallableRoles())) { + // these are not installed + continue; + } + + if (isset($attrs['role']) && !in_array($attrs['role'], + PEAR_Installer_Role::getBaseinstallRoles())) { + $attrs['baseinstalldir'] = $package; + } + + if (isset($attrs['baseinstalldir'])) { + $file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name; + } else { + $file = $name; + } + + $file = preg_replace(',^/+,', '', $file); + if ($channel != 'pear.php.net') { + if (!isset($files[$attrs['role']])) { + $files[$attrs['role']] = array(); + } + $files[$attrs['role']][$file] = array(strtolower($channel), + strtolower($package)); + } else { + if (!isset($files[$attrs['role']])) { + $files[$attrs['role']] = array(); + } + $files[$attrs['role']][$file] = strtolower($package); + } + } + } + } + + + $this->_assertStateDir(); + if (!$this->hasWriteAccess()) { + return false; + } + + $fp = @fopen($this->filemap, 'wb'); + if (!$fp) { + return false; + } + + $this->filemap_cache = $files; + fwrite($fp, serialize($files)); + fclose($fp); + return true; + } + + function _readFileMap() + { + if (!file_exists($this->filemap)) { + return array(); + } + + $fp = @fopen($this->filemap, 'r'); + if (!$fp) { + return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg); + } + + clearstatcache(); + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + $fsize = filesize($this->filemap); + fclose($fp); + $data = file_get_contents($this->filemap); + set_magic_quotes_runtime($rt); + $tmp = unserialize($data); + if (!$tmp && $fsize > 7) { + return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data); + } + + $this->filemap_cache = $tmp; + return true; + } + + /** + * Lock the registry. * - * @static - * @return string The temporary directory on the system + * @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN. + * See flock manual for more information. + * + * @return bool TRUE on success, FALSE if locking failed, or a + * PEAR error if some other error occurs (such as the + * lock file not being writable). + * + * @access private */ - function tmpdir() + function _lock($mode = LOCK_EX) { - if (OS_WINDOWS) { - if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { - return $var; - } - if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) { - return $var; + if (stristr(php_uname(), 'Windows 9')) { + return true; + } + + if ($mode != LOCK_UN && is_resource($this->lock_fp)) { + // XXX does not check type of lock (LOCK_SH/LOCK_EX) + return true; + } + + if (!$this->_assertStateDir()) { + if ($mode == LOCK_EX) { + return $this->raiseError('Registry directory is not writeable by the current user'); } - if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) { - return $var; + + return true; + } + + $open_mode = 'w'; + // XXX People reported problems with LOCK_SH and 'w' + if ($mode === LOCK_SH || $mode === LOCK_UN) { + if (!file_exists($this->lockfile)) { + touch($this->lockfile); } - if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) { - return $var; + $open_mode = 'r'; + } + + if (!is_resource($this->lock_fp)) { + $this->lock_fp = @fopen($this->lockfile, $open_mode); + } + + if (!is_resource($this->lock_fp)) { + $this->lock_fp = null; + return $this->raiseError("could not create lock file" . + (isset($php_errormsg) ? ": " . $php_errormsg : "")); + } + + if (!(int)flock($this->lock_fp, $mode)) { + switch ($mode) { + case LOCK_SH: $str = 'shared'; break; + case LOCK_EX: $str = 'exclusive'; break; + case LOCK_UN: $str = 'unlock'; break; + default: $str = 'unknown'; break; } - return getenv('SystemRoot') . '\temp'; + + //is resource at this point, close it on error. + fclose($this->lock_fp); + $this->lock_fp = null; + return $this->raiseError("could not acquire $str lock ($this->lockfile)", + PEAR_REGISTRY_ERROR_LOCK); } - if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) { - return $var; + + return true; + } + + function _unlock() + { + $ret = $this->_lock(LOCK_UN); + if (is_resource($this->lock_fp)) { + fclose($this->lock_fp); } - return realpath('/tmp'); + + $this->lock_fp = null; + return $ret; + } + + function _packageExists($package, $channel = false) + { + return file_exists($this->_packageFileName($package, $channel)); } /** - * The "which" command (show the full path of a command) + * Determine whether a channel exists in the registry * - * @param string $program The command to search for - * @param mixed $fallback Value to return if $program is not found + * @param string Channel name + * @param bool if true, then aliases will be ignored + * @return boolean + */ + function _channelExists($channel, $noaliases = false) + { + $a = file_exists($this->_channelFileName($channel, $noaliases)); + if (!$a && $channel == 'pear.php.net') { + return true; + } + + if (!$a && $channel == 'pecl.php.net') { + return true; + } + + if (!$a && $channel == 'doc.php.net') { + return true; + } + + return $a; + } + + /** + * Determine whether a mirror exists within the deafult channel in the registry * - * @return mixed A string with the full path or false if not found - * @static - * @author Stig Bakken + * @param string Channel name + * @param string Mirror name + * + * @return boolean */ - function which($program, $fallback = false) + function _mirrorExists($channel, $mirror) { - // enforce API - if (!is_string($program) || '' == $program) { - return $fallback; + $data = $this->_channelInfo($channel); + if (!isset($data['servers']['mirror'])) { + return false; } - // full path given - if (basename($program) != $program) { - $path_elements[] = dirname($program); - $program = basename($program); - } else { - // Honor safe mode - if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) { - $path = getenv('PATH'); - if (!$path) { - $path = getenv('Path'); // some OSes are just stupid enough to do this - } + foreach ($data['servers']['mirror'] as $m) { + if ($m['attribs']['host'] == $mirror) { + return true; } - $path_elements = explode(PATH_SEPARATOR, $path); } - if (OS_WINDOWS) { - $exe_suffixes = getenv('PATHEXT') - ? explode(PATH_SEPARATOR, getenv('PATHEXT')) - : array('.exe','.bat','.cmd','.com'); - // allow passing a command.exe param - if (strpos($program, '.') !== false) { - array_unshift($exe_suffixes, ''); + return false; + } + + /** + * @param PEAR_ChannelFile Channel object + * @param donotuse + * @param string Last-Modified HTTP tag from remote request + * @return boolean|PEAR_Error True on creation, false if it already exists + */ + function _addChannel($channel, $update = false, $lastmodified = false) + { + if (!is_a($channel, 'PEAR_ChannelFile')) { + return false; + } + + if (!$channel->validate()) { + return false; + } + + if (file_exists($this->_channelFileName($channel->getName()))) { + if (!$update) { + return false; + } + + $checker = $this->_getChannel($channel->getName()); + if (PEAR::isError($checker)) { + return $checker; + } + + if ($channel->getAlias() != $checker->getAlias()) { + if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) { + @unlink($this->_getChannelAliasFileName($checker->getAlias())); + } } - // is_executable() is not available on windows for PHP4 - $pear_is_executable = (function_exists('is_executable')) ? 'is_executable' : 'is_file'; } else { - $exe_suffixes = array(''); - $pear_is_executable = 'is_executable'; + if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net', 'doc.php.net'))) { + return false; + } } - foreach ($exe_suffixes as $suff) { - foreach ($path_elements as $dir) { - $file = $dir . DIRECTORY_SEPARATOR . $program . $suff; - if (@$pear_is_executable($file)) { - return $file; - } + $ret = $this->_assertChannelDir(); + if (PEAR::isError($ret)) { + return $ret; + } + + $ret = $this->_assertChannelStateDir($channel->getName()); + if (PEAR::isError($ret)) { + return $ret; + } + + if ($channel->getAlias() != $channel->getName()) { + if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) && + $this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) { + $channel->setAlias($channel->getName()); + } + + if (!$this->hasWriteAccess()) { + return false; + } + + $fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w'); + if (!$fp) { + return false; } + + fwrite($fp, $channel->getName()); + fclose($fp); } - return $fallback; + + if (!$this->hasWriteAccess()) { + return false; + } + + $fp = @fopen($this->_channelFileName($channel->getName()), 'wb'); + if (!$fp) { + return false; + } + + $info = $channel->toArray(); + if ($lastmodified) { + $info['_lastmodified'] = $lastmodified; + } else { + $info['_lastmodified'] = date('r'); + } + + fwrite($fp, serialize($info)); + fclose($fp); + return true; } /** - * The "find" command - * - * Usage: - * - * System::find($dir); - * System::find("$dir -type d"); - * System::find("$dir -type f"); - * System::find("$dir -name *.php"); - * System::find("$dir -name *.php -name *.htm*"); - * System::find("$dir -maxdepth 1"); - * - * Params implmented: - * $dir -> Start the search at this directory - * -type d -> return only directories - * -type f -> return only files - * -maxdepth -> max depth of recursion - * -name -> search pattern (bash style). Multiple -name param allowed - * - * @param mixed Either array or string with the command line - * @return array Array of found files - * @static - * + * Deletion fails if there are any packages installed from the channel + * @param string|PEAR_ChannelFile channel name + * @return boolean|PEAR_Error True on deletion, false if it doesn't exist */ - function find($args) + function _deleteChannel($channel) { - if (!is_array($args)) { - $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); + if (!is_string($channel)) { + if (!is_a($channel, 'PEAR_ChannelFile')) { + return false; + } + + if (!$channel->validate()) { + return false; + } + $channel = $channel->getName(); } - $dir = realpath(array_shift($args)); - if (!$dir) { - return array(); + + if ($this->_getChannelFromAlias($channel) == '__uri') { + return false; } - $patterns = array(); - $depth = 0; - $do_files = $do_dirs = true; - $args_count = count($args); - for ($i = 0; $i < $args_count; $i++) { - switch ($args[$i]) { - case '-type': - if (in_array($args[$i+1], array('d', 'f'))) { - if ($args[$i+1] == 'd') { - $do_files = false; - } else { - $do_dirs = false; - } - } - $i++; - break; - case '-name': - $name = preg_quote($args[$i+1], '#'); - // our magic characters ? and * have just been escaped, - // so now we change the escaped versions to PCRE operators - $name = strtr($name, array('\?' => '.', '\*' => '.*')); - $patterns[] = '('.$name.')'; - $i++; - break; - case '-maxdepth': - $depth = $args[$i+1]; - break; + + if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { + return false; + } + + if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { + return false; + } + + if (!$this->_channelExists($channel)) { + return false; + } + + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + return false; + } + + $channel = $this->_getChannelFromAlias($channel); + if ($channel == 'pear.php.net') { + return false; + } + + $test = $this->_listChannelPackages($channel); + if (count($test)) { + return false; + } + + $test = @rmdir($this->_channelDirectoryName($channel)); + if (!$test) { + return false; + } + + $file = $this->_getChannelAliasFileName($this->_getAlias($channel)); + if (file_exists($file)) { + $test = @unlink($file); + if (!$test) { + return false; } } - $path = System::_dirToStruct($dir, $depth, 0, true); - if ($do_files && $do_dirs) { - $files = array_merge($path['files'], $path['dirs']); - } elseif ($do_dirs) { - $files = $path['dirs']; - } else { - $files = $path['files']; + + $file = $this->_channelFileName($channel); + $ret = true; + if (file_exists($file)) { + $ret = @unlink($file); } - if (count($patterns)) { - $dsq = preg_quote(DIRECTORY_SEPARATOR, '#'); - $pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#'; - $ret = array(); - $files_count = count($files); - for ($i = 0; $i < $files_count; $i++) { - // only search in the part of the file below the current directory - $filepart = basename($files[$i]); - if (preg_match($pattern, $filepart)) { - $ret[] = $files[$i]; + + return $ret; + } + + /** + * Determine whether a channel exists in the registry + * @param string Channel Alias + * @return boolean + */ + function _isChannelAlias($alias) + { + return file_exists($this->_getChannelAliasFileName($alias)); + } + + /** + * @param string|null + * @param string|null + * @param string|null + * @return array|null + * @access private + */ + function _packageInfo($package = null, $key = null, $channel = 'pear.php.net') + { + if ($package === null) { + if ($channel === null) { + $channels = $this->_listChannels(); + $ret = array(); + foreach ($channels as $channel) { + $channel = strtolower($channel); + $ret[$channel] = array(); + $packages = $this->_listPackages($channel); + foreach ($packages as $package) { + $ret[$channel][] = $this->_packageInfo($package, null, $channel); + } } + + return $ret; } - return $ret; + + $ps = $this->_listPackages($channel); + if (!count($ps)) { + return array(); + } + return array_map(array(&$this, '_packageInfo'), + $ps, array_fill(0, count($ps), null), + array_fill(0, count($ps), $channel)); } - return $files; + + $fp = $this->_openPackageFile($package, 'r', $channel); + if ($fp === null) { + return null; + } + + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + clearstatcache(); + $this->_closePackageFile($fp); + $data = file_get_contents($this->_packageFileName($package, $channel)); + set_magic_quotes_runtime($rt); + $data = unserialize($data); + if ($key === null) { + return $data; + } + + // compatibility for package.xml version 2.0 + if (isset($data['old'][$key])) { + return $data['old'][$key]; + } + + if (isset($data[$key])) { + return $data[$key]; + } + + return null; } -}PEAR-1.8.0/template.spec100777 764 764 3725 100777 10015 Summary: PEAR: @summary@ -Name: @rpm_package@ -Version: @version@ -Release: 1 -License: @release_license@ -Group: Development/Libraries -Source: http://@master_server@/get/@package@-%{version}.tgz -BuildRoot: %{_tmppath}/%{name}-root -URL: http://@master_server@/package/@package@ -Prefix: %{_prefix} -BuildArchitectures: @arch@ -@extra_headers@ -%description -@description@ + /** + * @param string Channel name + * @param bool whether to strictly retrieve info of channels, not just aliases + * @return array|null + */ + function _channelInfo($channel, $noaliases = false) + { + if (!$this->_channelExists($channel, $noaliases)) { + return null; + } -%prep -rm -rf %{buildroot}/* -%setup -c -T -# XXX Source files location is missing here in pear cmd -pear -v -c %{buildroot}/pearrc \ - -d php_dir=%{_libdir}/php/pear \ - -d doc_dir=/docs \ - -d bin_dir=%{_bindir} \ - -d data_dir=%{_libdir}/php/pear/data \ - -d test_dir=%{_libdir}/php/pear/tests \ - -d ext_dir=%{_libdir} \@extra_config@ - -s + $fp = $this->_openChannelFile($channel, 'r'); + if ($fp === null) { + return null; + } -%build -echo BuildRoot=%{buildroot} + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + clearstatcache(); + $this->_closeChannelFile($fp); + $data = file_get_contents($this->_channelFileName($channel)); + set_magic_quotes_runtime($rt); + $data = unserialize($data); + return $data; + } -%postun -# if refcount = 0 then package has been removed (not upgraded) -if [ "$1" -eq "0" ]; then - pear uninstall --nodeps -r @possible_channel@@package@ - rm @rpm_xml_dir@/@package@.xml -fi + function _listChannels() + { + $channellist = array(); + if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) { + return array('pear.php.net', 'pecl.php.net', 'doc.php.net', '__uri'); + } + $dp = opendir($this->channelsdir); + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } -%post -# if refcount = 2 then package has been upgraded -if [ "$1" -ge "2" ]; then - pear upgrade --nodeps -r @rpm_xml_dir@/@package@.xml -else - pear install --nodeps -r @rpm_xml_dir@/@package@.xml -fi + if ($ent == '__uri.reg') { + $channellist[] = '__uri'; + continue; + } -%install -pear -c %{buildroot}/pearrc install --nodeps -R %{buildroot} \ - $RPM_SOURCE_DIR/@package@-%{version}.tgz -rm %{buildroot}/pearrc -rm %{buildroot}/%{_libdir}/php/pear/.filemap -rm %{buildroot}/%{_libdir}/php/pear/.lock -rm -rf %{buildroot}/%{_libdir}/php/pear/.registry -if [ "@doc_files@" != "" ]; then - mv %{buildroot}/docs/@package@/* . - rm -rf %{buildroot}/docs -fi -mkdir -p %{buildroot}@rpm_xml_dir@ -tar -xzf $RPM_SOURCE_DIR/@package@-%{version}.tgz package@package2xml@.xml -cp -p package@package2xml@.xml %{buildroot}@rpm_xml_dir@/@package@.xml + $channellist[] = str_replace('_', '/', substr($ent, 0, -4)); + } -#rm -rf %{buildroot}/* -#pear -q install -R %{buildroot} -n package@package2xml@.xml -#mkdir -p %{buildroot}@rpm_xml_dir@ -#cp -p package@package2xml@.xml %{buildroot}@rpm_xml_dir@/@package@.xml + closedir($dp); + if (!in_array('pear.php.net', $channellist)) { + $channellist[] = 'pear.php.net'; + } -%files - %defattr(-,root,root) - %doc @doc_files@ - / -package.xml100664 764 764 70773 100664 6267 - - - PEAR - PEAR Base System - The PEAR package contains: - * the PEAR installer, for creating, distributing - and installing packages - * the PEAR_Exception PHP5 error handling mechanism - * the PEAR_ErrorStack advanced error handling mechanism - * the PEAR_Error error handling mechanism - * the OS_Guess class for retrieving info about the OS - where PHP is running on - * the System class for quick handling of common operations - with files and directories - * the PEAR base class + if (!in_array('pecl.php.net', $channellist)) { + $channellist[] = 'pecl.php.net'; + } - Features in a nutshell: - * full support for channels - * pre-download dependency validation - * new package.xml 2.0 format allows tremendous flexibility while maintaining BC - * support for optional dependency groups and limited support for sub-packaging - * robust dependency support - * full dependency validation on uninstall - * remote install for hosts with only ftp access - no more problems with + if (!in_array('doc.php.net', $channellist)) { + $channellist[] = 'doc.php.net'; + } + + + if (!in_array('__uri', $channellist)) { + $channellist[] = '__uri'; + } + + natsort($channellist); + return $channellist; + } + + function _listPackages($channel = false) + { + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_listChannelPackages($channel); + } + + if (!file_exists($this->statedir) || !is_dir($this->statedir)) { + return array(); + } + + $pkglist = array(); + $dp = opendir($this->statedir); + if (!$dp) { + return $pkglist; + } + + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + + $pkglist[] = substr($ent, 0, -4); + } + closedir($dp); + return $pkglist; + } + + function _listChannelPackages($channel) + { + $pkglist = array(); + if (!file_exists($this->_channelDirectoryName($channel)) || + !is_dir($this->_channelDirectoryName($channel))) { + return array(); + } + + $dp = opendir($this->_channelDirectoryName($channel)); + if (!$dp) { + return $pkglist; + } + + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; + } + $pkglist[] = substr($ent, 0, -4); + } + + closedir($dp); + return $pkglist; + } + + function _listAllPackages() + { + $ret = array(); + foreach ($this->_listChannels() as $channel) { + $ret[$channel] = $this->_listPackages($channel); + } + + return $ret; + } + + /** + * Add an installed package to the registry + * @param string package name + * @param array package info (parsed by PEAR_Common::infoFrom*() methods) + * @return bool success of saving + * @access private + */ + function _addPackage($package, $info) + { + if ($this->_packageExists($package)) { + return false; + } + + $fp = $this->_openPackageFile($package, 'wb'); + if ($fp === null) { + return false; + } + + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + if (isset($info['filelist'])) { + $this->_rebuildFileMap(); + } + + return true; + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return bool + * @access private + */ + function _addPackage2($info) + { + if (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) { + return false; + } + + if (!$info->validate()) { + if (class_exists('PEAR_Common')) { + $ui = PEAR_Frontend::singleton(); + if ($ui) { + foreach ($info->getValidationWarnings() as $err) { + $ui->log($err['message'], true); + } + } + } + return false; + } + + $channel = $info->getChannel(); + $package = $info->getPackage(); + $save = $info; + if ($this->_packageExists($package, $channel)) { + return false; + } + + if (!$this->_channelExists($channel, true)) { + return false; + } + + $info = $info->toArray(true); + if (!$info) { + return false; + } + + $fp = $this->_openPackageFile($package, 'wb', $channel); + if ($fp === null) { + return false; + } + + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + $this->_rebuildFileMap(); + return true; + } + + /** + * @param string Package name + * @param array parsed package.xml 1.0 + * @param bool this parameter is only here for BC. Don't use it. + * @access private + */ + function _updatePackage($package, $info, $merge = true) + { + $oldinfo = $this->_packageInfo($package); + if (empty($oldinfo)) { + return false; + } + + $fp = $this->_openPackageFile($package, 'w'); + if ($fp === null) { + return false; + } + + if (is_object($info)) { + $info = $info->toArray(); + } + $info['_lastmodified'] = time(); + + $newinfo = $info; + if ($merge) { + $info = array_merge($oldinfo, $info); + } else { + $diff = $info; + } + + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + if (isset($newinfo['filelist'])) { + $this->_rebuildFileMap(); + } + + return true; + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return bool + * @access private + */ + function _updatePackage2($info) + { + if (!$this->_packageExists($info->getPackage(), $info->getChannel())) { + return false; + } + + $fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel()); + if ($fp === null) { + return false; + } + + $save = $info; + $info = $save->getArray(true); + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + $this->_rebuildFileMap(); + return true; + } + + /** + * @param string Package name + * @param string Channel name + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null + * @access private + */ + function &_getPackage($package, $channel = 'pear.php.net') + { + $info = $this->_packageInfo($package, null, $channel); + if ($info === null) { + return $info; + } + + $a = $this->_config; + if (!$a) { + $this->_config = &new PEAR_Config; + $this->_config->set('php_dir', $this->statedir); + } + + if (!class_exists('PEAR_PackageFile')) { + require_once 'PEAR/PackageFile.php'; + } + + $pkg = &new PEAR_PackageFile($this->_config); + $pf = &$pkg->fromArray($info); + return $pf; + } + + /** + * @param string channel name + * @param bool whether to strictly retrieve channel names + * @return PEAR_ChannelFile|PEAR_Error + * @access private + */ + function &_getChannel($channel, $noaliases = false) + { + $ch = false; + if ($this->_channelExists($channel, $noaliases)) { + $chinfo = $this->_channelInfo($channel, $noaliases); + if ($chinfo) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo); + } + } + + if ($ch) { + if ($ch->validate()) { + return $ch; + } + + foreach ($ch->getErrors(true) as $err) { + $message = $err['message'] . "\n"; + } + + $ch = PEAR::raiseError($message); + return $ch; + } + + if ($this->_getChannelFromAlias($channel) == 'pear.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setServer('pear.php.net'); + $pear_channel->setAlias('pear'); + $pear_channel->setSummary('PHP Extension and Application Repository'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/'); + return $pear_channel; + } + + if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setServer('pecl.php.net'); + $pear_channel->setAlias('pecl'); + $pear_channel->setSummary('PHP Extension Community Library'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); + $pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); + return $pear_channel; + } + + if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $doc_channel = new PEAR_ChannelFile; + $doc_channel->setServer('doc.php.net'); + $doc_channel->setAlias('phpdocs'); + $doc_channel->setSummary('PHP Documentation Team'); + $doc_channel->setDefaultPEARProtocols(); + $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/'); + return $doc_channel; + } + + + if ($this->_getChannelFromAlias($channel) == '__uri') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'PEAR/ChannelFile.php'; + } + + $private = new PEAR_ChannelFile; + $private->setName('__uri'); + $private->setDefaultPEARProtocols(); + $private->setBaseURL('REST1.0', '****'); + $private->setSummary('Pseudo-channel for static packages'); + return $private; + } + + return $ch; + } + + /** + * @param string Package name + * @param string Channel name + * @return bool + */ + function packageExists($package, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_packageExists($package, $channel); + $this->_unlock(); + return $ret; + } + + // }}} + + // {{{ channelExists() + + /** + * @param string channel name + * @param bool if true, then aliases will be ignored + * @return bool + */ + function channelExists($channel, $noaliases = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_channelExists($channel, $noaliases); + $this->_unlock(); + return $ret; + } + + // }}} + + /** + * @param string channel name mirror is in + * @param string mirror name + * + * @return bool + */ + function mirrorExists($channel, $mirror) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + + $ret = $this->_mirrorExists($channel, $mirror); + $this->_unlock(); + return $ret; + } + + // {{{ isAlias() + + /** + * Determines whether the parameter is an alias of a channel + * @param string + * @return bool + */ + function isAlias($alias) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_isChannelAlias($alias); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ packageInfo() + + /** + * @param string|null + * @param string|null + * @param string + * @return array|null + */ + function packageInfo($package = null, $key = null, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_packageInfo($package, $key, $channel); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ channelInfo() + + /** + * Retrieve a raw array of channel data. + * + * Do not use this, instead use {@link getChannel()} for normal + * operations. Array structure is undefined in this method + * @param string channel name + * @param bool whether to strictly retrieve information only on non-aliases + * @return array|null|PEAR_Error + */ + function channelInfo($channel = null, $noaliases = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_channelInfo($channel, $noaliases); + $this->_unlock(); + return $ret; + } + + // }}} + + /** + * @param string + */ + function channelName($channel) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_getChannelFromAlias($channel); + $this->_unlock(); + return $ret; + } + + /** + * @param string + */ + function channelAlias($channel) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_getAlias($channel); + $this->_unlock(); + return $ret; + } + // {{{ listPackages() + + function listPackages($channel = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listPackages($channel); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ listAllPackages() + + function listAllPackages() + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listAllPackages(); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ listChannel() + + function listChannels() + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listChannels(); + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ addPackage() + + /** + * Add an installed package to the registry + * @param string|PEAR_PackageFile_v1|PEAR_PackageFile_v2 package name or object + * that will be passed to {@link addPackage2()} + * @param array package info (parsed by PEAR_Common::infoFrom*() methods) + * @return bool success of saving + */ + function addPackage($package, $info) + { + if (is_object($info)) { + return $this->addPackage2($info); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_addPackage($package, $info); + $this->_unlock(); + if ($ret) { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->_config); + $pf->fromArray($info); + $this->_dependencyDB->uninstallPackage($pf); + $this->_dependencyDB->installPackage($pf); + } + return $ret; + } + + // }}} + // {{{ addPackage2() + + function addPackage2($info) + { + if (!is_object($info)) { + return $this->addPackage($info['package'], $info); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_addPackage2($info); + $this->_unlock(); + if ($ret) { + $this->_dependencyDB->uninstallPackage($info); + $this->_dependencyDB->installPackage($info); + } + return $ret; + } + + // }}} + // {{{ updateChannel() + + /** + * For future expandibility purposes, separate this + * @param PEAR_ChannelFile + */ + function updateChannel($channel, $lastmodified = null) + { + if ($channel->getName() == '__uri') { + return false; + } + return $this->addChannel($channel, $lastmodified, true); + } + + // }}} + // {{{ deleteChannel() + + /** + * Deletion fails if there are any packages installed from the channel + * @param string|PEAR_ChannelFile channel name + * @return boolean|PEAR_Error True on deletion, false if it doesn't exist + */ + function deleteChannel($channel) + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $ret = $this->_deleteChannel($channel); + $this->_unlock(); + if ($ret && is_a($this->_config, 'PEAR_Config')) { + $this->_config->setChannels($this->listChannels()); + } + + return $ret; + } + + // }}} + // {{{ addChannel() + + /** + * @param PEAR_ChannelFile Channel object + * @param string Last-Modified header from HTTP for caching + * @return boolean|PEAR_Error True on creation, false if it already exists + */ + function addChannel($channel, $lastmodified = false, $update = false) + { + if (!is_a($channel, 'PEAR_ChannelFile') || !$channel->validate()) { + return false; + } + + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $ret = $this->_addChannel($channel, $update, $lastmodified); + $this->_unlock(); + if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) { + $this->_config->setChannels($this->listChannels()); + } + + return $ret; + } + + // }}} + // {{{ deletePackage() + + function deletePackage($package, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $file = $this->_packageFileName($package, $channel); + $ret = file_exists($file) ? @unlink($file) : false; + $this->_rebuildFileMap(); + $this->_unlock(); + $p = array('channel' => $channel, 'package' => $package); + $this->_dependencyDB->uninstallPackage($p); + return $ret; + } + + // }}} + // {{{ updatePackage() + + function updatePackage($package, $info, $merge = true) + { + if (is_object($info)) { + return $this->updatePackage2($info, $merge); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_updatePackage($package, $info, $merge); + $this->_unlock(); + if ($ret) { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->_config); + $pf->fromArray($this->packageInfo($package)); + $this->_dependencyDB->uninstallPackage($pf); + $this->_dependencyDB->installPackage($pf); + } + return $ret; + } + + // }}} + // {{{ updatePackage2() + + function updatePackage2($info) + { + + if (!is_object($info)) { + return $this->updatePackage($info['package'], $info, $merge); + } + + if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) { + return false; + } + + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + + $ret = $this->_updatePackage2($info); + $this->_unlock(); + if ($ret) { + $this->_dependencyDB->uninstallPackage($info); + $this->_dependencyDB->installPackage($info); + } + + return $ret; + } + + // }}} + // {{{ getChannel() + /** + * @param string channel name + * @param bool whether to strictly return raw channels (no aliases) + * @return PEAR_ChannelFile|PEAR_Error + */ + function &getChannel($channel, $noaliases = false) + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = &$this->_getChannel($channel, $noaliases); + $this->_unlock(); + if (!$ret) { + return PEAR::raiseError('Unknown channel: ' . $channel); + } + return $ret; + } + + // }}} + // {{{ getPackage() + /** + * @param string package name + * @param string channel name + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null + */ + function &getPackage($package, $channel = 'pear.php.net') + { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $pf = &$this->_getPackage($package, $channel); + $this->_unlock(); + return $pf; + } + + // }}} + + /** + * Get PEAR_PackageFile_v[1/2] objects representing the contents of + * a dependency group that are installed. + * + * This is used at uninstall-time + * @param array + * @return array|false + */ + function getInstalledGroup($group) + { + $ret = array(); + if (isset($group['package'])) { + if (!isset($group['package'][0])) { + $group['package'] = array($group['package']); + } + foreach ($group['package'] as $package) { + $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; + $p = &$this->getPackage($package['name'], $depchannel); + if ($p) { + $save = &$p; + $ret[] = &$save; + } + } + } + if (isset($group['subpackage'])) { + if (!isset($group['subpackage'][0])) { + $group['subpackage'] = array($group['subpackage']); + } + foreach ($group['subpackage'] as $package) { + $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; + $p = &$this->getPackage($package['name'], $depchannel); + if ($p) { + $save = &$p; + $ret[] = &$save; + } + } + } + if (!count($ret)) { + return false; + } + return $ret; + } + + // {{{ getChannelValidator() + /** + * @param string channel name + * @return PEAR_Validate|false + */ + function &getChannelValidator($channel) + { + $chan = $this->getChannel($channel); + if (PEAR::isError($chan)) { + return $chan; + } + $val = $chan->getValidationObject(); + return $val; + } + // }}} + // {{{ getChannels() + /** + * @param string channel name + * @return array an array of PEAR_ChannelFile objects representing every installed channel + */ + function &getChannels() + { + $ret = array(); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + foreach ($this->_listChannels() as $channel) { + $e = &$this->_getChannel($channel); + if (!$e || PEAR::isError($e)) { + continue; + } + $ret[] = $e; + } + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ checkFileMap() + + /** + * Test whether a file or set of files belongs to a package. + * + * If an array is passed in + * @param string|array file path, absolute or relative to the pear + * install dir + * @param string|array name of PEAR package or array('package' => name, 'channel' => + * channel) of a package that will be ignored + * @param string API version - 1.1 will exclude any files belonging to a package + * @param array private recursion variable + * @return array|false which package and channel the file belongs to, or an empty + * string if the file does not belong to an installed package, + * or belongs to the second parameter's package + */ + function checkFileMap($path, $package = false, $api = '1.0', $attrs = false) + { + if (is_array($path)) { + static $notempty; + if (empty($notempty)) { + if (!class_exists('PEAR_Installer_Role')) { + require_once 'PEAR/Installer/Role.php'; + } + $notempty = create_function('$a','return !empty($a);'); + } + $package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1])) + : strtolower($package); + $pkgs = array(); + foreach ($path as $name => $attrs) { + if (is_array($attrs)) { + if (isset($attrs['install-as'])) { + $name = $attrs['install-as']; + } + if (!in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) { + // these are not installed + continue; + } + if (!in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) { + $attrs['baseinstalldir'] = is_array($package) ? $package[1] : $package; + } + if (isset($attrs['baseinstalldir'])) { + $name = $attrs['baseinstalldir'] . DIRECTORY_SEPARATOR . $name; + } + } + $pkgs[$name] = $this->checkFileMap($name, $package, $api, $attrs); + if (PEAR::isError($pkgs[$name])) { + return $pkgs[$name]; + } + } + return array_filter($pkgs, $notempty); + } + if (empty($this->filemap_cache)) { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $err = $this->_readFileMap(); + $this->_unlock(); + if (PEAR::isError($err)) { + return $err; + } + } + if (!$attrs) { + $attrs = array('role' => 'php'); // any old call would be for PHP role only + } + if (isset($this->filemap_cache[$attrs['role']][$path])) { + if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { + return false; + } + return $this->filemap_cache[$attrs['role']][$path]; + } + $l = strlen($this->install_dir); + if (substr($path, 0, $l) == $this->install_dir) { + $path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l)); + } + if (isset($this->filemap_cache[$attrs['role']][$path])) { + if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { + return false; + } + return $this->filemap_cache[$attrs['role']][$path]; + } + return false; + } + + // }}} + // {{{ flush() + /** + * Force a reload of the filemap + * @since 1.5.0RC3 + */ + function flushFileMap() + { + $this->filemap_cache = null; + clearstatcache(); // ensure that the next read gets the full, current filemap + } + + // }}} + // {{{ apiVersion() + /** + * Get the expected API version. Channels API is version 1.1, as it is backwards + * compatible with 1.0 + * @return string + */ + function apiVersion() + { + return '1.1'; + } + // }}} + + + /** + * Parse a package name, or validate a parsed package name array + * @param string|array pass in an array of format + * array( + * 'package' => 'pname', + * ['channel' => 'channame',] + * ['version' => 'version',] + * ['state' => 'state',] + * ['group' => 'groupname']) + * or a string of format + * [channel://][channame/]pname[-version|-state][/group=groupname] + * @return array|PEAR_Error + */ + function parsePackageName($param, $defaultchannel = 'pear.php.net') + { + $saveparam = $param; + if (is_array($param)) { + // convert to string for error messages + $saveparam = $this->parsedPackageNameToString($param); + // process the array + if (!isset($param['package'])) { + return PEAR::raiseError('parsePackageName(): array $param ' . + 'must contain a valid package name in index "param"', + 'package', null, null, $param); + } + if (!isset($param['uri'])) { + if (!isset($param['channel'])) { + $param['channel'] = $defaultchannel; + } + } else { + $param['channel'] = '__uri'; + } + } else { + $components = @parse_url((string) $param); + if (isset($components['scheme'])) { + if ($components['scheme'] == 'http') { + // uri package + $param = array('uri' => $param, 'channel' => '__uri'); + } elseif($components['scheme'] != 'channel') { + return PEAR::raiseError('parsePackageName(): only channel:// uris may ' . + 'be downloaded, not "' . $param . '"', 'invalid', null, null, $param); + } + } + if (!isset($components['path'])) { + return PEAR::raiseError('parsePackageName(): array $param ' . + 'must contain a valid package name in "' . $param . '"', + 'package', null, null, $param); + } + if (isset($components['host'])) { + // remove the leading "/" + $components['path'] = substr($components['path'], 1); + } + if (!isset($components['scheme'])) { + if (strpos($components['path'], '/') !== false) { + if ($components['path']{0} == '/') { + return PEAR::raiseError('parsePackageName(): this is not ' . + 'a package name, it begins with "/" in "' . $param . '"', + 'invalid', null, null, $param); + } + $parts = explode('/', $components['path']); + $components['host'] = array_shift($parts); + if (count($parts) > 1) { + $components['path'] = array_pop($parts); + $components['host'] .= '/' . implode('/', $parts); + } else { + $components['path'] = implode('/', $parts); + } + } else { + $components['host'] = $defaultchannel; + } + } else { + if (strpos($components['path'], '/')) { + $parts = explode('/', $components['path']); + $components['path'] = array_pop($parts); + $components['host'] .= '/' . implode('/', $parts); + } + } + + if (is_array($param)) { + $param['package'] = $components['path']; + } else { + $param = array( + 'package' => $components['path'] + ); + if (isset($components['host'])) { + $param['channel'] = $components['host']; + } + } + if (isset($components['fragment'])) { + $param['group'] = $components['fragment']; + } + if (isset($components['user'])) { + $param['user'] = $components['user']; + } + if (isset($components['pass'])) { + $param['pass'] = $components['pass']; + } + if (isset($components['query'])) { + parse_str($components['query'], $param['opts']); + } + // check for extension + $pathinfo = pathinfo($param['package']); + if (isset($pathinfo['extension']) && + in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) { + $param['extension'] = $pathinfo['extension']; + $param['package'] = substr($pathinfo['basename'], 0, + strlen($pathinfo['basename']) - 4); + } + // check for version + if (strpos($param['package'], '-')) { + $test = explode('-', $param['package']); + if (count($test) != 2) { + return PEAR::raiseError('parsePackageName(): only one version/state ' . + 'delimiter "-" is allowed in "' . $saveparam . '"', + 'version', null, null, $param); + } + list($param['package'], $param['version']) = $test; + } + } + // validation + $info = $this->channelExists($param['channel']); + if (PEAR::isError($info)) { + return $info; + } + if (!$info) { + return PEAR::raiseError('unknown channel "' . $param['channel'] . + '" in "' . $saveparam . '"', 'channel', null, null, $param); + } + $chan = $this->getChannel($param['channel']); + if (PEAR::isError($chan)) { + return $chan; + } + if (!$chan) { + return PEAR::raiseError("Exception: corrupt registry, could not " . + "retrieve channel " . $param['channel'] . " information", + 'registry', null, null, $param); + } + $param['channel'] = $chan->getName(); + $validate = $chan->getValidationObject(); + $vpackage = $chan->getValidationPackage(); + // validate package name + if (!$validate->validPackageName($param['package'], $vpackage['_content'])) { + return PEAR::raiseError('parsePackageName(): invalid package name "' . + $param['package'] . '" in "' . $saveparam . '"', + 'package', null, null, $param); + } + if (isset($param['group'])) { + if (!PEAR_Validate::validGroupName($param['group'])) { + return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] . + '" is not a valid group name in "' . $saveparam . '"', 'group', null, null, + $param); + } + } + if (isset($param['state'])) { + if (!in_array(strtolower($param['state']), $validate->getValidStates())) { + return PEAR::raiseError('parsePackageName(): state "' . $param['state'] + . '" is not a valid state in "' . $saveparam . '"', + 'state', null, null, $param); + } + } + if (isset($param['version'])) { + if (isset($param['state'])) { + return PEAR::raiseError('parsePackageName(): cannot contain both ' . + 'a version and a stability (state) in "' . $saveparam . '"', + 'version/state', null, null, $param); + } + // check whether version is actually a state + if (in_array(strtolower($param['version']), $validate->getValidStates())) { + $param['state'] = strtolower($param['version']); + unset($param['version']); + } else { + if (!$validate->validVersion($param['version'])) { + return PEAR::raiseError('parsePackageName(): "' . $param['version'] . + '" is neither a valid version nor a valid state in "' . + $saveparam . '"', 'version/state', null, null, $param); + } + } + } + return $param; + } + + /** + * @param array + * @return string + */ + function parsedPackageNameToString($parsed, $brief = false) + { + if (is_string($parsed)) { + return $parsed; + } + if (is_object($parsed)) { + $p = $parsed; + $parsed = array( + 'package' => $p->getPackage(), + 'channel' => $p->getChannel(), + 'version' => $p->getVersion(), + ); + } + if (isset($parsed['uri'])) { + return $parsed['uri']; + } + if ($brief) { + if ($channel = $this->channelAlias($parsed['channel'])) { + return $channel . '/' . $parsed['package']; + } + } + $upass = ''; + if (isset($parsed['user'])) { + $upass = $parsed['user']; + if (isset($parsed['pass'])) { + $upass .= ':' . $parsed['pass']; + } + $upass = "$upass@"; + } + $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package']; + if (isset($parsed['version']) || isset($parsed['state'])) { + $ver = isset($parsed['version']) ? $parsed['version'] : ''; + $ver .= isset($parsed['state']) ? $parsed['state'] : ''; + $ret .= '-' . $ver; + } + if (isset($parsed['extension'])) { + $ret .= '.' . $parsed['extension']; + } + if (isset($parsed['opts'])) { + $ret .= '?'; + foreach ($parsed['opts'] as $name => $value) { + $parsed['opts'][$name] = "$name=$value"; + } + $ret .= implode('&', $parsed['opts']); + } + if (isset($parsed['group'])) { + $ret .= '#' . $parsed['group']; + } + return $ret; + } +}PEAR-1.9.0/PEAR/REST.php100664 764 764 36073 100664 7354 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: REST.php 286489 2009-07-29 05:59:08Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * For downloading xml files + */ +require_once 'PEAR.php'; +require_once 'PEAR/XMLParser.php'; + +/** + * Intelligently retrieve data, following hyperlinks if necessary, and re-directing + * as well + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_REST +{ + var $config; + var $_options; + + function PEAR_REST(&$config, $options = array()) + { + $this->config = &$config; + $this->_options = $options; + } + + /** + * Retrieve REST data, but always retrieve the local cache if it is available. + * + * This is useful for elements that should never change, such as information on a particular + * release + * @param string full URL to this resource + * @param array|false contents of the accept-encoding header + * @param boolean if true, xml will be returned as a string, otherwise, xml will be + * parsed using PEAR_XMLParser + * @return string|array + */ + function retrieveCacheFirst($url, $accept = false, $forcestring = false, $channel = false) + { + $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . + md5($url) . 'rest.cachefile'; + + if (file_exists($cachefile)) { + return unserialize(implode('', file($cachefile))); + } + + return $this->retrieveData($url, $accept, $forcestring, $channel); + } + + /** + * Retrieve a remote REST resource + * @param string full URL to this resource + * @param array|false contents of the accept-encoding header + * @param boolean if true, xml will be returned as a string, otherwise, xml will be + * parsed using PEAR_XMLParser + * @return string|array + */ + function retrieveData($url, $accept = false, $forcestring = false, $channel = false) + { + $cacheId = $this->getCacheId($url); + if ($ret = $this->useLocalCache($url, $cacheId)) { + return $ret; + } + + $file = $trieddownload = false; + if (!isset($this->_options['offline'])) { + $trieddownload = true; + $file = $this->downloadHttp($url, $cacheId ? $cacheId['lastChange'] : false, $accept, $channel); + } + + if (PEAR::isError($file)) { + if ($file->getCode() !== -9276) { + return $file; + } + + $trieddownload = false; + $file = false; // use local copy if available on socket connect error + } + + if (!$file) { + $ret = $this->getCache($url); + if (!PEAR::isError($ret) && $trieddownload) { + // reset the age of the cache if the server says it was unmodified + $this->saveCache($url, $ret, null, true, $cacheId); + } + + return $ret; + } + + if (is_array($file)) { + $headers = $file[2]; + $lastmodified = $file[1]; + $content = $file[0]; + } else { + $headers = array(); + $lastmodified = false; + $content = $file; + } + + if ($forcestring) { + $this->saveCache($url, $content, $lastmodified, false, $cacheId); + return $content; + } + + if (isset($headers['content-type'])) { + switch ($headers['content-type']) { + case 'text/xml' : + case 'application/xml' : + case 'text/plain' : + if ($headers['content-type'] === 'text/plain') { + $check = substr($content, 0, 5); + if ($check !== 'parse($content); + PEAR::popErrorHandling(); + if (PEAR::isError($err)) { + return PEAR::raiseError('Invalid xml downloaded from "' . $url . '": ' . + $err->getMessage()); + } + $content = $parser->getData(); + case 'text/html' : + default : + // use it as a string + } + } else { + // assume XML + $parser = new PEAR_XMLParser; + $parser->parse($content); + $content = $parser->getData(); + } + + $this->saveCache($url, $content, $lastmodified, false, $cacheId); + return $content; + } + + function useLocalCache($url, $cacheid = null) + { + if ($cacheid === null) { + $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . + md5($url) . 'rest.cacheid'; + if (!file_exists($cacheidfile)) { + return false; + } + + $cacheid = unserialize(implode('', file($cacheidfile))); + } + + $cachettl = $this->config->get('cache_ttl'); + // If cache is newer than $cachettl seconds, we use the cache! + if (time() - $cacheid['age'] < $cachettl) { + return $this->getCache($url); + } + + return false; + } + + function getCacheId($url) + { + $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . + md5($url) . 'rest.cacheid'; + + if (!file_exists($cacheidfile)) { + return false; + } + + $ret = unserialize(implode('', file($cacheidfile))); + return $ret; + } + + function getCache($url) + { + $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . + md5($url) . 'rest.cachefile'; + + if (!file_exists($cachefile)) { + return PEAR::raiseError('No cached content available for "' . $url . '"'); + } + + return unserialize(implode('', file($cachefile))); + } + + /** + * @param string full URL to REST resource + * @param string original contents of the REST resource + * @param array HTTP Last-Modified and ETag headers + * @param bool if true, then the cache id file should be regenerated to + * trigger a new time-to-live value + */ + function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null) + { + $cachedir = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . md5($url); + $cacheidfile = $cachedir . 'rest.cacheid'; + $cachefile = $cachedir . 'rest.cachefile'; + + if ($cacheid === null && $nochange) { + $cacheid = unserialize(implode('', file($cacheidfile))); + } + + $fp = @fopen($cacheidfile, 'wb'); + if (!$fp) { + $cache_dir = $this->config->get('cache_dir'); + if (is_dir($cache_dir)) { + return false; + } + + System::mkdir(array('-p', $cache_dir)); + $fp = @fopen($cacheidfile, 'wb'); + if (!$fp) { + return false; + } + } + + if ($nochange) { + fwrite($fp, serialize(array( + 'age' => time(), + 'lastChange' => $cacheid['lastChange'], + )) + ); + + fclose($fp); + return true; + } + + fwrite($fp, serialize(array( + 'age' => time(), + 'lastChange' => $lastmodified, + )) + ); + + fclose($fp); + $fp = @fopen($cachefile, 'wb'); + if (!$fp) { + if (file_exists($cacheidfile)) { + @unlink($cacheidfile); + } + + return false; + } + + fwrite($fp, serialize($contents)); + fclose($fp); + return true; + } + + /** + * Efficiently Download a file through HTTP. Returns downloaded file as a string in-memory + * This is best used for small files + * + * If an HTTP proxy has been configured (http_proxy PEAR_Config + * setting), the proxy will be used. + * + * @param string $url the URL to download + * @param string $save_dir directory to save file in + * @param false|string|array $lastmodified header values to check against for caching + * use false to return the header values from this download + * @param false|array $accept Accept headers to send + * @return string|array Returns the contents of the downloaded file or a PEAR + * error on failure. If the error is caused by + * socket-related errors, the error object will + * have the fsockopen error code available through + * getCode(). If caching is requested, then return the header + * values. + * + * @access public + */ + function downloadHttp($url, $lastmodified = null, $accept = false, $channel = false) + { + static $redirect = 0; + // always reset , so we are clean case of error + $wasredirect = $redirect; + $redirect = 0; + + $info = parse_url($url); + if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) { + return PEAR::raiseError('Cannot download non-http URL "' . $url . '"'); + } + + if (!isset($info['host'])) { + return PEAR::raiseError('Cannot download from non-URL "' . $url . '"'); + } + + $host = isset($info['host']) ? $info['host'] : null; + $port = isset($info['port']) ? $info['port'] : null; + $path = isset($info['path']) ? $info['path'] : null; + $schema = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http'; + + $proxy_host = $proxy_port = $proxy_user = $proxy_pass = ''; + if ($this->config->get('http_proxy')&& + $proxy = parse_url($this->config->get('http_proxy')) + ) { + $proxy_host = isset($proxy['host']) ? $proxy['host'] : null; + if ($schema === 'https') { + $proxy_host = 'ssl://' . $proxy_host; + } + + $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080; + $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null; + $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null; + $proxy_schema = (isset($proxy['scheme']) && $proxy['scheme'] == 'https') ? 'https' : 'http'; + } + + if (empty($port)) { + $port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80; + } + + if (isset($proxy['host'])) { + $request = "GET $url HTTP/1.1\r\n"; + } else { + $request = "GET $path HTTP/1.1\r\n"; + } + + $request .= "Host: $host:$port\r\n"; + $ifmodifiedsince = ''; + if (is_array($lastmodified)) { + if (isset($lastmodified['Last-Modified'])) { + $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n"; + } + + if (isset($lastmodified['ETag'])) { + $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n"; + } + } else { + $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : ''); + } + + $request .= $ifmodifiedsince . + "User-Agent: PEAR/1.9.0/PHP/" . PHP_VERSION . "\r\n"; + + $username = $this->config->get('username', null, $channel); + $password = $this->config->get('password', null, $channel); + + if ($username && $password) { + $tmp = base64_encode("$username:$password"); + $request .= "Authorization: Basic $tmp\r\n"; + } + + if ($proxy_host != '' && $proxy_user != '') { + $request .= 'Proxy-Authorization: Basic ' . + base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n"; + } + + if ($accept) { + $request .= 'Accept: ' . implode(', ', $accept) . "\r\n"; + } + + $request .= "Accept-Encoding:\r\n"; + $request .= "Connection: close\r\n"; + $request .= "\r\n"; + + if ($proxy_host != '') { + $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr, 15); + if (!$fp) { + return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", -9276); + } + } else { + if ($schema === 'https') { + $host = 'ssl://' . $host; + } + + $fp = @fsockopen($host, $port, $errno, $errstr); + if (!$fp) { + return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); + } + } + + fwrite($fp, $request); + + $headers = array(); + $reply = 0; + while ($line = trim(fgets($fp, 1024))) { + if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) { + $headers[strtolower($matches[1])] = trim($matches[2]); + } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { + $reply = (int)$matches[1]; + if ($reply == 304 && ($lastmodified || ($lastmodified === false))) { + return false; + } + + if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) { + return PEAR::raiseError("File $schema://$host:$port$path not valid (received: $line)"); + } + } + } + + if ($reply != 200) { + if (!isset($headers['location'])) { + return PEAR::raiseError("File $schema://$host:$port$path not valid (redirected but no location)"); + } + + if ($wasredirect > 4) { + return PEAR::raiseError("File $schema://$host:$port$path not valid (redirection looped more than 5 times)"); + } + + $redirect = $wasredirect + 1; + return $this->downloadHttp($headers['location'], $lastmodified, $accept, $channel); + } + + $length = isset($headers['content-length']) ? $headers['content-length'] : -1; + + $data = ''; + while ($chunk = @fread($fp, 8192)) { + $data .= $chunk; + } + fclose($fp); + + if ($lastmodified === false || $lastmodified) { + if (isset($headers['etag'])) { + $lastmodified = array('ETag' => $headers['etag']); + } + + if (isset($headers['last-modified'])) { + if (is_array($lastmodified)) { + $lastmodified['Last-Modified'] = $headers['last-modified']; + } else { + $lastmodified = $headers['last-modified']; + } + } + + return array($data, $lastmodified, $headers); + } + + return $data; + } +}PEAR-1.9.0/PEAR/RunTest.php100664 764 764 105252 100664 10217 + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: RunTest.php 287447 2009-08-18 11:46:19Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.3.3 + */ + +/** + * for error handling + */ +require_once 'PEAR.php'; +require_once 'PEAR/Config.php'; + +define('DETAILED', 1); +putenv("PHP_PEAR_RUNTESTS=1"); + +/** + * Simplified version of PHP's test suite + * + * Try it with: + * + * $ php -r 'include "../PEAR/RunTest.php"; $t=new PEAR_RunTest; $o=$t->run("./pear_system.phpt");print_r($o);' + * + * + * @category pear + * @package PEAR + * @author Tomas V.V.Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.3.3 + */ +class PEAR_RunTest +{ + var $_headers = array(); + var $_logger; + var $_options; + var $_php; + var $tests_count; + var $xdebug_loaded; + /** + * Saved value of php executable, used to reset $_php when we + * have a test that uses cgi + * + * @var unknown_type + */ + var $_savephp; + var $ini_overwrites = array( + 'output_handler=', + 'open_basedir=', + 'safe_mode=0', + 'disable_functions=', + 'output_buffering=Off', + 'display_errors=1', + 'log_errors=0', + 'html_errors=0', + 'track_errors=1', + 'report_memleaks=0', + 'report_zend_debug=0', + 'docref_root=', + 'docref_ext=.html', + 'error_prepend_string=', + 'error_append_string=', + 'auto_prepend_file=', + 'auto_append_file=', + 'magic_quotes_runtime=0', + 'xdebug.default_enable=0', + 'allow_url_fopen=1', + ); + + /** + * An object that supports the PEAR_Common->log() signature, or null + * @param PEAR_Common|null + */ + function PEAR_RunTest($logger = null, $options = array()) + { + if (!defined('E_DEPRECATED')) { + define('E_DEPRECATED', 0); + } + if (!defined('E_STRICT')) { + define('E_STRICT', 0); + } + $this->ini_overwrites[] = 'error_reporting=' . (E_ALL & ~(E_DEPRECATED | E_STRICT)); + if (is_null($logger)) { + require_once 'PEAR/Common.php'; + $logger = new PEAR_Common; + } + $this->_logger = $logger; + $this->_options = $options; + + $conf = &PEAR_Config::singleton(); + $this->_php = $conf->get('php_bin'); + } + + /** + * Taken from php-src/run-tests.php + * + * @param string $commandline command name + * @param array $env + * @param string $stdin standard input to pass to the command + * @return unknown + */ + function system_with_timeout($commandline, $env = null, $stdin = null) + { + $data = ''; + if (version_compare(phpversion(), '5.0.0', '<')) { + $proc = proc_open($commandline, array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w') + ), $pipes); + } else { + $proc = proc_open($commandline, array( + 0 => array('pipe', 'r'), + 1 => array('pipe', 'w'), + 2 => array('pipe', 'w') + ), $pipes, null, $env, array('suppress_errors' => true)); + } + + if (!$proc) { + return false; + } + + if (is_string($stdin)) { + fwrite($pipes[0], $stdin); + } + fclose($pipes[0]); + + while (true) { + /* hide errors from interrupted syscalls */ + $r = $pipes; + $e = $w = null; + $n = @stream_select($r, $w, $e, 60); + + if ($n === 0) { + /* timed out */ + $data .= "\n ** ERROR: process timed out **\n"; + proc_terminate($proc); + return array(1234567890, $data); + } else if ($n > 0) { + $line = fread($pipes[1], 8192); + if (strlen($line) == 0) { + /* EOF */ + break; + } + $data .= $line; + } + } + if (function_exists('proc_get_status')) { + $stat = proc_get_status($proc); + if ($stat['signaled']) { + $data .= "\nTermsig=".$stat['stopsig']; + } + } + $code = proc_close($proc); + if (function_exists('proc_get_status')) { + $code = $stat['exitcode']; + } + return array($code, $data); + } + + /** + * Turns a PHP INI string into an array + * + * Turns -d "include_path=/foo/bar" into this: + * array( + * 'include_path' => array( + * 'operator' => '-d', + * 'value' => '/foo/bar', + * ) + * ) + * Works both with quotes and without + * + * @param string an PHP INI string, -d "include_path=/foo/bar" + * @return array + */ + function iniString2array($ini_string) + { + if (!$ini_string) { + return array(); + } + $split = preg_split('/[\s]|=/', $ini_string, -1, PREG_SPLIT_NO_EMPTY); + $key = $split[1][0] == '"' ? substr($split[1], 1) : $split[1]; + $value = $split[2][strlen($split[2]) - 1] == '"' ? substr($split[2], 0, -1) : $split[2]; + // FIXME review if this is really the struct to go with + $array = array($key => array('operator' => $split[0], 'value' => $value)); + return $array; + } + + function settings2array($settings, $ini_settings) + { + foreach ($settings as $setting) { + if (strpos($setting, '=') !== false) { + $setting = explode('=', $setting, 2); + $name = trim(strtolower($setting[0])); + $value = trim($setting[1]); + $ini_settings[$name] = $value; + } + } + return $ini_settings; + } + + function settings2params($ini_settings) + { + $settings = ''; + foreach ($ini_settings as $name => $value) { + if (is_array($value)) { + $operator = $value['operator']; + $value = $value['value']; + } else { + $operator = '-d'; + } + $value = addslashes($value); + $settings .= " $operator \"$name=$value\""; + } + return $settings; + } + + function _preparePhpBin($php, $file, $ini_settings) + { + $file = escapeshellarg($file); + // This was fixed in php 5.3 and is not needed after that + if (OS_WINDOWS && version_compare(PHP_VERSION, '5.3', '<')) { + $cmd = '"'.escapeshellarg($php).' '.$ini_settings.' -f ' . $file .'"'; + } else { + $cmd = $php . $ini_settings . ' -f ' . $file; + } + + return $cmd; + } + + function runPHPUnit($file, $ini_settings = '') + { + if (!file_exists($file) && file_exists(getcwd() . DIRECTORY_SEPARATOR . $file)) { + $file = realpath(getcwd() . DIRECTORY_SEPARATOR . $file); + } elseif (file_exists($file)) { + $file = realpath($file); + } + + $cmd = $this->_preparePhpBin($this->_php, $file, $ini_settings); + if (isset($this->_logger)) { + $this->_logger->log(2, 'Running command "' . $cmd . '"'); + } + + $savedir = getcwd(); // in case the test moves us around + chdir(dirname($file)); + echo `$cmd`; + chdir($savedir); + return 'PASSED'; // we have no way of knowing this information so assume passing + } + + /** + * Runs an individual test case. + * + * @param string The filename of the test + * @param array|string INI settings to be applied to the test run + * @param integer Number what the current running test is of the + * whole test suite being runned. + * + * @return string|object Returns PASSED, WARNED, FAILED depending on how the + * test came out. + * PEAR Error when the tester it self fails + */ + function run($file, $ini_settings = array(), $test_number = 1) + { + if (isset($this->_savephp)) { + $this->_php = $this->_savephp; + unset($this->_savephp); + } + if (empty($this->_options['cgi'])) { + // try to see if php-cgi is in the path + $res = $this->system_with_timeout('php-cgi -v'); + if (false !== $res && !(is_array($res) && $res === array(127, ''))) { + $this->_options['cgi'] = 'php-cgi'; + } + } + if (1 < $len = strlen($this->tests_count)) { + $test_number = str_pad($test_number, $len, ' ', STR_PAD_LEFT); + $test_nr = "[$test_number/$this->tests_count] "; + } else { + $test_nr = ''; + } + + $file = realpath($file); + $section_text = $this->_readFile($file); + if (PEAR::isError($section_text)) { + return $section_text; + } + + if (isset($section_text['POST_RAW']) && isset($section_text['UPLOAD'])) { + return PEAR::raiseError("Cannot contain both POST_RAW and UPLOAD in test file: $file"); + } + + $cwd = getcwd(); + + $pass_options = ''; + if (!empty($this->_options['ini'])) { + $pass_options = $this->_options['ini']; + } + + if (is_string($ini_settings)) { + $ini_settings = $this->iniString2array($ini_settings); + } + + $ini_settings = $this->settings2array($this->ini_overwrites, $ini_settings); + if ($section_text['INI']) { + if (strpos($section_text['INI'], '{PWD}') !== false) { + $section_text['INI'] = str_replace('{PWD}', dirname($file), $section_text['INI']); + } + $ini = preg_split( "/[\n\r]+/", $section_text['INI']); + $ini_settings = $this->settings2array($ini, $ini_settings); + } + $ini_settings = $this->settings2params($ini_settings); + $shortname = str_replace($cwd . DIRECTORY_SEPARATOR, '', $file); + + $tested = trim($section_text['TEST']); + $tested.= !isset($this->_options['simple']) ? "[$shortname]" : ' '; + + if (!empty($section_text['POST']) || !empty($section_text['POST_RAW']) || + !empty($section_text['UPLOAD']) || !empty($section_text['GET']) || + !empty($section_text['COOKIE']) || !empty($section_text['EXPECTHEADERS'])) { + if (empty($this->_options['cgi'])) { + if (!isset($this->_options['quiet'])) { + $this->_logger->log(0, "SKIP $test_nr$tested (reason: --cgi option needed for this test, type 'pear help run-tests')"); + } + if (isset($this->_options['tapoutput'])) { + return array('ok', ' # skip --cgi option needed for this test, "pear help run-tests" for info'); + } + return 'SKIPPED'; + } + $this->_savephp = $this->_php; + $this->_php = $this->_options['cgi']; + } + + $temp_dir = realpath(dirname($file)); + $main_file_name = basename($file, 'phpt'); + $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'diff'; + $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'log'; + $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'exp'; + $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'out'; + $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'mem'; + $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'php'; + $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'skip.php'; + $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name.'clean.php'; + $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.'); + + // unlink old test results + $this->_cleanupOldFiles($file); + + // Check if test should be skipped. + $res = $this->_runSkipIf($section_text, $temp_skipif, $tested, $ini_settings); + if (count($res) != 2) { + return $res; + } + $info = $res['info']; + $warn = $res['warn']; + + // We've satisfied the preconditions - run the test! + if (isset($this->_options['coverage']) && $this->xdebug_loaded) { + $xdebug_file = $temp_dir . DIRECTORY_SEPARATOR . $main_file_name . 'xdebug'; + $text = '"; + + $len_f = 5; + if (substr($section_text['FILE'], 0, 5) != 'save_text($temp_file, $text); + } else { + $this->save_text($temp_file, $section_text['FILE']); + } + + $args = $section_text['ARGS'] ? ' -- '.$section_text['ARGS'] : ''; + $cmd = $this->_preparePhpBin($this->_php, $temp_file, $ini_settings); + $cmd.= "$args 2>&1"; + if (isset($this->_logger)) { + $this->_logger->log(2, 'Running command "' . $cmd . '"'); + } + + // Reset environment from any previous test. + $env = $this->_resetEnv($section_text, $temp_file); + + $section_text = $this->_processUpload($section_text, $file); + if (PEAR::isError($section_text)) { + return $section_text; + } + + if (array_key_exists('POST_RAW', $section_text) && !empty($section_text['POST_RAW'])) { + $post = trim($section_text['POST_RAW']); + $raw_lines = explode("\n", $post); + + $request = ''; + $started = false; + foreach ($raw_lines as $i => $line) { + if (empty($env['CONTENT_TYPE']) && + preg_match('/^Content-Type:(.*)/i', $line, $res)) { + $env['CONTENT_TYPE'] = trim(str_replace("\r", '', $res[1])); + continue; + } + if ($started) { + $request .= "\n"; + } + $started = true; + $request .= $line; + } + + $env['CONTENT_LENGTH'] = strlen($request); + $env['REQUEST_METHOD'] = 'POST'; + + $this->save_text($tmp_post, $request); + $cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post"; + } elseif (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) { + $post = trim($section_text['POST']); + $this->save_text($tmp_post, $post); + $content_length = strlen($post); + + $env['REQUEST_METHOD'] = 'POST'; + $env['CONTENT_TYPE'] = 'application/x-www-form-urlencoded'; + $env['CONTENT_LENGTH'] = $content_length; + + $cmd = "$this->_php$pass_options$ini_settings \"$temp_file\" 2>&1 < $tmp_post"; + } else { + $env['REQUEST_METHOD'] = 'GET'; + $env['CONTENT_TYPE'] = ''; + $env['CONTENT_LENGTH'] = ''; + } + + if (OS_WINDOWS && isset($section_text['RETURNS'])) { + ob_start(); + system($cmd, $return_value); + $out = ob_get_contents(); + ob_end_clean(); + $section_text['RETURNS'] = (int) trim($section_text['RETURNS']); + $returnfail = ($return_value != $section_text['RETURNS']); + } else { + $returnfail = false; + $stdin = isset($section_text['STDIN']) ? $section_text['STDIN'] : null; + $out = $this->system_with_timeout($cmd, $env, $stdin); + $return_value = $out[0]; + $out = $out[1]; + } + + $output = preg_replace('/\r\n/', "\n", trim($out)); + + if (isset($tmp_post) && realpath($tmp_post) && file_exists($tmp_post)) { + @unlink(realpath($tmp_post)); + } + chdir($cwd); // in case the test moves us around + + $this->_testCleanup($section_text, $temp_clean); + + /* when using CGI, strip the headers from the output */ + $output = $this->_stripHeadersCGI($output); + + if (isset($section_text['EXPECTHEADERS'])) { + $testheaders = $this->_processHeaders($section_text['EXPECTHEADERS']); + $missing = array_diff_assoc($testheaders, $this->_headers); + $changed = ''; + foreach ($missing as $header => $value) { + if (isset($this->_headers[$header])) { + $changed .= "-$header: $value\n+$header: "; + $changed .= $this->_headers[$header]; + } else { + $changed .= "-$header: $value\n"; + } + } + if ($missing) { + // tack on failed headers to output: + $output .= "\n====EXPECTHEADERS FAILURE====:\n$changed"; + } + } + // Does the output match what is expected? + do { + if (isset($section_text['EXPECTF']) || isset($section_text['EXPECTREGEX'])) { + if (isset($section_text['EXPECTF'])) { + $wanted = trim($section_text['EXPECTF']); + } else { + $wanted = trim($section_text['EXPECTREGEX']); + } + $wanted_re = preg_replace('/\r\n/', "\n", $wanted); + if (isset($section_text['EXPECTF'])) { + $wanted_re = preg_quote($wanted_re, '/'); + // Stick to basics + $wanted_re = str_replace("%s", ".+?", $wanted_re); //not greedy + $wanted_re = str_replace("%i", "[+\-]?[0-9]+", $wanted_re); + $wanted_re = str_replace("%d", "[0-9]+", $wanted_re); + $wanted_re = str_replace("%x", "[0-9a-fA-F]+", $wanted_re); + $wanted_re = str_replace("%f", "[+\-]?\.?[0-9]+\.?[0-9]*(E-?[0-9]+)?", $wanted_re); + $wanted_re = str_replace("%c", ".", $wanted_re); + // %f allows two points "-.0.0" but that is the best *simple* expression + } + + /* DEBUG YOUR REGEX HERE + var_dump($wanted_re); + print(str_repeat('=', 80) . "\n"); + var_dump($output); + */ + if (!$returnfail && preg_match("/^$wanted_re\$/s", $output)) { + if (file_exists($temp_file)) { + unlink($temp_file); + } + if (array_key_exists('FAIL', $section_text)) { + break; + } + if (!isset($this->_options['quiet'])) { + $this->_logger->log(0, "PASS $test_nr$tested$info"); + } + if (isset($this->_options['tapoutput'])) { + return array('ok', ' - ' . $tested); + } + return 'PASSED'; + } + } else { + if (isset($section_text['EXPECTFILE'])) { + $f = $temp_dir . '/' . trim($section_text['EXPECTFILE']); + if (!($fp = @fopen($f, 'rb'))) { + return PEAR::raiseError('--EXPECTFILE-- section file ' . + $f . ' not found'); + } + fclose($fp); + $section_text['EXPECT'] = file_get_contents($f); + } + + if (isset($section_text['EXPECT'])) { + $wanted = preg_replace('/\r\n/', "\n", trim($section_text['EXPECT'])); + } else { + $wanted = ''; + } + + // compare and leave on success + if (!$returnfail && 0 == strcmp($output, $wanted)) { + if (file_exists($temp_file)) { + unlink($temp_file); + } + if (array_key_exists('FAIL', $section_text)) { + break; + } + if (!isset($this->_options['quiet'])) { + $this->_logger->log(0, "PASS $test_nr$tested$info"); + } + if (isset($this->_options['tapoutput'])) { + return array('ok', ' - ' . $tested); + } + return 'PASSED'; + } + } + } while (false); + + if (array_key_exists('FAIL', $section_text)) { + // we expect a particular failure + // this is only used for testing PEAR_RunTest + $expectf = isset($section_text['EXPECTF']) ? $wanted_re : null; + $faildiff = $this->generate_diff($wanted, $output, null, $expectf); + $faildiff = preg_replace('/\r/', '', $faildiff); + $wanted = preg_replace('/\r/', '', trim($section_text['FAIL'])); + if ($faildiff == $wanted) { + if (!isset($this->_options['quiet'])) { + $this->_logger->log(0, "PASS $test_nr$tested$info"); + } + if (isset($this->_options['tapoutput'])) { + return array('ok', ' - ' . $tested); + } + return 'PASSED'; + } + unset($section_text['EXPECTF']); + $output = $faildiff; + if (isset($section_text['RETURNS'])) { + return PEAR::raiseError('Cannot have both RETURNS and FAIL in the same test: ' . + $file); + } + } + + // Test failed so we need to report details. + $txt = $warn ? 'WARN ' : 'FAIL '; + $this->_logger->log(0, $txt . $test_nr . $tested . $info); + + // write .exp + $res = $this->_writeLog($exp_filename, $wanted); + if (PEAR::isError($res)) { + return $res; + } + + // write .out + $res = $this->_writeLog($output_filename, $output); + if (PEAR::isError($res)) { + return $res; + } + + // write .diff + $returns = isset($section_text['RETURNS']) ? + array(trim($section_text['RETURNS']), $return_value) : null; + $expectf = isset($section_text['EXPECTF']) ? $wanted_re : null; + $data = $this->generate_diff($wanted, $output, $returns, $expectf); + $res = $this->_writeLog($diff_filename, $data); + if (PEAR::isError($res)) { + return $res; + } + + // write .log + $data = " +---- EXPECTED OUTPUT +$wanted +---- ACTUAL OUTPUT +$output +---- FAILED +"; + + if ($returnfail) { + $data .= " +---- EXPECTED RETURN +$section_text[RETURNS] +---- ACTUAL RETURN +$return_value +"; + } + + $res = $this->_writeLog($log_filename, $data); + if (PEAR::isError($res)) { + return $res; + } + + if (isset($this->_options['tapoutput'])) { + $wanted = explode("\n", $wanted); + $wanted = "# Expected output:\n#\n#" . implode("\n#", $wanted); + $output = explode("\n", $output); + $output = "#\n#\n# Actual output:\n#\n#" . implode("\n#", $output); + return array($wanted . $output . 'not ok', ' - ' . $tested); + } + return $warn ? 'WARNED' : 'FAILED'; + } + + function generate_diff($wanted, $output, $rvalue, $wanted_re) + { + $w = explode("\n", $wanted); + $o = explode("\n", $output); + $wr = explode("\n", $wanted_re); + $w1 = array_diff_assoc($w, $o); + $o1 = array_diff_assoc($o, $w); + $o2 = $w2 = array(); + foreach ($w1 as $idx => $val) { + if (!$wanted_re || !isset($wr[$idx]) || !isset($o1[$idx]) || + !preg_match('/^' . $wr[$idx] . '\\z/', $o1[$idx])) { + $w2[sprintf("%03d<", $idx)] = sprintf("%03d- ", $idx + 1) . $val; + } + } + foreach ($o1 as $idx => $val) { + if (!$wanted_re || !isset($wr[$idx]) || + !preg_match('/^' . $wr[$idx] . '\\z/', $val)) { + $o2[sprintf("%03d>", $idx)] = sprintf("%03d+ ", $idx + 1) . $val; + } + } + $diff = array_merge($w2, $o2); + ksort($diff); + $extra = $rvalue ? "##EXPECTED: $rvalue[0]\r\n##RETURNED: $rvalue[1]" : ''; + return implode("\r\n", $diff) . $extra; + } + + // Write the given text to a temporary file, and return the filename. + function save_text($filename, $text) + { + if (!$fp = fopen($filename, 'w')) { + return PEAR::raiseError("Cannot open file '" . $filename . "' (save_text)"); + } + fwrite($fp, $text); + fclose($fp); + if (1 < DETAILED) echo " +FILE $filename {{{ +$text +}}} +"; + } + + function _cleanupOldFiles($file) + { + $temp_dir = realpath(dirname($file)); + $mainFileName = basename($file, 'phpt'); + $diff_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'diff'; + $log_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'log'; + $exp_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'exp'; + $output_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'out'; + $memcheck_filename = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'mem'; + $temp_file = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'php'; + $temp_skipif = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'skip.php'; + $temp_clean = $temp_dir . DIRECTORY_SEPARATOR . $mainFileName.'clean.php'; + $tmp_post = $temp_dir . DIRECTORY_SEPARATOR . uniqid('phpt.'); + + // unlink old test results + @unlink($diff_filename); + @unlink($log_filename); + @unlink($exp_filename); + @unlink($output_filename); + @unlink($memcheck_filename); + @unlink($temp_file); + @unlink($temp_skipif); + @unlink($tmp_post); + @unlink($temp_clean); + } + + function _runSkipIf($section_text, $temp_skipif, $tested, $ini_settings) + { + $info = ''; + $warn = false; + if (array_key_exists('SKIPIF', $section_text) && trim($section_text['SKIPIF'])) { + $this->save_text($temp_skipif, $section_text['SKIPIF']); + $output = $this->system_with_timeout("$this->_php$ini_settings -f \"$temp_skipif\""); + $output = $output[1]; + $loutput = ltrim($output); + unlink($temp_skipif); + if (!strncasecmp('skip', $loutput, 4)) { + $skipreason = "SKIP $tested"; + if (preg_match('/^\s*skip\s*(.+)\s*/i', $output, $m)) { + $skipreason .= '(reason: ' . $m[1] . ')'; + } + if (!isset($this->_options['quiet'])) { + $this->_logger->log(0, $skipreason); + } + if (isset($this->_options['tapoutput'])) { + return array('ok', ' # skip ' . $reason); + } + return 'SKIPPED'; + } + + if (!strncasecmp('info', $loutput, 4) + && preg_match('/^\s*info\s*(.+)\s*/i', $output, $m)) { + $info = " (info: $m[1])"; + } + + if (!strncasecmp('warn', $loutput, 4) + && preg_match('/^\s*warn\s*(.+)\s*/i', $output, $m)) { + $warn = true; /* only if there is a reason */ + $info = " (warn: $m[1])"; + } + } + + return array('warn' => $warn, 'info' => $info); + } + + function _stripHeadersCGI($output) + { + $this->headers = array(); + if (!empty($this->_options['cgi']) && + $this->_php == $this->_options['cgi'] && + preg_match("/^(.*?)(?:\n\n(.*)|\\z)/s", $output, $match)) { + $output = isset($match[2]) ? trim($match[2]) : ''; + $this->_headers = $this->_processHeaders($match[1]); + } + + return $output; + } + + /** + * Return an array that can be used with array_diff() to compare headers + * + * @param string $text + */ + function _processHeaders($text) + { + $headers = array(); + $rh = preg_split("/[\n\r]+/", $text); + foreach ($rh as $line) { + if (strpos($line, ':')!== false) { + $line = explode(':', $line, 2); + $headers[trim($line[0])] = trim($line[1]); + } + } + return $headers; + } + + function _readFile($file) + { + // Load the sections of the test file. + $section_text = array( + 'TEST' => '(unnamed test)', + 'SKIPIF' => '', + 'GET' => '', + 'COOKIE' => '', + 'POST' => '', + 'ARGS' => '', + 'INI' => '', + 'CLEAN' => '', + ); + + if (!is_file($file) || !$fp = fopen($file, "r")) { + return PEAR::raiseError("Cannot open test file: $file"); + } + + $section = ''; + while (!feof($fp)) { + $line = fgets($fp); + + // Match the beginning of a section. + if (preg_match('/^--([_A-Z]+)--/', $line, $r)) { + $section = $r[1]; + $section_text[$section] = ''; + continue; + } elseif (empty($section)) { + fclose($fp); + return PEAR::raiseError("Invalid sections formats in test file: $file"); + } + + // Add to the section text. + $section_text[$section] .= $line; + } + fclose($fp); + + return $section_text; + } + + function _writeLog($logname, $data) + { + if (!$log = fopen($logname, 'w')) { + return PEAR::raiseError("Cannot create test log - $logname"); + } + fwrite($log, $data); + fclose($log); + } + + function _resetEnv($section_text, $temp_file) + { + $env = $_ENV; + $env['REDIRECT_STATUS'] = ''; + $env['QUERY_STRING'] = ''; + $env['PATH_TRANSLATED'] = ''; + $env['SCRIPT_FILENAME'] = ''; + $env['REQUEST_METHOD'] = ''; + $env['CONTENT_TYPE'] = ''; + $env['CONTENT_LENGTH'] = ''; + if (!empty($section_text['ENV'])) { + if (strpos($section_text['ENV'], '{PWD}') !== false) { + $section_text['ENV'] = str_replace('{PWD}', dirname($temp_file), $section_text['ENV']); + } + foreach (explode("\n", trim($section_text['ENV'])) as $e) { + $e = explode('=', trim($e), 2); + if (!empty($e[0]) && isset($e[1])) { + $env[$e[0]] = $e[1]; + } + } + } + if (array_key_exists('GET', $section_text)) { + $env['QUERY_STRING'] = trim($section_text['GET']); + } else { + $env['QUERY_STRING'] = ''; + } + if (array_key_exists('COOKIE', $section_text)) { + $env['HTTP_COOKIE'] = trim($section_text['COOKIE']); + } else { + $env['HTTP_COOKIE'] = ''; + } + $env['REDIRECT_STATUS'] = '1'; + $env['PATH_TRANSLATED'] = $temp_file; + $env['SCRIPT_FILENAME'] = $temp_file; + + return $env; + } + + function _processUpload($section_text, $file) + { + if (array_key_exists('UPLOAD', $section_text) && !empty($section_text['UPLOAD'])) { + $upload_files = trim($section_text['UPLOAD']); + $upload_files = explode("\n", $upload_files); + + $request = "Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737\n" . + "-----------------------------20896060251896012921717172737\n"; + foreach ($upload_files as $fileinfo) { + $fileinfo = explode('=', $fileinfo); + if (count($fileinfo) != 2) { + return PEAR::raiseError("Invalid UPLOAD section in test file: $file"); + } + if (!realpath(dirname($file) . '/' . $fileinfo[1])) { + return PEAR::raiseError("File for upload does not exist: $fileinfo[1] " . + "in test file: $file"); + } + $file_contents = file_get_contents(dirname($file) . '/' . $fileinfo[1]); + $fileinfo[1] = basename($fileinfo[1]); + $request .= "Content-Disposition: form-data; name=\"$fileinfo[0]\"; filename=\"$fileinfo[1]\"\n"; + $request .= "Content-Type: text/plain\n\n"; + $request .= $file_contents . "\n" . + "-----------------------------20896060251896012921717172737\n"; + } + + if (array_key_exists('POST', $section_text) && !empty($section_text['POST'])) { + // encode POST raw + $post = trim($section_text['POST']); + $post = explode('&', $post); + foreach ($post as $i => $post_info) { + $post_info = explode('=', $post_info); + if (count($post_info) != 2) { + return PEAR::raiseError("Invalid POST data in test file: $file"); + } + $post_info[0] = rawurldecode($post_info[0]); + $post_info[1] = rawurldecode($post_info[1]); + $post[$i] = $post_info; + } + foreach ($post as $post_info) { + $request .= "Content-Disposition: form-data; name=\"$post_info[0]\"\n\n"; + $request .= $post_info[1] . "\n" . + "-----------------------------20896060251896012921717172737\n"; + } + unset($section_text['POST']); + } + $section_text['POST_RAW'] = $request; + } + + return $section_text; + } + + function _testCleanup($section_text, $temp_clean) + { + if ($section_text['CLEAN']) { + // perform test cleanup + $this->save_text($temp_clean, $section_text['CLEAN']); + $output = $this->system_with_timeout("$this->_php $temp_clean 2>&1"); + if (strlen($output[1])) { + echo "BORKED --CLEAN-- section! output:\n", $output[1]; + } + if (file_exists($temp_clean)) { + unlink($temp_clean); + } + } + } +}PEAR-1.9.0/PEAR/Validate.php100664 764 764 53055 100664 10327 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Validate.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/**#@+ + * Constants for install stage + */ +define('PEAR_VALIDATE_INSTALLING', 1); +define('PEAR_VALIDATE_UNINSTALLING', 2); // this is not bit-mapped like the others +define('PEAR_VALIDATE_NORMAL', 3); +define('PEAR_VALIDATE_DOWNLOADING', 4); // this is not bit-mapped like the others +define('PEAR_VALIDATE_PACKAGING', 7); +/**#@-*/ +require_once 'PEAR/Common.php'; +require_once 'PEAR/Validator/PECL.php'; + +/** + * Validation class for package.xml - channel-level advanced validation + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Validate +{ + var $packageregex = _PEAR_COMMON_PACKAGE_NAME_PREG; + /** + * @var PEAR_PackageFile_v1|PEAR_PackageFile_v2 + */ + var $_packagexml; + /** + * @var int one of the PEAR_VALIDATE_* constants + */ + var $_state = PEAR_VALIDATE_NORMAL; + /** + * Format: ('error' => array('field' => name, 'reason' => reason), 'warning' => same) + * @var array + * @access private + */ + var $_failures = array('error' => array(), 'warning' => array()); + + /** + * Override this method to handle validation of normal package names + * @param string + * @return bool + * @access protected + */ + function _validPackageName($name) + { + return (bool) preg_match('/^' . $this->packageregex . '\\z/', $name); + } + + /** + * @param string package name to validate + * @param string name of channel-specific validation package + * @final + */ + function validPackageName($name, $validatepackagename = false) + { + if ($validatepackagename) { + if (strtolower($name) == strtolower($validatepackagename)) { + return (bool) preg_match('/^[a-zA-Z0-9_]+(?:\.[a-zA-Z0-9_]+)*\\z/', $name); + } + } + return $this->_validPackageName($name); + } + + /** + * This validates a bundle name, and bundle names must conform + * to the PEAR naming convention, so the method is final and static. + * @param string + * @final + * @static + */ + function validGroupName($name) + { + return (bool) preg_match('/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/', $name); + } + + /** + * Determine whether $state represents a valid stability level + * @param string + * @return bool + * @static + * @final + */ + function validState($state) + { + return in_array($state, array('snapshot', 'devel', 'alpha', 'beta', 'stable')); + } + + /** + * Get a list of valid stability levels + * @return array + * @static + * @final + */ + function getValidStates() + { + return array('snapshot', 'devel', 'alpha', 'beta', 'stable'); + } + + /** + * Determine whether a version is a properly formatted version number that can be used + * by version_compare + * @param string + * @return bool + * @static + * @final + */ + function validVersion($ver) + { + return (bool) preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + */ + function setPackageFile(&$pf) + { + $this->_packagexml = &$pf; + } + + /** + * @access private + */ + function _addFailure($field, $reason) + { + $this->_failures['errors'][] = array('field' => $field, 'reason' => $reason); + } + + /** + * @access private + */ + function _addWarning($field, $reason) + { + $this->_failures['warnings'][] = array('field' => $field, 'reason' => $reason); + } + + function getFailures() + { + $failures = $this->_failures; + $this->_failures = array('warnings' => array(), 'errors' => array()); + return $failures; + } + + /** + * @param int one of the PEAR_VALIDATE_* constants + */ + function validate($state = null) + { + if (!isset($this->_packagexml)) { + return false; + } + if ($state !== null) { + $this->_state = $state; + } + $this->_failures = array('warnings' => array(), 'errors' => array()); + $this->validatePackageName(); + $this->validateVersion(); + $this->validateMaintainers(); + $this->validateDate(); + $this->validateSummary(); + $this->validateDescription(); + $this->validateLicense(); + $this->validateNotes(); + if ($this->_packagexml->getPackagexmlVersion() == '1.0') { + $this->validateState(); + $this->validateFilelist(); + } elseif ($this->_packagexml->getPackagexmlVersion() == '2.0' || + $this->_packagexml->getPackagexmlVersion() == '2.1') { + $this->validateTime(); + $this->validateStability(); + $this->validateDeps(); + $this->validateMainFilelist(); + $this->validateReleaseFilelist(); + //$this->validateGlobalTasks(); + $this->validateChangelog(); + } + return !((bool) count($this->_failures['errors'])); + } + + /** + * @access protected + */ + function validatePackageName() + { + if ($this->_state == PEAR_VALIDATE_PACKAGING || + $this->_state == PEAR_VALIDATE_NORMAL) { + if (($this->_packagexml->getPackagexmlVersion() == '2.0' || + $this->_packagexml->getPackagexmlVersion() == '2.1') && + $this->_packagexml->getExtends()) { + $version = $this->_packagexml->getVersion() . ''; + $name = $this->_packagexml->getPackage(); + $test = array_shift($a = explode('.', $version)); + if ($test == '0') { + return true; + } + $vlen = strlen($test); + $majver = substr($name, strlen($name) - $vlen); + while ($majver && !is_numeric($majver{0})) { + $majver = substr($majver, 1); + } + if ($majver != $test) { + $this->_addWarning('package', "package $name extends package " . + $this->_packagexml->getExtends() . ' and so the name should ' . + 'have a postfix equal to the major version like "' . + $this->_packagexml->getExtends() . $test . '"'); + return true; + } elseif (substr($name, 0, strlen($name) - $vlen) != + $this->_packagexml->getExtends()) { + $this->_addWarning('package', "package $name extends package " . + $this->_packagexml->getExtends() . ' and so the name must ' . + 'be an extension like "' . $this->_packagexml->getExtends() . + $test . '"'); + return true; + } + } + } + if (!$this->validPackageName($this->_packagexml->getPackage())) { + $this->_addFailure('name', 'package name "' . + $this->_packagexml->getPackage() . '" is invalid'); + return false; + } + } + + /** + * @access protected + */ + function validateVersion() + { + if ($this->_state != PEAR_VALIDATE_PACKAGING) { + if (!$this->validVersion($this->_packagexml->getVersion())) { + $this->_addFailure('version', + 'Invalid version number "' . $this->_packagexml->getVersion() . '"'); + } + return false; + } + $version = $this->_packagexml->getVersion(); + $versioncomponents = explode('.', $version); + if (count($versioncomponents) != 3) { + $this->_addWarning('version', + 'A version number should have 3 decimals (x.y.z)'); + return true; + } + $name = $this->_packagexml->getPackage(); + // version must be based upon state + switch ($this->_packagexml->getState()) { + case 'snapshot' : + return true; + case 'devel' : + if ($versioncomponents[0] . 'a' == '0a') { + return true; + } + if ($versioncomponents[0] == 0) { + $versioncomponents[0] = '0'; + $this->_addWarning('version', + 'version "' . $version . '" should be "' . + implode('.' ,$versioncomponents) . '"'); + } else { + $this->_addWarning('version', + 'packages with devel stability must be < version 1.0.0'); + } + return true; + break; + case 'alpha' : + case 'beta' : + // check for a package that extends a package, + // like Foo and Foo2 + if ($this->_state == PEAR_VALIDATE_PACKAGING) { + if (substr($versioncomponents[2], 1, 2) == 'rc') { + $this->_addFailure('version', 'Release Candidate versions ' . + 'must have capital RC, not lower-case rc'); + return false; + } + } + if (!$this->_packagexml->getExtends()) { + if ($versioncomponents[0] == '1') { + if ($versioncomponents[2]{0} == '0') { + if ($versioncomponents[2] == '0') { + // version 1.*.0000 + $this->_addWarning('version', + 'version 1.' . $versioncomponents[1] . + '.0 probably should not be alpha or beta'); + return true; + } elseif (strlen($versioncomponents[2]) > 1) { + // version 1.*.0RC1 or 1.*.0beta24 etc. + return true; + } else { + // version 1.*.0 + $this->_addWarning('version', + 'version 1.' . $versioncomponents[1] . + '.0 probably should not be alpha or beta'); + return true; + } + } else { + $this->_addWarning('version', + 'bugfix versions (1.3.x where x > 0) probably should ' . + 'not be alpha or beta'); + return true; + } + } elseif ($versioncomponents[0] != '0') { + $this->_addWarning('version', + 'major versions greater than 1 are not allowed for packages ' . + 'without an tag or an identical postfix (foo2 v2.0.0)'); + return true; + } + if ($versioncomponents[0] . 'a' == '0a') { + return true; + } + if ($versioncomponents[0] == 0) { + $versioncomponents[0] = '0'; + $this->_addWarning('version', + 'version "' . $version . '" should be "' . + implode('.' ,$versioncomponents) . '"'); + } + } else { + $vlen = strlen($versioncomponents[0] . ''); + $majver = substr($name, strlen($name) - $vlen); + while ($majver && !is_numeric($majver{0})) { + $majver = substr($majver, 1); + } + if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) { + $this->_addWarning('version', 'first version number "' . + $versioncomponents[0] . '" must match the postfix of ' . + 'package name "' . $name . '" (' . + $majver . ')'); + return true; + } + if ($versioncomponents[0] == $majver) { + if ($versioncomponents[2]{0} == '0') { + if ($versioncomponents[2] == '0') { + // version 2.*.0000 + $this->_addWarning('version', + "version $majver." . $versioncomponents[1] . + '.0 probably should not be alpha or beta'); + return false; + } elseif (strlen($versioncomponents[2]) > 1) { + // version 2.*.0RC1 or 2.*.0beta24 etc. + return true; + } else { + // version 2.*.0 + $this->_addWarning('version', + "version $majver." . $versioncomponents[1] . + '.0 cannot be alpha or beta'); + return true; + } + } else { + $this->_addWarning('version', + "bugfix versions ($majver.x.y where y > 0) should " . + 'not be alpha or beta'); + return true; + } + } elseif ($versioncomponents[0] != '0') { + $this->_addWarning('version', + "only versions 0.x.y and $majver.x.y are allowed for alpha/beta releases"); + return true; + } + if ($versioncomponents[0] . 'a' == '0a') { + return true; + } + if ($versioncomponents[0] == 0) { + $versioncomponents[0] = '0'; + $this->_addWarning('version', + 'version "' . $version . '" should be "' . + implode('.' ,$versioncomponents) . '"'); + } + } + return true; + break; + case 'stable' : + if ($versioncomponents[0] == '0') { + $this->_addWarning('version', 'versions less than 1.0.0 cannot ' . + 'be stable'); + return true; + } + if (!is_numeric($versioncomponents[2])) { + if (preg_match('/\d+(rc|a|alpha|b|beta)\d*/i', + $versioncomponents[2])) { + $this->_addWarning('version', 'version "' . $version . '" or any ' . + 'RC/beta/alpha version cannot be stable'); + return true; + } + } + // check for a package that extends a package, + // like Foo and Foo2 + if ($this->_packagexml->getExtends()) { + $vlen = strlen($versioncomponents[0] . ''); + $majver = substr($name, strlen($name) - $vlen); + while ($majver && !is_numeric($majver{0})) { + $majver = substr($majver, 1); + } + if (($versioncomponents[0] != 0) && $majver != $versioncomponents[0]) { + $this->_addWarning('version', 'first version number "' . + $versioncomponents[0] . '" must match the postfix of ' . + 'package name "' . $name . '" (' . + $majver . ')'); + return true; + } + } elseif ($versioncomponents[0] > 1) { + $this->_addWarning('version', 'major version x in x.y.z may not be greater than ' . + '1 for any package that does not have an tag'); + } + return true; + break; + default : + return false; + break; + } + } + + /** + * @access protected + */ + function validateMaintainers() + { + // maintainers can only be truly validated server-side for most channels + // but allow this customization for those who wish it + return true; + } + + /** + * @access protected + */ + function validateDate() + { + if ($this->_state == PEAR_VALIDATE_NORMAL || + $this->_state == PEAR_VALIDATE_PACKAGING) { + + if (!preg_match('/(\d\d\d\d)\-(\d\d)\-(\d\d)/', + $this->_packagexml->getDate(), $res) || + count($res) < 4 + || !checkdate($res[2], $res[3], $res[1]) + ) { + $this->_addFailure('date', 'invalid release date "' . + $this->_packagexml->getDate() . '"'); + return false; + } + + if ($this->_state == PEAR_VALIDATE_PACKAGING && + $this->_packagexml->getDate() != date('Y-m-d')) { + $this->_addWarning('date', 'Release Date "' . + $this->_packagexml->getDate() . '" is not today'); + } + } + return true; + } + + /** + * @access protected + */ + function validateTime() + { + if (!$this->_packagexml->getTime()) { + // default of no time value set + return true; + } + + // packager automatically sets time, so only validate if pear validate is called + if ($this->_state = PEAR_VALIDATE_NORMAL) { + if (!preg_match('/\d\d:\d\d:\d\d/', + $this->_packagexml->getTime())) { + $this->_addFailure('time', 'invalid release time "' . + $this->_packagexml->getTime() . '"'); + return false; + } + + $result = preg_match('|\d{2}\:\d{2}\:\d{2}|', $this->_packagexml->getTime(), $matches); + if ($result === false || empty($matches)) { + $this->_addFailure('time', 'invalid release time "' . + $this->_packagexml->getTime() . '"'); + return false; + } + } + + return true; + } + + /** + * @access protected + */ + function validateState() + { + // this is the closest to "final" php4 can get + if (!PEAR_Validate::validState($this->_packagexml->getState())) { + if (strtolower($this->_packagexml->getState() == 'rc')) { + $this->_addFailure('state', 'RC is not a state, it is a version ' . + 'postfix, use ' . $this->_packagexml->getVersion() . 'RC1, state beta'); + } + $this->_addFailure('state', 'invalid release state "' . + $this->_packagexml->getState() . '", must be one of: ' . + implode(', ', PEAR_Validate::getValidStates())); + return false; + } + return true; + } + + /** + * @access protected + */ + function validateStability() + { + $ret = true; + $packagestability = $this->_packagexml->getState(); + $apistability = $this->_packagexml->getState('api'); + if (!PEAR_Validate::validState($packagestability)) { + $this->_addFailure('state', 'invalid release stability "' . + $this->_packagexml->getState() . '", must be one of: ' . + implode(', ', PEAR_Validate::getValidStates())); + $ret = false; + } + $apistates = PEAR_Validate::getValidStates(); + array_shift($apistates); // snapshot is not allowed + if (!in_array($apistability, $apistates)) { + $this->_addFailure('state', 'invalid API stability "' . + $this->_packagexml->getState('api') . '", must be one of: ' . + implode(', ', $apistates)); + $ret = false; + } + return $ret; + } + + /** + * @access protected + */ + function validateSummary() + { + return true; + } + + /** + * @access protected + */ + function validateDescription() + { + return true; + } + + /** + * @access protected + */ + function validateLicense() + { + return true; + } + + /** + * @access protected + */ + function validateNotes() + { + return true; + } + + /** + * for package.xml 2.0 only - channels can't use package.xml 1.0 + * @access protected + */ + function validateDependencies() + { + return true; + } + + /** + * for package.xml 1.0 only + * @access private + */ + function _validateFilelist() + { + return true; // placeholder for now + } + + /** + * for package.xml 2.0 only + * @access protected + */ + function validateMainFilelist() + { + return true; // placeholder for now + } + + /** + * for package.xml 2.0 only + * @access protected + */ + function validateReleaseFilelist() + { + return true; // placeholder for now + } + + /** + * @access protected + */ + function validateChangelog() + { + return true; + } + + /** + * @access protected + */ + function validateFilelist() + { + return true; + } + + /** + * @access protected + */ + function validateDeps() + { + return true; + } +}PEAR-1.9.0/PEAR/XMLParser.php100664 764 764 16001 100664 10401 + * @author Stephan Schmidt (original XML_Unserializer code) + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license New BSD License + * @version CVS: $Id: XMLParser.php 282970 2009-06-28 23:10:07Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Parser for any xml file + * @category pear + * @package PEAR + * @author Greg Beaver + * @author Stephan Schmidt (original XML_Unserializer code) + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_XMLParser +{ + /** + * unserilialized data + * @var string $_serializedData + */ + var $_unserializedData = null; + + /** + * name of the root tag + * @var string $_root + */ + var $_root = null; + + /** + * stack for all data that is found + * @var array $_dataStack + */ + var $_dataStack = array(); + + /** + * stack for all values that are generated + * @var array $_valStack + */ + var $_valStack = array(); + + /** + * current tag depth + * @var int $_depth + */ + var $_depth = 0; + + /** + * The XML encoding to use + * @var string $encoding + */ + var $encoding = 'ISO-8859-1'; + + /** + * @return array + */ + function getData() + { + return $this->_unserializedData; + } + + /** + * @param string xml content + * @return true|PEAR_Error + */ + function parse($data) + { + if (!extension_loaded('xml')) { + include_once 'PEAR.php'; + return PEAR::raiseError("XML Extension not found", 1); + } + $this->_dataStack = $this->_valStack = array(); + $this->_depth = 0; + + if ( + strpos($data, 'encoding="UTF-8"') + || strpos($data, 'encoding="utf-8"') + || strpos($data, "encoding='UTF-8'") + || strpos($data, "encoding='utf-8'") + ) { + $this->encoding = 'UTF-8'; + } + + if (version_compare(phpversion(), '5.0.0', 'lt') && $this->encoding == 'UTF-8') { + $data = utf8_decode($data); + $this->encoding = 'ISO-8859-1'; + } + + $xp = xml_parser_create($this->encoding); + xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, 0); + xml_set_object($xp, $this); + xml_set_element_handler($xp, 'startHandler', 'endHandler'); + xml_set_character_data_handler($xp, 'cdataHandler'); + if (!xml_parse($xp, $data)) { + $msg = xml_error_string(xml_get_error_code($xp)); + $line = xml_get_current_line_number($xp); + xml_parser_free($xp); + include_once 'PEAR.php'; + return PEAR::raiseError("XML Error: '$msg' on line '$line'", 2); + } + xml_parser_free($xp); + return true; + } + + /** + * Start element handler for XML parser + * + * @access private + * @param object $parser XML parser object + * @param string $element XML element + * @param array $attribs attributes of XML tag + * @return void + */ + function startHandler($parser, $element, $attribs) + { + $this->_depth++; + $this->_dataStack[$this->_depth] = null; + + $val = array( + 'name' => $element, + 'value' => null, + 'type' => 'string', + 'childrenKeys' => array(), + 'aggregKeys' => array() + ); + + if (count($attribs) > 0) { + $val['children'] = array(); + $val['type'] = 'array'; + $val['children']['attribs'] = $attribs; + } + + array_push($this->_valStack, $val); + } + + /** + * post-process data + * + * @param string $data + * @param string $element element name + */ + function postProcess($data, $element) + { + return trim($data); + } + + /** + * End element handler for XML parser + * + * @access private + * @param object XML parser object + * @param string + * @return void + */ + function endHandler($parser, $element) + { + $value = array_pop($this->_valStack); + $data = $this->postProcess($this->_dataStack[$this->_depth], $element); + + // adjust type of the value + switch (strtolower($value['type'])) { + // unserialize an array + case 'array': + if ($data !== '') { + $value['children']['_content'] = $data; + } + + $value['value'] = isset($value['children']) ? $value['children'] : array(); + break; + + /* + * unserialize a null value + */ + case 'null': + $data = null; + break; + + /* + * unserialize any scalar value + */ + default: + settype($data, $value['type']); + $value['value'] = $data; + break; + } + + $parent = array_pop($this->_valStack); + if ($parent === null) { + $this->_unserializedData = &$value['value']; + $this->_root = &$value['name']; + return true; + } + + // parent has to be an array + if (!isset($parent['children']) || !is_array($parent['children'])) { + $parent['children'] = array(); + if ($parent['type'] != 'array') { + $parent['type'] = 'array'; + } + } + + if (!empty($value['name'])) { + // there already has been a tag with this name + if (in_array($value['name'], $parent['childrenKeys'])) { + // no aggregate has been created for this tag + if (!in_array($value['name'], $parent['aggregKeys'])) { + if (isset($parent['children'][$value['name']])) { + $parent['children'][$value['name']] = array($parent['children'][$value['name']]); + } else { + $parent['children'][$value['name']] = array(); + } + array_push($parent['aggregKeys'], $value['name']); + } + array_push($parent['children'][$value['name']], $value['value']); + } else { + $parent['children'][$value['name']] = &$value['value']; + array_push($parent['childrenKeys'], $value['name']); + } + } else { + array_push($parent['children'],$value['value']); + } + array_push($this->_valStack, $parent); + + $this->_depth--; + } + + /** + * Handler for character data + * + * @access private + * @param object XML parser object + * @param string CDATA + * @return void + */ + function cdataHandler($parser, $cdata) + { + $this->_dataStack[$this->_depth] .= $cdata; + } +}PEAR-1.9.0/scripts/pear.bat100775 764 764 11102 100775 10435 @ECHO OFF + +REM ---------------------------------------------------------------------- +REM PHP version 5 +REM ---------------------------------------------------------------------- +REM Copyright (c) 1997-2004 The PHP Group +REM ---------------------------------------------------------------------- +REM This source file is subject to version 3.0 of the PHP license, +REM that is bundled with this package in the file LICENSE, and is +REM available at through the world-wide-web at +REM http://www.php.net/license/3_0.txt. +REM If you did not receive a copy of the PHP license and are unable to +REM obtain it through the world-wide-web, please send a note to +REM license@php.net so we can mail you a copy immediately. +REM ---------------------------------------------------------------------- +REM Authors: Alexander Merz (alexmerz@php.net) +REM ---------------------------------------------------------------------- +REM +REM Last updated 12/29/2004 ($Id$ is not replaced if the file is binary) + +REM change this lines to match the paths of your system +REM ------------------- + + +REM Test to see if this is a raw pear.bat (uninstalled version) +SET TMPTMPTMPTMPT=@includ +SET PMTPMTPMT=%TMPTMPTMPTMPT%e_path@ +FOR %%x IN ("@include_path@") DO (if %%x=="%PMTPMTPMT%" GOTO :NOTINSTALLED) + +REM Check PEAR global ENV, set them if they do not exist +IF "%PHP_PEAR_INSTALL_DIR%"=="" SET "PHP_PEAR_INSTALL_DIR=@include_path@" +IF "%PHP_PEAR_BIN_DIR%"=="" SET "PHP_PEAR_BIN_DIR=@bin_dir@" +IF "%PHP_PEAR_PHP_BIN%"=="" SET "PHP_PEAR_PHP_BIN=@php_bin@" +GOTO :INSTALLED + +:NOTINSTALLED +ECHO WARNING: This is a raw, uninstalled pear.bat + +REM Check to see if we can grab the directory of this file (Windows NT+) +IF %~n0 == pear ( +FOR %%x IN (cli\php.exe php.exe) DO (if "%%~$PATH:x" NEQ "" ( +SET "PHP_PEAR_PHP_BIN=%%~$PATH:x" +echo Using PHP Executable "%PHP_PEAR_PHP_BIN%" +"%PHP_PEAR_PHP_BIN%" -v +GOTO :NEXTTEST +)) +GOTO :FAILAUTODETECT +:NEXTTEST +IF "%PHP_PEAR_PHP_BIN%" NEQ "" ( + +REM We can use this PHP to run a temporary php file to get the dirname of pear + +echo ^ > ~~getloc.php +"%PHP_PEAR_PHP_BIN%" ~~getloc.php +set /p PHP_PEAR_BIN_DIR=fakeprompt < ~a.a +DEL ~a.a +DEL ~~getloc.php +set "PHP_PEAR_INSTALL_DIR=%PHP_PEAR_BIN_DIR%pear" + +REM Make sure there is a pearcmd.php at our disposal + +IF NOT EXIST %PHP_PEAR_INSTALL_DIR%\pearcmd.php ( +IF EXIST %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php COPY %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php +IF EXIST pearcmd.php COPY pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php +IF EXIST %~dp0\scripts\pearcmd.php COPY %~dp0\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php +) +) +GOTO :INSTALLED +) ELSE ( +REM Windows Me/98 cannot succeed, so allow the batch to fail +) +:FAILAUTODETECT +echo WARNING: failed to auto-detect pear information +:INSTALLED + +REM Check Folders and files +IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%" GOTO PEAR_INSTALL_ERROR +IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" GOTO PEAR_INSTALL_ERROR2 +IF NOT EXIST "%PHP_PEAR_BIN_DIR%" GOTO PEAR_BIN_ERROR +IF NOT EXIST "%PHP_PEAR_PHP_BIN%" GOTO PEAR_PHPBIN_ERROR +REM launch pearcmd +GOTO RUN +:PEAR_INSTALL_ERROR +ECHO PHP_PEAR_INSTALL_DIR is not set correctly. +ECHO Please fix it using your environment variable or modify +ECHO the default value in pear.bat +ECHO The current value is: +ECHO %PHP_PEAR_INSTALL_DIR% +GOTO END +:PEAR_INSTALL_ERROR2 +ECHO PHP_PEAR_INSTALL_DIR is not set correctly. +ECHO pearcmd.php could not be found there. +ECHO Please fix it using your environment variable or modify +ECHO the default value in pear.bat +ECHO The current value is: +ECHO %PHP_PEAR_INSTALL_DIR% +GOTO END +:PEAR_BIN_ERROR +ECHO PHP_PEAR_BIN_DIR is not set correctly. +ECHO Please fix it using your environment variable or modify +ECHO the default value in pear.bat +ECHO The current value is: +ECHO %PHP_PEAR_BIN_DIR% +GOTO END +:PEAR_PHPBIN_ERROR +ECHO PHP_PEAR_PHP_BIN is not set correctly. +ECHO Please fix it using your environment variable or modify +ECHO the default value in pear.bat +ECHO The current value is: +ECHO %PHP_PEAR_PHP_BIN% +GOTO END +:RUN +"%PHP_PEAR_PHP_BIN%" -C -d output_buffering=1 -d safe_mode=0 -d open_basedir="" -d auto_prepend_file="" -d auto_append_file="" -d variables_order=EGPCS -d register_argc_argv="On" -d include_path="%PHP_PEAR_INSTALL_DIR%" -f "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" -- %1 %2 %3 %4 %5 %6 %7 %8 %9 +:END +@ECHO ONPEAR-1.9.0/scripts/peardev.bat100664 764 764 11112 100664 11127 @ECHO OFF + +REM ---------------------------------------------------------------------- +REM PHP version 5 +REM ---------------------------------------------------------------------- +REM Copyright (c) 1997-2004 The PHP Group +REM ---------------------------------------------------------------------- +REM This source file is subject to version 3.0 of the PHP license, +REM that is bundled with this package in the file LICENSE, and is +REM available at through the world-wide-web at +REM http://www.php.net/license/3_0.txt. +REM If you did not receive a copy of the PHP license and are unable to +REM obtain it through the world-wide-web, please send a note to +REM license@php.net so we can mail you a copy immediately. +REM ---------------------------------------------------------------------- +REM Authors: Alexander Merz (alexmerz@php.net) +REM ---------------------------------------------------------------------- +REM +REM $Id: peardev.bat,v 1.6 2007-09-03 03:00:17 cellog Exp $ + +REM change this lines to match the paths of your system +REM ------------------- + + +REM Test to see if this is a raw pear.bat (uninstalled version) +SET TMPTMPTMPTMPT=@includ +SET PMTPMTPMT=%TMPTMPTMPTMPT%e_path@ +FOR %%x IN ("@include_path@") DO (if %%x=="%PMTPMTPMT%" GOTO :NOTINSTALLED) + +REM Check PEAR global ENV, set them if they do not exist +IF "%PHP_PEAR_INSTALL_DIR%"=="" SET "PHP_PEAR_INSTALL_DIR=@include_path@" +IF "%PHP_PEAR_BIN_DIR%"=="" SET "PHP_PEAR_BIN_DIR=@bin_dir@" +IF "%PHP_PEAR_PHP_BIN%"=="" SET "PHP_PEAR_PHP_BIN=@php_bin@" +GOTO :INSTALLED + +:NOTINSTALLED +ECHO WARNING: This is a raw, uninstalled pear.bat + +REM Check to see if we can grab the directory of this file (Windows NT+) +IF %~n0 == pear ( +FOR %%x IN (cli\php.exe php.exe) DO (if "%%~$PATH:x" NEQ "" ( +SET "PHP_PEAR_PHP_BIN=%%~$PATH:x" +echo Using PHP Executable "%PHP_PEAR_PHP_BIN%" +"%PHP_PEAR_PHP_BIN%" -v +GOTO :NEXTTEST +)) +GOTO :FAILAUTODETECT +:NEXTTEST +IF "%PHP_PEAR_PHP_BIN%" NEQ "" ( + +REM We can use this PHP to run a temporary php file to get the dirname of pear + +echo ^ > ~~getloc.php +"%PHP_PEAR_PHP_BIN%" ~~getloc.php +set /p PHP_PEAR_BIN_DIR=fakeprompt < ~a.a +DEL ~a.a +DEL ~~getloc.php +set "PHP_PEAR_INSTALL_DIR=%PHP_PEAR_BIN_DIR%pear" + +REM Make sure there is a pearcmd.php at our disposal + +IF NOT EXIST %PHP_PEAR_INSTALL_DIR%\pearcmd.php ( +IF EXIST %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php COPY %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php +IF EXIST pearcmd.php COPY pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php +IF EXIST %~dp0\scripts\pearcmd.php COPY %~dp0\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php +) +) +GOTO :INSTALLED +) ELSE ( +REM Windows Me/98 cannot succeed, so allow the batch to fail +) +:FAILAUTODETECT +echo WARNING: failed to auto-detect pear information +:INSTALLED + +REM Check Folders and files +IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%" GOTO PEAR_INSTALL_ERROR +IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" GOTO PEAR_INSTALL_ERROR2 +IF NOT EXIST "%PHP_PEAR_BIN_DIR%" GOTO PEAR_BIN_ERROR +IF NOT EXIST "%PHP_PEAR_PHP_BIN%" GOTO PEAR_PHPBIN_ERROR +REM launch pearcmd +GOTO RUN +:PEAR_INSTALL_ERROR +ECHO PHP_PEAR_INSTALL_DIR is not set correctly. +ECHO Please fix it using your environment variable or modify +ECHO the default value in pear.bat +ECHO The current value is: +ECHO %PHP_PEAR_INSTALL_DIR% +GOTO END +:PEAR_INSTALL_ERROR2 +ECHO PHP_PEAR_INSTALL_DIR is not set correctly. +ECHO pearcmd.php could not be found there. +ECHO Please fix it using your environment variable or modify +ECHO the default value in pear.bat +ECHO The current value is: +ECHO %PHP_PEAR_INSTALL_DIR% +GOTO END +:PEAR_BIN_ERROR +ECHO PHP_PEAR_BIN_DIR is not set correctly. +ECHO Please fix it using your environment variable or modify +ECHO the default value in pear.bat +ECHO The current value is: +ECHO %PHP_PEAR_BIN_DIR% +GOTO END +:PEAR_PHPBIN_ERROR +ECHO PHP_PEAR_PHP_BIN is not set correctly. +ECHO Please fix it using your environment variable or modify +ECHO the default value in pear.bat +ECHO The current value is: +ECHO %PHP_PEAR_PHP_BIN% +GOTO END +:RUN +"%PHP_PEAR_PHP_BIN%" -C -d memory_limit="-1" -d safe_mode=0 -d register_argc_argv="On" -d auto_prepend_file="" -d auto_append_file="" -d variables_order=EGPCS -d open_basedir="" -d output_buffering=1 -d include_path="%PHP_PEAR_INSTALL_DIR%" -f "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" -- %1 %2 %3 %4 %5 %6 %7 %8 %9 +:END +@ECHO ONPEAR-1.9.0/scripts/pecl.bat100664 764 764 11003 100664 10423 @ECHO OFF + +REM ---------------------------------------------------------------------- +REM PHP version 5 +REM ---------------------------------------------------------------------- +REM Copyright (c) 1997-2004 The PHP Group +REM ---------------------------------------------------------------------- +REM This source file is subject to version 3.0 of the PHP license, +REM that is bundled with this package in the file LICENSE, and is +REM available at through the world-wide-web at +REM http://www.php.net/license/3_0.txt. +REM If you did not receive a copy of the PHP license and are unable to +REM obtain it through the world-wide-web, please send a note to +REM license@php.net so we can mail you a copy immediately. +REM ---------------------------------------------------------------------- +REM Authors: Alexander Merz (alexmerz@php.net) +REM ---------------------------------------------------------------------- +REM +REM Last updated 02/08/2004 ($Id$ is not replaced if the file is binary) + +REM change this lines to match the paths of your system +REM ------------------- + + +REM Test to see if this is a raw pear.bat (uninstalled version) +SET TMPTMPTMPTMPT=@includ +SET PMTPMTPMT=%TMPTMPTMPTMPT%e_path@ +FOR %%x IN ("@include_path@") DO (if %%x=="%PMTPMTPMT%" GOTO :NOTINSTALLED) + +REM Check PEAR global ENV, set them if they do not exist +IF "%PHP_PEAR_INSTALL_DIR%"=="" SET "PHP_PEAR_INSTALL_DIR=@include_path@" +IF "%PHP_PEAR_BIN_DIR%"=="" SET "PHP_PEAR_BIN_DIR=@bin_dir@" +IF "%PHP_PEAR_PHP_BIN%"=="" SET "PHP_PEAR_PHP_BIN=@php_bin@" +GOTO :INSTALLED + +:NOTINSTALLED +ECHO WARNING: This is a raw, uninstalled pear.bat + +REM Check to see if we can grab the directory of this file (Windows NT+) +IF %~n0 == pear ( +FOR %%x IN (cli\php.exe php.exe) DO (if "%%~$PATH:x" NEQ "" ( +SET "PHP_PEAR_PHP_BIN=%%~$PATH:x" +echo Using PHP Executable "%PHP_PEAR_PHP_BIN%" +"%PHP_PEAR_PHP_BIN%" -v +GOTO :NEXTTEST +)) +GOTO :FAILAUTODETECT +:NEXTTEST +IF "%PHP_PEAR_PHP_BIN%" NEQ "" ( + +REM We can use this PHP to run a temporary php file to get the dirname of pear + +echo ^ > ~~getloc.php +"%PHP_PEAR_PHP_BIN%" ~~getloc.php +set /p PHP_PEAR_BIN_DIR=fakeprompt < ~a.a +DEL ~a.a +DEL ~~getloc.php +set "PHP_PEAR_INSTALL_DIR=%PHP_PEAR_BIN_DIR%pear" + +REM Make sure there is a pearcmd.php at our disposal + +IF NOT EXIST %PHP_PEAR_INSTALL_DIR%\pearcmd.php ( +IF EXIST %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php COPY %PHP_PEAR_INSTALL_DIR%\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php +IF EXIST pearcmd.php COPY pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php +IF EXIST %~dp0\scripts\pearcmd.php COPY %~dp0\scripts\pearcmd.php %PHP_PEAR_INSTALL_DIR%\pearcmd.php +) +) +GOTO :INSTALLED +) ELSE ( +REM Windows Me/98 cannot succeed, so allow the batch to fail +) +:FAILAUTODETECT +echo WARNING: failed to auto-detect pear information +:INSTALLED + +REM Check Folders and files +IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%" GOTO PEAR_INSTALL_ERROR +IF NOT EXIST "%PHP_PEAR_INSTALL_DIR%\pearcmd.php" GOTO PEAR_INSTALL_ERROR2 +IF NOT EXIST "%PHP_PEAR_BIN_DIR%" GOTO PEAR_BIN_ERROR +IF NOT EXIST "%PHP_PEAR_PHP_BIN%" GOTO PEAR_PHPBIN_ERROR +REM launch pearcmd +GOTO RUN +:PEAR_INSTALL_ERROR +ECHO PHP_PEAR_INSTALL_DIR is not set correctly. +ECHO Please fix it using your environment variable or modify +ECHO the default value in pear.bat +ECHO The current value is: +ECHO %PHP_PEAR_INSTALL_DIR% +GOTO END +:PEAR_INSTALL_ERROR2 +ECHO PHP_PEAR_INSTALL_DIR is not set correctly. +ECHO pearcmd.php could not be found there. +ECHO Please fix it using your environment variable or modify +ECHO the default value in pear.bat +ECHO The current value is: +ECHO %PHP_PEAR_INSTALL_DIR% +GOTO END +:PEAR_BIN_ERROR +ECHO PHP_PEAR_BIN_DIR is not set correctly. +ECHO Please fix it using your environment variable or modify +ECHO the default value in pear.bat +ECHO The current value is: +ECHO %PHP_PEAR_BIN_DIR% +GOTO END +:PEAR_PHPBIN_ERROR +ECHO PHP_PEAR_PHP_BIN is not set correctly. +ECHO Please fix it using your environment variable or modify +ECHO the default value in pear.bat +ECHO The current value is: +ECHO %PHP_PEAR_PHP_BIN% +GOTO END +:RUN +"%PHP_PEAR_PHP_BIN%" -C -n -d output_buffering=1 -d safe_mode=0 -d include_path="%PHP_PEAR_INSTALL_DIR%" -d register_argc_argv="On" -d variables_order=EGPCS -f "%PHP_PEAR_INSTALL_DIR%\peclcmd.php" -- %1 %2 %3 %4 %5 %6 %7 %8 %9 +:END +@ECHO ONPEAR-1.9.0/scripts/pear.sh100664 764 764 1362 100664 10262 #!/bin/sh + +# first find which PHP binary to use +if test "x$PHP_PEAR_PHP_BIN" != "x"; then + PHP="$PHP_PEAR_PHP_BIN" +else + if test "@php_bin@" = '@'php_bin'@'; then + PHP=php + else + PHP="@php_bin@" + fi +fi + +# then look for the right pear include dir +if test "x$PHP_PEAR_INSTALL_DIR" != "x"; then + INCDIR=$PHP_PEAR_INSTALL_DIR + INCARG="-d include_path=$PHP_PEAR_INSTALL_DIR" +else + if test "@php_dir@" = '@'php_dir'@'; then + INCDIR=`dirname $0` + INCARG="" + else + INCDIR="@php_dir@" + INCARG="-d include_path=@php_dir@" + fi +fi + +exec $PHP -C -q $INCARG -d output_buffering=1 -d variables_order=EGPCS -d open_basedir="" -d safe_mode=0 -d register_argc_argv="On" -d auto_prepend_file="" -d auto_append_file="" $INCDIR/pearcmd.php "$@" +PEAR-1.9.0/scripts/peardev.sh100664 764 764 1407 100664 10761 #!/bin/sh + +# first find which PHP binary to use +if test "x$PHP_PEAR_PHP_BIN" != "x"; then + PHP="$PHP_PEAR_PHP_BIN" +else + if test "@php_bin@" = '@'php_bin'@'; then + PHP=php + else + PHP="@php_bin@" + fi +fi + +# then look for the right pear include dir +if test "x$PHP_PEAR_INSTALL_DIR" != "x"; then + INCDIR=$PHP_PEAR_INSTALL_DIR + INCARG="-d include_path=$PHP_PEAR_INSTALL_DIR" +else + if test "@php_dir@" = '@'php_dir'@'; then + INCDIR=`dirname $0` + INCARG="" + else + INCDIR="@php_dir@" + INCARG="-d include_path=@php_dir@" + fi +fi + +exec $PHP -d memory_limit="-1" -C -q $INCARG -d output_buffering=1 -d open_basedir="" -d safe_mode=0 -d register_argc_argv="On" -d auto_prepend_file="" -d variables_order=EGPCS -d auto_append_file="" $INCDIR/pearcmd.php "$@" +PEAR-1.9.0/scripts/pecl.sh100664 764 764 1263 100664 10256 #!/bin/sh + +# first find which PHP binary to use +if test "x$PHP_PEAR_PHP_BIN" != "x"; then + PHP="$PHP_PEAR_PHP_BIN" +else + if test "@php_bin@" = '@'php_bin'@'; then + PHP=php + else + PHP="@php_bin@" + fi +fi + +# then look for the right pear include dir +if test "x$PHP_PEAR_INSTALL_DIR" != "x"; then + INCDIR=$PHP_PEAR_INSTALL_DIR + INCARG="-d include_path=$PHP_PEAR_INSTALL_DIR" +else + if test "@php_dir@" = '@'php_dir'@'; then + INCDIR=`dirname $0` + INCARG="" + else + INCDIR="@php_dir@" + INCARG="-d include_path=@php_dir@" + fi +fi + +exec $PHP -C -n -q $INCARG -d output_buffering=1 -d variables_order=EGPCS -d safe_mode=0 -d register_argc_argv="On" $INCDIR/peclcmd.php "$@" +PEAR-1.9.0/scripts/pearcmd.php100664 764 764 34076 100664 11153 + * @author Tomas V.V.Cox + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: pearcmd.php 286487 2009-07-29 05:57:28Z dufuz $ + * @link http://pear.php.net/package/PEAR + */ + +ob_end_clean(); +if (!defined('PEAR_RUNTYPE')) { + // this is defined in peclcmd.php as 'pecl' + define('PEAR_RUNTYPE', 'pear'); +} +define('PEAR_IGNORE_BACKTRACE', 1); +/** + * @nodep Gtk + */ +if ('@include_path@' != '@'.'include_path'.'@') { + ini_set('include_path', '@include_path@'); + $raw = false; +} else { + // this is a raw, uninstalled pear, either a cvs checkout, or php distro + $raw = true; +} +@ini_set('allow_url_fopen', true); +if (!ini_get('safe_mode')) { + @set_time_limit(0); +} +ob_implicit_flush(true); +@ini_set('track_errors', true); +@ini_set('html_errors', false); +@ini_set('magic_quotes_runtime', false); +$_PEAR_PHPDIR = '#$%^&*'; +set_error_handler('error_handler'); + +$pear_package_version = "@pear_version@"; + +require_once 'PEAR.php'; +require_once 'PEAR/Frontend.php'; +require_once 'PEAR/Config.php'; +require_once 'PEAR/Command.php'; +require_once 'Console/Getopt.php'; + + +PEAR_Command::setFrontendType('CLI'); +$all_commands = PEAR_Command::getCommands(); + +// remove this next part when we stop supporting that crap-ass PHP 4.2 +if (!isset($_SERVER['argv']) && !isset($argv) && !isset($HTTP_SERVER_VARS['argv'])) { + echo 'ERROR: either use the CLI php executable, or set register_argc_argv=On in php.ini'; + exit(1); +} + +$argv = Console_Getopt::readPHPArgv(); +// fix CGI sapi oddity - the -- in pear.bat/pear is not removed +if (php_sapi_name() != 'cli' && isset($argv[1]) && $argv[1] == '--') { + unset($argv[1]); + $argv = array_values($argv); +} +$progname = PEAR_RUNTYPE; +array_shift($argv); +$options = Console_Getopt::getopt2($argv, "c:C:d:D:Gh?sSqu:vV"); +if (PEAR::isError($options)) { + usage($options); +} + +$opts = $options[0]; + +$fetype = 'CLI'; +if ($progname == 'gpear' || $progname == 'pear-gtk') { + $fetype = 'Gtk'; +} else { + foreach ($opts as $opt) { + if ($opt[0] == 'G') { + $fetype = 'Gtk'; + } + } +} +//Check if Gtk and PHP >= 5.1.0 +if ($fetype == 'Gtk' && version_compare(phpversion(), '5.1.0', '>=')) { + $fetype = 'Gtk2'; +} + +$pear_user_config = ''; +$pear_system_config = ''; +$store_user_config = false; +$store_system_config = false; +$verbose = 1; + +foreach ($opts as $opt) { + switch ($opt[0]) { + case 'c': + $pear_user_config = $opt[1]; + break; + case 'C': + $pear_system_config = $opt[1]; + break; + } +} + +PEAR_Command::setFrontendType($fetype); +$ui = &PEAR_Command::getFrontendObject(); +$config = &PEAR_Config::singleton($pear_user_config, $pear_system_config); + +if (PEAR::isError($config)) { + $_file = ''; + if ($pear_user_config !== false) { + $_file .= $pear_user_config; + } + if ($pear_system_config !== false) { + $_file .= '/' . $pear_system_config; + } + if ($_file == '/') { + $_file = 'The default config file'; + } + $config->getMessage(); + $ui->outputData("ERROR: $_file is not a valid config file or is corrupted."); + // We stop, we have no idea where we are :) + exit(1); +} + +// this is used in the error handler to retrieve a relative path +$_PEAR_PHPDIR = $config->get('php_dir'); +$ui->setConfig($config); +PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError")); +if (ini_get('safe_mode')) { + $ui->outputData('WARNING: running in safe mode requires that all files created ' . + 'be the same uid as the current script. PHP reports this script is uid: ' . + @getmyuid() . ', and current user is: ' . @get_current_user()); +} + +$verbose = $config->get("verbose"); +$cmdopts = array(); + +if ($raw) { + if (!$config->isDefinedLayer('user') && !$config->isDefinedLayer('system')) { + $found = false; + foreach ($opts as $opt) { + if ($opt[0] == 'd' || $opt[0] == 'D') { + $found = true; // the user knows what they are doing, and are setting config values + } + } + if (!$found) { + // no prior runs, try to install PEAR + if (strpos(dirname(__FILE__), 'scripts')) { + $packagexml = dirname(dirname(__FILE__)) . DIRECTORY_SEPARATOR . 'package2.xml'; + $pearbase = dirname(dirname(__FILE__)); + } else { + $packagexml = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'package2.xml'; + $pearbase = dirname(__FILE__); + } + if (file_exists($packagexml)) { + $options[1] = array( + 'install', + $packagexml + ); + $config->set('php_dir', $pearbase . DIRECTORY_SEPARATOR . 'php'); + $config->set('data_dir', $pearbase . DIRECTORY_SEPARATOR . 'data'); + $config->set('doc_dir', $pearbase . DIRECTORY_SEPARATOR . 'docs'); + $config->set('test_dir', $pearbase . DIRECTORY_SEPARATOR . 'tests'); + $config->set('ext_dir', $pearbase . DIRECTORY_SEPARATOR . 'extensions'); + $config->set('bin_dir', $pearbase); + $config->mergeConfigFile($pearbase . 'pear.ini', false); + $config->store(); + $config->set('auto_discover', 1); + } + } + } +} +foreach ($opts as $opt) { + $param = !empty($opt[1]) ? $opt[1] : true; + switch ($opt[0]) { + case 'd': + if ($param === true) { + die('Invalid usage of "-d" option, expected -d config_value=value, ' . + 'received "-d"' . "\n"); + } + $possible = explode('=', $param); + if (count($possible) != 2) { + die('Invalid usage of "-d" option, expected -d config_value=value, received "' . + $param . '"' . "\n"); + } + list($key, $value) = explode('=', $param); + $config->set($key, $value, 'user'); + break; + case 'D': + if ($param === true) { + die('Invalid usage of "-d" option, expected -d config_value=value, ' . + 'received "-d"' . "\n"); + } + $possible = explode('=', $param); + if (count($possible) != 2) { + die('Invalid usage of "-d" option, expected -d config_value=value, received "' . + $param . '"' . "\n"); + } + list($key, $value) = explode('=', $param); + $config->set($key, $value, 'system'); + break; + case 's': + $store_user_config = true; + break; + case 'S': + $store_system_config = true; + break; + case 'u': + $config->remove($param, 'user'); + break; + case 'v': + $config->set('verbose', $config->get('verbose') + 1); + break; + case 'q': + $config->set('verbose', $config->get('verbose') - 1); + break; + case 'V': + usage(null, 'version'); + case 'c': + case 'C': + break; + default: + // all non pear params goes to the command + $cmdopts[$opt[0]] = $param; + break; + } +} + +if ($store_system_config) { + $config->store('system'); +} + +if ($store_user_config) { + $config->store('user'); +} + +$command = (isset($options[1][0])) ? $options[1][0] : null; +if (empty($command) && ($store_user_config || $store_system_config)) { + exit; +} + +if ($fetype == 'Gtk' || $fetype == 'Gtk2') { + if (!$config->validConfiguration()) { + PEAR::raiseError('CRITICAL ERROR: no existing valid configuration files found in files ' . + "'$pear_user_config' or '$pear_system_config', please copy an existing configuration" . + 'file to one of these locations, or use the -c and -s options to create one'); + } + Gtk::main(); +} else do { + if ($command == 'help') { + usage(null, @$options[1][1]); + } + + if (!$config->validConfiguration()) { + PEAR::raiseError('CRITICAL ERROR: no existing valid configuration files found in files ' . + "'$pear_user_config' or '$pear_system_config', please copy an existing configuration" . + 'file to one of these locations, or use the -c and -s options to create one'); + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $cmd = PEAR_Command::factory($command, $config); + PEAR::popErrorHandling(); + if (PEAR::isError($cmd)) { + usage(null, @$options[1][0]); + } + + $short_args = $long_args = null; + PEAR_Command::getGetoptArgs($command, $short_args, $long_args); + array_shift($options[1]); + $tmp = Console_Getopt::getopt2($options[1], $short_args, $long_args); + + if (PEAR::isError($tmp)) { + break; + } + + list($tmpopt, $params) = $tmp; + $opts = array(); + foreach ($tmpopt as $foo => $tmp2) { + list($opt, $value) = $tmp2; + if ($value === null) { + $value = true; // options without args + } + + if (strlen($opt) == 1) { + $cmdoptions = $cmd->getOptions($command); + foreach ($cmdoptions as $o => $d) { + if (isset($d['shortopt']) && $d['shortopt'] == $opt) { + $opts[$o] = $value; + } + } + } else { + if (substr($opt, 0, 2) == '--') { + $opts[substr($opt, 2)] = $value; + } + } + } + + $ok = $cmd->run($command, $opts, $params); + if ($ok === false) { + PEAR::raiseError("unknown command `$command'"); + } + + if (PEAR::isError($ok)) { + PEAR::setErrorHandling(PEAR_ERROR_CALLBACK, array($ui, "displayFatalError")); + PEAR::raiseError($ok); + } +} while (false); + +// {{{ usage() + +function usage($error = null, $helpsubject = null) +{ + global $progname, $all_commands; + $stderr = fopen('php://stderr', 'w'); + if (PEAR::isError($error)) { + fputs($stderr, $error->getMessage() . "\n"); + } elseif ($error !== null) { + fputs($stderr, "$error\n"); + } + + if ($helpsubject != null) { + $put = cmdHelp($helpsubject); + } else { + $put = + "Commands:\n"; + $maxlen = max(array_map("strlen", $all_commands)); + $formatstr = "%-{$maxlen}s %s\n"; + ksort($all_commands); + foreach ($all_commands as $cmd => $class) { + $put .= sprintf($formatstr, $cmd, PEAR_Command::getDescription($cmd)); + } + $put .= + "Usage: $progname [options] command [command-options] \n". + "Type \"$progname help options\" to list all options.\n". + "Type \"$progname help shortcuts\" to list all command shortcuts.\n". + "Type \"$progname help \" to get the help for the specified command."; + } + fputs($stderr, "$put\n"); + fclose($stderr); + exit(1); +} + +function cmdHelp($command) +{ + global $progname, $all_commands, $config; + if ($command == "options") { + return + "Options:\n". + " -v increase verbosity level (default 1)\n". + " -q be quiet, decrease verbosity level\n". + " -c file find user configuration in `file'\n". + " -C file find system configuration in `file'\n". + " -d foo=bar set user config variable `foo' to `bar'\n". + " -D foo=bar set system config variable `foo' to `bar'\n". + " -G start in graphical (Gtk) mode\n". + " -s store user configuration\n". + " -S store system configuration\n". + " -u foo unset `foo' in the user configuration\n". + " -h, -? display help/usage (this message)\n". + " -V version information\n"; + } elseif ($command == "shortcuts") { + $sc = PEAR_Command::getShortcuts(); + $ret = "Shortcuts:\n"; + foreach ($sc as $s => $c) { + $ret .= sprintf(" %-8s %s\n", $s, $c); + } + return $ret; + + } elseif ($command == "version") { + return "PEAR Version: ".$GLOBALS['pear_package_version']. + "\nPHP Version: ".phpversion(). + "\nZend Engine Version: ".zend_version(). + "\nRunning on: ".php_uname(); + + } elseif ($help = PEAR_Command::getHelp($command)) { + if (is_string($help)) { + return "$progname $command [options] $help\n"; + } + + if ($help[1] === null) { + return "$progname $command $help[0]"; + } + + return "$progname $command [options] $help[0]\n$help[1]"; + } + + return "Command '$command' is not valid, try '$progname help'"; +} + +// }}} + +function error_handler($errno, $errmsg, $file, $line, $vars) { + if ((defined('E_STRICT') && $errno & E_STRICT) || (defined('E_DEPRECATED') && + $errno & E_DEPRECATED) || !error_reporting()) { + if (defined('E_STRICT') && $errno & E_STRICT) { + return; // E_STRICT + } + if (defined('E_DEPRECATED') && $errno & E_DEPRECATED) { + return; // E_DEPRECATED + } + if ($GLOBALS['config']->get('verbose') < 4) { + return false; // @silenced error, show all if debug is high enough + } + } + $errortype = array ( + E_ERROR => "Error", + E_WARNING => "Warning", + E_PARSE => "Parsing Error", + E_NOTICE => "Notice", + E_CORE_ERROR => "Core Error", + E_CORE_WARNING => "Core Warning", + E_COMPILE_ERROR => "Compile Error", + E_COMPILE_WARNING => "Compile Warning", + E_USER_ERROR => "User Error", + E_USER_WARNING => "User Warning", + E_USER_NOTICE => "User Notice" + ); + $prefix = $errortype[$errno]; + global $_PEAR_PHPDIR; + if (stristr($file, $_PEAR_PHPDIR)) { + $file = substr($file, strlen($_PEAR_PHPDIR) + 1); + } else { + $file = basename($file); + } + print "\n$prefix: $errmsg in $file on line $line\n"; + return false; +} + + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: nil + * mode: php + * End: + */ +// vim600:syn=phpPEAR-1.9.0/scripts/peclcmd.php100664 764 764 1636 100664 11123 + * @author Tomas V.V.Cox + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: peclcmd.php 276392 2009-02-25 00:06:23Z dufuz $ + * @link http://pear.php.net/package/PEAR + */ + +/** + * @nodep Gtk + */ +if ('@include_path@' != '@'.'include_path'.'@') { + ini_set('include_path', '@include_path@'); + $raw = false; +} else { + // this is a raw, uninstalled pear, either a cvs checkout, or php distro + $raw = true; +} +define('PEAR_RUNTYPE', 'pecl'); +require_once 'pearcmd.php'; +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * indent-tabs-mode: nil + * mode: php + * End: + */ +// vim600:syn=php + +?> +PEAR-1.9.0/LICENSE100664 764 764 2705 100664 6317 Copyright (c) 1997-2009, + Stig Bakken , + Gregory Beaver , + Helgi Þormar Þorbjörnsson , + Tomas V.V.Cox , + Martin Jansen . +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. + * 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. + +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 OWNER 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. +PEAR-1.9.0/INSTALL100664 764 764 3641 100664 6343 PEAR - The PEAR Installer +========================= +Installing the PEAR Installer. + +You should install PEAR on a local development machine first. Installing +PEAR on a remote production machine should only be done after you are +familiar with PEAR and have tested code using PEAR on your development +machine. + +There are two methods of installing PEAR + - PEAR bundled in PHP + - go-pear + +We will first examine how to install PEAR that is bundled with PHP. + +Microsoft Windows +================= +If you are running PHP 5.2.0 or newer, simply download and +run the windows installer (.msi) and PEAR can be automatically +installed. + +Otherwise, for older PHP versions, download the .zip of windows, +there is a script included with your PHP distribution that is called +"go-pear". You must open a command box in order to run it. Click +"start" then click "Run..." and type "cmd.exe" to open a command box. +Use "cd" to change directory to the location of PHP where you unzipped it, +and run the go-pear command. + +Unix +==== +make sure you have enabled default extensions, and if you want faster +downloads, enable the zlib extension. You must also enable the CLI +SAPI with the --enable-cli extension directive. After this, simply run: + +make install-pear + +and PEAR will be automatically configured for you. + +go-pear +======= +For users who cannot perform the above steps, or who wish to obtain the +latest PEAR with a slightly higher risk of failure, use go-pear. go-pear +is obtained by downloading http://go-pear.org and saving it as go-pear.php. +After downloading, simply run "php go-pear.php" or open it in a web browser +(windows only) to download and install PEAR. + +You can always ask general installation questions on pear-general@lists.php.net, +a public mailing list devoted to support for PEAR packages and installation- +related issues. + +Happy PHPing, we hope PEAR will be a great tool for your development work! + +$Id: INSTALL 220345 2006-09-22 03:31:36Z cellog $PEAR-1.9.0/package.dtd100664 764 764 6477 100664 7414 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +PEAR-1.9.0/PEAR5.php100664 764 764 2077 100664 6641 + * @author Stig Bakken + * @author Tomas V.V.Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: PEAR.php 286670 2009-08-02 14:16:06Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/**#@+ + * ERROR constants + */ +define('PEAR_ERROR_RETURN', 1); +define('PEAR_ERROR_PRINT', 2); +define('PEAR_ERROR_TRIGGER', 4); +define('PEAR_ERROR_DIE', 8); +define('PEAR_ERROR_CALLBACK', 16); +/** + * WARNING: obsolete + * @deprecated + */ +define('PEAR_ERROR_EXCEPTION', 32); +/**#@-*/ +define('PEAR_ZE2', (function_exists('version_compare') && + version_compare(zend_version(), "2-dev", "ge"))); + +if (substr(PHP_OS, 0, 3) == 'WIN') { + define('OS_WINDOWS', true); + define('OS_UNIX', false); + define('PEAR_OS', 'Windows'); +} else { + define('OS_WINDOWS', false); + define('OS_UNIX', true); + define('PEAR_OS', 'Unix'); // blatant assumption +} + +$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; +$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; +$GLOBALS['_PEAR_destructor_object_list'] = array(); +$GLOBALS['_PEAR_shutdown_funcs'] = array(); +$GLOBALS['_PEAR_error_handler_stack'] = array(); + +@ini_set('track_errors', true); + +/** + * Base class for other PEAR classes. Provides rudimentary + * emulation of destructors. + * + * If you want a destructor in your class, inherit PEAR and make a + * destructor method called _yourclassname (same name as the + * constructor, but with a "_" prefix). Also, in your constructor you + * have to call the PEAR constructor: $this->PEAR();. + * The destructor method will be called without parameters. Note that + * at in some SAPI implementations (such as Apache), any output during + * the request shutdown (in which destructors are called) seems to be + * discarded. If you need to get any debug information from your + * destructor, use error_log(), syslog() or something similar. + * + * IMPORTANT! To use the emulated destructors you need to create the + * objects by reference: $obj =& new PEAR_child; + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V.V. Cox + * @author Greg Beaver + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @see PEAR_Error + * @since Class available since PHP 4.0.2 + * @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear + */ +class PEAR +{ + // {{{ properties + + /** + * Whether to enable internal debug messages. + * + * @var bool + * @access private + */ + var $_debug = false; + + /** + * Default error mode for this object. + * + * @var int + * @access private + */ + var $_default_error_mode = null; + + /** + * Default error options used for this object when error mode + * is PEAR_ERROR_TRIGGER. + * + * @var int + * @access private + */ + var $_default_error_options = null; + + /** + * Default error handler (callback) for this object, if error mode is + * PEAR_ERROR_CALLBACK. + * + * @var string + * @access private + */ + var $_default_error_handler = ''; + + /** + * Which class to use for error objects. + * + * @var string + * @access private + */ + var $_error_class = 'PEAR_Error'; + + /** + * An array of expected errors. + * + * @var array + * @access private + */ + var $_expected_errors = array(); + + // }}} + + // {{{ constructor + + /** + * Constructor. Registers this object in + * $_PEAR_destructor_object_list for destructor emulation if a + * destructor object exists. + * + * @param string $error_class (optional) which class to use for + * error objects, defaults to PEAR_Error. + * @access public + * @return void + */ + function PEAR($error_class = null) + { + $classname = strtolower(get_class($this)); + if ($this->_debug) { + print "PEAR constructor called, class=$classname\n"; + } + if ($error_class !== null) { + $this->_error_class = $error_class; + } + while ($classname && strcasecmp($classname, "pear")) { + $destructor = "_$classname"; + if (method_exists($this, $destructor)) { + global $_PEAR_destructor_object_list; + $_PEAR_destructor_object_list[] = &$this; + if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { + register_shutdown_function("_PEAR_call_destructors"); + $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; + } + break; + } else { + $classname = get_parent_class($classname); + } + } + } + + // }}} + // {{{ destructor + + /** + * Destructor (the emulated type of...). Does nothing right now, + * but is included for forward compatibility, so subclass + * destructors should always call it. + * + * See the note in the class desciption about output from + * destructors. + * + * @access public + * @return void + */ + function _PEAR() { + if ($this->_debug) { + printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); + } + } + + // }}} + // {{{ getStaticProperty() + + /** + * If you have a class that's mostly/entirely static, and you need static + * properties, you can use this method to simulate them. Eg. in your method(s) + * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); + * You MUST use a reference, or they will not persist! + * + * @access public + * @param string $class The calling classname, to prevent clashes + * @param string $var The variable to retrieve. + * @return mixed A reference to the variable. If not set it will be + * auto initialised to NULL. + */ + function &getStaticProperty($class, $var) + { + static $properties; + if (!isset($properties[$class])) { + $properties[$class] = array(); + } + + if (!array_key_exists($var, $properties[$class])) { + $properties[$class][$var] = null; + } + + return $properties[$class][$var]; + } + + // }}} + // {{{ registerShutdownFunc() + + /** + * Use this function to register a shutdown method for static + * classes. + * + * @access public + * @param mixed $func The function name (or array of class/method) to call + * @param mixed $args The arguments to pass to the function + * @return void + */ + function registerShutdownFunc($func, $args = array()) + { + // if we are called statically, there is a potential + // that no shutdown func is registered. Bug #6445 + if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { + register_shutdown_function("_PEAR_call_destructors"); + $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; + } + $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); + } + + // }}} + // {{{ isError() + + /** + * Tell whether a value is a PEAR error. + * + * @param mixed $data the value to test + * @param int $code if $data is an error object, return true + * only if $code is a string and + * $obj->getMessage() == $code or + * $code is an integer and $obj->getCode() == $code + * @access public + * @return bool true if parameter is an error + */ + function isError($data, $code = null) + { + if (!is_a($data, 'PEAR_Error')) { + return false; + } + + if (is_null($code)) { + return true; + } elseif (is_string($code)) { + return $data->getMessage() == $code; + } + + return $data->getCode() == $code; + } + + // }}} + // {{{ setErrorHandling() + + /** + * Sets how errors generated by this object should be handled. + * Can be invoked both in objects and statically. If called + * statically, setErrorHandling sets the default behaviour for all + * PEAR objects. If called in an object, setErrorHandling sets + * the default behaviour for that object. + * + * @param int $mode + * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, + * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, + * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. + * + * @param mixed $options + * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one + * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). + * + * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected + * to be the callback function or method. A callback + * function is a string with the name of the function, a + * callback method is an array of two elements: the element + * at index 0 is the object, and the element at index 1 is + * the name of the method to call in the object. + * + * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is + * a printf format string used when printing the error + * message. + * + * @access public + * @return void + * @see PEAR_ERROR_RETURN + * @see PEAR_ERROR_PRINT + * @see PEAR_ERROR_TRIGGER + * @see PEAR_ERROR_DIE + * @see PEAR_ERROR_CALLBACK + * @see PEAR_ERROR_EXCEPTION + * + * @since PHP 4.0.5 + */ + + function setErrorHandling($mode = null, $options = null) + { + if (isset($this) && is_a($this, 'PEAR')) { + $setmode = &$this->_default_error_mode; + $setoptions = &$this->_default_error_options; + } else { + $setmode = &$GLOBALS['_PEAR_default_error_mode']; + $setoptions = &$GLOBALS['_PEAR_default_error_options']; + } + + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $setmode = $mode; + $setoptions = $options; + break; + + case PEAR_ERROR_CALLBACK: + $setmode = $mode; + // class/object method callback + if (is_callable($options)) { + $setoptions = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + } + + // }}} + // {{{ expectError() + + /** + * This method is used to tell which errors you expect to get. + * Expected errors are always returned with error mode + * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, + * and this method pushes a new element onto it. The list of + * expected errors are in effect until they are popped off the + * stack with the popExpect() method. + * + * Note that this method can not be called statically + * + * @param mixed $code a single error code or an array of error codes to expect + * + * @return int the new depth of the "expected errors" stack + * @access public + */ + function expectError($code = '*') + { + if (is_array($code)) { + array_push($this->_expected_errors, $code); + } else { + array_push($this->_expected_errors, array($code)); + } + return sizeof($this->_expected_errors); + } + + // }}} + // {{{ popExpect() + + /** + * This method pops one element off the expected error codes + * stack. + * + * @return array the list of error codes that were popped + */ + function popExpect() + { + return array_pop($this->_expected_errors); + } + + // }}} + // {{{ _checkDelExpect() + + /** + * This method checks unsets an error code if available + * + * @param mixed error code + * @return bool true if the error code was unset, false otherwise + * @access private + * @since PHP 4.3.0 + */ + function _checkDelExpect($error_code) + { + $deleted = false; + + foreach ($this->_expected_errors AS $key => $error_array) { + if (in_array($error_code, $error_array)) { + unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); + $deleted = true; + } + + // clean up empty arrays + if (0 == count($this->_expected_errors[$key])) { + unset($this->_expected_errors[$key]); + } + } + return $deleted; + } + + // }}} + // {{{ delExpect() + + /** + * This method deletes all occurences of the specified element from + * the expected error codes stack. + * + * @param mixed $error_code error code that should be deleted + * @return mixed list of error codes that were deleted or error + * @access public + * @since PHP 4.3.0 + */ + function delExpect($error_code) + { + $deleted = false; + if ((is_array($error_code) && (0 != count($error_code)))) { + // $error_code is a non-empty array here; + // we walk through it trying to unset all + // values + foreach($error_code as $key => $error) { + if ($this->_checkDelExpect($error)) { + $deleted = true; + } else { + $deleted = false; + } + } + return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + } elseif (!empty($error_code)) { + // $error_code comes alone, trying to unset it + if ($this->_checkDelExpect($error_code)) { + return true; + } else { + return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + } + } + + // $error_code is empty + return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME + } + + // }}} + // {{{ raiseError() + + /** + * This method is a wrapper that returns an instance of the + * configured error class with this object's default error + * handling applied. If the $mode and $options parameters are not + * specified, the object's defaults are used. + * + * @param mixed $message a text error message or a PEAR error object + * + * @param int $code a numeric error code (it is up to your class + * to define these if you want to use codes) + * + * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, + * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, + * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. + * + * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter + * specifies the PHP-internal error level (one of + * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). + * If $mode is PEAR_ERROR_CALLBACK, this + * parameter specifies the callback function or + * method. In other error modes this parameter + * is ignored. + * + * @param string $userinfo If you need to pass along for example debug + * information, this parameter is meant for that. + * + * @param string $error_class The returned error object will be + * instantiated from this class, if specified. + * + * @param bool $skipmsg If true, raiseError will only pass error codes, + * the error message parameter will be dropped. + * + * @access public + * @return object a PEAR error object + * @see PEAR::setErrorHandling + * @since PHP 4.0.5 + */ + function &raiseError($message = null, + $code = null, + $mode = null, + $options = null, + $userinfo = null, + $error_class = null, + $skipmsg = false) + { + // The error is yet a PEAR error object + if (is_object($message)) { + $code = $message->getCode(); + $userinfo = $message->getUserInfo(); + $error_class = $message->getType(); + $message->error_message_prefix = ''; + $message = $message->getMessage(); + } + + if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) { + if ($exp[0] == "*" || + (is_int(reset($exp)) && in_array($code, $exp)) || + (is_string(reset($exp)) && in_array($message, $exp))) { + $mode = PEAR_ERROR_RETURN; + } + } + + // No mode given, try global ones + if ($mode === null) { + // Class error handler + if (isset($this) && isset($this->_default_error_mode)) { + $mode = $this->_default_error_mode; + $options = $this->_default_error_options; + // Global error handler + } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { + $mode = $GLOBALS['_PEAR_default_error_mode']; + $options = $GLOBALS['_PEAR_default_error_options']; + } + } + + if ($error_class !== null) { + $ec = $error_class; + } elseif (isset($this) && isset($this->_error_class)) { + $ec = $this->_error_class; + } else { + $ec = 'PEAR_Error'; + } + + if (intval(PHP_VERSION) < 5) { + // little non-eval hack to fix bug #12147 + include 'PEAR/FixPHP5PEARWarnings.php'; + return $a; + } + + if ($skipmsg) { + $a = new $ec($code, $mode, $options, $userinfo); + } else { + $a = new $ec($message, $code, $mode, $options, $userinfo); + } + + return $a; + } + + // }}} + // {{{ throwError() + + /** + * Simpler form of raiseError with fewer options. In most cases + * message, code and userinfo are enough. + * + * @param string $message + * + */ + function &throwError($message = null, + $code = null, + $userinfo = null) + { + if (isset($this) && is_a($this, 'PEAR')) { + $a = &$this->raiseError($message, $code, null, null, $userinfo); + return $a; + } + + $a = &PEAR::raiseError($message, $code, null, null, $userinfo); + return $a; + } + + // }}} + function staticPushErrorHandling($mode, $options = null) + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_options = &$GLOBALS['_PEAR_default_error_options']; + $stack[] = array($def_mode, $def_options); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $def_mode = $mode; + $def_options = $options; + break; + + case PEAR_ERROR_CALLBACK: + $def_mode = $mode; + // class/object method callback + if (is_callable($options)) { + $def_options = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + $stack[] = array($mode, $options); + return true; + } + + function staticPopErrorHandling() + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $setmode = &$GLOBALS['_PEAR_default_error_mode']; + $setoptions = &$GLOBALS['_PEAR_default_error_options']; + array_pop($stack); + list($mode, $options) = $stack[sizeof($stack) - 1]; + array_pop($stack); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $setmode = $mode; + $setoptions = $options; + break; + + case PEAR_ERROR_CALLBACK: + $setmode = $mode; + // class/object method callback + if (is_callable($options)) { + $setoptions = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + return true; + } + + // {{{ pushErrorHandling() + + /** + * Push a new error handler on top of the error handler options stack. With this + * you can easily override the actual error handler for some code and restore + * it later with popErrorHandling. + * + * @param mixed $mode (same as setErrorHandling) + * @param mixed $options (same as setErrorHandling) + * + * @return bool Always true + * + * @see PEAR::setErrorHandling + */ + function pushErrorHandling($mode, $options = null) + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + if (isset($this) && is_a($this, 'PEAR')) { + $def_mode = &$this->_default_error_mode; + $def_options = &$this->_default_error_options; + } else { + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_options = &$GLOBALS['_PEAR_default_error_options']; + } + $stack[] = array($def_mode, $def_options); + + if (isset($this) && is_a($this, 'PEAR')) { + $this->setErrorHandling($mode, $options); + } else { + PEAR::setErrorHandling($mode, $options); + } + $stack[] = array($mode, $options); + return true; + } + + // }}} + // {{{ popErrorHandling() + + /** + * Pop the last error handler used + * + * @return bool Always true + * + * @see PEAR::pushErrorHandling + */ + function popErrorHandling() + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + array_pop($stack); + list($mode, $options) = $stack[sizeof($stack) - 1]; + array_pop($stack); + if (isset($this) && is_a($this, 'PEAR')) { + $this->setErrorHandling($mode, $options); + } else { + PEAR::setErrorHandling($mode, $options); + } + return true; + } + + // }}} + // {{{ loadExtension() + + /** + * OS independant PHP extension load. Remember to take care + * on the correct extension name for case sensitive OSes. + * + * @param string $ext The extension name + * @return bool Success or not on the dl() call + */ + function loadExtension($ext) + { + if (!extension_loaded($ext)) { + // if either returns true dl() will produce a FATAL error, stop that + if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) { + return false; + } + + if (OS_WINDOWS) { + $suffix = '.dll'; + } elseif (PHP_OS == 'HP-UX') { + $suffix = '.sl'; + } elseif (PHP_OS == 'AIX') { + $suffix = '.a'; + } elseif (PHP_OS == 'OSX') { + $suffix = '.bundle'; + } else { + $suffix = '.so'; + } + + return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); + } + + return true; + } + + // }}} +} + +if (PEAR_ZE2) { + include_once 'PEAR5.php'; +} + +// {{{ _PEAR_call_destructors() + +function _PEAR_call_destructors() +{ + global $_PEAR_destructor_object_list; + if (is_array($_PEAR_destructor_object_list) && + sizeof($_PEAR_destructor_object_list)) + { + reset($_PEAR_destructor_object_list); + if (PEAR_ZE2) { + $destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo'); + } else { + $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); + } + + if ($destructLifoExists) { + $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); + } + + while (list($k, $objref) = each($_PEAR_destructor_object_list)) { + $classname = get_class($objref); + while ($classname) { + $destructor = "_$classname"; + if (method_exists($objref, $destructor)) { + $objref->$destructor(); + break; + } else { + $classname = get_parent_class($classname); + } + } + } + // Empty the object list to ensure that destructors are + // not called more than once. + $_PEAR_destructor_object_list = array(); + } + + // Now call the shutdown functions + if (isset($GLOBALS['_PEAR_shutdown_funcs']) AND is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { + foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { + call_user_func_array($value[0], $value[1]); + } + } +} + +// }}} +/** + * Standard PEAR error class for PHP 4 + * + * This class is supserseded by {@link PEAR_Exception} in PHP 5 + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V.V. Cox + * @author Gregory Beaver + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/manual/en/core.pear.pear-error.php + * @see PEAR::raiseError(), PEAR::throwError() + * @since Class available since PHP 4.0.2 + */ +class PEAR_Error +{ + // {{{ properties + + var $error_message_prefix = ''; + var $mode = PEAR_ERROR_RETURN; + var $level = E_USER_NOTICE; + var $code = -1; + var $message = ''; + var $userinfo = ''; + var $backtrace = null; + + // }}} + // {{{ constructor + + /** + * PEAR_Error constructor + * + * @param string $message message + * + * @param int $code (optional) error code + * + * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, + * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, + * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION + * + * @param mixed $options (optional) error level, _OR_ in the case of + * PEAR_ERROR_CALLBACK, the callback function or object/method + * tuple. + * + * @param string $userinfo (optional) additional user/debug info + * + * @access public + * + */ + function PEAR_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + if ($mode === null) { + $mode = PEAR_ERROR_RETURN; + } + $this->message = $message; + $this->code = $code; + $this->mode = $mode; + $this->userinfo = $userinfo; + + if (PEAR_ZE2) { + $skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace'); + } else { + $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); + } + + if (!$skiptrace) { + $this->backtrace = debug_backtrace(); + if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) { + unset($this->backtrace[0]['object']); + } + } + + if ($mode & PEAR_ERROR_CALLBACK) { + $this->level = E_USER_NOTICE; + $this->callback = $options; + } else { + if ($options === null) { + $options = E_USER_NOTICE; + } + + $this->level = $options; + $this->callback = null; + } + + if ($this->mode & PEAR_ERROR_PRINT) { + if (is_null($options) || is_int($options)) { + $format = "%s"; + } else { + $format = $options; + } + + printf($format, $this->getMessage()); + } + + if ($this->mode & PEAR_ERROR_TRIGGER) { + trigger_error($this->getMessage(), $this->level); + } + + if ($this->mode & PEAR_ERROR_DIE) { + $msg = $this->getMessage(); + if (is_null($options) || is_int($options)) { + $format = "%s"; + if (substr($msg, -1) != "\n") { + $msg .= "\n"; + } + } else { + $format = $options; + } + die(sprintf($format, $msg)); + } + + if ($this->mode & PEAR_ERROR_CALLBACK) { + if (is_callable($this->callback)) { + call_user_func($this->callback, $this); + } + } + + if ($this->mode & PEAR_ERROR_EXCEPTION) { + trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); + eval('$e = new Exception($this->message, $this->code);throw($e);'); + } + } + + // }}} + // {{{ getMode() + + /** + * Get the error mode from an error object. + * + * @return int error mode + * @access public + */ + function getMode() { + return $this->mode; + } + + // }}} + // {{{ getCallback() + + /** + * Get the callback function/method from an error object. + * + * @return mixed callback function or object/method array + * @access public + */ + function getCallback() { + return $this->callback; + } + + // }}} + // {{{ getMessage() + + + /** + * Get the error message from an error object. + * + * @return string full error message + * @access public + */ + function getMessage() + { + return ($this->error_message_prefix . $this->message); + } + + + // }}} + // {{{ getCode() + + /** + * Get error code from an error object + * + * @return int error code + * @access public + */ + function getCode() + { + return $this->code; + } + + // }}} + // {{{ getType() + + /** + * Get the name of this error/exception. + * + * @return string error/exception name (type) + * @access public + */ + function getType() + { + return get_class($this); + } + + // }}} + // {{{ getUserInfo() + + /** + * Get additional user-supplied information. + * + * @return string user-supplied information + * @access public + */ + function getUserInfo() + { + return $this->userinfo; + } + + // }}} + // {{{ getDebugInfo() + + /** + * Get additional debug information supplied by the application. + * + * @return string debug information + * @access public + */ + function getDebugInfo() + { + return $this->getUserInfo(); + } + + // }}} + // {{{ getBacktrace() + + /** + * Get the call backtrace from where the error was generated. + * Supported with PHP 4.3.0 or newer. + * + * @param int $frame (optional) what frame to fetch + * @return array Backtrace, or NULL if not available. + * @access public + */ + function getBacktrace($frame = null) + { + if (defined('PEAR_IGNORE_BACKTRACE')) { + return null; + } + if ($frame === null) { + return $this->backtrace; + } + return $this->backtrace[$frame]; + } + + // }}} + // {{{ addUserInfo() + + function addUserInfo($info) + { + if (empty($this->userinfo)) { + $this->userinfo = $info; + } else { + $this->userinfo .= " ** $info"; + } + } + + // }}} + // {{{ toString() + function __toString() + { + return $this->getMessage(); + } + // }}} + // {{{ toString() + + /** + * Make a string representation of this object. + * + * @return string a string with an object summary + * @access public + */ + function toString() { + $modes = array(); + $levels = array(E_USER_NOTICE => 'notice', + E_USER_WARNING => 'warning', + E_USER_ERROR => 'error'); + if ($this->mode & PEAR_ERROR_CALLBACK) { + if (is_array($this->callback)) { + $callback = (is_object($this->callback[0]) ? + strtolower(get_class($this->callback[0])) : + $this->callback[0]) . '::' . + $this->callback[1]; + } else { + $callback = $this->callback; + } + return sprintf('[%s: message="%s" code=%d mode=callback '. + 'callback=%s prefix="%s" info="%s"]', + strtolower(get_class($this)), $this->message, $this->code, + $callback, $this->error_message_prefix, + $this->userinfo); + } + if ($this->mode & PEAR_ERROR_PRINT) { + $modes[] = 'print'; + } + if ($this->mode & PEAR_ERROR_TRIGGER) { + $modes[] = 'trigger'; + } + if ($this->mode & PEAR_ERROR_DIE) { + $modes[] = 'die'; + } + if ($this->mode & PEAR_ERROR_RETURN) { + $modes[] = 'return'; + } + return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. + 'prefix="%s" info="%s"]', + strtolower(get_class($this)), $this->message, $this->code, + implode("|", $modes), $levels[$this->level], + $this->error_message_prefix, + $this->userinfo); + } + + // }}} +} + +/* + * Local Variables: + * mode: php + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ +PEAR-1.9.0/README100664 764 764 2246 100664 6172 PEAR - The PEAR Installer +========================= + +What is the PEAR Installer? What is PEAR? + +PEAR is the PHP Extension and Application Repository, found at +http://pear.php.net. The PEAR Installer is this software, which +contains executable files and PHP code that is used to download +and install PEAR code from pear.php.net. + +PEAR contains useful software libraries and applications such as +MDB2 (database abstraction), HTML_QuickForm (HTML forms management), +PhpDocumentor (auto-documentation generator), DB_DataObject +(Data Access Abstraction), and many hundreds more. Browse all +available packages at http://pear.php.net, the list is constantly +growing and updating to reflect improvements in the PHP language. + +DOCUMENTATION +============= + +Documentation for PEAR can be found at http://pear.php.net/manual/. +Installation documentation can be found in the INSTALL file included +in this tarball. + +WARNING: DO NOT RUN PEAR WITHOUT INSTALLING IT - if you downloaded this +tarball manually, you MUST install it. Read the instructions in INSTALL +prior to use. + + +Happy PHPing, we hope PEAR will be a great tool for your development work! + +$Id: README 220345 2006-09-22 03:31:36Z cellog $PEAR-1.9.0/System.php100664 764 764 46777 100664 7350 + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: System.php 276386 2009-02-24 23:52:56Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'PEAR.php'; +require_once 'Console/Getopt.php'; + +$GLOBALS['_System_temp_files'] = array(); + +/** +* System offers cross plattform compatible system functions +* +* Static functions for different operations. Should work under +* Unix and Windows. The names and usage has been taken from its respectively +* GNU commands. The functions will return (bool) false on error and will +* trigger the error with the PHP trigger_error() function (you can silence +* the error by prefixing a '@' sign after the function call, but this +* is not recommended practice. Instead use an error handler with +* {@link set_error_handler()}). +* +* Documentation on this class you can find in: +* http://pear.php.net/manual/ +* +* Example usage: +* if (!@System::rm('-r file1 dir1')) { +* print "could not delete file1 or dir1"; +* } +* +* In case you need to to pass file names with spaces, +* pass the params as an array: +* +* System::rm(array('-r', $file1, $dir1)); +* +* @category pear +* @package System +* @author Tomas V.V. Cox +* @copyright 1997-2006 The PHP Group +* @license http://opensource.org/licenses/bsd-license.php New BSD License +* @version Release: 1.9.0 +* @link http://pear.php.net/package/PEAR +* @since Class available since Release 0.1 +* @static +*/ +class System +{ + /** + * returns the commandline arguments of a function + * + * @param string $argv the commandline + * @param string $short_options the allowed option short-tags + * @param string $long_options the allowed option long-tags + * @return array the given options and there values + * @static + * @access private + */ + function _parseArgs($argv, $short_options, $long_options = null) + { + if (!is_array($argv) && $argv !== null) { + $argv = preg_split('/\s+/', $argv, -1, PREG_SPLIT_NO_EMPTY); + } + return Console_Getopt::getopt2($argv, $short_options); + } + + /** + * Output errors with PHP trigger_error(). You can silence the errors + * with prefixing a "@" sign to the function call: @System::mkdir(..); + * + * @param mixed $error a PEAR error or a string with the error message + * @return bool false + * @static + * @access private + */ + function raiseError($error) + { + if (PEAR::isError($error)) { + $error = $error->getMessage(); + } + trigger_error($error, E_USER_WARNING); + return false; + } + + /** + * Creates a nested array representing the structure of a directory + * + * System::_dirToStruct('dir1', 0) => + * Array + * ( + * [dirs] => Array + * ( + * [0] => dir1 + * ) + * + * [files] => Array + * ( + * [0] => dir1/file2 + * [1] => dir1/file3 + * ) + * ) + * @param string $sPath Name of the directory + * @param integer $maxinst max. deep of the lookup + * @param integer $aktinst starting deep of the lookup + * @param bool $silent if true, do not emit errors. + * @return array the structure of the dir + * @static + * @access private + */ + function _dirToStruct($sPath, $maxinst, $aktinst = 0, $silent = false) + { + $struct = array('dirs' => array(), 'files' => array()); + if (($dir = @opendir($sPath)) === false) { + if (!$silent) { + System::raiseError("Could not open dir $sPath"); + } + return $struct; // XXX could not open error + } + + $struct['dirs'][] = $sPath = realpath($sPath); // XXX don't add if '.' or '..' ? + $list = array(); + while (false !== ($file = readdir($dir))) { + if ($file != '.' && $file != '..') { + $list[] = $file; + } + } + + closedir($dir); + natsort($list); + if ($aktinst < $maxinst || $maxinst == 0) { + foreach ($list as $val) { + $path = $sPath . DIRECTORY_SEPARATOR . $val; + if (is_dir($path) && !is_link($path)) { + $tmp = System::_dirToStruct($path, $maxinst, $aktinst+1, $silent); + $struct = array_merge_recursive($struct, $tmp); + } else { + $struct['files'][] = $path; + } + } + } + + return $struct; + } + + /** + * Creates a nested array representing the structure of a directory and files + * + * @param array $files Array listing files and dirs + * @return array + * @static + * @see System::_dirToStruct() + */ + function _multipleToStruct($files) + { + $struct = array('dirs' => array(), 'files' => array()); + settype($files, 'array'); + foreach ($files as $file) { + if (is_dir($file) && !is_link($file)) { + $tmp = System::_dirToStruct($file, 0); + $struct = array_merge_recursive($tmp, $struct); + } else { + if (!in_array($file, $struct['files'])) { + $struct['files'][] = $file; + } + } + } + return $struct; + } + + /** + * The rm command for removing files. + * Supports multiple files and dirs and also recursive deletes + * + * @param string $args the arguments for rm + * @return mixed PEAR_Error or true for success + * @static + * @access public + */ + function rm($args) + { + $opts = System::_parseArgs($args, 'rf'); // "f" does nothing but I like it :-) + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + foreach ($opts[0] as $opt) { + if ($opt[0] == 'r') { + $do_recursive = true; + } + } + $ret = true; + if (isset($do_recursive)) { + $struct = System::_multipleToStruct($opts[1]); + foreach ($struct['files'] as $file) { + if (!@unlink($file)) { + $ret = false; + } + } + + rsort($struct['dirs']); + foreach ($struct['dirs'] as $dir) { + if (!@rmdir($dir)) { + $ret = false; + } + } + } else { + foreach ($opts[1] as $file) { + $delete = (is_dir($file)) ? 'rmdir' : 'unlink'; + if (!@$delete($file)) { + $ret = false; + } + } + } + return $ret; + } + + /** + * Make directories. + * + * The -p option will create parent directories + * @param string $args the name of the director(y|ies) to create + * @return bool True for success + * @static + * @access public + */ + function mkDir($args) + { + $opts = System::_parseArgs($args, 'pm:'); + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + + $mode = 0777; // default mode + foreach ($opts[0] as $opt) { + if ($opt[0] == 'p') { + $create_parents = true; + } elseif ($opt[0] == 'm') { + // if the mode is clearly an octal number (starts with 0) + // convert it to decimal + if (strlen($opt[1]) && $opt[1]{0} == '0') { + $opt[1] = octdec($opt[1]); + } else { + // convert to int + $opt[1] += 0; + } + $mode = $opt[1]; + } + } + + $ret = true; + if (isset($create_parents)) { + foreach ($opts[1] as $dir) { + $dirstack = array(); + while ((!file_exists($dir) || !is_dir($dir)) && + $dir != DIRECTORY_SEPARATOR) { + array_unshift($dirstack, $dir); + $dir = dirname($dir); + } + + while ($newdir = array_shift($dirstack)) { + if (!is_writeable(dirname($newdir))) { + $ret = false; + break; + } + + if (!mkdir($newdir, $mode)) { + $ret = false; + } + } + } + } else { + foreach($opts[1] as $dir) { + if ((@file_exists($dir) || !is_dir($dir)) && !mkdir($dir, $mode)) { + $ret = false; + } + } + } + + return $ret; + } + + /** + * Concatenate files + * + * Usage: + * 1) $var = System::cat('sample.txt test.txt'); + * 2) System::cat('sample.txt test.txt > final.txt'); + * 3) System::cat('sample.txt test.txt >> final.txt'); + * + * Note: as the class use fopen, urls should work also (test that) + * + * @param string $args the arguments + * @return boolean true on success + * @static + * @access public + */ + function &cat($args) + { + $ret = null; + $files = array(); + if (!is_array($args)) { + $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); + } + + $count_args = count($args); + for ($i = 0; $i < $count_args; $i++) { + if ($args[$i] == '>') { + $mode = 'wb'; + $outputfile = $args[$i+1]; + break; + } elseif ($args[$i] == '>>') { + $mode = 'ab+'; + $outputfile = $args[$i+1]; + break; + } else { + $files[] = $args[$i]; + } + } + $outputfd = false; + if (isset($mode)) { + if (!$outputfd = fopen($outputfile, $mode)) { + $err = System::raiseError("Could not open $outputfile"); + return $err; + } + $ret = true; + } + foreach ($files as $file) { + if (!$fd = fopen($file, 'r')) { + System::raiseError("Could not open $file"); + continue; + } + while ($cont = fread($fd, 2048)) { + if (is_resource($outputfd)) { + fwrite($outputfd, $cont); + } else { + $ret .= $cont; + } + } + fclose($fd); + } + if (is_resource($outputfd)) { + fclose($outputfd); + } + return $ret; + } + + /** + * Creates temporary files or directories. This function will remove + * the created files when the scripts finish its execution. + * + * Usage: + * 1) $tempfile = System::mktemp("prefix"); + * 2) $tempdir = System::mktemp("-d prefix"); + * 3) $tempfile = System::mktemp(); + * 4) $tempfile = System::mktemp("-t /var/tmp prefix"); + * + * prefix -> The string that will be prepended to the temp name + * (defaults to "tmp"). + * -d -> A temporary dir will be created instead of a file. + * -t -> The target dir where the temporary (file|dir) will be created. If + * this param is missing by default the env vars TMP on Windows or + * TMPDIR in Unix will be used. If these vars are also missing + * c:\windows\temp or /tmp will be used. + * + * @param string $args The arguments + * @return mixed the full path of the created (file|dir) or false + * @see System::tmpdir() + * @static + * @access public + */ + function mktemp($args = null) + { + static $first_time = true; + $opts = System::_parseArgs($args, 't:d'); + if (PEAR::isError($opts)) { + return System::raiseError($opts); + } + + foreach ($opts[0] as $opt) { + if ($opt[0] == 'd') { + $tmp_is_dir = true; + } elseif ($opt[0] == 't') { + $tmpdir = $opt[1]; + } + } + + $prefix = (isset($opts[1][0])) ? $opts[1][0] : 'tmp'; + if (!isset($tmpdir)) { + $tmpdir = System::tmpdir(); + } + + if (!System::mkDir(array('-p', $tmpdir))) { + return false; + } + + $tmp = tempnam($tmpdir, $prefix); + if (isset($tmp_is_dir)) { + unlink($tmp); // be careful possible race condition here + if (!mkdir($tmp, 0700)) { + return System::raiseError("Unable to create temporary directory $tmpdir"); + } + } + + $GLOBALS['_System_temp_files'][] = $tmp; + if (isset($tmp_is_dir)) { + //$GLOBALS['_System_temp_files'][] = dirname($tmp); + } + + if ($first_time) { + PEAR::registerShutdownFunc(array('System', '_removeTmpFiles')); + $first_time = false; + } + + return $tmp; + } + + /** + * Remove temporary files created my mkTemp. This function is executed + * at script shutdown time + * + * @static + * @access private + */ + function _removeTmpFiles() + { + if (count($GLOBALS['_System_temp_files'])) { + $delete = $GLOBALS['_System_temp_files']; + array_unshift($delete, '-r'); + System::rm($delete); + $GLOBALS['_System_temp_files'] = array(); + } + } + + /** + * Get the path of the temporal directory set in the system + * by looking in its environments variables. + * Note: php.ini-recommended removes the "E" from the variables_order setting, + * making unavaible the $_ENV array, that s why we do tests with _ENV + * + * @static + * @return string The temporary directory on the system + */ + function tmpdir() + { + if (OS_WINDOWS) { + if ($var = isset($_ENV['TMP']) ? $_ENV['TMP'] : getenv('TMP')) { + return $var; + } + if ($var = isset($_ENV['TEMP']) ? $_ENV['TEMP'] : getenv('TEMP')) { + return $var; + } + if ($var = isset($_ENV['USERPROFILE']) ? $_ENV['USERPROFILE'] : getenv('USERPROFILE')) { + return $var; + } + if ($var = isset($_ENV['windir']) ? $_ENV['windir'] : getenv('windir')) { + return $var; + } + return getenv('SystemRoot') . '\temp'; + } + if ($var = isset($_ENV['TMPDIR']) ? $_ENV['TMPDIR'] : getenv('TMPDIR')) { + return $var; + } + return realpath('/tmp'); + } + + /** + * The "which" command (show the full path of a command) + * + * @param string $program The command to search for + * @param mixed $fallback Value to return if $program is not found + * + * @return mixed A string with the full path or false if not found + * @static + * @author Stig Bakken + */ + function which($program, $fallback = false) + { + // enforce API + if (!is_string($program) || '' == $program) { + return $fallback; + } + + // full path given + if (basename($program) != $program) { + $path_elements[] = dirname($program); + $program = basename($program); + } else { + // Honor safe mode + if (!ini_get('safe_mode') || !$path = ini_get('safe_mode_exec_dir')) { + $path = getenv('PATH'); + if (!$path) { + $path = getenv('Path'); // some OSes are just stupid enough to do this + } + } + $path_elements = explode(PATH_SEPARATOR, $path); + } + + if (OS_WINDOWS) { + $exe_suffixes = getenv('PATHEXT') + ? explode(PATH_SEPARATOR, getenv('PATHEXT')) + : array('.exe','.bat','.cmd','.com'); + // allow passing a command.exe param + if (strpos($program, '.') !== false) { + array_unshift($exe_suffixes, ''); + } + // is_executable() is not available on windows for PHP4 + $pear_is_executable = (function_exists('is_executable')) ? 'is_executable' : 'is_file'; + } else { + $exe_suffixes = array(''); + $pear_is_executable = 'is_executable'; + } + + foreach ($exe_suffixes as $suff) { + foreach ($path_elements as $dir) { + $file = $dir . DIRECTORY_SEPARATOR . $program . $suff; + if (@$pear_is_executable($file)) { + return $file; + } + } + } + return $fallback; + } + + /** + * The "find" command + * + * Usage: + * + * System::find($dir); + * System::find("$dir -type d"); + * System::find("$dir -type f"); + * System::find("$dir -name *.php"); + * System::find("$dir -name *.php -name *.htm*"); + * System::find("$dir -maxdepth 1"); + * + * Params implmented: + * $dir -> Start the search at this directory + * -type d -> return only directories + * -type f -> return only files + * -maxdepth -> max depth of recursion + * -name -> search pattern (bash style). Multiple -name param allowed + * + * @param mixed Either array or string with the command line + * @return array Array of found files + * @static + * + */ + function find($args) + { + if (!is_array($args)) { + $args = preg_split('/\s+/', $args, -1, PREG_SPLIT_NO_EMPTY); + } + $dir = realpath(array_shift($args)); + if (!$dir) { + return array(); + } + $patterns = array(); + $depth = 0; + $do_files = $do_dirs = true; + $args_count = count($args); + for ($i = 0; $i < $args_count; $i++) { + switch ($args[$i]) { + case '-type': + if (in_array($args[$i+1], array('d', 'f'))) { + if ($args[$i+1] == 'd') { + $do_files = false; + } else { + $do_dirs = false; + } + } + $i++; + break; + case '-name': + $name = preg_quote($args[$i+1], '#'); + // our magic characters ? and * have just been escaped, + // so now we change the escaped versions to PCRE operators + $name = strtr($name, array('\?' => '.', '\*' => '.*')); + $patterns[] = '('.$name.')'; + $i++; + break; + case '-maxdepth': + $depth = $args[$i+1]; + break; + } + } + $path = System::_dirToStruct($dir, $depth, 0, true); + if ($do_files && $do_dirs) { + $files = array_merge($path['files'], $path['dirs']); + } elseif ($do_dirs) { + $files = $path['dirs']; + } else { + $files = $path['files']; + } + if (count($patterns)) { + $dsq = preg_quote(DIRECTORY_SEPARATOR, '#'); + $pattern = '#(^|'.$dsq.')'.implode('|', $patterns).'($|'.$dsq.')#'; + $ret = array(); + $files_count = count($files); + for ($i = 0; $i < $files_count; $i++) { + // only search in the part of the file below the current directory + $filepart = basename($files[$i]); + if (preg_match($pattern, $filepart)) { + $ret[] = $files[$i]; + } + } + return $ret; + } + return $files; + } +}PEAR-1.9.0/template.spec100664 764 764 3725 100664 10004 Summary: PEAR: @summary@ +Name: @rpm_package@ +Version: @version@ +Release: 1 +License: @release_license@ +Group: Development/Libraries +Source: http://@master_server@/get/@package@-%{version}.tgz +BuildRoot: %{_tmppath}/%{name}-root +URL: http://@master_server@/package/@package@ +Prefix: %{_prefix} +BuildArchitectures: @arch@ +@extra_headers@ + +%description +@description@ + +%prep +rm -rf %{buildroot}/* +%setup -c -T +# XXX Source files location is missing here in pear cmd +pear -v -c %{buildroot}/pearrc \ + -d php_dir=%{_libdir}/php/pear \ + -d doc_dir=/docs \ + -d bin_dir=%{_bindir} \ + -d data_dir=%{_libdir}/php/pear/data \ + -d test_dir=%{_libdir}/php/pear/tests \ + -d ext_dir=%{_libdir} \@extra_config@ + -s + +%build +echo BuildRoot=%{buildroot} + +%postun +# if refcount = 0 then package has been removed (not upgraded) +if [ "$1" -eq "0" ]; then + pear uninstall --nodeps -r @possible_channel@@package@ + rm @rpm_xml_dir@/@package@.xml +fi + + +%post +# if refcount = 2 then package has been upgraded +if [ "$1" -ge "2" ]; then + pear upgrade --nodeps -r @rpm_xml_dir@/@package@.xml +else + pear install --nodeps -r @rpm_xml_dir@/@package@.xml +fi + +%install +pear -c %{buildroot}/pearrc install --nodeps -R %{buildroot} \ + $RPM_SOURCE_DIR/@package@-%{version}.tgz +rm %{buildroot}/pearrc +rm %{buildroot}/%{_libdir}/php/pear/.filemap +rm %{buildroot}/%{_libdir}/php/pear/.lock +rm -rf %{buildroot}/%{_libdir}/php/pear/.registry +if [ "@doc_files@" != "" ]; then + mv %{buildroot}/docs/@package@/* . + rm -rf %{buildroot}/docs +fi +mkdir -p %{buildroot}@rpm_xml_dir@ +tar -xzf $RPM_SOURCE_DIR/@package@-%{version}.tgz package@package2xml@.xml +cp -p package@package2xml@.xml %{buildroot}@rpm_xml_dir@/@package@.xml + +#rm -rf %{buildroot}/* +#pear -q install -R %{buildroot} -n package@package2xml@.xml +#mkdir -p %{buildroot}@rpm_xml_dir@ +#cp -p package@package2xml@.xml %{buildroot}@rpm_xml_dir@/@package@.xml + +%files + %defattr(-,root,root) + %doc @doc_files@ + / +package.xml100664 764 764 76000 100664 6254 + + + PEAR + PEAR Base System + The PEAR package contains: + * the PEAR installer, for creating, distributing + and installing packages + * the PEAR_Exception PHP5 error handling mechanism + * the PEAR_ErrorStack advanced error handling mechanism + * the PEAR_Error error handling mechanism + * the OS_Guess class for retrieving info about the OS + where PHP is running on + * the System class for quick handling of common operations + with files and directories + * the PEAR base class + + Features in a nutshell: + * full support for channels + * pre-download dependency validation + * new package.xml 2.0 format allows tremendous flexibility while maintaining BC + * support for optional dependency groups and limited support for sub-packaging + * robust dependency support + * full dependency validation on uninstall + * remote install for hosts with only ftp access - no more problems with restricted host installation * full support for mirroring * support for bundling several packages into a single tarball @@ -53761,14 +54340,11 @@ cp -p package@package2xml@.xml %{buildroot}@rpm_xml_dir@/@package@.xml - 1.8.0 - 2009-04-10 + 1.9.0 + 2009-09-03 New BSD License stable - * Fix Bug #14792: Bad md5sum for files with replaced content [dufuz] -* Fix Bug #16057:-r is limited to 4 directories in depth [dufuz] -* Fix Bug #16077: PEAR5::getStaticProperty does not return a reference to the property [dufuz] -Remove custom XML_Util class in favor of using upstream XML_Util package as dependency + * Fix Bug #16547: The phar for PEAR installer uses ereg() which is deprecated [dufuz] @@ -54062,6 +54638,7 @@ Remove custom XML_Util class in favor of using upstream XML_Util package as depe + @@ -54136,2163 +54713,6705 @@ Move codebase from the PHP License to New BSD 2 clause license - 1.8.0RC1 - 2009-03-27 + 1.8.0RC1 + 2009-03-27 + New BSD License + beta + * Fix Bug #14331: pear cvstag only works from inside the package directory [dufuz] +* Fix Bug #16045: E_Notice: Undefined index: channel in PEAR/DependencyDB.php [dufuz] +* Implemented Request #11230: better error message when mirror not in channel.xml file [dufuz] +* Implemented Request #13150: Add support for following HTTP 302 redirects [dufuz] + + + + + + New BSD License + Changes since RC1: + * Fix Bug #14792: Bad md5sum for files with replaced content [dufuz] + * Fix Bug #16057:-r is limited to 4 directories in depth [dufuz] + * Fix Bug #16077: PEAR5::getStaticProperty does not return a reference to the property [dufuz] + + Remove custom XML_Util class in favor of using upstream XML_Util package as dependency + +RC1 Release Notes: + * Fix Bug #14331: pear cvstag only works from inside the package directory [dufuz] + * Fix Bug #16045: E_Notice: Undefined index: channel in PEAR/DependencyDB.php [dufuz] + + * Implemented Request #11230: better error message when mirror not in channel.xml file [dufuz] + * Implemented Request #13150: Add support for following HTTP 302 redirects [dufuz] + +Alpha1 Release Notes: + * Implement Request #10373: if pref_state=stable and installed package=beta, allow up to latest beta version [dufuz] + * Implement Request #10581: login / logout should map to channel-login / channel-logout [dufuz] + * Implement Request #10825: Only display the "invalid or missing package file"-error if it makes sense [dufuz] + * Implement Request #11170: script to generate Command/[command].xml [dufuz] + * Implement Request #11176: improve channel ... has updated its protocols message [dufuz] + * Implement Request #12706: pear list -a hard to read [dufuz] + * Implement Request #11353: upgrade-all and upgrade commands to upgrade within the same stability level [dufuz] + * Implement Request #13015: Add https discovery for channel.xml [dufuz / initial patch by Martin Roos] + * Implement Request #13927: install-pear.php should have option to set www_dir [timj] + * Implement Request #14324: Make the pear install command behave similar to apt-get [dufuz] + * Implement Request #14325: make pear upgrade with no params behave like pear upgrade-all [dufuz] + - upgrade-all can be considered deprecated in favor of calling upgrade with no parameters to replicate + better what other package managers are doing. upgrade-all will still work as intended. + * Implement Request #14504: add a channel parameter support to the upgrade function [dufuz] + - Options -c ezc and --channel=ezc got added to upgrade and upgrade-all to allow for + channel specific upgrades + * Implement Request #14556: install-pear-nozlib.phar should get download_dir config and other options [cweiske] + * Implement Request #15566: Add doc.php.net as a default channel [dufuz / saltybeagle] + + * Fix PHP Bug #43857: --program-suffix not always reflected everywhere [cellog] + * Fix PHP Bug #47323: strotime warnings in make install [dufuz] + + * Fix Bug #13908: pear info command and maintainers inactive not mentioned [dufuz] + * Fix Bug #13926: install-pear.php does not set cfg_dir if -d option set with no -c option [timj] + * Fix Bug #13943: tests fail when php.exe path contains spaces [dufuz / jorrit] + * Fix Bug #13953: config-set/config-show with channel alias fail [cellog] + * Fix Bug #13958: When a phpt tests exit() or die() xdebug coverage is not generated, patch by izi (David Jean Louis) [izi / dufuz] + * Fix Bug #14041: Unpredictable unit test processing sequence [dufuz] + * Fix Bug #14140: Strict warning not suppressed in the shutdown function [dufuz] + * Fix Bug #14210: pear list -ia brings warnings [dufuz] + * Fix Bug #14274: PEAR packager mangles package.xml encoding, then complains about it [dufuz] + * Fix Bug #14287: cannot upgrade from stable to beta via -beta when config is set to stable [dufuz] + * Fix Bug #14300: Package files themselves can not be served over https [dufuz / initial patch by Martin Roos] + * Fix Bug #14437: openbasedir warning when loading config [dufuz] + * Fix Bug #14558: PackageFile.php creates tmp directory outside configured temp_dir [cweiske] + * Fix Bug #14947: downloadHttp() is missing Host part of the HTTP Request when using Proxy [ifeghali] + * Fix Bug #14977: PEAR/Frontend.php doesn't require_once PEAR.php [dufuz] + * Fix Bug #15750: Unreachable code in PEAR_Downloader [dufuz] + * Fix Bug #15979: Package files incorrectly removed when splitting a package into multiple pkgs [dufuz] + * Fix Bug #15914: pear upgrade installs different version if desired version not found [dufuz] + + NOTE! + Functions that have been deprecated for 3+ years in PEAR_Common, please take a moment + to migrate over to one of the alternatives that have ben provided: + * PEAR_Common->downloadHttp (use PEAR_Downloader->downloadHttp instead) + * PEAR_Common->infoFromTgzFile (use PEAR_PackageFile->fromTgzFile instead) + * PEAR_Common->infoFromDescriptionFile (use PEAR_PackageFile->fromPackageFile instead) + * PEAR_Common->infoFromString (use PEAR_PackageFile->fromXmlstring instead) + * PEAR_Common->infoFromArray (use PEAR_PackageFile->fromAnyFile instead) + * PEAR_Common->xmlFromInfo (use a PEAR_PackageFile_v* object's generator instead) + * PEAR_Common->validatePackageInfo (use the validation of PEAR_PackageFile objects) + * PEAR_Common->analyzeSourceCode (use a PEAR_PackageFile_v* object instead) + * PEAR_Common->detectDependencies (use PEAR_Downloader_Package->detectDependencies instead) + * PEAR_Common->buildProvidesArray (use PEAR_PackageFile_v1->_buildProvidesArray or + PEAR_PackageFile_v2_Validator->_buildProvidesArray) + + PHP 4.4 and 5.1.6 are now the minimum PHP requirements, for brave souls + pear upgrade -f PEAR will allow people with lower versions + to upgrade to this release but no guarantees will be made that it will work properly. + + Support for XML RPC channels has been dropped - The only ones that used it + (pear.php.net and pecl.php.net) have used the REST interface for years now. + SOAP support also removed as it was only proof of concept. + + Move codebase from the PHP License to New BSD 2 clause license + + + + 1.8.1 + 2009-04-15 + New BSD License + stable + * Fix Bug #16099 PEAR crash on PHP4 (parse error) [dufuz] + + + + 1.9.0RC1 + 2009-08-18 New BSD License beta - * Fix Bug #14331: pear cvstag only works from inside the package directory [dufuz] -* Fix Bug #16045: E_Notice: Undefined index: channel in PEAR/DependencyDB.php [dufuz] -* Implemented Request #11230: better error message when mirror not in channel.xml file [dufuz] -* Implemented Request #13150: Add support for following HTTP 302 redirects [dufuz] + * Implement Request #16213: add alias to list-channels output [dufuz] +* Implement Request #16378: pear svntag [dufuz] +* Implement Request #16386: PEAR_Config::remove() does not support specifying a channel [timj] +* Implement Request #16396: package-dependencies should allow package names [dufuz] +* Fix Bug #11181: pear requests channel.xml from main server instead from mirror [dufuz] +* Fix Bug #14493: pear install --offline doesn't print out errors [dufuz] +* Fix Bug #11348: pear package-dependencies isn't well explained [dufuz] +* Fix Bug #16108: PEAR_PackageFile_Generator_v2 PHP4 parse error when running upgrade-all [dufuz] +* Fix Bug #16113: Installing certain packages fails due incorrect encoding handling [dufuz] +* Fix Bug #16122: PEAR RunTest failed to run as expected [dufuz] +* Fix Bug #16366: compiling 5.2.10 leads to non-functioning pear [dufuz] +* Fix Bug #16387: channel-logout does not support logging out from a non-default channel [timj] +* Fix Bug #16444: Setting preferred mirror fails [dufuz] +* Fix the shutdown functions where a index might not exist and thus raise a notice [derick] + 1.9.0RC2 + 2009-08-20 + New BSD License + beta + * REST 1.4 file was occasionally being included but REST 1.4 is not intended for this release cycle [dufuz] + + 1.9.0RC3 + 2009-08-21 New BSD License - Changes since RC1: - * Fix Bug #14792: Bad md5sum for files with replaced content [dufuz] - * Fix Bug #16057:-r is limited to 4 directories in depth [dufuz] - * Fix Bug #16077: PEAR5::getStaticProperty does not return a reference to the property [dufuz] + beta + * Improved svntag support to handle packages like PEAR it self [dufuz] + + + + 1.9.0RC4 + 2009-08-23 + New BSD License + beta + * Fixed a problem where the original channel could not be set as a preferred_mirror again [dufuz] +* Make sure channel aliases can't be made to start with - [dufuz] +* Output issues with pear search [dufuz] +* Fixed couple of stray notices [dufuz] + + + + 1.9.0 + 2009-09-03 + New BSD License + stable + * Fix Bug #16547: The phar for PEAR installer uses ereg() which is deprecated [dufuz] + + + + + + * @author Stig Bakken + * @author Tomas V.V.Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: PEAR.php 286670 2009-08-02 14:16:06Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/**#@+ + * ERROR constants + */ +define('PEAR_ERROR_RETURN', 1); +define('PEAR_ERROR_PRINT', 2); +define('PEAR_ERROR_TRIGGER', 4); +define('PEAR_ERROR_DIE', 8); +define('PEAR_ERROR_CALLBACK', 16); +/** + * WARNING: obsolete + * @deprecated + */ +define('PEAR_ERROR_EXCEPTION', 32); +/**#@-*/ +define('PEAR_ZE2', (function_exists('version_compare') && + version_compare(zend_version(), "2-dev", "ge"))); + +if (substr(PHP_OS, 0, 3) == 'WIN') { + define('OS_WINDOWS', true); + define('OS_UNIX', false); + define('PEAR_OS', 'Windows'); +} else { + define('OS_WINDOWS', false); + define('OS_UNIX', true); + define('PEAR_OS', 'Unix'); // blatant assumption +} + +$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; +$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; +$GLOBALS['_PEAR_destructor_object_list'] = array(); +$GLOBALS['_PEAR_shutdown_funcs'] = array(); +$GLOBALS['_PEAR_error_handler_stack'] = array(); + +@ini_set('track_errors', true); + +/** + * Base class for other PEAR classes. Provides rudimentary + * emulation of destructors. + * + * If you want a destructor in your class, inherit PEAR and make a + * destructor method called _yourclassname (same name as the + * constructor, but with a "_" prefix). Also, in your constructor you + * have to call the PEAR constructor: $this->PEAR();. + * The destructor method will be called without parameters. Note that + * at in some SAPI implementations (such as Apache), any output during + * the request shutdown (in which destructors are called) seems to be + * discarded. If you need to get any debug information from your + * destructor, use error_log(), syslog() or something similar. + * + * IMPORTANT! To use the emulated destructors you need to create the + * objects by reference: $obj =& new PEAR_child; + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V.V. Cox + * @author Greg Beaver + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @see PEAR_Error + * @since Class available since PHP 4.0.2 + * @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear + */ +class PEAR +{ + // {{{ properties + + /** + * Whether to enable internal debug messages. + * + * @var bool + * @access private + */ + var $_debug = false; + + /** + * Default error mode for this object. + * + * @var int + * @access private + */ + var $_default_error_mode = null; + + /** + * Default error options used for this object when error mode + * is PEAR_ERROR_TRIGGER. + * + * @var int + * @access private + */ + var $_default_error_options = null; + + /** + * Default error handler (callback) for this object, if error mode is + * PEAR_ERROR_CALLBACK. + * + * @var string + * @access private + */ + var $_default_error_handler = ''; + + /** + * Which class to use for error objects. + * + * @var string + * @access private + */ + var $_error_class = 'PEAR_Error'; + + /** + * An array of expected errors. + * + * @var array + * @access private + */ + var $_expected_errors = array(); + + // }}} + + // {{{ constructor + + /** + * Constructor. Registers this object in + * $_PEAR_destructor_object_list for destructor emulation if a + * destructor object exists. + * + * @param string $error_class (optional) which class to use for + * error objects, defaults to PEAR_Error. + * @access public + * @return void + */ + function PEAR($error_class = null) + { + $classname = strtolower(get_class($this)); + if ($this->_debug) { + print "PEAR constructor called, class=$classname\n"; + } + if ($error_class !== null) { + $this->_error_class = $error_class; + } + while ($classname && strcasecmp($classname, "pear")) { + $destructor = "_$classname"; + if (method_exists($this, $destructor)) { + global $_PEAR_destructor_object_list; + $_PEAR_destructor_object_list[] = &$this; + if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { + register_shutdown_function("_PEAR_call_destructors"); + $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; + } + break; + } else { + $classname = get_parent_class($classname); + } + } + } + + // }}} + // {{{ destructor + + /** + * Destructor (the emulated type of...). Does nothing right now, + * but is included for forward compatibility, so subclass + * destructors should always call it. + * + * See the note in the class desciption about output from + * destructors. + * + * @access public + * @return void + */ + function _PEAR() { + if ($this->_debug) { + printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); + } + } + + // }}} + // {{{ getStaticProperty() + + /** + * If you have a class that's mostly/entirely static, and you need static + * properties, you can use this method to simulate them. Eg. in your method(s) + * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); + * You MUST use a reference, or they will not persist! + * + * @access public + * @param string $class The calling classname, to prevent clashes + * @param string $var The variable to retrieve. + * @return mixed A reference to the variable. If not set it will be + * auto initialised to NULL. + */ + function &getStaticProperty($class, $var) + { + static $properties; + if (!isset($properties[$class])) { + $properties[$class] = array(); + } + + if (!array_key_exists($var, $properties[$class])) { + $properties[$class][$var] = null; + } + + return $properties[$class][$var]; + } + + // }}} + // {{{ registerShutdownFunc() + + /** + * Use this function to register a shutdown method for static + * classes. + * + * @access public + * @param mixed $func The function name (or array of class/method) to call + * @param mixed $args The arguments to pass to the function + * @return void + */ + function registerShutdownFunc($func, $args = array()) + { + // if we are called statically, there is a potential + // that no shutdown func is registered. Bug #6445 + if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { + register_shutdown_function("_PEAR_call_destructors"); + $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; + } + $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); + } + + // }}} + // {{{ isError() + + /** + * Tell whether a value is a PEAR error. + * + * @param mixed $data the value to test + * @param int $code if $data is an error object, return true + * only if $code is a string and + * $obj->getMessage() == $code or + * $code is an integer and $obj->getCode() == $code + * @access public + * @return bool true if parameter is an error + */ + function isError($data, $code = null) + { + if (!is_a($data, 'PEAR_Error')) { + return false; + } + + if (is_null($code)) { + return true; + } elseif (is_string($code)) { + return $data->getMessage() == $code; + } + + return $data->getCode() == $code; + } + + // }}} + // {{{ setErrorHandling() + + /** + * Sets how errors generated by this object should be handled. + * Can be invoked both in objects and statically. If called + * statically, setErrorHandling sets the default behaviour for all + * PEAR objects. If called in an object, setErrorHandling sets + * the default behaviour for that object. + * + * @param int $mode + * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, + * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, + * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. + * + * @param mixed $options + * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one + * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). + * + * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected + * to be the callback function or method. A callback + * function is a string with the name of the function, a + * callback method is an array of two elements: the element + * at index 0 is the object, and the element at index 1 is + * the name of the method to call in the object. + * + * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is + * a printf format string used when printing the error + * message. + * + * @access public + * @return void + * @see PEAR_ERROR_RETURN + * @see PEAR_ERROR_PRINT + * @see PEAR_ERROR_TRIGGER + * @see PEAR_ERROR_DIE + * @see PEAR_ERROR_CALLBACK + * @see PEAR_ERROR_EXCEPTION + * + * @since PHP 4.0.5 + */ + + function setErrorHandling($mode = null, $options = null) + { + if (isset($this) && is_a($this, 'PEAR')) { + $setmode = &$this->_default_error_mode; + $setoptions = &$this->_default_error_options; + } else { + $setmode = &$GLOBALS['_PEAR_default_error_mode']; + $setoptions = &$GLOBALS['_PEAR_default_error_options']; + } + + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $setmode = $mode; + $setoptions = $options; + break; + + case PEAR_ERROR_CALLBACK: + $setmode = $mode; + // class/object method callback + if (is_callable($options)) { + $setoptions = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + } + + // }}} + // {{{ expectError() + + /** + * This method is used to tell which errors you expect to get. + * Expected errors are always returned with error mode + * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, + * and this method pushes a new element onto it. The list of + * expected errors are in effect until they are popped off the + * stack with the popExpect() method. + * + * Note that this method can not be called statically + * + * @param mixed $code a single error code or an array of error codes to expect + * + * @return int the new depth of the "expected errors" stack + * @access public + */ + function expectError($code = '*') + { + if (is_array($code)) { + array_push($this->_expected_errors, $code); + } else { + array_push($this->_expected_errors, array($code)); + } + return sizeof($this->_expected_errors); + } + + // }}} + // {{{ popExpect() + + /** + * This method pops one element off the expected error codes + * stack. + * + * @return array the list of error codes that were popped + */ + function popExpect() + { + return array_pop($this->_expected_errors); + } + + // }}} + // {{{ _checkDelExpect() + + /** + * This method checks unsets an error code if available + * + * @param mixed error code + * @return bool true if the error code was unset, false otherwise + * @access private + * @since PHP 4.3.0 + */ + function _checkDelExpect($error_code) + { + $deleted = false; + + foreach ($this->_expected_errors AS $key => $error_array) { + if (in_array($error_code, $error_array)) { + unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); + $deleted = true; + } + + // clean up empty arrays + if (0 == count($this->_expected_errors[$key])) { + unset($this->_expected_errors[$key]); + } + } + return $deleted; + } + + // }}} + // {{{ delExpect() + + /** + * This method deletes all occurences of the specified element from + * the expected error codes stack. + * + * @param mixed $error_code error code that should be deleted + * @return mixed list of error codes that were deleted or error + * @access public + * @since PHP 4.3.0 + */ + function delExpect($error_code) + { + $deleted = false; + if ((is_array($error_code) && (0 != count($error_code)))) { + // $error_code is a non-empty array here; + // we walk through it trying to unset all + // values + foreach($error_code as $key => $error) { + if ($this->_checkDelExpect($error)) { + $deleted = true; + } else { + $deleted = false; + } + } + return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + } elseif (!empty($error_code)) { + // $error_code comes alone, trying to unset it + if ($this->_checkDelExpect($error_code)) { + return true; + } else { + return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + } + } + + // $error_code is empty + return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME + } + + // }}} + // {{{ raiseError() + + /** + * This method is a wrapper that returns an instance of the + * configured error class with this object's default error + * handling applied. If the $mode and $options parameters are not + * specified, the object's defaults are used. + * + * @param mixed $message a text error message or a PEAR error object + * + * @param int $code a numeric error code (it is up to your class + * to define these if you want to use codes) + * + * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, + * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, + * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. + * + * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter + * specifies the PHP-internal error level (one of + * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). + * If $mode is PEAR_ERROR_CALLBACK, this + * parameter specifies the callback function or + * method. In other error modes this parameter + * is ignored. + * + * @param string $userinfo If you need to pass along for example debug + * information, this parameter is meant for that. + * + * @param string $error_class The returned error object will be + * instantiated from this class, if specified. + * + * @param bool $skipmsg If true, raiseError will only pass error codes, + * the error message parameter will be dropped. + * + * @access public + * @return object a PEAR error object + * @see PEAR::setErrorHandling + * @since PHP 4.0.5 + */ + function &raiseError($message = null, + $code = null, + $mode = null, + $options = null, + $userinfo = null, + $error_class = null, + $skipmsg = false) + { + // The error is yet a PEAR error object + if (is_object($message)) { + $code = $message->getCode(); + $userinfo = $message->getUserInfo(); + $error_class = $message->getType(); + $message->error_message_prefix = ''; + $message = $message->getMessage(); + } + + if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) { + if ($exp[0] == "*" || + (is_int(reset($exp)) && in_array($code, $exp)) || + (is_string(reset($exp)) && in_array($message, $exp))) { + $mode = PEAR_ERROR_RETURN; + } + } + + // No mode given, try global ones + if ($mode === null) { + // Class error handler + if (isset($this) && isset($this->_default_error_mode)) { + $mode = $this->_default_error_mode; + $options = $this->_default_error_options; + // Global error handler + } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { + $mode = $GLOBALS['_PEAR_default_error_mode']; + $options = $GLOBALS['_PEAR_default_error_options']; + } + } + + if ($error_class !== null) { + $ec = $error_class; + } elseif (isset($this) && isset($this->_error_class)) { + $ec = $this->_error_class; + } else { + $ec = 'PEAR_Error'; + } + + if (intval(PHP_VERSION) < 5) { + // little non-eval hack to fix bug #12147 + include 'phar://install-pear-nozlib.phar/' . 'PEAR/FixPHP5PEARWarnings.php'; + return $a; + } + + if ($skipmsg) { + $a = new $ec($code, $mode, $options, $userinfo); + } else { + $a = new $ec($message, $code, $mode, $options, $userinfo); + } + + return $a; + } + + // }}} + // {{{ throwError() + + /** + * Simpler form of raiseError with fewer options. In most cases + * message, code and userinfo are enough. + * + * @param string $message + * + */ + function &throwError($message = null, + $code = null, + $userinfo = null) + { + if (isset($this) && is_a($this, 'PEAR')) { + $a = &$this->raiseError($message, $code, null, null, $userinfo); + return $a; + } + + $a = &PEAR::raiseError($message, $code, null, null, $userinfo); + return $a; + } + + // }}} + function staticPushErrorHandling($mode, $options = null) + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_options = &$GLOBALS['_PEAR_default_error_options']; + $stack[] = array($def_mode, $def_options); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $def_mode = $mode; + $def_options = $options; + break; + + case PEAR_ERROR_CALLBACK: + $def_mode = $mode; + // class/object method callback + if (is_callable($options)) { + $def_options = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + $stack[] = array($mode, $options); + return true; + } + + function staticPopErrorHandling() + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + $setmode = &$GLOBALS['_PEAR_default_error_mode']; + $setoptions = &$GLOBALS['_PEAR_default_error_options']; + array_pop($stack); + list($mode, $options) = $stack[sizeof($stack) - 1]; + array_pop($stack); + switch ($mode) { + case PEAR_ERROR_EXCEPTION: + case PEAR_ERROR_RETURN: + case PEAR_ERROR_PRINT: + case PEAR_ERROR_TRIGGER: + case PEAR_ERROR_DIE: + case null: + $setmode = $mode; + $setoptions = $options; + break; + + case PEAR_ERROR_CALLBACK: + $setmode = $mode; + // class/object method callback + if (is_callable($options)) { + $setoptions = $options; + } else { + trigger_error("invalid error callback", E_USER_WARNING); + } + break; + + default: + trigger_error("invalid error mode", E_USER_WARNING); + break; + } + return true; + } + + // {{{ pushErrorHandling() + + /** + * Push a new error handler on top of the error handler options stack. With this + * you can easily override the actual error handler for some code and restore + * it later with popErrorHandling. + * + * @param mixed $mode (same as setErrorHandling) + * @param mixed $options (same as setErrorHandling) + * + * @return bool Always true + * + * @see PEAR::setErrorHandling + */ + function pushErrorHandling($mode, $options = null) + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + if (isset($this) && is_a($this, 'PEAR')) { + $def_mode = &$this->_default_error_mode; + $def_options = &$this->_default_error_options; + } else { + $def_mode = &$GLOBALS['_PEAR_default_error_mode']; + $def_options = &$GLOBALS['_PEAR_default_error_options']; + } + $stack[] = array($def_mode, $def_options); + + if (isset($this) && is_a($this, 'PEAR')) { + $this->setErrorHandling($mode, $options); + } else { + PEAR::setErrorHandling($mode, $options); + } + $stack[] = array($mode, $options); + return true; + } + + // }}} + // {{{ popErrorHandling() + + /** + * Pop the last error handler used + * + * @return bool Always true + * + * @see PEAR::pushErrorHandling + */ + function popErrorHandling() + { + $stack = &$GLOBALS['_PEAR_error_handler_stack']; + array_pop($stack); + list($mode, $options) = $stack[sizeof($stack) - 1]; + array_pop($stack); + if (isset($this) && is_a($this, 'PEAR')) { + $this->setErrorHandling($mode, $options); + } else { + PEAR::setErrorHandling($mode, $options); + } + return true; + } + + // }}} + // {{{ loadExtension() + + /** + * OS independant PHP extension load. Remember to take care + * on the correct extension name for case sensitive OSes. + * + * @param string $ext The extension name + * @return bool Success or not on the dl() call + */ + function loadExtension($ext) + { + if (!extension_loaded($ext)) { + // if either returns true dl() will produce a FATAL error, stop that + if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) { + return false; + } + + if (OS_WINDOWS) { + $suffix = '.dll'; + } elseif (PHP_OS == 'HP-UX') { + $suffix = '.sl'; + } elseif (PHP_OS == 'AIX') { + $suffix = '.a'; + } elseif (PHP_OS == 'OSX') { + $suffix = '.bundle'; + } else { + $suffix = '.so'; + } + + return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); + } + + return true; + } + + // }}} +} + +if (PEAR_ZE2) { + include_once 'phar://install-pear-nozlib.phar/' . 'PEAR5.php'; +} + +// {{{ _PEAR_call_destructors() + +function _PEAR_call_destructors() +{ + global $_PEAR_destructor_object_list; + if (is_array($_PEAR_destructor_object_list) && + sizeof($_PEAR_destructor_object_list)) + { + reset($_PEAR_destructor_object_list); + if (PEAR_ZE2) { + $destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo'); + } else { + $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); + } + + if ($destructLifoExists) { + $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); + } + + while (list($k, $objref) = each($_PEAR_destructor_object_list)) { + $classname = get_class($objref); + while ($classname) { + $destructor = "_$classname"; + if (method_exists($objref, $destructor)) { + $objref->$destructor(); + break; + } else { + $classname = get_parent_class($classname); + } + } + } + // Empty the object list to ensure that destructors are + // not called more than once. + $_PEAR_destructor_object_list = array(); + } + + // Now call the shutdown functions + if (isset($GLOBALS['_PEAR_shutdown_funcs']) AND is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { + foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { + call_user_func_array($value[0], $value[1]); + } + } +} + +// }}} +/** + * Standard PEAR error class for PHP 4 + * + * This class is supserseded by {@link PEAR_Exception} in PHP 5 + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V.V. Cox + * @author Gregory Beaver + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/manual/en/core.pear.pear-error.php + * @see PEAR::raiseError(), PEAR::throwError() + * @since Class available since PHP 4.0.2 + */ +class PEAR_Error +{ + // {{{ properties + + var $error_message_prefix = ''; + var $mode = PEAR_ERROR_RETURN; + var $level = E_USER_NOTICE; + var $code = -1; + var $message = ''; + var $userinfo = ''; + var $backtrace = null; + + // }}} + // {{{ constructor + + /** + * PEAR_Error constructor + * + * @param string $message message + * + * @param int $code (optional) error code + * + * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, + * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, + * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION + * + * @param mixed $options (optional) error level, _OR_ in the case of + * PEAR_ERROR_CALLBACK, the callback function or object/method + * tuple. + * + * @param string $userinfo (optional) additional user/debug info + * + * @access public + * + */ + function PEAR_Error($message = 'unknown error', $code = null, + $mode = null, $options = null, $userinfo = null) + { + if ($mode === null) { + $mode = PEAR_ERROR_RETURN; + } + $this->message = $message; + $this->code = $code; + $this->mode = $mode; + $this->userinfo = $userinfo; + + if (PEAR_ZE2) { + $skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace'); + } else { + $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); + } + + if (!$skiptrace) { + $this->backtrace = debug_backtrace(); + if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) { + unset($this->backtrace[0]['object']); + } + } + + if ($mode & PEAR_ERROR_CALLBACK) { + $this->level = E_USER_NOTICE; + $this->callback = $options; + } else { + if ($options === null) { + $options = E_USER_NOTICE; + } + + $this->level = $options; + $this->callback = null; + } + + if ($this->mode & PEAR_ERROR_PRINT) { + if (is_null($options) || is_int($options)) { + $format = "%s"; + } else { + $format = $options; + } + + printf($format, $this->getMessage()); + } + + if ($this->mode & PEAR_ERROR_TRIGGER) { + trigger_error($this->getMessage(), $this->level); + } + + if ($this->mode & PEAR_ERROR_DIE) { + $msg = $this->getMessage(); + if (is_null($options) || is_int($options)) { + $format = "%s"; + if (substr($msg, -1) != "\n") { + $msg .= "\n"; + } + } else { + $format = $options; + } + die(sprintf($format, $msg)); + } + + if ($this->mode & PEAR_ERROR_CALLBACK) { + if (is_callable($this->callback)) { + call_user_func($this->callback, $this); + } + } + + if ($this->mode & PEAR_ERROR_EXCEPTION) { + trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); + eval('$e = new Exception($this->message, $this->code);throw($e);'); + } + } + + // }}} + // {{{ getMode() + + /** + * Get the error mode from an error object. + * + * @return int error mode + * @access public + */ + function getMode() { + return $this->mode; + } + + // }}} + // {{{ getCallback() + + /** + * Get the callback function/method from an error object. + * + * @return mixed callback function or object/method array + * @access public + */ + function getCallback() { + return $this->callback; + } + + // }}} + // {{{ getMessage() + + + /** + * Get the error message from an error object. + * + * @return string full error message + * @access public + */ + function getMessage() + { + return ($this->error_message_prefix . $this->message); + } + + + // }}} + // {{{ getCode() + + /** + * Get error code from an error object + * + * @return int error code + * @access public + */ + function getCode() + { + return $this->code; + } + + // }}} + // {{{ getType() + + /** + * Get the name of this error/exception. + * + * @return string error/exception name (type) + * @access public + */ + function getType() + { + return get_class($this); + } + + // }}} + // {{{ getUserInfo() + + /** + * Get additional user-supplied information. + * + * @return string user-supplied information + * @access public + */ + function getUserInfo() + { + return $this->userinfo; + } + + // }}} + // {{{ getDebugInfo() + + /** + * Get additional debug information supplied by the application. + * + * @return string debug information + * @access public + */ + function getDebugInfo() + { + return $this->getUserInfo(); + } + + // }}} + // {{{ getBacktrace() + + /** + * Get the call backtrace from where the error was generated. + * Supported with PHP 4.3.0 or newer. + * + * @param int $frame (optional) what frame to fetch + * @return array Backtrace, or NULL if not available. + * @access public + */ + function getBacktrace($frame = null) + { + if (defined('PEAR_IGNORE_BACKTRACE')) { + return null; + } + if ($frame === null) { + return $this->backtrace; + } + return $this->backtrace[$frame]; + } + + // }}} + // {{{ addUserInfo() + + function addUserInfo($info) + { + if (empty($this->userinfo)) { + $this->userinfo = $info; + } else { + $this->userinfo .= " ** $info"; + } + } + + // }}} + // {{{ toString() + function __toString() + { + return $this->getMessage(); + } + // }}} + // {{{ toString() + + /** + * Make a string representation of this object. + * + * @return string a string with an object summary + * @access public + */ + function toString() { + $modes = array(); + $levels = array(E_USER_NOTICE => 'notice', + E_USER_WARNING => 'warning', + E_USER_ERROR => 'error'); + if ($this->mode & PEAR_ERROR_CALLBACK) { + if (is_array($this->callback)) { + $callback = (is_object($this->callback[0]) ? + strtolower(get_class($this->callback[0])) : + $this->callback[0]) . '::' . + $this->callback[1]; + } else { + $callback = $this->callback; + } + return sprintf('[%s: message="%s" code=%d mode=callback '. + 'callback=%s prefix="%s" info="%s"]', + strtolower(get_class($this)), $this->message, $this->code, + $callback, $this->error_message_prefix, + $this->userinfo); + } + if ($this->mode & PEAR_ERROR_PRINT) { + $modes[] = 'print'; + } + if ($this->mode & PEAR_ERROR_TRIGGER) { + $modes[] = 'trigger'; + } + if ($this->mode & PEAR_ERROR_DIE) { + $modes[] = 'die'; + } + if ($this->mode & PEAR_ERROR_RETURN) { + $modes[] = 'return'; + } + return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. + 'prefix="%s" info="%s"]', + strtolower(get_class($this)), $this->message, $this->code, + implode("|", $modes), $levels[$this->level], + $this->error_message_prefix, + $this->userinfo); + } + + // }}} +} + +/* + * Local Variables: + * mode: php + * tab-width: 4 + * c-basic-offset: 4 + * End: + */ + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: ChannelFile.php 286951 2009-08-09 14:41:22Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Needed for error handling + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ErrorStack.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Common.php'; + +/** + * Error code if the channel.xml tag does not contain a valid version + */ +define('PEAR_CHANNELFILE_ERROR_NO_VERSION', 1); +/** + * Error code if the channel.xml tag version is not supported (version 1.0 is the only supported version, + * currently + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_VERSION', 2); + +/** + * Error code if parsing is attempted with no xml extension + */ +define('PEAR_CHANNELFILE_ERROR_NO_XML_EXT', 3); + +/** + * Error code if creating the xml parser resource fails + */ +define('PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER', 4); + +/** + * Error code used for all sax xml parsing errors + */ +define('PEAR_CHANNELFILE_ERROR_PARSER_ERROR', 5); + +/**#@+ + * Validation errors + */ +/** + * Error code when channel name is missing + */ +define('PEAR_CHANNELFILE_ERROR_NO_NAME', 6); +/** + * Error code when channel name is invalid + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_NAME', 7); +/** + * Error code when channel summary is missing + */ +define('PEAR_CHANNELFILE_ERROR_NO_SUMMARY', 8); +/** + * Error code when channel summary is multi-line + */ +define('PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY', 9); +/** + * Error code when channel server is missing for protocol + */ +define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10); +/** + * Error code when channel server is invalid for protocol + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_HOST', 11); +/** + * Error code when a mirror name is invalid + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_MIRROR', 21); +/** + * Error code when a mirror type is invalid + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE', 22); +/** + * Error code when an attempt is made to generate xml, but the parsed content is invalid + */ +define('PEAR_CHANNELFILE_ERROR_INVALID', 23); +/** + * Error code when an empty package name validate regex is passed in + */ +define('PEAR_CHANNELFILE_ERROR_EMPTY_REGEX', 24); +/** + * Error code when a tag has no version + */ +define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION', 25); +/** + * Error code when a tag has no name + */ +define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME', 26); +/** + * Error code when a tag has no name + */ +define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME', 27); +/** + * Error code when a tag has no version attribute + */ +define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION', 28); +/** + * Error code when a mirror does not exist but is called for in one of the set* + * methods. + */ +define('PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND', 32); +/** + * Error code when a server port is not numeric + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_PORT', 33); +/** + * Error code when contains no version attribute + */ +define('PEAR_CHANNELFILE_ERROR_NO_STATICVERSION', 34); +/** + * Error code when contains no type attribute in a protocol definition + */ +define('PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE', 35); +/** + * Error code when a mirror is defined and the channel.xml represents the __uri pseudo-channel + */ +define('PEAR_CHANNELFILE_URI_CANT_MIRROR', 36); +/** + * Error code when ssl attribute is present and is not "yes" + */ +define('PEAR_CHANNELFILE_ERROR_INVALID_SSL', 37); +/**#@-*/ + +/** + * Mirror types allowed. Currently only internet servers are recognized. + */ +$GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] = array('server'); + + +/** + * The Channel handling class + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_ChannelFile +{ + /** + * @access private + * @var PEAR_ErrorStack + * @access private + */ + var $_stack; + + /** + * Supported channel.xml versions, for parsing + * @var array + * @access private + */ + var $_supportedVersions = array('1.0'); + + /** + * Parsed channel information + * @var array + * @access private + */ + var $_channelInfo; + + /** + * index into the subchannels array, used for parsing xml + * @var int + * @access private + */ + var $_subchannelIndex; + + /** + * index into the mirrors array, used for parsing xml + * @var int + * @access private + */ + var $_mirrorIndex; + + /** + * Flag used to determine the validity of parsed content + * @var boolean + * @access private + */ + var $_isValid = false; + + function PEAR_ChannelFile() + { + $this->_stack = &new PEAR_ErrorStack('PEAR_ChannelFile'); + $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); + $this->_isValid = false; + } + + /** + * @return array + * @access protected + */ + function _getErrorMessage() + { + return + array( + PEAR_CHANNELFILE_ERROR_INVALID_VERSION => + 'While parsing channel.xml, an invalid version number "%version% was passed in, expecting one of %versions%', + PEAR_CHANNELFILE_ERROR_NO_VERSION => + 'No version number found in tag', + PEAR_CHANNELFILE_ERROR_NO_XML_EXT => + '%error%', + PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER => + 'Unable to create XML parser', + PEAR_CHANNELFILE_ERROR_PARSER_ERROR => + '%error%', + PEAR_CHANNELFILE_ERROR_NO_NAME => + 'Missing channel name', + PEAR_CHANNELFILE_ERROR_INVALID_NAME => + 'Invalid channel %tag% "%name%"', + PEAR_CHANNELFILE_ERROR_NO_SUMMARY => + 'Missing channel summary', + PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY => + 'Channel summary should be on one line, but is multi-line', + PEAR_CHANNELFILE_ERROR_NO_HOST => + 'Missing channel server for %type% server', + PEAR_CHANNELFILE_ERROR_INVALID_HOST => + 'Server name "%server%" is invalid for %type% server', + PEAR_CHANNELFILE_ERROR_INVALID_MIRROR => + 'Invalid mirror name "%name%", mirror type %type%', + PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE => + 'Invalid mirror type "%type%"', + PEAR_CHANNELFILE_ERROR_INVALID => + 'Cannot generate xml, contents are invalid', + PEAR_CHANNELFILE_ERROR_EMPTY_REGEX => + 'packagenameregex cannot be empty', + PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION => + '%parent% %protocol% function has no version', + PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME => + '%parent% %protocol% function has no name', + PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE => + '%parent% rest baseurl has no type', + PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME => + 'Validation package has no name in tag', + PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION => + 'Validation package "%package%" has no version', + PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND => + 'Mirror "%mirror%" does not exist', + PEAR_CHANNELFILE_ERROR_INVALID_PORT => + 'Port "%port%" must be numeric', + PEAR_CHANNELFILE_ERROR_NO_STATICVERSION => + ' tag must contain version attribute', + PEAR_CHANNELFILE_URI_CANT_MIRROR => + 'The __uri pseudo-channel cannot have mirrors', + PEAR_CHANNELFILE_ERROR_INVALID_SSL => + '%server% has invalid ssl attribute "%ssl%" can only be yes or not present', + ); + } + + /** + * @param string contents of package.xml file + * @return bool success of parsing + */ + function fromXmlString($data) + { + if (preg_match('/_supportedVersions)) { + $this->_stack->push(PEAR_CHANNELFILE_ERROR_INVALID_VERSION, 'error', + array('version' => $channelversion[1])); + return false; + } + $parser = new PEAR_XMLParser; + $result = $parser->parse($data); + if ($result !== true) { + if ($result->getCode() == 1) { + $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_XML_EXT, 'error', + array('error' => $result->getMessage())); + } else { + $this->_stack->push(PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER, 'error'); + } + return false; + } + $this->_channelInfo = $parser->getData(); + return true; + } else { + $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_VERSION, 'error', array('xml' => $data)); + return false; + } + } + + /** + * @return array + */ + function toArray() + { + if (!$this->_isValid && !$this->validate()) { + return false; + } + return $this->_channelInfo; + } + + /** + * @param array + * @static + * @return PEAR_ChannelFile|false false if invalid + */ + function &fromArray($data, $compatibility = false, $stackClass = 'PEAR_ErrorStack') + { + $a = new PEAR_ChannelFile($compatibility, $stackClass); + $a->_fromArray($data); + if (!$a->validate()) { + $a = false; + return $a; + } + return $a; + } + + /** + * Unlike {@link fromArray()} this does not do any validation + * @param array + * @static + * @return PEAR_ChannelFile + */ + function &fromArrayWithErrors($data, $compatibility = false, + $stackClass = 'PEAR_ErrorStack') + { + $a = new PEAR_ChannelFile($compatibility, $stackClass); + $a->_fromArray($data); + return $a; + } + + /** + * @param array + * @access private + */ + function _fromArray($data) + { + $this->_channelInfo = $data; + } + + /** + * Wrapper to {@link PEAR_ErrorStack::getErrors()} + * @param boolean determines whether to purge the error stack after retrieving + * @return array + */ + function getErrors($purge = false) + { + return $this->_stack->getErrors($purge); + } + + /** + * Unindent given string (?) + * + * @param string $str The string that has to be unindented. + * @return string + * @access private + */ + function _unIndent($str) + { + // remove leading newlines + $str = preg_replace('/^[\r\n]+/', '', $str); + // find whitespace at the beginning of the first line + $indent_len = strspn($str, " \t"); + $indent = substr($str, 0, $indent_len); + $data = ''; + // remove the same amount of whitespace from following lines + foreach (explode("\n", $str) as $line) { + if (substr($line, 0, $indent_len) == $indent) { + $data .= substr($line, $indent_len) . "\n"; + } + } + return $data; + } + + /** + * Parse a channel.xml file. Expects the name of + * a channel xml file as input. + * + * @param string $descfile name of channel xml file + * @return bool success of parsing + */ + function fromXmlFile($descfile) + { + if (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) || + (!$fp = fopen($descfile, 'r'))) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; + return PEAR::raiseError("Unable to open $descfile"); + } + + // read the whole thing so we only get one cdata callback + // for each block of cdata + fclose($fp); + $data = file_get_contents($descfile); + return $this->fromXmlString($data); + } + + /** + * Parse channel information from different sources + * + * This method is able to extract information about a channel + * from an .xml file or a string + * + * @access public + * @param string Filename of the source or the source itself + * @return bool + */ + function fromAny($info) + { + if (is_string($info) && file_exists($info) && strlen($info) < 255) { + $tmp = substr($info, -4); + if ($tmp == '.xml') { + $info = $this->fromXmlFile($info); + } else { + $fp = fopen($info, "r"); + $test = fread($fp, 5); + fclose($fp); + if ($test == "fromXmlFile($info); + } + } + if (PEAR::isError($info)) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; + return PEAR::raiseError($info); + } + } + if (is_string($info)) { + $info = $this->fromXmlString($info); + } + return $info; + } + + /** + * Return an XML document based on previous parsing and modifications + * + * @return string XML data + * + * @access public + */ + function toXml() + { + if (!$this->_isValid && !$this->validate()) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID); + return false; + } + if (!isset($this->_channelInfo['attribs']['version'])) { + $this->_channelInfo['attribs']['version'] = '1.0'; + } + $channelInfo = $this->_channelInfo; + $ret = "\n"; + $ret .= " + $channelInfo[name] + " . htmlspecialchars($channelInfo['summary'])." +"; + if (isset($channelInfo['suggestedalias'])) { + $ret .= ' ' . $channelInfo['suggestedalias'] . "\n"; + } + if (isset($channelInfo['validatepackage'])) { + $ret .= ' ' . + htmlspecialchars($channelInfo['validatepackage']['_content']) . + "\n"; + } + $ret .= " \n"; + $ret .= ' _makeRestXml($channelInfo['servers']['primary']['rest'], ' '); + } + $ret .= " \n"; + if (isset($channelInfo['servers']['mirror'])) { + $ret .= $this->_makeMirrorsXml($channelInfo); + } + $ret .= " \n"; + $ret .= ""; + return str_replace("\r", "\n", str_replace("\r\n", "\n", $ret)); + } + + /** + * Generate the tag + * @access private + */ + function _makeRestXml($info, $indent) + { + $ret = $indent . "\n"; + if (isset($info['baseurl']) && !isset($info['baseurl'][0])) { + $info['baseurl'] = array($info['baseurl']); + } + + if (isset($info['baseurl'])) { + foreach ($info['baseurl'] as $url) { + $ret .= "$indent \n"; + } + } + $ret .= $indent . "\n"; + return $ret; + } + + /** + * Generate the tag + * @access private + */ + function _makeMirrorsXml($channelInfo) + { + $ret = ""; + if (!isset($channelInfo['servers']['mirror'][0])) { + $channelInfo['servers']['mirror'] = array($channelInfo['servers']['mirror']); + } + foreach ($channelInfo['servers']['mirror'] as $mirror) { + $ret .= ' _makeRestXml($mirror['rest'], ' '); + } + $ret .= " \n"; + } else { + $ret .= "/>\n"; + } + } + return $ret; + } + + /** + * Generate the tag + * @access private + */ + function _makeFunctionsXml($functions, $indent, $rest = false) + { + $ret = ''; + if (!isset($functions[0])) { + $functions = array($functions); + } + foreach ($functions as $function) { + $ret .= "$indent\n"; + } + return $ret; + } + + /** + * Validation error. Also marks the object contents as invalid + * @param error code + * @param array error information + * @access private + */ + function _validateError($code, $params = array()) + { + $this->_stack->push($code, 'error', $params); + $this->_isValid = false; + } + + /** + * Validation warning. Does not mark the object contents invalid. + * @param error code + * @param array error information + * @access private + */ + function _validateWarning($code, $params = array()) + { + $this->_stack->push($code, 'warning', $params); + } + + /** + * Validate parsed file. + * + * @access public + * @return boolean + */ + function validate() + { + $this->_isValid = true; + $info = $this->_channelInfo; + if (empty($info['name'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_NAME); + } elseif (!$this->validChannelServer($info['name'])) { + if ($info['name'] != '__uri') { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name', + 'name' => $info['name'])); + } + } + if (empty($info['summary'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY); + } elseif (strpos(trim($info['summary']), "\n") !== false) { + $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY, + array('summary' => $info['summary'])); + } + if (isset($info['suggestedalias'])) { + if (!$this->validChannelServer($info['suggestedalias'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, + array('tag' => 'suggestedalias', 'name' =>$info['suggestedalias'])); + } + } + if (isset($info['localalias'])) { + if (!$this->validChannelServer($info['localalias'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, + array('tag' => 'localalias', 'name' =>$info['localalias'])); + } + } + if (isset($info['validatepackage'])) { + if (!isset($info['validatepackage']['_content'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME); + } + if (!isset($info['validatepackage']['attribs']['version'])) { + $content = isset($info['validatepackage']['_content']) ? + $info['validatepackage']['_content'] : + null; + $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION, + array('package' => $content)); + } + } + + if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['port']) && + !is_numeric($info['servers']['primary']['attribs']['port'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT, + array('port' => $info['servers']['primary']['attribs']['port'])); + } + + if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['ssl']) && + $info['servers']['primary']['attribs']['ssl'] != 'yes') { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL, + array('ssl' => $info['servers']['primary']['attribs']['ssl'], + 'server' => $info['name'])); + } + + if (isset($info['servers']['primary']['rest']) && + isset($info['servers']['primary']['rest']['baseurl'])) { + $this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']); + } + if (isset($info['servers']['mirror'])) { + if ($this->_channelInfo['name'] == '__uri') { + $this->_validateError(PEAR_CHANNELFILE_URI_CANT_MIRROR); + } + if (!isset($info['servers']['mirror'][0])) { + $info['servers']['mirror'] = array($info['servers']['mirror']); + } + foreach ($info['servers']['mirror'] as $mirror) { + if (!isset($mirror['attribs']['host'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST, + array('type' => 'mirror')); + } elseif (!$this->validChannelServer($mirror['attribs']['host'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_HOST, + array('server' => $mirror['attribs']['host'], 'type' => 'mirror')); + } + if (isset($mirror['attribs']['ssl']) && $mirror['attribs']['ssl'] != 'yes') { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL, + array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host'])); + } + if (isset($mirror['rest'])) { + $this->_validateFunctions('rest', $mirror['rest']['baseurl'], + $mirror['attribs']['host']); + } + } + } + return $this->_isValid; + } + + /** + * @param string rest - protocol name this function applies to + * @param array the functions + * @param string the name of the parent element (mirror name, for instance) + */ + function _validateFunctions($protocol, $functions, $parent = '') + { + if (!isset($functions[0])) { + $functions = array($functions); + } + + foreach ($functions as $function) { + if (!isset($function['_content']) || empty($function['_content'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME, + array('parent' => $parent, 'protocol' => $protocol)); + } + + if ($protocol == 'rest') { + if (!isset($function['attribs']['type']) || + empty($function['attribs']['type'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE, + array('parent' => $parent, 'protocol' => $protocol)); + } + } else { + if (!isset($function['attribs']['version']) || + empty($function['attribs']['version'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION, + array('parent' => $parent, 'protocol' => $protocol)); + } + } + } + } + + /** + * Test whether a string contains a valid channel server. + * @param string $ver the package version to test + * @return bool + */ + function validChannelServer($server) + { + if ($server == '__uri') { + return true; + } + return (bool) preg_match(PEAR_CHANNELS_SERVER_PREG, $server); + } + + /** + * @return string|false + */ + function getName() + { + if (isset($this->_channelInfo['name'])) { + return $this->_channelInfo['name']; + } + + return false; + } + + /** + * @return string|false + */ + function getServer() + { + if (isset($this->_channelInfo['name'])) { + return $this->_channelInfo['name']; + } + + return false; + } + + /** + * @return int|80 port number to connect to + */ + function getPort($mirror = false) + { + if ($mirror) { + if ($mir = $this->getMirror($mirror)) { + if (isset($mir['attribs']['port'])) { + return $mir['attribs']['port']; + } + + if ($this->getSSL($mirror)) { + return 443; + } + + return 80; + } + + return false; + } + + if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) { + return $this->_channelInfo['servers']['primary']['attribs']['port']; + } + + if ($this->getSSL()) { + return 443; + } + + return 80; + } + + /** + * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel + */ + function getSSL($mirror = false) + { + if ($mirror) { + if ($mir = $this->getMirror($mirror)) { + if (isset($mir['attribs']['ssl'])) { + return true; + } + + return false; + } + + return false; + } + + if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) { + return true; + } + + return false; + } + + /** + * @return string|false + */ + function getSummary() + { + if (isset($this->_channelInfo['summary'])) { + return $this->_channelInfo['summary']; + } + + return false; + } + + /** + * @param string protocol type + * @param string Mirror name + * @return array|false + */ + function getFunctions($protocol, $mirror = false) + { + if ($this->getName() == '__uri') { + return false; + } + + $function = $protocol == 'rest' ? 'baseurl' : 'function'; + if ($mirror) { + if ($mir = $this->getMirror($mirror)) { + if (isset($mir[$protocol][$function])) { + return $mir[$protocol][$function]; + } + } + + return false; + } + + if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) { + return $this->_channelInfo['servers']['primary'][$protocol][$function]; + } + + return false; + } + + /** + * @param string Protocol type + * @param string Function name (null to return the + * first protocol of the type requested) + * @param string Mirror name, if any + * @return array + */ + function getFunction($type, $name = null, $mirror = false) + { + $protocols = $this->getFunctions($type, $mirror); + if (!$protocols) { + return false; + } + + foreach ($protocols as $protocol) { + if ($name === null) { + return $protocol; + } + + if ($protocol['_content'] != $name) { + continue; + } + + return $protocol; + } + + return false; + } + + /** + * @param string protocol type + * @param string protocol name + * @param string version + * @param string mirror name + * @return boolean + */ + function supports($type, $name = null, $mirror = false, $version = '1.0') + { + $protocols = $this->getFunctions($type, $mirror); + if (!$protocols) { + return false; + } + + foreach ($protocols as $protocol) { + if ($protocol['attribs']['version'] != $version) { + continue; + } + + if ($name === null) { + return true; + } + + if ($protocol['_content'] != $name) { + continue; + } + + return true; + } + + return false; + } + + /** + * Determines whether a channel supports Representational State Transfer (REST) protocols + * for retrieving channel information + * @param string + * @return bool + */ + function supportsREST($mirror = false) + { + if ($mirror == $this->_channelInfo['name']) { + $mirror = false; + } + + if ($mirror) { + if ($mir = $this->getMirror($mirror)) { + return isset($mir['rest']); + } + + return false; + } + + return isset($this->_channelInfo['servers']['primary']['rest']); + } + + /** + * Get the URL to access a base resource. + * + * Hyperlinks in the returned xml will be used to retrieve the proper information + * needed. This allows extreme extensibility and flexibility in implementation + * @param string Resource Type to retrieve + */ + function getBaseURL($resourceType, $mirror = false) + { + if ($mirror == $this->_channelInfo['name']) { + $mirror = false; + } + + if ($mirror) { + $mir = $this->getMirror($mirror); + if (!$mir) { + return false; + } + + $rest = $mir['rest']; + } else { + $rest = $this->_channelInfo['servers']['primary']['rest']; + } + + if (!isset($rest['baseurl'][0])) { + $rest['baseurl'] = array($rest['baseurl']); + } + + foreach ($rest['baseurl'] as $baseurl) { + if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) { + return $baseurl['_content']; + } + } + + return false; + } + + /** + * Since REST does not implement RPC, provide this as a logical wrapper around + * resetFunctions for REST + * @param string|false mirror name, if any + */ + function resetREST($mirror = false) + { + return $this->resetFunctions('rest', $mirror); + } + + /** + * Empty all protocol definitions + * @param string protocol type + * @param string|false mirror name, if any + */ + function resetFunctions($type, $mirror = false) + { + if ($mirror) { + if (isset($this->_channelInfo['servers']['mirror'])) { + $mirrors = $this->_channelInfo['servers']['mirror']; + if (!isset($mirrors[0])) { + $mirrors = array($mirrors); + } + + foreach ($mirrors as $i => $mir) { + if ($mir['attribs']['host'] == $mirror) { + if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) { + unset($this->_channelInfo['servers']['mirror'][$i][$type]); + } + + return true; + } + } + + return false; + } + + return false; + } + + if (isset($this->_channelInfo['servers']['primary'][$type])) { + unset($this->_channelInfo['servers']['primary'][$type]); + } + + return true; + } + + /** + * Set a channel's protocols to the protocols supported by pearweb + */ + function setDefaultPEARProtocols($version = '1.0', $mirror = false) + { + switch ($version) { + case '1.0' : + $this->resetREST($mirror); + + if (!isset($this->_channelInfo['servers'])) { + $this->_channelInfo['servers'] = array('primary' => + array('rest' => array())); + } elseif (!isset($this->_channelInfo['servers']['primary'])) { + $this->_channelInfo['servers']['primary'] = array('rest' => array()); + } + + return true; + break; + default : + return false; + break; + } + } + + /** + * @return array + */ + function getMirrors() + { + if (isset($this->_channelInfo['servers']['mirror'])) { + $mirrors = $this->_channelInfo['servers']['mirror']; + if (!isset($mirrors[0])) { + $mirrors = array($mirrors); + } + + return $mirrors; + } + + return array(); + } + + /** + * Get the unserialized XML representing a mirror + * @return array|false + */ + function getMirror($server) + { + foreach ($this->getMirrors() as $mirror) { + if ($mirror['attribs']['host'] == $server) { + return $mirror; + } + } + + return false; + } + + /** + * @param string + * @return string|false + * @error PEAR_CHANNELFILE_ERROR_NO_NAME + * @error PEAR_CHANNELFILE_ERROR_INVALID_NAME + */ + function setName($name) + { + return $this->setServer($name); + } + + /** + * Set the socket number (port) that is used to connect to this channel + * @param integer + * @param string|false name of the mirror server, or false for the primary + */ + function setPort($port, $mirror = false) + { + if ($mirror) { + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + if (isset($this->_channelInfo['servers']['mirror'][0])) { + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + $this->_channelInfo['servers']['mirror'][$i]['attribs']['port'] = $port; + return true; + } + } + + return false; + } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { + $this->_channelInfo['servers']['mirror']['attribs']['port'] = $port; + $this->_isValid = false; + return true; + } + } + + $this->_channelInfo['servers']['primary']['attribs']['port'] = $port; + $this->_isValid = false; + return true; + } + + /** + * Set the socket number (port) that is used to connect to this channel + * @param bool Determines whether to turn on SSL support or turn it off + * @param string|false name of the mirror server, or false for the primary + */ + function setSSL($ssl = true, $mirror = false) + { + if ($mirror) { + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + if (isset($this->_channelInfo['servers']['mirror'][0])) { + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + if (!$ssl) { + if (isset($this->_channelInfo['servers']['mirror'][$i] + ['attribs']['ssl'])) { + unset($this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl']); + } + } else { + $this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes'; + } + + return true; + } + } + + return false; + } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { + if (!$ssl) { + if (isset($this->_channelInfo['servers']['mirror']['attribs']['ssl'])) { + unset($this->_channelInfo['servers']['mirror']['attribs']['ssl']); + } + } else { + $this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes'; + } + + $this->_isValid = false; + return true; + } + } + + if ($ssl) { + $this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes'; + } else { + if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) { + unset($this->_channelInfo['servers']['primary']['attribs']['ssl']); + } + } + + $this->_isValid = false; + return true; + } + + /** + * @param string + * @return string|false + * @error PEAR_CHANNELFILE_ERROR_NO_SERVER + * @error PEAR_CHANNELFILE_ERROR_INVALID_SERVER + */ + function setServer($server, $mirror = false) + { + if (empty($server)) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SERVER); + return false; + } elseif (!$this->validChannelServer($server)) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, + array('tag' => 'name', 'name' => $server)); + return false; + } + + if ($mirror) { + $found = false; + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + $found = true; + break; + } + } + + if (!$found) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + $this->_channelInfo['mirror'][$i]['attribs']['host'] = $server; + return true; + } + + $this->_channelInfo['name'] = $server; + return true; + } + + /** + * @param string + * @return boolean success + * @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY + * @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY + */ + function setSummary($summary) + { + if (empty($summary)) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY); + return false; + } elseif (strpos(trim($summary), "\n") !== false) { + $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY, + array('summary' => $summary)); + } + + $this->_channelInfo['summary'] = $summary; + return true; + } + + /** + * @param string + * @param boolean determines whether the alias is in channel.xml or local + * @return boolean success + */ + function setAlias($alias, $local = false) + { + if (!$this->validChannelServer($alias)) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, + array('tag' => 'suggestedalias', 'name' => $alias)); + return false; + } + + if ($local) { + $this->_channelInfo['localalias'] = $alias; + } else { + $this->_channelInfo['suggestedalias'] = $alias; + } + + return true; + } + + /** + * @return string + */ + function getAlias() + { + if (isset($this->_channelInfo['localalias'])) { + return $this->_channelInfo['localalias']; + } + if (isset($this->_channelInfo['suggestedalias'])) { + return $this->_channelInfo['suggestedalias']; + } + if (isset($this->_channelInfo['name'])) { + return $this->_channelInfo['name']; + } + return ''; + } + + /** + * Set the package validation object if it differs from PEAR's default + * The class must be includeable via changing _ in the classname to path separator, + * but no checking of this is made. + * @param string|false pass in false to reset to the default packagename regex + * @return boolean success + */ + function setValidationPackage($validateclass, $version) + { + if (empty($validateclass)) { + unset($this->_channelInfo['validatepackage']); + } + $this->_channelInfo['validatepackage'] = array('_content' => $validateclass); + $this->_channelInfo['validatepackage']['attribs'] = array('version' => $version); + } + + /** + * Add a protocol to the provides section + * @param string protocol type + * @param string protocol version + * @param string protocol name, if any + * @param string mirror name, if this is a mirror's protocol + * @return bool + */ + function addFunction($type, $version, $name = '', $mirror = false) + { + if ($mirror) { + return $this->addMirrorFunction($mirror, $type, $version, $name); + } + + $set = array('attribs' => array('version' => $version), '_content' => $name); + if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) { + if (!isset($this->_channelInfo['servers'])) { + $this->_channelInfo['servers'] = array('primary' => + array($type => array())); + } elseif (!isset($this->_channelInfo['servers']['primary'])) { + $this->_channelInfo['servers']['primary'] = array($type => array()); + } + + $this->_channelInfo['servers']['primary'][$type]['function'] = $set; + $this->_isValid = false; + return true; + } elseif (!isset($this->_channelInfo['servers']['primary'][$type]['function'][0])) { + $this->_channelInfo['servers']['primary'][$type]['function'] = array( + $this->_channelInfo['servers']['primary'][$type]['function']); + } + + $this->_channelInfo['servers']['primary'][$type]['function'][] = $set; + return true; + } + /** + * Add a protocol to a mirror's provides section + * @param string mirror name (server) + * @param string protocol type + * @param string protocol version + * @param string protocol name, if any + */ + function addMirrorFunction($mirror, $type, $version, $name = '') + { + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + $setmirror = false; + if (isset($this->_channelInfo['servers']['mirror'][0])) { + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + $setmirror = &$this->_channelInfo['servers']['mirror'][$i]; + break; + } + } + } else { + if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { + $setmirror = &$this->_channelInfo['servers']['mirror']; + } + } + + if (!$setmirror) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + $set = array('attribs' => array('version' => $version), '_content' => $name); + if (!isset($setmirror[$type]['function'])) { + $setmirror[$type]['function'] = $set; + $this->_isValid = false; + return true; + } elseif (!isset($setmirror[$type]['function'][0])) { + $setmirror[$type]['function'] = array($setmirror[$type]['function']); + } + + $setmirror[$type]['function'][] = $set; + $this->_isValid = false; + return true; + } + + /** + * @param string Resource Type this url links to + * @param string URL + * @param string|false mirror name, if this is not a primary server REST base URL + */ + function setBaseURL($resourceType, $url, $mirror = false) + { + if ($mirror) { + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, + array('mirror' => $mirror)); + return false; + } + + $setmirror = false; + if (isset($this->_channelInfo['servers']['mirror'][0])) { + foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { + if ($mirror == $mir['attribs']['host']) { + $setmirror = &$this->_channelInfo['servers']['mirror'][$i]; + break; + } + } + } else { + if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { + $setmirror = &$this->_channelInfo['servers']['mirror']; + } + } + } else { + $setmirror = &$this->_channelInfo['servers']['primary']; + } + + $set = array('attribs' => array('type' => $resourceType), '_content' => $url); + if (!isset($setmirror['rest'])) { + $setmirror['rest'] = array(); + } + + if (!isset($setmirror['rest']['baseurl'])) { + $setmirror['rest']['baseurl'] = $set; + $this->_isValid = false; + return true; + } elseif (!isset($setmirror['rest']['baseurl'][0])) { + $setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']); + } + + foreach ($setmirror['rest']['baseurl'] as $i => $url) { + if ($url['attribs']['type'] == $resourceType) { + $this->_isValid = false; + $setmirror['rest']['baseurl'][$i] = $set; + return true; + } + } + + $setmirror['rest']['baseurl'][] = $set; + $this->_isValid = false; + return true; + } + + /** + * @param string mirror server + * @param int mirror http port + * @return boolean + */ + function addMirror($server, $port = null) + { + if ($this->_channelInfo['name'] == '__uri') { + return false; // the __uri channel cannot have mirrors by definition + } + + $set = array('attribs' => array('host' => $server)); + if (is_numeric($port)) { + $set['attribs']['port'] = $port; + } + + if (!isset($this->_channelInfo['servers']['mirror'])) { + $this->_channelInfo['servers']['mirror'] = $set; + return true; + } + + if (!isset($this->_channelInfo['servers']['mirror'][0])) { + $this->_channelInfo['servers']['mirror'] = + array($this->_channelInfo['servers']['mirror']); + } + + $this->_channelInfo['servers']['mirror'][] = $set; + return true; + } + + /** + * Retrieve the name of the validation package for this channel + * @return string|false + */ + function getValidationPackage() + { + if (!$this->_isValid && !$this->validate()) { + return false; + } + + if (!isset($this->_channelInfo['validatepackage'])) { + return array('attribs' => array('version' => 'default'), + '_content' => 'PEAR_Validate'); + } + + return $this->_channelInfo['validatepackage']; + } + + /** + * Retrieve the object that can be used for custom validation + * @param string|false the name of the package to validate. If the package is + * the channel validation package, PEAR_Validate is returned + * @return PEAR_Validate|false false is returned if the validation package + * cannot be located + */ + function &getValidationObject($package = false) + { + if (!class_exists('PEAR_Validate')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validate.php'; + } + + if (!$this->_isValid) { + if (!$this->validate()) { + $a = false; + return $a; + } + } + + if (isset($this->_channelInfo['validatepackage'])) { + if ($package == $this->_channelInfo['validatepackage']) { + // channel validation packages are always validated by PEAR_Validate + $val = &new PEAR_Validate; + return $val; + } + + if (!class_exists(str_replace('.', '_', + $this->_channelInfo['validatepackage']['_content']))) { + if ($this->isIncludeable(str_replace('_', '/', + $this->_channelInfo['validatepackage']['_content']) . '.php')) { + include_once 'phar://install-pear-nozlib.phar/' . str_replace('_', '/', + $this->_channelInfo['validatepackage']['_content']) . '.php'; + $vclass = str_replace('.', '_', + $this->_channelInfo['validatepackage']['_content']); + $val = &new $vclass; + } else { + $a = false; + return $a; + } + } else { + $vclass = str_replace('.', '_', + $this->_channelInfo['validatepackage']['_content']); + $val = &new $vclass; + } + } else { + $val = &new PEAR_Validate; + } + + return $val; + } + + function isIncludeable($path) + { + $possibilities = explode(PATH_SEPARATOR, ini_get('include_path')); + foreach ($possibilities as $dir) { + if (file_exists($dir . DIRECTORY_SEPARATOR . $path) + && is_readable($dir . DIRECTORY_SEPARATOR . $path)) { + return true; + } + } + + return false; + } + + /** + * This function is used by the channel updater and retrieves a value set by + * the registry, or the current time if it has not been set + * @return string + */ + function lastModified() + { + if (isset($this->_channelInfo['_lastmodified'])) { + return $this->_channelInfo['_lastmodified']; + } + + return time(); + } +} + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Parser.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * base xml parser class + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; +/** + * Parser for channel.xml + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_ChannelFile_Parser extends PEAR_XMLParser +{ + var $_config; + var $_logger; + var $_registry; + + function setConfig(&$c) + { + $this->_config = &$c; + $this->_registry = &$c->getRegistry(); + } + + function setLogger(&$l) + { + $this->_logger = &$l; + } + + function parse($data, $file) + { + if (PEAR::isError($err = parent::parse($data, $file))) { + return $err; + } + + $ret = new PEAR_ChannelFile; + $ret->setConfig($this->_config); + if (isset($this->_logger)) { + $ret->setLogger($this->_logger); + } + + $ret->fromArray($this->_unserializedData); + // make sure the filelist is in the easy to read format needed + $ret->flattenFilelist(); + $ret->setPackagefile($file, $archive); + return $ret; + } +} + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Command.php 286494 2009-07-29 06:57:11Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * Needed for error handling + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Frontend.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; + +/** + * List of commands and what classes they are implemented in. + * @var array command => implementing class + */ +$GLOBALS['_PEAR_Command_commandlist'] = array(); + +/** + * List of commands and their descriptions + * @var array command => description + */ +$GLOBALS['_PEAR_Command_commanddesc'] = array(); + +/** + * List of shortcuts to common commands. + * @var array shortcut => command + */ +$GLOBALS['_PEAR_Command_shortcuts'] = array(); + +/** + * Array of command objects + * @var array class => object + */ +$GLOBALS['_PEAR_Command_objects'] = array(); + +/** + * PEAR command class, a simple factory class for administrative + * commands. + * + * How to implement command classes: + * + * - The class must be called PEAR_Command_Nnn, installed in the + * "PEAR/Common" subdir, with a method called getCommands() that + * returns an array of the commands implemented by the class (see + * PEAR/Command/Install.php for an example). + * + * - The class must implement a run() function that is called with three + * params: + * + * (string) command name + * (array) assoc array with options, freely defined by each + * command, for example: + * array('force' => true) + * (array) list of the other parameters + * + * The run() function returns a PEAR_CommandResponse object. Use + * these methods to get information: + * + * int getStatus() Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL) + * *_PARTIAL means that you need to issue at least + * one more command to complete the operation + * (used for example for validation steps). + * + * string getMessage() Returns a message for the user. Remember, + * no HTML or other interface-specific markup. + * + * If something unexpected happens, run() returns a PEAR error. + * + * - DON'T OUTPUT ANYTHING! Return text for output instead. + * + * - DON'T USE HTML! The text you return will be used from both Gtk, + * web and command-line interfaces, so for now, keep everything to + * plain text. + * + * - DON'T USE EXIT OR DIE! Always use pear errors. From static + * classes do PEAR::raiseError(), from other classes do + * $this->raiseError(). + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Command +{ + // {{{ factory() + + /** + * Get the right object for executing a command. + * + * @param string $command The name of the command + * @param object $config Instance of PEAR_Config object + * + * @return object the command object or a PEAR error + * + * @access public + * @static + */ + function &factory($command, &$config) + { + if (empty($GLOBALS['_PEAR_Command_commandlist'])) { + PEAR_Command::registerCommands(); + } + if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { + $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; + } + if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { + $a = PEAR::raiseError("unknown command `$command'"); + return $a; + } + $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; + if (!class_exists($class)) { + require_once $GLOBALS['_PEAR_Command_objects'][$class]; + } + if (!class_exists($class)) { + $a = PEAR::raiseError("unknown command `$command'"); + return $a; + } + $ui =& PEAR_Command::getFrontendObject(); + $obj = &new $class($ui, $config); + return $obj; + } + + // }}} + // {{{ & getObject() + function &getObject($command) + { + $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; + if (!class_exists($class)) { + require_once $GLOBALS['_PEAR_Command_objects'][$class]; + } + if (!class_exists($class)) { + return PEAR::raiseError("unknown command `$command'"); + } + $ui =& PEAR_Command::getFrontendObject(); + $config = &PEAR_Config::singleton(); + $obj = &new $class($ui, $config); + return $obj; + } + + // }}} + // {{{ & getFrontendObject() + + /** + * Get instance of frontend object. + * + * @return object|PEAR_Error + * @static + */ + function &getFrontendObject() + { + $a = &PEAR_Frontend::singleton(); + return $a; + } + + // }}} + // {{{ & setFrontendClass() + + /** + * Load current frontend class. + * + * @param string $uiclass Name of class implementing the frontend + * + * @return object the frontend object, or a PEAR error + * @static + */ + function &setFrontendClass($uiclass) + { + $a = &PEAR_Frontend::setFrontendClass($uiclass); + return $a; + } + + // }}} + // {{{ setFrontendType() + + /** + * Set current frontend. + * + * @param string $uitype Name of the frontend type (for example "CLI") + * + * @return object the frontend object, or a PEAR error + * @static + */ + function setFrontendType($uitype) + { + $uiclass = 'PEAR_Frontend_' . $uitype; + return PEAR_Command::setFrontendClass($uiclass); + } + + // }}} + // {{{ registerCommands() + + /** + * Scan through the Command directory looking for classes + * and see what commands they implement. + * + * @param bool (optional) if FALSE (default), the new list of + * commands should replace the current one. If TRUE, + * new entries will be merged with old. + * + * @param string (optional) where (what directory) to look for + * classes, defaults to the Command subdirectory of + * the directory from where this file (__FILE__) is + * included. + * + * @return bool TRUE on success, a PEAR error on failure + * + * @access public + * @static + */ + function registerCommands($merge = false, $dir = null) + { + $parser = new PEAR_XMLParser; + if ($dir === null) { + $dir = dirname(__FILE__) . '/Command'; + } + if (!is_dir($dir)) { + return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory"); + } + $dp = @opendir($dir); + if (empty($dp)) { + return PEAR::raiseError("registerCommands: opendir($dir) failed"); + } + if (!$merge) { + $GLOBALS['_PEAR_Command_commandlist'] = array(); + } + + while ($file = readdir($dp)) { + if ($file{0} == '.' || substr($file, -4) != '.xml') { + continue; + } + + $f = substr($file, 0, -4); + $class = "PEAR_Command_" . $f; + // List of commands + if (empty($GLOBALS['_PEAR_Command_objects'][$class])) { + $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . $f . '.php'; + } + + $parser->parse(file_get_contents("$dir/$file")); + $implements = $parser->getData(); + foreach ($implements as $command => $desc) { + if ($command == 'attribs') { + continue; + } - Remove custom XML_Util class in favor of using upstream XML_Util package as dependency + if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { + return PEAR::raiseError('Command "' . $command . '" already registered in ' . + 'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); + } -RC1 Release Notes: - * Fix Bug #14331: pear cvstag only works from inside the package directory [dufuz] - * Fix Bug #16045: E_Notice: Undefined index: channel in PEAR/DependencyDB.php [dufuz] + $GLOBALS['_PEAR_Command_commandlist'][$command] = $class; + $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary']; + if (isset($desc['shortcut'])) { + $shortcut = $desc['shortcut']; + if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) { + return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' . + 'registered to command "' . $command . '" in class "' . + $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); + } + $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command; + } - * Implemented Request #11230: better error message when mirror not in channel.xml file [dufuz] - * Implemented Request #13150: Add support for following HTTP 302 redirects [dufuz] + if (isset($desc['options']) && $desc['options']) { + foreach ($desc['options'] as $oname => $option) { + if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) { + return PEAR::raiseError('Option "' . $oname . '" short option "' . + $option['shortopt'] . '" must be ' . + 'only 1 character in Command "' . $command . '" in class "' . + $class . '"'); + } + } + } + } + } -Alpha1 Release Notes: - * Implement Request #10373: if pref_state=stable and installed package=beta, allow up to latest beta version [dufuz] - * Implement Request #10581: login / logout should map to channel-login / channel-logout [dufuz] - * Implement Request #10825: Only display the "invalid or missing package file"-error if it makes sense [dufuz] - * Implement Request #11170: script to generate Command/[command].xml [dufuz] - * Implement Request #11176: improve channel ... has updated its protocols message [dufuz] - * Implement Request #12706: pear list -a hard to read [dufuz] - * Implement Request #11353: upgrade-all and upgrade commands to upgrade within the same stability level [dufuz] - * Implement Request #13015: Add https discovery for channel.xml [dufuz / initial patch by Martin Roos] - * Implement Request #13927: install-pear.php should have option to set www_dir [timj] - * Implement Request #14324: Make the pear install command behave similar to apt-get [dufuz] - * Implement Request #14325: make pear upgrade with no params behave like pear upgrade-all [dufuz] - - upgrade-all can be considered deprecated in favor of calling upgrade with no parameters to replicate - better what other package managers are doing. upgrade-all will still work as intended. - * Implement Request #14504: add a channel parameter support to the upgrade function [dufuz] - - Options -c ezc and --channel=ezc got added to upgrade and upgrade-all to allow for - channel specific upgrades - * Implement Request #14556: install-pear-nozlib.phar should get download_dir config and other options [cweiske] - * Implement Request #15566: Add doc.php.net as a default channel [dufuz / saltybeagle] + ksort($GLOBALS['_PEAR_Command_shortcuts']); + ksort($GLOBALS['_PEAR_Command_commandlist']); + @closedir($dp); + return true; + } - * Fix PHP Bug #43857: --program-suffix not always reflected everywhere [cellog] - * Fix PHP Bug #47323: strotime warnings in make install [dufuz] + // }}} + // {{{ getCommands() - * Fix Bug #13908: pear info command and maintainers inactive not mentioned [dufuz] - * Fix Bug #13926: install-pear.php does not set cfg_dir if -d option set with no -c option [timj] - * Fix Bug #13943: tests fail when php.exe path contains spaces [dufuz / jorrit] - * Fix Bug #13953: config-set/config-show with channel alias fail [cellog] - * Fix Bug #13958: When a phpt tests exit() or die() xdebug coverage is not generated, patch by izi (David Jean Louis) [izi / dufuz] - * Fix Bug #14041: Unpredictable unit test processing sequence [dufuz] - * Fix Bug #14140: Strict warning not suppressed in the shutdown function [dufuz] - * Fix Bug #14210: pear list -ia brings warnings [dufuz] - * Fix Bug #14274: PEAR packager mangles package.xml encoding, then complains about it [dufuz] - * Fix Bug #14287: cannot upgrade from stable to beta via -beta when config is set to stable [dufuz] - * Fix Bug #14300: Package files themselves can not be served over https [dufuz / initial patch by Martin Roos] - * Fix Bug #14437: openbasedir warning when loading config [dufuz] - * Fix Bug #14558: PackageFile.php creates tmp directory outside configured temp_dir [cweiske] - * Fix Bug #14947: downloadHttp() is missing Host part of the HTTP Request when using Proxy [ifeghali] - * Fix Bug #14977: PEAR/Frontend.php doesn't require_once PEAR.php [dufuz] - * Fix Bug #15750: Unreachable code in PEAR_Downloader [dufuz] - * Fix Bug #15979: Package files incorrectly removed when splitting a package into multiple pkgs [dufuz] - * Fix Bug #15914: pear upgrade installs different version if desired version not found [dufuz] + /** + * Get the list of currently supported commands, and what + * classes implement them. + * + * @return array command => implementing class + * + * @access public + * @static + */ + function getCommands() + { + if (empty($GLOBALS['_PEAR_Command_commandlist'])) { + PEAR_Command::registerCommands(); + } + return $GLOBALS['_PEAR_Command_commandlist']; + } - NOTE! - Functions that have been deprecated for 3+ years in PEAR_Common, please take a moment - to migrate over to one of the alternatives that have ben provided: - * PEAR_Common->downloadHttp (use PEAR_Downloader->downloadHttp instead) - * PEAR_Common->infoFromTgzFile (use PEAR_PackageFile->fromTgzFile instead) - * PEAR_Common->infoFromDescriptionFile (use PEAR_PackageFile->fromPackageFile instead) - * PEAR_Common->infoFromString (use PEAR_PackageFile->fromXmlstring instead) - * PEAR_Common->infoFromArray (use PEAR_PackageFile->fromAnyFile instead) - * PEAR_Common->xmlFromInfo (use a PEAR_PackageFile_v* object's generator instead) - * PEAR_Common->validatePackageInfo (use the validation of PEAR_PackageFile objects) - * PEAR_Common->analyzeSourceCode (use a PEAR_PackageFile_v* object instead) - * PEAR_Common->detectDependencies (use PEAR_Downloader_Package->detectDependencies instead) - * PEAR_Common->buildProvidesArray (use PEAR_PackageFile_v1->_buildProvidesArray or - PEAR_PackageFile_v2_Validator->_buildProvidesArray) + // }}} + // {{{ getShortcuts() - PHP 4.4 and 5.1.6 are now the minimum PHP requirements, for brave souls - pear upgrade -f PEAR will allow people with lower versions - to upgrade to this release but no guarantees will be made that it will work properly. + /** + * Get the list of command shortcuts. + * + * @return array shortcut => command + * + * @access public + * @static + */ + function getShortcuts() + { + if (empty($GLOBALS['_PEAR_Command_shortcuts'])) { + PEAR_Command::registerCommands(); + } + return $GLOBALS['_PEAR_Command_shortcuts']; + } - Support for XML RPC channels has been dropped - The only ones that used it - (pear.php.net and pecl.php.net) have used the REST interface for years now. - SOAP support also removed as it was only proof of concept. + // }}} + // {{{ getGetoptArgs() - Move codebase from the PHP License to New BSD 2 clause license - - - - -getGetoptArgs($command, $short_args, $long_args); + } + + // }}} + // {{{ getDescription() + + /** + * Get description for a command. + * + * @param string $command Name of the command + * + * @return string command description + * + * @access public + * @static + */ + function getDescription($command) + { + if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) { + return null; + } + return $GLOBALS['_PEAR_Command_commanddesc'][$command]; + } + + // }}} + // {{{ getHelp() + + /** + * Get help for command. + * + * @param string $command Name of the command to return help for + * + * @access public + * @static + */ + function getHelp($command) + { + $cmds = PEAR_Command::getCommands(); + if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { + $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; + } + if (isset($cmds[$command])) { + $obj = &PEAR_Command::getObject($command); + return $obj->getHelp($command); + } + return false; + } + // }}} +} * @author Stig Bakken - * @author Tomas V.V.Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PEAR.php,v 1.111 2009/04/08 23:32:04 dufuz Exp $ + * @version CVS: $Id: Common.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ -/**#@+ - * ERROR constants +/** + * base class */ -define('PEAR_ERROR_RETURN', 1); -define('PEAR_ERROR_PRINT', 2); -define('PEAR_ERROR_TRIGGER', 4); -define('PEAR_ERROR_DIE', 8); -define('PEAR_ERROR_CALLBACK', 16); +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; + /** - * WARNING: obsolete - * @deprecated + * PEAR commands base class + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 */ -define('PEAR_ERROR_EXCEPTION', 32); -/**#@-*/ -define('PEAR_ZE2', (function_exists('version_compare') && - version_compare(zend_version(), "2-dev", "ge"))); +class PEAR_Command_Common extends PEAR +{ + /** + * PEAR_Config object used to pass user system and configuration + * on when executing commands + * + * @var PEAR_Config + */ + var $config; + /** + * @var PEAR_Registry + * @access protected + */ + var $_registry; -if (substr(PHP_OS, 0, 3) == 'WIN') { - define('OS_WINDOWS', true); - define('OS_UNIX', false); - define('PEAR_OS', 'Windows'); -} else { - define('OS_WINDOWS', false); - define('OS_UNIX', true); - define('PEAR_OS', 'Unix'); // blatant assumption -} + /** + * User Interface object, for all interaction with the user. + * @var object + */ + var $ui; -$GLOBALS['_PEAR_default_error_mode'] = PEAR_ERROR_RETURN; -$GLOBALS['_PEAR_default_error_options'] = E_USER_NOTICE; -$GLOBALS['_PEAR_destructor_object_list'] = array(); -$GLOBALS['_PEAR_shutdown_funcs'] = array(); -$GLOBALS['_PEAR_error_handler_stack'] = array(); + var $_deps_rel_trans = array( + 'lt' => '<', + 'le' => '<=', + 'eq' => '=', + 'ne' => '!=', + 'gt' => '>', + 'ge' => '>=', + 'has' => '==' + ); -@ini_set('track_errors', true); + var $_deps_type_trans = array( + 'pkg' => 'package', + 'ext' => 'extension', + 'php' => 'PHP', + 'prog' => 'external program', + 'ldlib' => 'external library for linking', + 'rtlib' => 'external runtime library', + 'os' => 'operating system', + 'websrv' => 'web server', + 'sapi' => 'SAPI backend' + ); + + /** + * PEAR_Command_Common constructor. + * + * @access public + */ + function PEAR_Command_Common(&$ui, &$config) + { + parent::PEAR(); + $this->config = &$config; + $this->ui = &$ui; + } + + /** + * Return a list of all the commands defined by this class. + * @return array list of commands + * @access public + */ + function getCommands() + { + $ret = array(); + foreach (array_keys($this->commands) as $command) { + $ret[$command] = $this->commands[$command]['summary']; + } + + return $ret; + } + + /** + * Return a list of all the command shortcuts defined by this class. + * @return array shortcut => command + * @access public + */ + function getShortcuts() + { + $ret = array(); + foreach (array_keys($this->commands) as $command) { + if (isset($this->commands[$command]['shortcut'])) { + $ret[$this->commands[$command]['shortcut']] = $command; + } + } + + return $ret; + } + + function getOptions($command) + { + $shortcuts = $this->getShortcuts(); + if (isset($shortcuts[$command])) { + $command = $shortcuts[$command]; + } + + if (isset($this->commands[$command]) && + isset($this->commands[$command]['options'])) { + return $this->commands[$command]['options']; + } + + return null; + } + + function getGetoptArgs($command, &$short_args, &$long_args) + { + $short_args = ''; + $long_args = array(); + if (empty($this->commands[$command]) || empty($this->commands[$command]['options'])) { + return; + } + + reset($this->commands[$command]['options']); + while (list($option, $info) = each($this->commands[$command]['options'])) { + $larg = $sarg = ''; + if (isset($info['arg'])) { + if ($info['arg']{0} == '(') { + $larg = '=='; + $sarg = '::'; + $arg = substr($info['arg'], 1, -1); + } else { + $larg = '='; + $sarg = ':'; + $arg = $info['arg']; + } + } + + if (isset($info['shortopt'])) { + $short_args .= $info['shortopt'] . $sarg; + } + + $long_args[] = $option . $larg; + } + } + + /** + * Returns the help message for the given command + * + * @param string $command The command + * @return mixed A fail string if the command does not have help or + * a two elements array containing [0]=>help string, + * [1]=> help string for the accepted cmd args + */ + function getHelp($command) + { + $config = &PEAR_Config::singleton(); + if (!isset($this->commands[$command])) { + return "No such command \"$command\""; + } + + $help = null; + if (isset($this->commands[$command]['doc'])) { + $help = $this->commands[$command]['doc']; + } + + if (empty($help)) { + // XXX (cox) Fallback to summary if there is no doc (show both?) + if (!isset($this->commands[$command]['summary'])) { + return "No help for command \"$command\""; + } + $help = $this->commands[$command]['summary']; + } + + if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) { + foreach($matches[0] as $k => $v) { + $help = preg_replace("/$v/", $config->get($matches[1][$k]), $help); + } + } + + return array($help, $this->getHelpArgs($command)); + } + + /** + * Returns the help for the accepted arguments of a command + * + * @param string $command + * @return string The help string + */ + function getHelpArgs($command) + { + if (isset($this->commands[$command]['options']) && + count($this->commands[$command]['options'])) + { + $help = "Options:\n"; + foreach ($this->commands[$command]['options'] as $k => $v) { + if (isset($v['arg'])) { + if ($v['arg'][0] == '(') { + $arg = substr($v['arg'], 1, -1); + $sapp = " [$arg]"; + $lapp = "[=$arg]"; + } else { + $sapp = " $v[arg]"; + $lapp = "=$v[arg]"; + } + } else { + $sapp = $lapp = ""; + } + + if (isset($v['shortopt'])) { + $s = $v['shortopt']; + $help .= " -$s$sapp, --$k$lapp\n"; + } else { + $help .= " --$k$lapp\n"; + } + + $p = " "; + $doc = rtrim(str_replace("\n", "\n$p", $v['doc'])); + $help .= " $doc\n"; + } + + return $help; + } + + return null; + } + + function run($command, $options, $params) + { + if (empty($this->commands[$command]['function'])) { + // look for shortcuts + foreach (array_keys($this->commands) as $cmd) { + if (isset($this->commands[$cmd]['shortcut']) && $this->commands[$cmd]['shortcut'] == $command) { + if (empty($this->commands[$cmd]['function'])) { + return $this->raiseError("unknown command `$command'"); + } else { + $func = $this->commands[$cmd]['function']; + } + $command = $cmd; + + //$command = $this->commands[$cmd]['function']; + break; + } + } + } else { + $func = $this->commands[$command]['function']; + } + return $this->$func($command, $options, $params); + } +}PEAR();. - * The destructor method will be called without parameters. Note that - * at in some SAPI implementations (such as Apache), any output during - * the request shutdown (in which destructors are called) seems to be - * discarded. If you need to get any debug information from your - * destructor, use error_log(), syslog() or something similar. + * PHP versions 4 and 5 * - * IMPORTANT! To use the emulated destructors you need to create the - * objects by reference: $obj =& new PEAR_child; + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Install.php 287477 2009-08-19 14:19:43Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * base class + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Command/Common.php'; + +/** + * PEAR commands for installation or deinstallation/upgrading of + * packages. * * @category pear * @package PEAR * @author Stig Bakken - * @author Tomas V.V. Cox * @author Greg Beaver - * @copyright 1997-2006 The PHP Group + * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @see PEAR_Error - * @since Class available since PHP 4.0.2 - * @link http://pear.php.net/manual/en/core.pear.php#core.pear.pear + * @since Class available since Release 0.1 */ -class PEAR +class PEAR_Command_Install extends PEAR_Command_Common { // {{{ properties - /** - * Whether to enable internal debug messages. - * - * @var bool - * @access private - */ - var $_debug = false; + var $commands = array( + 'install' => array( + 'summary' => 'Install Package', + 'function' => 'doInstall', + 'shortcut' => 'i', + 'options' => array( + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'will overwrite newer installed packages', + ), + 'loose' => array( + 'shortopt' => 'l', + 'doc' => 'do not check for recommended dependency version', + ), + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, install anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not install files, only register the package as installed', + ), + 'soft' => array( + 'shortopt' => 's', + 'doc' => 'soft install, fail silently, or upgrade if already installed', + ), + 'nobuild' => array( + 'shortopt' => 'B', + 'doc' => 'don\'t build C extensions', + ), + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'request uncompressed files when downloading', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', + ), + 'packagingroot' => array( + 'shortopt' => 'P', + 'arg' => 'DIR', + 'doc' => 'root directory used when packaging files, like RPM packaging', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + 'alldeps' => array( + 'shortopt' => 'a', + 'doc' => 'install all required and optional dependencies', + ), + 'onlyreqdeps' => array( + 'shortopt' => 'o', + 'doc' => 'install all required dependencies', + ), + 'offline' => array( + 'shortopt' => 'O', + 'doc' => 'do not attempt to download any urls or contact channels', + ), + 'pretend' => array( + 'shortopt' => 'p', + 'doc' => 'Only list the packages that would be downloaded', + ), + ), + 'doc' => '[channel/] ... +Installs one or more PEAR packages. You can specify a package to +install in four ways: - /** - * Default error mode for this object. - * - * @var int - * @access private - */ - var $_default_error_mode = null; +"Package-1.0.tgz" : installs from a local file + +"http://example.com/Package-1.0.tgz" : installs from +anywhere on the net. + +"package.xml" : installs the package described in +package.xml. Useful for testing, or for wrapping a PEAR package in +another package manager such as RPM. + +"Package[-version/state][.tar]" : queries your default channel\'s server +({config master_server}) and downloads the newest package with +the preferred quality/state ({config preferred_state}). + +To retrieve Package version 1.1, use "Package-1.1," to retrieve +Package state beta, use "Package-beta." To retrieve an uncompressed +file, append .tar (make sure there is no file by the same name first) + +To download a package from another channel, prefix with the channel name like +"channel/Package" + +More than one package may be specified at once. It is ok to mix these +four ways of specifying packages. +'), + 'upgrade' => array( + 'summary' => 'Upgrade Package', + 'function' => 'doInstall', + 'shortcut' => 'up', + 'options' => array( + 'channel' => array( + 'shortopt' => 'c', + 'doc' => 'upgrade packages from a specific channel', + 'arg' => 'CHAN', + ), + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'overwrite newer installed packages', + ), + 'loose' => array( + 'shortopt' => 'l', + 'doc' => 'do not check for recommended dependency version', + ), + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, upgrade anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not install files, only register the package as upgraded', + ), + 'nobuild' => array( + 'shortopt' => 'B', + 'doc' => 'don\'t build C extensions', + ), + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'request uncompressed files when downloading', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + 'alldeps' => array( + 'shortopt' => 'a', + 'doc' => 'install all required and optional dependencies', + ), + 'onlyreqdeps' => array( + 'shortopt' => 'o', + 'doc' => 'install all required dependencies', + ), + 'offline' => array( + 'shortopt' => 'O', + 'doc' => 'do not attempt to download any urls or contact channels', + ), + 'pretend' => array( + 'shortopt' => 'p', + 'doc' => 'Only list the packages that would be downloaded', + ), + ), + 'doc' => ' ... +Upgrades one or more PEAR packages. See documentation for the +"install" command for ways to specify a package. + +When upgrading, your package will be updated if the provided new +package has a higher version number (use the -f option if you need to +upgrade anyway). + +More than one package may be specified at once. +'), + 'upgrade-all' => array( + 'summary' => 'Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters]', + 'function' => 'doUpgradeAll', + 'shortcut' => 'ua', + 'options' => array( + 'channel' => array( + 'shortopt' => 'c', + 'doc' => 'upgrade packages from a specific channel', + 'arg' => 'CHAN', + ), + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, upgrade anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not install files, only register the package as upgraded', + ), + 'nobuild' => array( + 'shortopt' => 'B', + 'doc' => 'don\'t build C extensions', + ), + 'nocompress' => array( + 'shortopt' => 'Z', + 'doc' => 'request uncompressed files when downloading', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + 'loose' => array( + 'doc' => 'do not check for recommended dependency version', + ), + ), + 'doc' => ' +WARNING: This function is deprecated in favor of using the upgrade command with no params + +Upgrades all packages that have a newer release available. Upgrades are +done only if there is a release available of the state specified in +"preferred_state" (currently {config preferred_state}), or a state considered +more stable. +'), + 'uninstall' => array( + 'summary' => 'Un-install Package', + 'function' => 'doUninstall', + 'shortcut' => 'un', + 'options' => array( + 'nodeps' => array( + 'shortopt' => 'n', + 'doc' => 'ignore dependencies, uninstall anyway', + ), + 'register-only' => array( + 'shortopt' => 'r', + 'doc' => 'do not remove files, only register the packages as not installed', + ), + 'installroot' => array( + 'shortopt' => 'R', + 'arg' => 'DIR', + 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', + ), + 'ignore-errors' => array( + 'doc' => 'force install even if there were errors', + ), + 'offline' => array( + 'shortopt' => 'O', + 'doc' => 'do not attempt to uninstall remotely', + ), + ), + 'doc' => '[channel/] ... +Uninstalls one or more PEAR packages. More than one package may be +specified at once. Prefix with channel name to uninstall from a +channel not in your default channel ({config default_channel}) +'), + 'bundle' => array( + 'summary' => 'Unpacks a Pecl Package', + 'function' => 'doBundle', + 'shortcut' => 'bun', + 'options' => array( + 'destination' => array( + 'shortopt' => 'd', + 'arg' => 'DIR', + 'doc' => 'Optional destination directory for unpacking (defaults to current path or "ext" if exists)', + ), + 'force' => array( + 'shortopt' => 'f', + 'doc' => 'Force the unpacking even if there were errors in the package', + ), + ), + 'doc' => ' +Unpacks a Pecl Package into the selected location. It will download the +package if needed. +'), + 'run-scripts' => array( + 'summary' => 'Run Post-Install Scripts bundled with a package', + 'function' => 'doRunScripts', + 'shortcut' => 'rs', + 'options' => array( + ), + 'doc' => ' +Run post-installation scripts in package , if any exist. +'), + ); + + // }}} + // {{{ constructor /** - * Default error options used for this object when error mode - * is PEAR_ERROR_TRIGGER. + * PEAR_Command_Install constructor. * - * @var int - * @access private + * @access public */ - var $_default_error_options = null; + function PEAR_Command_Install(&$ui, &$config) + { + parent::PEAR_Command_Common($ui, $config); + } + + // }}} /** - * Default error handler (callback) for this object, if error mode is - * PEAR_ERROR_CALLBACK. - * - * @var string - * @access private + * For unit testing purposes */ - var $_default_error_handler = ''; + function &getDownloader(&$ui, $options, &$config) + { + if (!class_exists('PEAR_Downloader')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Downloader.php'; + } + $a = &new PEAR_Downloader($ui, $options, $config); + return $a; + } /** - * Which class to use for error objects. - * - * @var string - * @access private + * For unit testing purposes */ - var $_error_class = 'PEAR_Error'; + function &getInstaller(&$ui) + { + if (!class_exists('PEAR_Installer')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer.php'; + } + $a = &new PEAR_Installer($ui); + return $a; + } + + function enableExtension($binaries, $type) + { + if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) { + return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location'); + } + $ini = $this->_parseIni($phpini); + if (PEAR::isError($ini)) { + return $ini; + } + $line = 0; + if ($type == 'extsrc' || $type == 'extbin') { + $search = 'extensions'; + $enable = 'extension'; + } else { + $search = 'zend_extensions'; + ob_start(); + phpinfo(INFO_GENERAL); + $info = ob_get_contents(); + ob_end_clean(); + $debug = function_exists('leak') ? '_debug' : ''; + $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; + $enable = 'zend_extension' . $debug . $ts; + } + foreach ($ini[$search] as $line => $extension) { + if (in_array($extension, $binaries, true) || in_array( + $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) { + // already enabled - assume if one is, all are + return true; + } + } + if ($line) { + $newini = array_slice($ini['all'], 0, $line); + } else { + $newini = array(); + } + foreach ($binaries as $binary) { + if ($ini['extension_dir']) { + $binary = basename($binary); + } + $newini[] = $enable . '="' . $binary . '"' . (OS_UNIX ? "\n" : "\r\n"); + } + $newini = array_merge($newini, array_slice($ini['all'], $line)); + $fp = @fopen($phpini, 'wb'); + if (!$fp) { + return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing'); + } + foreach ($newini as $line) { + fwrite($fp, $line); + } + fclose($fp); + return true; + } + + function disableExtension($binaries, $type) + { + if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) { + return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location'); + } + $ini = $this->_parseIni($phpini); + if (PEAR::isError($ini)) { + return $ini; + } + $line = 0; + if ($type == 'extsrc' || $type == 'extbin') { + $search = 'extensions'; + $enable = 'extension'; + } else { + $search = 'zend_extensions'; + ob_start(); + phpinfo(INFO_GENERAL); + $info = ob_get_contents(); + ob_end_clean(); + $debug = function_exists('leak') ? '_debug' : ''; + $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; + $enable = 'zend_extension' . $debug . $ts; + } + $found = false; + foreach ($ini[$search] as $line => $extension) { + if (in_array($extension, $binaries, true) || in_array( + $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) { + $found = true; + break; + } + } + if (!$found) { + // not enabled + return true; + } + $fp = @fopen($phpini, 'wb'); + if (!$fp) { + return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing'); + } + if ($line) { + $newini = array_slice($ini['all'], 0, $line); + // delete the enable line + $newini = array_merge($newini, array_slice($ini['all'], $line + 1)); + } else { + $newini = array_slice($ini['all'], 1); + } + foreach ($newini as $line) { + fwrite($fp, $line); + } + fclose($fp); + return true; + } + + function _parseIni($filename) + { + if (!file_exists($filename)) { + return PEAR::raiseError('php.ini "' . $filename . '" does not exist'); + } + + if (filesize($filename) > 300000) { + return PEAR::raiseError('php.ini "' . $filename . '" is too large, aborting'); + } + + ob_start(); + phpinfo(INFO_GENERAL); + $info = ob_get_contents(); + ob_end_clean(); + $debug = function_exists('leak') ? '_debug' : ''; + $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : ''; + $zend_extension_line = 'zend_extension' . $debug . $ts; + $all = @file($filename); + if (!$all) { + return PEAR::raiseError('php.ini "' . $filename .'" could not be read'); + } + $zend_extensions = $extensions = array(); + // assume this is right, but pull from the php.ini if it is found + $extension_dir = ini_get('extension_dir'); + foreach ($all as $linenum => $line) { + $line = trim($line); + if (!$line) { + continue; + } + if ($line[0] == ';') { + continue; + } + if (strtolower(substr($line, 0, 13)) == 'extension_dir') { + $line = trim(substr($line, 13)); + if ($line[0] == '=') { + $x = trim(substr($line, 1)); + $x = explode(';', $x); + $extension_dir = str_replace('"', '', array_shift($x)); + continue; + } + } + if (strtolower(substr($line, 0, 9)) == 'extension') { + $line = trim(substr($line, 9)); + if ($line[0] == '=') { + $x = trim(substr($line, 1)); + $x = explode(';', $x); + $extensions[$linenum] = str_replace('"', '', array_shift($x)); + continue; + } + } + if (strtolower(substr($line, 0, strlen($zend_extension_line))) == + $zend_extension_line) { + $line = trim(substr($line, strlen($zend_extension_line))); + if ($line[0] == '=') { + $x = trim(substr($line, 1)); + $x = explode(';', $x); + $zend_extensions[$linenum] = str_replace('"', '', array_shift($x)); + continue; + } + } + } + return array( + 'extensions' => $extensions, + 'zend_extensions' => $zend_extensions, + 'extension_dir' => $extension_dir, + 'all' => $all, + ); + } - /** - * An array of expected errors. - * - * @var array - * @access private - */ - var $_expected_errors = array(); + // {{{ doInstall() - // }}} + function doInstall($command, $options, $params) + { + if (!class_exists('PEAR_PackageFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile.php'; + } - // {{{ constructor + if (isset($options['installroot']) && isset($options['packagingroot'])) { + return $this->raiseError('ERROR: cannot use both --installroot and --packagingroot'); + } - /** - * Constructor. Registers this object in - * $_PEAR_destructor_object_list for destructor emulation if a - * destructor object exists. - * - * @param string $error_class (optional) which class to use for - * error objects, defaults to PEAR_Error. - * @access public - * @return void - */ - function PEAR($error_class = null) - { - $classname = strtolower(get_class($this)); - if ($this->_debug) { - print "PEAR constructor called, class=$classname\n"; + $reg = &$this->config->getRegistry(); + $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel'); + if (!$reg->channelExists($channel)) { + return $this->raiseError('Channel "' . $channel . '" does not exist'); } - if ($error_class !== null) { - $this->_error_class = $error_class; + + if (empty($this->installer)) { + $this->installer = &$this->getInstaller($this->ui); } - while ($classname && strcasecmp($classname, "pear")) { - $destructor = "_$classname"; - if (method_exists($this, $destructor)) { - global $_PEAR_destructor_object_list; - $_PEAR_destructor_object_list[] = &$this; - if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { - register_shutdown_function("_PEAR_call_destructors"); - $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; - } - break; - } else { - $classname = get_parent_class($classname); + + if ($command == 'upgrade' || $command == 'upgrade-all') { + // If people run the upgrade command but pass nothing, emulate a upgrade-all + if ($command == 'upgrade' && empty($params)) { + return $this->doUpgradeAll($command, $options, $params); } + $options['upgrade'] = true; + } else { + $packages = $params; } - } - // }}} - // {{{ destructor + $instreg = &$reg; // instreg used to check if package is installed + if (isset($options['packagingroot']) && !isset($options['upgrade'])) { + $packrootphp_dir = $this->installer->_prependPath( + $this->config->get('php_dir', null, 'pear.php.net'), + $options['packagingroot']); + $instreg = new PEAR_Registry($packrootphp_dir); // other instreg! - /** - * Destructor (the emulated type of...). Does nothing right now, - * but is included for forward compatibility, so subclass - * destructors should always call it. - * - * See the note in the class desciption about output from - * destructors. - * - * @access public - * @return void - */ - function _PEAR() { - if ($this->_debug) { - printf("PEAR destructor called, class=%s\n", strtolower(get_class($this))); + if ($this->config->get('verbose') > 2) { + $this->ui->outputData('using package root: ' . $options['packagingroot']); + } } - } - // }}} - // {{{ getStaticProperty() + $abstractpackages = $otherpackages = array(); + // parse params + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - /** - * If you have a class that's mostly/entirely static, and you need static - * properties, you can use this method to simulate them. Eg. in your method(s) - * do this: $myVar = &PEAR::getStaticProperty('myclass', 'myVar'); - * You MUST use a reference, or they will not persist! - * - * @access public - * @param string $class The calling classname, to prevent clashes - * @param string $var The variable to retrieve. - * @return mixed A reference to the variable. If not set it will be - * auto initialised to NULL. - */ - function &getStaticProperty($class, $var) - { - static $properties; - if (!isset($properties[$class])) { - $properties[$class] = array(); - } + foreach ($params as $param) { + if (strpos($param, 'http://') === 0) { + $otherpackages[] = $param; + continue; + } - if (!array_key_exists($var, $properties[$class])) { - $properties[$class][$var] = null; - } + if (strpos($param, 'channel://') === false && @file_exists($param)) { + if (isset($options['force'])) { + $otherpackages[] = $param; + continue; + } - return $properties[$class][$var]; - } + $pkg = new PEAR_PackageFile($this->config); + $pf = $pkg->fromAnyFile($param, PEAR_VALIDATE_DOWNLOADING); + if (PEAR::isError($pf)) { + $otherpackages[] = $param; + continue; + } - // }}} - // {{{ registerShutdownFunc() + $exists = $reg->packageExists($pf->getPackage(), $pf->getChannel()); + $pversion = $reg->packageInfo($pf->getPackage(), 'version', $pf->getChannel()); + $version_compare = version_compare($pf->getVersion(), $pversion, '<='); + if ($exists && $version_compare) { + if ($this->config->get('verbose')) { + $this->ui->outputData('Ignoring installed package ' . + $reg->parsedPackageNameToString( + array('package' => $pf->getPackage(), + 'channel' => $pf->getChannel()), true)); + } + continue; + } + $otherpackages[] = $param; + continue; + } - /** - * Use this function to register a shutdown method for static - * classes. - * - * @access public - * @param mixed $func The function name (or array of class/method) to call - * @param mixed $args The arguments to pass to the function - * @return void - */ - function registerShutdownFunc($func, $args = array()) - { - // if we are called statically, there is a potential - // that no shutdown func is registered. Bug #6445 - if (!isset($GLOBALS['_PEAR_SHUTDOWN_REGISTERED'])) { - register_shutdown_function("_PEAR_call_destructors"); - $GLOBALS['_PEAR_SHUTDOWN_REGISTERED'] = true; + $e = $reg->parsePackageName($param, $channel); + if (PEAR::isError($e)) { + $otherpackages[] = $param; + } else { + $abstractpackages[] = $e; + } } - $GLOBALS['_PEAR_shutdown_funcs'][] = array($func, $args); - } + PEAR::staticPopErrorHandling(); - // }}} - // {{{ isError() + // if there are any local package .tgz or remote static url, we can't + // filter. The filter only works for abstract packages + if (count($abstractpackages) && !isset($options['force'])) { + // when not being forced, only do necessary upgrades/installs + if (isset($options['upgrade'])) { + $abstractpackages = $this->_filterUptodatePackages($abstractpackages, $command); + } else { + $count = count($abstractpackages); + foreach ($abstractpackages as $i => $package) { + if (isset($package['group'])) { + // do not filter out install groups + continue; + } - /** - * Tell whether a value is a PEAR error. - * - * @param mixed $data the value to test - * @param int $code if $data is an error object, return true - * only if $code is a string and - * $obj->getMessage() == $code or - * $code is an integer and $obj->getCode() == $code - * @access public - * @return bool true if parameter is an error - */ - function isError($data, $code = null) - { - if (!is_a($data, 'PEAR_Error')) { - return false; + if ($instreg->packageExists($package['package'], $package['channel'])) { + if ($count > 1) { + if ($this->config->get('verbose')) { + $this->ui->outputData('Ignoring installed package ' . + $reg->parsedPackageNameToString($package, true)); + } + unset($abstractpackages[$i]); + } elseif ($count === 1) { + // Lets try to upgrade it since it's already installed + $options['upgrade'] = true; + } + } + } + } + $abstractpackages = + array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages); + } elseif (count($abstractpackages)) { + $abstractpackages = + array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages); } - if (is_null($code)) { + $packages = array_merge($abstractpackages, $otherpackages); + if (!count($packages)) { + $c = ''; + if (isset($options['channel'])){ + $c .= ' in channel "' . $options['channel'] . '"'; + } + $this->ui->outputData('Nothing to ' . $command . $c); return true; - } elseif (is_string($code)) { - return $data->getMessage() == $code; } - return $data->getCode() == $code; - } + $this->downloader = &$this->getDownloader($this->ui, $options, $this->config); + $errors = $downloaded = $binaries = array(); + $downloaded = &$this->downloader->download($packages); + if (PEAR::isError($downloaded)) { + return $this->raiseError($downloaded); + } - // }}} - // {{{ setErrorHandling() + $errors = $this->downloader->getErrorMsgs(); + if (count($errors)) { + $err = array(); + $err['data'] = array(); + foreach ($errors as $error) { + if ($error !== null) { + $err['data'][] = array($error); + } + } - /** - * Sets how errors generated by this object should be handled. - * Can be invoked both in objects and statically. If called - * statically, setErrorHandling sets the default behaviour for all - * PEAR objects. If called in an object, setErrorHandling sets - * the default behaviour for that object. - * - * @param int $mode - * One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, - * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, - * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION. - * - * @param mixed $options - * When $mode is PEAR_ERROR_TRIGGER, this is the error level (one - * of E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). - * - * When $mode is PEAR_ERROR_CALLBACK, this parameter is expected - * to be the callback function or method. A callback - * function is a string with the name of the function, a - * callback method is an array of two elements: the element - * at index 0 is the object, and the element at index 1 is - * the name of the method to call in the object. - * - * When $mode is PEAR_ERROR_PRINT or PEAR_ERROR_DIE, this is - * a printf format string used when printing the error - * message. - * - * @access public - * @return void - * @see PEAR_ERROR_RETURN - * @see PEAR_ERROR_PRINT - * @see PEAR_ERROR_TRIGGER - * @see PEAR_ERROR_DIE - * @see PEAR_ERROR_CALLBACK - * @see PEAR_ERROR_EXCEPTION - * - * @since PHP 4.0.5 - */ + if (!empty($err['data'])) { + $err['headline'] = 'Install Errors'; + $this->ui->outputData($err); + } - function setErrorHandling($mode = null, $options = null) - { - if (isset($this) && is_a($this, 'PEAR')) { - $setmode = &$this->_default_error_mode; - $setoptions = &$this->_default_error_options; - } else { - $setmode = &$GLOBALS['_PEAR_default_error_mode']; - $setoptions = &$GLOBALS['_PEAR_default_error_options']; + if (!count($downloaded)) { + return $this->raiseError("$command failed"); + } } - switch ($mode) { - case PEAR_ERROR_EXCEPTION: - case PEAR_ERROR_RETURN: - case PEAR_ERROR_PRINT: - case PEAR_ERROR_TRIGGER: - case PEAR_ERROR_DIE: - case null: - $setmode = $mode; - $setoptions = $options; - break; + $data = array( + 'headline' => 'Packages that would be Installed' + ); - case PEAR_ERROR_CALLBACK: - $setmode = $mode; - // class/object method callback - if (is_callable($options)) { - $setoptions = $options; - } else { - trigger_error("invalid error callback", E_USER_WARNING); - } - break; + if (isset($options['pretend'])) { + foreach ($downloaded as $package) { + $data['data'][] = array($reg->parsedPackageNameToString($package->getParsedPackage())); + } + $this->ui->outputData($data, 'pretend'); + return true; + } - default: - trigger_error("invalid error mode", E_USER_WARNING); - break; + $this->installer->setOptions($options); + $this->installer->sortPackagesForInstall($downloaded); + if (PEAR::isError($err = $this->installer->setDownloadedPackages($downloaded))) { + $this->raiseError($err->getMessage()); + return true; } - } - // }}} - // {{{ expectError() + $binaries = $extrainfo = array(); + foreach ($downloaded as $param) { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $info = $this->installer->install($param, $options); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($info)) { + $oldinfo = $info; + $pkg = &$param->getPackageFile(); + if ($info->getCode() != PEAR_INSTALLER_NOBINARY) { + if (!($info = $pkg->installBinary($this->installer))) { + $this->ui->outputData('ERROR: ' .$oldinfo->getMessage()); + continue; + } - /** - * This method is used to tell which errors you expect to get. - * Expected errors are always returned with error mode - * PEAR_ERROR_RETURN. Expected error codes are stored in a stack, - * and this method pushes a new element onto it. The list of - * expected errors are in effect until they are popped off the - * stack with the popExpect() method. - * - * Note that this method can not be called statically - * - * @param mixed $code a single error code or an array of error codes to expect - * - * @return int the new depth of the "expected errors" stack - * @access public - */ - function expectError($code = '*') - { - if (is_array($code)) { - array_push($this->_expected_errors, $code); - } else { - array_push($this->_expected_errors, array($code)); - } - return sizeof($this->_expected_errors); - } + // we just installed a different package than requested, + // let's change the param and info so that the rest of this works + $param = $info[0]; + $info = $info[1]; + } + } - // }}} - // {{{ popExpect() + if (!is_array($info)) { + return $this->raiseError("$command failed"); + } - /** - * This method pops one element off the expected error codes - * stack. - * - * @return array the list of error codes that were popped - */ - function popExpect() - { - return array_pop($this->_expected_errors); - } + if ($param->getPackageType() == 'extsrc' || + $param->getPackageType() == 'extbin' || + $param->getPackageType() == 'zendextsrc' || + $param->getPackageType() == 'zendextbin') { + $pkg = &$param->getPackageFile(); + if ($instbin = $pkg->getInstalledBinary()) { + $instpkg = &$instreg->getPackage($instbin, $pkg->getChannel()); + } else { + $instpkg = &$instreg->getPackage($pkg->getPackage(), $pkg->getChannel()); + } - // }}} - // {{{ _checkDelExpect() + foreach ($instpkg->getFilelist() as $name => $atts) { + $pinfo = pathinfo($atts['installed_as']); + if (!isset($pinfo['extension']) || + in_array($pinfo['extension'], array('c', 'h'))) { + continue; // make sure we don't match php_blah.h + } - /** - * This method checks unsets an error code if available - * - * @param mixed error code - * @return bool true if the error code was unset, false otherwise - * @access private - * @since PHP 4.3.0 - */ - function _checkDelExpect($error_code) - { - $deleted = false; + if ((strpos($pinfo['basename'], 'php_') === 0 && + $pinfo['extension'] == 'dll') || + // most unices + $pinfo['extension'] == 'so' || + // hp-ux + $pinfo['extension'] == 'sl') { + $binaries[] = array($atts['installed_as'], $pinfo); + break; + } + } - foreach ($this->_expected_errors AS $key => $error_array) { - if (in_array($error_code, $error_array)) { - unset($this->_expected_errors[$key][array_search($error_code, $error_array)]); - $deleted = true; + if (count($binaries)) { + foreach ($binaries as $pinfo) { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $ret = $this->enableExtension(array($pinfo[0]), $param->getPackageType()); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($ret)) { + $extrainfo[] = $ret->getMessage(); + if ($param->getPackageType() == 'extsrc' || + $param->getPackageType() == 'extbin') { + $exttype = 'extension'; + } else { + ob_start(); + phpinfo(INFO_GENERAL); + $info = ob_get_contents(); + ob_end_clean(); + $debug = function_exists('leak') ? '_debug' : ''; + $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; + $exttype = 'zend_extension' . $debug . $ts; + } + $extrainfo[] = 'You should add "' . $exttype . '=' . + $pinfo[1]['basename'] . '" to php.ini'; + } else { + $extrainfo[] = 'Extension ' . $instpkg->getProvidesExtension() . + ' enabled in php.ini'; + } + } + } + } + + if ($this->config->get('verbose') > 0) { + $chan = $param->getChannel(); + $label = $reg->parsedPackageNameToString( + array( + 'channel' => $chan, + 'package' => $param->getPackage(), + 'version' => $param->getVersion(), + )); + $out = array('data' => "$command ok: $label"); + if (isset($info['release_warnings'])) { + $out['release_warnings'] = $info['release_warnings']; + } + $this->ui->outputData($out, $command); + + if (!isset($options['register-only']) && !isset($options['offline'])) { + if ($this->config->isDefinedLayer('ftp')) { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $info = $this->installer->ftpInstall($param); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($info)) { + $this->ui->outputData($info->getMessage()); + $this->ui->outputData("remote install failed: $label"); + } else { + $this->ui->outputData("remote install ok: $label"); + } + } + } } - // clean up empty arrays - if (0 == count($this->_expected_errors[$key])) { - unset($this->_expected_errors[$key]); - } - } - return $deleted; - } + $deps = $param->getDeps(); + if ($deps) { + if (isset($deps['group'])) { + $groups = $deps['group']; + if (!isset($groups[0])) { + $groups = array($groups); + } - // }}} - // {{{ delExpect() + foreach ($groups as $group) { + if ($group['attribs']['name'] == 'default') { + // default group is always installed, unless the user + // explicitly chooses to install another group + continue; + } + $extrainfo[] = $param->getPackage() . ': Optional feature ' . + $group['attribs']['name'] . ' available (' . + $group['attribs']['hint'] . ')'; + } - /** - * This method deletes all occurences of the specified element from - * the expected error codes stack. - * - * @param mixed $error_code error code that should be deleted - * @return mixed list of error codes that were deleted or error - * @access public - * @since PHP 4.3.0 - */ - function delExpect($error_code) - { - $deleted = false; - if ((is_array($error_code) && (0 != count($error_code)))) { - // $error_code is a non-empty array here; - // we walk through it trying to unset all - // values - foreach($error_code as $key => $error) { - if ($this->_checkDelExpect($error)) { - $deleted = true; - } else { - $deleted = false; + $extrainfo[] = $param->getPackage() . + ': To install optional features use "pear install ' . + $reg->parsedPackageNameToString( + array('package' => $param->getPackage(), + 'channel' => $param->getChannel()), true) . + '#featurename"'; } } - return $deleted ? true : PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME - } elseif (!empty($error_code)) { - // $error_code comes alone, trying to unset it - if ($this->_checkDelExpect($error_code)) { - return true; - } else { - return PEAR::raiseError("The expected error you submitted does not exist"); // IMPROVE ME + + $pkg = &$instreg->getPackage($param->getPackage(), $param->getChannel()); + // $pkg may be NULL if install is a 'fake' install via --packagingroot + if (is_object($pkg)) { + $pkg->setConfig($this->config); + if ($list = $pkg->listPostinstallScripts()) { + $pn = $reg->parsedPackageNameToString(array('channel' => + $param->getChannel(), 'package' => $param->getPackage()), true); + $extrainfo[] = $pn . ' has post-install scripts:'; + foreach ($list as $file) { + $extrainfo[] = $file; + } + $extrainfo[] = $param->getPackage() . + ': Use "pear run-scripts ' . $pn . '" to finish setup.'; + $extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES'; + } } } - // $error_code is empty - return PEAR::raiseError("The expected error you submitted is empty"); // IMPROVE ME + if (count($extrainfo)) { + foreach ($extrainfo as $info) { + $this->ui->outputData($info); + } + } + + return true; } // }}} - // {{{ raiseError() + // {{{ doUpgradeAll() - /** - * This method is a wrapper that returns an instance of the - * configured error class with this object's default error - * handling applied. If the $mode and $options parameters are not - * specified, the object's defaults are used. - * - * @param mixed $message a text error message or a PEAR error object - * - * @param int $code a numeric error code (it is up to your class - * to define these if you want to use codes) - * - * @param int $mode One of PEAR_ERROR_RETURN, PEAR_ERROR_PRINT, - * PEAR_ERROR_TRIGGER, PEAR_ERROR_DIE, - * PEAR_ERROR_CALLBACK, PEAR_ERROR_EXCEPTION. - * - * @param mixed $options If $mode is PEAR_ERROR_TRIGGER, this parameter - * specifies the PHP-internal error level (one of - * E_USER_NOTICE, E_USER_WARNING or E_USER_ERROR). - * If $mode is PEAR_ERROR_CALLBACK, this - * parameter specifies the callback function or - * method. In other error modes this parameter - * is ignored. - * - * @param string $userinfo If you need to pass along for example debug - * information, this parameter is meant for that. - * - * @param string $error_class The returned error object will be - * instantiated from this class, if specified. - * - * @param bool $skipmsg If true, raiseError will only pass error codes, - * the error message parameter will be dropped. - * - * @access public - * @return object a PEAR error object - * @see PEAR::setErrorHandling - * @since PHP 4.0.5 - */ - function &raiseError($message = null, - $code = null, - $mode = null, - $options = null, - $userinfo = null, - $error_class = null, - $skipmsg = false) + function doUpgradeAll($command, $options, $params) { - // The error is yet a PEAR error object - if (is_object($message)) { - $code = $message->getCode(); - $userinfo = $message->getUserInfo(); - $error_class = $message->getType(); - $message->error_message_prefix = ''; - $message = $message->getMessage(); - } + $reg = &$this->config->getRegistry(); + $upgrade = array(); - if (isset($this) && isset($this->_expected_errors) && sizeof($this->_expected_errors) > 0 && sizeof($exp = end($this->_expected_errors))) { - if ($exp[0] == "*" || - (is_int(reset($exp)) && in_array($code, $exp)) || - (is_string(reset($exp)) && in_array($message, $exp))) { - $mode = PEAR_ERROR_RETURN; - } + if (isset($options['channel'])) { + $channels = array($options['channel']); + } else { + $channels = $reg->listChannels(); } - // No mode given, try global ones - if ($mode === null) { - // Class error handler - if (isset($this) && isset($this->_default_error_mode)) { - $mode = $this->_default_error_mode; - $options = $this->_default_error_options; - // Global error handler - } elseif (isset($GLOBALS['_PEAR_default_error_mode'])) { - $mode = $GLOBALS['_PEAR_default_error_mode']; - $options = $GLOBALS['_PEAR_default_error_options']; + foreach ($channels as $channel) { + if ($channel == '__uri') { + continue; } - } - - if ($error_class !== null) { - $ec = $error_class; - } elseif (isset($this) && isset($this->_error_class)) { - $ec = $this->_error_class; - } else { - $ec = 'PEAR_Error'; - } - if (intval(PHP_VERSION) < 5) { - // little non-eval hack to fix bug #12147 - include 'phar://install-pear-nozlib.phar/' . 'PEAR/FixPHP5PEARWarnings.php'; - return $a; + // parse name with channel + foreach ($reg->listPackages($channel) as $name) { + $upgrade[] = $reg->parsedPackageNameToString(array( + 'channel' => $channel, + 'package' => $name + )); + } } - if ($skipmsg) { - $a = new $ec($code, $mode, $options, $userinfo); - } else { - $a = new $ec($message, $code, $mode, $options, $userinfo); + $err = $this->doInstall($command, $options, $upgrade); + if (PEAR::isError($err)) { + $this->ui->outputData($err->getMessage(), $command); } - - return $a; - } + } // }}} - // {{{ throwError() + // {{{ doUninstall() - /** - * Simpler form of raiseError with fewer options. In most cases - * message, code and userinfo are enough. - * - * @param string $message - * - */ - function &throwError($message = null, - $code = null, - $userinfo = null) + function doUninstall($command, $options, $params) { - if (isset($this) && is_a($this, 'PEAR')) { - $a = &$this->raiseError($message, $code, null, null, $userinfo); - return $a; + if (count($params) < 1) { + return $this->raiseError("Please supply the package(s) you want to uninstall"); } - $a = &PEAR::raiseError($message, $code, null, null, $userinfo); - return $a; - } + if (empty($this->installer)) { + $this->installer = &$this->getInstaller($this->ui); + } - // }}} - function staticPushErrorHandling($mode, $options = null) - { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - $def_mode = &$GLOBALS['_PEAR_default_error_mode']; - $def_options = &$GLOBALS['_PEAR_default_error_options']; - $stack[] = array($def_mode, $def_options); - switch ($mode) { - case PEAR_ERROR_EXCEPTION: - case PEAR_ERROR_RETURN: - case PEAR_ERROR_PRINT: - case PEAR_ERROR_TRIGGER: - case PEAR_ERROR_DIE: - case null: - $def_mode = $mode; - $def_options = $options; - break; + if (isset($options['remoteconfig'])) { + $e = $this->config->readFTPConfigFile($options['remoteconfig']); + if (!PEAR::isError($e)) { + $this->installer->setConfig($this->config); + } + } - case PEAR_ERROR_CALLBACK: - $def_mode = $mode; - // class/object method callback - if (is_callable($options)) { - $def_options = $options; - } else { - trigger_error("invalid error callback", E_USER_WARNING); + $reg = &$this->config->getRegistry(); + $newparams = array(); + $binaries = array(); + $badparams = array(); + foreach ($params as $pkg) { + $channel = $this->config->get('default_channel'); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $parsed = $reg->parsePackageName($pkg, $channel); + PEAR::staticPopErrorHandling(); + if (!$parsed || PEAR::isError($parsed)) { + $badparams[] = $pkg; + continue; + } + $package = $parsed['package']; + $channel = $parsed['channel']; + $info = &$reg->getPackage($package, $channel); + if ($info === null && + ($channel == 'pear.php.net' || $channel == 'pecl.php.net')) { + // make sure this isn't a package that has flipped from pear to pecl but + // used a package.xml 1.0 + $testc = ($channel == 'pear.php.net') ? 'pecl.php.net' : 'pear.php.net'; + $info = &$reg->getPackage($package, $testc); + if ($info !== null) { + $channel = $testc; } - break; - - default: - trigger_error("invalid error mode", E_USER_WARNING); - break; + } + if ($info === null) { + $badparams[] = $pkg; + } else { + $newparams[] = &$info; + // check for binary packages (this is an alias for those packages if so) + if ($installedbinary = $info->getInstalledBinary()) { + $this->ui->log('adding binary package ' . + $reg->parsedPackageNameToString(array('channel' => $channel, + 'package' => $installedbinary), true)); + $newparams[] = &$reg->getPackage($installedbinary, $channel); + } + // add the contents of a dependency group to the list of installed packages + if (isset($parsed['group'])) { + $group = $info->getDependencyGroup($parsed['group']); + if ($group) { + $installed = $reg->getInstalledGroup($group); + if ($installed) { + foreach ($installed as $i => $p) { + $newparams[] = &$installed[$i]; + } + } + } + } + } } - $stack[] = array($mode, $options); - return true; - } - - function staticPopErrorHandling() - { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - $setmode = &$GLOBALS['_PEAR_default_error_mode']; - $setoptions = &$GLOBALS['_PEAR_default_error_options']; - array_pop($stack); - list($mode, $options) = $stack[sizeof($stack) - 1]; - array_pop($stack); - switch ($mode) { - case PEAR_ERROR_EXCEPTION: - case PEAR_ERROR_RETURN: - case PEAR_ERROR_PRINT: - case PEAR_ERROR_TRIGGER: - case PEAR_ERROR_DIE: - case null: - $setmode = $mode; - $setoptions = $options; - break; - - case PEAR_ERROR_CALLBACK: - $setmode = $mode; - // class/object method callback - if (is_callable($options)) { - $setoptions = $options; - } else { - trigger_error("invalid error callback", E_USER_WARNING); + $err = $this->installer->sortPackagesForUninstall($newparams); + if (PEAR::isError($err)) { + $this->ui->outputData($err->getMessage(), $command); + return true; + } + $params = $newparams; + // twist this to use it to check on whether dependent packages are also being uninstalled + // for circular dependencies like subpackages + $this->installer->setUninstallPackages($newparams); + $params = array_merge($params, $badparams); + $binaries = array(); + foreach ($params as $pkg) { + $this->installer->pushErrorHandling(PEAR_ERROR_RETURN); + if ($err = $this->installer->uninstall($pkg, $options)) { + $this->installer->popErrorHandling(); + if (PEAR::isError($err)) { + $this->ui->outputData($err->getMessage(), $command); + continue; } - break; + if ($pkg->getPackageType() == 'extsrc' || + $pkg->getPackageType() == 'extbin' || + $pkg->getPackageType() == 'zendextsrc' || + $pkg->getPackageType() == 'zendextbin') { + if ($instbin = $pkg->getInstalledBinary()) { + continue; // this will be uninstalled later + } - default: - trigger_error("invalid error mode", E_USER_WARNING); - break; + foreach ($pkg->getFilelist() as $name => $atts) { + $pinfo = pathinfo($atts['installed_as']); + if (!isset($pinfo['extension']) || + in_array($pinfo['extension'], array('c', 'h'))) { + continue; // make sure we don't match php_blah.h + } + if ((strpos($pinfo['basename'], 'php_') === 0 && + $pinfo['extension'] == 'dll') || + // most unices + $pinfo['extension'] == 'so' || + // hp-ux + $pinfo['extension'] == 'sl') { + $binaries[] = array($atts['installed_as'], $pinfo); + break; + } + } + if (count($binaries)) { + foreach ($binaries as $pinfo) { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType()); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($ret)) { + $extrainfo[] = $ret->getMessage(); + if ($pkg->getPackageType() == 'extsrc' || + $pkg->getPackageType() == 'extbin') { + $exttype = 'extension'; + } else { + ob_start(); + phpinfo(INFO_GENERAL); + $info = ob_get_contents(); + ob_end_clean(); + $debug = function_exists('leak') ? '_debug' : ''; + $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; + $exttype = 'zend_extension' . $debug . $ts; + } + $this->ui->outputData('Unable to remove "' . $exttype . '=' . + $pinfo[1]['basename'] . '" from php.ini', $command); + } else { + $this->ui->outputData('Extension ' . $pkg->getProvidesExtension() . + ' disabled in php.ini', $command); + } + } + } + } + $savepkg = $pkg; + if ($this->config->get('verbose') > 0) { + if (is_object($pkg)) { + $pkg = $reg->parsedPackageNameToString($pkg); + } + $this->ui->outputData("uninstall ok: $pkg", $command); + } + if (!isset($options['offline']) && is_object($savepkg) && + defined('PEAR_REMOTEINSTALL_OK')) { + if ($this->config->isDefinedLayer('ftp')) { + $this->installer->pushErrorHandling(PEAR_ERROR_RETURN); + $info = $this->installer->ftpUninstall($savepkg); + $this->installer->popErrorHandling(); + if (PEAR::isError($info)) { + $this->ui->outputData($info->getMessage()); + $this->ui->outputData("remote uninstall failed: $pkg"); + } else { + $this->ui->outputData("remote uninstall ok: $pkg"); + } + } + } + } else { + $this->installer->popErrorHandling(); + if (!is_object($pkg)) { + return $this->raiseError("uninstall failed: $pkg"); + } + $pkg = $reg->parsedPackageNameToString($pkg); + } } + return true; } - // {{{ pushErrorHandling() + // }}} - /** - * Push a new error handler on top of the error handler options stack. With this - * you can easily override the actual error handler for some code and restore - * it later with popErrorHandling. - * - * @param mixed $mode (same as setErrorHandling) - * @param mixed $options (same as setErrorHandling) - * - * @return bool Always true - * - * @see PEAR::setErrorHandling - */ - function pushErrorHandling($mode, $options = null) + + // }}} + // {{{ doBundle() + /* + (cox) It just downloads and untars the package, does not do + any check that the PEAR_Installer::_installFile() does. + */ + + function doBundle($command, $options, $params) { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - if (isset($this) && is_a($this, 'PEAR')) { - $def_mode = &$this->_default_error_mode; - $def_options = &$this->_default_error_options; - } else { - $def_mode = &$GLOBALS['_PEAR_default_error_mode']; - $def_options = &$GLOBALS['_PEAR_default_error_options']; + $opts = array( + 'force' => true, + 'nodeps' => true, + 'soft' => true, + 'downloadonly' => true + ); + $downloader = &$this->getDownloader($this->ui, $opts, $this->config); + $reg = &$this->config->getRegistry(); + if (count($params) < 1) { + return $this->raiseError("Please supply the package you want to bundle"); } - $stack[] = array($def_mode, $def_options); - if (isset($this) && is_a($this, 'PEAR')) { - $this->setErrorHandling($mode, $options); + if (isset($options['destination'])) { + if (!is_dir($options['destination'])) { + System::mkdir('-p ' . $options['destination']); + } + $dest = realpath($options['destination']); } else { - PEAR::setErrorHandling($mode, $options); + $pwd = getcwd(); + $dir = $pwd . DIRECTORY_SEPARATOR . 'ext'; + $dest = is_dir($dir) ? $dir : $pwd; } - $stack[] = array($mode, $options); - return true; - } - - // }}} - // {{{ popErrorHandling() + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $err = $downloader->setDownloadDir($dest); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($err)) { + return PEAR::raiseError('download directory "' . $dest . + '" is not writeable.'); + } + $result = &$downloader->download(array($params[0])); + if (PEAR::isError($result)) { + return $result; + } + if (!isset($result[0])) { + return $this->raiseError('unable to unpack ' . $params[0]); + } + $pkgfile = &$result[0]->getPackageFile(); + $pkgname = $pkgfile->getName(); + $pkgversion = $pkgfile->getVersion(); - /** - * Pop the last error handler used - * - * @return bool Always true - * - * @see PEAR::pushErrorHandling - */ - function popErrorHandling() - { - $stack = &$GLOBALS['_PEAR_error_handler_stack']; - array_pop($stack); - list($mode, $options) = $stack[sizeof($stack) - 1]; - array_pop($stack); - if (isset($this) && is_a($this, 'PEAR')) { - $this->setErrorHandling($mode, $options); - } else { - PEAR::setErrorHandling($mode, $options); + // Unpacking ------------------------------------------------- + $dest .= DIRECTORY_SEPARATOR . $pkgname; + $orig = $pkgname . '-' . $pkgversion; + + $tar = &new Archive_Tar($pkgfile->getArchiveFile()); + if (!$tar->extractModify($dest, $orig)) { + return $this->raiseError('unable to unpack ' . $pkgfile->getArchiveFile()); } - return true; + $this->ui->outputData("Package ready at '$dest'"); + // }}} } // }}} - // {{{ loadExtension() - /** - * OS independant PHP extension load. Remember to take care - * on the correct extension name for case sensitive OSes. - * - * @param string $ext The extension name - * @return bool Success or not on the dl() call - */ - function loadExtension($ext) + function doRunScripts($command, $options, $params) { - if (!extension_loaded($ext)) { - // if either returns true dl() will produce a FATAL error, stop that - if ((ini_get('enable_dl') != 1) || (ini_get('safe_mode') == 1)) { - return false; - } + if (!isset($params[0])) { + return $this->raiseError('run-scripts expects 1 parameter: a package name'); + } - if (OS_WINDOWS) { - $suffix = '.dll'; - } elseif (PHP_OS == 'HP-UX') { - $suffix = '.sl'; - } elseif (PHP_OS == 'AIX') { - $suffix = '.a'; - } elseif (PHP_OS == 'OSX') { - $suffix = '.bundle'; - } else { - $suffix = '.so'; - } + $reg = &$this->config->getRegistry(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel')); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($parsed)) { + return $this->raiseError($parsed); + } - return @dl('php_'.$ext.$suffix) || @dl($ext.$suffix); + $package = &$reg->getPackage($parsed['package'], $parsed['channel']); + if (!is_object($package)) { + return $this->raiseError('Could not retrieve package "' . $params[0] . '" from registry'); } + $package->setConfig($this->config); + $package->runPostinstallScripts(); + $this->ui->outputData('Install scripts complete', $command); return true; } - // }}} -} - -if (PEAR_ZE2) { /** - * This is only meant for PHP 5 to get rid of certain strict warning - * that doesn't get hidden since it's in the shutdown function + * Given a list of packages, filter out those ones that are already up to date + * + * @param $packages: packages, in parsed array format ! + * @return list of packages that can be upgraded */ - class PEAR5 + function _filterUptodatePackages($packages, $command) { - /** - * If you have a class that's mostly/entirely static, and you need static - * properties, you can use this method to simulate them. Eg. in your method(s) - * do this: $myVar = &PEAR5::getStaticProperty('myclass', 'myVar'); - * You MUST use a reference, or they will not persist! - * - * @access public - * @param string $class The calling classname, to prevent clashes - * @param string $var The variable to retrieve. - * @return mixed A reference to the variable. If not set it will be - * auto initialised to NULL. - */ - static function &getStaticProperty($class, $var) - { - static $properties; - if (!isset($properties[$class])) { - $properties[$class] = array(); + $reg = &$this->config->getRegistry(); + $latestReleases = array(); + + $ret = array(); + foreach ($packages as $package) { + if (isset($package['group'])) { + $ret[] = $package; + continue; } - if (!array_key_exists($var, $properties[$class])) { - $properties[$class][$var] = null; + $channel = $package['channel']; + $name = $package['package']; + if (!$reg->packageExists($name, $channel)) { + $ret[] = $package; + continue; } - return $properties[$class][$var]; - } - } -} + if (!isset($latestReleases[$channel])) { + // fill in cache for this channel + $chan = &$reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $this->raiseError($chan); + } -// {{{ _PEAR_call_destructors() + $base2 = false; + $preferred_mirror = $this->config->get('preferred_mirror', null, $channel); + if ($chan->supportsREST($preferred_mirror) && + ( + //($base2 = $chan->getBaseURL('REST1.4', $preferred_mirror)) || + ($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) + ) + ) { + $dorest = true; + } -function _PEAR_call_destructors() -{ - global $_PEAR_destructor_object_list; - if (is_array($_PEAR_destructor_object_list) && - sizeof($_PEAR_destructor_object_list)) - { - reset($_PEAR_destructor_object_list); - if (PEAR_ZE2) { - $destructLifoExists = PEAR5::getStaticProperty('PEAR', 'destructlifo'); - } else { - $destructLifoExists = PEAR::getStaticProperty('PEAR', 'destructlifo'); - } + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (!isset($package['state'])) { + $state = $this->config->get('preferred_state', null, $channel); + } else { + $state = $package['state']; + } - if ($destructLifoExists) { - $_PEAR_destructor_object_list = array_reverse($_PEAR_destructor_object_list); - } + if ($dorest) { + if ($base2) { + $rest = &$this->config->getREST('1.4', array()); + $base = $base2; + } else { + $rest = &$this->config->getREST('1.0', array()); + } - while (list($k, $objref) = each($_PEAR_destructor_object_list)) { - $classname = get_class($objref); - while ($classname) { - $destructor = "_$classname"; - if (method_exists($objref, $destructor)) { - $objref->$destructor(); - break; - } else { - $classname = get_parent_class($classname); + $installed = array_flip($reg->listPackages($channel)); + $latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg); + } + + PEAR::staticPopErrorHandling(); + if (PEAR::isError($latest)) { + $this->ui->outputData('Error getting channel info from ' . $channel . + ': ' . $latest->getMessage()); + continue; } + + $latestReleases[$channel] = array_change_key_case($latest); } - } - // Empty the object list to ensure that destructors are - // not called more than once. - $_PEAR_destructor_object_list = array(); - } - // Now call the shutdown functions - if (is_array($GLOBALS['_PEAR_shutdown_funcs']) AND !empty($GLOBALS['_PEAR_shutdown_funcs'])) { - foreach ($GLOBALS['_PEAR_shutdown_funcs'] as $value) { - call_user_func_array($value[0], $value[1]); + // check package for latest release + $name_lower = strtolower($name); + if (isset($latestReleases[$channel][$name_lower])) { + // if not set, up to date + $inst_version = $reg->packageInfo($name, 'version', $channel); + $channel_version = $latestReleases[$channel][$name_lower]['version']; + if (version_compare($channel_version, $inst_version, 'le')) { + // installed version is up-to-date + continue; + } + + // maintain BC + if ($command == 'upgrade-all') { + $this->ui->outputData(array('data' => 'Will upgrade ' . + $reg->parsedPackageNameToString($package)), $command); + } + $ret[] = $package; + } } + + return $ret; } -} +} + + Install Package + doInstall + i + + + f + will overwrite newer installed packages + + + l + do not check for recommended dependency version + + + n + ignore dependencies, install anyway + + + r + do not install files, only register the package as installed + + + s + soft install, fail silently, or upgrade if already installed + + + B + don't build C extensions + + + Z + request uncompressed files when downloading + + + R + root directory used when installing files (ala PHP's INSTALL_ROOT), use packagingroot for RPM + DIR + + + P + root directory used when packaging files, like RPM packaging + DIR + + + + force install even if there were errors + + + a + install all required and optional dependencies + + + o + install all required dependencies + + + O + do not attempt to download any urls or contact channels + + + p + Only list the packages that would be downloaded + + + [channel/]<package> ... +Installs one or more PEAR packages. You can specify a package to +install in four ways: + +"Package-1.0.tgz" : installs from a local file + +"http://example.com/Package-1.0.tgz" : installs from +anywhere on the net. + +"package.xml" : installs the package described in +package.xml. Useful for testing, or for wrapping a PEAR package in +another package manager such as RPM. + +"Package[-version/state][.tar]" : queries your default channel's server +({config master_server}) and downloads the newest package with +the preferred quality/state ({config preferred_state}). + +To retrieve Package version 1.1, use "Package-1.1," to retrieve +Package state beta, use "Package-beta." To retrieve an uncompressed +file, append .tar (make sure there is no file by the same name first) + +To download a package from another channel, prefix with the channel name like +"channel/Package" + +More than one package may be specified at once. It is ok to mix these +four ways of specifying packages. + + + + Upgrade Package + doInstall + up + + + c + upgrade packages from a specific channel + CHAN + + + f + overwrite newer installed packages + + + l + do not check for recommended dependency version + + + n + ignore dependencies, upgrade anyway + + + r + do not install files, only register the package as upgraded + + + B + don't build C extensions + + + Z + request uncompressed files when downloading + + + R + root directory used when installing files (ala PHP's INSTALL_ROOT) + DIR + + + + force install even if there were errors + + + a + install all required and optional dependencies + + + o + install all required dependencies + + + O + do not attempt to download any urls or contact channels + + + p + Only list the packages that would be downloaded + + + <package> ... +Upgrades one or more PEAR packages. See documentation for the +"install" command for ways to specify a package. + +When upgrading, your package will be updated if the provided new +package has a higher version number (use the -f option if you need to +upgrade anyway). + +More than one package may be specified at once. + + + + Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters] + doUpgradeAll + ua + + + c + upgrade packages from a specific channel + CHAN + + + n + ignore dependencies, upgrade anyway + + + r + do not install files, only register the package as upgraded + + + B + don't build C extensions + + + Z + request uncompressed files when downloading + + + R + root directory used when installing files (ala PHP's INSTALL_ROOT), use packagingroot for RPM + DIR + + + + force install even if there were errors + + + + do not check for recommended dependency version + + + +WARNING: This function is deprecated in favor of using the upgrade command with no params + +Upgrades all packages that have a newer release available. Upgrades are +done only if there is a release available of the state specified in +"preferred_state" (currently {config preferred_state}), or a state considered +more stable. + + + + Un-install Package + doUninstall + un + + + n + ignore dependencies, uninstall anyway + + + r + do not remove files, only register the packages as not installed + + + R + root directory used when installing files (ala PHP's INSTALL_ROOT) + DIR + + + + force install even if there were errors + + + O + do not attempt to uninstall remotely + + + [channel/]<package> ... +Uninstalls one or more PEAR packages. More than one package may be +specified at once. Prefix with channel name to uninstall from a +channel not in your default channel ({config default_channel}) + + + + Unpacks a Pecl Package + doBundle + bun + + + d + Optional destination directory for unpacking (defaults to current path or "ext" if exists) + DIR + + + f + Force the unpacking even if there were errors in the package + + + <package> +Unpacks a Pecl Package into the selected location. It will download the +package if needed. + + + + Run Post-Install Scripts bundled with a package + doRunScripts + rs + + <package> +Run post-installation scripts in package <package>, if any exist. + + + + * @author Tomas V. V. Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Common.php 282969 2009-06-28 23:09:27Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1.0 + * @deprecated File deprecated since Release 1.4.0a1 + */ + +/** + * Include error handling + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; + +/** + * PEAR_Common error when an invalid PHP file is passed to PEAR_Common::analyzeSourceCode() + */ +define('PEAR_COMMON_ERROR_INVALIDPHP', 1); +define('_PEAR_COMMON_PACKAGE_NAME_PREG', '[A-Za-z][a-zA-Z0-9_]+'); +define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/'); + +// this should allow: 1, 1.0, 1.0RC1, 1.0dev, 1.0dev123234234234, 1.0a1, 1.0b1, 1.0pl1 +define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?'); +define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '\\z/i'); + +// XXX far from perfect :-) +define('_PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '(' . _PEAR_COMMON_PACKAGE_NAME_PREG . + ')(-([.0-9a-zA-Z]+))?'); +define('PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_PACKAGE_DOWNLOAD_PREG . + '\\z/'); + +define('_PEAR_CHANNELS_NAME_PREG', '[A-Za-z][a-zA-Z0-9\.]+'); +define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '\\z/'); + +// this should allow any dns or IP address, plus a path - NO UNDERSCORES ALLOWED +define('_PEAR_CHANNELS_SERVER_PREG', '[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*(\/[a-zA-Z0-9\-]+)*'); +define('PEAR_CHANNELS_SERVER_PREG', '/^' . _PEAR_CHANNELS_SERVER_PREG . '\\z/i'); + +define('_PEAR_CHANNELS_PACKAGE_PREG', '(' ._PEAR_CHANNELS_SERVER_PREG . ')\/(' + . _PEAR_COMMON_PACKAGE_NAME_PREG . ')'); +define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '\\z/i'); + +define('_PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '(' . _PEAR_CHANNELS_NAME_PREG . ')::(' + . _PEAR_COMMON_PACKAGE_NAME_PREG . ')(-([.0-9a-zA-Z]+))?'); +define('PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_CHANNEL_DOWNLOAD_PREG . '\\z/'); -// }}} /** - * Standard PEAR error class for PHP 4 - * - * This class is supserseded by {@link PEAR_Exception} in PHP 5 - * - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Tomas V.V. Cox - * @author Gregory Beaver - * @copyright 1997-2006 The PHP Group - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/manual/en/core.pear.pear-error.php - * @see PEAR::raiseError(), PEAR::throwError() - * @since Class available since PHP 4.0.2 + * List of temporary files and directories registered by + * PEAR_Common::addTempFile(). + * @var array */ -class PEAR_Error -{ - // {{{ properties +$GLOBALS['_PEAR_Common_tempfiles'] = array(); - var $error_message_prefix = ''; - var $mode = PEAR_ERROR_RETURN; - var $level = E_USER_NOTICE; - var $code = -1; - var $message = ''; - var $userinfo = ''; - var $backtrace = null; +/** + * Valid maintainer roles + * @var array + */ +$GLOBALS['_PEAR_Common_maintainer_roles'] = array('lead','developer','contributor','helper'); - // }}} - // {{{ constructor +/** + * Valid release states + * @var array + */ +$GLOBALS['_PEAR_Common_release_states'] = array('alpha','beta','stable','snapshot','devel'); - /** - * PEAR_Error constructor - * - * @param string $message message - * - * @param int $code (optional) error code - * - * @param int $mode (optional) error mode, one of: PEAR_ERROR_RETURN, - * PEAR_ERROR_PRINT, PEAR_ERROR_DIE, PEAR_ERROR_TRIGGER, - * PEAR_ERROR_CALLBACK or PEAR_ERROR_EXCEPTION - * - * @param mixed $options (optional) error level, _OR_ in the case of - * PEAR_ERROR_CALLBACK, the callback function or object/method - * tuple. - * - * @param string $userinfo (optional) additional user/debug info - * - * @access public - * - */ - function PEAR_Error($message = 'unknown error', $code = null, - $mode = null, $options = null, $userinfo = null) - { - if ($mode === null) { - $mode = PEAR_ERROR_RETURN; - } - $this->message = $message; - $this->code = $code; - $this->mode = $mode; - $this->userinfo = $userinfo; +/** + * Valid dependency types + * @var array + */ +$GLOBALS['_PEAR_Common_dependency_types'] = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi'); - if (PEAR_ZE2) { - $skiptrace = PEAR5::getStaticProperty('PEAR_Error', 'skiptrace'); - } else { - $skiptrace = PEAR::getStaticProperty('PEAR_Error', 'skiptrace'); - } +/** + * Valid dependency relations + * @var array + */ +$GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge','not', 'ne'); - if (!$skiptrace) { - $this->backtrace = debug_backtrace(); - if (isset($this->backtrace[0]) && isset($this->backtrace[0]['object'])) { - unset($this->backtrace[0]['object']); - } - } - if ($mode & PEAR_ERROR_CALLBACK) { - $this->level = E_USER_NOTICE; - $this->callback = $options; - } else { - if ($options === null) { - $options = E_USER_NOTICE; - } - $this->level = $options; - $this->callback = null; - } - if ($this->mode & PEAR_ERROR_PRINT) { - if (is_null($options) || is_int($options)) { - $format = "%s"; - } else { - $format = $options; - } - printf($format, $this->getMessage()); - } - if ($this->mode & PEAR_ERROR_TRIGGER) { - trigger_error($this->getMessage(), $this->level); - } - if ($this->mode & PEAR_ERROR_DIE) { - $msg = $this->getMessage(); - if (is_null($options) || is_int($options)) { - $format = "%s"; - if (substr($msg, -1) != "\n") { - $msg .= "\n"; - } - } else { - $format = $options; - } - die(sprintf($format, $msg)); - } - if ($this->mode & PEAR_ERROR_CALLBACK) { - if (is_callable($this->callback)) { - call_user_func($this->callback, $this); - } - } - if ($this->mode & PEAR_ERROR_EXCEPTION) { - trigger_error("PEAR_ERROR_EXCEPTION is obsolete, use class PEAR_Exception for exceptions", E_USER_WARNING); - eval('$e = new Exception($this->message, $this->code);throw($e);'); - } - } +/** + * Valid file roles + * @var array + */ +$GLOBALS['_PEAR_Common_file_roles'] = array('php','ext','test','doc','data','src','script'); - // }}} - // {{{ getMode() +/** + * Valid replacement types + * @var array + */ +$GLOBALS['_PEAR_Common_replacement_types'] = array('php-const', 'pear-config', 'package-info'); - /** - * Get the error mode from an error object. - * - * @return int error mode - * @access public - */ - function getMode() { - return $this->mode; - } +/** + * Valid "provide" types + * @var array + */ +$GLOBALS['_PEAR_Common_provide_types'] = array('ext', 'prog', 'class', 'function', 'feature', 'api'); - // }}} - // {{{ getCallback() +/** + * Valid "provide" types + * @var array + */ +$GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'pre-uninstall', 'post-uninstall', 'pre-build', 'post-build', 'pre-configure', 'post-configure', 'pre-setup', 'post-setup'); +/** + * Class providing common functionality for PEAR administration classes. + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V. V. Cox + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + * @deprecated This class will disappear, and its components will be spread + * into smaller classes, like the AT&T breakup, as of Release 1.4.0a1 + */ +class PEAR_Common extends PEAR +{ /** - * Get the callback function/method from an error object. - * - * @return mixed callback function or object/method array - * @access public + * User Interface object (PEAR_Frontend_* class). If null, + * the log() method uses print. + * @var object */ - function getCallback() { - return $this->callback; - } - - // }}} - // {{{ getMessage() - + var $ui = null; /** - * Get the error message from an error object. - * - * @return string full error message - * @access public + * Configuration object (PEAR_Config). + * @var PEAR_Config */ - function getMessage() - { - return ($this->error_message_prefix . $this->message); - } - + var $config = null; - // }}} - // {{{ getCode() + /** stack of elements, gives some sort of XML context */ + var $element_stack = array(); - /** - * Get error code from an error object - * - * @return int error code - * @access public - */ - function getCode() - { - return $this->code; - } + /** name of currently parsed XML element */ + var $current_element; - // }}} - // {{{ getType() + /** array of attributes of the currently parsed XML element */ + var $current_attributes = array(); - /** - * Get the name of this error/exception. - * - * @return string error/exception name (type) - * @access public - */ - function getType() - { - return get_class($this); - } + /** assoc with information about a package */ + var $pkginfo = array(); - // }}} - // {{{ getUserInfo() + var $current_path = null; /** - * Get additional user-supplied information. - * - * @return string user-supplied information - * @access public + * Flag variable used to mark a valid package file + * @var boolean + * @access private */ - function getUserInfo() - { - return $this->userinfo; - } - - // }}} - // {{{ getDebugInfo() + var $_validPackageFile; /** - * Get additional debug information supplied by the application. + * PEAR_Common constructor * - * @return string debug information * @access public */ - function getDebugInfo() + function PEAR_Common() { - return $this->getUserInfo(); + parent::PEAR(); + $this->config = &PEAR_Config::singleton(); + $this->debug = $this->config->get('verbose'); } - // }}} - // {{{ getBacktrace() - /** - * Get the call backtrace from where the error was generated. - * Supported with PHP 4.3.0 or newer. + * PEAR_Common destructor * - * @param int $frame (optional) what frame to fetch - * @return array Backtrace, or NULL if not available. - * @access public + * @access private */ - function getBacktrace($frame = null) + function _PEAR_Common() { - if (defined('PEAR_IGNORE_BACKTRACE')) { - return null; - } - if ($frame === null) { - return $this->backtrace; - } - return $this->backtrace[$frame]; - } - - // }}} - // {{{ addUserInfo() + // doesn't work due to bug #14744 + //$tempfiles = $this->_tempfiles; + $tempfiles =& $GLOBALS['_PEAR_Common_tempfiles']; + while ($file = array_shift($tempfiles)) { + if (@is_dir($file)) { + if (!class_exists('System')) { + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + } - function addUserInfo($info) - { - if (empty($this->userinfo)) { - $this->userinfo = $info; - } else { - $this->userinfo .= " ** $info"; + System::rm(array('-rf', $file)); + } elseif (file_exists($file)) { + unlink($file); + } } } - // }}} - // {{{ toString() - function __toString() - { - return $this->getMessage(); - } - // }}} - // {{{ toString() - /** - * Make a string representation of this object. + * Register a temporary file or directory. When the destructor is + * executed, all registered temporary files and directories are + * removed. + * + * @param string $file name of file or directory + * + * @return void * - * @return string a string with an object summary * @access public */ - function toString() { - $modes = array(); - $levels = array(E_USER_NOTICE => 'notice', - E_USER_WARNING => 'warning', - E_USER_ERROR => 'error'); - if ($this->mode & PEAR_ERROR_CALLBACK) { - if (is_array($this->callback)) { - $callback = (is_object($this->callback[0]) ? - strtolower(get_class($this->callback[0])) : - $this->callback[0]) . '::' . - $this->callback[1]; - } else { - $callback = $this->callback; - } - return sprintf('[%s: message="%s" code=%d mode=callback '. - 'callback=%s prefix="%s" info="%s"]', - strtolower(get_class($this)), $this->message, $this->code, - $callback, $this->error_message_prefix, - $this->userinfo); - } - if ($this->mode & PEAR_ERROR_PRINT) { - $modes[] = 'print'; - } - if ($this->mode & PEAR_ERROR_TRIGGER) { - $modes[] = 'trigger'; - } - if ($this->mode & PEAR_ERROR_DIE) { - $modes[] = 'die'; - } - if ($this->mode & PEAR_ERROR_RETURN) { - $modes[] = 'return'; + function addTempFile($file) + { + if (!class_exists('PEAR_Frontend')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Frontend.php'; } - return sprintf('[%s: message="%s" code=%d mode=%s level=%s '. - 'prefix="%s" info="%s"]', - strtolower(get_class($this)), $this->message, $this->code, - implode("|", $modes), $levels[$this->level], - $this->error_message_prefix, - $this->userinfo); + PEAR_Frontend::addTempFile($file); } - // }}} -} - -/* - * Local Variables: - * mode: php - * tab-width: 4 - * c-basic-offset: 4 - * End: - */ - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: ChannelFile.php,v 1.84 2009/03/09 01:03:51 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * Needed for error handling - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ErrorStack.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Common.php'; - -/** - * Error code if the channel.xml tag does not contain a valid version - */ -define('PEAR_CHANNELFILE_ERROR_NO_VERSION', 1); -/** - * Error code if the channel.xml tag version is not supported (version 1.0 is the only supported version, - * currently - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_VERSION', 2); - -/** - * Error code if parsing is attempted with no xml extension - */ -define('PEAR_CHANNELFILE_ERROR_NO_XML_EXT', 3); - -/** - * Error code if creating the xml parser resource fails - */ -define('PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER', 4); - -/** - * Error code used for all sax xml parsing errors - */ -define('PEAR_CHANNELFILE_ERROR_PARSER_ERROR', 5); - -/**#@+ - * Validation errors - */ -/** - * Error code when channel name is missing - */ -define('PEAR_CHANNELFILE_ERROR_NO_NAME', 6); -/** - * Error code when channel name is invalid - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_NAME', 7); -/** - * Error code when channel summary is missing - */ -define('PEAR_CHANNELFILE_ERROR_NO_SUMMARY', 8); -/** - * Error code when channel summary is multi-line - */ -define('PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY', 9); -/** - * Error code when channel server is missing for protocol - */ -define('PEAR_CHANNELFILE_ERROR_NO_HOST', 10); -/** - * Error code when channel server is invalid for protocol - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_HOST', 11); -/** - * Error code when a mirror name is invalid - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_MIRROR', 21); -/** - * Error code when a mirror type is invalid - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE', 22); -/** - * Error code when an attempt is made to generate xml, but the parsed content is invalid - */ -define('PEAR_CHANNELFILE_ERROR_INVALID', 23); -/** - * Error code when an empty package name validate regex is passed in - */ -define('PEAR_CHANNELFILE_ERROR_EMPTY_REGEX', 24); -/** - * Error code when a tag has no version - */ -define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION', 25); -/** - * Error code when a tag has no name - */ -define('PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME', 26); -/** - * Error code when a tag has no name - */ -define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME', 27); -/** - * Error code when a tag has no version attribute - */ -define('PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION', 28); -/** - * Error code when a mirror does not exist but is called for in one of the set* - * methods. - */ -define('PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND', 32); -/** - * Error code when a server port is not numeric - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_PORT', 33); -/** - * Error code when contains no version attribute - */ -define('PEAR_CHANNELFILE_ERROR_NO_STATICVERSION', 34); -/** - * Error code when contains no type attribute in a protocol definition - */ -define('PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE', 35); -/** - * Error code when a mirror is defined and the channel.xml represents the __uri pseudo-channel - */ -define('PEAR_CHANNELFILE_URI_CANT_MIRROR', 36); -/** - * Error code when ssl attribute is present and is not "yes" - */ -define('PEAR_CHANNELFILE_ERROR_INVALID_SSL', 37); -/**#@-*/ - -/** - * Mirror types allowed. Currently only internet servers are recognized. - */ -$GLOBALS['_PEAR_CHANNELS_MIRROR_TYPES'] = array('server'); + /** + * Wrapper to System::mkDir(), creates a directory as well as + * any necessary parent directories. + * + * @param string $dir directory name + * + * @return bool TRUE on success, or a PEAR error + * + * @access public + */ + function mkDirHier($dir) + { + // Only used in Installer - move it there ? + $this->log(2, "+ create dir $dir"); + if (!class_exists('System')) { + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + } + return System::mkDir(array('-p', $dir)); + } + + /** + * Logging method. + * + * @param int $level log level (0 is quiet, higher is noisier) + * @param string $msg message to write to the log + * + * @return void + * + * @access public + * @static + */ + function log($level, $msg, $append_crlf = true) + { + if ($this->debug >= $level) { + if (!class_exists('PEAR_Frontend')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Frontend.php'; + } + $ui = &PEAR_Frontend::singleton(); + if (is_a($ui, 'PEAR_Frontend')) { + $ui->log($msg, $append_crlf); + } else { + print "$msg\n"; + } + } + } -/** - * The Channel handling class - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_ChannelFile -{ /** - * @access private - * @var PEAR_ErrorStack - * @access private + * Create and register a temporary directory. + * + * @param string $tmpdir (optional) Directory to use as tmpdir. + * Will use system defaults (for example + * /tmp or c:\windows\temp) if not specified + * + * @return string name of created directory + * + * @access public */ - var $_stack; + function mkTempDir($tmpdir = '') + { + $topt = $tmpdir ? array('-t', $tmpdir) : array(); + $topt = array_merge($topt, array('-d', 'pear')); + if (!class_exists('System')) { + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + } + + if (!$tmpdir = System::mktemp($topt)) { + return false; + } + + $this->addTempFile($tmpdir); + return $tmpdir; + } /** - * Supported channel.xml versions, for parsing - * @var array - * @access private + * Set object that represents the frontend to be used. + * + * @param object Reference of the frontend object + * @return void + * @access public */ - var $_supportedVersions = array('1.0'); + function setFrontendObject(&$ui) + { + $this->ui = &$ui; + } /** - * Parsed channel information - * @var array - * @access private + * Return an array containing all of the states that are more stable than + * or equal to the passed in state + * + * @param string Release state + * @param boolean Determines whether to include $state in the list + * @return false|array False if $state is not a valid release state */ - var $_channelInfo; + function betterStates($state, $include = false) + { + static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); + $i = array_search($state, $states); + if ($i === false) { + return false; + } + if ($include) { + $i--; + } + return array_slice($states, $i + 1); + } /** - * index into the subchannels array, used for parsing xml - * @var int - * @access private + * Get the valid roles for a PEAR package maintainer + * + * @return array + * @static */ - var $_subchannelIndex; + function getUserRoles() + { + return $GLOBALS['_PEAR_Common_maintainer_roles']; + } /** - * index into the mirrors array, used for parsing xml - * @var int - * @access private + * Get the valid package release states of packages + * + * @return array + * @static */ - var $_mirrorIndex; + function getReleaseStates() + { + return $GLOBALS['_PEAR_Common_release_states']; + } /** - * Flag used to determine the validity of parsed content - * @var boolean - * @access private + * Get the implemented dependency types (php, ext, pkg etc.) + * + * @return array + * @static */ - var $_isValid = false; + function getDependencyTypes() + { + return $GLOBALS['_PEAR_Common_dependency_types']; + } - function PEAR_ChannelFile() + /** + * Get the implemented dependency relations (has, lt, ge etc.) + * + * @return array + * @static + */ + function getDependencyRelations() { - $this->_stack = &new PEAR_ErrorStack('PEAR_ChannelFile'); - $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); - $this->_isValid = false; + return $GLOBALS['_PEAR_Common_dependency_relations']; } /** + * Get the implemented file roles + * * @return array - * @access protected + * @static */ - function _getErrorMessage() + function getFileRoles() { - return - array( - PEAR_CHANNELFILE_ERROR_INVALID_VERSION => - 'While parsing channel.xml, an invalid version number "%version% was passed in, expecting one of %versions%', - PEAR_CHANNELFILE_ERROR_NO_VERSION => - 'No version number found in tag', - PEAR_CHANNELFILE_ERROR_NO_XML_EXT => - '%error%', - PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER => - 'Unable to create XML parser', - PEAR_CHANNELFILE_ERROR_PARSER_ERROR => - '%error%', - PEAR_CHANNELFILE_ERROR_NO_NAME => - 'Missing channel name', - PEAR_CHANNELFILE_ERROR_INVALID_NAME => - 'Invalid channel %tag% "%name%"', - PEAR_CHANNELFILE_ERROR_NO_SUMMARY => - 'Missing channel summary', - PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY => - 'Channel summary should be on one line, but is multi-line', - PEAR_CHANNELFILE_ERROR_NO_HOST => - 'Missing channel server for %type% server', - PEAR_CHANNELFILE_ERROR_INVALID_HOST => - 'Server name "%server%" is invalid for %type% server', - PEAR_CHANNELFILE_ERROR_INVALID_MIRROR => - 'Invalid mirror name "%name%", mirror type %type%', - PEAR_CHANNELFILE_ERROR_INVALID_MIRRORTYPE => - 'Invalid mirror type "%type%"', - PEAR_CHANNELFILE_ERROR_INVALID => - 'Cannot generate xml, contents are invalid', - PEAR_CHANNELFILE_ERROR_EMPTY_REGEX => - 'packagenameregex cannot be empty', - PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION => - '%parent% %protocol% function has no version', - PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME => - '%parent% %protocol% function has no name', - PEAR_CHANNELFILE_ERROR_NOBASEURLTYPE => - '%parent% rest baseurl has no type', - PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME => - 'Validation package has no name in tag', - PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION => - 'Validation package "%package%" has no version', - PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND => - 'Mirror "%mirror%" does not exist', - PEAR_CHANNELFILE_ERROR_INVALID_PORT => - 'Port "%port%" must be numeric', - PEAR_CHANNELFILE_ERROR_NO_STATICVERSION => - ' tag must contain version attribute', - PEAR_CHANNELFILE_URI_CANT_MIRROR => - 'The __uri pseudo-channel cannot have mirrors', - PEAR_CHANNELFILE_ERROR_INVALID_SSL => - '%server% has invalid ssl attribute "%ssl%" can only be yes or not present', - ); + return $GLOBALS['_PEAR_Common_file_roles']; } /** - * @param string contents of package.xml file - * @return bool success of parsing + * Get the implemented file replacement types in + * + * @return array + * @static */ - function fromXmlString($data) + function getReplacementTypes() { - if (preg_match('/_supportedVersions)) { - $this->_stack->push(PEAR_CHANNELFILE_ERROR_INVALID_VERSION, 'error', - array('version' => $channelversion[1])); - return false; - } - $parser = new PEAR_XMLParser; - $result = $parser->parse($data); - if ($result !== true) { - if ($result->getCode() == 1) { - $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_XML_EXT, 'error', - array('error' => $result->getMessage())); - } else { - $this->_stack->push(PEAR_CHANNELFILE_ERROR_CANT_MAKE_PARSER, 'error'); - } - return false; - } - $this->_channelInfo = $parser->getData(); - return true; - } else { - $this->_stack->push(PEAR_CHANNELFILE_ERROR_NO_VERSION, 'error', array('xml' => $data)); - return false; - } + return $GLOBALS['_PEAR_Common_replacement_types']; } /** + * Get the implemented file replacement types in + * * @return array + * @static */ - function toArray() + function getProvideTypes() { - if (!$this->_isValid && !$this->validate()) { - return false; - } - return $this->_channelInfo; + return $GLOBALS['_PEAR_Common_provide_types']; } /** - * @param array + * Get the implemented file replacement types in + * + * @return array * @static - * @return PEAR_ChannelFile|false false if invalid */ - function &fromArray($data, $compatibility = false, $stackClass = 'PEAR_ErrorStack') + function getScriptPhases() { - $a = new PEAR_ChannelFile($compatibility, $stackClass); - $a->_fromArray($data); - if (!$a->validate()) { - $a = false; - return $a; - } - return $a; + return $GLOBALS['_PEAR_Common_script_phases']; } /** - * Unlike {@link fromArray()} this does not do any validation - * @param array + * Test whether a string contains a valid package name. + * + * @param string $name the package name to test + * + * @return bool + * + * @access public + */ + function validPackageName($name) + { + return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name); + } + + /** + * Test whether a string contains a valid package version. + * + * @param string $ver the package version to test + * + * @return bool + * + * @access public + */ + function validPackageVersion($ver) + { + return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); + } + + /** + * @param string $path relative or absolute include path + * @return boolean * @static - * @return PEAR_ChannelFile */ - function &fromArrayWithErrors($data, $compatibility = false, - $stackClass = 'PEAR_ErrorStack') + function isIncludeable($path) { - $a = new PEAR_ChannelFile($compatibility, $stackClass); - $a->_fromArray($data); - return $a; + if (file_exists($path) && is_readable($path)) { + return true; + } + + $ipath = explode(PATH_SEPARATOR, ini_get('include_path')); + foreach ($ipath as $include) { + $test = realpath($include . DIRECTORY_SEPARATOR . $path); + if (file_exists($test) && is_readable($test)) { + return true; + } + } + + return false; + } + + function _postProcessChecks($pf) + { + if (!PEAR::isError($pf)) { + return $this->_postProcessValidPackagexml($pf); + } + + $errs = $pf->getUserinfo(); + if (is_array($errs)) { + foreach ($errs as $error) { + $e = $this->raiseError($error['message'], $error['code'], null, null, $error); + } + } + + return $pf; } /** - * @param array - * @access private + * Returns information about a package file. Expects the name of + * a gzipped tar file as input. + * + * @param string $file name of .tgz file + * + * @return array array with package information + * + * @access public + * @deprecated use PEAR_PackageFile->fromTgzFile() instead + * */ - function _fromArray($data) + function infoFromTgzFile($file) { - $this->_channelInfo = $data; + $packagefile = &new PEAR_PackageFile($this->config); + $pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL); + return $this->_postProcessChecks($pf); } /** - * Wrapper to {@link PEAR_ErrorStack::getErrors()} - * @param boolean determines whether to purge the error stack after retrieving + * Returns information about a package file. Expects the name of + * a package xml file as input. + * + * @param string $descfile name of package xml file + * + * @return array array with package information + * + * @access public + * @deprecated use PEAR_PackageFile->fromPackageFile() instead + * + */ + function infoFromDescriptionFile($descfile) + { + $packagefile = &new PEAR_PackageFile($this->config); + $pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); + return $this->_postProcessChecks($pf); + } + + /** + * Returns information about a package file. Expects the contents + * of a package xml file as input. + * + * @param string $data contents of package.xml file + * + * @return array array with package information + * + * @access public + * @deprecated use PEAR_PackageFile->fromXmlstring() instead + * + */ + function infoFromString($data) + { + $packagefile = &new PEAR_PackageFile($this->config); + $pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false); + return $this->_postProcessChecks($pf); + } + + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 * @return array */ - function getErrors($purge = false) + function _postProcessValidPackagexml(&$pf) { - return $this->_stack->getErrors($purge); + if (!is_a($pf, 'PEAR_PackageFile_v2')) { + $this->pkginfo = $pf->toArray(); + return $this->pkginfo; + } + + // sort of make this into a package.xml 1.0-style array + // changelog is not converted to old format. + $arr = $pf->toArray(true); + $arr = array_merge($arr, $arr['old']); + unset($arr['old'], $arr['xsdversion'], $arr['contents'], $arr['compatible'], + $arr['channel'], $arr['uri'], $arr['dependencies'], $arr['phprelease'], + $arr['extsrcrelease'], $arr['zendextsrcrelease'], $arr['extbinrelease'], + $arr['zendextbinrelease'], $arr['bundle'], $arr['lead'], $arr['developer'], + $arr['helper'], $arr['contributor']); + $arr['filelist'] = $pf->getFilelist(); + $this->pkginfo = $arr; + return $arr; } /** - * Unindent given string (?) + * Returns package information from different sources * - * @param string $str The string that has to be unindented. + * This method is able to extract information about a package + * from a .tgz archive or from a XML package definition file. + * + * @access public + * @param string Filename of the source ('package.xml', '.tgz') * @return string - * @access private + * @deprecated use PEAR_PackageFile->fromAnyFile() instead */ - function _unIndent($str) + function infoFromAny($info) { - // remove leading newlines - $str = preg_replace('/^[\r\n]+/', '', $str); - // find whitespace at the beginning of the first line - $indent_len = strspn($str, " \t"); - $indent = substr($str, 0, $indent_len); - $data = ''; - // remove the same amount of whitespace from following lines - foreach (explode("\n", $str) as $line) { - if (substr($line, 0, $indent_len) == $indent) { - $data .= substr($line, $indent_len) . "\n"; + if (is_string($info) && file_exists($info)) { + $packagefile = &new PEAR_PackageFile($this->config); + $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); + if (PEAR::isError($pf)) { + $errs = $pf->getUserinfo(); + if (is_array($errs)) { + foreach ($errs as $error) { + $e = $this->raiseError($error['message'], $error['code'], null, null, $error); + } + } + + return $pf; + } + + return $this->_postProcessValidPackagexml($pf); + } + + return $info; + } + + /** + * Return an XML document based on the package info (as returned + * by the PEAR_Common::infoFrom* methods). + * + * @param array $pkginfo package info + * + * @return string XML data + * + * @access public + * @deprecated use a PEAR_PackageFile_v* object's generator instead + */ + function xmlFromInfo($pkginfo) + { + $config = &PEAR_Config::singleton(); + $packagefile = &new PEAR_PackageFile($config); + $pf = &$packagefile->fromArray($pkginfo); + $gen = &$pf->getDefaultGenerator(); + return $gen->toXml(PEAR_VALIDATE_PACKAGING); + } + + /** + * Validate XML package definition file. + * + * @param string $info Filename of the package archive or of the + * package definition file + * @param array $errors Array that will contain the errors + * @param array $warnings Array that will contain the warnings + * @param string $dir_prefix (optional) directory where source files + * may be found, or empty if they are not available + * @access public + * @return boolean + * @deprecated use the validation of PEAR_PackageFile objects + */ + function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '') + { + $config = &PEAR_Config::singleton(); + $packagefile = &new PEAR_PackageFile($config); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (strpos($info, 'fromXmlString($info, PEAR_VALIDATE_NORMAL, ''); + } else { + $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); + } + + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf)) { + $errs = $pf->getUserinfo(); + if (is_array($errs)) { + foreach ($errs as $error) { + if ($error['level'] == 'error') { + $errors[] = $error['message']; + } else { + $warnings[] = $error['message']; + } + } } - } - return $data; - } - /** - * Parse a channel.xml file. Expects the name of - * a channel xml file as input. - * - * @param string $descfile name of channel xml file - * @return bool success of parsing - */ - function fromXmlFile($descfile) - { - if (!file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) || - (!$fp = fopen($descfile, 'r'))) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; - return PEAR::raiseError("Unable to open $descfile"); + return false; } - // read the whole thing so we only get one cdata callback - // for each block of cdata - fclose($fp); - $data = file_get_contents($descfile); - return $this->fromXmlString($data); + return true; } /** - * Parse channel information from different sources + * Build a "provides" array from data returned by + * analyzeSourceCode(). The format of the built array is like + * this: * - * This method is able to extract information about a channel - * from an .xml file or a string + * array( + * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), + * ... + * ) + * + * + * @param array $srcinfo array with information about a source file + * as returned by the analyzeSourceCode() method. + * + * @return void * * @access public - * @param string Filename of the source or the source itself - * @return bool + * */ - function fromAny($info) + function buildProvidesArray($srcinfo) { - if (is_string($info) && file_exists($info) && strlen($info) < 255) { - $tmp = substr($info, -4); - if ($tmp == '.xml') { - $info = $this->fromXmlFile($info); - } else { - $fp = fopen($info, "r"); - $test = fread($fp, 5); - fclose($fp); - if ($test == "fromXmlFile($info); - } + $file = basename($srcinfo['source_file']); + $pn = ''; + if (isset($this->_packageName)) { + $pn = $this->_packageName; + } + + $pnl = strlen($pn); + foreach ($srcinfo['declared_classes'] as $class) { + $key = "class;$class"; + if (isset($this->pkginfo['provides'][$key])) { + continue; } - if (PEAR::isError($info)) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; - return PEAR::raiseError($info); + + $this->pkginfo['provides'][$key] = + array('file'=> $file, 'type' => 'class', 'name' => $class); + if (isset($srcinfo['inheritance'][$class])) { + $this->pkginfo['provides'][$key]['extends'] = + $srcinfo['inheritance'][$class]; } } - if (is_string($info)) { - $info = $this->fromXmlString($info); + + foreach ($srcinfo['declared_methods'] as $class => $methods) { + foreach ($methods as $method) { + $function = "$class::$method"; + $key = "function;$function"; + if ($method{0} == '_' || !strcasecmp($method, $class) || + isset($this->pkginfo['provides'][$key])) { + continue; + } + + $this->pkginfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } + } + + foreach ($srcinfo['declared_functions'] as $function) { + $key = "function;$function"; + if ($function{0} == '_' || isset($this->pkginfo['provides'][$key])) { + continue; + } + + if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { + $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; + } + + $this->pkginfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); } - return $info; } /** - * Return an XML document based on previous parsing and modifications - * - * @return string XML data + * Analyze the source code of the given PHP file * + * @param string Filename of the PHP file + * @return mixed * @access public */ - function toXml() + function analyzeSourceCode($file) { - if (!$this->_isValid && !$this->validate()) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID); - return false; - } - if (!isset($this->_channelInfo['attribs']['version'])) { - $this->_channelInfo['attribs']['version'] = '1.0'; - } - $channelInfo = $this->_channelInfo; - $ret = "\n"; - $ret .= " - $channelInfo[name] - " . htmlspecialchars($channelInfo['summary'])." -"; - if (isset($channelInfo['suggestedalias'])) { - $ret .= ' ' . $channelInfo['suggestedalias'] . "\n"; - } - if (isset($channelInfo['validatepackage'])) { - $ret .= ' ' . - htmlspecialchars($channelInfo['validatepackage']['_content']) . - "\n"; + if (!class_exists('PEAR_PackageFile_v2_Validator')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2/Validator.php'; } - $ret .= " \n"; - $ret .= ' analyzeSourceCode($file); + } + + function detectDependencies($any, $status_callback = null) + { + if (!function_exists("token_get_all")) { + return false; } - if (isset($channelInfo['servers']['primary']['attribs']['port'])) { - $ret .= ' port="' . $channelInfo['servers']['primary']['attribs']['port'] . '"'; + + if (PEAR::isError($info = $this->infoFromAny($any))) { + return $this->raiseError($info); } - $ret .= ">\n"; - if (isset($channelInfo['servers']['primary']['rest'])) { - $ret .= $this->_makeRestXml($channelInfo['servers']['primary']['rest'], ' '); + + if (!is_array($info)) { + return false; } - $ret .= " \n"; - if (isset($channelInfo['servers']['mirror'])) { - $ret .= $this->_makeMirrorsXml($channelInfo); + + $deps = array(); + $used_c = $decl_c = $decl_f = $decl_m = array(); + foreach ($info['filelist'] as $file => $fa) { + $tmp = $this->analyzeSourceCode($file); + $used_c = @array_merge($used_c, $tmp['used_classes']); + $decl_c = @array_merge($decl_c, $tmp['declared_classes']); + $decl_f = @array_merge($decl_f, $tmp['declared_functions']); + $decl_m = @array_merge($decl_m, $tmp['declared_methods']); + $inheri = @array_merge($inheri, $tmp['inheritance']); } - $ret .= " \n"; - $ret .= ""; - return str_replace("\r", "\n", str_replace("\r\n", "\n", $ret)); + + $used_c = array_unique($used_c); + $decl_c = array_unique($decl_c); + $undecl_c = array_diff($used_c, $decl_c); + + return array('used_classes' => $used_c, + 'declared_classes' => $decl_c, + 'declared_methods' => $decl_m, + 'declared_functions' => $decl_f, + 'undeclared_classes' => $undecl_c, + 'inheritance' => $inheri, + ); } /** - * Generate the tag - * @access private + * Download a file through HTTP. Considers suggested file name in + * Content-disposition: header and can run a callback function for + * different events. The callback will be called with two + * parameters: the callback type, and parameters. The implemented + * callback types are: + * + * 'setup' called at the very beginning, parameter is a UI object + * that should be used for all output + * 'message' the parameter is a string with an informational message + * 'saveas' may be used to save with a different file name, the + * parameter is the filename that is about to be used. + * If a 'saveas' callback returns a non-empty string, + * that file name will be used as the filename instead. + * Note that $save_dir will not be affected by this, only + * the basename of the file. + * 'start' download is starting, parameter is number of bytes + * that are expected, or -1 if unknown + * 'bytesread' parameter is the number of bytes read so far + * 'done' download is complete, parameter is the total number + * of bytes read + * 'connfailed' if the TCP connection fails, this callback is called + * with array(host,port,errno,errmsg) + * 'writefailed' if writing to disk fails, this callback is called + * with array(destfile,errmsg) + * + * If an HTTP proxy has been configured (http_proxy PEAR_Config + * setting), the proxy will be used. + * + * @param string $url the URL to download + * @param object $ui PEAR_Frontend_* instance + * @param object $config PEAR_Config instance + * @param string $save_dir (optional) directory to save file in + * @param mixed $callback (optional) function/method to call for status + * updates + * + * @return string Returns the full path of the downloaded file or a PEAR + * error on failure. If the error is caused by + * socket-related errors, the error object will + * have the fsockopen error code available through + * getCode(). + * + * @access public + * @deprecated in favor of PEAR_Downloader::downloadHttp() */ - function _makeRestXml($info, $indent) + function downloadHttp($url, &$ui, $save_dir = '.', $callback = null) { - $ret = $indent . "\n"; - if (!isset($info['baseurl'][0])) { - $info['baseurl'] = array($info['baseurl']); - } - foreach ($info['baseurl'] as $url) { - $ret .= "$indent \n"; + if (!class_exists('PEAR_Downloader')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Downloader.php'; } - $ret .= $indent . "\n"; - return $ret; + return PEAR_Downloader::downloadHttp($url, $ui, $save_dir, $callback); } +} + +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Config.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile.php'; + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Config.php 286480 2009-07-29 02:50:02Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * Required for error handling + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Registry.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + +/** + * Last created PEAR_Config instance. + * @var object + */ +$GLOBALS['_PEAR_Config_instance'] = null; +if (!defined('PEAR_INSTALL_DIR') || !PEAR_INSTALL_DIR) { + $PEAR_INSTALL_DIR = PHP_LIBDIR . DIRECTORY_SEPARATOR . 'pear'; +} else { + $PEAR_INSTALL_DIR = PEAR_INSTALL_DIR; +} + +// Below we define constants with default values for all configuration +// parameters except username/password. All of them can have their +// defaults set through environment variables. The reason we use the +// PHP_ prefix is for some security, PHP protects environment +// variables starting with PHP_*. + +// default channel and preferred mirror is based on whether we are invoked through +// the "pear" or the "pecl" command +if (!defined('PEAR_RUNTYPE')) { + define('PEAR_RUNTYPE', 'pear'); +} + +if (PEAR_RUNTYPE == 'pear') { + define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pear.php.net'); +} else { + define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pecl.php.net'); +} + +if (getenv('PHP_PEAR_SYSCONF_DIR')) { + define('PEAR_CONFIG_SYSCONFDIR', getenv('PHP_PEAR_SYSCONF_DIR')); +} elseif (getenv('SystemRoot')) { + define('PEAR_CONFIG_SYSCONFDIR', getenv('SystemRoot')); +} else { + define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR); +} + +// Default for master_server +if (getenv('PHP_PEAR_MASTER_SERVER')) { + define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv('PHP_PEAR_MASTER_SERVER')); +} else { + define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net'); +} + +// Default for http_proxy +if (getenv('PHP_PEAR_HTTP_PROXY')) { + define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('PHP_PEAR_HTTP_PROXY')); +} elseif (getenv('http_proxy')) { + define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('http_proxy')); +} else { + define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', ''); +} + +// Default for php_dir +if (getenv('PHP_PEAR_INSTALL_DIR')) { + define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR')); +} else { + if (@file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) { + define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); + } else { + define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); + } +} + +// Default for ext_dir +if (getenv('PHP_PEAR_EXTENSION_DIR')) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR')); +} else { + if (ini_get('extension_dir')) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get('extension_dir')); + } elseif (defined('PEAR_EXTENSION_DIR') && + file_exists(PEAR_EXTENSION_DIR) && is_dir(PEAR_EXTENSION_DIR)) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', PEAR_EXTENSION_DIR); + } elseif (defined('PHP_EXTENSION_DIR')) { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', PHP_EXTENSION_DIR); + } else { + define('PEAR_CONFIG_DEFAULT_EXT_DIR', '.'); + } +} + +// Default for doc_dir +if (getenv('PHP_PEAR_DOC_DIR')) { + define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv('PHP_PEAR_DOC_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_DOC_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'docs'); +} + +// Default for bin_dir +if (getenv('PHP_PEAR_BIN_DIR')) { + define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv('PHP_PEAR_BIN_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR); +} + +// Default for data_dir +if (getenv('PHP_PEAR_DATA_DIR')) { + define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv('PHP_PEAR_DATA_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_DATA_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data'); +} + +// Default for cfg_dir +if (getenv('PHP_PEAR_CFG_DIR')) { + define('PEAR_CONFIG_DEFAULT_CFG_DIR', getenv('PHP_PEAR_CFG_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_CFG_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'cfg'); +} + +// Default for www_dir +if (getenv('PHP_PEAR_WWW_DIR')) { + define('PEAR_CONFIG_DEFAULT_WWW_DIR', getenv('PHP_PEAR_WWW_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_WWW_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'www'); +} + +// Default for test_dir +if (getenv('PHP_PEAR_TEST_DIR')) { + define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_TEST_DIR', + $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests'); +} + +// Default for temp_dir +if (getenv('PHP_PEAR_TEMP_DIR')) { + define('PEAR_CONFIG_DEFAULT_TEMP_DIR', getenv('PHP_PEAR_TEMP_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_TEMP_DIR', + System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . + DIRECTORY_SEPARATOR . 'temp'); +} + +// Default for cache_dir +if (getenv('PHP_PEAR_CACHE_DIR')) { + define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv('PHP_PEAR_CACHE_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_CACHE_DIR', + System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . + DIRECTORY_SEPARATOR . 'cache'); +} + +// Default for download_dir +if (getenv('PHP_PEAR_DOWNLOAD_DIR')) { + define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', getenv('PHP_PEAR_DOWNLOAD_DIR')); +} else { + define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', + System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . + DIRECTORY_SEPARATOR . 'download'); +} + +// Default for php_bin +if (getenv('PHP_PEAR_PHP_BIN')) { + define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv('PHP_PEAR_PHP_BIN')); +} else { + define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR. + DIRECTORY_SEPARATOR.'php'.(OS_WINDOWS ? '.exe' : '')); +} + +// Default for verbose +if (getenv('PHP_PEAR_VERBOSE')) { + define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv('PHP_PEAR_VERBOSE')); +} else { + define('PEAR_CONFIG_DEFAULT_VERBOSE', 1); +} + +// Default for preferred_state +if (getenv('PHP_PEAR_PREFERRED_STATE')) { + define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv('PHP_PEAR_PREFERRED_STATE')); +} else { + define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable'); +} + +// Default for umask +if (getenv('PHP_PEAR_UMASK')) { + define('PEAR_CONFIG_DEFAULT_UMASK', getenv('PHP_PEAR_UMASK')); +} else { + define('PEAR_CONFIG_DEFAULT_UMASK', decoct(umask())); +} + +// Default for cache_ttl +if (getenv('PHP_PEAR_CACHE_TTL')) { + define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv('PHP_PEAR_CACHE_TTL')); +} else { + define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600); +} + +// Default for sig_type +if (getenv('PHP_PEAR_SIG_TYPE')) { + define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv('PHP_PEAR_SIG_TYPE')); +} else { + define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg'); +} + +// Default for sig_bin +if (getenv('PHP_PEAR_SIG_BIN')) { + define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv('PHP_PEAR_SIG_BIN')); +} else { + define('PEAR_CONFIG_DEFAULT_SIG_BIN', + System::which( + 'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg')); +} + +// Default for sig_keydir +if (getenv('PHP_PEAR_SIG_KEYDIR')) { + define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv('PHP_PEAR_SIG_KEYDIR')); +} else { + define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', + PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys'); +} + +/** + * This is a class for storing configuration data, keeping track of + * which are system-defined, user-defined or defaulted. + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Config extends PEAR +{ + /** + * Array of config files used. + * + * @var array layer => config file + */ + var $files = array( + 'system' => '', + 'user' => '', + ); + + var $layers = array(); /** - * Generate the tag - * @access private + * Configuration data, two-dimensional array where the first + * dimension is the config layer ('user', 'system' and 'default'), + * and the second dimension is keyname => value. + * + * The order in the first dimension is important! Earlier + * layers will shadow later ones when a config value is + * requested (if a 'user' value exists, it will be returned first, + * then 'system' and finally 'default'). + * + * @var array layer => array(keyname => value, ...) */ - function _makeMirrorsXml($channelInfo) - { - $ret = ""; - if (!isset($channelInfo['servers']['mirror'][0])) { - $channelInfo['servers']['mirror'] = array($channelInfo['servers']['mirror']); - } - foreach ($channelInfo['servers']['mirror'] as $mirror) { - $ret .= ' _makeRestXml($mirror['rest'], ' '); - } - $ret .= " \n"; - } else { - $ret .= "/>\n"; - } - } - return $ret; - } + var $configuration = array( + 'user' => array(), + 'system' => array(), + 'default' => array(), + ); /** - * Generate the tag + * Configuration values that can be set for a channel + * + * All other configuration values can only have a global value + * @var array * @access private */ - function _makeFunctionsXml($functions, $indent, $rest = false) - { - $ret = ''; - if (!isset($functions[0])) { - $functions = array($functions); - } - foreach ($functions as $function) { - $ret .= "$indent\n"; - } - return $ret; - } + var $_channelConfigInfo = array( + 'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'cfg_dir', + 'test_dir', 'www_dir', 'php_bin', 'php_prefix', 'php_suffix', 'username', + 'password', 'verbose', 'preferred_state', 'umask', 'preferred_mirror', 'php_ini' + ); /** - * Validation error. Also marks the object contents as invalid - * @param error code - * @param array error information + * Channels that can be accessed + * @see setChannels() + * @var array * @access private */ - function _validateError($code, $params = array()) - { - $this->_stack->push($code, 'error', $params); - $this->_isValid = false; - } + var $_channels = array('pear.php.net', 'pecl.php.net', '__uri'); /** - * Validation warning. Does not mark the object contents invalid. - * @param error code - * @param array error information + * This variable is used to control the directory values returned + * @see setInstallRoot(); + * @var string|false * @access private */ - function _validateWarning($code, $params = array()) - { - $this->_stack->push($code, 'warning', $params); - } + var $_installRoot = false; /** - * Validate parsed file. - * - * @access public - * @return boolean + * If requested, this will always refer to the registry + * contained in php_dir + * @var PEAR_Registry */ - function validate() - { - $this->_isValid = true; - $info = $this->_channelInfo; - if (empty($info['name'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_NAME); - } elseif (!$this->validChannelServer($info['name'])) { - if ($info['name'] != '__uri') { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, array('tag' => 'name', - 'name' => $info['name'])); - } - } - if (empty($info['summary'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY); - } elseif (strpos(trim($info['summary']), "\n") !== false) { - $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY, - array('summary' => $info['summary'])); - } - if (isset($info['suggestedalias'])) { - if (!$this->validChannelServer($info['suggestedalias'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, - array('tag' => 'suggestedalias', 'name' =>$info['suggestedalias'])); - } - } - if (isset($info['localalias'])) { - if (!$this->validChannelServer($info['localalias'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, - array('tag' => 'localalias', 'name' =>$info['localalias'])); - } - } - if (isset($info['validatepackage'])) { - if (!isset($info['validatepackage']['_content'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_NAME); - } - if (!isset($info['validatepackage']['attribs']['version'])) { - $content = isset($info['validatepackage']['_content']) ? - $info['validatepackage']['_content'] : - null; - $this->_validateError(PEAR_CHANNELFILE_ERROR_NOVALIDATE_VERSION, - array('package' => $content)); - } - } - - if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['port']) && - !is_numeric($info['servers']['primary']['attribs']['port'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_PORT, - array('port' => $info['servers']['primary']['attribs']['port'])); - } - - if (isset($info['servers']['primary']['attribs'], $info['servers']['primary']['attribs']['ssl']) && - $info['servers']['primary']['attribs']['ssl'] != 'yes') { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL, - array('ssl' => $info['servers']['primary']['attribs']['ssl'], - 'server' => $info['name'])); - } - - if (isset($info['servers']['primary']['rest']) && - isset($info['servers']['primary']['rest']['baseurl'])) { - $this->_validateFunctions('rest', $info['servers']['primary']['rest']['baseurl']); - } - if (isset($info['servers']['mirror'])) { - if ($this->_channelInfo['name'] == '__uri') { - $this->_validateError(PEAR_CHANNELFILE_URI_CANT_MIRROR); - } - if (!isset($info['servers']['mirror'][0])) { - $info['servers']['mirror'] = array($info['servers']['mirror']); - } - foreach ($info['servers']['mirror'] as $mirror) { - if (!isset($mirror['attribs']['host'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_HOST, - array('type' => 'mirror')); - } elseif (!$this->validChannelServer($mirror['attribs']['host'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_HOST, - array('server' => $mirror['attribs']['host'], 'type' => 'mirror')); - } - if (isset($mirror['attribs']['ssl']) && $mirror['attribs']['ssl'] != 'yes') { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_SSL, - array('ssl' => $info['ssl'], 'server' => $mirror['attribs']['host'])); - } - if (isset($mirror['rest'])) { - $this->_validateFunctions('rest', $mirror['rest']['baseurl'], - $mirror['attribs']['host']); - } - } - } - return $this->_isValid; - } + var $_registry = array(); /** - * @param string rest - protocol name this function applies to - * @param array the functions - * @param string the name of the parent element (mirror name, for instance) + * @var array + * @access private */ - function _validateFunctions($protocol, $functions, $parent = '') - { - if (!isset($functions[0])) { - $functions = array($functions); - } - foreach ($functions as $function) { - if (!isset($function['_content']) || empty($function['_content'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONNAME, - array('parent' => $parent, 'protocol' => $protocol)); - } - if ($protocol == 'rest') { - if (!isset($function['attribs']['type']) || - empty($function['attribs']['type'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_BASEURLTYPE, - array('parent' => $parent, 'protocol' => $protocol)); - } - } else { - if (!isset($function['attribs']['version']) || - empty($function['attribs']['version'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_FUNCTIONVERSION, - array('parent' => $parent, 'protocol' => $protocol)); - } - } - } - } + var $_regInitialized = array(); /** - * Test whether a string contains a valid channel server. - * @param string $ver the package version to test - * @return bool + * @var bool + * @access private */ - function validChannelServer($server) - { - if ($server == '__uri') { - return true; - } - return (bool) preg_match(PEAR_CHANNELS_SERVER_PREG, $server); - } + var $_noRegistry = false; /** - * @return string|false + * amount of errors found while parsing config + * @var integer + * @access private */ - function getName() - { - if (isset($this->_channelInfo['name'])) { - return $this->_channelInfo['name']; - } - - return false; - } + var $_errorsFound = 0; + var $_lastError = null; /** - * @return string|false + * Information about the configuration data. Stores the type, + * default value and a documentation string for each configuration + * value. + * + * @var array layer => array(infotype => value, ...) */ - function getServer() - { - if (isset($this->_channelInfo['name'])) { - return $this->_channelInfo['name']; - } - - return false; - } + var $configuration_info = array( + // Channels/Internet Access + 'default_channel' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, + 'doc' => 'the default channel to use for all non explicit commands', + 'prompt' => 'Default Channel', + 'group' => 'Internet Access', + ), + 'preferred_mirror' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, + 'doc' => 'the default server or mirror to use for channel actions', + 'prompt' => 'Default Channel Mirror', + 'group' => 'Internet Access', + ), + 'remote_config' => array( + 'type' => 'password', + 'default' => '', + 'doc' => 'ftp url of remote configuration file to use for synchronized install', + 'prompt' => 'Remote Configuration File', + 'group' => 'Internet Access', + ), + 'auto_discover' => array( + 'type' => 'integer', + 'default' => 0, + 'doc' => 'whether to automatically discover new channels', + 'prompt' => 'Auto-discover new Channels', + 'group' => 'Internet Access', + ), + // Internet Access + 'master_server' => array( + 'type' => 'string', + 'default' => 'pear.php.net', + 'doc' => 'name of the main PEAR server [NOT USED IN THIS VERSION]', + 'prompt' => 'PEAR server [DEPRECATED]', + 'group' => 'Internet Access', + ), + 'http_proxy' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY, + 'doc' => 'HTTP proxy (host:port) to use when downloading packages', + 'prompt' => 'HTTP Proxy Server Address', + 'group' => 'Internet Access', + ), + // File Locations + 'php_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_PHP_DIR, + 'doc' => 'directory where .php files are installed', + 'prompt' => 'PEAR directory', + 'group' => 'File Locations', + ), + 'ext_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_EXT_DIR, + 'doc' => 'directory where loadable extensions are installed', + 'prompt' => 'PHP extension directory', + 'group' => 'File Locations', + ), + 'doc_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_DOC_DIR, + 'doc' => 'directory where documentation is installed', + 'prompt' => 'PEAR documentation directory', + 'group' => 'File Locations', + ), + 'bin_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_BIN_DIR, + 'doc' => 'directory where executables are installed', + 'prompt' => 'PEAR executables directory', + 'group' => 'File Locations', + ), + 'data_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_DATA_DIR, + 'doc' => 'directory where data files are installed', + 'prompt' => 'PEAR data directory', + 'group' => 'File Locations (Advanced)', + ), + 'cfg_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_CFG_DIR, + 'doc' => 'directory where modifiable configuration files are installed', + 'prompt' => 'PEAR configuration file directory', + 'group' => 'File Locations (Advanced)', + ), + 'www_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_WWW_DIR, + 'doc' => 'directory where www frontend files (html/js) are installed', + 'prompt' => 'PEAR www files directory', + 'group' => 'File Locations (Advanced)', + ), + 'test_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_TEST_DIR, + 'doc' => 'directory where regression tests are installed', + 'prompt' => 'PEAR test directory', + 'group' => 'File Locations (Advanced)', + ), + 'cache_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR, + 'doc' => 'directory which is used for web service cache', + 'prompt' => 'PEAR Installer cache directory', + 'group' => 'File Locations (Advanced)', + ), + 'temp_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_TEMP_DIR, + 'doc' => 'directory which is used for all temp files', + 'prompt' => 'PEAR Installer temp directory', + 'group' => 'File Locations (Advanced)', + ), + 'download_dir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR, + 'doc' => 'directory which is used for all downloaded files', + 'prompt' => 'PEAR Installer download directory', + 'group' => 'File Locations (Advanced)', + ), + 'php_bin' => array( + 'type' => 'file', + 'default' => PEAR_CONFIG_DEFAULT_PHP_BIN, + 'doc' => 'PHP CLI/CGI binary for executing scripts', + 'prompt' => 'PHP CLI/CGI binary', + 'group' => 'File Locations (Advanced)', + ), + 'php_prefix' => array( + 'type' => 'string', + 'default' => '', + 'doc' => '--program-prefix for php_bin\'s ./configure, used for pecl installs', + 'prompt' => '--program-prefix passed to PHP\'s ./configure', + 'group' => 'File Locations (Advanced)', + ), + 'php_suffix' => array( + 'type' => 'string', + 'default' => '', + 'doc' => '--program-suffix for php_bin\'s ./configure, used for pecl installs', + 'prompt' => '--program-suffix passed to PHP\'s ./configure', + 'group' => 'File Locations (Advanced)', + ), + 'php_ini' => array( + 'type' => 'file', + 'default' => '', + 'doc' => 'location of php.ini in which to enable PECL extensions on install', + 'prompt' => 'php.ini location', + 'group' => 'File Locations (Advanced)', + ), + // Maintainers + 'username' => array( + 'type' => 'string', + 'default' => '', + 'doc' => '(maintainers) your PEAR account name', + 'prompt' => 'PEAR username (for maintainers)', + 'group' => 'Maintainers', + ), + 'password' => array( + 'type' => 'password', + 'default' => '', + 'doc' => '(maintainers) your PEAR account password', + 'prompt' => 'PEAR password (for maintainers)', + 'group' => 'Maintainers', + ), + // Advanced + 'verbose' => array( + 'type' => 'integer', + 'default' => PEAR_CONFIG_DEFAULT_VERBOSE, + 'doc' => 'verbosity level +0: really quiet +1: somewhat quiet +2: verbose +3: debug', + 'prompt' => 'Debug Log Level', + 'group' => 'Advanced', + ), + 'preferred_state' => array( + 'type' => 'set', + 'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE, + 'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified', + 'valid_set' => array( + 'stable', 'beta', 'alpha', 'devel', 'snapshot'), + 'prompt' => 'Preferred Package State', + 'group' => 'Advanced', + ), + 'umask' => array( + 'type' => 'mask', + 'default' => PEAR_CONFIG_DEFAULT_UMASK, + 'doc' => 'umask used when creating files (Unix-like systems only)', + 'prompt' => 'Unix file mask', + 'group' => 'Advanced', + ), + 'cache_ttl' => array( + 'type' => 'integer', + 'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL, + 'doc' => 'amount of secs where the local cache is used and not updated', + 'prompt' => 'Cache TimeToLive', + 'group' => 'Advanced', + ), + 'sig_type' => array( + 'type' => 'set', + 'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE, + 'doc' => 'which package signature mechanism to use', + 'valid_set' => array('gpg'), + 'prompt' => 'Package Signature Type', + 'group' => 'Maintainers', + ), + 'sig_bin' => array( + 'type' => 'string', + 'default' => PEAR_CONFIG_DEFAULT_SIG_BIN, + 'doc' => 'which package signature mechanism to use', + 'prompt' => 'Signature Handling Program', + 'group' => 'Maintainers', + ), + 'sig_keyid' => array( + 'type' => 'string', + 'default' => '', + 'doc' => 'which key to use for signing with', + 'prompt' => 'Signature Key Id', + 'group' => 'Maintainers', + ), + 'sig_keydir' => array( + 'type' => 'directory', + 'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR, + 'doc' => 'directory where signature keys are located', + 'prompt' => 'Signature Key Directory', + 'group' => 'Maintainers', + ), + // __channels is reserved - used for channel-specific configuration + ); /** - * @return int|80 port number to connect to + * Constructor. + * + * @param string file to read user-defined options from + * @param string file to read system-wide defaults from + * @param bool determines whether a registry object "follows" + * the value of php_dir (is automatically created + * and moved when php_dir is changed) + * @param bool if true, fails if configuration files cannot be loaded + * + * @access public + * + * @see PEAR_Config::singleton */ - function getPort($mirror = false) + function PEAR_Config($user_file = '', $system_file = '', $ftp_file = false, + $strict = true) { - if ($mirror) { - if ($mir = $this->getMirror($mirror)) { - if (isset($mir['attribs']['port'])) { - return $mir['attribs']['port']; - } - - if ($this->getSSL($mirror)) { - return 443; - } - - return 80; + $this->PEAR(); + PEAR_Installer_Role::initializeConfig($this); + $sl = DIRECTORY_SEPARATOR; + if (empty($user_file)) { + if (OS_WINDOWS) { + $user_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini'; + } else { + $user_file = getenv('HOME') . $sl . '.pearrc'; } - - return false; } - if (isset($this->_channelInfo['servers']['primary']['attribs']['port'])) { - return $this->_channelInfo['servers']['primary']['attribs']['port']; + if (empty($system_file)) { + $system_file = PEAR_CONFIG_SYSCONFDIR . $sl; + if (OS_WINDOWS) { + $system_file .= 'pearsys.ini'; + } else { + $system_file .= 'pear.conf'; + } } - if ($this->getSSL()) { - return 443; + $this->layers = array_keys($this->configuration); + $this->files['user'] = $user_file; + $this->files['system'] = $system_file; + if ($user_file && file_exists($user_file)) { + $this->pushErrorHandling(PEAR_ERROR_RETURN); + $this->readConfigFile($user_file, 'user', $strict); + $this->popErrorHandling(); + if ($this->_errorsFound > 0) { + return; + } } - return 80; - } - - /** - * @return bool Determines whether secure sockets layer (SSL) is used to connect to this channel - */ - function getSSL($mirror = false) - { - if ($mirror) { - if ($mir = $this->getMirror($mirror)) { - if (isset($mir['attribs']['ssl'])) { - return true; - } - - return false; + if ($system_file && @file_exists($system_file)) { + $this->mergeConfigFile($system_file, false, 'system', $strict); + if ($this->_errorsFound > 0) { + return; } - return false; } - if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) { - return true; + if (!$ftp_file) { + $ftp_file = $this->get('remote_config'); } - return false; - } + if ($ftp_file && defined('PEAR_REMOTEINSTALL_OK')) { + $this->readFTPConfigFile($ftp_file); + } - /** - * @return string|false - */ - function getSummary() - { - if (isset($this->_channelInfo['summary'])) { - return $this->_channelInfo['summary']; + foreach ($this->configuration_info as $key => $info) { + $this->configuration['default'][$key] = $info['default']; } - return false; + $this->_registry['default'] = &new PEAR_Registry($this->configuration['default']['php_dir']); + $this->_registry['default']->setConfig($this, false); + $this->_regInitialized['default'] = false; + //$GLOBALS['_PEAR_Config_instance'] = &$this; } /** - * @param string protocol type - * @param string Mirror name - * @return array|false + * Return the default locations of user and system configuration files + * @static */ - function getFunctions($protocol, $mirror = false) + function getDefaultConfigFiles() { - if ($this->getName() == '__uri') { - return false; - } - - $function = $protocol == 'rest' ? 'baseurl' : 'function'; - if ($mirror) { - if ($mir = $this->getMirror($mirror)) { - if (isset($mir[$protocol][$function])) { - return $mir[$protocol][$function]; - } - } - - return false; - } - - if (isset($this->_channelInfo['servers']['primary'][$protocol][$function])) { - return $this->_channelInfo['servers']['primary'][$protocol][$function]; + $sl = DIRECTORY_SEPARATOR; + if (OS_WINDOWS) { + return array( + 'user' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini', + 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini' + ); } - return false; + return array( + 'user' => getenv('HOME') . $sl . '.pearrc', + 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf' + ); } /** - * @param string Protocol type - * @param string Function name (null to return the - * first protocol of the type requested) - * @param string Mirror name, if any - * @return array + * Static singleton method. If you want to keep only one instance + * of this class in use, this method will give you a reference to + * the last created PEAR_Config object if one exists, or create a + * new object. + * + * @param string (optional) file to read user-defined options from + * @param string (optional) file to read system-wide defaults from + * + * @return object an existing or new PEAR_Config instance + * + * @access public + * + * @see PEAR_Config::PEAR_Config */ - function getFunction($type, $name = null, $mirror = false) - { - $protocols = $this->getFunctions($type, $mirror); - if (!$protocols) { - return false; + function &singleton($user_file = '', $system_file = '', $strict = true) + { + if (is_object($GLOBALS['_PEAR_Config_instance'])) { + return $GLOBALS['_PEAR_Config_instance']; } - foreach ($protocols as $protocol) { - if ($name === null) { - return $protocol; - } - - if ($protocol['_content'] != $name) { - continue; - } - - return $protocol; + $t_conf = &new PEAR_Config($user_file, $system_file, false, $strict); + if ($t_conf->_errorsFound > 0) { + return $t_conf->lastError; } - return false; - } + $GLOBALS['_PEAR_Config_instance'] = &$t_conf; + return $GLOBALS['_PEAR_Config_instance']; + } /** - * @param string protocol type - * @param string protocol name - * @param string version - * @param string mirror name - * @return boolean + * Determine whether any configuration files have been detected, and whether a + * registry object can be retrieved from this configuration. + * @return bool + * @since PEAR 1.4.0a1 */ - function supports($type, $name = null, $mirror = false, $version = '1.0') + function validConfiguration() { - $protocols = $this->getFunctions($type, $mirror); - if (!$protocols) { - return false; - } - - foreach ($protocols as $protocol) { - if ($protocol['attribs']['version'] != $version) { - continue; - } - - if ($name === null) { - return true; - } - - if ($protocol['_content'] != $name) { - continue; - } - + if ($this->isDefinedLayer('user') || $this->isDefinedLayer('system')) { return true; } @@ -56300,14321 +61419,13713 @@ class PEAR_ChannelFile } /** - * Determines whether a channel supports Representational State Transfer (REST) protocols - * for retrieving channel information - * @param string - * @return bool + * Reads configuration data from a file. All existing values in + * the config layer are discarded and replaced with data from the + * file. + * @param string file to read from, if NULL or not specified, the + * last-used file for the same layer (second param) is used + * @param string config layer to insert data into ('user' or 'system') + * @return bool TRUE on success or a PEAR error on failure */ - function supportsREST($mirror = false) + function readConfigFile($file = null, $layer = 'user', $strict = true) { - if ($mirror == $this->_channelInfo['name']) { - $mirror = false; - } - - if ($mirror) { - if ($mir = $this->getMirror($mirror)) { - return isset($mir['rest']); - } - - return false; + if (empty($this->files[$layer])) { + return $this->raiseError("unknown config layer `$layer'"); } - return isset($this->_channelInfo['servers']['primary']['rest']); - } - - /** - * Get the URL to access a base resource. - * - * Hyperlinks in the returned xml will be used to retrieve the proper information - * needed. This allows extreme extensibility and flexibility in implementation - * @param string Resource Type to retrieve - */ - function getBaseURL($resourceType, $mirror = false) - { - if ($mirror == $this->_channelInfo['name']) { - $mirror = false; + if ($file === null) { + $file = $this->files[$layer]; } - if ($mirror) { - $mir = $this->getMirror($mirror); - if (!$mir) { - return false; + $data = $this->_readConfigDataFrom($file); + if (PEAR::isError($data)) { + if (!$strict) { + return true; } - $rest = $mir['rest']; - } else { - $rest = $this->_channelInfo['servers']['primary']['rest']; - } + $this->_errorsFound++; + $this->lastError = $data; - if (!isset($rest['baseurl'][0])) { - $rest['baseurl'] = array($rest['baseurl']); + return $data; } - foreach ($rest['baseurl'] as $baseurl) { - if (strtolower($baseurl['attribs']['type']) == strtolower($resourceType)) { - return $baseurl['_content']; - } + $this->files[$layer] = $file; + $this->_decodeInput($data); + $this->configuration[$layer] = $data; + $this->_setupChannels(); + if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { + $this->_registry[$layer] = &new PEAR_Registry($phpdir); + $this->_registry[$layer]->setConfig($this, false); + $this->_regInitialized[$layer] = false; + } else { + unset($this->_registry[$layer]); } - - return false; - } - - /** - * Since REST does not implement RPC, provide this as a logical wrapper around - * resetFunctions for REST - * @param string|false mirror name, if any - */ - function resetREST($mirror = false) - { - return $this->resetFunctions('rest', $mirror); + return true; } /** - * Empty all protocol definitions - * @param string protocol type - * @param string|false mirror name, if any + * @param string url to the remote config file, like ftp://www.example.com/pear/config.ini + * @return true|PEAR_Error */ - function resetFunctions($type, $mirror = false) + function readFTPConfigFile($path) { - if ($mirror) { - if (isset($this->_channelInfo['servers']['mirror'])) { - $mirrors = $this->_channelInfo['servers']['mirror']; - if (!isset($mirrors[0])) { - $mirrors = array($mirrors); + do { // poor man's try + if (!class_exists('PEAR_FTP')) { + if (!class_exists('PEAR_Common')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Common.php'; } - - foreach ($mirrors as $i => $mir) { - if ($mir['attribs']['host'] == $mirror) { - if (isset($this->_channelInfo['servers']['mirror'][$i][$type])) { - unset($this->_channelInfo['servers']['mirror'][$i][$type]); - } - - return true; - } + if (PEAR_Common::isIncludeable('PEAR/FTP.php')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/FTP.php'; } - - return false; } - return false; - } + if (!class_exists('PEAR_FTP')) { + return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config'); + } - if (isset($this->_channelInfo['servers']['primary'][$type])) { - unset($this->_channelInfo['servers']['primary'][$type]); - } + $this->_ftp = &new PEAR_FTP; + $this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN); + $e = $this->_ftp->init($path); + if (PEAR::isError($e)) { + $this->_ftp->popErrorHandling(); + return $e; + } - return true; - } + $tmp = System::mktemp('-d'); + PEAR_Common::addTempFile($tmp); + $e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR . + 'pear.ini', false, FTP_BINARY); + if (PEAR::isError($e)) { + $this->_ftp->popErrorHandling(); + return $e; + } - /** - * Set a channel's protocols to the protocols supported by pearweb - */ - function setDefaultPEARProtocols($version = '1.0', $mirror = false) - { - switch ($version) { - case '1.0' : - $this->resetREST($mirror); - return true; - break; - default : - return false; - break; - } - } + PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini'); + $this->_ftp->disconnect(); + $this->_ftp->popErrorHandling(); + $this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini'; + $e = $this->readConfigFile(null, 'ftp'); + if (PEAR::isError($e)) { + return $e; + } - /** - * @return array - */ - function getMirrors() - { - if (isset($this->_channelInfo['servers']['mirror'])) { - $mirrors = $this->_channelInfo['servers']['mirror']; - if (!isset($mirrors[0])) { - $mirrors = array($mirrors); + $fail = array(); + foreach ($this->configuration_info as $key => $val) { + if (in_array($this->getGroup($key), + array('File Locations', 'File Locations (Advanced)')) && + $this->getType($key) == 'directory') { + // any directory configs must be set for this to work + if (!isset($this->configuration['ftp'][$key])) { + $fail[] = $key; + } + } } - return $mirrors; - } + if (!count($fail)) { + return true; + } - return array(); + $fail = '"' . implode('", "', $fail) . '"'; + unset($this->files['ftp']); + unset($this->configuration['ftp']); + return PEAR::raiseError('ERROR: Ftp configuration file must set all ' . + 'directory configuration variables. These variables were not set: ' . + $fail); + } while (false); // poor man's catch + unset($this->files['ftp']); + return PEAR::raiseError('no remote host specified'); } /** - * Get the unserialized XML representing a mirror - * @return array|false + * Reads the existing configurations and creates the _channels array from it */ - function getMirror($server) + function _setupChannels() { - foreach ($this->getMirrors() as $mirror) { - if ($mirror['attribs']['host'] == $server) { - return $mirror; + $set = array_flip(array_values($this->_channels)); + foreach ($this->configuration as $layer => $data) { + $i = 1000; + if (isset($data['__channels']) && is_array($data['__channels'])) { + foreach ($data['__channels'] as $channel => $info) { + $set[$channel] = $i++; + } } } - - return false; - } - - /** - * @param string - * @return string|false - * @error PEAR_CHANNELFILE_ERROR_NO_NAME - * @error PEAR_CHANNELFILE_ERROR_INVALID_NAME - */ - function setName($name) - { - return $this->setServer($name); + $this->_channels = array_values(array_flip($set)); + $this->setChannels($this->_channels); } - /** - * Set the socket number (port) that is used to connect to this channel - * @param integer - * @param string|false name of the mirror server, or false for the primary - */ - function setPort($port, $mirror = false) + function deleteChannel($channel) { - if ($mirror) { - if (!isset($this->_channelInfo['servers']['mirror'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, - array('mirror' => $mirror)); - return false; - } - - if (isset($this->_channelInfo['servers']['mirror'][0])) { - foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { - if ($mirror == $mir['attribs']['host']) { - $this->_channelInfo['servers']['mirror'][$i]['attribs']['port'] = $port; - return true; - } - } - - return false; - } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { - $this->_channelInfo['servers']['mirror']['attribs']['port'] = $port; - $this->_isValid = false; - return true; + $ch = strtolower($channel); + foreach ($this->configuration as $layer => $data) { + if (isset($data['__channels']) && isset($data['__channels'][$ch])) { + unset($this->configuration[$layer]['__channels'][$ch]); } } - $this->_channelInfo['servers']['primary']['attribs']['port'] = $port; - $this->_isValid = false; - return true; + $this->_channels = array_flip($this->_channels); + unset($this->_channels[$ch]); + $this->_channels = array_flip($this->_channels); } /** - * Set the socket number (port) that is used to connect to this channel - * @param bool Determines whether to turn on SSL support or turn it off - * @param string|false name of the mirror server, or false for the primary + * Merges data into a config layer from a file. Does the same + * thing as readConfigFile, except it does not replace all + * existing values in the config layer. + * @param string file to read from + * @param bool whether to overwrite existing data (default TRUE) + * @param string config layer to insert data into ('user' or 'system') + * @param string if true, errors are returned if file opening fails + * @return bool TRUE on success or a PEAR error on failure */ - function setSSL($ssl = true, $mirror = false) + function mergeConfigFile($file, $override = true, $layer = 'user', $strict = true) { - if ($mirror) { - if (!isset($this->_channelInfo['servers']['mirror'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, - array('mirror' => $mirror)); - return false; - } - - if (isset($this->_channelInfo['servers']['mirror'][0])) { - foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { - if ($mirror == $mir['attribs']['host']) { - if (!$ssl) { - if (isset($this->_channelInfo['servers']['mirror'][$i] - ['attribs']['ssl'])) { - unset($this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl']); - } - } else { - $this->_channelInfo['servers']['mirror'][$i]['attribs']['ssl'] = 'yes'; - } - - return true; - } - } + if (empty($this->files[$layer])) { + return $this->raiseError("unknown config layer `$layer'"); + } - return false; - } elseif ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { - if (!$ssl) { - if (isset($this->_channelInfo['servers']['mirror']['attribs']['ssl'])) { - unset($this->_channelInfo['servers']['mirror']['attribs']['ssl']); - } - } else { - $this->_channelInfo['servers']['mirror']['attribs']['ssl'] = 'yes'; - } + if ($file === null) { + $file = $this->files[$layer]; + } - $this->_isValid = false; + $data = $this->_readConfigDataFrom($file); + if (PEAR::isError($data)) { + if (!$strict) { return true; } + + $this->_errorsFound++; + $this->lastError = $data; + + return $data; } - if ($ssl) { - $this->_channelInfo['servers']['primary']['attribs']['ssl'] = 'yes'; + $this->_decodeInput($data); + if ($override) { + $this->configuration[$layer] = + PEAR_Config::arrayMergeRecursive($this->configuration[$layer], $data); } else { - if (isset($this->_channelInfo['servers']['primary']['attribs']['ssl'])) { - unset($this->_channelInfo['servers']['primary']['attribs']['ssl']); - } + $this->configuration[$layer] = + PEAR_Config::arrayMergeRecursive($data, $this->configuration[$layer]); } - $this->_isValid = false; + $this->_setupChannels(); + if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { + $this->_registry[$layer] = &new PEAR_Registry($phpdir); + $this->_registry[$layer]->setConfig($this, false); + $this->_regInitialized[$layer] = false; + } else { + unset($this->_registry[$layer]); + } return true; } /** - * @param string - * @return string|false - * @error PEAR_CHANNELFILE_ERROR_NO_SERVER - * @error PEAR_CHANNELFILE_ERROR_INVALID_SERVER + * @param array + * @param array + * @return array + * @static */ - function setServer($server, $mirror = false) + function arrayMergeRecursive($arr2, $arr1) { - if (empty($server)) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SERVER); - return false; - } elseif (!$this->validChannelServer($server)) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, - array('tag' => 'name', 'name' => $server)); - return false; - } - - if ($mirror) { - $found = false; - foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { - if ($mirror == $mir['attribs']['host']) { - $found = true; - break; - } + $ret = array(); + foreach ($arr2 as $key => $data) { + if (!isset($arr1[$key])) { + $ret[$key] = $data; + unset($arr1[$key]); + continue; } - - if (!$found) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, - array('mirror' => $mirror)); - return false; + if (is_array($data)) { + if (!is_array($arr1[$key])) { + $ret[$key] = $arr1[$key]; + unset($arr1[$key]); + continue; + } + $ret[$key] = PEAR_Config::arrayMergeRecursive($arr1[$key], $arr2[$key]); + unset($arr1[$key]); } - - $this->_channelInfo['mirror'][$i]['attribs']['host'] = $server; - return true; } - $this->_channelInfo['name'] = $server; - return true; + return array_merge($ret, $arr1); } /** - * @param string - * @return boolean success - * @error PEAR_CHANNELFILE_ERROR_NO_SUMMARY - * @warning PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY + * Writes data into a config layer from a file. + * + * @param string|null file to read from, or null for default + * @param string config layer to insert data into ('user' or + * 'system') + * @param string|null data to write to config file or null for internal data [DEPRECATED] + * @return bool TRUE on success or a PEAR error on failure */ - function setSummary($summary) + function writeConfigFile($file = null, $layer = 'user', $data = null) { - if (empty($summary)) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_NO_SUMMARY); - return false; - } elseif (strpos(trim($summary), "\n") !== false) { - $this->_validateWarning(PEAR_CHANNELFILE_ERROR_MULTILINE_SUMMARY, - array('summary' => $summary)); + $this->_lazyChannelSetup($layer); + if ($layer == 'both' || $layer == 'all') { + foreach ($this->files as $type => $file) { + $err = $this->writeConfigFile($file, $type, $data); + if (PEAR::isError($err)) { + return $err; + } + } + return true; } - $this->_channelInfo['summary'] = $summary; - return true; - } + if (empty($this->files[$layer])) { + return $this->raiseError("unknown config file type `$layer'"); + } - /** - * @param string - * @param boolean determines whether the alias is in channel.xml or local - * @return boolean success - */ - function setAlias($alias, $local = false) - { - if (!$this->validChannelServer($alias)) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_INVALID_NAME, - array('tag' => 'suggestedalias', 'name' => $alias)); - return false; + if ($file === null) { + $file = $this->files[$layer]; } - if ($local) { - $this->_channelInfo['localalias'] = $alias; - } else { - $this->_channelInfo['suggestedalias'] = $alias; + $data = ($data === null) ? $this->configuration[$layer] : $data; + $this->_encodeOutput($data); + $opt = array('-p', dirname($file)); + if (!@System::mkDir($opt)) { + return $this->raiseError("could not create directory: " . dirname($file)); + } + + if (file_exists($file) && is_file($file) && !is_writeable($file)) { + return $this->raiseError("no write access to $file!"); + } + + $fp = @fopen($file, "w"); + if (!$fp) { + return $this->raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed ($php_errormsg)"); } + $contents = "#PEAR_Config 0.9\n" . serialize($data); + if (!@fwrite($fp, $contents)) { + return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed ($php_errormsg)"); + } return true; } /** - * @return string + * Reads configuration data from a file and returns the parsed data + * in an array. + * + * @param string file to read from + * @return array configuration data or a PEAR error on failure + * @access private */ - function getAlias() + function _readConfigDataFrom($file) { - if (isset($this->_channelInfo['localalias'])) { - return $this->_channelInfo['localalias']; + $fp = false; + if (file_exists($file)) { + $fp = @fopen($file, "r"); } - if (isset($this->_channelInfo['suggestedalias'])) { - return $this->_channelInfo['suggestedalias']; + + if (!$fp) { + return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed"); } - if (isset($this->_channelInfo['name'])) { - return $this->_channelInfo['name']; + + $size = filesize($file); + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + fclose($fp); + $contents = file_get_contents($file); + if (empty($contents)) { + return $this->raiseError('Configuration file "' . $file . '" is empty'); } - return ''; + + set_magic_quotes_runtime($rt); + + $version = false; + if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) { + $version = $matches[1]; + $contents = substr($contents, strlen($matches[0])); + } else { + // Museum config file + if (substr($contents,0,2) == 'a:') { + $version = '0.1'; + } + } + + if ($version && version_compare("$version", '1', '<')) { + // no '@', it is possible that unserialize + // raises a notice but it seems to block IO to + // STDOUT if a '@' is used and a notice is raise + $data = unserialize($contents); + + if (!is_array($data) && !$data) { + if ($contents == serialize(false)) { + $data = array(); + } else { + $err = $this->raiseError("PEAR_Config: bad data in $file"); + return $err; + } + } + if (!is_array($data)) { + if (strlen(trim($contents)) > 0) { + $error = "PEAR_Config: bad data in $file"; + $err = $this->raiseError($error); + return $err; + } + + $data = array(); + } + // add parsing of newer formats here... + } else { + $err = $this->raiseError("$file: unknown version `$version'"); + return $err; + } + + return $data; } /** - * Set the package validation object if it differs from PEAR's default - * The class must be includeable via changing _ in the classname to path separator, - * but no checking of this is made. - * @param string|false pass in false to reset to the default packagename regex - * @return boolean success - */ - function setValidationPackage($validateclass, $version) + * Gets the file used for storing the config for a layer + * + * @param string $layer 'user' or 'system' + */ + function getConfFile($layer) { - if (empty($validateclass)) { - unset($this->_channelInfo['validatepackage']); - } - $this->_channelInfo['validatepackage'] = array('_content' => $validateclass); - $this->_channelInfo['validatepackage']['attribs'] = array('version' => $version); + return $this->files[$layer]; } /** - * Add a protocol to the provides section - * @param string protocol type - * @param string protocol version - * @param string protocol name, if any - * @param string mirror name, if this is a mirror's protocol - * @return bool + * @param string Configuration class name, used for detecting duplicate calls + * @param array information on a role as parsed from its xml file + * @return true|PEAR_Error + * @access private */ - function addFunction($type, $version, $name = '', $mirror = false) + function _addConfigVars($class, $vars) { - if ($mirror) { - return $this->addMirrorFunction($mirror, $type, $version, $name); + static $called = array(); + if (isset($called[$class])) { + return; } - $set = array('attribs' => array('version' => $version), '_content' => $name); - if (!isset($this->_channelInfo['servers']['primary'][$type]['function'])) { - if (!isset($this->_channelInfo['servers'])) { - $this->_channelInfo['servers'] = array('primary' => - array($type => array())); - } elseif (!isset($this->_channelInfo['servers']['primary'])) { - $this->_channelInfo['servers']['primary'] = array($type => array()); + $called[$class] = 1; + if (count($vars) > 3) { + return $this->raiseError('Roles can only define 3 new config variables or less'); + } + + foreach ($vars as $name => $var) { + if (!is_array($var)) { + return $this->raiseError('Configuration information must be an array'); } - $this->_channelInfo['servers']['primary'][$type]['function'] = $set; - $this->_isValid = false; - return true; - } elseif (!isset($this->_channelInfo['servers']['primary'][$type]['function'][0])) { - $this->_channelInfo['servers']['primary'][$type]['function'] = array( - $this->_channelInfo['servers']['primary'][$type]['function']); - } + if (!isset($var['type'])) { + return $this->raiseError('Configuration information must contain a type'); + } elseif (!in_array($var['type'], + array('string', 'mask', 'password', 'directory', 'file', 'set'))) { + return $this->raiseError( + 'Configuration type must be one of directory, file, string, ' . + 'mask, set, or password'); + } + if (!isset($var['default'])) { + return $this->raiseError( + 'Configuration information must contain a default value ("default" index)'); + } - $this->_channelInfo['servers']['primary'][$type]['function'][] = $set; - return true; - } - /** - * Add a protocol to a mirror's provides section - * @param string mirror name (server) - * @param string protocol type - * @param string protocol version - * @param string protocol name, if any - */ - function addMirrorFunction($mirror, $type, $version, $name = '') - { - if (!isset($this->_channelInfo['servers']['mirror'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, - array('mirror' => $mirror)); - return false; - } + if (is_array($var['default'])) { + $real_default = ''; + foreach ($var['default'] as $config_var => $val) { + if (strpos($config_var, 'text') === 0) { + $real_default .= $val; + } elseif (strpos($config_var, 'constant') === 0) { + if (!defined($val)) { + return $this->raiseError( + 'Unknown constant "' . $val . '" requested in ' . + 'default value for configuration variable "' . + $name . '"'); + } - $setmirror = false; - if (isset($this->_channelInfo['servers']['mirror'][0])) { - foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { - if ($mirror == $mir['attribs']['host']) { - $setmirror = &$this->_channelInfo['servers']['mirror'][$i]; - break; + $real_default .= constant($val); + } elseif (isset($this->configuration_info[$config_var])) { + $real_default .= + $this->configuration_info[$config_var]['default']; + } else { + return $this->raiseError( + 'Unknown request for "' . $config_var . '" value in ' . + 'default value for configuration variable "' . + $name . '"'); + } } + $var['default'] = $real_default; } - } else { - if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { - $setmirror = &$this->_channelInfo['servers']['mirror']; + + if ($var['type'] == 'integer') { + $var['default'] = (integer) $var['default']; } - } - if (!$setmirror) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, - array('mirror' => $mirror)); - return false; - } + if (!isset($var['doc'])) { + return $this->raiseError( + 'Configuration information must contain a summary ("doc" index)'); + } - $set = array('attribs' => array('version' => $version), '_content' => $name); - if (!isset($setmirror[$type]['function'])) { - $setmirror[$type]['function'] = $set; - $this->_isValid = false; - return true; - } elseif (!isset($setmirror[$type]['function'][0])) { - $setmirror[$type]['function'] = array($setmirror[$type]['function']); + if (!isset($var['prompt'])) { + return $this->raiseError( + 'Configuration information must contain a simple prompt ("prompt" index)'); + } + + if (!isset($var['group'])) { + return $this->raiseError( + 'Configuration information must contain a simple group ("group" index)'); + } + + if (isset($this->configuration_info[$name])) { + return $this->raiseError('Configuration variable "' . $name . + '" already exists'); + } + + $this->configuration_info[$name] = $var; + // fix bug #7351: setting custom config variable in a channel fails + $this->_channelConfigInfo[] = $name; } - $setmirror[$type]['function'][] = $set; - $this->_isValid = false; return true; } /** - * @param string Resource Type this url links to - * @param string URL - * @param string|false mirror name, if this is not a primary server REST base URL + * Encodes/scrambles configuration data before writing to files. + * Currently, 'password' values will be base64-encoded as to avoid + * that people spot cleartext passwords by accident. + * + * @param array (reference) array to encode values in + * @return bool TRUE on success + * @access private */ - function setBaseURL($resourceType, $url, $mirror = false) + function _encodeOutput(&$data) { - if ($mirror) { - if (!isset($this->_channelInfo['servers']['mirror'])) { - $this->_validateError(PEAR_CHANNELFILE_ERROR_MIRROR_NOT_FOUND, - array('mirror' => $mirror)); - return false; + foreach ($data as $key => $value) { + if ($key == '__channels') { + foreach ($data['__channels'] as $channel => $blah) { + $this->_encodeOutput($data['__channels'][$channel]); + } } - $setmirror = false; - if (isset($this->_channelInfo['servers']['mirror'][0])) { - foreach ($this->_channelInfo['servers']['mirror'] as $i => $mir) { - if ($mirror == $mir['attribs']['host']) { - $setmirror = &$this->_channelInfo['servers']['mirror'][$i]; - break; - } + if (!isset($this->configuration_info[$key])) { + continue; + } + + $type = $this->configuration_info[$key]['type']; + switch ($type) { + // we base64-encode passwords so they are at least + // not shown in plain by accident + case 'password': { + $data[$key] = base64_encode($data[$key]); + break; } - } else { - if ($this->_channelInfo['servers']['mirror']['attribs']['host'] == $mirror) { - $setmirror = &$this->_channelInfo['servers']['mirror']; + case 'mask': { + $data[$key] = octdec($data[$key]); + break; } } - } else { - $setmirror = &$this->_channelInfo['servers']['primary']; } - $set = array('attribs' => array('type' => $resourceType), '_content' => $url); - if (!isset($setmirror['rest'])) { - $setmirror['rest'] = array(); - } + return true; + } - if (!isset($setmirror['rest']['baseurl'])) { - $setmirror['rest']['baseurl'] = $set; - $this->_isValid = false; + /** + * Decodes/unscrambles configuration data after reading from files. + * + * @param array (reference) array to encode values in + * @return bool TRUE on success + * @access private + * + * @see PEAR_Config::_encodeOutput + */ + function _decodeInput(&$data) + { + if (!is_array($data)) { return true; - } elseif (!isset($setmirror['rest']['baseurl'][0])) { - $setmirror['rest']['baseurl'] = array($setmirror['rest']['baseurl']); } - foreach ($setmirror['rest']['baseurl'] as $i => $url) { - if ($url['attribs']['type'] == $resourceType) { - $this->_isValid = false; - $setmirror['rest']['baseurl'][$i] = $set; - return true; + foreach ($data as $key => $value) { + if ($key == '__channels') { + foreach ($data['__channels'] as $channel => $blah) { + $this->_decodeInput($data['__channels'][$channel]); + } + } + + if (!isset($this->configuration_info[$key])) { + continue; + } + + $type = $this->configuration_info[$key]['type']; + switch ($type) { + case 'password': { + $data[$key] = base64_decode($data[$key]); + break; + } + case 'mask': { + $data[$key] = decoct($data[$key]); + break; + } } } - $setmirror['rest']['baseurl'][] = $set; - $this->_isValid = false; return true; } /** - * @param string mirror server - * @param int mirror http port - * @return boolean + * Retrieve the default channel. + * + * On startup, channels are not initialized, so if the default channel is not + * pear.php.net, then initialize the config. + * @param string registry layer + * @return string|false */ - function addMirror($server, $port = null) + function getDefaultChannel($layer = null) { - if ($this->_channelInfo['name'] == '__uri') { - return false; // the __uri channel cannot have mirrors by definition - } - - $set = array('attribs' => array('host' => $server)); - if (is_numeric($port)) { - $set['attribs']['port'] = $port; + $ret = false; + if ($layer === null) { + foreach ($this->layers as $layer) { + if (isset($this->configuration[$layer]['default_channel'])) { + $ret = $this->configuration[$layer]['default_channel']; + break; + } + } + } elseif (isset($this->configuration[$layer]['default_channel'])) { + $ret = $this->configuration[$layer]['default_channel']; } - if (!isset($this->_channelInfo['servers']['mirror'])) { - $this->_channelInfo['servers']['mirror'] = $set; - return true; + if ($ret == 'pear.php.net' && defined('PEAR_RUNTYPE') && PEAR_RUNTYPE == 'pecl') { + $ret = 'pecl.php.net'; } - if (!isset($this->_channelInfo['servers']['mirror'][0])) { - $this->_channelInfo['servers']['mirror'] = - array($this->_channelInfo['servers']['mirror']); + if ($ret) { + if ($ret != 'pear.php.net') { + $this->_lazyChannelSetup(); + } + + return $ret; } - $this->_channelInfo['servers']['mirror'][] = $set; - return true; + return PEAR_CONFIG_DEFAULT_CHANNEL; } /** - * Retrieve the name of the validation package for this channel - * @return string|false + * Returns a configuration value, prioritizing layers as per the + * layers property. + * + * @param string config key + * @return mixed the config value, or NULL if not found + * @access public */ - function getValidationPackage() + function get($key, $layer = null, $channel = false) { - if (!$this->_isValid && !$this->validate()) { - return false; + if (!isset($this->configuration_info[$key])) { + return null; } - if (!isset($this->_channelInfo['validatepackage'])) { - return array('attribs' => array('version' => 'default'), - '_content' => 'PEAR_Validate'); + if ($key == '__channels') { + return null; } - return $this->_channelInfo['validatepackage']; - } + if ($key == 'default_channel') { + return $this->getDefaultChannel($layer); + } - /** - * Retrieve the object that can be used for custom validation - * @param string|false the name of the package to validate. If the package is - * the channel validation package, PEAR_Validate is returned - * @return PEAR_Validate|false false is returned if the validation package - * cannot be located - */ - function &getValidationObject($package = false) - { - if (!class_exists('PEAR_Validate')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validate.php'; + if (!$channel) { + $channel = $this->getDefaultChannel(); + } elseif ($channel != 'pear.php.net') { + $this->_lazyChannelSetup(); } + $channel = strtolower($channel); - if (!$this->_isValid) { - if (!$this->validate()) { - $a = false; - return $a; + $test = (in_array($key, $this->_channelConfigInfo)) ? + $this->_getChannelValue($key, $layer, $channel) : + null; + if ($test !== null) { + if ($this->_installRoot) { + if (in_array($this->getGroup($key), + array('File Locations', 'File Locations (Advanced)')) && + $this->getType($key) == 'directory') { + return $this->_prependPath($test, $this->_installRoot); + } } + return $test; } - if (isset($this->_channelInfo['validatepackage'])) { - if ($package == $this->_channelInfo['validatepackage']) { - // channel validation packages are always validated by PEAR_Validate - $val = &new PEAR_Validate; - return $val; - } + if ($layer === null) { + foreach ($this->layers as $layer) { + if (isset($this->configuration[$layer][$key])) { + $test = $this->configuration[$layer][$key]; + if ($this->_installRoot) { + if (in_array($this->getGroup($key), + array('File Locations', 'File Locations (Advanced)')) && + $this->getType($key) == 'directory') { + return $this->_prependPath($test, $this->_installRoot); + } + } - if (!class_exists(str_replace('.', '_', - $this->_channelInfo['validatepackage']['_content']))) { - if ($this->isIncludeable(str_replace('_', '/', - $this->_channelInfo['validatepackage']['_content']) . '.php')) { - include_once 'phar://install-pear-nozlib.phar/' . str_replace('_', '/', - $this->_channelInfo['validatepackage']['_content']) . '.php'; - $vclass = str_replace('.', '_', - $this->_channelInfo['validatepackage']['_content']); - $val = &new $vclass; - } else { - $a = false; - return $a; + if ($key == 'preferred_mirror') { + $reg = &$this->getRegistry(); + if (is_object($reg)) { + $chan = &$reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $channel; + } + + if (!$chan->getMirror($test) && $chan->getName() != $test) { + return $channel; // mirror does not exist + } + } + } + return $test; + } + } + } elseif (isset($this->configuration[$layer][$key])) { + $test = $this->configuration[$layer][$key]; + if ($this->_installRoot) { + if (in_array($this->getGroup($key), + array('File Locations', 'File Locations (Advanced)')) && + $this->getType($key) == 'directory') { + return $this->_prependPath($test, $this->_installRoot); } - } else { - $vclass = str_replace('.', '_', - $this->_channelInfo['validatepackage']['_content']); - $val = &new $vclass; } - } else { - $val = &new PEAR_Validate; - } - return $val; - } + if ($key == 'preferred_mirror') { + $reg = &$this->getRegistry(); + if (is_object($reg)) { + $chan = &$reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $channel; + } - function isIncludeable($path) - { - $possibilities = explode(PATH_SEPARATOR, ini_get('include_path')); - foreach ($possibilities as $dir) { - if (file_exists($dir . DIRECTORY_SEPARATOR . $path) - && is_readable($dir . DIRECTORY_SEPARATOR . $path)) { - return true; + if (!$chan->getMirror($test) && $chan->getName() != $test) { + return $channel; // mirror does not exist + } + } } + + return $test; } - return false; + return null; } /** - * This function is used by the channel updater and retrieves a value set by - * the registry, or the current time if it has not been set - * @return string + * Returns a channel-specific configuration value, prioritizing layers as per the + * layers property. + * + * @param string config key + * @return mixed the config value, or NULL if not found + * @access private */ - function lastModified() + function _getChannelValue($key, $layer, $channel) { - if (isset($this->_channelInfo['_lastmodified'])) { - return $this->_channelInfo['_lastmodified']; + if ($key == '__channels' || $channel == 'pear.php.net') { + return null; } - return time(); - } -} - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Parser.php,v 1.7 2009/02/24 23:39:07 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * base xml parser class - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; -/** - * Parser for channel.xml - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_ChannelFile_Parser extends PEAR_XMLParser -{ - var $_config; - var $_logger; - var $_registry; - - function setConfig(&$c) - { - $this->_config = &$c; - $this->_registry = &$c->getRegistry(); - } - - function setLogger(&$l) - { - $this->_logger = &$l; - } - - function parse($data, $file) - { - if (PEAR::isError($err = parent::parse($data, $file))) { - return $err; + $ret = null; + if ($layer === null) { + foreach ($this->layers as $ilayer) { + if (isset($this->configuration[$ilayer]['__channels'][$channel][$key])) { + $ret = $this->configuration[$ilayer]['__channels'][$channel][$key]; + break; + } + } + } elseif (isset($this->configuration[$layer]['__channels'][$channel][$key])) { + $ret = $this->configuration[$layer]['__channels'][$channel][$key]; } - $ret = new PEAR_ChannelFile; - $ret->setConfig($this->_config); - if (isset($this->_logger)) { - $ret->setLogger($this->_logger); + if ($key != 'preferred_mirror') { + return $ret; } - $ret->fromArray($this->_unserializedData); - // make sure the filelist is in the easy to read format needed - $ret->flattenFilelist(); - $ret->setPackagefile($file, $archive); - return $ret; - } -} - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Command.php,v 1.41 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ - -/** - * Needed for error handling - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Frontend.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; -/** - * List of commands and what classes they are implemented in. - * @var array command => implementing class - */ -$GLOBALS['_PEAR_Command_commandlist'] = array(); + if ($ret !== null) { + $reg = &$this->getRegistry($layer); + if (is_object($reg)) { + $chan = &$reg->getChannel($channel); + if (PEAR::isError($chan)) { + return $channel; + } -/** - * List of commands and their descriptions - * @var array command => description - */ -$GLOBALS['_PEAR_Command_commanddesc'] = array(); + if (!$chan->getMirror($ret) && $chan->getName() != $ret) { + return $channel; // mirror does not exist + } + } -/** - * List of shortcuts to common commands. - * @var array shortcut => command - */ -$GLOBALS['_PEAR_Command_shortcuts'] = array(); + return $ret; + } -/** - * Array of command objects - * @var array class => object - */ -$GLOBALS['_PEAR_Command_objects'] = array(); + if ($channel != $this->getDefaultChannel($layer)) { + return $channel; // we must use the channel name as the preferred mirror + // if the user has not chosen an alternate + } -/** - * PEAR command class, a simple factory class for administrative - * commands. - * - * How to implement command classes: - * - * - The class must be called PEAR_Command_Nnn, installed in the - * "PEAR/Common" subdir, with a method called getCommands() that - * returns an array of the commands implemented by the class (see - * PEAR/Command/Install.php for an example). - * - * - The class must implement a run() function that is called with three - * params: - * - * (string) command name - * (array) assoc array with options, freely defined by each - * command, for example: - * array('force' => true) - * (array) list of the other parameters - * - * The run() function returns a PEAR_CommandResponse object. Use - * these methods to get information: - * - * int getStatus() Returns PEAR_COMMAND_(SUCCESS|FAILURE|PARTIAL) - * *_PARTIAL means that you need to issue at least - * one more command to complete the operation - * (used for example for validation steps). - * - * string getMessage() Returns a message for the user. Remember, - * no HTML or other interface-specific markup. - * - * If something unexpected happens, run() returns a PEAR error. - * - * - DON'T OUTPUT ANYTHING! Return text for output instead. - * - * - DON'T USE HTML! The text you return will be used from both Gtk, - * web and command-line interfaces, so for now, keep everything to - * plain text. - * - * - DON'T USE EXIT OR DIE! Always use pear errors. From static - * classes do PEAR::raiseError(), from other classes do - * $this->raiseError(). - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 - */ -class PEAR_Command -{ - // {{{ factory() + return $this->getDefaultChannel($layer); + } /** - * Get the right object for executing a command. - * - * @param string $command The name of the command - * @param object $config Instance of PEAR_Config object - * - * @return object the command object or a PEAR error + * Set a config value in a specific layer (defaults to 'user'). + * Enforces the types defined in the configuration_info array. An + * integer config variable will be cast to int, and a set config + * variable will be validated against its legal values. * - * @access public - * @static + * @param string config key + * @param string config value + * @param string (optional) config layer + * @param string channel to set this value for, or null for global value + * @return bool TRUE on success, FALSE on failure */ - function &factory($command, &$config) + function set($key, $value, $layer = 'user', $channel = false) { - if (empty($GLOBALS['_PEAR_Command_commandlist'])) { - PEAR_Command::registerCommands(); + if ($key == '__channels') { + return false; } - if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { - $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; + + if (!isset($this->configuration[$layer])) { + return false; } - if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { - $a = PEAR::raiseError("unknown command `$command'"); - return $a; + + if ($key == 'default_channel') { + // can only set this value globally + $channel = 'pear.php.net'; + if ($value != 'pear.php.net') { + $this->_lazyChannelSetup($layer); + } } - $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; - if (!class_exists($class)) { - require_once $GLOBALS['_PEAR_Command_objects'][$class]; + + if ($key == 'preferred_mirror') { + if ($channel == '__uri') { + return false; // can't set the __uri pseudo-channel's mirror + } + + $reg = &$this->getRegistry($layer); + if (is_object($reg)) { + $chan = &$reg->getChannel($channel ? $channel : 'pear.php.net'); + if (PEAR::isError($chan)) { + return false; + } + + if (!$chan->getMirror($value) && $chan->getName() != $value) { + return false; // mirror does not exist + } + } } - if (!class_exists($class)) { - $a = PEAR::raiseError("unknown command `$command'"); - return $a; + + if (!isset($this->configuration_info[$key])) { + return false; } - $ui =& PEAR_Command::getFrontendObject(); - $obj = &new $class($ui, $config); - return $obj; - } - // }}} - // {{{ & getObject() - function &getObject($command) - { - $class = $GLOBALS['_PEAR_Command_commandlist'][$command]; - if (!class_exists($class)) { - require_once $GLOBALS['_PEAR_Command_objects'][$class]; + extract($this->configuration_info[$key]); + switch ($type) { + case 'integer': + $value = (int)$value; + break; + case 'set': { + // If a valid_set is specified, require the value to + // be in the set. If there is no valid_set, accept + // any value. + if ($valid_set) { + reset($valid_set); + if ((key($valid_set) === 0 && !in_array($value, $valid_set)) || + (key($valid_set) !== 0 && empty($valid_set[$value]))) + { + return false; + } + } + break; + } } - if (!class_exists($class)) { - return PEAR::raiseError("unknown command `$command'"); + + if (!$channel) { + $channel = $this->get('default_channel', null, 'pear.php.net'); } - $ui =& PEAR_Command::getFrontendObject(); - $config = &PEAR_Config::singleton(); - $obj = &new $class($ui, $config); - return $obj; - } - // }}} - // {{{ & getFrontendObject() + if (!in_array($channel, $this->_channels)) { + $this->_lazyChannelSetup($layer); + $reg = &$this->getRegistry($layer); + if ($reg) { + $channel = $reg->channelName($channel); + } - /** - * Get instance of frontend object. - * - * @return object|PEAR_Error - * @static - */ - function &getFrontendObject() - { - $a = &PEAR_Frontend::singleton(); - return $a; - } + if (!in_array($channel, $this->_channels)) { + return false; + } + } + + if ($channel != 'pear.php.net') { + if (in_array($key, $this->_channelConfigInfo)) { + $this->configuration[$layer]['__channels'][$channel][$key] = $value; + return true; + } + + return false; + } + + if ($key == 'default_channel') { + if (!isset($reg)) { + $reg = &$this->getRegistry($layer); + if (!$reg) { + $reg = &$this->getRegistry(); + } + } + + if ($reg) { + $value = $reg->channelName($value); + } + + if (!$value) { + return false; + } + } + + $this->configuration[$layer][$key] = $value; + if ($key == 'php_dir' && !$this->_noRegistry) { + if (!isset($this->_registry[$layer]) || + $value != $this->_registry[$layer]->install_dir) { + $this->_registry[$layer] = &new PEAR_Registry($value); + $this->_regInitialized[$layer] = false; + $this->_registry[$layer]->setConfig($this, false); + } + } - // }}} - // {{{ & setFrontendClass() + return true; + } - /** - * Load current frontend class. - * - * @param string $uiclass Name of class implementing the frontend - * - * @return object the frontend object, or a PEAR error - * @static - */ - function &setFrontendClass($uiclass) + function _lazyChannelSetup($uselayer = false) { - $a = &PEAR_Frontend::setFrontendClass($uiclass); - return $a; - } + if ($this->_noRegistry) { + return; + } - // }}} - // {{{ setFrontendType() + $merge = false; + foreach ($this->_registry as $layer => $p) { + if ($uselayer && $uselayer != $layer) { + continue; + } - /** - * Set current frontend. - * - * @param string $uitype Name of the frontend type (for example "CLI") - * - * @return object the frontend object, or a PEAR error - * @static - */ - function setFrontendType($uitype) - { - $uiclass = 'PEAR_Frontend_' . $uitype; - return PEAR_Command::setFrontendClass($uiclass); - } + if (!$this->_regInitialized[$layer]) { + if ($layer == 'default' && isset($this->_registry['user']) || + isset($this->_registry['system'])) { + // only use the default registry if there are no alternatives + continue; + } - // }}} - // {{{ registerCommands() + if (!is_object($this->_registry[$layer])) { + if ($phpdir = $this->get('php_dir', $layer, 'pear.php.net')) { + $this->_registry[$layer] = &new PEAR_Registry($phpdir); + $this->_registry[$layer]->setConfig($this, false); + $this->_regInitialized[$layer] = false; + } else { + unset($this->_registry[$layer]); + return; + } + } + + $this->setChannels($this->_registry[$layer]->listChannels(), $merge); + $this->_regInitialized[$layer] = true; + $merge = true; + } + } + } /** - * Scan through the Command directory looking for classes - * and see what commands they implement. - * - * @param bool (optional) if FALSE (default), the new list of - * commands should replace the current one. If TRUE, - * new entries will be merged with old. - * - * @param string (optional) where (what directory) to look for - * classes, defaults to the Command subdirectory of - * the directory from where this file (__FILE__) is - * included. - * - * @return bool TRUE on success, a PEAR error on failure + * Set the list of channels. * - * @access public - * @static + * This should be set via a call to {@link PEAR_Registry::listChannels()} + * @param array + * @param bool + * @return bool success of operation */ - function registerCommands($merge = false, $dir = null) + function setChannels($channels, $merge = false) { - $parser = new PEAR_XMLParser; - if ($dir === null) { - $dir = dirname(__FILE__) . '/Command'; - } - if (!is_dir($dir)) { - return PEAR::raiseError("registerCommands: opendir($dir) '$dir' does not exist or is not a directory"); - } - $dp = @opendir($dir); - if (empty($dp)) { - return PEAR::raiseError("registerCommands: opendir($dir) failed"); + if (!is_array($channels)) { + return false; } - if (!$merge) { - $GLOBALS['_PEAR_Command_commandlist'] = array(); + + if ($merge) { + $this->_channels = array_merge($this->_channels, $channels); + } else { + $this->_channels = $channels; } - while ($entry = readdir($dp)) { - if ($entry{0} == '.' || substr($entry, -4) != '.xml') { + + foreach ($channels as $channel) { + $channel = strtolower($channel); + if ($channel == 'pear.php.net') { continue; } - $class = "PEAR_Command_".substr($entry, 0, -4); - $file = "$dir/$entry"; - $parser->parse(file_get_contents($file)); - $implements = $parser->getData(); - // List of commands - if (empty($GLOBALS['_PEAR_Command_objects'][$class])) { - $GLOBALS['_PEAR_Command_objects'][$class] = "$dir/" . substr($entry, 0, -4) . - '.php'; - } - foreach ($implements as $command => $desc) { - if ($command == 'attribs') { - continue; - } - if (isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { - return PEAR::raiseError('Command "' . $command . '" already registered in ' . - 'class "' . $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); - } - $GLOBALS['_PEAR_Command_commandlist'][$command] = $class; - $GLOBALS['_PEAR_Command_commanddesc'][$command] = $desc['summary']; - if (isset($desc['shortcut'])) { - $shortcut = $desc['shortcut']; - if (isset($GLOBALS['_PEAR_Command_shortcuts'][$shortcut])) { - return PEAR::raiseError('Command shortcut "' . $shortcut . '" already ' . - 'registered to command "' . $command . '" in class "' . - $GLOBALS['_PEAR_Command_commandlist'][$command] . '"'); - } - $GLOBALS['_PEAR_Command_shortcuts'][$shortcut] = $command; + + foreach ($this->layers as $layer) { + if (!isset($this->configuration[$layer]['__channels'])) { + $this->configuration[$layer]['__channels'] = array(); } - if (isset($desc['options']) && $desc['options']) { - foreach ($desc['options'] as $oname => $option) { - if (isset($option['shortopt']) && strlen($option['shortopt']) > 1) { - return PEAR::raiseError('Option "' . $oname . '" short option "' . - $option['shortopt'] . '" must be ' . - 'only 1 character in Command "' . $command . '" in class "' . - $class . '"'); - } - } + if (!isset($this->configuration[$layer]['__channels'][$channel]) + || !is_array($this->configuration[$layer]['__channels'][$channel])) { + $this->configuration[$layer]['__channels'][$channel] = array(); } } } - ksort($GLOBALS['_PEAR_Command_shortcuts']); - ksort($GLOBALS['_PEAR_Command_commandlist']); - @closedir($dp); + return true; } - // }}} - // {{{ getCommands() - /** - * Get the list of currently supported commands, and what - * classes implement them. + * Get the type of a config value. * - * @return array command => implementing class + * @param string config key + * + * @return string type, one of "string", "integer", "file", + * "directory", "set" or "password". * * @access public - * @static + * */ - function getCommands() + function getType($key) { - if (empty($GLOBALS['_PEAR_Command_commandlist'])) { - PEAR_Command::registerCommands(); + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['type']; } - return $GLOBALS['_PEAR_Command_commandlist']; + return false; } - // }}} - // {{{ getShortcuts() - /** - * Get the list of command shortcuts. + * Get the documentation for a config value. * - * @return array shortcut => command + * @param string config key + * @return string documentation string * * @access public - * @static + * */ - function getShortcuts() + function getDocs($key) { - if (empty($GLOBALS['_PEAR_Command_shortcuts'])) { - PEAR_Command::registerCommands(); + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['doc']; } - return $GLOBALS['_PEAR_Command_shortcuts']; - } - // }}} - // {{{ getGetoptArgs() + return false; + } /** - * Compiles arguments for getopt. - * - * @param string $command command to get optstring for - * @param string $short_args (reference) short getopt format - * @param array $long_args (reference) long getopt format + * Get the short documentation for a config value. * - * @return void + * @param string config key + * @return string short documentation string * * @access public - * @static + * */ - function getGetoptArgs($command, &$short_args, &$long_args) + function getPrompt($key) { - if (empty($GLOBALS['_PEAR_Command_commandlist'])) { - PEAR_Command::registerCommands(); - } - if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { - $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; - } - if (!isset($GLOBALS['_PEAR_Command_commandlist'][$command])) { - return null; + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['prompt']; } - $obj = &PEAR_Command::getObject($command); - return $obj->getGetoptArgs($command, $short_args, $long_args); - } - // }}} - // {{{ getDescription() + return false; + } /** - * Get description for a command. - * - * @param string $command Name of the command + * Get the parameter group for a config key. * - * @return string command description + * @param string config key + * @return string parameter group * * @access public - * @static + * */ - function getDescription($command) + function getGroup($key) { - if (!isset($GLOBALS['_PEAR_Command_commanddesc'][$command])) { - return null; + if (isset($this->configuration_info[$key])) { + return $this->configuration_info[$key]['group']; } - return $GLOBALS['_PEAR_Command_commanddesc'][$command]; - } - // }}} - // {{{ getHelp() + return false; + } /** - * Get help for command. + * Get the list of parameter groups. * - * @param string $command Name of the command to return help for + * @return array list of parameter groups * * @access public - * @static + * */ - function getHelp($command) + function getGroups() { - $cmds = PEAR_Command::getCommands(); - if (isset($GLOBALS['_PEAR_Command_shortcuts'][$command])) { - $command = $GLOBALS['_PEAR_Command_shortcuts'][$command]; - } - if (isset($cmds[$command])) { - $obj = &PEAR_Command::getObject($command); - return $obj->getHelp($command); + $tmp = array(); + foreach ($this->configuration_info as $key => $info) { + $tmp[$info['group']] = 1; } - return false; - } - // }}} -} - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.39 2009/02/24 23:39:29 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ -/** - * base class - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; + return array_keys($tmp); + } -/** - * PEAR commands base class - * - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 - */ -class PEAR_Command_Common extends PEAR -{ /** - * PEAR_Config object used to pass user system and configuration - * on when executing commands + * Get the list of the parameters in a group. * - * @var PEAR_Config - */ - var $config; - /** - * @var PEAR_Registry - * @access protected - */ - var $_registry; - - /** - * User Interface object, for all interaction with the user. - * @var object - */ - var $ui; - - var $_deps_rel_trans = array( - 'lt' => '<', - 'le' => '<=', - 'eq' => '=', - 'ne' => '!=', - 'gt' => '>', - 'ge' => '>=', - 'has' => '==' - ); - - var $_deps_type_trans = array( - 'pkg' => 'package', - 'ext' => 'extension', - 'php' => 'PHP', - 'prog' => 'external program', - 'ldlib' => 'external library for linking', - 'rtlib' => 'external runtime library', - 'os' => 'operating system', - 'websrv' => 'web server', - 'sapi' => 'SAPI backend' - ); - - /** - * PEAR_Command_Common constructor. + * @param string $group parameter group + * @return array list of parameters in $group * * @access public + * */ - function PEAR_Command_Common(&$ui, &$config) + function getGroupKeys($group) { - parent::PEAR(); - $this->config = &$config; - $this->ui = &$ui; + $keys = array(); + foreach ($this->configuration_info as $key => $info) { + if ($info['group'] == $group) { + $keys[] = $key; + } + } + + return $keys; } /** - * Return a list of all the commands defined by this class. - * @return array list of commands + * Get the list of allowed set values for a config value. Returns + * NULL for config values that are not sets. + * + * @param string config key + * @return array enumerated array of set values, or NULL if the + * config key is unknown or not a set + * * @access public + * */ - function getCommands() + function getSetValues($key) { - $ret = array(); - foreach (array_keys($this->commands) as $command) { - $ret[$command] = $this->commands[$command]['summary']; + if (isset($this->configuration_info[$key]) && + isset($this->configuration_info[$key]['type']) && + $this->configuration_info[$key]['type'] == 'set') + { + $valid_set = $this->configuration_info[$key]['valid_set']; + reset($valid_set); + if (key($valid_set) === 0) { + return $valid_set; + } + + return array_keys($valid_set); } - return $ret; + return null; } /** - * Return a list of all the command shortcuts defined by this class. - * @return array shortcut => command + * Get all the current config keys. + * + * @return array simple array of config keys + * * @access public */ - function getShortcuts() + function getKeys() { - $ret = array(); - foreach (array_keys($this->commands) as $command) { - if (isset($this->commands[$command]['shortcut'])) { - $ret[$this->commands[$command]['shortcut']] = $command; + $keys = array(); + foreach ($this->layers as $layer) { + $test = $this->configuration[$layer]; + if (isset($test['__channels'])) { + foreach ($test['__channels'] as $channel => $configs) { + $keys = array_merge($keys, $configs); + } } - } - return $ret; - } - - function getOptions($command) - { - $shortcuts = $this->getShortcuts(); - if (isset($shortcuts[$command])) { - $command = $shortcuts[$command]; - } + unset($test['__channels']); + $keys = array_merge($keys, $test); - if (isset($this->commands[$command]) && - isset($this->commands[$command]['options'])) { - return $this->commands[$command]['options']; } - - return null; + return array_keys($keys); } - function getGetoptArgs($command, &$short_args, &$long_args) + /** + * Remove the a config key from a specific config layer. + * + * @param string config key + * @param string (optional) config layer + * @param string (optional) channel (defaults to default channel) + * @return bool TRUE on success, FALSE on failure + * + * @access public + */ + function remove($key, $layer = 'user', $channel = null) { - $short_args = ''; - $long_args = array(); - if (empty($this->commands[$command]) || empty($this->commands[$command]['options'])) { - return; + if ($channel === null) { + $channel = $this->getDefaultChannel(); } - reset($this->commands[$command]['options']); - while (list($option, $info) = each($this->commands[$command]['options'])) { - $larg = $sarg = ''; - if (isset($info['arg'])) { - if ($info['arg']{0} == '(') { - $larg = '=='; - $sarg = '::'; - $arg = substr($info['arg'], 1, -1); - } else { - $larg = '='; - $sarg = ':'; - $arg = $info['arg']; - } - } - - if (isset($info['shortopt'])) { - $short_args .= $info['shortopt'] . $sarg; + if ($channel !== 'pear.php.net') { + if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { + unset($this->configuration[$layer]['__channels'][$channel][$key]); + return true; } + } - $long_args[] = $option . $larg; + if (isset($this->configuration[$layer][$key])) { + unset($this->configuration[$layer][$key]); + return true; } + + return false; } /** - * Returns the help message for the given command - * - * @param string $command The command - * @return mixed A fail string if the command does not have help or - * a two elements array containing [0]=>help string, - * [1]=> help string for the accepted cmd args - */ - function getHelp($command) + * Temporarily remove an entire config layer. USE WITH CARE! + * + * @param string config key + * @param string (optional) config layer + * @return bool TRUE on success, FALSE on failure + * + * @access public + */ + function removeLayer($layer) { - $config = &PEAR_Config::singleton(); - if (!isset($this->commands[$command])) { - return "No such command \"$command\""; - } - - $help = null; - if (isset($this->commands[$command]['doc'])) { - $help = $this->commands[$command]['doc']; - } - - if (empty($help)) { - // XXX (cox) Fallback to summary if there is no doc (show both?) - if (!isset($this->commands[$command]['summary'])) { - return "No help for command \"$command\""; - } - $help = $this->commands[$command]['summary']; + if (isset($this->configuration[$layer])) { + $this->configuration[$layer] = array(); + return true; } - if (preg_match_all('/{config\s+([^\}]+)}/e', $help, $matches)) { - foreach($matches[0] as $k => $v) { - $help = preg_replace("/$v/", $config->get($matches[1][$k]), $help); - } - } + return false; + } - return array($help, $this->getHelpArgs($command)); + /** + * Stores configuration data in a layer. + * + * @param string config layer to store + * @return bool TRUE on success, or PEAR error on failure + * + * @access public + */ + function store($layer = 'user', $data = null) + { + return $this->writeConfigFile(null, $layer, $data); } /** - * Returns the help for the accepted arguments of a command + * Tells what config layer that gets to define a key. * - * @param string $command - * @return string The help string + * @param string config key + * @param boolean return the defining channel + * + * @return string|array the config layer, or an empty string if not found. + * + * if $returnchannel, the return is an array array('layer' => layername, + * 'channel' => channelname), or an empty string if not found + * + * @access public */ - function getHelpArgs($command) + function definedBy($key, $returnchannel = false) { - if (isset($this->commands[$command]['options']) && - count($this->commands[$command]['options'])) - { - $help = "Options:\n"; - foreach ($this->commands[$command]['options'] as $k => $v) { - if (isset($v['arg'])) { - if ($v['arg'][0] == '(') { - $arg = substr($v['arg'], 1, -1); - $sapp = " [$arg]"; - $lapp = "[=$arg]"; - } else { - $sapp = " $v[arg]"; - $lapp = "=$v[arg]"; + foreach ($this->layers as $layer) { + $channel = $this->getDefaultChannel(); + if ($channel !== 'pear.php.net') { + if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { + if ($returnchannel) { + return array('layer' => $layer, 'channel' => $channel); } - } else { - $sapp = $lapp = ""; + return $layer; } + } - if (isset($v['shortopt'])) { - $s = $v['shortopt']; - $help .= " -$s$sapp, --$k$lapp\n"; - } else { - $help .= " --$k$lapp\n"; + if (isset($this->configuration[$layer][$key])) { + if ($returnchannel) { + return array('layer' => $layer, 'channel' => 'pear.php.net'); } - - $p = " "; - $doc = rtrim(str_replace("\n", "\n$p", $v['doc'])); - $help .= " $doc\n"; + return $layer; } - - return $help; } - return null; + return ''; } - function run($command, $options, $params) + /** + * Tells whether a given key exists as a config value. + * + * @param string config key + * @return bool whether exists in this object + * + * @access public + */ + function isDefined($key) { - if (empty($this->commands[$command]['function'])) { - // look for shortcuts - foreach (array_keys($this->commands) as $cmd) { - if (isset($this->commands[$cmd]['shortcut']) && $this->commands[$cmd]['shortcut'] == $command) { - if (empty($this->commands[$cmd]['function'])) { - return $this->raiseError("unknown command `$command'"); - } else { - $func = $this->commands[$cmd]['function']; - } - $command = $cmd; - - //$command = $this->commands[$cmd]['function']; - break; - } + foreach ($this->layers as $layer) { + if (isset($this->configuration[$layer][$key])) { + return true; } - } else { - $func = $this->commands[$command]['function']; } - return $this->$func($command, $options, $params); + return false; } -} - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Install.php,v 1.153 2009/03/08 04:01:11 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ - -/** - * base class - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Command/Common.php'; - -/** - * PEAR commands for installation or deinstallation/upgrading of - * packages. - * - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 - */ -class PEAR_Command_Install extends PEAR_Command_Common -{ - // {{{ properties - - var $commands = array( - 'install' => array( - 'summary' => 'Install Package', - 'function' => 'doInstall', - 'shortcut' => 'i', - 'options' => array( - 'force' => array( - 'shortopt' => 'f', - 'doc' => 'will overwrite newer installed packages', - ), - 'loose' => array( - 'shortopt' => 'l', - 'doc' => 'do not check for recommended dependency version', - ), - 'nodeps' => array( - 'shortopt' => 'n', - 'doc' => 'ignore dependencies, install anyway', - ), - 'register-only' => array( - 'shortopt' => 'r', - 'doc' => 'do not install files, only register the package as installed', - ), - 'soft' => array( - 'shortopt' => 's', - 'doc' => 'soft install, fail silently, or upgrade if already installed', - ), - 'nobuild' => array( - 'shortopt' => 'B', - 'doc' => 'don\'t build C extensions', - ), - 'nocompress' => array( - 'shortopt' => 'Z', - 'doc' => 'request uncompressed files when downloading', - ), - 'installroot' => array( - 'shortopt' => 'R', - 'arg' => 'DIR', - 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', - ), - 'packagingroot' => array( - 'shortopt' => 'P', - 'arg' => 'DIR', - 'doc' => 'root directory used when packaging files, like RPM packaging', - ), - 'ignore-errors' => array( - 'doc' => 'force install even if there were errors', - ), - 'alldeps' => array( - 'shortopt' => 'a', - 'doc' => 'install all required and optional dependencies', - ), - 'onlyreqdeps' => array( - 'shortopt' => 'o', - 'doc' => 'install all required dependencies', - ), - 'offline' => array( - 'shortopt' => 'O', - 'doc' => 'do not attempt to download any urls or contact channels', - ), - 'pretend' => array( - 'shortopt' => 'p', - 'doc' => 'Only list the packages that would be downloaded', - ), - ), - 'doc' => '[channel/] ... -Installs one or more PEAR packages. You can specify a package to -install in four ways: - -"Package-1.0.tgz" : installs from a local file - -"http://example.com/Package-1.0.tgz" : installs from -anywhere on the net. - -"package.xml" : installs the package described in -package.xml. Useful for testing, or for wrapping a PEAR package in -another package manager such as RPM. - -"Package[-version/state][.tar]" : queries your default channel\'s server -({config master_server}) and downloads the newest package with -the preferred quality/state ({config preferred_state}). - -To retrieve Package version 1.1, use "Package-1.1," to retrieve -Package state beta, use "Package-beta." To retrieve an uncompressed -file, append .tar (make sure there is no file by the same name first) - -To download a package from another channel, prefix with the channel name like -"channel/Package" - -More than one package may be specified at once. It is ok to mix these -four ways of specifying packages. -'), - 'upgrade' => array( - 'summary' => 'Upgrade Package', - 'function' => 'doInstall', - 'shortcut' => 'up', - 'options' => array( - 'channel' => array( - 'shortopt' => 'c', - 'doc' => 'upgrade packages from a specific channel', - 'arg' => 'CHAN', - ), - 'force' => array( - 'shortopt' => 'f', - 'doc' => 'overwrite newer installed packages', - ), - 'loose' => array( - 'shortopt' => 'l', - 'doc' => 'do not check for recommended dependency version', - ), - 'nodeps' => array( - 'shortopt' => 'n', - 'doc' => 'ignore dependencies, upgrade anyway', - ), - 'register-only' => array( - 'shortopt' => 'r', - 'doc' => 'do not install files, only register the package as upgraded', - ), - 'nobuild' => array( - 'shortopt' => 'B', - 'doc' => 'don\'t build C extensions', - ), - 'nocompress' => array( - 'shortopt' => 'Z', - 'doc' => 'request uncompressed files when downloading', - ), - 'installroot' => array( - 'shortopt' => 'R', - 'arg' => 'DIR', - 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', - ), - 'ignore-errors' => array( - 'doc' => 'force install even if there were errors', - ), - 'alldeps' => array( - 'shortopt' => 'a', - 'doc' => 'install all required and optional dependencies', - ), - 'onlyreqdeps' => array( - 'shortopt' => 'o', - 'doc' => 'install all required dependencies', - ), - 'offline' => array( - 'shortopt' => 'O', - 'doc' => 'do not attempt to download any urls or contact channels', - ), - 'pretend' => array( - 'shortopt' => 'p', - 'doc' => 'Only list the packages that would be downloaded', - ), - ), - 'doc' => ' ... -Upgrades one or more PEAR packages. See documentation for the -"install" command for ways to specify a package. - -When upgrading, your package will be updated if the provided new -package has a higher version number (use the -f option if you need to -upgrade anyway). - -More than one package may be specified at once. -'), - 'upgrade-all' => array( - 'summary' => 'Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters]', - 'function' => 'doUpgradeAll', - 'shortcut' => 'ua', - 'options' => array( - 'channel' => array( - 'shortopt' => 'c', - 'doc' => 'upgrade packages from a specific channel', - 'arg' => 'CHAN', - ), - 'nodeps' => array( - 'shortopt' => 'n', - 'doc' => 'ignore dependencies, upgrade anyway', - ), - 'register-only' => array( - 'shortopt' => 'r', - 'doc' => 'do not install files, only register the package as upgraded', - ), - 'nobuild' => array( - 'shortopt' => 'B', - 'doc' => 'don\'t build C extensions', - ), - 'nocompress' => array( - 'shortopt' => 'Z', - 'doc' => 'request uncompressed files when downloading', - ), - 'installroot' => array( - 'shortopt' => 'R', - 'arg' => 'DIR', - 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT), use packagingroot for RPM', - ), - 'ignore-errors' => array( - 'doc' => 'force install even if there were errors', - ), - 'loose' => array( - 'doc' => 'do not check for recommended dependency version', - ), - ), - 'doc' => ' -WARNING: This function is deprecated in favor of using the upgrade command with no params - -Upgrades all packages that have a newer release available. Upgrades are -done only if there is a release available of the state specified in -"preferred_state" (currently {config preferred_state}), or a state considered -more stable. -'), - 'uninstall' => array( - 'summary' => 'Un-install Package', - 'function' => 'doUninstall', - 'shortcut' => 'un', - 'options' => array( - 'nodeps' => array( - 'shortopt' => 'n', - 'doc' => 'ignore dependencies, uninstall anyway', - ), - 'register-only' => array( - 'shortopt' => 'r', - 'doc' => 'do not remove files, only register the packages as not installed', - ), - 'installroot' => array( - 'shortopt' => 'R', - 'arg' => 'DIR', - 'doc' => 'root directory used when installing files (ala PHP\'s INSTALL_ROOT)', - ), - 'ignore-errors' => array( - 'doc' => 'force install even if there were errors', - ), - 'offline' => array( - 'shortopt' => 'O', - 'doc' => 'do not attempt to uninstall remotely', - ), - ), - 'doc' => '[channel/] ... -Uninstalls one or more PEAR packages. More than one package may be -specified at once. Prefix with channel name to uninstall from a -channel not in your default channel ({config default_channel}) -'), - 'bundle' => array( - 'summary' => 'Unpacks a Pecl Package', - 'function' => 'doBundle', - 'shortcut' => 'bun', - 'options' => array( - 'destination' => array( - 'shortopt' => 'd', - 'arg' => 'DIR', - 'doc' => 'Optional destination directory for unpacking (defaults to current path or "ext" if exists)', - ), - 'force' => array( - 'shortopt' => 'f', - 'doc' => 'Force the unpacking even if there were errors in the package', - ), - ), - 'doc' => ' -Unpacks a Pecl Package into the selected location. It will download the -package if needed. -'), - 'run-scripts' => array( - 'summary' => 'Run Post-Install Scripts bundled with a package', - 'function' => 'doRunScripts', - 'shortcut' => 'rs', - 'options' => array( - ), - 'doc' => ' -Run post-installation scripts in package , if any exist. -'), - ); - - // }}} - // {{{ constructor /** - * PEAR_Command_Install constructor. + * Tells whether a given config layer exists. + * + * @param string config layer + * @return bool whether exists in this object * * @access public */ - function PEAR_Command_Install(&$ui, &$config) + function isDefinedLayer($layer) { - parent::PEAR_Command_Common($ui, $config); + return isset($this->configuration[$layer]); } - // }}} - /** - * For unit testing purposes + * Returns the layers defined (except the 'default' one) + * + * @return array of the defined layers */ - function &getDownloader(&$ui, $options, &$config) + function getLayers() { - if (!class_exists('PEAR_Downloader')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Downloader.php'; - } - $a = &new PEAR_Downloader($ui, $options, $config); - return $a; + $cf = $this->configuration; + unset($cf['default']); + return array_keys($cf); } - /** - * For unit testing purposes - */ - function &getInstaller(&$ui) + function apiVersion() { - if (!class_exists('PEAR_Installer')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer.php'; - } - $a = &new PEAR_Installer($ui); - return $a; + return '1.1'; } - function enableExtension($binaries, $type) + /** + * @return PEAR_Registry + */ + function &getRegistry($use = null) { - if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) { - return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location'); - } - $ini = $this->_parseIni($phpini); - if (PEAR::isError($ini)) { - return $ini; - } - $line = 0; - if ($type == 'extsrc' || $type == 'extbin') { - $search = 'extensions'; - $enable = 'extension'; - } else { - $search = 'zend_extensions'; - ob_start(); - phpinfo(INFO_GENERAL); - $info = ob_get_contents(); - ob_end_clean(); - $debug = function_exists('leak') ? '_debug' : ''; - $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; - $enable = 'zend_extension' . $debug . $ts; - } - foreach ($ini[$search] as $line => $extension) { - if (in_array($extension, $binaries, true) || in_array( - $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) { - // already enabled - assume if one is, all are - return true; - } - } - if ($line) { - $newini = array_slice($ini['all'], 0, $line); - } else { - $newini = array(); - } - foreach ($binaries as $binary) { - if ($ini['extension_dir']) { - $binary = basename($binary); - } - $newini[] = $enable . '="' . $binary . '"' . (OS_UNIX ? "\n" : "\r\n"); - } - $newini = array_merge($newini, array_slice($ini['all'], $line)); - $fp = @fopen($phpini, 'wb'); - if (!$fp) { - return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing'); - } - foreach ($newini as $line) { - fwrite($fp, $line); + $layer = $use === null ? 'user' : $use; + if (isset($this->_registry[$layer])) { + return $this->_registry[$layer]; + } elseif ($use === null && isset($this->_registry['system'])) { + return $this->_registry['system']; + } elseif ($use === null && isset($this->_registry['default'])) { + return $this->_registry['default']; + } elseif ($use) { + $a = false; + return $a; } - fclose($fp); - return true; + + // only go here if null was passed in + echo "CRITICAL ERROR: Registry could not be initialized from any value"; + exit(1); } - function disableExtension($binaries, $type) + /** + * This is to allow customization like the use of installroot + * @param PEAR_Registry + * @return bool + */ + function setRegistry(&$reg, $layer = 'user') { - if (!($phpini = $this->config->get('php_ini', null, 'pear.php.net'))) { - return PEAR::raiseError('configuration option "php_ini" is not set to php.ini location'); - } - $ini = $this->_parseIni($phpini); - if (PEAR::isError($ini)) { - return $ini; - } - $line = 0; - if ($type == 'extsrc' || $type == 'extbin') { - $search = 'extensions'; - $enable = 'extension'; - } else { - $search = 'zend_extensions'; - ob_start(); - phpinfo(INFO_GENERAL); - $info = ob_get_contents(); - ob_end_clean(); - $debug = function_exists('leak') ? '_debug' : ''; - $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; - $enable = 'zend_extension' . $debug . $ts; - } - $found = false; - foreach ($ini[$search] as $line => $extension) { - if (in_array($extension, $binaries, true) || in_array( - $ini['extension_dir'] . DIRECTORY_SEPARATOR . $extension, $binaries, true)) { - $found = true; - break; - } - } - if (!$found) { - // not enabled - return true; - } - $fp = @fopen($phpini, 'wb'); - if (!$fp) { - return PEAR::raiseError('cannot open php.ini "' . $phpini . '" for writing'); + if ($this->_noRegistry) { + return false; } - if ($line) { - $newini = array_slice($ini['all'], 0, $line); - // delete the enable line - $newini = array_merge($newini, array_slice($ini['all'], $line + 1)); - } else { - $newini = array_slice($ini['all'], 1); + + if (!in_array($layer, array('user', 'system'))) { + return false; } - foreach ($newini as $line) { - fwrite($fp, $line); + + $this->_registry[$layer] = &$reg; + if (is_object($reg)) { + $this->_registry[$layer]->setConfig($this, false); } - fclose($fp); + return true; } - function _parseIni($filename) + function noRegistry() { - if (!file_exists($filename)) { - return PEAR::raiseError('php.ini "' . $filename . '" does not exist'); - } + $this->_noRegistry = true; + } - if (filesize($filename) > 300000) { - return PEAR::raiseError('php.ini "' . $filename . '" is too large, aborting'); + /** + * @return PEAR_REST + */ + function &getREST($version, $options = array()) + { + $version = str_replace('.', '', $version); + if (!class_exists($class = 'PEAR_REST_' . $version)) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/REST/' . $version . '.php'; } - ob_start(); - phpinfo(INFO_GENERAL); - $info = ob_get_contents(); - ob_end_clean(); - $debug = function_exists('leak') ? '_debug' : ''; - $ts = preg_match('/Thread Safety.+enabled/', $info) ? '_ts' : ''; - $zend_extension_line = 'zend_extension' . $debug . $ts; - $all = @file($filename); - if (!$all) { - return PEAR::raiseError('php.ini "' . $filename .'" could not be read'); + $remote = &new $class($this, $options); + return $remote; + } + + /** + * The ftp server is set in {@link readFTPConfigFile()}. It exists only if a + * remote configuration file has been specified + * @return PEAR_FTP|false + */ + function &getFTP() + { + if (isset($this->_ftp)) { + return $this->_ftp; } - $zend_extensions = $extensions = array(); - // assume this is right, but pull from the php.ini if it is found - $extension_dir = ini_get('extension_dir'); - foreach ($all as $linenum => $line) { - $line = trim($line); - if (!$line) { - continue; - } - if ($line[0] == ';') { - continue; - } - if (strtolower(substr($line, 0, 13)) == 'extension_dir') { - $line = trim(substr($line, 13)); - if ($line[0] == '=') { - $x = trim(substr($line, 1)); - $x = explode(';', $x); - $extension_dir = str_replace('"', '', array_shift($x)); - continue; - } - } - if (strtolower(substr($line, 0, 9)) == 'extension') { - $line = trim(substr($line, 9)); - if ($line[0] == '=') { - $x = trim(substr($line, 1)); - $x = explode(';', $x); - $extensions[$linenum] = str_replace('"', '', array_shift($x)); - continue; + + $a = false; + return $a; + } + + function _prependPath($path, $prepend) + { + if (strlen($prepend) > 0) { + if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { + if (preg_match('/^[a-z]:/i', $prepend)) { + $prepend = substr($prepend, 2); + } elseif ($prepend{0} != '\\') { + $prepend = "\\$prepend"; } + $path = substr($path, 0, 2) . $prepend . substr($path, 2); + } else { + $path = $prepend . $path; } - if (strtolower(substr($line, 0, strlen($zend_extension_line))) == - $zend_extension_line) { - $line = trim(substr($line, strlen($zend_extension_line))); - if ($line[0] == '=') { - $x = trim(substr($line, 1)); - $x = explode(';', $x); - $zend_extensions[$linenum] = str_replace('"', '', array_shift($x)); + } + return $path; + } + + /** + * @param string|false installation directory to prepend to all _dir variables, or false to + * disable + */ + function setInstallRoot($root) + { + if (substr($root, -1) == DIRECTORY_SEPARATOR) { + $root = substr($root, 0, -1); + } + $old = $this->_installRoot; + $this->_installRoot = $root; + if (($old != $root) && !$this->_noRegistry) { + foreach (array_keys($this->_registry) as $layer) { + if ($layer == 'ftp' || !isset($this->_registry[$layer])) { continue; } + $this->_registry[$layer] = + &new PEAR_Registry($this->get('php_dir', $layer, 'pear.php.net')); + $this->_registry[$layer]->setConfig($this, false); + $this->_regInitialized[$layer] = false; } } - return array( - 'extensions' => $extensions, - 'zend_extensions' => $zend_extensions, - 'extension_dir' => $extension_dir, - 'all' => $all, - ); } +} + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Dependency2.php 286494 2009-07-29 06:57:11Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ - // {{{ doInstall() +/** + * Required for the PEAR_VALIDATE_* constants + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validate.php'; - function doInstall($command, $options, $params) - { - if (!class_exists('PEAR_PackageFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile.php'; - } +/** + * Dependency check for PEAR packages + * + * This class handles both version 1.0 and 2.0 dependencies + * WARNING: *any* changes to this class must be duplicated in the + * test_PEAR_Dependency2 class found in tests/PEAR_Dependency2/setup.php.inc, + * or unit tests will not actually validate the changes + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Dependency2 +{ + /** + * One of the PEAR_VALIDATE_* states + * @see PEAR_VALIDATE_NORMAL + * @var integer + */ + var $_state; - if (isset($options['installroot']) && isset($options['packagingroot'])) { - return $this->raiseError('ERROR: cannot use both --installroot and --packagingroot'); + /** + * Command-line options to install/upgrade/uninstall commands + * @param array + */ + var $_options; + + /** + * @var OS_Guess + */ + var $_os; + + /** + * @var PEAR_Registry + */ + var $_registry; + + /** + * @var PEAR_Config + */ + var $_config; + + /** + * @var PEAR_DependencyDB + */ + var $_dependencydb; + + /** + * Output of PEAR_Registry::parsedPackageName() + * @var array + */ + var $_currentPackage; + + /** + * @param PEAR_Config + * @param array installation options + * @param array format of PEAR_Registry::parsedPackageName() + * @param int installation state (one of PEAR_VALIDATE_*) + */ + function PEAR_Dependency2(&$config, $installoptions, $package, + $state = PEAR_VALIDATE_INSTALLING) + { + $this->_config = &$config; + if (!class_exists('PEAR_DependencyDB')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/DependencyDB.php'; } - $reg = &$this->config->getRegistry(); - $channel = isset($options['channel']) ? $options['channel'] : $this->config->get('default_channel'); - if (!$reg->channelExists($channel)) { - return $this->raiseError('Channel "' . $channel . '" does not exist'); + if (isset($installoptions['packagingroot'])) { + // make sure depdb is in the right location + $config->setInstallRoot($installoptions['packagingroot']); } - if (empty($this->installer)) { - $this->installer = &$this->getInstaller($this->ui); + $this->_registry = &$config->getRegistry(); + $this->_dependencydb = &PEAR_DependencyDB::singleton($config); + if (isset($installoptions['packagingroot'])) { + $config->setInstallRoot(false); } - if ($command == 'upgrade' || $command == 'upgrade-all') { - // If people run the upgrade command but pass nothing, emulate a upgrade-all - if ($command == 'upgrade' && empty($params)) { - return $this->doUpgradeAll($command, $options, $params); - } - $options['upgrade'] = true; - } else { - $packages = $params; + $this->_options = $installoptions; + $this->_state = $state; + if (!class_exists('OS_Guess')) { + require_once 'phar://install-pear-nozlib.phar/' . 'OS/Guess.php'; } - $instreg = &$reg; // instreg used to check if package is installed - if (isset($options['packagingroot']) && !isset($options['upgrade'])) { - $packrootphp_dir = $this->installer->_prependPath( - $this->config->get('php_dir', null, 'pear.php.net'), - $options['packagingroot']); - $instreg = new PEAR_Registry($packrootphp_dir); // other instreg! + $this->_os = new OS_Guess; + $this->_currentPackage = $package; + } - if ($this->config->get('verbose') > 2) { - $this->ui->outputData('using package root: ' . $options['packagingroot']); - } + function _getExtraString($dep) + { + $extra = ' ('; + if (isset($dep['uri'])) { + return ''; } - $abstractpackages = array(); - $otherpackages = array(); - // parse params - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (isset($dep['recommended'])) { + $extra .= 'recommended version ' . $dep['recommended']; + } else { + if (isset($dep['min'])) { + $extra .= 'version >= ' . $dep['min']; + } - foreach ($params as $param) { - if (strpos($param, 'http://') === 0) { - $otherpackages[] = $param; - continue; + if (isset($dep['max'])) { + if ($extra != ' (') { + $extra .= ', '; + } + $extra .= 'version <= ' . $dep['max']; } - if (strpos($param, 'channel://') === false && @file_exists($param)) { - if (isset($options['force'])) { - $otherpackages[] = $param; - continue; + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); } - $pkg = new PEAR_PackageFile($this->config); - $pf = $pkg->fromAnyFile($param, PEAR_VALIDATE_DOWNLOADING); - if (PEAR::isError($pf)) { - $otherpackages[] = $param; - continue; + if ($extra != ' (') { + $extra .= ', '; } - $exists = $reg->packageExists($pf->getPackage(), $pf->getChannel()); - $pversion = $reg->packageInfo($pf->getPackage(), 'version', $pf->getChannel()); - $version_compare = version_compare($pf->getVersion(), $pversion, '<='); - if ($exists && $version_compare) { - if ($this->config->get('verbose')) { - $this->ui->outputData('Ignoring installed package ' . - $reg->parsedPackageNameToString( - array('package' => $pf->getPackage(), - 'channel' => $pf->getChannel()), true)); + $extra .= 'excluded versions: '; + foreach ($dep['exclude'] as $i => $exclude) { + if ($i) { + $extra .= ', '; } - continue; + $extra .= $exclude; } - $otherpackages[] = $param; - continue; } + } - $e = $reg->parsePackageName($param, $channel); - if (PEAR::isError($e)) { - $otherpackages[] = $param; - } else { - $abstractpackages[] = $e; - } + $extra .= ')'; + if ($extra == ' ()') { + $extra = ''; } - PEAR::staticPopErrorHandling(); - // if there are any local package .tgz or remote static url, we can't - // filter. The filter only works for abstract packages - if (count($abstractpackages) && !isset($options['force'])) { - // when not being forced, only do necessary upgrades/installs - if (isset($options['upgrade'])) { - $abstractpackages = $this->_filterUptodatePackages($abstractpackages, $command); - } else { - $count = count($abstractpackages); - foreach ($abstractpackages as $i => $package) { - if (isset($package['group'])) { - // do not filter out install groups - continue; + return $extra; + } + + /** + * This makes unit-testing a heck of a lot easier + */ + function getPHP_OS() + { + return PHP_OS; + } + + /** + * This makes unit-testing a heck of a lot easier + */ + function getsysname() + { + return $this->_os->getSysname(); + } + + /** + * Specify a dependency on an OS. Use arch for detailed os/processor information + * + * There are two generic OS dependencies that will be the most common, unix and windows. + * Other options are linux, freebsd, darwin (OS X), sunos, irix, hpux, aix + */ + function validateOsDependency($dep) + { + if ($this->_state != PEAR_VALIDATE_INSTALLING && $this->_state != PEAR_VALIDATE_DOWNLOADING) { + return true; + } + + if ($dep['name'] == '*') { + return true; + } + + $not = isset($dep['conflicts']) ? true : false; + switch (strtolower($dep['name'])) { + case 'windows' : + if ($not) { + if (strtolower(substr($this->getPHP_OS(), 0, 3)) == 'win') { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError("Cannot install %s on Windows"); + } + + return $this->warning("warning: Cannot install %s on Windows"); } + } else { + if (strtolower(substr($this->getPHP_OS(), 0, 3)) != 'win') { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError("Can only install %s on Windows"); + } - if ($instreg->packageExists($package['package'], $package['channel'])) { - if ($count > 1) { - if ($this->config->get('verbose')) { - $this->ui->outputData('Ignoring installed package ' . - $reg->parsedPackageNameToString($package, true)); - } - unset($abstractpackages[$i]); - } elseif ($count === 1) { - // Lets try to upgrade it since it's already installed - $options['upgrade'] = true; + return $this->warning("warning: Can only install %s on Windows"); + } + } + break; + case 'unix' : + $unices = array('linux', 'freebsd', 'darwin', 'sunos', 'irix', 'hpux', 'aix'); + if ($not) { + if (in_array($this->getSysname(), $unices)) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError("Cannot install %s on any Unix system"); + } + + return $this->warning( "warning: Cannot install %s on any Unix system"); + } + } else { + if (!in_array($this->getSysname(), $unices)) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError("Can only install %s on a Unix system"); } + + return $this->warning("warning: Can only install %s on a Unix system"); } } - } - $abstractpackages = - array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages); - } elseif (count($abstractpackages)) { - $abstractpackages = - array_map(array($reg, 'parsedPackageNameToString'), $abstractpackages); + break; + default : + if ($not) { + if (strtolower($dep['name']) == strtolower($this->getSysname())) { + if (!isset($this->_options['nodeps']) && + !isset($this->_options['force'])) { + return $this->raiseError('Cannot install %s on ' . $dep['name'] . + ' operating system'); + } + + return $this->warning('warning: Cannot install %s on ' . + $dep['name'] . ' operating system'); + } + } else { + if (strtolower($dep['name']) != strtolower($this->getSysname())) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('Cannot install %s on ' . + $this->getSysname() . + ' operating system, can only install on ' . $dep['name']); + } + + return $this->warning('warning: Cannot install %s on ' . + $this->getSysname() . + ' operating system, can only install on ' . $dep['name']); + } + } + } + return true; + } + + /** + * This makes unit-testing a heck of a lot easier + */ + function matchSignature($pattern) + { + return $this->_os->matchSignature($pattern); + } + + /** + * Specify a complex dependency on an OS/processor/kernel version, + * Use OS for simple operating system dependency. + * + * This is the only dependency that accepts an eregable pattern. The pattern + * will be matched against the php_uname() output parsed by OS_Guess + */ + function validateArchDependency($dep) + { + if ($this->_state != PEAR_VALIDATE_INSTALLING) { + return true; } - $packages = array_merge($abstractpackages, $otherpackages); - if (!count($packages)) { - $c = ''; - if (isset($options['channel'])){ - $c .= ' in channel "' . $options['channel'] . '"'; + $not = isset($dep['conflicts']) ? true : false; + if (!$this->matchSignature($dep['pattern'])) { + if (!$not) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s Architecture dependency failed, does not ' . + 'match "' . $dep['pattern'] . '"'); + } + + return $this->warning('warning: %s Architecture dependency failed, does ' . + 'not match "' . $dep['pattern'] . '"'); } - $this->ui->outputData('Nothing to ' . $command . $c); + return true; } - $this->downloader = &$this->getDownloader($this->ui, $options, $this->config); - $errors = $downloaded = $binaries = array(); - $downloaded = &$this->downloader->download($packages); - if (PEAR::isError($downloaded)) { - return $this->raiseError($downloaded); + if ($not) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s Architecture dependency failed, required "' . + $dep['pattern'] . '"'); + } + + return $this->warning('warning: %s Architecture dependency failed, ' . + 'required "' . $dep['pattern'] . '"'); } - $errors = $this->downloader->getErrorMsgs(); - if (count($errors)) { - $err = array(); - $err['data'] = array(); - foreach ($errors as $error) { - if ($error !== null) { - $err['data'][] = array($error); - } - } + return true; + } - if (!empty($err['data'])) { - $err['headline'] = 'Install Errors'; - $this->ui->outputData($err); - } + /** + * This makes unit-testing a heck of a lot easier + */ + function extension_loaded($name) + { + return extension_loaded($name); + } - if (!count($downloaded)) { - return $this->raiseError("$command failed"); - } + /** + * This makes unit-testing a heck of a lot easier + */ + function phpversion($name = null) + { + if ($name !== null) { + return phpversion($name); } - $data = array( - 'headline' => 'Packages that would be Installed' - ); + return phpversion(); + } - if (isset($options['pretend'])) { - foreach ($downloaded as $package) { - $data['data'][] = array($reg->parsedPackageNameToString($package->getParsedPackage())); - } - $this->ui->outputData($data, 'pretend'); + function validateExtensionDependency($dep, $required = true) + { + if ($this->_state != PEAR_VALIDATE_INSTALLING && + $this->_state != PEAR_VALIDATE_DOWNLOADING) { return true; } - $this->installer->setOptions($options); - $this->installer->sortPackagesForInstall($downloaded); - if (PEAR::isError($err = $this->installer->setDownloadedPackages($downloaded))) { - $this->raiseError($err->getMessage()); - return true; + $loaded = $this->extension_loaded($dep['name']); + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } } - $extrainfo = array(); - $binaries = array(); - foreach ($downloaded as $param) { - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $info = $this->installer->install($param, $options); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($info)) { - $oldinfo = $info; - $pkg = &$param->getPackageFile(); - if ($info->getCode() != PEAR_INSTALLER_NOBINARY) { - if (!($info = $pkg->installBinary($this->installer))) { - $this->ui->outputData('ERROR: ' .$oldinfo->getMessage()); - continue; + if (!isset($dep['min']) && !isset($dep['max']) && + !isset($dep['recommended']) && !isset($dep['exclude']) + ) { + if ($loaded) { + if (isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra); } - // we just installed a different package than requested, - // let's change the param and info so that the rest of this works - $param = $info[0]; - $info = $info[1]; + return $this->warning('warning: %s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra); } - } - if (!is_array($info)) { - return $this->raiseError("$command failed"); + return true; } - if ($param->getPackageType() == 'extsrc' || - $param->getPackageType() == 'extbin' || - $param->getPackageType() == 'zendextsrc' || - $param->getPackageType() == 'zendextbin') { - $pkg = &$param->getPackageFile(); - if ($instbin = $pkg->getInstalledBinary()) { - $instpkg = &$instreg->getPackage($instbin, $pkg->getChannel()); - } else { - $instpkg = &$instreg->getPackage($pkg->getPackage(), $pkg->getChannel()); - } - - foreach ($instpkg->getFilelist() as $name => $atts) { - $pinfo = pathinfo($atts['installed_as']); - if (!isset($pinfo['extension']) || - in_array($pinfo['extension'], array('c', 'h'))) { - continue; // make sure we don't match php_blah.h - } - - if ((strpos($pinfo['basename'], 'php_') === 0 && - $pinfo['extension'] == 'dll') || - // most unices - $pinfo['extension'] == 'so' || - // hp-ux - $pinfo['extension'] == 'sl') { - $binaries[] = array($atts['installed_as'], $pinfo); - break; - } - } - - if (count($binaries)) { - foreach ($binaries as $pinfo) { - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $ret = $this->enableExtension(array($pinfo[0]), $param->getPackageType()); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($ret)) { - $extrainfo[] = $ret->getMessage(); - if ($param->getPackageType() == 'extsrc' || - $param->getPackageType() == 'extbin') { - $exttype = 'extension'; - } else { - ob_start(); - phpinfo(INFO_GENERAL); - $info = ob_get_contents(); - ob_end_clean(); - $debug = function_exists('leak') ? '_debug' : ''; - $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; - $exttype = 'zend_extension' . $debug . $ts; - } - $extrainfo[] = 'You should add "' . $exttype . '=' . - $pinfo[1]['basename'] . '" to php.ini'; - } else { - $extrainfo[] = 'Extension ' . $instpkg->getProvidesExtension() . - ' enabled in php.ini'; - } - } - } + if (isset($dep['conflicts'])) { + return true; } - if ($this->config->get('verbose') > 0) { - $chan = $param->getChannel(); - $label = $reg->parsedPackageNameToString( - array( - 'channel' => $chan, - 'package' => $param->getPackage(), - 'version' => $param->getVersion(), - )); - $out = array('data' => "$command ok: $label"); - if (isset($info['release_warnings'])) { - $out['release_warnings'] = $info['release_warnings']; + if ($required) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP extension "' . + $dep['name'] . '"' . $extra); } - $this->ui->outputData($out, $command); - if (!isset($options['register-only']) && !isset($options['offline'])) { - if ($this->config->isDefinedLayer('ftp')) { - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $info = $this->installer->ftpInstall($param); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($info)) { - $this->ui->outputData($info->getMessage()); - $this->ui->outputData("remote install failed: $label"); - } else { - $this->ui->outputData("remote install ok: $label"); - } - } - } + return $this->warning('warning: %s requires PHP extension "' . + $dep['name'] . '"' . $extra); } - $deps = $param->getDeps(); - if ($deps) { - if (isset($deps['group'])) { - $groups = $deps['group']; - if (!isset($groups[0])) { - $groups = array($groups); - } - - foreach ($groups as $group) { - if ($group['attribs']['name'] == 'default') { - // default group is always installed, unless the user - // explicitly chooses to install another group - continue; - } - $extrainfo[] = $param->getPackage() . ': Optional feature ' . - $group['attribs']['name'] . ' available (' . - $group['attribs']['hint'] . ')'; - } + return $this->warning('%s can optionally use PHP extension "' . + $dep['name'] . '"' . $extra); + } - $extrainfo[] = $param->getPackage() . - ': To install optional features use "pear install ' . - $reg->parsedPackageNameToString( - array('package' => $param->getPackage(), - 'channel' => $param->getChannel()), true) . - '#featurename"'; - } + if (!$loaded) { + if (isset($dep['conflicts'])) { + return true; } - $pkg = &$instreg->getPackage($param->getPackage(), $param->getChannel()); - // $pkg may be NULL if install is a 'fake' install via --packagingroot - if (is_object($pkg)) { - $pkg->setConfig($this->config); - if ($list = $pkg->listPostinstallScripts()) { - $pn = $reg->parsedPackageNameToString(array('channel' => - $param->getChannel(), 'package' => $param->getPackage()), true); - $extrainfo[] = $pn . ' has post-install scripts:'; - foreach ($list as $file) { - $extrainfo[] = $file; - } - $extrainfo[] = $param->getPackage() . - ': Use "pear run-scripts ' . $pn . '" to finish setup.'; - $extrainfo[] = 'DO NOT RUN SCRIPTS FROM UNTRUSTED SOURCES'; - } + if (!$required) { + return $this->warning('%s can optionally use PHP extension "' . + $dep['name'] . '"' . $extra); } - } - if (count($extrainfo)) { - foreach ($extrainfo as $info) { - $this->ui->outputData($info); + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP extension "' . $dep['name'] . + '"' . $extra); } - } - return true; - } + return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . + '"' . $extra); + } - // }}} - // {{{ doUpgradeAll() + $version = (string) $this->phpversion($dep['name']); + if (empty($version)) { + $version = '0'; + } - function doUpgradeAll($command, $options, $params) - { - $reg = &$this->config->getRegistry(); - $upgrade = array(); + $fail = false; + if (isset($dep['min']) && !version_compare($version, $dep['min'], '>=')) { + $fail = true; + } - if (isset($options['channel'])) { - $channels = array($options['channel']); - } else { - $channels = $reg->listChannels(); + if (isset($dep['max']) && !version_compare($version, $dep['max'], '<=')) { + $fail = true; } - foreach ($channels as $channel) { - if ($channel == '__uri') { - continue; + if ($fail && !isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP extension "' . $dep['name'] . + '"' . $extra . ', installed version is ' . $version); } - // parse name with channel - foreach ($reg->listPackages($channel) as $name) { - $upgrade[] = $reg->parsedPackageNameToString(array( - 'channel' => $channel, - 'package' => $name - )); + return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . + '"' . $extra . ', installed version is ' . $version); + } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra . ', installed version is ' . $version); } - } - $err = $this->doInstall($command, $options, $upgrade); - if (PEAR::isError($err)) { - $this->ui->outputData($err->getMessage(), $command); + return $this->warning('warning: %s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra . ', installed version is ' . $version); } - } - // }}} - // {{{ doUninstall() + if (isset($dep['exclude'])) { + foreach ($dep['exclude'] as $exclude) { + if (version_compare($version, $exclude, '==')) { + if (isset($dep['conflicts'])) { + continue; + } - function doUninstall($command, $options, $params) - { - if (count($params) < 1) { - return $this->raiseError("Please supply the package(s) you want to uninstall"); - } + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s is not compatible with PHP extension "' . + $dep['name'] . '" version ' . + $exclude); + } - if (empty($this->installer)) { - $this->installer = &$this->getInstaller($this->ui); - } + return $this->warning('warning: %s is not compatible with PHP extension "' . + $dep['name'] . '" version ' . + $exclude); + } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra . ', installed version is ' . $version); + } - if (isset($options['remoteconfig'])) { - $e = $this->config->readFTPConfigFile($options['remoteconfig']); - if (!PEAR::isError($e)) { - $this->installer->setConfig($this->config); + return $this->warning('warning: %s conflicts with PHP extension "' . + $dep['name'] . '"' . $extra . ', installed version is ' . $version); + } } } - $reg = &$this->config->getRegistry(); - $newparams = array(); - $binaries = array(); - $badparams = array(); - foreach ($params as $pkg) { - $channel = $this->config->get('default_channel'); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $parsed = $reg->parsePackageName($pkg, $channel); - PEAR::staticPopErrorHandling(); - if (!$parsed || PEAR::isError($parsed)) { - $badparams[] = $pkg; - continue; - } - $package = $parsed['package']; - $channel = $parsed['channel']; - $info = &$reg->getPackage($package, $channel); - if ($info === null && - ($channel == 'pear.php.net' || $channel == 'pecl.php.net')) { - // make sure this isn't a package that has flipped from pear to pecl but - // used a package.xml 1.0 - $testc = ($channel == 'pear.php.net') ? 'pecl.php.net' : 'pear.php.net'; - $info = &$reg->getPackage($package, $testc); - if ($info !== null) { - $channel = $testc; - } - } - if ($info === null) { - $badparams[] = $pkg; - } else { - $newparams[] = &$info; - // check for binary packages (this is an alias for those packages if so) - if ($installedbinary = $info->getInstalledBinary()) { - $this->ui->log('adding binary package ' . - $reg->parsedPackageNameToString(array('channel' => $channel, - 'package' => $installedbinary), true)); - $newparams[] = &$reg->getPackage($installedbinary, $channel); - } - // add the contents of a dependency group to the list of installed packages - if (isset($parsed['group'])) { - $group = $info->getDependencyGroup($parsed['group']); - if ($group) { - $installed = $reg->getInstalledGroup($group); - if ($installed) { - foreach ($installed as $i => $p) { - $newparams[] = &$installed[$i]; - } - } - } - } + if (isset($dep['recommended'])) { + if (version_compare($version, $dep['recommended'], '==')) { + return true; } - } - $err = $this->installer->sortPackagesForUninstall($newparams); - if (PEAR::isError($err)) { - $this->ui->outputData($err->getMessage(), $command); - return true; - } - $params = $newparams; - // twist this to use it to check on whether dependent packages are also being uninstalled - // for circular dependencies like subpackages - $this->installer->setUninstallPackages($newparams); - $params = array_merge($params, $badparams); - $binaries = array(); - foreach ($params as $pkg) { - $this->installer->pushErrorHandling(PEAR_ERROR_RETURN); - if ($err = $this->installer->uninstall($pkg, $options)) { - $this->installer->popErrorHandling(); - if (PEAR::isError($err)) { - $this->ui->outputData($err->getMessage(), $command); - continue; - } - if ($pkg->getPackageType() == 'extsrc' || - $pkg->getPackageType() == 'extbin' || - $pkg->getPackageType() == 'zendextsrc' || - $pkg->getPackageType() == 'zendextbin') { - if ($instbin = $pkg->getInstalledBinary()) { - continue; // this will be uninstalled later - } - foreach ($pkg->getFilelist() as $name => $atts) { - $pinfo = pathinfo($atts['installed_as']); - if (!isset($pinfo['extension']) || - in_array($pinfo['extension'], array('c', 'h'))) { - continue; // make sure we don't match php_blah.h - } - if ((strpos($pinfo['basename'], 'php_') === 0 && - $pinfo['extension'] == 'dll') || - // most unices - $pinfo['extension'] == 'so' || - // hp-ux - $pinfo['extension'] == 'sl') { - $binaries[] = array($atts['installed_as'], $pinfo); - break; - } - } - if (count($binaries)) { - foreach ($binaries as $pinfo) { - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $ret = $this->disableExtension(array($pinfo[0]), $pkg->getPackageType()); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($ret)) { - $extrainfo[] = $ret->getMessage(); - if ($pkg->getPackageType() == 'extsrc' || - $pkg->getPackageType() == 'extbin') { - $exttype = 'extension'; - } else { - ob_start(); - phpinfo(INFO_GENERAL); - $info = ob_get_contents(); - ob_end_clean(); - $debug = function_exists('leak') ? '_debug' : ''; - $ts = preg_match('Thread Safety.+enabled', $info) ? '_ts' : ''; - $exttype = 'zend_extension' . $debug . $ts; - } - $this->ui->outputData('Unable to remove "' . $exttype . '=' . - $pinfo[1]['basename'] . '" from php.ini', $command); - } else { - $this->ui->outputData('Extension ' . $pkg->getProvidesExtension() . - ' disabled in php.ini', $command); - } - } - } - } - $savepkg = $pkg; - if ($this->config->get('verbose') > 0) { - if (is_object($pkg)) { - $pkg = $reg->parsedPackageNameToString($pkg); - } - $this->ui->outputData("uninstall ok: $pkg", $command); - } - if (!isset($options['offline']) && is_object($savepkg) && - defined('PEAR_REMOTEINSTALL_OK')) { - if ($this->config->isDefinedLayer('ftp')) { - $this->installer->pushErrorHandling(PEAR_ERROR_RETURN); - $info = $this->installer->ftpUninstall($savepkg); - $this->installer->popErrorHandling(); - if (PEAR::isError($info)) { - $this->ui->outputData($info->getMessage()); - $this->ui->outputData("remote uninstall failed: $pkg"); - } else { - $this->ui->outputData("remote uninstall ok: $pkg"); - } - } - } - } else { - $this->installer->popErrorHandling(); - if (!is_object($pkg)) { - return $this->raiseError("uninstall failed: $pkg"); - } - $pkg = $reg->parsedPackageNameToString($pkg); + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s dependency: PHP extension ' . $dep['name'] . + ' version "' . $version . '"' . + ' is not the recommended version "' . $dep['recommended'] . + '", but may be compatible, use --force to install'); } + + return $this->warning('warning: %s dependency: PHP extension ' . + $dep['name'] . ' version "' . $version . '"' . + ' is not the recommended version "' . $dep['recommended'].'"'); } return true; } - // }}} - - - // }}} - // {{{ doBundle() - /* - (cox) It just downloads and untars the package, does not do - any check that the PEAR_Installer::_installFile() does. - */ - - function doBundle($command, $options, $params) + function validatePhpDependency($dep) { - $opts = array( - 'force' => true, - 'nodeps' => true, - 'soft' => true, - 'downloadonly' => true - ); - $downloader = &$this->getDownloader($this->ui, $opts, $this->config); - $reg = &$this->config->getRegistry(); - if (count($params) < 1) { - return $this->raiseError("Please supply the package you want to bundle"); + if ($this->_state != PEAR_VALIDATE_INSTALLING && + $this->_state != PEAR_VALIDATE_DOWNLOADING) { + return true; } - if (isset($options['destination'])) { - if (!is_dir($options['destination'])) { - System::mkdir('-p ' . $options['destination']); + $version = $this->phpversion(); + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); } - $dest = realpath($options['destination']); - } else { - $pwd = getcwd(); - $dir = $pwd . DIRECTORY_SEPARATOR . 'ext'; - $dest = is_dir($dir) ? $dir : $pwd; - } - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $err = $downloader->setDownloadDir($dest); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($err)) { - return PEAR::raiseError('download directory "' . $dest . - '" is not writeable.'); } - $result = &$downloader->download(array($params[0])); - if (PEAR::isError($result)) { - return $result; + + if (isset($dep['min'])) { + if (!version_compare($version, $dep['min'], '>=')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP' . + $extra . ', installed version is ' . $version); + } + + return $this->warning('warning: %s requires PHP' . + $extra . ', installed version is ' . $version); + } } - if (!isset($result[0])) { - return $this->raiseError('unable to unpack ' . $params[0]); + + if (isset($dep['max'])) { + if (!version_compare($version, $dep['max'], '<=')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PHP' . + $extra . ', installed version is ' . $version); + } + + return $this->warning('warning: %s requires PHP' . + $extra . ', installed version is ' . $version); + } } - $pkgfile = &$result[0]->getPackageFile(); - $pkgname = $pkgfile->getName(); - $pkgversion = $pkgfile->getVersion(); - // Unpacking ------------------------------------------------- - $dest .= DIRECTORY_SEPARATOR . $pkgname; - $orig = $pkgname . '-' . $pkgversion; + if (isset($dep['exclude'])) { + foreach ($dep['exclude'] as $exclude) { + if (version_compare($version, $exclude, '==')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s is not compatible with PHP version ' . + $exclude); + } - $tar = &new Archive_Tar($pkgfile->getArchiveFile()); - if (!$tar->extractModify($dest, $orig)) { - return $this->raiseError('unable to unpack ' . $pkgfile->getArchiveFile()); + return $this->warning( + 'warning: %s is not compatible with PHP version ' . + $exclude); + } + } } - $this->ui->outputData("Package ready at '$dest'"); - // }}} + + return true; } - // }}} + /** + * This makes unit-testing a heck of a lot easier + */ + function getPEARVersion() + { + return '1.9.0'; + } - function doRunScripts($command, $options, $params) + function validatePearinstallerDependency($dep) { - if (!isset($params[0])) { - return $this->raiseError('run-scripts expects 1 parameter: a package name'); + $pearversion = $this->getPEARVersion(); + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } } - $reg = &$this->config->getRegistry(); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $parsed = $reg->parsePackageName($params[0], $this->config->get('default_channel')); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($parsed)) { - return $this->raiseError($parsed); + if (version_compare($pearversion, $dep['min'], '<')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PEAR Installer' . $extra . + ', installed version is ' . $pearversion); + } + + return $this->warning('warning: %s requires PEAR Installer' . $extra . + ', installed version is ' . $pearversion); } - $package = &$reg->getPackage($parsed['package'], $parsed['channel']); - if (!is_object($package)) { - return $this->raiseError('Could not retrieve package "' . $params[0] . '" from registry'); + if (isset($dep['max'])) { + if (version_compare($pearversion, $dep['max'], '>')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires PEAR Installer' . $extra . + ', installed version is ' . $pearversion); + } + + return $this->warning('warning: %s requires PEAR Installer' . $extra . + ', installed version is ' . $pearversion); + } + } + + if (isset($dep['exclude'])) { + if (!isset($dep['exclude'][0])) { + $dep['exclude'] = array($dep['exclude']); + } + + foreach ($dep['exclude'] as $exclude) { + if (version_compare($exclude, $pearversion, '==')) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s is not compatible with PEAR Installer ' . + 'version ' . $exclude); + } + + return $this->warning('warning: %s is not compatible with PEAR ' . + 'Installer version ' . $exclude); + } + } } - $package->setConfig($this->config); - $package->runPostinstallScripts(); - $this->ui->outputData('Install scripts complete', $command); return true; } + function validateSubpackageDependency($dep, $required, $params) + { + return $this->validatePackageDependency($dep, $required, $params); + } + /** - * Given a list of packages, filter out those ones that are already up to date - * - * @param $packages: packages, in parsed array format ! - * @return list of packages that can be upgraded + * @param array dependency information (2.0 format) + * @param boolean whether this is a required dependency + * @param array a list of downloaded packages to be installed, if any + * @param boolean if true, then deps on pear.php.net that fail will also check + * against pecl.php.net packages to accomodate extensions that have + * moved to pecl.php.net from pear.php.net */ - function _filterUptodatePackages($packages, $command) + function validatePackageDependency($dep, $required, $params, $depv1 = false) { - $reg = &$this->config->getRegistry(); - $latestReleases = array(); + if ($this->_state != PEAR_VALIDATE_INSTALLING && + $this->_state != PEAR_VALIDATE_DOWNLOADING) { + return true; + } - $ret = array(); - foreach ($packages as $package) { - if (isset($package['group'])) { - $ret[] = $package; - continue; + if (isset($dep['providesextension'])) { + if ($this->extension_loaded($dep['providesextension'])) { + $save = $dep; + $subdep = $dep; + $subdep['name'] = $subdep['providesextension']; + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $ret = $this->validateExtensionDependency($subdep, $required); + PEAR::popErrorHandling(); + if (!PEAR::isError($ret)) { + return true; + } } + } - $channel = $package['channel']; - $name = $package['package']; - if (!$reg->packageExists($name, $channel)) { - $ret[] = $package; - continue; + if ($this->_state == PEAR_VALIDATE_INSTALLING) { + return $this->_validatePackageInstall($dep, $required, $depv1); + } + + if ($this->_state == PEAR_VALIDATE_DOWNLOADING) { + return $this->_validatePackageDownload($dep, $required, $params, $depv1); + } + } + + function _validatePackageDownload($dep, $required, $params, $depv1 = false) + { + $dep['package'] = $dep['name']; + if (isset($dep['uri'])) { + $dep['channel'] = '__uri'; + } + + $depname = $this->_registry->parsedPackageNameToString($dep, true); + $found = false; + foreach ($params as $param) { + if ($param->isEqual( + array('package' => $dep['name'], + 'channel' => $dep['channel']))) { + $found = true; + break; } - if (!isset($latestReleases[$channel])) { - // fill in cache for this channel - $chan = &$reg->getChannel($channel); - if (PEAR::isError($chan)) { - return $this->raiseError($chan); + if ($depv1 && $dep['channel'] == 'pear.php.net') { + if ($param->isEqual( + array('package' => $dep['name'], + 'channel' => 'pecl.php.net'))) { + $found = true; + break; } + } + } - $preferred_mirror = $this->config->get('preferred_mirror', null, $channel); - if ($chan->supportsREST($preferred_mirror) && - $base = $chan->getBaseURL('REST1.0', $preferred_mirror)) - { - $dorest = true; + if (!$found && isset($dep['providesextension'])) { + foreach ($params as $param) { + if ($param->isExtension($dep['providesextension'])) { + $found = true; + break; } + } + } - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - if (!isset($package['state'])) { - $state = $this->config->get('preferred_state', null, $channel); + if ($found) { + $version = $param->getVersion(); + $installed = false; + $downloaded = true; + } else { + if ($this->_registry->packageExists($dep['name'], $dep['channel'])) { + $installed = true; + $downloaded = false; + $version = $this->_registry->packageinfo($dep['name'], 'version', + $dep['channel']); + } else { + if ($dep['channel'] == 'pecl.php.net' && $this->_registry->packageExists($dep['name'], + 'pear.php.net')) { + $installed = true; + $downloaded = false; + $version = $this->_registry->packageinfo($dep['name'], 'version', + 'pear.php.net'); } else { - $state = $package['state']; + $version = 'not installed or downloaded'; + $installed = false; + $downloaded = false; } + } + } - if ($dorest) { - $rest = &$this->config->getREST('1.0', array()); - $installed = array_flip($reg->listPackages($channel)); + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude']) && !is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + + if (!isset($dep['min']) && !isset($dep['max']) && + !isset($dep['recommended']) && !isset($dep['exclude']) + ) { + if ($installed || $downloaded) { + $installed = $installed ? 'installed' : 'downloaded'; + if (isset($dep['conflicts'])) { + $rest = ''; + if ($version) { + $rest = ", $installed version is " . $version; + } + + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . $rest); + } - $latest = $rest->listLatestUpgrades($base, $state, $installed, $channel, $reg); + return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . $rest); } - PEAR::staticPopErrorHandling(); - if (PEAR::isError($latest)) { - $this->ui->outputData('Error getting channel info from ' . $channel . - ': ' . $latest->getMessage()); - continue; + return true; + } + + if (isset($dep['conflicts'])) { + return true; + } + + if ($required) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires package "' . $depname . '"' . $extra); } - $latestReleases[$channel] = array_change_key_case($latest); + return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); } - // check package for latest release - $name_lower = strtolower($name); - if (isset($latestReleases[$channel][$name_lower])) { - // if not set, up to date - $inst_version = $reg->packageInfo($name, 'version', $channel); - $channel_version = $latestReleases[$channel][$name_lower]['version']; - if (version_compare($channel_version, $inst_version, 'le')) { - // installed version is up-to-date - continue; + return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); + } + + if (!$installed && !$downloaded) { + if (isset($dep['conflicts'])) { + return true; + } + + if ($required) { + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires package "' . $depname . '"' . $extra); } - // maintain BC - if ($command == 'upgrade-all') { - $this->ui->outputData(array('data' => 'Will upgrade ' . - $reg->parsedPackageNameToString($package)), $command); + return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); + } + + return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); + } + + $fail = false; + if (isset($dep['min']) && version_compare($version, $dep['min'], '<')) { + $fail = true; + } + + if (isset($dep['max']) && version_compare($version, $dep['max'], '>')) { + $fail = true; + } + + if ($fail && !isset($dep['conflicts'])) { + $installed = $installed ? 'installed' : 'downloaded'; + $dep['package'] = $dep['name']; + $dep = $this->_registry->parsedPackageNameToString($dep, true); + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s requires package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } + + return $this->warning('warning: %s requires package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && + isset($dep['conflicts']) && !isset($dep['exclude'])) { + $installed = $installed ? 'installed' : 'downloaded'; + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . + ", $installed version is " . $version); + } + + return $this->warning('warning: %s conflicts with package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } + + if (isset($dep['exclude'])) { + $installed = $installed ? 'installed' : 'downloaded'; + foreach ($dep['exclude'] as $exclude) { + if (version_compare($version, $exclude, '==') && !isset($dep['conflicts'])) { + if (!isset($this->_options['nodeps']) && + !isset($this->_options['force']) + ) { + return $this->raiseError('%s is not compatible with ' . + $installed . ' package "' . + $depname . '" version ' . + $exclude); + } + + return $this->warning('warning: %s is not compatible with ' . + $installed . ' package "' . + $depname . '" version ' . + $exclude); + } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { + $installed = $installed ? 'installed' : 'downloaded'; + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('%s conflicts with package "' . $depname . '"' . + $extra . ", $installed version is " . $version); + } + + return $this->warning('warning: %s conflicts with package "' . $depname . '"' . + $extra . ", $installed version is " . $version); } - $ret[] = $package; } } - return $ret; - } -} - - Install Package - doInstall - i - - - f - will overwrite newer installed packages - - - l - do not check for recommended dependency version - - - n - ignore dependencies, install anyway - - - r - do not install files, only register the package as installed - - - s - soft install, fail silently, or upgrade if already installed - - - B - don't build C extensions - - - Z - request uncompressed files when downloading - - - R - root directory used when installing files (ala PHP's INSTALL_ROOT), use packagingroot for RPM - DIR - - - P - root directory used when packaging files, like RPM packaging - DIR - - - - force install even if there were errors - - - a - install all required and optional dependencies - - - o - install all required dependencies - - - O - do not attempt to download any urls or contact channels - - - p - Only list the packages that would be downloaded - - - [channel/]<package> ... -Installs one or more PEAR packages. You can specify a package to -install in four ways: + if (isset($dep['recommended'])) { + $installed = $installed ? 'installed' : 'downloaded'; + if (version_compare($version, $dep['recommended'], '==')) { + return true; + } -"Package-1.0.tgz" : installs from a local file + if (!$found && $installed) { + $param = $this->_registry->getPackage($dep['name'], $dep['channel']); + } + + if ($param) { + $found = false; + foreach ($params as $parent) { + if ($parent->isEqual($this->_currentPackage)) { + $found = true; + break; + } + } + + if ($found) { + if ($param->isCompatible($parent)) { + return true; + } + } else { // this is for validPackage() calls + $parent = $this->_registry->getPackage($this->_currentPackage['package'], + $this->_currentPackage['channel']); + if ($parent !== null && $param->isCompatible($parent)) { + return true; + } + } + } -"http://example.com/Package-1.0.tgz" : installs from -anywhere on the net. + if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) && + !isset($this->_options['loose']) + ) { + return $this->raiseError('%s dependency package "' . $depname . + '" ' . $installed . ' version ' . $version . + ' is not the recommended version ' . $dep['recommended'] . + ', but may be compatible, use --force to install'); + } -"package.xml" : installs the package described in -package.xml. Useful for testing, or for wrapping a PEAR package in -another package manager such as RPM. + return $this->warning('warning: %s dependency package "' . $depname . + '" ' . $installed . ' version ' . $version . + ' is not the recommended version ' . $dep['recommended']); + } -"Package[-version/state][.tar]" : queries your default channel's server -({config master_server}) and downloads the newest package with -the preferred quality/state ({config preferred_state}). + return true; + } -To retrieve Package version 1.1, use "Package-1.1," to retrieve -Package state beta, use "Package-beta." To retrieve an uncompressed -file, append .tar (make sure there is no file by the same name first) + function _validatePackageInstall($dep, $required, $depv1 = false) + { + return $this->_validatePackageDownload($dep, $required, array(), $depv1); + } -To download a package from another channel, prefix with the channel name like -"channel/Package" + /** + * Verify that uninstalling packages passed in to command line is OK. + * + * @param PEAR_Installer $dl + * @return PEAR_Error|true + */ + function validatePackageUninstall(&$dl) + { + if (PEAR::isError($this->_dependencydb)) { + return $this->_dependencydb; + } -More than one package may be specified at once. It is ok to mix these -four ways of specifying packages. - - - - Upgrade Package - doInstall - up - - - c - upgrade packages from a specific channel - CHAN - - - f - overwrite newer installed packages - - - l - do not check for recommended dependency version - - - n - ignore dependencies, upgrade anyway - - - r - do not install files, only register the package as upgraded - - - B - don't build C extensions - - - Z - request uncompressed files when downloading - - - R - root directory used when installing files (ala PHP's INSTALL_ROOT) - DIR - - - - force install even if there were errors - - - a - install all required and optional dependencies - - - o - install all required dependencies - - - O - do not attempt to download any urls or contact channels - - - p - Only list the packages that would be downloaded - - - <package> ... -Upgrades one or more PEAR packages. See documentation for the -"install" command for ways to specify a package. + $params = array(); + // construct an array of "downloaded" packages to fool the package dependency checker + // into using these to validate uninstalls of circular dependencies + $downloaded = &$dl->getUninstallPackages(); + foreach ($downloaded as $i => $pf) { + if (!class_exists('PEAR_Downloader_Package')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Downloader/Package.php'; + } + $dp = &new PEAR_Downloader_Package($dl); + $dp->setPackageFile($downloaded[$i]); + $params[$i] = &$dp; + } -When upgrading, your package will be updated if the provided new -package has a higher version number (use the -f option if you need to -upgrade anyway). + // check cache + $memyselfandI = strtolower($this->_currentPackage['channel']) . '/' . + strtolower($this->_currentPackage['package']); + if (isset($dl->___uninstall_package_cache)) { + $badpackages = $dl->___uninstall_package_cache; + if (isset($badpackages[$memyselfandI]['warnings'])) { + foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { + $dl->log(0, $warning[0]); + } + } -More than one package may be specified at once. - - - - Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters] - doUpgradeAll - ua - - - c - upgrade packages from a specific channel - CHAN - - - n - ignore dependencies, upgrade anyway - - - r - do not install files, only register the package as upgraded - - - B - don't build C extensions - - - Z - request uncompressed files when downloading - - - R - root directory used when installing files (ala PHP's INSTALL_ROOT), use packagingroot for RPM - DIR - - - - force install even if there were errors - - - - do not check for recommended dependency version - - - -WARNING: This function is deprecated in favor of using the upgrade command with no params + if (isset($badpackages[$memyselfandI]['errors'])) { + foreach ($badpackages[$memyselfandI]['errors'] as $error) { + if (is_array($error)) { + $dl->log(0, $error[0]); + } else { + $dl->log(0, $error->getMessage()); + } + } -Upgrades all packages that have a newer release available. Upgrades are -done only if there is a release available of the state specified in -"preferred_state" (currently {config preferred_state}), or a state considered -more stable. - - - - Un-install Package - doUninstall - un - - - n - ignore dependencies, uninstall anyway - - - r - do not remove files, only register the packages as not installed - - - R - root directory used when installing files (ala PHP's INSTALL_ROOT) - DIR - - - f - force install even if there were errors - - - O - do not attempt to uninstall remotely - - - [channel/]<package> ... -Uninstalls one or more PEAR packages. More than one package may be -specified at once. Prefix with channel name to uninstall from a -channel not in your default channel ({config default_channel}) - - - - Unpacks a Pecl Package - doBundle - bun - - - d - Optional destination directory for unpacking (defaults to current path or "ext" if exists) - DIR - - - - Force the unpacking even if there were errors in the package - - - <package> -Unpacks a Pecl Package into the selected location. It will download the -package if needed. - - - - Run Post-Install Scripts bundled with a package - doRunScripts - rs - - <package> -Run post-installation scripts in package <package>, if any exist. - - - - * @author Tomas V. V. Cox - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.168 2009/03/27 19:35:47 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1.0 - * @deprecated File deprecated since Release 1.4.0a1 - */ + if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { + return $this->warning( + 'warning: %s should not be uninstalled, other installed packages depend ' . + 'on this package'); + } -/** - * Include error handling - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; + return $this->raiseError( + '%s cannot be uninstalled, other installed packages depend on this package'); + } -/** - * PEAR_Common error when an invalid PHP file is passed to PEAR_Common::analyzeSourceCode() - */ -define('PEAR_COMMON_ERROR_INVALIDPHP', 1); -define('_PEAR_COMMON_PACKAGE_NAME_PREG', '[A-Za-z][a-zA-Z0-9_]+'); -define('PEAR_COMMON_PACKAGE_NAME_PREG', '/^' . _PEAR_COMMON_PACKAGE_NAME_PREG . '\\z/'); + return true; + } -// this should allow: 1, 1.0, 1.0RC1, 1.0dev, 1.0dev123234234234, 1.0a1, 1.0b1, 1.0pl1 -define('_PEAR_COMMON_PACKAGE_VERSION_PREG', '\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?'); -define('PEAR_COMMON_PACKAGE_VERSION_PREG', '/^' . _PEAR_COMMON_PACKAGE_VERSION_PREG . '\\z/i'); + // first, list the immediate parents of each package to be uninstalled + $perpackagelist = array(); + $allparents = array(); + foreach ($params as $i => $param) { + $a = array( + 'channel' => strtolower($param->getChannel()), + 'package' => strtolower($param->getPackage()) + ); -// XXX far from perfect :-) -define('_PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '(' . _PEAR_COMMON_PACKAGE_NAME_PREG . - ')(-([.0-9a-zA-Z]+))?'); -define('PEAR_COMMON_PACKAGE_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_PACKAGE_DOWNLOAD_PREG . - '\\z/'); + $deps = $this->_dependencydb->getDependentPackages($a); + if ($deps) { + foreach ($deps as $d) { + $pardeps = $this->_dependencydb->getDependencies($d); + foreach ($pardeps as $dep) { + if (strtolower($dep['dep']['channel']) == $a['channel'] && + strtolower($dep['dep']['name']) == $a['package']) { + if (!isset($perpackagelist[$a['channel'] . '/' . $a['package']])) { + $perpackagelist[$a['channel'] . '/' . $a['package']] = array(); + } + $perpackagelist[$a['channel'] . '/' . $a['package']][] + = array($d['channel'] . '/' . $d['package'], $dep); + if (!isset($allparents[$d['channel'] . '/' . $d['package']])) { + $allparents[$d['channel'] . '/' . $d['package']] = array(); + } + if (!isset($allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']])) { + $allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']] = array(); + } + $allparents[$d['channel'] . '/' . $d['package']] + [$a['channel'] . '/' . $a['package']][] + = array($d, $dep); + } + } + } + } + } -define('_PEAR_CHANNELS_NAME_PREG', '[A-Za-z][a-zA-Z0-9\.]+'); -define('PEAR_CHANNELS_NAME_PREG', '/^' . _PEAR_CHANNELS_NAME_PREG . '\\z/'); + // next, remove any packages from the parents list that are not installed + $remove = array(); + foreach ($allparents as $parent => $d1) { + foreach ($d1 as $d) { + if ($this->_registry->packageExists($d[0][0]['package'], $d[0][0]['channel'])) { + continue; + } + $remove[$parent] = true; + } + } -// this should allow any dns or IP address, plus a path - NO UNDERSCORES ALLOWED -define('_PEAR_CHANNELS_SERVER_PREG', '[a-zA-Z0-9\-]+(?:\.[a-zA-Z0-9\-]+)*(\/[a-zA-Z0-9\-]+)*'); -define('PEAR_CHANNELS_SERVER_PREG', '/^' . _PEAR_CHANNELS_SERVER_PREG . '\\z/i'); + // next remove any packages from the parents list that are not passed in for + // uninstallation + foreach ($allparents as $parent => $d1) { + foreach ($d1 as $d) { + foreach ($params as $param) { + if (strtolower($param->getChannel()) == $d[0][0]['channel'] && + strtolower($param->getPackage()) == $d[0][0]['package']) { + // found it + continue 3; + } + } + $remove[$parent] = true; + } + } -define('_PEAR_CHANNELS_PACKAGE_PREG', '(' ._PEAR_CHANNELS_SERVER_PREG . ')\/(' - . _PEAR_COMMON_PACKAGE_NAME_PREG . ')'); -define('PEAR_CHANNELS_PACKAGE_PREG', '/^' . _PEAR_CHANNELS_PACKAGE_PREG . '\\z/i'); + // remove all packages whose dependencies fail + // save which ones failed for error reporting + $badchildren = array(); + do { + $fail = false; + foreach ($remove as $package => $unused) { + if (!isset($allparents[$package])) { + continue; + } -define('_PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '(' . _PEAR_CHANNELS_NAME_PREG . ')::(' - . _PEAR_COMMON_PACKAGE_NAME_PREG . ')(-([.0-9a-zA-Z]+))?'); -define('PEAR_COMMON_CHANNEL_DOWNLOAD_PREG', '/^' . _PEAR_COMMON_CHANNEL_DOWNLOAD_PREG . '\\z/'); + foreach ($allparents[$package] as $kid => $d1) { + foreach ($d1 as $depinfo) { + if ($depinfo[1]['type'] != 'optional') { + if (isset($badchildren[$kid])) { + continue; + } + $badchildren[$kid] = true; + $remove[$kid] = true; + $fail = true; + continue 2; + } + } + } + if ($fail) { + // start over, we removed some children + continue 2; + } + } + } while ($fail); -/** - * List of temporary files and directories registered by - * PEAR_Common::addTempFile(). - * @var array - */ -$GLOBALS['_PEAR_Common_tempfiles'] = array(); + // next, construct the list of packages that can't be uninstalled + $badpackages = array(); + $save = $this->_currentPackage; + foreach ($perpackagelist as $package => $packagedeps) { + foreach ($packagedeps as $parent) { + if (!isset($remove[$parent[0]])) { + continue; + } -/** - * Valid maintainer roles - * @var array - */ -$GLOBALS['_PEAR_Common_maintainer_roles'] = array('lead','developer','contributor','helper'); + $packagename = $this->_registry->parsePackageName($parent[0]); + $packagename['channel'] = $this->_registry->channelAlias($packagename['channel']); + $pa = $this->_registry->getPackage($packagename['package'], $packagename['channel']); + $packagename['package'] = $pa->getPackage(); + $this->_currentPackage = $packagename; + // parent is not present in uninstall list, make sure we can actually + // uninstall it (parent dep is optional) + $parentname['channel'] = $this->_registry->channelAlias($parent[1]['dep']['channel']); + $pa = $this->_registry->getPackage($parent[1]['dep']['name'], $parent[1]['dep']['channel']); + $parentname['package'] = $pa->getPackage(); + $parent[1]['dep']['package'] = $parentname['package']; + $parent[1]['dep']['channel'] = $parentname['channel']; + if ($parent[1]['type'] == 'optional') { + $test = $this->_validatePackageUninstall($parent[1]['dep'], false, $dl); + if ($test !== true) { + $badpackages[$package]['warnings'][] = $test; + } + } else { + $test = $this->_validatePackageUninstall($parent[1]['dep'], true, $dl); + if ($test !== true) { + $badpackages[$package]['errors'][] = $test; + } + } + } + } -/** - * Valid release states - * @var array - */ -$GLOBALS['_PEAR_Common_release_states'] = array('alpha','beta','stable','snapshot','devel'); + $this->_currentPackage = $save; + $dl->___uninstall_package_cache = $badpackages; + if (isset($badpackages[$memyselfandI])) { + if (isset($badpackages[$memyselfandI]['warnings'])) { + foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { + $dl->log(0, $warning[0]); + } + } -/** - * Valid dependency types - * @var array - */ -$GLOBALS['_PEAR_Common_dependency_types'] = array('pkg','ext','php','prog','ldlib','rtlib','os','websrv','sapi'); + if (isset($badpackages[$memyselfandI]['errors'])) { + foreach ($badpackages[$memyselfandI]['errors'] as $error) { + if (is_array($error)) { + $dl->log(0, $error[0]); + } else { + $dl->log(0, $error->getMessage()); + } + } -/** - * Valid dependency relations - * @var array - */ -$GLOBALS['_PEAR_Common_dependency_relations'] = array('has','eq','lt','le','gt','ge','not', 'ne'); + if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { + return $this->warning( + 'warning: %s should not be uninstalled, other installed packages depend ' . + 'on this package'); + } -/** - * Valid file roles - * @var array - */ -$GLOBALS['_PEAR_Common_file_roles'] = array('php','ext','test','doc','data','src','script'); + return $this->raiseError( + '%s cannot be uninstalled, other installed packages depend on this package'); + } + } -/** - * Valid replacement types - * @var array - */ -$GLOBALS['_PEAR_Common_replacement_types'] = array('php-const', 'pear-config', 'package-info'); + return true; + } -/** - * Valid "provide" types - * @var array - */ -$GLOBALS['_PEAR_Common_provide_types'] = array('ext', 'prog', 'class', 'function', 'feature', 'api'); + function _validatePackageUninstall($dep, $required, $dl) + { + $depname = $this->_registry->parsedPackageNameToString($dep, true); + $version = $this->_registry->packageinfo($dep['package'], 'version', $dep['channel']); + if (!$version) { + return true; + } -/** - * Valid "provide" types - * @var array - */ -$GLOBALS['_PEAR_Common_script_phases'] = array('pre-install', 'post-install', 'pre-uninstall', 'post-uninstall', 'pre-build', 'post-build', 'pre-configure', 'post-configure', 'pre-setup', 'post-setup'); + $extra = $this->_getExtraString($dep); + if (isset($dep['exclude']) && !is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } -/** - * Class providing common functionality for PEAR administration classes. - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Tomas V. V. Cox - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - * @deprecated This class will disappear, and its components will be spread - * into smaller classes, like the AT&T breakup, as of Release 1.4.0a1 - */ -class PEAR_Common extends PEAR -{ - /** - * User Interface object (PEAR_Frontend_* class). If null, - * the log() method uses print. - * @var object - */ - var $ui = null; + if (isset($dep['conflicts'])) { + return true; // uninstall OK - these packages conflict (probably installed with --force) + } - /** - * Configuration object (PEAR_Config). - * @var PEAR_Config - */ - var $config = null; + if (!isset($dep['min']) && !isset($dep['max'])) { + if (!$required) { + return $this->warning('"' . $depname . '" can be optionally used by ' . + 'installed package %s' . $extra); + } - /** stack of elements, gives some sort of XML context */ - var $element_stack = array(); + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError('"' . $depname . '" is required by ' . + 'installed package %s' . $extra); + } - /** name of currently parsed XML element */ - var $current_element; + return $this->warning('warning: "' . $depname . '" is required by ' . + 'installed package %s' . $extra); + } - /** array of attributes of the currently parsed XML element */ - var $current_attributes = array(); + $fail = false; + if (isset($dep['min']) && version_compare($version, $dep['min'], '>=')) { + $fail = true; + } - /** assoc with information about a package */ - var $pkginfo = array(); + if (isset($dep['max']) && version_compare($version, $dep['max'], '<=')) { + $fail = true; + } - var $current_path = null; + // we re-use this variable, preserve the original value + $saverequired = $required; + if (!$required) { + return $this->warning($depname . $extra . ' can be optionally used by installed package' . + ' "%s"'); + } - /** - * Flag variable used to mark a valid package file - * @var boolean - * @access private - */ - var $_validPackageFile; + if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { + return $this->raiseError($depname . $extra . ' is required by installed package' . + ' "%s"'); + } - /** - * PEAR_Common constructor - * - * @access public - */ - function PEAR_Common() - { - parent::PEAR(); - $this->config = &PEAR_Config::singleton(); - $this->debug = $this->config->get('verbose'); + return $this->raiseError('warning: ' . $depname . $extra . + ' is required by installed package "%s"'); } /** - * PEAR_Common destructor + * validate a downloaded package against installed packages * - * @access private + * As of PEAR 1.4.3, this will only validate + * + * @param array|PEAR_Downloader_Package|PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * $pkg package identifier (either + * array('package' => blah, 'channel' => blah) or an array with + * index 'info' referencing an object) + * @param PEAR_Downloader $dl + * @param array $params full list of packages to install + * @return true|PEAR_Error */ - function _PEAR_Common() + function validatePackage($pkg, &$dl, $params = array()) { - // doesn't work due to bug #14744 - //$tempfiles = $this->_tempfiles; - $tempfiles =& $GLOBALS['_PEAR_Common_tempfiles']; - while ($file = array_shift($tempfiles)) { - if (@is_dir($file)) { - if (!class_exists('System')) { - require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; - } + if (is_array($pkg) && isset($pkg['info'])) { + $deps = $this->_dependencydb->getDependentPackageDependencies($pkg['info']); + } else { + $deps = $this->_dependencydb->getDependentPackageDependencies($pkg); + } - System::rm(array('-rf', $file)); - } elseif (file_exists($file)) { - unlink($file); + $fail = false; + if ($deps) { + if (!class_exists('PEAR_Downloader_Package')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Downloader/Package.php'; + } + + $dp = &new PEAR_Downloader_Package($dl); + if (is_object($pkg)) { + $dp->setPackageFile($pkg); + } else { + $dp->setDownloadURL($pkg); + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + foreach ($deps as $channel => $info) { + foreach ($info as $package => $ds) { + foreach ($params as $packd) { + if (strtolower($packd->getPackage()) == strtolower($package) && + $packd->getChannel() == $channel) { + $dl->log(3, 'skipping installed package check of "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $channel, 'package' => $package), + true) . + '", version "' . $packd->getVersion() . '" will be ' . + 'downloaded and installed'); + continue 2; // jump to next package + } + } + + foreach ($ds as $d) { + $checker = &new PEAR_Dependency2($this->_config, $this->_options, + array('channel' => $channel, 'package' => $package), $this->_state); + $dep = $d['dep']; + $required = $d['type'] == 'required'; + $ret = $checker->_validatePackageDownload($dep, $required, array(&$dp)); + if (is_array($ret)) { + $dl->log(0, $ret[0]); + } elseif (PEAR::isError($ret)) { + $dl->log(0, $ret->getMessage()); + $fail = true; + } + } + } } + PEAR::popErrorHandling(); } - } - /** - * Register a temporary file or directory. When the destructor is - * executed, all registered temporary files and directories are - * removed. - * - * @param string $file name of file or directory - * - * @return void - * - * @access public - */ - function addTempFile($file) - { - if (!class_exists('PEAR_Frontend')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Frontend.php'; + if ($fail) { + return $this->raiseError( + '%s cannot be installed, conflicts with installed packages'); } - PEAR_Frontend::addTempFile($file); + + return true; } /** - * Wrapper to System::mkDir(), creates a directory as well as - * any necessary parent directories. - * - * @param string $dir directory name - * - * @return bool TRUE on success, or a PEAR error - * - * @access public + * validate a package.xml 1.0 dependency */ - function mkDirHier($dir) + function validateDependency1($dep, $params = array()) { - // Only used in Installer - move it there ? - $this->log(2, "+ create dir $dir"); - if (!class_exists('System')) { - require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + if (!isset($dep['optional'])) { + $dep['optional'] = 'no'; + } + + list($newdep, $type) = $this->normalizeDep($dep); + if (!$newdep) { + return $this->raiseError("Invalid Dependency"); + } + + if (method_exists($this, "validate{$type}Dependency")) { + return $this->{"validate{$type}Dependency"}($newdep, $dep['optional'] == 'no', + $params, true); } - return System::mkDir(array('-p', $dir)); } /** - * Logging method. - * - * @param int $level log level (0 is quiet, higher is noisier) - * @param string $msg message to write to the log - * - * @return void - * - * @access public - * @static + * Convert a 1.0 dep into a 2.0 dep */ - function log($level, $msg, $append_crlf = true) + function normalizeDep($dep) { - if ($this->debug >= $level) { - if (!class_exists('PEAR_Frontend')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Frontend.php'; + $types = array( + 'pkg' => 'Package', + 'ext' => 'Extension', + 'os' => 'Os', + 'php' => 'Php' + ); + + if (!isset($types[$dep['type']])) { + return array(false, false); + } + + $type = $types[$dep['type']]; + + $newdep = array(); + switch ($type) { + case 'Package' : + $newdep['channel'] = 'pear.php.net'; + case 'Extension' : + case 'Os' : + $newdep['name'] = $dep['name']; + break; + } + + $dep['rel'] = PEAR_Dependency2::signOperator($dep['rel']); + switch ($dep['rel']) { + case 'has' : + return array($newdep, $type); + break; + case 'not' : + $newdep['conflicts'] = true; + break; + case '>=' : + case '>' : + $newdep['min'] = $dep['version']; + if ($dep['rel'] == '>') { + $newdep['exclude'] = $dep['version']; + } + break; + case '<=' : + case '<' : + $newdep['max'] = $dep['version']; + if ($dep['rel'] == '<') { + $newdep['exclude'] = $dep['version']; + } + break; + case 'ne' : + case '!=' : + $newdep['min'] = '0'; + $newdep['max'] = '100000'; + $newdep['exclude'] = $dep['version']; + break; + case '==' : + $newdep['min'] = $dep['version']; + $newdep['max'] = $dep['version']; + break; + } + if ($type == 'Php') { + if (!isset($newdep['min'])) { + $newdep['min'] = '4.4.0'; } - $ui = &PEAR_Frontend::singleton(); - if (is_a($ui, 'PEAR_Frontend')) { - $ui->log($msg, $append_crlf); - } else { - print "$msg\n"; + if (!isset($newdep['max'])) { + $newdep['max'] = '6.0.0'; } } + return array($newdep, $type); } /** - * Create and register a temporary directory. - * - * @param string $tmpdir (optional) Directory to use as tmpdir. - * Will use system defaults (for example - * /tmp or c:\windows\temp) if not specified + * Converts text comparing operators to them sign equivalents * - * @return string name of created directory + * Example: 'ge' to '>=' * * @access public + * @param string Operator + * @return string Sign equivalent */ - function mkTempDir($tmpdir = '') + function signOperator($operator) { - $topt = $tmpdir ? array('-t', $tmpdir) : array(); - $topt = array_merge($topt, array('-d', 'pear')); - if (!class_exists('System')) { - require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + switch($operator) { + case 'lt': return '<'; + case 'le': return '<='; + case 'gt': return '>'; + case 'ge': return '>='; + case 'eq': return '=='; + case 'ne': return '!='; + default: + return $operator; } + } - if (!$tmpdir = System::mktemp($topt)) { - return false; + function raiseError($msg) + { + if (isset($this->_options['ignore-errors'])) { + return $this->warning($msg); } - $this->addTempFile($tmpdir); - return $tmpdir; + return PEAR::raiseError(sprintf($msg, $this->_registry->parsedPackageNameToString( + $this->_currentPackage, true))); } - /** - * Set object that represents the frontend to be used. - * - * @param object Reference of the frontend object - * @return void - * @access public - */ - function setFrontendObject(&$ui) + function warning($msg) { - $this->ui = &$ui; + return array(sprintf($msg, $this->_registry->parsedPackageNameToString( + $this->_currentPackage, true))); } +} + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: DependencyDB.php 286686 2009-08-02 17:38:57Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Needed for error handling + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Config.php'; + +$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array(); +/** + * Track dependency relationships between installed packages + * @category pear + * @package PEAR + * @author Greg Beaver + * @author Tomas V.V.Cox + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_DependencyDB +{ + // {{{ properties /** - * Return an array containing all of the states that are more stable than - * or equal to the passed in state - * - * @param string Release state - * @param boolean Determines whether to include $state in the list - * @return false|array False if $state is not a valid release state + * This is initialized by {@link setConfig()} + * @var PEAR_Config + * @access private */ - function betterStates($state, $include = false) - { - static $states = array('snapshot', 'devel', 'alpha', 'beta', 'stable'); - $i = array_search($state, $states); - if ($i === false) { - return false; - } - if ($include) { - $i--; - } - return array_slice($states, $i + 1); - } - + var $_config; /** - * Get the valid roles for a PEAR package maintainer - * - * @return array - * @static + * This is initialized by {@link setConfig()} + * @var PEAR_Registry + * @access private */ - function getUserRoles() - { - return $GLOBALS['_PEAR_Common_maintainer_roles']; - } - + var $_registry; /** - * Get the valid package release states of packages - * - * @return array - * @static + * Filename of the dependency DB (usually .depdb) + * @var string + * @access private */ - function getReleaseStates() - { - return $GLOBALS['_PEAR_Common_release_states']; - } - + var $_depdb = false; /** - * Get the implemented dependency types (php, ext, pkg etc.) - * - * @return array - * @static + * File name of the lockfile (usually .depdblock) + * @var string + * @access private */ - function getDependencyTypes() - { - return $GLOBALS['_PEAR_Common_dependency_types']; - } - + var $_lockfile = false; /** - * Get the implemented dependency relations (has, lt, ge etc.) - * - * @return array - * @static + * Open file resource for locking the lockfile + * @var resource|false + * @access private */ - function getDependencyRelations() - { - return $GLOBALS['_PEAR_Common_dependency_relations']; - } - + var $_lockFp = false; /** - * Get the implemented file roles - * - * @return array - * @static + * API version of this class, used to validate a file on-disk + * @var string + * @access private */ - function getFileRoles() - { - return $GLOBALS['_PEAR_Common_file_roles']; - } - + var $_version = '1.0'; /** - * Get the implemented file replacement types in - * - * @return array - * @static + * Cached dependency database file + * @var array|null + * @access private */ - function getReplacementTypes() - { - return $GLOBALS['_PEAR_Common_replacement_types']; - } + var $_cache; + + // }}} + // {{{ & singleton() /** - * Get the implemented file replacement types in - * - * @return array + * Get a raw dependency database. Calls setConfig() and assertDepsDB() + * @param PEAR_Config + * @param string|false full path to the dependency database, or false to use default + * @return PEAR_DependencyDB|PEAR_Error * @static */ - function getProvideTypes() + function &singleton(&$config, $depdb = false) { - return $GLOBALS['_PEAR_Common_provide_types']; + $phpdir = $config->get('php_dir', null, 'pear.php.net'); + if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir])) { + $a = new PEAR_DependencyDB; + $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir] = &$a; + $a->setConfig($config, $depdb); + $e = $a->assertDepsDB(); + if (PEAR::isError($e)) { + return $e; + } + } + + return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir]; } /** - * Get the implemented file replacement types in - * - * @return array - * @static + * Set up the registry/location of dependency DB + * @param PEAR_Config|false + * @param string|false full path to the dependency database, or false to use default */ - function getScriptPhases() + function setConfig(&$config, $depdb = false) { - return $GLOBALS['_PEAR_Common_script_phases']; + if (!$config) { + $this->_config = &PEAR_Config::singleton(); + } else { + $this->_config = &$config; + } + + $this->_registry = &$this->_config->getRegistry(); + if (!$depdb) { + $this->_depdb = $this->_config->get('php_dir', null, 'pear.php.net') . + DIRECTORY_SEPARATOR . '.depdb'; + } else { + $this->_depdb = $depdb; + } + + $this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock'; } + // }}} - /** - * Test whether a string contains a valid package name. - * - * @param string $name the package name to test - * - * @return bool - * - * @access public - */ - function validPackageName($name) + function hasWriteAccess() { - return (bool)preg_match(PEAR_COMMON_PACKAGE_NAME_PREG, $name); + if (!file_exists($this->_depdb)) { + $dir = $this->_depdb; + while ($dir && $dir != '.') { + $dir = dirname($dir); // cd .. + if ($dir != '.' && file_exists($dir)) { + if (is_writeable($dir)) { + return true; + } + + return false; + } + } + + return false; + } + + return is_writeable($this->_depdb); } + // {{{ assertDepsDB() + /** - * Test whether a string contains a valid package version. - * - * @param string $ver the package version to test - * - * @return bool - * - * @access public + * Create the dependency database, if it doesn't exist. Error if the database is + * newer than the code reading it. + * @return void|PEAR_Error */ - function validPackageVersion($ver) + function assertDepsDB() { - return (bool)preg_match(PEAR_COMMON_PACKAGE_VERSION_PREG, $ver); + if (!is_file($this->_depdb)) { + $this->rebuildDB(); + return; + } + + $depdb = $this->_getDepDB(); + // Datatype format has been changed, rebuild the Deps DB + if ($depdb['_version'] < $this->_version) { + $this->rebuildDB(); + } + + if ($depdb['_version']{0} > $this->_version{0}) { + return PEAR::raiseError('Dependency database is version ' . + $depdb['_version'] . ', and we are version ' . + $this->_version . ', cannot continue'); + } } /** - * @param string $path relative or absolute include path - * @return boolean - * @static + * Get a list of installed packages that depend on this package + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array + * @return array|false */ - function isIncludeable($path) + function getDependentPackages(&$pkg) { - if (file_exists($path) && is_readable($path)) { - return true; + $data = $this->_getDepDB(); + if (is_object($pkg)) { + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + } else { + $channel = strtolower($pkg['channel']); + $package = strtolower($pkg['package']); } - $ipath = explode(PATH_SEPARATOR, ini_get('include_path')); - foreach ($ipath as $include) { - $test = realpath($include . DIRECTORY_SEPARATOR . $path); - if (file_exists($test) && is_readable($test)) { - return true; - } + if (isset($data['packages'][$channel][$package])) { + return $data['packages'][$channel][$package]; } return false; } /** - * Returns information about a package file. Expects the name of - * a gzipped tar file as input. - * - * @param string $file name of .tgz file - * - * @return array array with package information - * - * @access public - * @deprecated use PEAR_PackageFile->fromTgzFile() instead - * + * Get a list of the actual dependencies of installed packages that depend on + * a package. + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array + * @return array|false */ - function infoFromTgzFile($file) + function getDependentPackageDependencies(&$pkg) { - $packagefile = &new PEAR_PackageFile($this->config); - $pf = &$packagefile->fromTgzFile($file, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); + $data = $this->_getDepDB(); + if (is_object($pkg)) { + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + } else { + $channel = strtolower($pkg['channel']); + $package = strtolower($pkg['package']); + } + + $depend = $this->getDependentPackages($pkg); + if (!$depend) { + return false; + } + + $dependencies = array(); + foreach ($depend as $info) { + $temp = $this->getDependencies($info); + foreach ($temp as $dep) { + if ( + isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) && + strtolower($dep['dep']['channel']) == $channel && + strtolower($dep['dep']['name']) == $package + ) { + if (!isset($dependencies[$info['channel']])) { + $dependencies[$info['channel']] = array(); + } + + if (!isset($dependencies[$info['channel']][$info['package']])) { + $dependencies[$info['channel']][$info['package']] = array(); + } + $dependencies[$info['channel']][$info['package']][] = $dep; } } - - return $pf; } - return $this->_postProcessValidPackagexml($pf); + return $dependencies; } /** - * Returns information about a package file. Expects the name of - * a package xml file as input. - * - * @param string $descfile name of package xml file - * - * @return array array with package information - * - * @access public - * @deprecated use PEAR_PackageFile->fromPackageFile() instead - * + * Get a list of dependencies of this installed package + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array + * @return array|false */ - function infoFromDescriptionFile($descfile) + function getDependencies(&$pkg) { - $packagefile = &new PEAR_PackageFile($this->config); - $pf = &$packagefile->fromPackageFile($descfile, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); - } - } + if (is_object($pkg)) { + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + } else { + $channel = strtolower($pkg['channel']); + $package = strtolower($pkg['package']); + } - return $pf; + $data = $this->_getDepDB(); + if (isset($data['dependencies'][$channel][$package])) { + return $data['dependencies'][$channel][$package]; } - return $this->_postProcessValidPackagexml($pf); + return false; } /** - * Returns information about a package file. Expects the contents - * of a package xml file as input. - * - * @param string $data contents of package.xml file - * - * @return array array with package information - * - * @access public - * @deprecated use PEAR_PackageFile->fromXmlstring() instead - * + * Determine whether $parent depends on $child, near or deep + * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2 + * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2 */ - function infoFromString($data) + function dependsOn($parent, $child) { - $packagefile = &new PEAR_PackageFile($this->config); - $pf = &$packagefile->fromXmlString($data, PEAR_VALIDATE_NORMAL, false); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); + $c = array(); + $this->_getDepDB(); + return $this->_dependsOn($parent, $child, $c); + } + + function _dependsOn($parent, $child, &$checked) + { + if (is_object($parent)) { + $channel = strtolower($parent->getChannel()); + $package = strtolower($parent->getPackage()); + } else { + $channel = strtolower($parent['channel']); + $package = strtolower($parent['package']); + } + + if (is_object($child)) { + $depchannel = strtolower($child->getChannel()); + $deppackage = strtolower($child->getPackage()); + } else { + $depchannel = strtolower($child['channel']); + $deppackage = strtolower($child['package']); + } + + if (isset($checked[$channel][$package][$depchannel][$deppackage])) { + return false; // avoid endless recursion + } + + $checked[$channel][$package][$depchannel][$deppackage] = true; + if (!isset($this->_cache['dependencies'][$channel][$package])) { + return false; + } + + foreach ($this->_cache['dependencies'][$channel][$package] as $info) { + if (isset($info['dep']['uri'])) { + if (is_object($child)) { + if ($info['dep']['uri'] == $child->getURI()) { + return true; + } + } elseif (isset($child['uri'])) { + if ($info['dep']['uri'] == $child['uri']) { + return true; + } } + return false; } - return $pf; + if (strtolower($info['dep']['channel']) == $depchannel && + strtolower($info['dep']['name']) == $deppackage) { + return true; + } + } + + foreach ($this->_cache['dependencies'][$channel][$package] as $info) { + if (isset($info['dep']['uri'])) { + if ($this->_dependsOn(array( + 'uri' => $info['dep']['uri'], + 'package' => $info['dep']['name']), $child, $checked)) { + return true; + } + } else { + if ($this->_dependsOn(array( + 'channel' => $info['dep']['channel'], + 'package' => $info['dep']['name']), $child, $checked)) { + return true; + } + } } - return $this->_postProcessValidPackagexml($pf); + return false; } /** - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @return array + * Register dependencies of a package that is being installed or upgraded + * @param PEAR_PackageFile_v2|PEAR_PackageFile_v2 */ - function _postProcessValidPackagexml(&$pf) + function installPackage(&$package) { - if (!is_a($pf, 'PEAR_PackageFile_v2')) { - $this->pkginfo = $pf->toArray(); - return $this->pkginfo; - } - - // sort of make this into a package.xml 1.0-style array - // changelog is not converted to old format. - $arr = $pf->toArray(true); - $arr = array_merge($arr, $arr['old']); - unset($arr['old']); - unset($arr['xsdversion']); - unset($arr['contents']); - unset($arr['compatible']); - unset($arr['channel']); - unset($arr['uri']); - unset($arr['dependencies']); - unset($arr['phprelease']); - unset($arr['extsrcrelease']); - unset($arr['zendextsrcrelease']); - unset($arr['extbinrelease']); - unset($arr['zendextbinrelease']); - unset($arr['bundle']); - unset($arr['lead']); - unset($arr['developer']); - unset($arr['helper']); - unset($arr['contributor']); - $arr['filelist'] = $pf->getFilelist(); - $this->pkginfo = $arr; - return $arr; + $data = $this->_getDepDB(); + unset($this->_cache); + $this->_setPackageDeps($data, $package); + $this->_writeDepDB($data); } /** - * Returns package information from different sources - * - * This method is able to extract information about a package - * from a .tgz archive or from a XML package definition file. + * Remove dependencies of a package that is being uninstalled, or upgraded. * - * @access public - * @param string Filename of the source ('package.xml', '.tgz') - * @return string - * @deprecated use PEAR_PackageFile->fromAnyFile() instead + * Upgraded packages first uninstall, then install + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have + * indices 'channel' and 'package' */ - function infoFromAny($info) + function uninstallPackage(&$pkg) { - if (is_string($info) && file_exists($info)) { - $packagefile = &new PEAR_PackageFile($this->config); - $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - $e = $this->raiseError($error['message'], $error['code'], null, null, $error); + $data = $this->_getDepDB(); + unset($this->_cache); + if (is_object($pkg)) { + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); + } else { + $channel = strtolower($pkg['channel']); + $package = strtolower($pkg['package']); + } + + if (!isset($data['dependencies'][$channel][$package])) { + return true; + } + + foreach ($data['dependencies'][$channel][$package] as $dep) { + $found = false; + $depchannel = isset($dep['dep']['uri']) ? '__uri' : strtolower($dep['dep']['channel']); + $depname = strtolower($dep['dep']['name']); + if (isset($data['packages'][$depchannel][$depname])) { + foreach ($data['packages'][$depchannel][$depname] as $i => $info) { + if ($info['channel'] == $channel && $info['package'] == $package) { + $found = true; + break; } } + } - return $pf; + if ($found) { + unset($data['packages'][$depchannel][$depname][$i]); + if (!count($data['packages'][$depchannel][$depname])) { + unset($data['packages'][$depchannel][$depname]); + if (!count($data['packages'][$depchannel])) { + unset($data['packages'][$depchannel]); + } + } else { + $data['packages'][$depchannel][$depname] = + array_values($data['packages'][$depchannel][$depname]); + } } + } - return $this->_postProcessValidPackagexml($pf); + unset($data['dependencies'][$channel][$package]); + if (!count($data['dependencies'][$channel])) { + unset($data['dependencies'][$channel]); } - return $info; - } + if (!count($data['dependencies'])) { + unset($data['dependencies']); + } - /** - * Return an XML document based on the package info (as returned - * by the PEAR_Common::infoFrom* methods). - * - * @param array $pkginfo package info - * - * @return string XML data - * - * @access public - * @deprecated use a PEAR_PackageFile_v* object's generator instead - */ - function xmlFromInfo($pkginfo) - { - $config = &PEAR_Config::singleton(); - $packagefile = &new PEAR_PackageFile($config); - $pf = &$packagefile->fromArray($pkginfo); - $gen = &$pf->getDefaultGenerator(); - return $gen->toXml(PEAR_VALIDATE_PACKAGING); + if (!count($data['packages'])) { + unset($data['packages']); + } + + $this->_writeDepDB($data); } /** - * Validate XML package definition file. - * - * @param string $info Filename of the package archive or of the - * package definition file - * @param array $errors Array that will contain the errors - * @param array $warnings Array that will contain the warnings - * @param string $dir_prefix (optional) directory where source files - * may be found, or empty if they are not available - * @access public - * @return boolean - * @deprecated use the validation of PEAR_PackageFile objects + * Rebuild the dependency DB by reading registry entries. + * @return true|PEAR_Error */ - function validatePackageInfo($info, &$errors, &$warnings, $dir_prefix = '') + function rebuildDB() { - $config = &PEAR_Config::singleton(); - $packagefile = &new PEAR_PackageFile($config); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - if (strpos($info, 'fromXmlString($info, PEAR_VALIDATE_NORMAL, ''); - } else { - $pf = &$packagefile->fromAnyFile($info, PEAR_VALIDATE_NORMAL); + $depdb = array('_version' => $this->_version); + if (!$this->hasWriteAccess()) { + // allow startup for read-only with older Registry + return $depdb; } - PEAR::staticPopErrorHandling(); - if (PEAR::isError($pf)) { - $errs = $pf->getUserinfo(); - if (is_array($errs)) { - foreach ($errs as $error) { - if ($error['level'] == 'error') { - $errors[] = $error['message']; - } else { - $warnings[] = $error['message']; - } + $packages = $this->_registry->listAllPackages(); + if (PEAR::isError($packages)) { + return $packages; + } + + foreach ($packages as $channel => $ps) { + foreach ($ps as $package) { + $package = $this->_registry->getPackage($package, $channel); + if (PEAR::isError($package)) { + return $package; } + $this->_setPackageDeps($depdb, $package); } + } - return false; + $error = $this->_writeDepDB($depdb); + if (PEAR::isError($error)) { + return $error; } + $this->_cache = $depdb; return true; } /** - * Build a "provides" array from data returned by - * analyzeSourceCode(). The format of the built array is like - * this: - * - * array( - * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), - * ... - * ) - * - * - * @param array $srcinfo array with information about a source file - * as returned by the analyzeSourceCode() method. - * - * @return void - * - * @access public - * + * Register usage of the dependency DB to prevent race conditions + * @param int one of the LOCK_* constants + * @return true|PEAR_Error + * @access private */ - function buildProvidesArray($srcinfo) + function _lock($mode = LOCK_EX) { - $file = basename($srcinfo['source_file']); - $pn = ''; - if (isset($this->_packageName)) { - $pn = $this->_packageName; + if (stristr(php_uname(), 'Windows 9')) { + return true; } - $pnl = strlen($pn); - foreach ($srcinfo['declared_classes'] as $class) { - $key = "class;$class"; - if (isset($this->pkginfo['provides'][$key])) { - continue; - } + if ($mode != LOCK_UN && is_resource($this->_lockFp)) { + // XXX does not check type of lock (LOCK_SH/LOCK_EX) + return true; + } - $this->pkginfo['provides'][$key] = - array('file'=> $file, 'type' => 'class', 'name' => $class); - if (isset($srcinfo['inheritance'][$class])) { - $this->pkginfo['provides'][$key]['extends'] = - $srcinfo['inheritance'][$class]; + $open_mode = 'w'; + // XXX People reported problems with LOCK_SH and 'w' + if ($mode === LOCK_SH) { + if (!file_exists($this->_lockfile)) { + touch($this->_lockfile); + } elseif (!is_file($this->_lockfile)) { + return PEAR::raiseError('could not create Dependency lock file, ' . + 'it exists and is not a regular file'); } + $open_mode = 'r'; } - foreach ($srcinfo['declared_methods'] as $class => $methods) { - foreach ($methods as $method) { - $function = "$class::$method"; - $key = "function;$function"; - if ($method{0} == '_' || !strcasecmp($method, $class) || - isset($this->pkginfo['provides'][$key])) { - continue; - } - - $this->pkginfo['provides'][$key] = - array('file'=> $file, 'type' => 'function', 'name' => $function); - } + if (!is_resource($this->_lockFp)) { + $this->_lockFp = @fopen($this->_lockfile, $open_mode); } - foreach ($srcinfo['declared_functions'] as $function) { - $key = "function;$function"; - if ($function{0} == '_' || isset($this->pkginfo['provides'][$key])) { - continue; - } + if (!is_resource($this->_lockFp)) { + return PEAR::raiseError("could not create Dependency lock file" . + (isset($php_errormsg) ? ": " . $php_errormsg : "")); + } - if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { - $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; + if (!(int)flock($this->_lockFp, $mode)) { + switch ($mode) { + case LOCK_SH: $str = 'shared'; break; + case LOCK_EX: $str = 'exclusive'; break; + case LOCK_UN: $str = 'unlock'; break; + default: $str = 'unknown'; break; } - $this->pkginfo['provides'][$key] = - array('file'=> $file, 'type' => 'function', 'name' => $function); + return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)"); } + + return true; } /** - * Analyze the source code of the given PHP file - * - * @param string Filename of the PHP file - * @return mixed - * @access public + * Release usage of dependency DB + * @return true|PEAR_Error + * @access private */ - function analyzeSourceCode($file) + function _unlock() { - if (!class_exists('PEAR_PackageFile_v2_Validator')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2/Validator.php'; + $ret = $this->_lock(LOCK_UN); + if (is_resource($this->_lockFp)) { + fclose($this->_lockFp); } - - $a = new PEAR_PackageFile_v2_Validator; - return $a->analyzeSourceCode($file); + $this->_lockFp = null; + return $ret; } - function detectDependencies($any, $status_callback = null) + /** + * Load the dependency database from disk, or return the cache + * @return array|PEAR_Error + */ + function _getDepDB() { - if (!function_exists("token_get_all")) { - return false; + if (!$this->hasWriteAccess()) { + return array('_version' => $this->_version); } - if (PEAR::isError($info = $this->infoFromAny($any))) { - return $this->raiseError($info); + if (isset($this->_cache)) { + return $this->_cache; } - if (!is_array($info)) { - return false; + if (!$fp = fopen($this->_depdb, 'r')) { + $err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'"); + return $err; } - $deps = array(); - $used_c = $decl_c = $decl_f = $decl_m = array(); - foreach ($info['filelist'] as $file => $fa) { - $tmp = $this->analyzeSourceCode($file); - $used_c = @array_merge($used_c, $tmp['used_classes']); - $decl_c = @array_merge($decl_c, $tmp['declared_classes']); - $decl_f = @array_merge($decl_f, $tmp['declared_functions']); - $decl_m = @array_merge($decl_m, $tmp['declared_methods']); - $inheri = @array_merge($inheri, $tmp['inheritance']); + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + clearstatcache(); + fclose($fp); + $data = unserialize(file_get_contents($this->_depdb)); + set_magic_quotes_runtime($rt); + $this->_cache = $data; + return $data; + } + + /** + * Write out the dependency database to disk + * @param array the database + * @return true|PEAR_Error + * @access private + */ + function _writeDepDB(&$deps) + { + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; } - $used_c = array_unique($used_c); - $decl_c = array_unique($decl_c); - $undecl_c = array_diff($used_c, $decl_c); + if (!$fp = fopen($this->_depdb, 'wb')) { + $this->_unlock(); + return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing"); + } - return array('used_classes' => $used_c, - 'declared_classes' => $decl_c, - 'declared_methods' => $decl_m, - 'declared_functions' => $decl_f, - 'undeclared_classes' => $undecl_c, - 'inheritance' => $inheri, - ); + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + fwrite($fp, serialize($deps)); + set_magic_quotes_runtime($rt); + fclose($fp); + $this->_unlock(); + $this->_cache = $deps; + return true; } /** - * Download a file through HTTP. Considers suggested file name in - * Content-disposition: header and can run a callback function for - * different events. The callback will be called with two - * parameters: the callback type, and parameters. The implemented - * callback types are: - * - * 'setup' called at the very beginning, parameter is a UI object - * that should be used for all output - * 'message' the parameter is a string with an informational message - * 'saveas' may be used to save with a different file name, the - * parameter is the filename that is about to be used. - * If a 'saveas' callback returns a non-empty string, - * that file name will be used as the filename instead. - * Note that $save_dir will not be affected by this, only - * the basename of the file. - * 'start' download is starting, parameter is number of bytes - * that are expected, or -1 if unknown - * 'bytesread' parameter is the number of bytes read so far - * 'done' download is complete, parameter is the total number - * of bytes read - * 'connfailed' if the TCP connection fails, this callback is called - * with array(host,port,errno,errmsg) - * 'writefailed' if writing to disk fails, this callback is called - * with array(destfile,errmsg) - * - * If an HTTP proxy has been configured (http_proxy PEAR_Config - * setting), the proxy will be used. - * - * @param string $url the URL to download - * @param object $ui PEAR_Frontend_* instance - * @param object $config PEAR_Config instance - * @param string $save_dir (optional) directory to save file in - * @param mixed $callback (optional) function/method to call for status - * updates - * - * @return string Returns the full path of the downloaded file or a PEAR - * error on failure. If the error is caused by - * socket-related errors, the error object will - * have the fsockopen error code available through - * getCode(). - * - * @access public - * @deprecated in favor of PEAR_Downloader::downloadHttp() + * Register all dependencies from a package in the dependencies database, in essence + * "installing" the package's dependency information + * @param array the database + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @access private */ - function downloadHttp($url, &$ui, $save_dir = '.', $callback = null) + function _setPackageDeps(&$data, &$pkg) { - if (!class_exists('PEAR_Downloader')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Downloader.php'; + $pkg->setConfig($this->_config); + if ($pkg->getPackagexmlVersion() == '1.0') { + $gen = &$pkg->getDefaultGenerator(); + $deps = $gen->dependenciesToV2(); + } else { + $deps = $pkg->getDeps(true); } - return PEAR_Downloader::downloadHttp($url, $ui, $save_dir, $callback); - } -} -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Config.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile.php'; - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Config.php,v 1.157 2009/02/25 00:23:26 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ + if (!$deps) { + return; + } -/** - * Required for error handling - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Registry.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + if (!is_array($data)) { + $data = array(); + } -/** - * Last created PEAR_Config instance. - * @var object - */ -$GLOBALS['_PEAR_Config_instance'] = null; -if (!defined('PEAR_INSTALL_DIR') || !PEAR_INSTALL_DIR) { - $PEAR_INSTALL_DIR = PHP_LIBDIR . DIRECTORY_SEPARATOR . 'pear'; -} else { - $PEAR_INSTALL_DIR = PEAR_INSTALL_DIR; -} + if (!isset($data['dependencies'])) { + $data['dependencies'] = array(); + } -// Below we define constants with default values for all configuration -// parameters except username/password. All of them can have their -// defaults set through environment variables. The reason we use the -// PHP_ prefix is for some security, PHP protects environment -// variables starting with PHP_*. + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); -// default channel and preferred mirror is based on whether we are invoked through -// the "pear" or the "pecl" command -if (!defined('PEAR_RUNTYPE')) { - define('PEAR_RUNTYPE', 'pear'); -} + if (!isset($data['dependencies'][$channel])) { + $data['dependencies'][$channel] = array(); + } -if (PEAR_RUNTYPE == 'pear') { - define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pear.php.net'); -} else { - define('PEAR_CONFIG_DEFAULT_CHANNEL', 'pecl.php.net'); -} + $data['dependencies'][$channel][$package] = array(); + if (isset($deps['required']['package'])) { + if (!isset($deps['required']['package'][0])) { + $deps['required']['package'] = array($deps['required']['package']); + } -if (getenv('PHP_PEAR_SYSCONF_DIR')) { - define('PEAR_CONFIG_SYSCONFDIR', getenv('PHP_PEAR_SYSCONF_DIR')); -} elseif (getenv('SystemRoot')) { - define('PEAR_CONFIG_SYSCONFDIR', getenv('SystemRoot')); -} else { - define('PEAR_CONFIG_SYSCONFDIR', PHP_SYSCONFDIR); -} + foreach ($deps['required']['package'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'required'); + } + } -// Default for master_server -if (getenv('PHP_PEAR_MASTER_SERVER')) { - define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', getenv('PHP_PEAR_MASTER_SERVER')); -} else { - define('PEAR_CONFIG_DEFAULT_MASTER_SERVER', 'pear.php.net'); -} + if (isset($deps['optional']['package'])) { + if (!isset($deps['optional']['package'][0])) { + $deps['optional']['package'] = array($deps['optional']['package']); + } -// Default for http_proxy -if (getenv('PHP_PEAR_HTTP_PROXY')) { - define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('PHP_PEAR_HTTP_PROXY')); -} elseif (getenv('http_proxy')) { - define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', getenv('http_proxy')); -} else { - define('PEAR_CONFIG_DEFAULT_HTTP_PROXY', ''); -} + foreach ($deps['optional']['package'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'optional'); + } + } -// Default for php_dir -if (getenv('PHP_PEAR_INSTALL_DIR')) { - define('PEAR_CONFIG_DEFAULT_PHP_DIR', getenv('PHP_PEAR_INSTALL_DIR')); -} else { - if (@file_exists($PEAR_INSTALL_DIR) && is_dir($PEAR_INSTALL_DIR)) { - define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); - } else { - define('PEAR_CONFIG_DEFAULT_PHP_DIR', $PEAR_INSTALL_DIR); - } -} + if (isset($deps['required']['subpackage'])) { + if (!isset($deps['required']['subpackage'][0])) { + $deps['required']['subpackage'] = array($deps['required']['subpackage']); + } -// Default for ext_dir -if (getenv('PHP_PEAR_EXTENSION_DIR')) { - define('PEAR_CONFIG_DEFAULT_EXT_DIR', getenv('PHP_PEAR_EXTENSION_DIR')); -} else { - if (ini_get('extension_dir')) { - define('PEAR_CONFIG_DEFAULT_EXT_DIR', ini_get('extension_dir')); - } elseif (defined('PEAR_EXTENSION_DIR') && - file_exists(PEAR_EXTENSION_DIR) && is_dir(PEAR_EXTENSION_DIR)) { - define('PEAR_CONFIG_DEFAULT_EXT_DIR', PEAR_EXTENSION_DIR); - } elseif (defined('PHP_EXTENSION_DIR')) { - define('PEAR_CONFIG_DEFAULT_EXT_DIR', PHP_EXTENSION_DIR); - } else { - define('PEAR_CONFIG_DEFAULT_EXT_DIR', '.'); - } -} + foreach ($deps['required']['subpackage'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'required'); + } + } -// Default for doc_dir -if (getenv('PHP_PEAR_DOC_DIR')) { - define('PEAR_CONFIG_DEFAULT_DOC_DIR', getenv('PHP_PEAR_DOC_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_DOC_DIR', - $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'docs'); -} + if (isset($deps['optional']['subpackage'])) { + if (!isset($deps['optional']['subpackage'][0])) { + $deps['optional']['subpackage'] = array($deps['optional']['subpackage']); + } -// Default for bin_dir -if (getenv('PHP_PEAR_BIN_DIR')) { - define('PEAR_CONFIG_DEFAULT_BIN_DIR', getenv('PHP_PEAR_BIN_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_BIN_DIR', PHP_BINDIR); -} + foreach ($deps['optional']['subpackage'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'optional'); + } + } -// Default for data_dir -if (getenv('PHP_PEAR_DATA_DIR')) { - define('PEAR_CONFIG_DEFAULT_DATA_DIR', getenv('PHP_PEAR_DATA_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_DATA_DIR', - $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'data'); -} + if (isset($deps['group'])) { + if (!isset($deps['group'][0])) { + $deps['group'] = array($deps['group']); + } -// Default for cfg_dir -if (getenv('PHP_PEAR_CFG_DIR')) { - define('PEAR_CONFIG_DEFAULT_CFG_DIR', getenv('PHP_PEAR_CFG_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_CFG_DIR', - $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'cfg'); -} + foreach ($deps['group'] as $group) { + if (isset($group['package'])) { + if (!isset($group['package'][0])) { + $group['package'] = array($group['package']); + } -// Default for www_dir -if (getenv('PHP_PEAR_WWW_DIR')) { - define('PEAR_CONFIG_DEFAULT_WWW_DIR', getenv('PHP_PEAR_WWW_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_WWW_DIR', - $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'www'); -} + foreach ($group['package'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'optional', + $group['attribs']['name']); + } + } -// Default for test_dir -if (getenv('PHP_PEAR_TEST_DIR')) { - define('PEAR_CONFIG_DEFAULT_TEST_DIR', getenv('PHP_PEAR_TEST_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_TEST_DIR', - $PEAR_INSTALL_DIR.DIRECTORY_SEPARATOR.'tests'); -} + if (isset($group['subpackage'])) { + if (!isset($group['subpackage'][0])) { + $group['subpackage'] = array($group['subpackage']); + } -// Default for temp_dir -if (getenv('PHP_PEAR_TEMP_DIR')) { - define('PEAR_CONFIG_DEFAULT_TEMP_DIR', getenv('PHP_PEAR_TEMP_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_TEMP_DIR', - System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . - DIRECTORY_SEPARATOR . 'temp'); -} + foreach ($group['subpackage'] as $dep) { + $this->_registerDep($data, $pkg, $dep, 'optional', + $group['attribs']['name']); + } + } + } + } -// Default for cache_dir -if (getenv('PHP_PEAR_CACHE_DIR')) { - define('PEAR_CONFIG_DEFAULT_CACHE_DIR', getenv('PHP_PEAR_CACHE_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_CACHE_DIR', - System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . - DIRECTORY_SEPARATOR . 'cache'); -} + if ($data['dependencies'][$channel][$package] == array()) { + unset($data['dependencies'][$channel][$package]); + if (!count($data['dependencies'][$channel])) { + unset($data['dependencies'][$channel]); + } + } + } -// Default for download_dir -if (getenv('PHP_PEAR_DOWNLOAD_DIR')) { - define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', getenv('PHP_PEAR_DOWNLOAD_DIR')); -} else { - define('PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR', - System::tmpdir() . DIRECTORY_SEPARATOR . 'pear' . - DIRECTORY_SEPARATOR . 'download'); -} + /** + * @param array the database + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param array the specific dependency + * @param required|optional whether this is a required or an optional dep + * @param string|false dependency group this dependency is from, or false for ordinary dep + */ + function _registerDep(&$data, &$pkg, $dep, $type, $group = false) + { + $info = array( + 'dep' => $dep, + 'type' => $type, + 'group' => $group + ); -// Default for php_bin -if (getenv('PHP_PEAR_PHP_BIN')) { - define('PEAR_CONFIG_DEFAULT_PHP_BIN', getenv('PHP_PEAR_PHP_BIN')); -} else { - define('PEAR_CONFIG_DEFAULT_PHP_BIN', PEAR_CONFIG_DEFAULT_BIN_DIR. - DIRECTORY_SEPARATOR.'php'.(OS_WINDOWS ? '.exe' : '')); -} + $dep = array_map('strtolower', $dep); + $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; + if (!isset($data['dependencies'])) { + $data['dependencies'] = array(); + } -// Default for verbose -if (getenv('PHP_PEAR_VERBOSE')) { - define('PEAR_CONFIG_DEFAULT_VERBOSE', getenv('PHP_PEAR_VERBOSE')); -} else { - define('PEAR_CONFIG_DEFAULT_VERBOSE', 1); -} + $channel = strtolower($pkg->getChannel()); + $package = strtolower($pkg->getPackage()); -// Default for preferred_state -if (getenv('PHP_PEAR_PREFERRED_STATE')) { - define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', getenv('PHP_PEAR_PREFERRED_STATE')); -} else { - define('PEAR_CONFIG_DEFAULT_PREFERRED_STATE', 'stable'); -} + if (!isset($data['dependencies'][$channel])) { + $data['dependencies'][$channel] = array(); + } -// Default for umask -if (getenv('PHP_PEAR_UMASK')) { - define('PEAR_CONFIG_DEFAULT_UMASK', getenv('PHP_PEAR_UMASK')); -} else { - define('PEAR_CONFIG_DEFAULT_UMASK', decoct(umask())); -} + if (!isset($data['dependencies'][$channel][$package])) { + $data['dependencies'][$channel][$package] = array(); + } -// Default for cache_ttl -if (getenv('PHP_PEAR_CACHE_TTL')) { - define('PEAR_CONFIG_DEFAULT_CACHE_TTL', getenv('PHP_PEAR_CACHE_TTL')); -} else { - define('PEAR_CONFIG_DEFAULT_CACHE_TTL', 3600); -} + $data['dependencies'][$channel][$package][] = $info; + if (isset($data['packages'][$depchannel][$dep['name']])) { + $found = false; + foreach ($data['packages'][$depchannel][$dep['name']] as $i => $p) { + if ($p['channel'] == $channel && $p['package'] == $package) { + $found = true; + break; + } + } + } else { + if (!isset($data['packages'])) { + $data['packages'] = array(); + } -// Default for sig_type -if (getenv('PHP_PEAR_SIG_TYPE')) { - define('PEAR_CONFIG_DEFAULT_SIG_TYPE', getenv('PHP_PEAR_SIG_TYPE')); -} else { - define('PEAR_CONFIG_DEFAULT_SIG_TYPE', 'gpg'); -} + if (!isset($data['packages'][$depchannel])) { + $data['packages'][$depchannel] = array(); + } + + if (!isset($data['packages'][$depchannel][$dep['name']])) { + $data['packages'][$depchannel][$dep['name']] = array(); + } + + $found = false; + } + + if (!$found) { + $data['packages'][$depchannel][$dep['name']][] = array( + 'channel' => $channel, + 'package' => $package + ); + } + } +} + * @author Stig Bakken + * @author Tomas V. V. Cox + * @author Martin Jansen + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Downloader.php 287109 2009-08-11 18:50:30Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.3.0 + */ -// Default for sig_bin -if (getenv('PHP_PEAR_SIG_BIN')) { - define('PEAR_CONFIG_DEFAULT_SIG_BIN', getenv('PHP_PEAR_SIG_BIN')); -} else { - define('PEAR_CONFIG_DEFAULT_SIG_BIN', - System::which( - 'gpg', OS_WINDOWS ? 'c:\gnupg\gpg.exe' : '/usr/local/bin/gpg')); -} +/** + * Needed for constants, extending + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Common.php'; -// Default for sig_keydir -if (getenv('PHP_PEAR_SIG_KEYDIR')) { - define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', getenv('PHP_PEAR_SIG_KEYDIR')); -} else { - define('PEAR_CONFIG_DEFAULT_SIG_KEYDIR', - PEAR_CONFIG_SYSCONFDIR . DIRECTORY_SEPARATOR . 'pearkeys'); -} +define('PEAR_INSTALLER_OK', 1); +define('PEAR_INSTALLER_FAILED', 0); +define('PEAR_INSTALLER_SKIPPED', -1); +define('PEAR_INSTALLER_ERROR_NO_PREF_STATE', 2); /** - * This is a class for storing configuration data, keeping track of - * which are system-defined, user-defined or defaulted. + * Administration class used to download anything from the internet (PEAR Packages, + * static URLs, xml files) + * * @category pear * @package PEAR - * @author Stig Bakken * @author Greg Beaver + * @author Stig Bakken + * @author Tomas V. V. Cox + * @author Martin Jansen * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 + * @since Class available since Release 1.3.0 */ -class PEAR_Config extends PEAR +class PEAR_Downloader extends PEAR_Common { /** - * Array of config files used. - * - * @var array layer => config file + * @var PEAR_Registry + * @access private */ - var $files = array( - 'system' => '', - 'user' => '', - ); + var $_registry; - var $layers = array(); + /** + * Preferred Installation State (snapshot, devel, alpha, beta, stable) + * @var string|null + * @access private + */ + var $_preferredState; /** - * Configuration data, two-dimensional array where the first - * dimension is the config layer ('user', 'system' and 'default'), - * and the second dimension is keyname => value. - * - * The order in the first dimension is important! Earlier - * layers will shadow later ones when a config value is - * requested (if a 'user' value exists, it will be returned first, - * then 'system' and finally 'default'). + * Options from command-line passed to Install. * - * @var array layer => array(keyname => value, ...) + * Recognized options:
    + * - onlyreqdeps : install all required dependencies as well + * - alldeps : install all dependencies, including optional + * - installroot : base relative path to install files in + * - force : force a download even if warnings would prevent it + * - nocompress : download uncompressed tarballs + * @see PEAR_Command_Install + * @access private + * @var array */ - var $configuration = array( - 'user' => array(), - 'system' => array(), - 'default' => array(), - ); + var $_options; /** - * Configuration values that can be set for a channel + * Downloaded Packages after a call to download(). * - * All other configuration values can only have a global value + * Format of each entry: + * + * + * array('pkg' => 'package_name', 'file' => '/path/to/local/file', + * 'info' => array() // parsed package.xml + * ); + * + * @access private * @var array + */ + var $_downloadedPackages = array(); + + /** + * Packages slated for download. + * + * This is used to prevent downloading a package more than once should it be a dependency + * for two packages to be installed. + * Format of each entry: + * + *
    +     * array('package_name1' => parsed package.xml, 'package_name2' => parsed package.xml,
    +     * );
    +     * 
    * @access private + * @var array */ - var $_channelConfigInfo = array( - 'php_dir', 'ext_dir', 'doc_dir', 'bin_dir', 'data_dir', 'cfg_dir', - 'test_dir', 'www_dir', 'php_bin', 'php_prefix', 'php_suffix', 'username', - 'password', 'verbose', 'preferred_state', 'umask', 'preferred_mirror', 'php_ini' - ); + var $_toDownload = array(); /** - * Channels that can be accessed - * @see setChannels() + * Array of every package installed, with names lower-cased. + * + * Format: + * + * array('package1' => 0, 'package2' => 1, ); + * * @var array - * @access private */ - var $_channels = array('pear.php.net', 'pecl.php.net', '__uri'); + var $_installed = array(); /** - * This variable is used to control the directory values returned - * @see setInstallRoot(); - * @var string|false + * @var array * @access private */ - var $_installRoot = false; + var $_errorStack = array(); /** - * If requested, this will always refer to the registry - * contained in php_dir - * @var PEAR_Registry + * @var boolean + * @access private */ - var $_registry = array(); + var $_internalDownload = false; /** + * Temporary variable used in sorting packages by dependency in {@link sortPkgDeps()} * @var array * @access private */ - var $_regInitialized = array(); + var $_packageSortTree; /** - * @var bool - * @access private + * Temporary directory, or configuration value where downloads will occur + * @var string */ - var $_noRegistry = false; + var $_downloadDir; /** - * amount of errors found while parsing config - * @var integer - * @access private + * @param PEAR_Frontend_* + * @param array + * @param PEAR_Config */ - var $_errorsFound = 0; - var $_lastError = null; + function PEAR_Downloader(&$ui, $options, &$config) + { + parent::PEAR_Common(); + $this->_options = $options; + $this->config = &$config; + $this->_preferredState = $this->config->get('preferred_state'); + $this->ui = &$ui; + if (!$this->_preferredState) { + // don't inadvertantly use a non-set preferred_state + $this->_preferredState = null; + } + + if (isset($this->_options['installroot'])) { + $this->config->setInstallRoot($this->_options['installroot']); + } + $this->_registry = &$config->getRegistry(); + + if (isset($this->_options['alldeps']) || isset($this->_options['onlyreqdeps'])) { + $this->_installed = $this->_registry->listAllPackages(); + foreach ($this->_installed as $key => $unused) { + if (!count($unused)) { + continue; + } + $strtolower = create_function('$a','return strtolower($a);'); + array_walk($this->_installed[$key], $strtolower); + } + } + } /** - * Information about the configuration data. Stores the type, - * default value and a documentation string for each configuration - * value. - * - * @var array layer => array(infotype => value, ...) + * Attempt to discover a channel's remote capabilities from + * its server name + * @param string + * @return boolean */ - var $configuration_info = array( - // Channels/Internet Access - 'default_channel' => array( - 'type' => 'string', - 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, - 'doc' => 'the default channel to use for all non explicit commands', - 'prompt' => 'Default Channel', - 'group' => 'Internet Access', - ), - 'preferred_mirror' => array( - 'type' => 'string', - 'default' => PEAR_CONFIG_DEFAULT_CHANNEL, - 'doc' => 'the default server or mirror to use for channel actions', - 'prompt' => 'Default Channel Mirror', - 'group' => 'Internet Access', - ), - 'remote_config' => array( - 'type' => 'password', - 'default' => '', - 'doc' => 'ftp url of remote configuration file to use for synchronized install', - 'prompt' => 'Remote Configuration File', - 'group' => 'Internet Access', - ), - 'auto_discover' => array( - 'type' => 'integer', - 'default' => 0, - 'doc' => 'whether to automatically discover new channels', - 'prompt' => 'Auto-discover new Channels', - 'group' => 'Internet Access', - ), - // Internet Access - 'master_server' => array( - 'type' => 'string', - 'default' => 'pear.php.net', - 'doc' => 'name of the main PEAR server [NOT USED IN THIS VERSION]', - 'prompt' => 'PEAR server [DEPRECATED]', - 'group' => 'Internet Access', - ), - 'http_proxy' => array( - 'type' => 'string', - 'default' => PEAR_CONFIG_DEFAULT_HTTP_PROXY, - 'doc' => 'HTTP proxy (host:port) to use when downloading packages', - 'prompt' => 'HTTP Proxy Server Address', - 'group' => 'Internet Access', - ), - // File Locations - 'php_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_PHP_DIR, - 'doc' => 'directory where .php files are installed', - 'prompt' => 'PEAR directory', - 'group' => 'File Locations', - ), - 'ext_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_EXT_DIR, - 'doc' => 'directory where loadable extensions are installed', - 'prompt' => 'PHP extension directory', - 'group' => 'File Locations', - ), - 'doc_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_DOC_DIR, - 'doc' => 'directory where documentation is installed', - 'prompt' => 'PEAR documentation directory', - 'group' => 'File Locations', - ), - 'bin_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_BIN_DIR, - 'doc' => 'directory where executables are installed', - 'prompt' => 'PEAR executables directory', - 'group' => 'File Locations', - ), - 'data_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_DATA_DIR, - 'doc' => 'directory where data files are installed', - 'prompt' => 'PEAR data directory', - 'group' => 'File Locations (Advanced)', - ), - 'cfg_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_CFG_DIR, - 'doc' => 'directory where modifiable configuration files are installed', - 'prompt' => 'PEAR configuration file directory', - 'group' => 'File Locations (Advanced)', - ), - 'www_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_WWW_DIR, - 'doc' => 'directory where www frontend files (html/js) are installed', - 'prompt' => 'PEAR www files directory', - 'group' => 'File Locations (Advanced)', - ), - 'test_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_TEST_DIR, - 'doc' => 'directory where regression tests are installed', - 'prompt' => 'PEAR test directory', - 'group' => 'File Locations (Advanced)', - ), - 'cache_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_CACHE_DIR, - 'doc' => 'directory which is used for web service cache', - 'prompt' => 'PEAR Installer cache directory', - 'group' => 'File Locations (Advanced)', - ), - 'temp_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_TEMP_DIR, - 'doc' => 'directory which is used for all temp files', - 'prompt' => 'PEAR Installer temp directory', - 'group' => 'File Locations (Advanced)', - ), - 'download_dir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_DOWNLOAD_DIR, - 'doc' => 'directory which is used for all downloaded files', - 'prompt' => 'PEAR Installer download directory', - 'group' => 'File Locations (Advanced)', - ), - 'php_bin' => array( - 'type' => 'file', - 'default' => PEAR_CONFIG_DEFAULT_PHP_BIN, - 'doc' => 'PHP CLI/CGI binary for executing scripts', - 'prompt' => 'PHP CLI/CGI binary', - 'group' => 'File Locations (Advanced)', - ), - 'php_prefix' => array( - 'type' => 'string', - 'default' => '', - 'doc' => '--program-prefix for php_bin\'s ./configure, used for pecl installs', - 'prompt' => '--program-prefix passed to PHP\'s ./configure', - 'group' => 'File Locations (Advanced)', - ), - 'php_suffix' => array( - 'type' => 'string', - 'default' => '', - 'doc' => '--program-suffix for php_bin\'s ./configure, used for pecl installs', - 'prompt' => '--program-suffix passed to PHP\'s ./configure', - 'group' => 'File Locations (Advanced)', - ), - 'php_ini' => array( - 'type' => 'file', - 'default' => '', - 'doc' => 'location of php.ini in which to enable PECL extensions on install', - 'prompt' => 'php.ini location', - 'group' => 'File Locations (Advanced)', - ), - // Maintainers - 'username' => array( - 'type' => 'string', - 'default' => '', - 'doc' => '(maintainers) your PEAR account name', - 'prompt' => 'PEAR username (for maintainers)', - 'group' => 'Maintainers', - ), - 'password' => array( - 'type' => 'password', - 'default' => '', - 'doc' => '(maintainers) your PEAR account password', - 'prompt' => 'PEAR password (for maintainers)', - 'group' => 'Maintainers', - ), - // Advanced - 'verbose' => array( - 'type' => 'integer', - 'default' => PEAR_CONFIG_DEFAULT_VERBOSE, - 'doc' => 'verbosity level -0: really quiet -1: somewhat quiet -2: verbose -3: debug', - 'prompt' => 'Debug Log Level', - 'group' => 'Advanced', - ), - 'preferred_state' => array( - 'type' => 'set', - 'default' => PEAR_CONFIG_DEFAULT_PREFERRED_STATE, - 'doc' => 'the installer will prefer releases with this state when installing packages without a version or state specified', - 'valid_set' => array( - 'stable', 'beta', 'alpha', 'devel', 'snapshot'), - 'prompt' => 'Preferred Package State', - 'group' => 'Advanced', - ), - 'umask' => array( - 'type' => 'mask', - 'default' => PEAR_CONFIG_DEFAULT_UMASK, - 'doc' => 'umask used when creating files (Unix-like systems only)', - 'prompt' => 'Unix file mask', - 'group' => 'Advanced', - ), - 'cache_ttl' => array( - 'type' => 'integer', - 'default' => PEAR_CONFIG_DEFAULT_CACHE_TTL, - 'doc' => 'amount of secs where the local cache is used and not updated', - 'prompt' => 'Cache TimeToLive', - 'group' => 'Advanced', - ), - 'sig_type' => array( - 'type' => 'set', - 'default' => PEAR_CONFIG_DEFAULT_SIG_TYPE, - 'doc' => 'which package signature mechanism to use', - 'valid_set' => array('gpg'), - 'prompt' => 'Package Signature Type', - 'group' => 'Maintainers', - ), - 'sig_bin' => array( - 'type' => 'string', - 'default' => PEAR_CONFIG_DEFAULT_SIG_BIN, - 'doc' => 'which package signature mechanism to use', - 'prompt' => 'Signature Handling Program', - 'group' => 'Maintainers', - ), - 'sig_keyid' => array( - 'type' => 'string', - 'default' => '', - 'doc' => 'which key to use for signing with', - 'prompt' => 'Signature Key Id', - 'group' => 'Maintainers', - ), - 'sig_keydir' => array( - 'type' => 'directory', - 'default' => PEAR_CONFIG_DEFAULT_SIG_KEYDIR, - 'doc' => 'directory where signature keys are located', - 'prompt' => 'Signature Key Directory', - 'group' => 'Maintainers', - ), - // __channels is reserved - used for channel-specific configuration - ); + function discover($channel) + { + $this->log(1, 'Attempting to discover channel "' . $channel . '"...'); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $callback = $this->ui ? array(&$this, '_downloadCallback') : null; + if (!class_exists('System')) { + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + } + + $tmp = System::mktemp(array('-d')); + $a = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false); + PEAR::popErrorHandling(); + if (PEAR::isError($a)) { + // Attempt to fallback to https automatically. + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $this->log(1, 'Attempting fallback to https instead of http on channel "' . $channel . '"...'); + $a = $this->downloadHttp('https://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false); + PEAR::popErrorHandling(); + if (PEAR::isError($a)) { + return false; + } + } + + list($a, $lastmodified) = $a; + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $b = new PEAR_ChannelFile; + if ($b->fromXmlFile($a)) { + unlink($a); + if ($this->config->get('auto_discover')) { + $this->_registry->addChannel($b, $lastmodified); + $alias = $b->getName(); + if ($b->getName() == $this->_registry->channelName($b->getAlias())) { + $alias = $b->getAlias(); + } + + $this->log(1, 'Auto-discovered channel "' . $channel . + '", alias "' . $alias . '", adding to registry'); + } + + return true; + } + + unlink($a); + return false; + } /** - * Constructor. - * - * @param string file to read user-defined options from - * @param string file to read system-wide defaults from - * @param bool determines whether a registry object "follows" - * the value of php_dir (is automatically created - * and moved when php_dir is changed) - * @param bool if true, fails if configuration files cannot be loaded - * - * @access public - * - * @see PEAR_Config::singleton + * For simpler unit-testing + * @param PEAR_Downloader + * @return PEAR_Downloader_Package */ - function PEAR_Config($user_file = '', $system_file = '', $ftp_file = false, - $strict = true) + function &newDownloaderPackage(&$t) + { + if (!class_exists('PEAR_Downloader_Package')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Downloader/Package.php'; + } + $a = &new PEAR_Downloader_Package($t); + return $a; + } + + /** + * For simpler unit-testing + * @param PEAR_Config + * @param array + * @param array + * @param int + */ + function &getDependency2Object(&$c, $i, $p, $s) + { + if (!class_exists('PEAR_Dependency2')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; + } + $z = &new PEAR_Dependency2($c, $i, $p, $s); + return $z; + } + + function &download($params) { - $this->PEAR(); - PEAR_Installer_Role::initializeConfig($this); - $sl = DIRECTORY_SEPARATOR; - if (empty($user_file)) { - if (OS_WINDOWS) { - $user_file = PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini'; - } else { - $user_file = getenv('HOME') . $sl . '.pearrc'; - } + if (!count($params)) { + $a = array(); + return $a; } - if (empty($system_file)) { - $system_file = PEAR_CONFIG_SYSCONFDIR . $sl; - if (OS_WINDOWS) { - $system_file .= 'pearsys.ini'; + if (!isset($this->_registry)) { + $this->_registry = &$this->config->getRegistry(); + } + + $channelschecked = array(); + // convert all parameters into PEAR_Downloader_Package objects + foreach ($params as $i => $param) { + $params[$i] = &$this->newDownloaderPackage($this); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $err = $params[$i]->initialize($param); + PEAR::staticPopErrorHandling(); + if (!$err) { + // skip parameters that were missed by preferred_state + continue; + } + + if (PEAR::isError($err)) { + if (!isset($this->_options['soft']) && $err->getMessage() !== '') { + $this->log(0, $err->getMessage()); + } + + $params[$i] = false; + if (is_object($param)) { + $param = $param->getChannel() . '/' . $param->getPackage(); + } + + if (!isset($this->_options['soft'])) { + $this->log(2, 'Package "' . $param . '" is not valid'); + } + + // Message logged above in a specific verbose mode, passing null to not show up on CLI + $this->pushError(null, PEAR_INSTALLER_SKIPPED); } else { - $system_file .= 'pear.conf'; + do { + if ($params[$i] && $params[$i]->getType() == 'local') { + // bug #7090 skip channel.xml check for local packages + break; + } + + if ($params[$i] && !isset($channelschecked[$params[$i]->getChannel()]) && + !isset($this->_options['offline']) + ) { + $channelschecked[$params[$i]->getChannel()] = true; + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (!class_exists('System')) { + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + } + + $curchannel = &$this->_registry->getChannel($params[$i]->getChannel()); + if (PEAR::isError($curchannel)) { + PEAR::staticPopErrorHandling(); + return $this->raiseError($curchannel); + } + + if (PEAR::isError($dir = $this->getDownloadDir())) { + PEAR::staticPopErrorHandling(); + break; + } + + $mirror = $this->config->get('preferred_mirror', null, $params[$i]->getChannel()); + $url = 'http://' . $mirror . '/channel.xml'; + $a = $this->downloadHttp($url, $this->ui, $dir, null, $curchannel->lastModified()); + + PEAR::staticPopErrorHandling(); + if (PEAR::isError($a) || !$a) { + // Attempt fallback to https automatically + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $a = $this->downloadHttp('https://' . $mirror . + '/channel.xml', $this->ui, $dir, null, $curchannel->lastModified()); + + PEAR::staticPopErrorHandling(); + if (PEAR::isError($a) || !$a) { + break; + } + } + $this->log(0, 'WARNING: channel "' . $params[$i]->getChannel() . '" has ' . + 'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $params[$i]->getChannel() . + '" to update'); + } + } while (false); + + if ($params[$i] && !isset($this->_options['downloadonly'])) { + if (isset($this->_options['packagingroot'])) { + $checkdir = $this->_prependPath( + $this->config->get('php_dir', null, $params[$i]->getChannel()), + $this->_options['packagingroot']); + } else { + $checkdir = $this->config->get('php_dir', + null, $params[$i]->getChannel()); + } + + while ($checkdir && $checkdir != '/' && !file_exists($checkdir)) { + $checkdir = dirname($checkdir); + } + + if ($checkdir == '.') { + $checkdir = '/'; + } + + if (!is_writeable($checkdir)) { + return PEAR::raiseError('Cannot install, php_dir for channel "' . + $params[$i]->getChannel() . '" is not writeable by the current user'); + } + } } } - $this->layers = array_keys($this->configuration); - $this->files['user'] = $user_file; - $this->files['system'] = $system_file; - if ($user_file && file_exists($user_file)) { - $this->pushErrorHandling(PEAR_ERROR_RETURN); - $this->readConfigFile($user_file, 'user', $strict); - $this->popErrorHandling(); - if ($this->_errorsFound > 0) { - return; - } + unset($channelschecked); + PEAR_Downloader_Package::removeDuplicates($params); + if (!count($params)) { + $a = array(); + return $a; } - if ($system_file && @file_exists($system_file)) { - $this->mergeConfigFile($system_file, false, 'system', $strict); - if ($this->_errorsFound > 0) { - return; + if (!isset($this->_options['nodeps']) && !isset($this->_options['offline'])) { + $reverify = true; + while ($reverify) { + $reverify = false; + foreach ($params as $i => $param) { + //PHP Bug 40768 / PEAR Bug #10944 + //Nested foreaches fail in PHP 5.2.1 + key($params); + $ret = $params[$i]->detectDependencies($params); + if (PEAR::isError($ret)) { + $reverify = true; + $params[$i] = false; + PEAR_Downloader_Package::removeDuplicates($params); + if (!isset($this->_options['soft'])) { + $this->log(0, $ret->getMessage()); + } + continue 2; + } + } } + } + if (isset($this->_options['offline'])) { + $this->log(3, 'Skipping dependency download check, --offline specified'); } - if (!$ftp_file) { - $ftp_file = $this->get('remote_config'); + if (!count($params)) { + $a = array(); + return $a; } - if ($ftp_file && defined('PEAR_REMOTEINSTALL_OK')) { - $this->readFTPConfigFile($ftp_file); + while (PEAR_Downloader_Package::mergeDependencies($params)); + PEAR_Downloader_Package::removeDuplicates($params, true); + $errorparams = array(); + if (PEAR_Downloader_Package::detectStupidDuplicates($params, $errorparams)) { + if (count($errorparams)) { + foreach ($errorparams as $param) { + $name = $this->_registry->parsedPackageNameToString($param->getParsedPackage()); + $this->pushError('Duplicate package ' . $name . ' found', PEAR_INSTALLER_FAILED); + } + $a = array(); + return $a; + } } - foreach ($this->configuration_info as $key => $info) { - $this->configuration['default'][$key] = $info['default']; + PEAR_Downloader_Package::removeInstalled($params); + if (!count($params)) { + $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED); + $a = array(); + return $a; } - $this->_registry['default'] = &new PEAR_Registry($this->configuration['default']['php_dir']); - $this->_registry['default']->setConfig($this, false); - $this->_regInitialized['default'] = false; - //$GLOBALS['_PEAR_Config_instance'] = &$this; - } + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->analyzeDependencies($params); + PEAR::popErrorHandling(); + if (!count($params)) { + $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED); + $a = array(); + return $a; + } - /** - * Return the default locations of user and system configuration files - * @static - */ - function getDefaultConfigFiles() - { - $sl = DIRECTORY_SEPARATOR; - if (OS_WINDOWS) { - return array( - 'user' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.ini', - 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pearsys.ini' - ); + $ret = array(); + $newparams = array(); + if (isset($this->_options['pretend'])) { + return $params; } - return array( - 'user' => getenv('HOME') . $sl . '.pearrc', - 'system' => PEAR_CONFIG_SYSCONFDIR . $sl . 'pear.conf' - ); - } + $somefailed = false; + foreach ($params as $i => $package) { + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $pf = &$params[$i]->download(); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($pf)) { + if (!isset($this->_options['soft'])) { + $this->log(1, $pf->getMessage()); + $this->log(0, 'Error: cannot download "' . + $this->_registry->parsedPackageNameToString($package->getParsedPackage(), + true) . + '"'); + } + $somefailed = true; + continue; + } - /** - * Static singleton method. If you want to keep only one instance - * of this class in use, this method will give you a reference to - * the last created PEAR_Config object if one exists, or create a - * new object. - * - * @param string (optional) file to read user-defined options from - * @param string (optional) file to read system-wide defaults from - * - * @return object an existing or new PEAR_Config instance - * - * @access public - * - * @see PEAR_Config::PEAR_Config - */ - function &singleton($user_file = '', $system_file = '', $strict = true) - { - if (is_object($GLOBALS['_PEAR_Config_instance'])) { - return $GLOBALS['_PEAR_Config_instance']; + $newparams[] = &$params[$i]; + $ret[] = array( + 'file' => $pf->getArchiveFile(), + 'info' => &$pf, + 'pkg' => $pf->getPackage() + ); } - $t_conf = &new PEAR_Config($user_file, $system_file, false, $strict); - if ($t_conf->_errorsFound > 0) { - return $t_conf->lastError; + if ($somefailed) { + // remove params that did not download successfully + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->analyzeDependencies($newparams, true); + PEAR::popErrorHandling(); + if (!count($newparams)) { + $this->pushError('Download failed', PEAR_INSTALLER_FAILED); + $a = array(); + return $a; + } } - $GLOBALS['_PEAR_Config_instance'] = &$t_conf; - return $GLOBALS['_PEAR_Config_instance']; + $this->_downloadedPackages = $ret; + return $newparams; } /** - * Determine whether any configuration files have been detected, and whether a - * registry object can be retrieved from this configuration. - * @return bool - * @since PEAR 1.4.0a1 + * @param array all packages to be installed */ - function validConfiguration() + function analyzeDependencies(&$params, $force = false) { - if ($this->isDefinedLayer('user') || $this->isDefinedLayer('system')) { - return true; + $hasfailed = $failed = false; + if (isset($this->_options['downloadonly'])) { + return; } - return false; - } + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $redo = true; + $reset = false; + while ($redo) { + $redo = false; + foreach ($params as $i => $param) { + $deps = $param->getDeps(); + if (!$deps) { + $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(), + $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); + $send = $param->getPackageFile(); - /** - * Reads configuration data from a file. All existing values in - * the config layer are discarded and replaced with data from the - * file. - * @param string file to read from, if NULL or not specified, the - * last-used file for the same layer (second param) is used - * @param string config layer to insert data into ('user' or 'system') - * @return bool TRUE on success or a PEAR error on failure - */ - function readConfigFile($file = null, $layer = 'user', $strict = true) - { - if (empty($this->files[$layer])) { - return $this->raiseError("unknown config layer `$layer'"); - } + $installcheck = $depchecker->validatePackage($send, $this, $params); + if (PEAR::isError($installcheck)) { + if (!isset($this->_options['soft'])) { + $this->log(0, $installcheck->getMessage()); + } + $hasfailed = true; + $params[$i] = false; + $reset = true; + $redo = true; + $failed = false; + PEAR_Downloader_Package::removeDuplicates($params); + continue 2; + } + continue; + } - if ($file === null) { - $file = $this->files[$layer]; - } + if (!$reset && $param->alreadyValidated() && !$force) { + continue; + } - $data = $this->_readConfigDataFrom($file); - if (PEAR::isError($data)) { - if (!$strict) { - return true; - } + if (count($deps)) { + $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(), + $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); + $send = $param->getPackageFile(); + if ($send === null) { + $send = $param->getDownloadURL(); + } - $this->_errorsFound++; - $this->lastError = $data; + $installcheck = $depchecker->validatePackage($send, $this, $params); + if (PEAR::isError($installcheck)) { + if (!isset($this->_options['soft'])) { + $this->log(0, $installcheck->getMessage()); + } + $hasfailed = true; + $params[$i] = false; + $reset = true; + $redo = true; + $failed = false; + PEAR_Downloader_Package::removeDuplicates($params); + continue 2; + } - return $data; - } + $failed = false; + if (isset($deps['required'])) { + foreach ($deps['required'] as $type => $dep) { + // note: Dependency2 will never return a PEAR_Error if ignore-errors + // is specified, so soft is needed to turn off logging + if (!isset($dep[0])) { + if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep, + true, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } else { + foreach ($dep as $d) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($d, + true, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } + } + } - $this->files[$layer] = $file; - $this->_decodeInput($data); - $this->configuration[$layer] = $data; - $this->_setupChannels(); - if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { - $this->_registry[$layer] = &new PEAR_Registry($phpdir); - $this->_registry[$layer]->setConfig($this, false); - $this->_regInitialized[$layer] = false; - } else { - unset($this->_registry[$layer]); - } - return true; - } + if (isset($deps['optional'])) { + foreach ($deps['optional'] as $type => $dep) { + if (!isset($dep[0])) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($dep, + false, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } else { + foreach ($dep as $d) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($d, + false, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } + } + } + } - /** - * @param string url to the remote config file, like ftp://www.example.com/pear/config.ini - * @return true|PEAR_Error - */ - function readFTPConfigFile($path) - { - do { // poor man's try - if (!class_exists('PEAR_FTP')) { - if (!class_exists('PEAR_Common')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Common.php'; - } - if (PEAR_Common::isIncludeable('PEAR/FTP.php')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/FTP.php'; + $groupname = $param->getGroup(); + if (isset($deps['group']) && $groupname) { + if (!isset($deps['group'][0])) { + $deps['group'] = array($deps['group']); + } + + $found = false; + foreach ($deps['group'] as $group) { + if ($group['attribs']['name'] == $groupname) { + $found = true; + break; + } + } + + if ($found) { + unset($group['attribs']); + foreach ($group as $type => $dep) { + if (!isset($dep[0])) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($dep, + false, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } else { + foreach ($dep as $d) { + if (PEAR::isError($e = + $depchecker->{"validate{$type}Dependency"}($d, + false, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } + } + } + } + } + } else { + foreach ($deps as $dep) { + if (PEAR::isError($e = $depchecker->validateDependency1($dep, $params))) { + $failed = true; + if (!isset($this->_options['soft'])) { + $this->log(0, $e->getMessage()); + } + } elseif (is_array($e) && !$param->alreadyValidated()) { + if (!isset($this->_options['soft'])) { + $this->log(0, $e[0]); + } + } + } + } + $params[$i]->setValidated(); } - } - - if (!class_exists('PEAR_FTP')) { - return PEAR::raiseError('PEAR_RemoteInstaller must be installed to use remote config'); - } - - $this->_ftp = &new PEAR_FTP; - $this->_ftp->pushErrorHandling(PEAR_ERROR_RETURN); - $e = $this->_ftp->init($path); - if (PEAR::isError($e)) { - $this->_ftp->popErrorHandling(); - return $e; - } - - $tmp = System::mktemp('-d'); - PEAR_Common::addTempFile($tmp); - $e = $this->_ftp->get(basename($path), $tmp . DIRECTORY_SEPARATOR . - 'pear.ini', false, FTP_BINARY); - if (PEAR::isError($e)) { - $this->_ftp->popErrorHandling(); - return $e; - } - PEAR_Common::addTempFile($tmp . DIRECTORY_SEPARATOR . 'pear.ini'); - $this->_ftp->disconnect(); - $this->_ftp->popErrorHandling(); - $this->files['ftp'] = $tmp . DIRECTORY_SEPARATOR . 'pear.ini'; - $e = $this->readConfigFile(null, 'ftp'); - if (PEAR::isError($e)) { - return $e; - } - - $fail = array(); - foreach ($this->configuration_info as $key => $val) { - if (in_array($this->getGroup($key), - array('File Locations', 'File Locations (Advanced)')) && - $this->getType($key) == 'directory') { - // any directory configs must be set for this to work - if (!isset($this->configuration['ftp'][$key])) { - $fail[] = $key; - } + if ($failed) { + $hasfailed = true; + $params[$i] = false; + $reset = true; + $redo = true; + $failed = false; + PEAR_Downloader_Package::removeDuplicates($params); + continue 2; } } - - if (!count($fail)) { - return true; + } + PEAR::staticPopErrorHandling(); + if ($hasfailed && (isset($this->_options['ignore-errors']) || + isset($this->_options['nodeps']))) { + // this is probably not needed, but just in case + if (!isset($this->_options['soft'])) { + $this->log(0, 'WARNING: dependencies failed'); } - - $fail = '"' . implode('", "', $fail) . '"'; - unset($this->files['ftp']); - unset($this->configuration['ftp']); - return PEAR::raiseError('ERROR: Ftp configuration file must set all ' . - 'directory configuration variables. These variables were not set: ' . - $fail); - } while (false); // poor man's catch - unset($this->files['ftp']); - return PEAR::raiseError('no remote host specified'); + } } /** - * Reads the existing configurations and creates the _channels array from it + * Retrieve the directory that downloads will happen in + * @access private + * @return string */ - function _setupChannels() + function getDownloadDir() { - $set = array_flip(array_values($this->_channels)); - foreach ($this->configuration as $layer => $data) { - $i = 1000; - if (isset($data['__channels']) && is_array($data['__channels'])) { - foreach ($data['__channels'] as $channel => $info) { - $set[$channel] = $i++; - } + if (isset($this->_downloadDir)) { + return $this->_downloadDir; + } + $downloaddir = $this->config->get('download_dir'); + if (empty($downloaddir) || (is_dir($downloaddir) && !is_writable($downloaddir))) { + if (is_dir($downloaddir) && !is_writable($downloaddir)) { + $this->log(0, 'WARNING: configuration download directory "' . $downloaddir . + '" is not writeable. Change download_dir config variable to ' . + 'a writeable dir to avoid this warning'); + } + if (!class_exists('System')) { + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; } + if (PEAR::isError($downloaddir = System::mktemp('-d'))) { + return $downloaddir; + } + $this->log(3, '+ tmp dir created at ' . $downloaddir); } - $this->_channels = array_values(array_flip($set)); - $this->setChannels($this->_channels); + if (!is_writable($downloaddir)) { + if (PEAR::isError(System::mkdir(array('-p', $downloaddir))) || + !is_writable($downloaddir)) { + return PEAR::raiseError('download directory "' . $downloaddir . + '" is not writeable. Change download_dir config variable to ' . + 'a writeable dir'); + } + } + return $this->_downloadDir = $downloaddir; } - function deleteChannel($channel) + function setDownloadDir($dir) { - $ch = strtolower($channel); - foreach ($this->configuration as $layer => $data) { - if (isset($data['__channels']) && isset($data['__channels'][$ch])) { - unset($this->configuration[$layer]['__channels'][$ch]); + if (!@is_writable($dir)) { + if (PEAR::isError(System::mkdir(array('-p', $dir)))) { + return PEAR::raiseError('download directory "' . $dir . + '" is not writeable. Change download_dir config variable to ' . + 'a writeable dir'); } } - - $this->_channels = array_flip($this->_channels); - unset($this->_channels[$ch]); - $this->_channels = array_flip($this->_channels); + $this->_downloadDir = $dir; } - /** - * Merges data into a config layer from a file. Does the same - * thing as readConfigFile, except it does not replace all - * existing values in the config layer. - * @param string file to read from - * @param bool whether to overwrite existing data (default TRUE) - * @param string config layer to insert data into ('user' or 'system') - * @param string if true, errors are returned if file opening fails - * @return bool TRUE on success or a PEAR error on failure - */ - function mergeConfigFile($file, $override = true, $layer = 'user', $strict = true) + function configSet($key, $value, $layer = 'user', $channel = false) { - if (empty($this->files[$layer])) { - return $this->raiseError("unknown config layer `$layer'"); - } - - if ($file === null) { - $file = $this->files[$layer]; - } - - $data = $this->_readConfigDataFrom($file); - if (PEAR::isError($data)) { - if (!$strict) { - return true; - } - - $this->_errorsFound++; - $this->lastError = $data; - - return $data; + $this->config->set($key, $value, $layer, $channel); + $this->_preferredState = $this->config->get('preferred_state', null, $channel); + if (!$this->_preferredState) { + // don't inadvertantly use a non-set preferred_state + $this->_preferredState = null; } + } - $this->_decodeInput($data); - if ($override) { - $this->configuration[$layer] = - PEAR_Config::arrayMergeRecursive($this->configuration[$layer], $data); - } else { - $this->configuration[$layer] = - PEAR_Config::arrayMergeRecursive($data, $this->configuration[$layer]); - } + function setOptions($options) + { + $this->_options = $options; + } - $this->_setupChannels(); - if (!$this->_noRegistry && ($phpdir = $this->get('php_dir', $layer, 'pear.php.net'))) { - $this->_registry[$layer] = &new PEAR_Registry($phpdir); - $this->_registry[$layer]->setConfig($this, false); - $this->_regInitialized[$layer] = false; - } else { - unset($this->_registry[$layer]); - } - return true; + // }}} + // {{{ setOptions() + function getOptions() + { + return $this->_options; } /** - * @param array - * @param array - * @return array - * @static + * For simpler unit-testing + * @param PEAR_Config + * @param int + * @param string */ - function arrayMergeRecursive($arr2, $arr1) + function &getPackagefileObject(&$c, $d, $t = false) { - $ret = array(); - foreach ($arr2 as $key => $data) { - if (!isset($arr1[$key])) { - $ret[$key] = $data; - unset($arr1[$key]); - continue; - } - if (is_array($data)) { - if (!is_array($arr1[$key])) { - $ret[$key] = $arr1[$key]; - unset($arr1[$key]); - continue; - } - $ret[$key] = PEAR_Config::arrayMergeRecursive($arr1[$key], $arr2[$key]); - unset($arr1[$key]); - } + if (!class_exists('PEAR_PackageFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile.php'; } - - return array_merge($ret, $arr1); + $a = &new PEAR_PackageFile($c, $d, $t); + return $a; } /** - * Writes data into a config layer from a file. - * - * @param string|null file to read from, or null for default - * @param string config layer to insert data into ('user' or - * 'system') - * @param string|null data to write to config file or null for internal data [DEPRECATED] - * @return bool TRUE on success or a PEAR error on failure + * @param array output of {@link parsePackageName()} + * @access private */ - function writeConfigFile($file = null, $layer = 'user', $data = null) + function _getPackageDownloadUrl($parr) { - $this->_lazyChannelSetup($layer); - if ($layer == 'both' || $layer == 'all') { - foreach ($this->files as $type => $file) { - $err = $this->writeConfigFile($file, $type, $data); - if (PEAR::isError($err)) { - return $err; + $curchannel = $this->config->get('default_channel'); + $this->configSet('default_channel', $parr['channel']); + // getDownloadURL returns an array. On error, it only contains information + // on the latest release as array(version, info). On success it contains + // array(version, info, download url string) + $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state'); + if (!$this->_registry->channelExists($parr['channel'])) { + do { + if ($this->config->get('auto_discover') && $this->discover($parr['channel'])) { + break; } - } - return true; + + $this->configSet('default_channel', $curchannel); + return PEAR::raiseError('Unknown remote channel: ' . $parr['channel']); + } while (false); } - if (empty($this->files[$layer])) { - return $this->raiseError("unknown config file type `$layer'"); + $chan = &$this->_registry->getChannel($parr['channel']); + if (PEAR::isError($chan)) { + return $chan; } - if ($file === null) { - $file = $this->files[$layer]; + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $version = $this->_registry->packageInfo($parr['package'], 'version', $parr['channel']); + $stability = $this->_registry->packageInfo($parr['package'], 'stability', $parr['channel']); + // package is installed - use the installed release stability level + if (!isset($parr['state']) && $stability !== null) { + $state = $stability['release']; } + PEAR::staticPopErrorHandling(); + $base2 = false; - $data = ($data === null) ? $this->configuration[$layer] : $data; - $this->_encodeOutput($data); - $opt = array('-p', dirname($file)); - if (!@System::mkDir($opt)) { - return $this->raiseError("could not create directory: " . dirname($file)); + $preferred_mirror = $this->config->get('preferred_mirror'); + if (!$chan->supportsREST($preferred_mirror) || + ( + !($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror)) + && + !($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) + ) + ) { + return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.'); } - if (file_exists($file) && is_file($file) && !is_writeable($file)) { - return $this->raiseError("no write access to $file!"); + if ($base2) { + $rest = &$this->config->getREST('1.3', $this->_options); + $base = $base2; + } else { + $rest = &$this->config->getREST('1.0', $this->_options); } - $fp = @fopen($file, "w"); - if (!$fp) { - return $this->raiseError("PEAR_Config::writeConfigFile fopen('$file','w') failed ($php_errormsg)"); + $downloadVersion = false; + if (!isset($parr['version']) && !isset($parr['state']) && $version + && !PEAR::isError($version) + && !isset($this->_options['downloadonly']) + ) { + $downloadVersion = $version; } - $contents = "#PEAR_Config 0.9\n" . serialize($data); - if (!@fwrite($fp, $contents)) { - return $this->raiseError("PEAR_Config::writeConfigFile: fwrite failed ($php_errormsg)"); + $url = $rest->getDownloadURL($base, $parr, $state, $downloadVersion, $chan->getName()); + if (PEAR::isError($url)) { + $this->configSet('default_channel', $curchannel); + return $url; } - return true; - } - /** - * Reads configuration data from a file and returns the parsed data - * in an array. - * - * @param string file to read from - * @return array configuration data or a PEAR error on failure - * @access private - */ - function _readConfigDataFrom($file) - { - $fp = false; - if (file_exists($file)) { - $fp = @fopen($file, "r"); + if ($parr['channel'] != $curchannel) { + $this->configSet('default_channel', $curchannel); } - if (!$fp) { - return $this->raiseError("PEAR_Config::readConfigFile fopen('$file','r') failed"); + if (!is_array($url)) { + return $url; } - $size = filesize($file); - $rt = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - fclose($fp); - $contents = file_get_contents($file); - if (empty($contents)) { - return $this->raiseError('Configuration file "' . $file . '" is empty'); + $url['raw'] = false; // no checking is necessary for REST + if (!is_array($url['info'])) { + return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . + 'this should never happen'); } - set_magic_quotes_runtime($rt); + if (!isset($this->_options['force']) && + !isset($this->_options['downloadonly']) && + $version && + !PEAR::isError($version) && + !isset($parr['group']) + ) { + if (version_compare($version, $url['version'], '=')) { + return PEAR::raiseError($this->_registry->parsedPackageNameToString( + $parr, true) . ' is already installed and is the same as the ' . + 'released version ' . $url['version'], -976); + } - $version = false; - if (preg_match('/^#PEAR_Config\s+(\S+)\s+/si', $contents, $matches)) { - $version = $matches[1]; - $contents = substr($contents, strlen($matches[0])); - } else { - // Museum config file - if (substr($contents,0,2) == 'a:') { - $version = '0.1'; + if (version_compare($version, $url['version'], '>')) { + return PEAR::raiseError($this->_registry->parsedPackageNameToString( + $parr, true) . ' is already installed and is newer than detected ' . + 'released version ' . $url['version'], -976); } } - if ($version && version_compare("$version", '1', '<')) { - // no '@', it is possible that unserialize - // raises a notice but it seems to block IO to - // STDOUT if a '@' is used and a notice is raise - $data = unserialize($contents); - - if (!is_array($data) && !$data) { - if ($contents == serialize(false)) { - $data = array(); - } else { - $err = $this->raiseError("PEAR_Config: bad data in $file"); - return $err; - } + if (isset($url['info']['required']) || $url['compatible']) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2.php'; + $pf = new PEAR_PackageFile_v2; + $pf->setRawChannel($parr['channel']); + if ($url['compatible']) { + $pf->setRawCompatible($url['compatible']); } - if (!is_array($data)) { - if (strlen(trim($contents)) > 0) { - $error = "PEAR_Config: bad data in $file"; - $err = $this->raiseError($error); - return $err; - } + } else { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; + $pf = new PEAR_PackageFile_v1; + } - $data = array(); - } - // add parsing of newer formats here... + $pf->setRawPackage($url['package']); + $pf->setDeps($url['info']); + if ($url['compatible']) { + $pf->setCompatible($url['compatible']); + } + + $pf->setRawState($url['stability']); + $url['info'] = &$pf; + if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) { + $ext = '.tar'; } else { - $err = $this->raiseError("$file: unknown version `$version'"); - return $err; + $ext = '.tgz'; } - return $data; - } + if (is_array($url) && isset($url['url'])) { + $url['url'] .= $ext; + } - /** - * Gets the file used for storing the config for a layer - * - * @param string $layer 'user' or 'system' - */ - function getConfFile($layer) - { - return $this->files[$layer]; + return $url; } /** - * @param string Configuration class name, used for detecting duplicate calls - * @param array information on a role as parsed from its xml file - * @return true|PEAR_Error + * @param array dependency array * @access private */ - function _addConfigVars($class, $vars) + function _getDepPackageDownloadUrl($dep, $parr) { - static $called = array(); - if (isset($called[$class])) { - return; - } + $xsdversion = isset($dep['rel']) ? '1.0' : '2.0'; + $curchannel = $this->config->get('default_channel'); + if (isset($dep['uri'])) { + $xsdversion = '2.0'; + $chan = &$this->_registry->getChannel('__uri'); + if (PEAR::isError($chan)) { + return $chan; + } - $called[$class] = 1; - if (count($vars) > 3) { - return $this->raiseError('Roles can only define 3 new config variables or less'); - } + $version = $this->_registry->packageInfo($dep['name'], 'version', '__uri'); + $this->configSet('default_channel', '__uri'); + } else { + if (isset($dep['channel'])) { + $remotechannel = $dep['channel']; + } else { + $remotechannel = 'pear.php.net'; + } - foreach ($vars as $name => $var) { - if (!is_array($var)) { - return $this->raiseError('Configuration information must be an array'); + if (!$this->_registry->channelExists($remotechannel)) { + do { + if ($this->config->get('auto_discover')) { + if ($this->discover($remotechannel)) { + break; + } + } + return PEAR::raiseError('Unknown remote channel: ' . $remotechannel); + } while (false); } - if (!isset($var['type'])) { - return $this->raiseError('Configuration information must contain a type'); - } elseif (!in_array($var['type'], - array('string', 'mask', 'password', 'directory', 'file', 'set'))) { - return $this->raiseError( - 'Configuration type must be one of directory, file, string, ' . - 'mask, set, or password'); + $chan = &$this->_registry->getChannel($remotechannel); + if (PEAR::isError($chan)) { + return $chan; } - if (!isset($var['default'])) { - return $this->raiseError( - 'Configuration information must contain a default value ("default" index)'); + + $version = $this->_registry->packageInfo($dep['name'], 'version', $remotechannel); + $this->configSet('default_channel', $remotechannel); + } + + $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state'); + if (isset($parr['state']) && isset($parr['version'])) { + unset($parr['state']); + } + + if (isset($dep['uri'])) { + $info = &$this->newDownloaderPackage($this); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $err = $info->initialize($dep); + PEAR::staticPopErrorHandling(); + if (!$err) { + // skip parameters that were missed by preferred_state + return PEAR::raiseError('Cannot initialize dependency'); } - if (is_array($var['default'])) { - $real_default = ''; - foreach ($var['default'] as $config_var => $val) { - if (strpos($config_var, 'text') === 0) { - $real_default .= $val; - } elseif (strpos($config_var, 'constant') === 0) { - if (!defined($val)) { - return $this->raiseError( - 'Unknown constant "' . $val . '" requested in ' . - 'default value for configuration variable "' . - $name . '"'); - } + if (PEAR::isError($err)) { + if (!isset($this->_options['soft'])) { + $this->log(0, $err->getMessage()); + } - $real_default .= constant($val); - } elseif (isset($this->configuration_info[$config_var])) { - $real_default .= - $this->configuration_info[$config_var]['default']; - } else { - return $this->raiseError( - 'Unknown request for "' . $config_var . '" value in ' . - 'default value for configuration variable "' . - $name . '"'); - } + if (is_object($info)) { + $param = $info->getChannel() . '/' . $info->getPackage(); } - $var['default'] = $real_default; + return PEAR::raiseError('Package "' . $param . '" is not valid'); + } + return $info; + } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) + && $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror')) + ) { + $rest = &$this->config->getREST('1.0', $this->_options); + $url = $rest->getDepDownloadURL($base, $xsdversion, $dep, $parr, + $state, $version, $chan->getName()); + if (PEAR::isError($url)) { + return $url; } - if ($var['type'] == 'integer') { - $var['default'] = (integer) $var['default']; + if ($parr['channel'] != $curchannel) { + $this->configSet('default_channel', $curchannel); } - if (!isset($var['doc'])) { - return $this->raiseError( - 'Configuration information must contain a summary ("doc" index)'); + if (!is_array($url)) { + return $url; } - if (!isset($var['prompt'])) { - return $this->raiseError( - 'Configuration information must contain a simple prompt ("prompt" index)'); + $url['raw'] = false; // no checking is necessary for REST + if (!is_array($url['info'])) { + return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . + 'this should never happen'); } - if (!isset($var['group'])) { - return $this->raiseError( - 'Configuration information must contain a simple group ("group" index)'); + if (isset($url['info']['required'])) { + if (!class_exists('PEAR_PackageFile_v2')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2.php'; + } + $pf = new PEAR_PackageFile_v2; + $pf->setRawChannel($remotechannel); + } else { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; + + } + $pf->setRawPackage($url['package']); + $pf->setDeps($url['info']); + if ($url['compatible']) { + $pf->setCompatible($url['compatible']); } - if (isset($this->configuration_info[$name])) { - return $this->raiseError('Configuration variable "' . $name . - '" already exists'); + $pf->setRawState($url['stability']); + $url['info'] = &$pf; + if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) { + $ext = '.tar'; + } else { + $ext = '.tgz'; } - $this->configuration_info[$name] = $var; - // fix bug #7351: setting custom config variable in a channel fails - $this->_channelConfigInfo[] = $name; + if (is_array($url) && isset($url['url'])) { + $url['url'] .= $ext; + } + + return $url; } - return true; + return $this->raiseError($parr['channel'] . ' is using a unsupported protocol - This should never happen.'); } /** - * Encodes/scrambles configuration data before writing to files. - * Currently, 'password' values will be base64-encoded as to avoid - * that people spot cleartext passwords by accident. - * - * @param array (reference) array to encode values in - * @return bool TRUE on success - * @access private + * @deprecated in favor of _getPackageDownloadUrl */ - function _encodeOutput(&$data) + function getPackageDownloadUrl($package, $version = null, $channel = false) { - foreach ($data as $key => $value) { - if ($key == '__channels') { - foreach ($data['__channels'] as $channel => $blah) { - $this->_encodeOutput($data['__channels'][$channel]); - } - } - - if (!isset($this->configuration_info[$key])) { - continue; - } - - $type = $this->configuration_info[$key]['type']; - switch ($type) { - // we base64-encode passwords so they are at least - // not shown in plain by accident - case 'password': { - $data[$key] = base64_encode($data[$key]); - break; - } - case 'mask': { - $data[$key] = octdec($data[$key]); - break; - } + if ($version) { + $package .= "-$version"; + } + if ($this === null || $this->_registry === null) { + $package = "http://pear.php.net/get/$package"; + } else { + $chan = $this->_registry->getChannel($channel); + if (PEAR::isError($chan)) { + return ''; } + $package = "http://" . $chan->getServer() . "/get/$package"; } - - return true; + if (!extension_loaded("zlib")) { + $package .= '?uncompress=yes'; + } + return $package; } /** - * Decodes/unscrambles configuration data after reading from files. - * - * @param array (reference) array to encode values in - * @return bool TRUE on success - * @access private + * Retrieve a list of downloaded packages after a call to {@link download()}. * - * @see PEAR_Config::_encodeOutput + * Also resets the list of downloaded packages. + * @return array */ - function _decodeInput(&$data) + function getDownloadedPackages() { - if (!is_array($data)) { - return true; - } + $ret = $this->_downloadedPackages; + $this->_downloadedPackages = array(); + $this->_toDownload = array(); + return $ret; + } - foreach ($data as $key => $value) { - if ($key == '__channels') { - foreach ($data['__channels'] as $channel => $blah) { - $this->_decodeInput($data['__channels'][$channel]); + function _downloadCallback($msg, $params = null) + { + switch ($msg) { + case 'saveas': + $this->log(1, "downloading $params ..."); + break; + case 'done': + $this->log(1, '...done: ' . number_format($params, 0, '', ',') . ' bytes'); + break; + case 'bytesread': + static $bytes; + if (empty($bytes)) { + $bytes = 0; } - } - - if (!isset($this->configuration_info[$key])) { - continue; - } - - $type = $this->configuration_info[$key]['type']; - switch ($type) { - case 'password': { - $data[$key] = base64_decode($data[$key]); - break; + if (!($bytes % 10240)) { + $this->log(1, '.', false); } - case 'mask': { - $data[$key] = decoct($data[$key]); - break; + $bytes += $params; + break; + case 'start': + if($params[1] == -1) { + $length = "Unknown size"; + } else { + $length = number_format($params[1], 0, '', ',')." bytes"; } - } + $this->log(1, "Starting to download {$params[0]} ($length)"); + break; } - - return true; + if (method_exists($this->ui, '_downloadCallback')) + $this->ui->_downloadCallback($msg, $params); } - /** - * Retrieve the default channel. - * - * On startup, channels are not initialized, so if the default channel is not - * pear.php.net, then initialize the config. - * @param string registry layer - * @return string|false - */ - function getDefaultChannel($layer = null) + function _prependPath($path, $prepend) { - $ret = false; - if ($layer === null) { - foreach ($this->layers as $layer) { - if (isset($this->configuration[$layer]['default_channel'])) { - $ret = $this->configuration[$layer]['default_channel']; - break; + if (strlen($prepend) > 0) { + if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { + if (preg_match('/^[a-z]:/i', $prepend)) { + $prepend = substr($prepend, 2); + } elseif ($prepend{0} != '\\') { + $prepend = "\\$prepend"; } + $path = substr($path, 0, 2) . $prepend . substr($path, 2); + } else { + $path = $prepend . $path; } - } elseif (isset($this->configuration[$layer]['default_channel'])) { - $ret = $this->configuration[$layer]['default_channel']; - } - - if ($ret == 'pear.php.net' && defined('PEAR_RUNTYPE') && PEAR_RUNTYPE == 'pecl') { - $ret = 'pecl.php.net'; } + return $path; + } - if ($ret) { - if ($ret != 'pear.php.net') { - $this->_lazyChannelSetup(); - } + /** + * @param string + * @param integer + */ + function pushError($errmsg, $code = -1) + { + array_push($this->_errorStack, array($errmsg, $code)); + } - return $ret; + function getErrorMsgs() + { + $msgs = array(); + $errs = $this->_errorStack; + foreach ($errs as $err) { + $msgs[] = $err[0]; } + $this->_errorStack = array(); + return $msgs; + } - return PEAR_CONFIG_DEFAULT_CHANNEL; + /** + * for BC + * + * @deprecated + */ + function sortPkgDeps(&$packages, $uninstall = false) + { + $uninstall ? + $this->sortPackagesForUninstall($packages) : + $this->sortPackagesForInstall($packages); } /** - * Returns a configuration value, prioritizing layers as per the - * layers property. + * Sort a list of arrays of array(downloaded packagefilename) by dependency. * - * @param string config key - * @return mixed the config value, or NULL if not found - * @access public + * This uses the topological sort method from graph theory, and the + * Structures_Graph package to properly sort dependencies for installation. + * @param array an array of downloaded PEAR_Downloader_Packages + * @return array array of array(packagefilename, package.xml contents) */ - function get($key, $layer = null, $channel = false) + function sortPackagesForInstall(&$packages) { - if (!isset($this->configuration_info[$key])) { - return null; + require_once 'phar://install-pear-nozlib.phar/' . 'Structures/Graph.php'; + require_once 'phar://install-pear-nozlib.phar/' . 'Structures/Graph/Node.php'; + require_once 'phar://install-pear-nozlib.phar/' . 'Structures/Graph/Manipulator/TopologicalSorter.php'; + $depgraph = new Structures_Graph(true); + $nodes = array(); + $reg = &$this->config->getRegistry(); + foreach ($packages as $i => $package) { + $pname = $reg->parsedPackageNameToString( + array( + 'channel' => $package->getChannel(), + 'package' => strtolower($package->getPackage()), + )); + $nodes[$pname] = new Structures_Graph_Node; + $nodes[$pname]->setData($packages[$i]); + $depgraph->addNode($nodes[$pname]); } - if ($key == '__channels') { - return null; - } + $deplinks = array(); + foreach ($nodes as $package => $node) { + $pf = &$node->getData(); + $pdeps = $pf->getDeps(true); + if (!$pdeps) { + continue; + } - if ($key == 'default_channel') { - return $this->getDefaultChannel($layer); - } + if ($pf->getPackagexmlVersion() == '1.0') { + foreach ($pdeps as $dep) { + if ($dep['type'] != 'pkg' || + (isset($dep['optional']) && $dep['optional'] == 'yes')) { + continue; + } - if (!$channel) { - $channel = $this->getDefaultChannel(); - } elseif ($channel != 'pear.php.net') { - $this->_lazyChannelSetup(); - } - $channel = strtolower($channel); + $dname = $reg->parsedPackageNameToString( + array( + 'channel' => 'pear.php.net', + 'package' => strtolower($dep['name']), + )); - $test = (in_array($key, $this->_channelConfigInfo)) ? - $this->_getChannelValue($key, $layer, $channel) : - null; - if ($test !== null) { - if ($this->_installRoot) { - if (in_array($this->getGroup($key), - array('File Locations', 'File Locations (Advanced)')) && - $this->getType($key) == 'directory') { - return $this->_prependPath($test, $this->_installRoot); - } - } - return $test; - } + if (isset($nodes[$dname])) { + if (!isset($deplinks[$dname])) { + $deplinks[$dname] = array(); + } - if ($layer === null) { - foreach ($this->layers as $layer) { - if (isset($this->configuration[$layer][$key])) { - $test = $this->configuration[$layer][$key]; - if ($this->_installRoot) { - if (in_array($this->getGroup($key), - array('File Locations', 'File Locations (Advanced)')) && - $this->getType($key) == 'directory') { - return $this->_prependPath($test, $this->_installRoot); + $deplinks[$dname][$package] = 1; + // dependency is in installed packages + continue; + } + + $dname = $reg->parsedPackageNameToString( + array( + 'channel' => 'pecl.php.net', + 'package' => strtolower($dep['name']), + )); + + if (isset($nodes[$dname])) { + if (!isset($deplinks[$dname])) { + $deplinks[$dname] = array(); } + + $deplinks[$dname][$package] = 1; + // dependency is in installed packages + continue; + } + } + } else { + // the only ordering we care about is: + // 1) subpackages must be installed before packages that depend on them + // 2) required deps must be installed before packages that depend on them + if (isset($pdeps['required']['subpackage'])) { + $t = $pdeps['required']['subpackage']; + if (!isset($t[0])) { + $t = array($t); } - if ($key == 'preferred_mirror') { - $reg = &$this->getRegistry(); - if (is_object($reg)) { - $chan = &$reg->getChannel($channel); - if (PEAR::isError($chan)) { - return $channel; + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + + if (isset($pdeps['group'])) { + if (!isset($pdeps['group'][0])) { + $pdeps['group'] = array($pdeps['group']); + } + + foreach ($pdeps['group'] as $group) { + if (isset($group['subpackage'])) { + $t = $group['subpackage']; + if (!isset($t[0])) { + $t = array($t); } - if (!$chan->getMirror($test) && $chan->getName() != $test) { - return $channel; // mirror does not exist + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + } + } + + if (isset($pdeps['optional']['subpackage'])) { + $t = $pdeps['optional']['subpackage']; + if (!isset($t[0])) { + $t = array($t); + } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + + if (isset($pdeps['required']['package'])) { + $t = $pdeps['required']['package']; + if (!isset($t[0])) { + $t = array($t); + } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + } + + if (isset($pdeps['group'])) { + if (!isset($pdeps['group'][0])) { + $pdeps['group'] = array($pdeps['group']); + } + + foreach ($pdeps['group'] as $group) { + if (isset($group['package'])) { + $t = $group['package']; + if (!isset($t[0])) { + $t = array($t); } + + $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); } } - return $test; } } - } elseif (isset($this->configuration[$layer][$key])) { - $test = $this->configuration[$layer][$key]; - if ($this->_installRoot) { - if (in_array($this->getGroup($key), - array('File Locations', 'File Locations (Advanced)')) && - $this->getType($key) == 'directory') { - return $this->_prependPath($test, $this->_installRoot); - } + } + + $this->_detectDepCycle($deplinks); + foreach ($deplinks as $dependent => $parents) { + foreach ($parents as $parent => $unused) { + $nodes[$dependent]->connectTo($nodes[$parent]); } + } - if ($key == 'preferred_mirror') { - $reg = &$this->getRegistry(); - if (is_object($reg)) { - $chan = &$reg->getChannel($channel); - if (PEAR::isError($chan)) { - return $channel; + $installOrder = Structures_Graph_Manipulator_TopologicalSorter::sort($depgraph); + $ret = array(); + for ($i = 0, $count = count($installOrder); $i < $count; $i++) { + foreach ($installOrder[$i] as $index => $sortedpackage) { + $data = &$installOrder[$i][$index]->getData(); + $ret[] = &$nodes[$reg->parsedPackageNameToString( + array( + 'channel' => $data->getChannel(), + 'package' => strtolower($data->getPackage()), + ))]->getData(); + } + } + + $packages = $ret; + return; + } + + /** + * Detect recursive links between dependencies and break the cycles + * + * @param array + * @access private + */ + function _detectDepCycle(&$deplinks) + { + do { + $keepgoing = false; + foreach ($deplinks as $dep => $parents) { + foreach ($parents as $parent => $unused) { + // reset the parent cycle detector + $this->_testCycle(null, null, null); + if ($this->_testCycle($dep, $deplinks, $parent)) { + $keepgoing = true; + unset($deplinks[$dep][$parent]); + if (count($deplinks[$dep]) == 0) { + unset($deplinks[$dep]); + } + + continue 3; } + } + } + } while ($keepgoing); + } + + function _testCycle($test, $deplinks, $dep) + { + static $visited = array(); + if ($test === null) { + $visited = array(); + return; + } + + // this happens when a parent has a dep cycle on another dependency + // but the child is not part of the cycle + if (isset($visited[$dep])) { + return false; + } + + $visited[$dep] = 1; + if ($test == $dep) { + return true; + } + + if (isset($deplinks[$dep])) { + if (in_array($test, array_keys($deplinks[$dep]), true)) { + return true; + } - if (!$chan->getMirror($test) && $chan->getName() != $test) { - return $channel; // mirror does not exist - } + foreach ($deplinks[$dep] as $parent => $unused) { + if ($this->_testCycle($test, $deplinks, $parent)) { + return true; } } - - return $test; } - return null; + return false; } /** - * Returns a channel-specific configuration value, prioritizing layers as per the - * layers property. + * Set up the dependency for installation parsing * - * @param string config key - * @return mixed the config value, or NULL if not found + * @param array $t dependency information + * @param PEAR_Registry $reg + * @param array $deplinks list of dependency links already established + * @param array $nodes all existing package nodes + * @param string $package parent package name * @access private */ - function _getChannelValue($key, $layer, $channel) + function _setupGraph($t, $reg, &$deplinks, &$nodes, $package) { - if ($key == '__channels' || $channel == 'pear.php.net') { - return null; - } + foreach ($t as $dep) { + $depchannel = !isset($dep['channel']) ? '__uri': $dep['channel']; + $dname = $reg->parsedPackageNameToString( + array( + 'channel' => $depchannel, + 'package' => strtolower($dep['name']), + )); - $ret = null; - if ($layer === null) { - foreach ($this->layers as $ilayer) { - if (isset($this->configuration[$ilayer]['__channels'][$channel][$key])) { - $ret = $this->configuration[$ilayer]['__channels'][$channel][$key]; - break; + if (isset($nodes[$dname])) { + if (!isset($deplinks[$dname])) { + $deplinks[$dname] = array(); } + $deplinks[$dname][$package] = 1; } - } elseif (isset($this->configuration[$layer]['__channels'][$channel][$key])) { - $ret = $this->configuration[$layer]['__channels'][$channel][$key]; } + } - if ($key != 'preferred_mirror') { - return $ret; - } + function _dependsOn($a, $b) + { + return $this->_checkDepTree(strtolower($a->getChannel()), strtolower($a->getPackage()), $b); + } + function _checkDepTree($channel, $package, $b, $checked = array()) + { + $checked[$channel][$package] = true; + if (!isset($this->_depTree[$channel][$package])) { + return false; + } - if ($ret !== null) { - $reg = &$this->getRegistry($layer); - if (is_object($reg)) { - $chan = &$reg->getChannel($channel); - if (PEAR::isError($chan)) { - return $channel; - } + if (isset($this->_depTree[$channel][$package][strtolower($b->getChannel())] + [strtolower($b->getPackage())])) { + return true; + } - if (!$chan->getMirror($ret) && $chan->getName() != $ret) { - return $channel; // mirror does not exist + foreach ($this->_depTree[$channel][$package] as $ch => $packages) { + foreach ($packages as $pa => $true) { + if ($this->_checkDepTree($ch, $pa, $b, $checked)) { + return true; } } - - return $ret; } - if ($channel != $this->getDefaultChannel($layer)) { - return $channel; // we must use the channel name as the preferred mirror - // if the user has not chosen an alternate - } + return false; + } - return $this->getDefaultChannel($layer); + function _sortInstall($a, $b) + { + if (!$a->getDeps() && !$b->getDeps()) { + return 0; // neither package has dependencies, order is insignificant + } + if ($a->getDeps() && !$b->getDeps()) { + return 1; // $a must be installed after $b because $a has dependencies + } + if (!$a->getDeps() && $b->getDeps()) { + return -1; // $b must be installed after $a because $b has dependencies + } + // both packages have dependencies + if ($this->_dependsOn($a, $b)) { + return 1; + } + if ($this->_dependsOn($b, $a)) { + return -1; + } + return 0; } /** - * Set a config value in a specific layer (defaults to 'user'). - * Enforces the types defined in the configuration_info array. An - * integer config variable will be cast to int, and a set config - * variable will be validated against its legal values. + * Download a file through HTTP. Considers suggested file name in + * Content-disposition: header and can run a callback function for + * different events. The callback will be called with two + * parameters: the callback type, and parameters. The implemented + * callback types are: * - * @param string config key - * @param string config value - * @param string (optional) config layer - * @param string channel to set this value for, or null for global value - * @return bool TRUE on success, FALSE on failure + * 'setup' called at the very beginning, parameter is a UI object + * that should be used for all output + * 'message' the parameter is a string with an informational message + * 'saveas' may be used to save with a different file name, the + * parameter is the filename that is about to be used. + * If a 'saveas' callback returns a non-empty string, + * that file name will be used as the filename instead. + * Note that $save_dir will not be affected by this, only + * the basename of the file. + * 'start' download is starting, parameter is number of bytes + * that are expected, or -1 if unknown + * 'bytesread' parameter is the number of bytes read so far + * 'done' download is complete, parameter is the total number + * of bytes read + * 'connfailed' if the TCP/SSL connection fails, this callback is called + * with array(host,port,errno,errmsg) + * 'writefailed' if writing to disk fails, this callback is called + * with array(destfile,errmsg) + * + * If an HTTP proxy has been configured (http_proxy PEAR_Config + * setting), the proxy will be used. + * + * @param string $url the URL to download + * @param object $ui PEAR_Frontend_* instance + * @param object $config PEAR_Config instance + * @param string $save_dir directory to save file in + * @param mixed $callback function/method to call for status + * updates + * @param false|string|array $lastmodified header values to check against for caching + * use false to return the header values from this download + * @param false|array $accept Accept headers to send + * @param false|string $channel Channel to use for retrieving authentication + * @return string|array Returns the full path of the downloaded file or a PEAR + * error on failure. If the error is caused by + * socket-related errors, the error object will + * have the fsockopen error code available through + * getCode(). If caching is requested, then return the header + * values. + * + * @access public */ - function set($key, $value, $layer = 'user', $channel = false) + function downloadHttp($url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null, + $accept = false, $channel = false) { - if ($key == '__channels') { - return false; + static $redirect = 0; + // always reset , so we are clean case of error + $wasredirect = $redirect; + $redirect = 0; + if ($callback) { + call_user_func($callback, 'setup', array(&$ui)); } - if (!isset($this->configuration[$layer])) { - return false; + $info = parse_url($url); + if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) { + return PEAR::raiseError('Cannot download non-http URL "' . $url . '"'); } - if ($key == 'default_channel') { - // can only set this value globally - $channel = 'pear.php.net'; - if ($value != 'pear.php.net') { - $this->_lazyChannelSetup($layer); - } + if (!isset($info['host'])) { + return PEAR::raiseError('Cannot download from non-URL "' . $url . '"'); } - if ($key == 'preferred_mirror') { - if ($channel == '__uri') { - return false; // can't set the __uri pseudo-channel's mirror - } + $host = isset($info['host']) ? $info['host'] : null; + $port = isset($info['port']) ? $info['port'] : null; + $path = isset($info['path']) ? $info['path'] : null; - $reg = &$this->getRegistry($layer); - if (is_object($reg)) { - $chan = &$reg->getChannel($channel ? $channel : 'pear.php.net'); - if (PEAR::isError($chan)) { - return false; - } + if (isset($this)) { + $config = &$this->config; + } else { + $config = &PEAR_Config::singleton(); + } - if (!$chan->getMirror($value) && $chan->getName() != $value) { - return false; // mirror does not exist - } + $proxy_host = $proxy_port = $proxy_user = $proxy_pass = ''; + if ($config->get('http_proxy') && + $proxy = parse_url($config->get('http_proxy'))) { + $proxy_host = isset($proxy['host']) ? $proxy['host'] : null; + if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') { + $proxy_host = 'ssl://' . $proxy_host; + } + $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080; + $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null; + $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null; + + if ($callback) { + call_user_func($callback, 'message', "Using HTTP proxy $host:$port"); } } - if (!isset($this->configuration_info[$key])) { - return false; + if (empty($port)) { + $port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80; } - extract($this->configuration_info[$key]); - switch ($type) { - case 'integer': - $value = (int)$value; - break; - case 'set': { - // If a valid_set is specified, require the value to - // be in the set. If there is no valid_set, accept - // any value. - if ($valid_set) { - reset($valid_set); - if ((key($valid_set) === 0 && !in_array($value, $valid_set)) || - (key($valid_set) !== 0 && empty($valid_set[$value]))) - { - return false; - } + $scheme = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http'; + + if ($proxy_host != '') { + $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr); + if (!$fp) { + if ($callback) { + call_user_func($callback, 'connfailed', array($proxy_host, $proxy_port, + $errno, $errstr)); } - break; + return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", $errno); } - } - if (!$channel) { - $channel = $this->get('default_channel', null, 'pear.php.net'); + if ($lastmodified === false || $lastmodified) { + $request = "GET $url HTTP/1.1\r\n"; + $request .= "Host: $host:$port\r\n"; + } else { + $request = "GET $url HTTP/1.0\r\n"; + $request .= "Host: $host\r\n"; + } + } else { + $network_host = $host; + if (isset($info['scheme']) && $info['scheme'] == 'https') { + $network_host = 'ssl://' . $host; + } + + $fp = @fsockopen($network_host, $port, $errno, $errstr); + if (!$fp) { + if ($callback) { + call_user_func($callback, 'connfailed', array($host, $port, + $errno, $errstr)); + } + return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); + } + + if ($lastmodified === false || $lastmodified) { + $request = "GET $path HTTP/1.1\r\n"; + $request .= "Host: $host:$port\r\n"; + } else { + $request = "GET $path HTTP/1.0\r\n"; + $request .= "Host: $host\r\n"; + } } - if (!in_array($channel, $this->_channels)) { - $this->_lazyChannelSetup($layer); - $reg = &$this->getRegistry($layer); - if ($reg) { - $channel = $reg->channelName($channel); + $ifmodifiedsince = ''; + if (is_array($lastmodified)) { + if (isset($lastmodified['Last-Modified'])) { + $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n"; } - if (!in_array($channel, $this->_channels)) { - return false; + if (isset($lastmodified['ETag'])) { + $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n"; } + } else { + $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : ''); } - if ($channel != 'pear.php.net') { - if (in_array($key, $this->_channelConfigInfo)) { - $this->configuration[$layer]['__channels'][$channel][$key] = $value; - return true; + $request .= $ifmodifiedsince . + "User-Agent: PEAR/1.9.0/PHP/" . PHP_VERSION . "\r\n"; + + if (isset($this)) { // only pass in authentication for non-static calls + $username = $config->get('username', null, $channel); + $password = $config->get('password', null, $channel); + if ($username && $password) { + $tmp = base64_encode("$username:$password"); + $request .= "Authorization: Basic $tmp\r\n"; } + } - return false; + if ($proxy_host != '' && $proxy_user != '') { + $request .= 'Proxy-Authorization: Basic ' . + base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n"; } - if ($key == 'default_channel') { - if (!isset($reg)) { - $reg = &$this->getRegistry($layer); - if (!$reg) { - $reg = &$this->getRegistry(); + if ($accept) { + $request .= 'Accept: ' . implode(', ', $accept) . "\r\n"; + } + + $request .= "Connection: close\r\n"; + $request .= "\r\n"; + fwrite($fp, $request); + $headers = array(); + $reply = 0; + while (trim($line = fgets($fp, 1024))) { + if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) { + $headers[strtolower($matches[1])] = trim($matches[2]); + } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { + $reply = (int)$matches[1]; + if ($reply == 304 && ($lastmodified || ($lastmodified === false))) { + return false; + } + + if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) { + return PEAR::raiseError("File $scheme://$host:$port$path not valid (received: $line)"); } } + } - if ($reg) { - $value = $reg->channelName($value); + if ($reply != 200) { + if (!isset($headers['location'])) { + return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirected but no location)"); } - if (!$value) { - return false; + if ($wasredirect > 4) { + return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirection looped more than 5 times)"); } + + $redirect = $wasredirect + 1; + return $this->downloadHttp($headers['location'], + $ui, $save_dir, $callback, $lastmodified, $accept); } - $this->configuration[$layer][$key] = $value; - if ($key == 'php_dir' && !$this->_noRegistry) { - if (!isset($this->_registry[$layer]) || - $value != $this->_registry[$layer]->install_dir) { - $this->_registry[$layer] = &new PEAR_Registry($value); - $this->_regInitialized[$layer] = false; - $this->_registry[$layer]->setConfig($this, false); + if (isset($headers['content-disposition']) && + preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|\\z)/', $headers['content-disposition'], $matches)) { + $save_as = basename($matches[1]); + } else { + $save_as = basename($url); + } + + if ($callback) { + $tmp = call_user_func($callback, 'saveas', $save_as); + if ($tmp) { + $save_as = $tmp; } } - return true; - } + $dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as; + if (!$wp = @fopen($dest_file, 'wb')) { + fclose($fp); + if ($callback) { + call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); + } + return PEAR::raiseError("could not open $dest_file for writing"); + } - function _lazyChannelSetup($uselayer = false) - { - if ($this->_noRegistry) { - return; + $length = isset($headers['content-length']) ? $headers['content-length'] : -1; + + $bytes = 0; + if ($callback) { + call_user_func($callback, 'start', array(basename($dest_file), $length)); } - $merge = false; - foreach ($this->_registry as $layer => $p) { - if ($uselayer && $uselayer != $layer) { - continue; + while ($data = fread($fp, 1024)) { + $bytes += strlen($data); + if ($callback) { + call_user_func($callback, 'bytesread', $bytes); } - - if (!$this->_regInitialized[$layer]) { - if ($layer == 'default' && isset($this->_registry['user']) || - isset($this->_registry['system'])) { - // only use the default registry if there are no alternatives - continue; + if (!@fwrite($wp, $data)) { + fclose($fp); + if ($callback) { + call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); } + return PEAR::raiseError("$dest_file: write failed ($php_errormsg)"); + } + } - if (!is_object($this->_registry[$layer])) { - if ($phpdir = $this->get('php_dir', $layer, 'pear.php.net')) { - $this->_registry[$layer] = &new PEAR_Registry($phpdir); - $this->_registry[$layer]->setConfig($this, false); - $this->_regInitialized[$layer] = false; - } else { - unset($this->_registry[$layer]); - return; - } - } + fclose($fp); + fclose($wp); + if ($callback) { + call_user_func($callback, 'done', $bytes); + } - $this->setChannels($this->_registry[$layer]->listChannels(), $merge); - $this->_regInitialized[$layer] = true; - $merge = true; + if ($lastmodified === false || $lastmodified) { + if (isset($headers['etag'])) { + $lastmodified = array('ETag' => $headers['etag']); + } + + if (isset($headers['last-modified'])) { + if (is_array($lastmodified)) { + $lastmodified['Last-Modified'] = $headers['last-modified']; + } else { + $lastmodified = $headers['last-modified']; + } } + return array($dest_file, $lastmodified, $headers); } + return $dest_file; } +} +// }}} + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Package.php 287560 2009-08-21 22:36:18Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * Error code when parameter initialization fails because no releases + * exist within preferred_state, but releases do exist + */ +define('PEAR_DOWNLOADER_PACKAGE_STATE', -1003); +/** + * Error code when parameter initialization fails because no releases + * exist that will work with the existing PHP version + */ +define('PEAR_DOWNLOADER_PACKAGE_PHPVERSION', -1004); +/** + * Coordinates download parameters and manages their dependencies + * prior to downloading them. + * + * Input can come from three sources: + * + * - local files (archives or package.xml) + * - remote files (downloadable urls) + * - abstract package names + * + * The first two elements are handled cleanly by PEAR_PackageFile, but the third requires + * accessing pearweb's xml-rpc interface to determine necessary dependencies, and the + * format returned of dependencies is slightly different from that used in package.xml. + * + * This class hides the differences between these elements, and makes automatic + * dependency resolution a piece of cake. It also manages conflicts when + * two classes depend on incompatible dependencies, or differing versions of the same + * package dependency. In addition, download will not be attempted if the php version is + * not supported, PEAR installer version is not supported, or non-PECL extensions are not + * installed. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Downloader_Package +{ + /** + * @var PEAR_Downloader + */ + var $_downloader; + /** + * @var PEAR_Config + */ + var $_config; + /** + * @var PEAR_Registry + */ + var $_registry; + /** + * Used to implement packagingroot properly + * @var PEAR_Registry + */ + var $_installRegistry; /** - * Set the list of channels. - * - * This should be set via a call to {@link PEAR_Registry::listChannels()} - * @param array - * @param bool - * @return bool success of operation + * @var PEAR_PackageFile_v1|PEAR_PackageFile|v2 */ - function setChannels($channels, $merge = false) - { - if (!is_array($channels)) { - return false; - } - - if ($merge) { - $this->_channels = array_merge($this->_channels, $channels); - } else { - $this->_channels = $channels; - } - - foreach ($channels as $channel) { - $channel = strtolower($channel); - if ($channel == 'pear.php.net') { - continue; - } - - foreach ($this->layers as $layer) { - if (!isset($this->configuration[$layer]['__channels'])) { - $this->configuration[$layer]['__channels'] = array(); - } - if (!isset($this->configuration[$layer]['__channels'][$channel]) - || !is_array($this->configuration[$layer]['__channels'][$channel])) { - $this->configuration[$layer]['__channels'][$channel] = array(); - } - } - } - - return true; - } - + var $_packagefile; /** - * Get the type of a config value. - * - * @param string config key - * - * @return string type, one of "string", "integer", "file", - * "directory", "set" or "password". - * - * @access public - * + * @var array */ - function getType($key) - { - if (isset($this->configuration_info[$key])) { - return $this->configuration_info[$key]['type']; - } - return false; - } - + var $_parsedname; /** - * Get the documentation for a config value. - * - * @param string config key - * @return string documentation string - * - * @access public - * + * @var array */ - function getDocs($key) - { - if (isset($this->configuration_info[$key])) { - return $this->configuration_info[$key]['doc']; - } - - return false; - } - + var $_downloadURL; /** - * Get the short documentation for a config value. - * - * @param string config key - * @return string short documentation string - * - * @access public + * @var array + */ + var $_downloadDeps = array(); + /** + * @var boolean + */ + var $_valid = false; + /** + * @var boolean + */ + var $_analyzed = false; + /** + * if this or a parent package was invoked with Package-state, this is set to the + * state variable. * + * This allows temporary reassignment of preferred_state for a parent package and all of + * its dependencies. + * @var string|false */ - function getPrompt($key) - { - if (isset($this->configuration_info[$key])) { - return $this->configuration_info[$key]['prompt']; - } - - return false; - } + var $_explicitState = false; + /** + * If this package is invoked with Package#group, this variable will be true + */ + var $_explicitGroup = false; + /** + * Package type local|url + * @var string + */ + var $_type; + /** + * Contents of package.xml, if downloaded from a remote channel + * @var string|false + * @access private + */ + var $_rawpackagefile; + /** + * @var boolean + * @access private + */ + var $_validated = false; /** - * Get the parameter group for a config key. - * - * @param string config key - * @return string parameter group - * - * @access public - * + * @param PEAR_Downloader */ - function getGroup($key) + function PEAR_Downloader_Package(&$downloader) { - if (isset($this->configuration_info[$key])) { - return $this->configuration_info[$key]['group']; + $this->_downloader = &$downloader; + $this->_config = &$this->_downloader->config; + $this->_registry = &$this->_config->getRegistry(); + $options = $downloader->getOptions(); + if (isset($options['packagingroot'])) { + $this->_config->setInstallRoot($options['packagingroot']); + $this->_installRegistry = &$this->_config->getRegistry(); + $this->_config->setInstallRoot(false); + } else { + $this->_installRegistry = &$this->_registry; } - - return false; + $this->_valid = $this->_analyzed = false; } /** - * Get the list of parameter groups. - * - * @return array list of parameter groups - * - * @access public + * Parse the input and determine whether this is a local file, a remote uri, or an + * abstract package name. * + * This is the heart of the PEAR_Downloader_Package(), and is used in + * {@link PEAR_Downloader::download()} + * @param string + * @return bool|PEAR_Error */ - function getGroups() + function initialize($param) { - $tmp = array(); - foreach ($this->configuration_info as $key => $info) { - $tmp[$info['group']] = 1; + $origErr = $this->_fromFile($param); + if ($this->_valid) { + return true; } - return array_keys($tmp); - } + $options = $this->_downloader->getOptions(); + if (isset($options['offline'])) { + if (PEAR::isError($origErr) && !isset($options['soft'])) { + foreach ($origErr->getUserInfo() as $userInfo) { + if (isset($userInfo['message'])) { + $this->_downloader->log(0, $userInfo['message']); + } + } - /** - * Get the list of the parameters in a group. - * - * @param string $group parameter group - * @return array list of parameters in $group - * - * @access public - * - */ - function getGroupKeys($group) - { - $keys = array(); - foreach ($this->configuration_info as $key => $info) { - if ($info['group'] == $group) { - $keys[] = $key; + $this->_downloader->log(0, $origErr->getMessage()); } + + return PEAR::raiseError('Cannot download non-local package "' . $param . '"'); } - return $keys; - } + $err = $this->_fromUrl($param); + if (PEAR::isError($err) || !$this->_valid) { + if ($this->_type == 'url') { + if (PEAR::isError($err) && !isset($options['soft'])) { + $this->_downloader->log(0, $err->getMessage()); + } - /** - * Get the list of allowed set values for a config value. Returns - * NULL for config values that are not sets. - * - * @param string config key - * @return array enumerated array of set values, or NULL if the - * config key is unknown or not a set - * - * @access public - * - */ - function getSetValues($key) - { - if (isset($this->configuration_info[$key]) && - isset($this->configuration_info[$key]['type']) && - $this->configuration_info[$key]['type'] == 'set') - { - $valid_set = $this->configuration_info[$key]['valid_set']; - reset($valid_set); - if (key($valid_set) === 0) { - return $valid_set; + return PEAR::raiseError("Invalid or missing remote package file"); } - return array_keys($valid_set); - } + $err = $this->_fromString($param); + if (PEAR::isError($err) || !$this->_valid) { + if (PEAR::isError($err) && $err->getCode() == PEAR_DOWNLOADER_PACKAGE_STATE) { + return false; // instruct the downloader to silently skip + } - return null; - } + if (isset($this->_type) && $this->_type == 'local' && PEAR::isError($origErr)) { + if (is_array($origErr->getUserInfo())) { + foreach ($origErr->getUserInfo() as $err) { + if (is_array($err)) { + $err = $err['message']; + } - /** - * Get all the current config keys. - * - * @return array simple array of config keys - * - * @access public - */ - function getKeys() - { - $keys = array(); - foreach ($this->layers as $layer) { - $test = $this->configuration[$layer]; - if (isset($test['__channels'])) { - foreach ($test['__channels'] as $channel => $configs) { - $keys = array_merge($keys, $configs); + if (!isset($options['soft'])) { + $this->_downloader->log(0, $err); + } + } + } + + if (!isset($options['soft'])) { + $this->_downloader->log(0, $origErr->getMessage()); + } + + if (is_array($param)) { + $param = $this->_registry->parsedPackageNameToString($param, true); + } + + if (!isset($options['soft'])) { + $this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file"); + } + + // Passing no message back - already logged above + return PEAR::raiseError(); } - } - unset($test['__channels']); - $keys = array_merge($keys, $test); + if (PEAR::isError($err) && !isset($options['soft'])) { + $this->_downloader->log(0, $err->getMessage()); + } - } - return array_keys($keys); - } + if (is_array($param)) { + $param = $this->_registry->parsedPackageNameToString($param, true); + } - /** - * Remove the a config key from a specific config layer. - * - * @param string config key - * @param string (optional) config layer - * @return bool TRUE on success, FALSE on failure - * - * @access public - */ - function remove($key, $layer = 'user') - { - $channel = $this->getDefaultChannel(); - if ($channel !== 'pear.php.net') { - if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { - unset($this->configuration[$layer]['__channels'][$channel][$key]); - return true; - } - } + if (!isset($options['soft'])) { + $this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file"); + } - if (isset($this->configuration[$layer][$key])) { - unset($this->configuration[$layer][$key]); - return true; + // Passing no message back - already logged above + return PEAR::raiseError(); + } } - return false; + return true; } /** - * Temporarily remove an entire config layer. USE WITH CARE! - * - * @param string config key - * @param string (optional) config layer - * @return bool TRUE on success, FALSE on failure - * - * @access public + * Retrieve any non-local packages + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|PEAR_Error */ - function removeLayer($layer) + function &download() { - if (isset($this->configuration[$layer])) { - $this->configuration[$layer] = array(); - return true; + if (isset($this->_packagefile)) { + return $this->_packagefile; } - return false; - } + if (isset($this->_downloadURL['url'])) { + $this->_isvalid = false; + $info = $this->getParsedPackage(); + foreach ($info as $i => $p) { + $info[$i] = strtolower($p); + } - /** - * Stores configuration data in a layer. - * - * @param string config layer to store - * @return bool TRUE on success, or PEAR error on failure - * - * @access public - */ - function store($layer = 'user', $data = null) - { - return $this->writeConfigFile(null, $layer, $data); - } + $err = $this->_fromUrl($this->_downloadURL['url'], + $this->_registry->parsedPackageNameToString($this->_parsedname, true)); + $newinfo = $this->getParsedPackage(); + foreach ($newinfo as $i => $p) { + $newinfo[$i] = strtolower($p); + } - /** - * Tells what config layer that gets to define a key. - * - * @param string config key - * @param boolean return the defining channel - * - * @return string|array the config layer, or an empty string if not found. - * - * if $returnchannel, the return is an array array('layer' => layername, - * 'channel' => channelname), or an empty string if not found - * - * @access public - */ - function definedBy($key, $returnchannel = false) - { - foreach ($this->layers as $layer) { - $channel = $this->getDefaultChannel(); - if ($channel !== 'pear.php.net') { - if (isset($this->configuration[$layer]['__channels'][$channel][$key])) { - if ($returnchannel) { - return array('layer' => $layer, 'channel' => $channel); + if ($info != $newinfo) { + do { + if ($info['channel'] == 'pecl.php.net' && $newinfo['channel'] == 'pear.php.net') { + $info['channel'] = 'pear.php.net'; + if ($info == $newinfo) { + // skip the channel check if a pecl package says it's a PEAR package + break; + } } - return $layer; - } + if ($info['channel'] == 'pear.php.net' && $newinfo['channel'] == 'pecl.php.net') { + $info['channel'] = 'pecl.php.net'; + if ($info == $newinfo) { + // skip the channel check if a pecl package says it's a PEAR package + break; + } + } + + return PEAR::raiseError('CRITICAL ERROR: We are ' . + $this->_registry->parsedPackageNameToString($info) . ', but the file ' . + 'downloaded claims to be ' . + $this->_registry->parsedPackageNameToString($this->getParsedPackage())); + } while (false); } - if (isset($this->configuration[$layer][$key])) { - if ($returnchannel) { - return array('layer' => $layer, 'channel' => 'pear.php.net'); - } - return $layer; + if (PEAR::isError($err) || !$this->_valid) { + return $err; } } - return ''; + $this->_type = 'local'; + return $this->_packagefile; } - /** - * Tells whether a given key exists as a config value. - * - * @param string config key - * @return bool whether exists in this object - * - * @access public - */ - function isDefined($key) + function &getPackageFile() { - foreach ($this->layers as $layer) { - if (isset($this->configuration[$layer][$key])) { - return true; - } - } + return $this->_packagefile; + } - return false; + function &getDownloader() + { + return $this->_downloader; } - /** - * Tells whether a given config layer exists. - * - * @param string config layer - * @return bool whether exists in this object - * - * @access public - */ - function isDefinedLayer($layer) + function getType() { - return isset($this->configuration[$layer]); + return $this->_type; } /** - * Returns the layers defined (except the 'default' one) - * - * @return array of the defined layers + * Like {@link initialize()}, but operates on a dependency */ - function getLayers() + function fromDepURL($dep) { - $cf = $this->configuration; - unset($cf['default']); - return array_keys($cf); - } + $this->_downloadURL = $dep; + if (isset($dep['uri'])) { + $options = $this->_downloader->getOptions(); + if (!extension_loaded("zlib") || isset($options['nocompress'])) { + $ext = '.tar'; + } else { + $ext = '.tgz'; + } - function apiVersion() - { - return '1.1'; + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->_fromUrl($dep['uri'] . $ext); + PEAR::popErrorHandling(); + if (PEAR::isError($err)) { + if (!isset($options['soft'])) { + $this->_downloader->log(0, $err->getMessage()); + } + + return PEAR::raiseError('Invalid uri dependency "' . $dep['uri'] . $ext . '", ' . + 'cannot download'); + } + } else { + $this->_parsedname = + array( + 'package' => $dep['info']->getPackage(), + 'channel' => $dep['info']->getChannel(), + 'version' => $dep['version'] + ); + if (!isset($dep['nodefault'])) { + $this->_parsedname['group'] = 'default'; // download the default dependency group + $this->_explicitGroup = false; + } + + $this->_rawpackagefile = $dep['raw']; + } } - /** - * @return PEAR_Registry - */ - function &getRegistry($use = null) + function detectDependencies($params) { - $layer = $use === null ? 'user' : $use; - if (isset($this->_registry[$layer])) { - return $this->_registry[$layer]; - } elseif ($use === null && isset($this->_registry['system'])) { - return $this->_registry['system']; - } elseif ($use === null && isset($this->_registry['default'])) { - return $this->_registry['default']; - } elseif ($use) { - $a = false; - return $a; + $options = $this->_downloader->getOptions(); + if (isset($options['downloadonly'])) { + return; + } + + if (isset($options['offline'])) { + $this->_downloader->log(3, 'Skipping dependency download check, --offline specified'); + return; } - // only go here if null was passed in - echo "CRITICAL ERROR: Registry could not be initialized from any value"; - exit(1); - } - - /** - * This is to allow customization like the use of installroot - * @param PEAR_Registry - * @return bool - */ - function setRegistry(&$reg, $layer = 'user') - { - if ($this->_noRegistry) { - return false; + $pname = $this->getParsedPackage(); + if (!$pname) { + return; } - if (!in_array($layer, array('user', 'system'))) { - return false; + $deps = $this->getDeps(); + if (!$deps) { + return; } - $this->_registry[$layer] = &$reg; - if (is_object($reg)) { - $this->_registry[$layer]->setConfig($this, false); + if (isset($deps['required'])) { // package.xml 2.0 + return $this->_detect2($deps, $pname, $options, $params); } - return true; + return $this->_detect1($deps, $pname, $options, $params); } - function noRegistry() + function setValidated() { - $this->_noRegistry = true; + $this->_validated = true; } - /** - * @return PEAR_REST - */ - function &getREST($version, $options = array()) + function alreadyValidated() { - $version = str_replace('.', '', $version); - if (!class_exists($class = 'PEAR_REST_' . $version)) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/REST/' . $version . '.php'; - } - - $remote = &new $class($this, $options); - return $remote; + return $this->_validated; } /** - * The ftp server is set in {@link readFTPConfigFile()}. It exists only if a - * remote configuration file has been specified - * @return PEAR_FTP|false + * Remove packages to be downloaded that are already installed + * @param array of PEAR_Downloader_Package objects + * @static */ - function &getFTP() + function removeInstalled(&$params) { - if (isset($this->_ftp)) { - return $this->_ftp; + if (!isset($params[0])) { + return; } - $a = false; - return $a; - } - - function _prependPath($path, $prepend) - { - if (strlen($prepend) > 0) { - if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { - if (preg_match('/^[a-z]:/i', $prepend)) { - $prepend = substr($prepend, 2); - } elseif ($prepend{0} != '\\') { - $prepend = "\\$prepend"; + $options = $params[0]->_downloader->getOptions(); + if (!isset($options['downloadonly'])) { + foreach ($params as $i => $param) { + $package = $param->getPackage(); + $channel = $param->getChannel(); + // remove self if already installed with this version + // this does not need any pecl magic - we only remove exact matches + if ($param->_installRegistry->packageExists($package, $channel)) { + $packageVersion = $param->_installRegistry->packageInfo($package, 'version', $channel); + if (version_compare($packageVersion, $param->getVersion(), '==')) { + if (!isset($options['force'])) { + $info = $param->getParsedPackage(); + unset($info['version']); + unset($info['state']); + if (!isset($options['soft'])) { + $param->_downloader->log(1, 'Skipping package "' . + $param->getShortName() . + '", already installed as version ' . $packageVersion); + } + $params[$i] = false; + } + } elseif (!isset($options['force']) && !isset($options['upgrade']) && + !isset($options['soft'])) { + $info = $param->getParsedPackage(); + $param->_downloader->log(1, 'Skipping package "' . + $param->getShortName() . + '", already installed as version ' . $packageVersion); + $params[$i] = false; + } } - $path = substr($path, 0, 2) . $prepend . substr($path, 2); - } else { - $path = $prepend . $path; } } - return $path; + + PEAR_Downloader_Package::removeDuplicates($params); } - /** - * @param string|false installation directory to prepend to all _dir variables, or false to - * disable - */ - function setInstallRoot($root) + function _detect2($deps, $pname, $options, $params) { - if (substr($root, -1) == DIRECTORY_SEPARATOR) { - $root = substr($root, 0, -1); - } - $old = $this->_installRoot; - $this->_installRoot = $root; - if (($old != $root) && !$this->_noRegistry) { - foreach (array_keys($this->_registry) as $layer) { - if ($layer == 'ftp' || !isset($this->_registry[$layer])) { + $this->_downloadDeps = array(); + $groupnotfound = false; + foreach (array('package', 'subpackage') as $packagetype) { + // get required dependency group + if (isset($deps['required'][$packagetype])) { + if (isset($deps['required'][$packagetype][0])) { + foreach ($deps['required'][$packagetype] as $dep) { + if (isset($dep['conflicts'])) { + // skip any package that this package conflicts with + continue; + } + $ret = $this->_detect2Dep($dep, $pname, 'required', $params); + if (is_array($ret)) { + $this->_downloadDeps[] = $ret; + } elseif (PEAR::isError($ret) && !isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } + } + } else { + $dep = $deps['required'][$packagetype]; + if (!isset($dep['conflicts'])) { + // skip any package that this package conflicts with + $ret = $this->_detect2Dep($dep, $pname, 'required', $params); + if (is_array($ret)) { + $this->_downloadDeps[] = $ret; + } elseif (PEAR::isError($ret) && !isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } + } + } + } + + // get optional dependency group, if any + if (isset($deps['optional'][$packagetype])) { + $skipnames = array(); + if (!isset($deps['optional'][$packagetype][0])) { + $deps['optional'][$packagetype] = array($deps['optional'][$packagetype]); + } + + foreach ($deps['optional'][$packagetype] as $dep) { + $skip = false; + if (!isset($options['alldeps'])) { + $dep['package'] = $dep['name']; + if (!isset($options['soft'])) { + $this->_downloader->log(3, 'Notice: package "' . + $this->_registry->parsedPackageNameToString($this->getParsedPackage(), + true) . '" optional dependency "' . + $this->_registry->parsedPackageNameToString(array('package' => + $dep['name'], 'channel' => 'pear.php.net'), true) . + '" will not be automatically downloaded'); + } + $skipnames[] = $this->_registry->parsedPackageNameToString($dep, true); + $skip = true; + unset($dep['package']); + } + + $ret = $this->_detect2Dep($dep, $pname, 'optional', $params); + if (PEAR::isError($ret) && !isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } + + if (!$ret) { + $dep['package'] = $dep['name']; + $skip = count($skipnames) ? + $skipnames[count($skipnames) - 1] : ''; + if ($skip == + $this->_registry->parsedPackageNameToString($dep, true)) { + array_pop($skipnames); + } + } + + if (!$skip && is_array($ret)) { + $this->_downloadDeps[] = $ret; + } + } + + if (count($skipnames)) { + if (!isset($options['soft'])) { + $this->_downloader->log(1, 'Did not download optional dependencies: ' . + implode(', ', $skipnames) . + ', use --alldeps to download automatically'); + } + } + } + + // get requested dependency group, if any + $groupname = $this->getGroup(); + $explicit = $this->_explicitGroup; + if (!$groupname) { + if (!$this->canDefault()) { continue; } - $this->_registry[$layer] = - &new PEAR_Registry($this->get('php_dir', $layer, 'pear.php.net')); - $this->_registry[$layer]->setConfig($this, false); - $this->_regInitialized[$layer] = false; + + $groupname = 'default'; // try the default dependency group + } + + if ($groupnotfound) { + continue; + } + + if (isset($deps['group'])) { + if (isset($deps['group']['attribs'])) { + if (strtolower($deps['group']['attribs']['name']) == strtolower($groupname)) { + $group = $deps['group']; + } elseif ($explicit) { + if (!isset($options['soft'])) { + $this->_downloader->log(0, 'Warning: package "' . + $this->_registry->parsedPackageNameToString($pname, true) . + '" has no dependency ' . 'group named "' . $groupname . '"'); + } + + $groupnotfound = true; + continue; + } + } else { + $found = false; + foreach ($deps['group'] as $group) { + if (strtolower($group['attribs']['name']) == strtolower($groupname)) { + $found = true; + break; + } + } + + if (!$found) { + if ($explicit) { + if (!isset($options['soft'])) { + $this->_downloader->log(0, 'Warning: package "' . + $this->_registry->parsedPackageNameToString($pname, true) . + '" has no dependency ' . 'group named "' . $groupname . '"'); + } + } + + $groupnotfound = true; + continue; + } + } + } + + if (isset($group) && isset($group[$packagetype])) { + if (isset($group[$packagetype][0])) { + foreach ($group[$packagetype] as $dep) { + $ret = $this->_detect2Dep($dep, $pname, 'dependency group "' . + $group['attribs']['name'] . '"', $params); + if (is_array($ret)) { + $this->_downloadDeps[] = $ret; + } elseif (PEAR::isError($ret) && !isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } + } + } else { + $ret = $this->_detect2Dep($group[$packagetype], $pname, + 'dependency group "' . + $group['attribs']['name'] . '"', $params); + if (is_array($ret)) { + $this->_downloadDeps[] = $ret; + } elseif (PEAR::isError($ret) && !isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } + } } } } -} - - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Dependency2.php,v 1.59 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/** - * Required for the PEAR_VALIDATE_* constants - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validate.php'; + function _detect2Dep($dep, $pname, $group, $params) + { + if (isset($dep['conflicts'])) { + return true; + } -/** - * Dependency check for PEAR packages - * - * This class handles both version 1.0 and 2.0 dependencies - * WARNING: *any* changes to this class must be duplicated in the - * test_PEAR_Dependency2 class found in tests/PEAR_Dependency2/setup.php.inc, - * or unit tests will not actually validate the changes - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Dependency2 -{ - /** - * One of the PEAR_VALIDATE_* states - * @see PEAR_VALIDATE_NORMAL - * @var integer - */ - var $_state; + $options = $this->_downloader->getOptions(); + if (isset($dep['uri'])) { + return array('uri' => $dep['uri'], 'dep' => $dep);; + } - /** - * Command-line options to install/upgrade/uninstall commands - * @param array - */ - var $_options; + $testdep = $dep; + $testdep['package'] = $dep['name']; + if (PEAR_Downloader_Package::willDownload($testdep, $params)) { + $dep['package'] = $dep['name']; + if (!isset($options['soft'])) { + $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group . + ' dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '", will be installed'); + } + return false; + } - /** - * @var OS_Guess - */ - var $_os; + $options = $this->_downloader->getOptions(); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + if ($this->_explicitState) { + $pname['state'] = $this->_explicitState; + } - /** - * @var PEAR_Registry - */ - var $_registry; + $url = $this->_downloader->_getDepPackageDownloadUrl($dep, $pname); + if (PEAR::isError($url)) { + PEAR::popErrorHandling(); + return $url; + } - /** - * @var PEAR_Config - */ - var $_config; + $dep['package'] = $dep['name']; + $ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params, $group == 'optional' && + !isset($options['alldeps']), true); + PEAR::popErrorHandling(); + if (PEAR::isError($ret)) { + if (!isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); + } - /** - * @var PEAR_DependencyDB - */ - var $_dependencydb; + return false; + } - /** - * Output of PEAR_Registry::parsedPackageName() - * @var array - */ - var $_currentPackage; + // check to see if a dep is already installed and is the same or newer + if (!isset($dep['min']) && !isset($dep['max']) && !isset($dep['recommended'])) { + $oper = 'has'; + } else { + $oper = 'gt'; + } - /** - * @param PEAR_Config - * @param array installation options - * @param array format of PEAR_Registry::parsedPackageName() - * @param int installation state (one of PEAR_VALIDATE_*) - */ - function PEAR_Dependency2(&$config, $installoptions, $package, - $state = PEAR_VALIDATE_INSTALLING) - { - $this->_config = &$config; - if (!class_exists('PEAR_DependencyDB')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/DependencyDB.php'; + // do not try to move this before getDepPackageDownloadURL + // we can't determine whether upgrade is necessary until we know what + // version would be downloaded + if (!isset($options['force']) && $this->isInstalled($ret, $oper)) { + $version = $this->_installRegistry->packageInfo($dep['name'], 'version', $dep['channel']); + $dep['package'] = $dep['name']; + if (!isset($options['soft'])) { + $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group . + ' dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '" version ' . $url['version'] . ', already installed as version ' . + $version); + } + + return false; } - if (isset($installoptions['packagingroot'])) { - // make sure depdb is in the right location - $config->setInstallRoot($installoptions['packagingroot']); + if (isset($dep['nodefault'])) { + $ret['nodefault'] = true; } - $this->_registry = &$config->getRegistry(); - $this->_dependencydb = &PEAR_DependencyDB::singleton($config); - if (isset($installoptions['packagingroot'])) { - $config->setInstallRoot(false); - } + return $ret; + } + + function _detect1($deps, $pname, $options, $params) + { + $this->_downloadDeps = array(); + $skipnames = array(); + foreach ($deps as $dep) { + $nodownload = false; + if (isset ($dep['type']) && $dep['type'] === 'pkg') { + $dep['channel'] = 'pear.php.net'; + $dep['package'] = $dep['name']; + switch ($dep['rel']) { + case 'not' : + continue 2; + case 'ge' : + case 'eq' : + case 'gt' : + case 'has' : + $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ? + 'required' : + 'optional'; + if (PEAR_Downloader_Package::willDownload($dep, $params)) { + $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group + . ' dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '", will be installed'); + continue 2; + } + $fakedp = new PEAR_PackageFile_v1; + $fakedp->setPackage($dep['name']); + // skip internet check if we are not upgrading (bug #5810) + if (!isset($options['upgrade']) && $this->isInstalled( + $fakedp, $dep['rel'])) { + $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group + . ' dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '", is already installed'); + continue 2; + } + } + + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + if ($this->_explicitState) { + $pname['state'] = $this->_explicitState; + } + + $url = $this->_downloader->_getDepPackageDownloadUrl($dep, $pname); + $chan = 'pear.php.net'; + if (PEAR::isError($url)) { + // check to see if this is a pecl package that has jumped + // from pear.php.net to pecl.php.net channel + if (!class_exists('PEAR_Dependency2')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; + } + + $newdep = PEAR_Dependency2::normalizeDep($dep); + $newdep = $newdep[0]; + $newdep['channel'] = 'pecl.php.net'; + $chan = 'pecl.php.net'; + $url = $this->_downloader->_getDepPackageDownloadUrl($newdep, $pname); + $obj = &$this->_installRegistry->getPackage($dep['name']); + if (PEAR::isError($url)) { + PEAR::popErrorHandling(); + if ($obj !== null && $this->isInstalled($obj, $dep['rel'])) { + $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ? + 'required' : + 'optional'; + $dep['package'] = $dep['name']; + if (!isset($options['soft'])) { + $this->_downloader->log(3, $this->getShortName() . + ': Skipping ' . $group . ' dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '", already installed as version ' . $obj->getVersion()); + } + $skip = count($skipnames) ? + $skipnames[count($skipnames) - 1] : ''; + if ($skip == + $this->_registry->parsedPackageNameToString($dep, true)) { + array_pop($skipnames); + } + continue; + } else { + if (isset($dep['optional']) && $dep['optional'] == 'yes') { + $this->_downloader->log(2, $this->getShortName() . + ': Skipping optional dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '", no releases exist'); + continue; + } else { + return $url; + } + } + } + } + + PEAR::popErrorHandling(); + if (!isset($options['alldeps'])) { + if (isset($dep['optional']) && $dep['optional'] == 'yes') { + if (!isset($options['soft'])) { + $this->_downloader->log(3, 'Notice: package "' . + $this->getShortName() . + '" optional dependency "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $chan, 'package' => + $dep['name']), true) . + '" will not be automatically downloaded'); + } + $skipnames[] = $this->_registry->parsedPackageNameToString( + array('channel' => $chan, 'package' => + $dep['name']), true); + $nodownload = true; + } + } - $this->_options = $installoptions; - $this->_state = $state; - if (!class_exists('OS_Guess')) { - require_once 'phar://install-pear-nozlib.phar/' . 'OS/Guess.php'; - } + if (!isset($options['alldeps']) && !isset($options['onlyreqdeps'])) { + if (!isset($dep['optional']) || $dep['optional'] == 'no') { + if (!isset($options['soft'])) { + $this->_downloader->log(3, 'Notice: package "' . + $this->getShortName() . + '" required dependency "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $chan, 'package' => + $dep['name']), true) . + '" will not be automatically downloaded'); + } + $skipnames[] = $this->_registry->parsedPackageNameToString( + array('channel' => $chan, 'package' => + $dep['name']), true); + $nodownload = true; + } + } - $this->_os = new OS_Guess; - $this->_currentPackage = $package; - } + // check to see if a dep is already installed + // do not try to move this before getDepPackageDownloadURL + // we can't determine whether upgrade is necessary until we know what + // version would be downloaded + if (!isset($options['force']) && $this->isInstalled( + $url, $dep['rel'])) { + $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ? + 'required' : + 'optional'; + $dep['package'] = $dep['name']; + if (isset($newdep)) { + $version = $this->_installRegistry->packageInfo($newdep['name'], 'version', $newdep['channel']); + } else { + $version = $this->_installRegistry->packageInfo($dep['name'], 'version'); + } - function _getExtraString($dep) - { - $extra = ' ('; - if (isset($dep['uri'])) { - return ''; - } + $dep['version'] = $url['version']; + if (!isset($options['soft'])) { + $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group . + ' dependency "' . + $this->_registry->parsedPackageNameToString($dep, true) . + '", already installed as version ' . $version); + } - if (isset($dep['recommended'])) { - $extra .= 'recommended version ' . $dep['recommended']; - } else { - if (isset($dep['min'])) { - $extra .= 'version >= ' . $dep['min']; - } + $skip = count($skipnames) ? + $skipnames[count($skipnames) - 1] : ''; + if ($skip == + $this->_registry->parsedPackageNameToString($dep, true)) { + array_pop($skipnames); + } - if (isset($dep['max'])) { - if ($extra != ' (') { - $extra .= ', '; + continue; } - $extra .= 'version <= ' . $dep['max']; - } - if (isset($dep['exclude'])) { - if (!is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); + if ($nodownload) { + continue; } - if ($extra != ' (') { - $extra .= ', '; + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + if (isset($newdep)) { + $dep = $newdep; } - $extra .= 'excluded versions: '; - foreach ($dep['exclude'] as $i => $exclude) { - if ($i) { - $extra .= ', '; + $dep['package'] = $dep['name']; + $ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params, + isset($dep['optional']) && $dep['optional'] == 'yes' && + !isset($options['alldeps']), true); + PEAR::popErrorHandling(); + if (PEAR::isError($ret)) { + if (!isset($options['soft'])) { + $this->_downloader->log(0, $ret->getMessage()); } - $extra .= $exclude; + continue; } + + $this->_downloadDeps[] = $ret; } } - $extra .= ')'; - if ($extra == ' ()') { - $extra = ''; + if (count($skipnames)) { + if (!isset($options['soft'])) { + $this->_downloader->log(1, 'Did not download dependencies: ' . + implode(', ', $skipnames) . + ', use --alldeps or --onlyreqdeps to download automatically'); + } } - - return $extra; } - /** - * This makes unit-testing a heck of a lot easier - */ - function getPHP_OS() + function setDownloadURL($pkg) { - return PHP_OS; + $this->_downloadURL = $pkg; } /** - * This makes unit-testing a heck of a lot easier + * Set the package.xml object for this downloaded package + * + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 $pkg */ - function getsysname() + function setPackageFile(&$pkg) { - return $this->_os->getSysname(); + $this->_packagefile = &$pkg; } - /** - * Specify a dependency on an OS. Use arch for detailed os/processor information - * - * There are two generic OS dependencies that will be the most common, unix and windows. - * Other options are linux, freebsd, darwin (OS X), sunos, irix, hpux, aix - */ - function validateOsDependency($dep) + function getShortName() { - if ($this->_state != PEAR_VALIDATE_INSTALLING && $this->_state != PEAR_VALIDATE_DOWNLOADING) { - return true; - } + return $this->_registry->parsedPackageNameToString(array('channel' => $this->getChannel(), + 'package' => $this->getPackage()), true); + } - if ($dep['name'] == '*') { - return true; + function getParsedPackage() + { + if (isset($this->_packagefile) || isset($this->_parsedname)) { + return array('channel' => $this->getChannel(), + 'package' => $this->getPackage(), + 'version' => $this->getVersion()); } - $not = isset($dep['conflicts']) ? true : false; - switch (strtolower($dep['name'])) { - case 'windows' : - if ($not) { - if (strtolower(substr($this->getPHP_OS(), 0, 3)) == 'win') { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError("Cannot install %s on Windows"); - } - - return $this->warning("warning: Cannot install %s on Windows"); - } - } else { - if (strtolower(substr($this->getPHP_OS(), 0, 3)) != 'win') { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError("Can only install %s on Windows"); - } - - return $this->warning("warning: Can only install %s on Windows"); - } - } - break; - case 'unix' : - $unices = array('linux', 'freebsd', 'darwin', 'sunos', 'irix', 'hpux', 'aix'); - if ($not) { - if (in_array($this->getSysname(), $unices)) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError("Cannot install %s on any Unix system"); - } - - return $this->warning( "warning: Cannot install %s on any Unix system"); - } - } else { - if (!in_array($this->getSysname(), $unices)) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError("Can only install %s on a Unix system"); - } - - return $this->warning("warning: Can only install %s on a Unix system"); - } - } - break; - default : - if ($not) { - if (strtolower($dep['name']) == strtolower($this->getSysname())) { - if (!isset($this->_options['nodeps']) && - !isset($this->_options['force'])) { - return $this->raiseError('Cannot install %s on ' . $dep['name'] . - ' operating system'); - } + return false; + } - return $this->warning('warning: Cannot install %s on ' . - $dep['name'] . ' operating system'); - } - } else { - if (strtolower($dep['name']) != strtolower($this->getSysname())) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('Cannot install %s on ' . - $this->getSysname() . - ' operating system, can only install on ' . $dep['name']); - } + function getDownloadURL() + { + return $this->_downloadURL; + } - return $this->warning('warning: Cannot install %s on ' . - $this->getSysname() . - ' operating system, can only install on ' . $dep['name']); - } - } + function canDefault() + { + if (isset($this->_downloadURL) && isset($this->_downloadURL['nodefault'])) { + return false; } + return true; } - /** - * This makes unit-testing a heck of a lot easier - */ - function matchSignature($pattern) + function getPackage() { - return $this->_os->matchSignature($pattern); + if (isset($this->_packagefile)) { + return $this->_packagefile->getPackage(); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->getPackage(); + } + + return false; } /** - * Specify a complex dependency on an OS/processor/kernel version, - * Use OS for simple operating system dependency. - * - * This is the only dependency that accepts an eregable pattern. The pattern - * will be matched against the php_uname() output parsed by OS_Guess + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 */ - function validateArchDependency($dep) + function isSubpackage(&$pf) { - if ($this->_state != PEAR_VALIDATE_INSTALLING) { - return true; + if (isset($this->_packagefile)) { + return $this->_packagefile->isSubpackage($pf); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->isSubpackage($pf); } - $not = isset($dep['conflicts']) ? true : false; - if (!$this->matchSignature($dep['pattern'])) { - if (!$not) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s Architecture dependency failed, does not ' . - 'match "' . $dep['pattern'] . '"'); - } - - return $this->warning('warning: %s Architecture dependency failed, does ' . - 'not match "' . $dep['pattern'] . '"'); - } + return false; + } - return true; + function getPackageType() + { + if (isset($this->_packagefile)) { + return $this->_packagefile->getPackageType(); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->getPackageType(); } - if ($not) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s Architecture dependency failed, required "' . - $dep['pattern'] . '"'); - } + return false; + } - return $this->warning('warning: %s Architecture dependency failed, ' . - 'required "' . $dep['pattern'] . '"'); + function isBundle() + { + if (isset($this->_packagefile)) { + return $this->_packagefile->getPackageType() == 'bundle'; } - return true; + return false; } - /** - * This makes unit-testing a heck of a lot easier - */ - function extension_loaded($name) + function getPackageXmlVersion() { - return extension_loaded($name); + if (isset($this->_packagefile)) { + return $this->_packagefile->getPackagexmlVersion(); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->getPackagexmlVersion(); + } + + return '1.0'; } - /** - * This makes unit-testing a heck of a lot easier - */ - function phpversion($name = null) + function getChannel() { - if ($name !== null) { - return phpversion($name); + if (isset($this->_packagefile)) { + return $this->_packagefile->getChannel(); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->getChannel(); } - return phpversion(); + return false; } - function validateExtensionDependency($dep, $required = true) + function getURI() { - if ($this->_state != PEAR_VALIDATE_INSTALLING && - $this->_state != PEAR_VALIDATE_DOWNLOADING) { - return true; + if (isset($this->_packagefile)) { + return $this->_packagefile->getURI(); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->getURI(); } - $loaded = $this->extension_loaded($dep['name']); - $extra = $this->_getExtraString($dep); - if (isset($dep['exclude'])) { - if (!is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); - } + return false; + } + + function getVersion() + { + if (isset($this->_packagefile)) { + return $this->_packagefile->getVersion(); + } elseif (isset($this->_downloadURL['version'])) { + return $this->_downloadURL['version']; } - if (!isset($dep['min']) && !isset($dep['max']) && - !isset($dep['recommended']) && !isset($dep['exclude'])) { - if ($loaded) { - if (isset($dep['conflicts'])) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s conflicts with PHP extension "' . - $dep['name'] . '"' . $extra); - } + return false; + } - return $this->warning('warning: %s conflicts with PHP extension "' . - $dep['name'] . '"' . $extra); - } + function isCompatible($pf) + { + if (isset($this->_packagefile)) { + return $this->_packagefile->isCompatible($pf); + } elseif (isset($this->_downloadURL['info'])) { + return $this->_downloadURL['info']->isCompatible($pf); + } - return true; - } else { - if (isset($dep['conflicts'])) { - return true; - } + return true; + } - if ($required) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PHP extension "' . - $dep['name'] . '"' . $extra); - } + function setGroup($group) + { + $this->_parsedname['group'] = $group; + } - return $this->warning('warning: %s requires PHP extension "' . - $dep['name'] . '"' . $extra); - } + function getGroup() + { + if (isset($this->_parsedname['group'])) { + return $this->_parsedname['group']; + } - return $this->warning('%s can optionally use PHP extension "' . - $dep['name'] . '"' . $extra); + return ''; + } + + function isExtension($name) + { + if (isset($this->_packagefile)) { + return $this->_packagefile->isExtension($name); + } elseif (isset($this->_downloadURL['info'])) { + if ($this->_downloadURL['info']->getPackagexmlVersion() == '2.0') { + return $this->_downloadURL['info']->getProvidesExtension() == $name; } + + return false; } - if (!$loaded) { - if (isset($dep['conflicts'])) { - return true; - } + return false; + } - if (!$required) { - return $this->warning('%s can optionally use PHP extension "' . - $dep['name'] . '"' . $extra); + function getDeps() + { + if (isset($this->_packagefile)) { + $ver = $this->_packagefile->getPackagexmlVersion(); + if (version_compare($ver, '2.0', '>=')) { + return $this->_packagefile->getDeps(true); } - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PHP extension "' . $dep['name'] . - '"' . $extra); + return $this->_packagefile->getDeps(); + } elseif (isset($this->_downloadURL['info'])) { + $ver = $this->_downloadURL['info']->getPackagexmlVersion(); + if (version_compare($ver, '2.0', '>=')) { + return $this->_downloadURL['info']->getDeps(true); } - return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . - '"' . $extra); - } - - $version = (string) $this->phpversion($dep['name']); - if (empty($version)) { - $version = '0'; - } - - $fail = false; - if (isset($dep['min']) && !version_compare($version, $dep['min'], '>=')) { - $fail = true; + return $this->_downloadURL['info']->getDeps(); } - if (isset($dep['max']) && !version_compare($version, $dep['max'], '<=')) { - $fail = true; - } + return array(); + } - if ($fail && !isset($dep['conflicts'])) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PHP extension "' . $dep['name'] . - '"' . $extra . ', installed version is ' . $version); + /** + * @param array Parsed array from {@link PEAR_Registry::parsePackageName()} or a dependency + * returned from getDepDownloadURL() + */ + function isEqual($param) + { + if (is_object($param)) { + $channel = $param->getChannel(); + $package = $param->getPackage(); + if ($param->getURI()) { + $param = array( + 'channel' => $param->getChannel(), + 'package' => $param->getPackage(), + 'version' => $param->getVersion(), + 'uri' => $param->getURI(), + ); + } else { + $param = array( + 'channel' => $param->getChannel(), + 'package' => $param->getPackage(), + 'version' => $param->getVersion(), + ); } - - return $this->warning('warning: %s requires PHP extension "' . $dep['name'] . - '"' . $extra . ', installed version is ' . $version); - } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && isset($dep['conflicts'])) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s conflicts with PHP extension "' . - $dep['name'] . '"' . $extra . ', installed version is ' . $version); + } else { + if (isset($param['uri'])) { + if ($this->getChannel() != '__uri') { + return false; + } + return $param['uri'] == $this->getURI(); } - return $this->warning('warning: %s conflicts with PHP extension "' . - $dep['name'] . '"' . $extra . ', installed version is ' . $version); + $package = isset($param['package']) ? $param['package'] : $param['info']->getPackage(); + $channel = isset($param['channel']) ? $param['channel'] : $param['info']->getChannel(); + if (isset($param['rel'])) { + if (!class_exists('PEAR_Dependency2')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; + } + + $newdep = PEAR_Dependency2::normalizeDep($param); + $newdep = $newdep[0]; + } elseif (isset($param['min'])) { + $newdep = $param; + } } - if (isset($dep['exclude'])) { - foreach ($dep['exclude'] as $exclude) { - if (version_compare($version, $exclude, '==')) { - if (isset($dep['conflicts'])) { - continue; - } - - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s is not compatible with PHP extension "' . - $dep['name'] . '" version ' . - $exclude); - } + if (isset($newdep)) { + if (!isset($newdep['min'])) { + $newdep['min'] = '0'; + } - return $this->warning('warning: %s is not compatible with PHP extension "' . - $dep['name'] . '" version ' . - $exclude); - } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s conflicts with PHP extension "' . - $dep['name'] . '"' . $extra . ', installed version is ' . $version); - } + if (!isset($newdep['max'])) { + $newdep['max'] = '100000000000000000000'; + } - return $this->warning('warning: %s conflicts with PHP extension "' . - $dep['name'] . '"' . $extra . ', installed version is ' . $version); + // use magic to support pecl packages suddenly jumping to the pecl channel + // we need to support both dependency possibilities + if ($channel == 'pear.php.net' && $this->getChannel() == 'pecl.php.net') { + if ($package == $this->getPackage()) { + $channel = 'pecl.php.net'; } } - } - - if (isset($dep['recommended'])) { - if (version_compare($version, $dep['recommended'], '==')) { - return true; + if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') { + if ($package == $this->getPackage()) { + $channel = 'pear.php.net'; + } } - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s dependency: PHP extension ' . $dep['name'] . - ' version "' . $version . '"' . - ' is not the recommended version "' . $dep['recommended'] . - '", but may be compatible, use --force to install'); + return (strtolower($package) == strtolower($this->getPackage()) && + $channel == $this->getChannel() && + version_compare($newdep['min'], $this->getVersion(), '<=') && + version_compare($newdep['max'], $this->getVersion(), '>=')); + } + + // use magic to support pecl packages suddenly jumping to the pecl channel + if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') { + if (strtolower($package) == strtolower($this->getPackage())) { + $channel = 'pear.php.net'; } + } - return $this->warning('warning: %s dependency: PHP extension ' . - $dep['name'] . ' version "' . $version . '"' . - ' is not the recommended version "' . $dep['recommended'].'"'); + if (isset($param['version'])) { + return (strtolower($package) == strtolower($this->getPackage()) && + $channel == $this->getChannel() && + $param['version'] == $this->getVersion()); } - return true; + return strtolower($package) == strtolower($this->getPackage()) && + $channel == $this->getChannel(); } - function validatePhpDependency($dep) + function isInstalled($dep, $oper = '==') { - if ($this->_state != PEAR_VALIDATE_INSTALLING && - $this->_state != PEAR_VALIDATE_DOWNLOADING) { - return true; + if (!$dep) { + return false; } - $version = $this->phpversion(); - $extra = $this->_getExtraString($dep); - if (isset($dep['exclude'])) { - if (!is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); - } + if ($oper != 'ge' && $oper != 'gt' && $oper != 'has' && $oper != '==') { + return false; } - if (isset($dep['min'])) { - if (!version_compare($version, $dep['min'], '>=')) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PHP' . - $extra . ', installed version is ' . $version); - } - - return $this->warning('warning: %s requires PHP' . - $extra . ', installed version is ' . $version); + if (is_object($dep)) { + $package = $dep->getPackage(); + $channel = $dep->getChannel(); + if ($dep->getURI()) { + $dep = array( + 'uri' => $dep->getURI(), + 'version' => $dep->getVersion(), + ); + } else { + $dep = array( + 'version' => $dep->getVersion(), + ); + } + } else { + if (isset($dep['uri'])) { + $channel = '__uri'; + $package = $dep['dep']['name']; + } else { + $channel = $dep['info']->getChannel(); + $package = $dep['info']->getPackage(); } } - if (isset($dep['max'])) { - if (!version_compare($version, $dep['max'], '<=')) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PHP' . - $extra . ', installed version is ' . $version); - } - - return $this->warning('warning: %s requires PHP' . - $extra . ', installed version is ' . $version); - } + $options = $this->_downloader->getOptions(); + $test = $this->_installRegistry->packageExists($package, $channel); + if (!$test && $channel == 'pecl.php.net') { + // do magic to allow upgrading from old pecl packages to new ones + $test = $this->_installRegistry->packageExists($package, 'pear.php.net'); + $channel = 'pear.php.net'; } - if (isset($dep['exclude'])) { - foreach ($dep['exclude'] as $exclude) { - if (version_compare($version, $exclude, '==')) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s is not compatible with PHP version ' . - $exclude); - } + if ($test) { + if (isset($dep['uri'])) { + if ($this->_installRegistry->packageInfo($package, 'uri', '__uri') == $dep['uri']) { + return true; + } + } - return $this->warning( - 'warning: %s is not compatible with PHP version ' . - $exclude); + if (isset($options['upgrade'])) { + $packageVersion = $this->_installRegistry->packageInfo($package, 'version', $channel); + if (version_compare($packageVersion, $dep['version'], '>=')) { + return true; } + + return false; } + + return true; } - return true; + return false; } /** - * This makes unit-testing a heck of a lot easier + * Detect duplicate package names with differing versions + * + * If a user requests to install Date 1.4.6 and Date 1.4.7, + * for instance, this is a logic error. This method + * detects this situation. + * + * @param array $params array of PEAR_Downloader_Package objects + * @param array $errorparams empty array + * @return array array of stupid duplicated packages in PEAR_Downloader_Package obejcts */ - function getPEARVersion() - { - return '1.8.0'; - } - - function validatePearinstallerDependency($dep) + function detectStupidDuplicates($params, &$errorparams) { - $pearversion = $this->getPEARVersion(); - $extra = $this->_getExtraString($dep); - if (isset($dep['exclude'])) { - if (!is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); + $existing = array(); + foreach ($params as $i => $param) { + $package = $param->getPackage(); + $channel = $param->getChannel(); + $group = $param->getGroup(); + if (!isset($existing[$channel . '/' . $package])) { + $existing[$channel . '/' . $package] = array(); } - } - if (version_compare($pearversion, $dep['min'], '<')) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PEAR Installer' . $extra . - ', installed version is ' . $pearversion); + if (!isset($existing[$channel . '/' . $package][$group])) { + $existing[$channel . '/' . $package][$group] = array(); } - return $this->warning('warning: %s requires PEAR Installer' . $extra . - ', installed version is ' . $pearversion); + $existing[$channel . '/' . $package][$group][] = $i; } - if (isset($dep['max'])) { - if (version_compare($pearversion, $dep['max'], '>')) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires PEAR Installer' . $extra . - ', installed version is ' . $pearversion); + $indices = array(); + foreach ($existing as $package => $groups) { + foreach ($groups as $group => $dupes) { + if (count($dupes) > 1) { + $indices = $indices + $dupes; } - - return $this->warning('warning: %s requires PEAR Installer' . $extra . - ', installed version is ' . $pearversion); } } - if (isset($dep['exclude'])) { - if (!isset($dep['exclude'][0])) { - $dep['exclude'] = array($dep['exclude']); - } - - foreach ($dep['exclude'] as $exclude) { - if (version_compare($exclude, $pearversion, '==')) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s is not compatible with PEAR Installer ' . - 'version ' . $exclude); - } - - return $this->warning('warning: %s is not compatible with PEAR ' . - 'Installer version ' . $exclude); - } - } + $indices = array_unique($indices); + foreach ($indices as $index) { + $errorparams[] = $params[$index]; } - return true; - } - - function validateSubpackageDependency($dep, $required, $params) - { - return $this->validatePackageDependency($dep, $required, $params); + return count($errorparams); } /** - * @param array dependency information (2.0 format) - * @param boolean whether this is a required dependency - * @param array a list of downloaded packages to be installed, if any - * @param boolean if true, then deps on pear.php.net that fail will also check - * against pecl.php.net packages to accomodate extensions that have - * moved to pecl.php.net from pear.php.net + * @param array + * @param bool ignore install groups - for final removal of dupe packages + * @static */ - function validatePackageDependency($dep, $required, $params, $depv1 = false) + function removeDuplicates(&$params, $ignoreGroups = false) { - if ($this->_state != PEAR_VALIDATE_INSTALLING && - $this->_state != PEAR_VALIDATE_DOWNLOADING) { - return true; - } - - if (isset($dep['providesextension'])) { - if ($this->extension_loaded($dep['providesextension'])) { - $save = $dep; - $subdep = $dep; - $subdep['name'] = $subdep['providesextension']; - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $ret = $this->validateExtensionDependency($subdep, $required); - PEAR::popErrorHandling(); - if (!PEAR::isError($ret)) { - return true; - } + $pnames = array(); + foreach ($params as $i => $param) { + if (!$param) { + continue; } - } - - if ($this->_state == PEAR_VALIDATE_INSTALLING) { - return $this->_validatePackageInstall($dep, $required, $depv1); - } - - if ($this->_state == PEAR_VALIDATE_DOWNLOADING) { - return $this->_validatePackageDownload($dep, $required, $params, $depv1); - } - } - function _validatePackageDownload($dep, $required, $params, $depv1 = false) - { - $dep['package'] = $dep['name']; - if (isset($dep['uri'])) { - $dep['channel'] = '__uri'; + if ($param->getPackage()) { + $group = $ignoreGroups ? '' : $param->getGroup(); + $pnames[$i] = $param->getChannel() . '/' . + $param->getPackage() . '-' . $param->getVersion() . '#' . $group; + } } - $depname = $this->_registry->parsedPackageNameToString($dep, true); - $found = false; - foreach ($params as $param) { - if ($param->isEqual( - array('package' => $dep['name'], - 'channel' => $dep['channel']))) { - $found = true; - break; + $pnames = array_unique($pnames); + $unset = array_diff(array_keys($params), array_keys($pnames)); + $testp = array_flip($pnames); + foreach ($params as $i => $param) { + if (!$param) { + $unset[] = $i; + continue; } - if ($depv1 && $dep['channel'] == 'pear.php.net') { - if ($param->isEqual( - array('package' => $dep['name'], - 'channel' => 'pecl.php.net'))) { - $found = true; - break; - } + if (!is_a($param, 'PEAR_Downloader_Package')) { + $unset[] = $i; + continue; } - } - if (!$found && isset($dep['providesextension'])) { - foreach ($params as $param) { - if ($param->isExtension($dep['providesextension'])) { - $found = true; - break; - } + $group = $ignoreGroups ? '' : $param->getGroup(); + if (!isset($testp[$param->getChannel() . '/' . $param->getPackage() . '-' . + $param->getVersion() . '#' . $group])) { + $unset[] = $i; } } - if ($found) { - $version = $param->getVersion(); - $installed = false; - $downloaded = true; - } else { - if ($this->_registry->packageExists($dep['name'], $dep['channel'])) { - $installed = true; - $downloaded = false; - $version = $this->_registry->packageinfo($dep['name'], 'version', - $dep['channel']); - } else { - if ($dep['channel'] == 'pecl.php.net' && $this->_registry->packageExists($dep['name'], - 'pear.php.net')) { - $installed = true; - $downloaded = false; - $version = $this->_registry->packageinfo($dep['name'], 'version', - 'pear.php.net'); - } else { - $version = 'not installed or downloaded'; - $installed = false; - $downloaded = false; - } - } + foreach ($unset as $i) { + unset($params[$i]); } - $extra = $this->_getExtraString($dep); - if (isset($dep['exclude']) && !is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); + $ret = array(); + foreach ($params as $i => $param) { + $ret[] = &$params[$i]; } - if (!isset($dep['min']) && !isset($dep['max']) && - !isset($dep['recommended']) && !isset($dep['exclude']) - ) { - if ($installed || $downloaded) { - $installed = $installed ? 'installed' : 'downloaded'; - if (isset($dep['conflicts'])) { - $rest = ''; - if ($version) { - $rest = ", $installed version is " . $version; - } + $params = array(); + foreach ($ret as $i => $param) { + $params[] = &$ret[$i]; + } + } - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . $rest); - } + function explicitState() + { + return $this->_explicitState; + } - return $this->warning('warning: %s conflicts with package "' . $depname . '"' . $extra . $rest); - } + function setExplicitState($s) + { + $this->_explicitState = $s; + } - return true; + /** + * @static + */ + function mergeDependencies(&$params) + { + $bundles = $newparams = array(); + foreach ($params as $i => $param) { + if (!$param->isBundle()) { + continue; } - if (isset($dep['conflicts'])) { - return true; + $bundles[] = $i; + $pf = &$param->getPackageFile(); + $newdeps = array(); + $contents = $pf->getBundledPackages(); + if (!is_array($contents)) { + $contents = array($contents); } - if ($required) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires package "' . $depname . '"' . $extra); + foreach ($contents as $file) { + $filecontents = $pf->getFileContents($file); + $dl = &$param->getDownloader(); + $options = $dl->getOptions(); + if (PEAR::isError($dir = $dl->getDownloadDir())) { + return $dir; } - return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); - } + $fp = @fopen($dir . DIRECTORY_SEPARATOR . $file, 'wb'); + if (!$fp) { + continue; + } - return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); - } + fwrite($fp, $filecontents, strlen($filecontents)); + fclose($fp); + if ($s = $params[$i]->explicitState()) { + $obj->setExplicitState($s); + } - if (!$installed && !$downloaded) { - if (isset($dep['conflicts'])) { - return true; - } + $obj = &new PEAR_Downloader_Package($params[$i]->getDownloader()); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + if (PEAR::isError($dir = $dl->getDownloadDir())) { + PEAR::popErrorHandling(); + return $dir; + } - if ($required) { - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires package "' . $depname . '"' . $extra); + $e = $obj->_fromFile($a = $dir . DIRECTORY_SEPARATOR . $file); + PEAR::popErrorHandling(); + if (PEAR::isError($e)) { + if (!isset($options['soft'])) { + $dl->log(0, $e->getMessage()); + } + continue; } - return $this->warning('warning: %s requires package "' . $depname . '"' . $extra); + $j = &$obj; + if (!PEAR_Downloader_Package::willDownload($j, + array_merge($params, $newparams)) && !$param->isInstalled($j)) { + $newparams[] = &$j; + } } - - return $this->warning('%s can optionally use package "' . $depname . '"' . $extra); - } - - $fail = false; - if (isset($dep['min']) && version_compare($version, $dep['min'], '<')) { - $fail = true; } - if (isset($dep['max']) && version_compare($version, $dep['max'], '>')) { - $fail = true; + foreach ($bundles as $i) { + unset($params[$i]); // remove bundles - only their contents matter for installation } - if ($fail && !isset($dep['conflicts'])) { - $installed = $installed ? 'installed' : 'downloaded'; - $dep['package'] = $dep['name']; - $dep = $this->_registry->parsedPackageNameToString($dep, true); - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s requires package "' . $depname . '"' . - $extra . ", $installed version is " . $version); - } - - return $this->warning('warning: %s requires package "' . $depname . '"' . - $extra . ", $installed version is " . $version); - } elseif ((isset($dep['min']) || isset($dep['max'])) && !$fail && - isset($dep['conflicts']) && !isset($dep['exclude'])) { - $installed = $installed ? 'installed' : 'downloaded'; - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s conflicts with package "' . $depname . '"' . $extra . - ", $installed version is " . $version); + PEAR_Downloader_Package::removeDuplicates($params); // strip any unset indices + if (count($newparams)) { // add in bundled packages for install + foreach ($newparams as $i => $unused) { + $params[] = &$newparams[$i]; } - - return $this->warning('warning: %s conflicts with package "' . $depname . '"' . - $extra . ", $installed version is " . $version); + $newparams = array(); } - if (isset($dep['exclude'])) { - $installed = $installed ? 'installed' : 'downloaded'; - foreach ($dep['exclude'] as $exclude) { - if (version_compare($version, $exclude, '==') && !isset($dep['conflicts'])) { - if (!isset($this->_options['nodeps']) && - !isset($this->_options['force']) - ) { - return $this->raiseError('%s is not compatible with ' . - $installed . ' package "' . - $depname . '" version ' . - $exclude); - } - - return $this->warning('warning: %s is not compatible with ' . - $installed . ' package "' . - $depname . '" version ' . - $exclude); - } elseif (version_compare($version, $exclude, '!=') && isset($dep['conflicts'])) { - $installed = $installed ? 'installed' : 'downloaded'; - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('%s conflicts with package "' . $depname . '"' . - $extra . ", $installed version is " . $version); - } - - return $this->warning('warning: %s conflicts with package "' . $depname . '"' . - $extra . ", $installed version is " . $version); + foreach ($params as $i => $param) { + $newdeps = array(); + foreach ($param->_downloadDeps as $dep) { + $merge = array_merge($params, $newparams); + if (!PEAR_Downloader_Package::willDownload($dep, $merge) + && !$param->isInstalled($dep) + ) { + $newdeps[] = $dep; + } else { + //var_dump($dep); + // detect versioning conflicts here } } - } - - if (isset($dep['recommended'])) { - $installed = $installed ? 'installed' : 'downloaded'; - if (version_compare($version, $dep['recommended'], '==')) { - return true; - } - if (!$found && $installed) { - $param = $this->_registry->getPackage($dep['name'], $dep['channel']); - } + // convert the dependencies into PEAR_Downloader_Package objects for the next time around + $params[$i]->_downloadDeps = array(); + foreach ($newdeps as $dep) { + $obj = &new PEAR_Downloader_Package($params[$i]->getDownloader()); + if ($s = $params[$i]->explicitState()) { + $obj->setExplicitState($s); + } - if ($param) { - $found = false; - foreach ($params as $parent) { - if ($parent->isEqual($this->_currentPackage)) { - $found = true; - break; + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $e = $obj->fromDepURL($dep); + PEAR::popErrorHandling(); + if (PEAR::isError($e)) { + if (!isset($options['soft'])) { + $obj->_downloader->log(0, $e->getMessage()); } + continue; } - if ($found) { - if ($param->isCompatible($parent)) { - return true; - } - } else { // this is for validPackage() calls - $parent = $this->_registry->getPackage($this->_currentPackage['package'], - $this->_currentPackage['channel']); - if ($parent !== null && $param->isCompatible($parent)) { - return true; + $e = $obj->detectDependencies($params); + if (PEAR::isError($e)) { + if (!isset($options['soft'])) { + $obj->_downloader->log(0, $e->getMessage()); } } - } - if (!isset($this->_options['nodeps']) && !isset($this->_options['force']) && - !isset($this->_options['loose']) - ) { - return $this->raiseError('%s dependency package "' . $depname . - '" ' . $installed . ' version ' . $version . - ' is not the recommended version ' . $dep['recommended'] . - ', but may be compatible, use --force to install'); + $j = &$obj; + $newparams[] = &$j; } + } - return $this->warning('warning: %s dependency package "' . $depname . - '" ' . $installed . ' version ' . $version . - ' is not the recommended version ' . $dep['recommended']); + if (count($newparams)) { + foreach ($newparams as $i => $unused) { + $params[] = &$newparams[$i]; + } + return true; } - return true; + return false; } - function _validatePackageInstall($dep, $required, $depv1 = false) - { - return $this->_validatePackageDownload($dep, $required, array(), $depv1); - } /** - * Verify that uninstalling packages passed in to command line is OK. - * - * @param PEAR_Installer $dl - * @return PEAR_Error|true + * @static */ - function validatePackageUninstall(&$dl) + function willDownload($param, $params) { - if (PEAR::isError($this->_dependencydb)) { - return $this->_dependencydb; + if (!is_array($params)) { + return false; } - $params = array(); - // construct an array of "downloaded" packages to fool the package dependency checker - // into using these to validate uninstalls of circular dependencies - $downloaded = &$dl->getUninstallPackages(); - foreach ($downloaded as $i => $pf) { - if (!class_exists('PEAR_Downloader_Package')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Downloader/Package.php'; + foreach ($params as $obj) { + if ($obj->isEqual($param)) { + return true; } - $dp = &new PEAR_Downloader_Package($dl); - $dp->setPackageFile($downloaded[$i]); - $params[$i] = &$dp; } - // check cache - $memyselfandI = strtolower($this->_currentPackage['channel']) . '/' . - strtolower($this->_currentPackage['package']); - if (isset($dl->___uninstall_package_cache)) { - $badpackages = $dl->___uninstall_package_cache; - if (isset($badpackages[$memyselfandI]['warnings'])) { - foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { - $dl->log(0, $warning[0]); - } - } + return false; + } - if (isset($badpackages[$memyselfandI]['errors'])) { - foreach ($badpackages[$memyselfandI]['errors'] as $error) { - if (is_array($error)) { - $dl->log(0, $error[0]); - } else { - $dl->log(0, $error->getMessage()); - } - } + /** + * For simpler unit-testing + * @param PEAR_Config + * @param int + * @param string + */ + function &getPackagefileObject(&$c, $d, $t = false) + { + $a = &new PEAR_PackageFile($c, $d, $t); + return $a; + } - if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { - return $this->warning( - 'warning: %s should not be uninstalled, other installed packages depend ' . - 'on this package'); - } - return $this->raiseError( - '%s cannot be uninstalled, other installed packages depend on this package'); + /** + * This will retrieve from a local file if possible, and parse out + * a group name as well. The original parameter will be modified to reflect this. + * @param string|array can be a parsed package name as well + * @access private + */ + function _fromFile(&$param) + { + $saveparam = $param; + if (is_string($param)) { + if (!@file_exists($param)) { + $test = explode('#', $param); + $group = array_pop($test); + if (@file_exists(implode('#', $test))) { + $this->setGroup($group); + $param = implode('#', $test); + $this->_explicitGroup = true; + } } - return true; - } - - // first, list the immediate parents of each package to be uninstalled - $perpackagelist = array(); - $allparents = array(); - foreach ($params as $i => $param) { - $a = array( - 'channel' => strtolower($param->getChannel()), - 'package' => strtolower($param->getPackage()) - ); - - $deps = $this->_dependencydb->getDependentPackages($a); - if ($deps) { - foreach ($deps as $d) { - $pardeps = $this->_dependencydb->getDependencies($d); - foreach ($pardeps as $dep) { - if (strtolower($dep['dep']['channel']) == $a['channel'] && - strtolower($dep['dep']['name']) == $a['package']) { - if (!isset($perpackagelist[$a['channel'] . '/' . $a['package']])) { - $perpackagelist[$a['channel'] . '/' . $a['package']] = array(); - } - $perpackagelist[$a['channel'] . '/' . $a['package']][] - = array($d['channel'] . '/' . $d['package'], $dep); - if (!isset($allparents[$d['channel'] . '/' . $d['package']])) { - $allparents[$d['channel'] . '/' . $d['package']] = array(); - } - if (!isset($allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']])) { - $allparents[$d['channel'] . '/' . $d['package']][$a['channel'] . '/' . $a['package']] = array(); - } - $allparents[$d['channel'] . '/' . $d['package']] - [$a['channel'] . '/' . $a['package']][] - = array($d, $dep); - } + if (@is_file($param)) { + $this->_type = 'local'; + $options = $this->_downloader->getOptions(); + if (isset($options['downloadonly'])) { + $pkg = &$this->getPackagefileObject($this->_config, + $this->_downloader->_debug); + } else { + if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) { + return $dir; } + $pkg = &$this->getPackagefileObject($this->_config, + $this->_downloader->_debug, $dir); } - } - } - - // next, remove any packages from the parents list that are not installed - $remove = array(); - foreach ($allparents as $parent => $d1) { - foreach ($d1 as $d) { - if ($this->_registry->packageExists($d[0][0]['package'], $d[0][0]['channel'])) { - continue; + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $pf = &$pkg->fromAnyFile($param, PEAR_VALIDATE_INSTALLING); + PEAR::popErrorHandling(); + if (PEAR::isError($pf)) { + $this->_valid = false; + $param = $saveparam; + return $pf; } - $remove[$parent] = true; - } - } - - // next remove any packages from the parents list that are not passed in for - // uninstallation - foreach ($allparents as $parent => $d1) { - foreach ($d1 as $d) { - foreach ($params as $param) { - if (strtolower($param->getChannel()) == $d[0][0]['channel'] && - strtolower($param->getPackage()) == $d[0][0]['package']) { - // found it - continue 3; - } + $this->_packagefile = &$pf; + if (!$this->getGroup()) { + $this->setGroup('default'); // install the default dependency group } - $remove[$parent] = true; + return $this->_valid = true; } } + $param = $saveparam; + return $this->_valid = false; + } - // remove all packages whose dependencies fail - // save which ones failed for error reporting - $badchildren = array(); - do { - $fail = false; - foreach ($remove as $package => $unused) { - if (!isset($allparents[$package])) { - continue; - } + function _fromUrl($param, $saveparam = '') + { + if (!is_array($param) && (preg_match('#^(http|https|ftp)://#', $param))) { + $options = $this->_downloader->getOptions(); + $this->_type = 'url'; + $callback = $this->_downloader->ui ? + array(&$this->_downloader, '_downloadCallback') : null; + $this->_downloader->pushErrorHandling(PEAR_ERROR_RETURN); + if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) { + $this->_downloader->popErrorHandling(); + return $dir; + } - foreach ($allparents[$package] as $kid => $d1) { - foreach ($d1 as $depinfo) { - if ($depinfo[1]['type'] != 'optional') { - if (isset($badchildren[$kid])) { - continue; - } - $badchildren[$kid] = true; - $remove[$kid] = true; - $fail = true; - continue 2; - } - } - } - if ($fail) { - // start over, we removed some children - continue 2; + $this->_downloader->log(3, 'Downloading "' . $param . '"'); + $file = $this->_downloader->downloadHttp($param, $this->_downloader->ui, + $dir, $callback, null, false, $this->getChannel()); + $this->_downloader->popErrorHandling(); + if (PEAR::isError($file)) { + if (!empty($saveparam)) { + $saveparam = ", cannot download \"$saveparam\""; } + $err = PEAR::raiseError('Could not download from "' . $param . + '"' . $saveparam . ' (' . $file->getMessage() . ')'); + return $err; } - } while ($fail); - // next, construct the list of packages that can't be uninstalled - $badpackages = array(); - $save = $this->_currentPackage; - foreach ($perpackagelist as $package => $packagedeps) { - foreach ($packagedeps as $parent) { - if (!isset($remove[$parent[0]])) { - continue; + if ($this->_rawpackagefile) { + require_once 'phar://install-pear-nozlib.phar/' . 'Archive/Tar.php'; + $tar = &new Archive_Tar($file); + $packagexml = $tar->extractInString('package2.xml'); + if (!$packagexml) { + $packagexml = $tar->extractInString('package.xml'); } - $packagename = $this->_registry->parsePackageName($parent[0]); - $packagename['channel'] = $this->_registry->channelAlias($packagename['channel']); - $pa = $this->_registry->getPackage($packagename['package'], $packagename['channel']); - $packagename['package'] = $pa->getPackage(); - $this->_currentPackage = $packagename; - // parent is not present in uninstall list, make sure we can actually - // uninstall it (parent dep is optional) - $parentname['channel'] = $this->_registry->channelAlias($parent[1]['dep']['channel']); - $pa = $this->_registry->getPackage($parent[1]['dep']['name'], $parent[1]['dep']['channel']); - $parentname['package'] = $pa->getPackage(); - $parent[1]['dep']['package'] = $parentname['package']; - $parent[1]['dep']['channel'] = $parentname['channel']; - if ($parent[1]['type'] == 'optional') { - $test = $this->_validatePackageUninstall($parent[1]['dep'], false, $dl); - if ($test !== true) { - $badpackages[$package]['warnings'][] = $test; - } - } else { - $test = $this->_validatePackageUninstall($parent[1]['dep'], true, $dl); - if ($test !== true) { - $badpackages[$package]['errors'][] = $test; + if (str_replace(array("\n", "\r"), array('',''), $packagexml) != + str_replace(array("\n", "\r"), array('',''), $this->_rawpackagefile)) { + if ($this->getChannel() != 'pear.php.net') { + return PEAR::raiseError('CRITICAL ERROR: package.xml downloaded does ' . + 'not match value returned from xml-rpc'); } + + // be more lax for the existing PEAR packages that have not-ok + // characters in their package.xml + $this->_downloader->log(0, 'CRITICAL WARNING: The "' . + $this->getPackage() . '" package has invalid characters in its ' . + 'package.xml. The next version of PEAR may not be able to install ' . + 'this package for security reasons. Please open a bug report at ' . + 'http://pear.php.net/package/' . $this->getPackage() . '/bugs'); } } - } - $this->_currentPackage = $save; - $dl->___uninstall_package_cache = $badpackages; - if (isset($badpackages[$memyselfandI])) { - if (isset($badpackages[$memyselfandI]['warnings'])) { - foreach ($badpackages[$memyselfandI]['warnings'] as $warning) { - $dl->log(0, $warning[0]); + // whew, download worked! + if (isset($options['downloadonly'])) { + $pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug); + } else { + $dir = $this->_downloader->getDownloadDir(); + if (PEAR::isError($dir)) { + return $dir; } + $pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug, $dir); } - if (isset($badpackages[$memyselfandI]['errors'])) { - foreach ($badpackages[$memyselfandI]['errors'] as $error) { - if (is_array($error)) { - $dl->log(0, $error[0]); - } else { - $dl->log(0, $error->getMessage()); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $pf = &$pkg->fromAnyFile($file, PEAR_VALIDATE_INSTALLING); + PEAR::popErrorHandling(); + if (PEAR::isError($pf)) { + if (is_array($pf->getUserInfo())) { + foreach ($pf->getUserInfo() as $err) { + if (is_array($err)) { + $err = $err['message']; + } + + if (!isset($options['soft'])) { + $this->_downloader->log(0, "Validation Error: $err"); + } } } - if (isset($this->_options['nodeps']) || isset($this->_options['force'])) { - return $this->warning( - 'warning: %s should not be uninstalled, other installed packages depend ' . - 'on this package'); + if (!isset($options['soft'])) { + $this->_downloader->log(0, $pf->getMessage()); } - return $this->raiseError( - '%s cannot be uninstalled, other installed packages depend on this package'); - } - } - - return true; - } - - function _validatePackageUninstall($dep, $required, $dl) - { - $depname = $this->_registry->parsedPackageNameToString($dep, true); - $version = $this->_registry->packageinfo($dep['package'], 'version', $dep['channel']); - if (!$version) { - return true; - } - - $extra = $this->_getExtraString($dep); - if (isset($dep['exclude']) && !is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); - } - - if (isset($dep['conflicts'])) { - return true; // uninstall OK - these packages conflict (probably installed with --force) - } - - if (!isset($dep['min']) && !isset($dep['max'])) { - if (!$required) { - return $this->warning('"' . $depname . '" can be optionally used by ' . - 'installed package %s' . $extra); - } - - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError('"' . $depname . '" is required by ' . - 'installed package %s' . $extra); + ///FIXME need to pass back some error code that we can use to match with to cancel all further operations + /// At least stop all deps of this package from being installed + $out = $saveparam ? $saveparam : $param; + $err = PEAR::raiseError('Download of "' . $out . '" succeeded, but it is not a valid package archive'); + $this->_valid = false; + return $err; } - return $this->warning('warning: "' . $depname . '" is required by ' . - 'installed package %s' . $extra); - } - - $fail = false; - if (isset($dep['min']) && version_compare($version, $dep['min'], '>=')) { - $fail = true; - } - - if (isset($dep['max']) && version_compare($version, $dep['max'], '<=')) { - $fail = true; - } - - // we re-use this variable, preserve the original value - $saverequired = $required; - if (!$required) { - return $this->warning($depname . $extra . ' can be optionally used by installed package' . - ' "%s"'); - } - - if (!isset($this->_options['nodeps']) && !isset($this->_options['force'])) { - return $this->raiseError($depname . $extra . ' is required by installed package' . - ' "%s"'); + $this->_packagefile = &$pf; + $this->setGroup('default'); // install the default dependency group + return $this->_valid = true; } - return $this->raiseError('warning: ' . $depname . $extra . - ' is required by installed package "%s"'); + return $this->_valid = false; } /** - * validate a downloaded package against installed packages * - * As of PEAR 1.4.3, this will only validate - * - * @param array|PEAR_Downloader_Package|PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * $pkg package identifier (either - * array('package' => blah, 'channel' => blah) or an array with - * index 'info' referencing an object) - * @param PEAR_Downloader $dl - * @param array $params full list of packages to install - * @return true|PEAR_Error + * @param string|array pass in an array of format + * array( + * 'package' => 'pname', + * ['channel' => 'channame',] + * ['version' => 'version',] + * ['state' => 'state',]) + * or a string of format [channame/]pname[-version|-state] */ - function validatePackage($pkg, &$dl, $params = array()) + function _fromString($param) { - if (is_array($pkg) && isset($pkg['info'])) { - $deps = $this->_dependencydb->getDependentPackageDependencies($pkg['info']); - } else { - $deps = $this->_dependencydb->getDependentPackageDependencies($pkg); - } - - $fail = false; - if ($deps) { - if (!class_exists('PEAR_Downloader_Package')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Downloader/Package.php'; - } - - $dp = &new PEAR_Downloader_Package($dl); - if (is_object($pkg)) { - $dp->setPackageFile($pkg); - } else { - $dp->setDownloadURL($pkg); + $options = $this->_downloader->getOptions(); + $channel = $this->_config->get('default_channel'); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $pname = $this->_registry->parsePackageName($param, $channel); + PEAR::popErrorHandling(); + if (PEAR::isError($pname)) { + if ($pname->getCode() == 'invalid') { + $this->_valid = false; + return false; } - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - foreach ($deps as $channel => $info) { - foreach ($info as $package => $ds) { - foreach ($params as $packd) { - if (strtolower($packd->getPackage()) == strtolower($package) && - $packd->getChannel() == $channel) { - $dl->log(3, 'skipping installed package check of "' . - $this->_registry->parsedPackageNameToString( - array('channel' => $channel, 'package' => $package), - true) . - '", version "' . $packd->getVersion() . '" will be ' . - 'downloaded and installed'); - continue 2; // jump to next package + if ($pname->getCode() == 'channel') { + $parsed = $pname->getUserInfo(); + if ($this->_downloader->discover($parsed['channel'])) { + if ($this->_config->get('auto_discover')) { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $pname = $this->_registry->parsePackageName($param, $channel); + PEAR::popErrorHandling(); + } else { + if (!isset($options['soft'])) { + $this->_downloader->log(0, 'Channel "' . $parsed['channel'] . + '" is not initialized, use ' . + '"pear channel-discover ' . $parsed['channel'] . '" to initialize' . + 'or pear config-set auto_discover 1'); } } + } + + if (PEAR::isError($pname)) { + if (!isset($options['soft'])) { + $this->_downloader->log(0, $pname->getMessage()); + } - foreach ($ds as $d) { - $checker = &new PEAR_Dependency2($this->_config, $this->_options, - array('channel' => $channel, 'package' => $package), $this->_state); - $dep = $d['dep']; - $required = $d['type'] == 'required'; - $ret = $checker->_validatePackageDownload($dep, $required, array(&$dp)); - if (is_array($ret)) { - $dl->log(0, $ret[0]); - } elseif (PEAR::isError($ret)) { - $dl->log(0, $ret->getMessage()); - $fail = true; - } + if (is_array($param)) { + $param = $this->_registry->parsedPackageNameToString($param); } + + $err = PEAR::raiseError('invalid package name/package file "' . $param . '"'); + $this->_valid = false; + return $err; + } + } else { + if (!isset($options['soft'])) { + $this->_downloader->log(0, $pname->getMessage()); } + + $err = PEAR::raiseError('invalid package name/package file "' . $param . '"'); + $this->_valid = false; + return $err; } - PEAR::popErrorHandling(); } - if ($fail) { - return $this->raiseError( - '%s cannot be installed, conflicts with installed packages'); + if (!isset($this->_type)) { + $this->_type = 'rest'; } - return true; - } + $this->_parsedname = $pname; + $this->_explicitState = isset($pname['state']) ? $pname['state'] : false; + $this->_explicitGroup = isset($pname['group']) ? true : false; - /** - * validate a package.xml 1.0 dependency - */ - function validateDependency1($dep, $params = array()) - { - if (!isset($dep['optional'])) { - $dep['optional'] = 'no'; + $info = $this->_downloader->_getPackageDownloadUrl($pname); + if (PEAR::isError($info)) { + if ($info->getCode() != -976 && $pname['channel'] == 'pear.php.net') { + // try pecl + $pname['channel'] = 'pecl.php.net'; + if ($test = $this->_downloader->_getPackageDownloadUrl($pname)) { + if (!PEAR::isError($test)) { + $info = PEAR::raiseError($info->getMessage() . ' - package ' . + $this->_registry->parsedPackageNameToString($pname, true) . + ' can be installed with "pecl install ' . $pname['package'] . + '"'); + } else { + $pname['channel'] = 'pear.php.net'; + } + } else { + $pname['channel'] = 'pear.php.net'; + } + } + + return $info; } - list($newdep, $type) = $this->normalizeDep($dep); - if (!$newdep) { - return $this->raiseError("Invalid Dependency"); + $this->_rawpackagefile = $info['raw']; + $ret = $this->_analyzeDownloadURL($info, $param, $pname); + if (PEAR::isError($ret)) { + return $ret; } - if (method_exists($this, "validate{$type}Dependency")) { - return $this->{"validate{$type}Dependency"}($newdep, $dep['optional'] == 'no', - $params, true); + if ($ret) { + $this->_downloadURL = $ret; + return $this->_valid = (bool) $ret; } } /** - * Convert a 1.0 dep into a 2.0 dep + * @param array output of package.getDownloadURL + * @param string|array|object information for detecting packages to be downloaded, and + * for errors + * @param array name information of the package + * @param array|null packages to be downloaded + * @param bool is this an optional dependency? + * @param bool is this any kind of dependency? + * @access private */ - function normalizeDep($dep) + function _analyzeDownloadURL($info, $param, $pname, $params = null, $optional = false, + $isdependency = false) { - $types = array( - 'pkg' => 'Package', - 'ext' => 'Extension', - 'os' => 'Os', - 'php' => 'Php' - ); - - if (!isset($types[$dep['type']])) { - return array(false, false); + if (!is_string($param) && PEAR_Downloader_Package::willDownload($param, $params)) { + return false; } - $type = $types[$dep['type']]; + if ($info === false) { + $saveparam = !is_string($param) ? ", cannot download \"$param\"" : ''; - $newdep = array(); - switch ($type) { - case 'Package' : - $newdep['channel'] = 'pear.php.net'; - case 'Extension' : - case 'Os' : - $newdep['name'] = $dep['name']; - break; + // no releases exist + return PEAR::raiseError('No releases for package "' . + $this->_registry->parsedPackageNameToString($pname, true) . '" exist' . $saveparam); } - $dep['rel'] = PEAR_Dependency2::signOperator($dep['rel']); - switch ($dep['rel']) { - case 'has' : - return array($newdep, $type); - break; - case 'not' : - $newdep['conflicts'] = true; - break; - case '>=' : - case '>' : - $newdep['min'] = $dep['version']; - if ($dep['rel'] == '>') { - $newdep['exclude'] = $dep['version']; + if (strtolower($info['info']->getChannel()) != strtolower($pname['channel'])) { + $err = false; + if ($pname['channel'] == 'pecl.php.net') { + if ($info['info']->getChannel() != 'pear.php.net') { + $err = true; } - break; - case '<=' : - case '<' : - $newdep['max'] = $dep['version']; - if ($dep['rel'] == '<') { - $newdep['exclude'] = $dep['version']; + } elseif ($info['info']->getChannel() == 'pecl.php.net') { + if ($pname['channel'] != 'pear.php.net') { + $err = true; } - break; - case 'ne' : - case '!=' : - $newdep['min'] = '0'; - $newdep['max'] = '100000'; - $newdep['exclude'] = $dep['version']; - break; - case '==' : - $newdep['min'] = $dep['version']; - $newdep['max'] = $dep['version']; - break; - } - if ($type == 'Php') { - if (!isset($newdep['min'])) { - $newdep['min'] = '4.4.0'; + } else { + $err = true; } - if (!isset($newdep['max'])) { - $newdep['max'] = '6.0.0'; + if ($err) { + return PEAR::raiseError('SECURITY ERROR: package in channel "' . $pname['channel'] . + '" retrieved another channel\'s name for download! ("' . + $info['info']->getChannel() . '")'); } } - return array($newdep, $type); - } - /** - * Converts text comparing operators to them sign equivalents - * - * Example: 'ge' to '>=' - * - * @access public - * @param string Operator - * @return string Sign equivalent - */ - function signOperator($operator) - { - switch($operator) { - case 'lt': return '<'; - case 'le': return '<='; - case 'gt': return '>'; - case 'ge': return '>='; - case 'eq': return '=='; - case 'ne': return '!='; - default: - return $operator; - } - } + $preferred_state = $this->_config->get('preferred_state'); + if (!isset($info['url'])) { + $package_version = $this->_registry->packageInfo($info['info']->getPackage(), + 'version', $info['info']->getChannel()); + if ($this->isInstalled($info)) { + if ($isdependency && version_compare($info['version'], $package_version, '<=')) { + // ignore bogus errors of "failed to download dependency" + // if it is already installed and the one that would be + // downloaded is older or the same version (Bug #7219) + return false; + } + } - function raiseError($msg) - { - if (isset($this->_options['ignore-errors'])) { - return $this->warning($msg); + if ($info['version'] === $package_version) { + if (!isset($options['soft'])) { + $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . + '/' . $pname['package'] . '-' . $package_version. ', additionally the suggested version' . + ' (' . $package_version . ') is the same as the locally installed one.'); + } + + return false; + } + + if (version_compare($info['version'], $package_version, '<=')) { + if (!isset($options['soft'])) { + $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . + '/' . $pname['package'] . '-' . $package_version . ', additionally the suggested version' . + ' (' . $info['version'] . ') is a lower version than the locally installed one (' . $package_version . ').'); + } + + return false; + } + + $instead = ', will instead download version ' . $info['version'] . + ', stability "' . $info['info']->getState() . '"'; + // releases exist, but we failed to get any + if (isset($this->_downloader->_options['force'])) { + if (isset($pname['version'])) { + $vs = ', version "' . $pname['version'] . '"'; + } elseif (isset($pname['state'])) { + $vs = ', stability "' . $pname['state'] . '"'; + } elseif ($param == 'dependency') { + if (!class_exists('PEAR_Common')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Common.php'; + } + + if (!in_array($info['info']->getState(), + PEAR_Common::betterStates($preferred_state, true))) { + if ($optional) { + // don't spit out confusing error message + return $this->_downloader->_getPackageDownloadUrl( + array('package' => $pname['package'], + 'channel' => $pname['channel'], + 'version' => $info['version'])); + } + $vs = ' within preferred state "' . $preferred_state . + '"'; + } else { + if (!class_exists('PEAR_Dependency2')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; + } + + if ($optional) { + // don't spit out confusing error message + return $this->_downloader->_getPackageDownloadUrl( + array('package' => $pname['package'], + 'channel' => $pname['channel'], + 'version' => $info['version'])); + } + $vs = PEAR_Dependency2::_getExtraString($pname); + $instead = ''; + } + } else { + $vs = ' within preferred state "' . $preferred_state . '"'; + } + + if (!isset($options['soft'])) { + $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . + '/' . $pname['package'] . $vs . $instead); + } + + // download the latest release + return $this->_downloader->_getPackageDownloadUrl( + array('package' => $pname['package'], + 'channel' => $pname['channel'], + 'version' => $info['version'])); + } else { + if (isset($info['php']) && $info['php']) { + $err = PEAR::raiseError('Failed to download ' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pname['channel'], + 'package' => $pname['package']), + true) . + ', latest release is version ' . $info['php']['v'] . + ', but it requires PHP version "' . + $info['php']['m'] . '", use "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pname['channel'], 'package' => $pname['package'], + 'version' => $info['php']['v'])) . '" to install', + PEAR_DOWNLOADER_PACKAGE_PHPVERSION); + return $err; + } + + // construct helpful error message + if (isset($pname['version'])) { + $vs = ', version "' . $pname['version'] . '"'; + } elseif (isset($pname['state'])) { + $vs = ', stability "' . $pname['state'] . '"'; + } elseif ($param == 'dependency') { + if (!class_exists('PEAR_Common')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Common.php'; + } + + if (!in_array($info['info']->getState(), + PEAR_Common::betterStates($preferred_state, true))) { + if ($optional) { + // don't spit out confusing error message, and don't die on + // optional dep failure! + return $this->_downloader->_getPackageDownloadUrl( + array('package' => $pname['package'], + 'channel' => $pname['channel'], + 'version' => $info['version'])); + } + $vs = ' within preferred state "' . $preferred_state . '"'; + } else { + if (!class_exists('PEAR_Dependency2')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; + } + + if ($optional) { + // don't spit out confusing error message, and don't die on + // optional dep failure! + return $this->_downloader->_getPackageDownloadUrl( + array('package' => $pname['package'], + 'channel' => $pname['channel'], + 'version' => $info['version'])); + } + $vs = PEAR_Dependency2::_getExtraString($pname); + } + } else { + $vs = ' within preferred state "' . $this->_downloader->config->get('preferred_state') . '"'; + } + + $options = $this->_downloader->getOptions(); + // this is only set by the "download-all" command + if (isset($options['ignorepreferred_state'])) { + $err = PEAR::raiseError( + 'Failed to download ' . $this->_registry->parsedPackageNameToString( + array('channel' => $pname['channel'], 'package' => $pname['package']), + true) + . $vs . + ', latest release is version ' . $info['version'] . + ', stability "' . $info['info']->getState() . '", use "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pname['channel'], 'package' => $pname['package'], + 'version' => $info['version'])) . '" to install', + PEAR_DOWNLOADER_PACKAGE_STATE); + return $err; + } + + // Checks if the user has a package installed already and checks the release against + // the state against the installed package, this allows upgrades for packages + // with lower stability than the preferred_state + $stability = $this->_registry->packageInfo($pname['package'], 'stability', $pname['channel']); + if (!$this->isInstalled($info) + || !in_array($info['info']->getState(), PEAR_Common::betterStates($stability['release'], true)) + ) { + $err = PEAR::raiseError( + 'Failed to download ' . $this->_registry->parsedPackageNameToString( + array('channel' => $pname['channel'], 'package' => $pname['package']), + true) + . $vs . + ', latest release is version ' . $info['version'] . + ', stability "' . $info['info']->getState() . '", use "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pname['channel'], 'package' => $pname['package'], + 'version' => $info['version'])) . '" to install'); + return $err; + } + } } - return PEAR::raiseError(sprintf($msg, $this->_registry->parsedPackageNameToString( - $this->_currentPackage, true))); - } + if (isset($info['deprecated']) && $info['deprecated']) { + $this->_downloader->log(0, + 'WARNING: "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $info['info']->getChannel(), + 'package' => $info['info']->getPackage()), true) . + '" is deprecated in favor of "' . + $this->_registry->parsedPackageNameToString($info['deprecated'], true) . + '"'); + } - function warning($msg) - { - return array(sprintf($msg, $this->_registry->parsedPackageNameToString( - $this->_currentPackage, true))); + return $info; } } + * Since version PEAR1.3.2, ErrorStack no longer instantiates an exception class. This can + * still be done quite handily in an error callback or by manipulating the returned array + * @category Debugging + * @package PEAR_ErrorStack * @author Greg Beaver - * @copyright 1997-2009 The Authors + * @copyright 2004-2008 Greg Beaver * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: DependencyDB.php,v 1.44 2009/03/21 15:15:26 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 + * @version CVS: $Id: ErrorStack.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR_ErrorStack */ /** - * Needed for error handling + * Singleton storage + * + * Format: + *
    + * array(
    + *  'package1' => PEAR_ErrorStack object,
    + *  'package2' => PEAR_ErrorStack object,
    + *  ...
    + * )
    + * 
    + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Config.php'; +$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array(); -$GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'] = array(); /** - * Track dependency relationships between installed packages - * @category pear - * @package PEAR + * Global error callback (default) + * + * This is only used if set to non-false. * is the default callback for + * all packages, whereas specific packages may set a default callback + * for all instances, regardless of whether they are a singleton or not. + * + * To exclude non-singletons, only set the local callback for the singleton + * @see PEAR_ErrorStack::setDefaultCallback() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] + */ +$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array( + '*' => false, +); + +/** + * Global Log object (default) + * + * This is only used if set to non-false. Use to set a default log object for + * all stacks, regardless of instantiation order or location + * @see PEAR_ErrorStack::setDefaultLogger() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] + */ +$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false; + +/** + * Global Overriding Callback + * + * This callback will override any error callbacks that specific loggers have set. + * Use with EXTREME caution + * @see PEAR_ErrorStack::staticPushCallback() + * @access private + * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] + */ +$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); + +/**#@+ + * One of four possible return values from the error Callback + * @see PEAR_ErrorStack::_errorCallback() + */ +/** + * If this is returned, then the error will be both pushed onto the stack + * and logged. + */ +define('PEAR_ERRORSTACK_PUSHANDLOG', 1); +/** + * If this is returned, then the error will only be pushed onto the stack, + * and not logged. + */ +define('PEAR_ERRORSTACK_PUSH', 2); +/** + * If this is returned, then the error will only be logged, but not pushed + * onto the error stack. + */ +define('PEAR_ERRORSTACK_LOG', 3); +/** + * If this is returned, then the error is completely ignored. + */ +define('PEAR_ERRORSTACK_IGNORE', 4); +/** + * If this is returned, then the error is logged and die() is called. + */ +define('PEAR_ERRORSTACK_DIE', 5); +/**#@-*/ + +/** + * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in + * the singleton method. + */ +define('PEAR_ERRORSTACK_ERR_NONCLASS', 1); + +/** + * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()} + * that has no __toString() method + */ +define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2); +/** + * Error Stack Implementation + * + * Usage: + * + * // global error stack + * $global_stack = &PEAR_ErrorStack::singleton('MyPackage'); + * // local error stack + * $local_stack = new PEAR_ErrorStack('MyPackage'); + * * @author Greg Beaver - * @author Tomas V.V.Cox - * @copyright 1997-2009 The Authors + * @version 1.9.0 + * @package PEAR_ErrorStack + * @category Debugging + * @copyright 2004-2008 Greg Beaver * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 + * @version CVS: $Id: ErrorStack.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR_ErrorStack */ -class PEAR_DependencyDB -{ - // {{{ properties - +class PEAR_ErrorStack { /** - * This is initialized by {@link setConfig()} - * @var PEAR_Config + * Errors are stored in the order that they are pushed on the stack. + * @since 0.4alpha Errors are no longer organized by error level. + * This renders pop() nearly unusable, and levels could be more easily + * handled in a callback anyway + * @var array * @access private */ - var $_config; + var $_errors = array(); + /** - * This is initialized by {@link setConfig()} - * @var PEAR_Registry + * Storage of errors by level. + * + * Allows easy retrieval and deletion of only errors from a particular level + * @since PEAR 1.4.0dev + * @var array * @access private */ - var $_registry; + var $_errorsByLevel = array(); + /** - * Filename of the dependency DB (usually .depdb) + * Package name this error stack represents * @var string - * @access private + * @access protected */ - var $_depdb = false; + var $_package; + /** - * File name of the lockfile (usually .depdblock) - * @var string + * Determines whether a PEAR_Error is thrown upon every error addition + * @var boolean * @access private */ - var $_lockfile = false; + var $_compat = false; + /** - * Open file resource for locking the lockfile - * @var resource|false + * If set to a valid callback, this will be used to generate the error + * message from the error code, otherwise the message passed in will be + * used + * @var false|string|array * @access private */ - var $_lockFp = false; + var $_msgCallback = false; + /** - * API version of this class, used to validate a file on-disk - * @var string - * @access private + * If set to a valid callback, this will be used to generate the error + * context for an error. For PHP-related errors, this will be a file + * and line number as retrieved from debug_backtrace(), but can be + * customized for other purposes. The error might actually be in a separate + * configuration file, or in a database query. + * @var false|string|array + * @access protected */ - var $_version = '1.0'; + var $_contextCallback = false; + /** - * Cached dependency database file - * @var array|null - * @access private + * If set to a valid callback, this will be called every time an error + * is pushed onto the stack. The return value will be used to determine + * whether to allow an error to be pushed or logged. + * + * The return value must be one an PEAR_ERRORSTACK_* constant + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @var false|string|array + * @access protected */ - var $_cache; - - // }}} - // {{{ & singleton() - + var $_errorCallback = array(); + /** - * Get a raw dependency database. Calls setConfig() and assertDepsDB() - * @param PEAR_Config - * @param string|false full path to the dependency database, or false to use default - * @return PEAR_DependencyDB|PEAR_Error - * @static + * PEAR::Log object for logging errors + * @var false|Log + * @access protected + */ + var $_logger = false; + + /** + * Error messages - designed to be overridden + * @var array + * @abstract + */ + var $_errorMsgs = array(); + + /** + * Set up a new error stack + * + * @param string $package name of the package this error stack represents + * @param callback $msgCallback callback used for error message generation + * @param callback $contextCallback callback used for context generation, + * defaults to {@link getFileLine()} + * @param boolean $throwPEAR_Error */ - function &singleton(&$config, $depdb = false) + function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false, + $throwPEAR_Error = false) { - $phpdir = $config->get('php_dir', null, 'pear.php.net'); - if (!isset($GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir])) { - $a = new PEAR_DependencyDB; - $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir] = &$a; - $a->setConfig($config, $depdb); - $e = $a->assertDepsDB(); - if (PEAR::isError($e)) { - return $e; - } - } - - return $GLOBALS['_PEAR_DEPENDENCYDB_INSTANCE'][$phpdir]; + $this->_package = $package; + $this->setMessageCallback($msgCallback); + $this->setContextCallback($contextCallback); + $this->_compat = $throwPEAR_Error; } - + /** - * Set up the registry/location of dependency DB - * @param PEAR_Config|false - * @param string|false full path to the dependency database, or false to use default + * Return a single error stack for this package. + * + * Note that all parameters are ignored if the stack for package $package + * has already been instantiated + * @param string $package name of the package this error stack represents + * @param callback $msgCallback callback used for error message generation + * @param callback $contextCallback callback used for context generation, + * defaults to {@link getFileLine()} + * @param boolean $throwPEAR_Error + * @param string $stackClass class to instantiate + * @static + * @return PEAR_ErrorStack */ - function setConfig(&$config, $depdb = false) + function &singleton($package, $msgCallback = false, $contextCallback = false, + $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack') { - if (!$config) { - $this->_config = &PEAR_Config::singleton(); - } else { - $this->_config = &$config; + if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; } - - $this->_registry = &$this->_config->getRegistry(); - if (!$depdb) { - $this->_depdb = $this->_config->get('php_dir', null, 'pear.php.net') . - DIRECTORY_SEPARATOR . '.depdb'; - } else { - $this->_depdb = $depdb; + if (!class_exists($stackClass)) { + if (function_exists('debug_backtrace')) { + $trace = debug_backtrace(); + } + PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS, + 'exception', array('stackclass' => $stackClass), + 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)', + false, $trace); } + $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] = + new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error); - $this->_lockfile = dirname($this->_depdb) . DIRECTORY_SEPARATOR . '.depdblock'; + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; } - // }}} - function hasWriteAccess() + /** + * Internal error handler for PEAR_ErrorStack class + * + * Dies if the error is an exception (and would have died anyway) + * @access private + */ + function _handleError($err) { - if (!file_exists($this->_depdb)) { - $dir = $this->_depdb; - while ($dir && $dir != '.') { - $dir = dirname($dir); // cd .. - if ($dir != '.' && file_exists($dir)) { - if (is_writeable($dir)) { - return true; - } - - return false; - } + if ($err['level'] == 'exception') { + $message = $err['message']; + if (isset($_SERVER['REQUEST_URI'])) { + echo '
    '; + } else { + echo "\n"; } - - return false; + var_dump($err['context']); + die($message); } - - return is_writeable($this->_depdb); } - - // {{{ assertDepsDB() - + /** - * Create the dependency database, if it doesn't exist. Error if the database is - * newer than the code reading it. - * @return void|PEAR_Error + * Set up a PEAR::Log object for all error stacks that don't have one + * @param Log $log + * @static */ - function assertDepsDB() + function setDefaultLogger(&$log) { - if (!is_file($this->_depdb)) { - $this->rebuildDB(); - } else { - $depdb = $this->_getDepDB(); - // Datatype format has been changed, rebuild the Deps DB - if ($depdb['_version'] < $this->_version) { - $this->rebuildDB(); - } - - if ($depdb['_version']{0} > $this->_version{0}) { - return PEAR::raiseError('Dependency database is version ' . - $depdb['_version'] . ', and we are version ' . - $this->_version . ', cannot continue'); - } - } + if (is_object($log) && method_exists($log, 'log') ) { + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + } elseif (is_callable($log)) { + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; + } } - + /** - * Get a list of installed packages that depend on this package - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array - * @return array|false + * Set up a PEAR::Log object for this error stack + * @param Log $log */ - function getDependentPackages(&$pkg) + function setLogger(&$log) { - $data = $this->_getDepDB(); - if (is_object($pkg)) { - $channel = strtolower($pkg->getChannel()); - $package = strtolower($pkg->getPackage()); - } else { - $channel = strtolower($pkg['channel']); - $package = strtolower($pkg['package']); + if (is_object($log) && method_exists($log, 'log') ) { + $this->_logger = &$log; + } elseif (is_callable($log)) { + $this->_logger = &$log; } - - if (isset($data['packages'][$channel][$package])) { - return $data['packages'][$channel][$package]; - } - - return false; } - + /** - * Get a list of the actual dependencies of installed packages that depend on - * a package. - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array - * @return array|false + * Set an error code => error message mapping callback + * + * This method sets the callback that can be used to generate error + * messages for any instance + * @param array|string Callback function/method */ - function getDependentPackageDependencies(&$pkg) + function setMessageCallback($msgCallback) { - $data = $this->_getDepDB(); - if (is_object($pkg)) { - $channel = strtolower($pkg->getChannel()); - $package = strtolower($pkg->getPackage()); + if (!$msgCallback) { + $this->_msgCallback = array(&$this, 'getErrorMessage'); } else { - $channel = strtolower($pkg['channel']); - $package = strtolower($pkg['package']); - } - - $depend = $this->getDependentPackages($pkg); - if (!$depend) { - return false; - } - - $dependencies = array(); - foreach ($depend as $info) { - $temp = $this->getDependencies($info); - foreach ($temp as $dep) { - if (isset($dep['dep'], $dep['dep']['channel'], $dep['dep']['name']) && - strtolower($dep['dep']['channel']) == $channel && - strtolower($dep['dep']['name']) == $package - ) { - if (!isset($dependencies[$info['channel']])) { - $dependencies[$info['channel']] = array(); - } - - if (!isset($dependencies[$info['channel']][$info['package']])) { - $dependencies[$info['channel']][$info['package']] = array(); - } - $dependencies[$info['channel']][$info['package']][] = $dep; - } + if (is_callable($msgCallback)) { + $this->_msgCallback = $msgCallback; } } - - return $dependencies; } - + /** - * Get a list of dependencies of this installed package - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array - * @return array|false + * Get an error code => error message mapping callback + * + * This method returns the current callback that can be used to generate error + * messages + * @return array|string|false Callback function/method or false if none */ - function getDependencies(&$pkg) + function getMessageCallback() { - if (is_object($pkg)) { - $channel = strtolower($pkg->getChannel()); - $package = strtolower($pkg->getPackage()); - } else { - $channel = strtolower($pkg['channel']); - $package = strtolower($pkg['package']); - } - - $data = $this->_getDepDB(); - if (isset($data['dependencies'][$channel][$package])) { - return $data['dependencies'][$channel][$package]; - } - - return false; + return $this->_msgCallback; } - + /** - * Determine whether $parent depends on $child, near or deep - * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2 - * @param array|PEAR_PackageFile_v2|PEAR_PackageFile_v2 + * Sets a default callback to be used by all error stacks + * + * This method sets the callback that can be used to generate error + * messages for a singleton + * @param array|string Callback function/method + * @param string Package name, or false for all packages + * @static */ - function dependsOn($parent, $child) + function setDefaultCallback($callback = false, $package = false) { - $c = array(); - $this->_getDepDB(); - return $this->_dependsOn($parent, $child, $c); + if (!is_callable($callback)) { + $callback = false; + } + $package = $package ? $package : '*'; + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback; } - - function _dependsOn($parent, $child, &$checked) + + /** + * Set a callback that generates context information (location of error) for an error stack + * + * This method sets the callback that can be used to generate context + * information for an error. Passing in NULL will disable context generation + * and remove the expensive call to debug_backtrace() + * @param array|string|null Callback function/method + */ + function setContextCallback($contextCallback) { - if (is_object($parent)) { - $channel = strtolower($parent->getChannel()); - $package = strtolower($parent->getPackage()); - } else { - $channel = strtolower($parent['channel']); - $package = strtolower($parent['package']); + if ($contextCallback === null) { + return $this->_contextCallback = false; } - - if (is_object($child)) { - $depchannel = strtolower($child->getChannel()); - $deppackage = strtolower($child->getPackage()); + if (!$contextCallback) { + $this->_contextCallback = array(&$this, 'getFileLine'); } else { - $depchannel = strtolower($child['channel']); - $deppackage = strtolower($child['package']); - } - - if (isset($checked[$channel][$package][$depchannel][$deppackage])) { - return false; // avoid endless recursion - } - - $checked[$channel][$package][$depchannel][$deppackage] = true; - if (!isset($this->_cache['dependencies'][$channel][$package])) { - return false; - } - - foreach ($this->_cache['dependencies'][$channel][$package] as $info) { - if (isset($info['dep']['uri'])) { - if (is_object($child)) { - if ($info['dep']['uri'] == $child->getURI()) { - return true; - } - } elseif (isset($child['uri'])) { - if ($info['dep']['uri'] == $child['uri']) { - return true; - } - } - return false; - } - - if (strtolower($info['dep']['channel']) == $depchannel && - strtolower($info['dep']['name']) == $deppackage) { - return true; - } - } - - foreach ($this->_cache['dependencies'][$channel][$package] as $info) { - if (isset($info['dep']['uri'])) { - if ($this->_dependsOn(array( - 'uri' => $info['dep']['uri'], - 'package' => $info['dep']['name']), $child, $checked)) { - return true; - } - } else { - if ($this->_dependsOn(array( - 'channel' => $info['dep']['channel'], - 'package' => $info['dep']['name']), $child, $checked)) { - return true; - } + if (is_callable($contextCallback)) { + $this->_contextCallback = $contextCallback; } } - - return false; } - + /** - * Register dependencies of a package that is being installed or upgraded - * @param PEAR_PackageFile_v2|PEAR_PackageFile_v2 + * Set an error Callback + * If set to a valid callback, this will be called every time an error + * is pushed onto the stack. The return value will be used to determine + * whether to allow an error to be pushed or logged. + * + * The return value must be one of the ERRORSTACK_* constants. + * + * This functionality can be used to emulate PEAR's pushErrorHandling, and + * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of + * the error stack or logging + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @see popCallback() + * @param string|array $cb */ - function installPackage(&$package) + function pushCallback($cb) { - $data = $this->_getDepDB(); - unset($this->_cache); - $this->_setPackageDeps($data, $package); - $this->_writeDepDB($data); + array_push($this->_errorCallback, $cb); } - + /** - * Remove dependencies of a package that is being uninstalled, or upgraded. - * - * Upgraded packages first uninstall, then install - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2|array If an array, then it must have - * indices 'channel' and 'package' + * Remove a callback from the error callback stack + * @see pushCallback() + * @return array|string|false */ - function uninstallPackage(&$pkg) + function popCallback() { - $data = $this->_getDepDB(); - unset($this->_cache); - if (is_object($pkg)) { - $channel = strtolower($pkg->getChannel()); - $package = strtolower($pkg->getPackage()); - } else { - $channel = strtolower($pkg['channel']); - $package = strtolower($pkg['package']); - } - - if (!isset($data['dependencies'][$channel][$package])) { - return true; - } - - foreach ($data['dependencies'][$channel][$package] as $dep) { - $found = false; - $depchannel = isset($dep['dep']['uri']) ? '__uri' : strtolower($dep['dep']['channel']); - $depname = strtolower($dep['dep']['name']); - if (isset($data['packages'][$depchannel][$depname])) { - foreach ($data['packages'][$depchannel][$depname] as $i => $info) { - if ($info['channel'] == $channel && $info['package'] == $package) { - $found = true; - break; - } - } - } - - if ($found) { - unset($data['packages'][$depchannel][$depname][$i]); - if (!count($data['packages'][$depchannel][$depname])) { - unset($data['packages'][$depchannel][$depname]); - if (!count($data['packages'][$depchannel])) { - unset($data['packages'][$depchannel]); - } - } else { - $data['packages'][$depchannel][$depname] = - array_values($data['packages'][$depchannel][$depname]); - } - } - } - - unset($data['dependencies'][$channel][$package]); - if (!count($data['dependencies'][$channel])) { - unset($data['dependencies'][$channel]); - } - - if (!count($data['dependencies'])) { - unset($data['dependencies']); - } - - if (!count($data['packages'])) { - unset($data['packages']); + if (!count($this->_errorCallback)) { + return false; } - - $this->_writeDepDB($data); + return array_pop($this->_errorCallback); } - + /** - * Rebuild the dependency DB by reading registry entries. - * @return true|PEAR_Error + * Set a temporary overriding error callback for every package error stack + * + * Use this to temporarily disable all existing callbacks (can be used + * to emulate the @ operator, for instance) + * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG + * @see staticPopCallback(), pushCallback() + * @param string|array $cb + * @static */ - function rebuildDB() + function staticPushCallback($cb) { - $depdb = array('_version' => $this->_version); - if (!$this->hasWriteAccess()) { - // allow startup for read-only with older Registry - return $depdb; - } - - $packages = $this->_registry->listAllPackages(); - if (PEAR::isError($packages)) { - return $packages; - } - - foreach ($packages as $channel => $ps) { - foreach ($ps as $package) { - $package = $this->_registry->getPackage($package, $channel); - if (PEAR::isError($package)) { - return $package; - } - $this->_setPackageDeps($depdb, $package); - } - } - - $error = $this->_writeDepDB($depdb); - if (PEAR::isError($error)) { - return $error; - } - - $this->_cache = $depdb; - return true; + array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb); } - + /** - * Register usage of the dependency DB to prevent race conditions - * @param int one of the LOCK_* constants - * @return true|PEAR_Error - * @access private + * Remove a temporary overriding error callback + * @see staticPushCallback() + * @return array|string|false + * @static */ - function _lock($mode = LOCK_EX) + function staticPopCallback() { - if (stristr(php_uname(), 'Windows 9')) { - return true; - } - - if ($mode != LOCK_UN && is_resource($this->_lockFp)) { - // XXX does not check type of lock (LOCK_SH/LOCK_EX) - return true; + $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']); + if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) { + $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); } - - $open_mode = 'w'; - // XXX People reported problems with LOCK_SH and 'w' - if ($mode === LOCK_SH) { - if (!file_exists($this->_lockfile)) { - touch($this->_lockfile); - } elseif (!is_file($this->_lockfile)) { - return PEAR::raiseError('could not create Dependency lock file, ' . - 'it exists and is not a regular file'); + return $ret; + } + + /** + * Add an error to the stack + * + * If the message generator exists, it is called with 2 parameters. + * - the current Error Stack object + * - an array that is in the same format as an error. Available indices + * are 'code', 'package', 'time', 'params', 'level', and 'context' + * + * Next, if the error should contain context information, this is + * handled by the context grabbing method. + * Finally, the error is pushed onto the proper error stack + * @param int $code Package-specific error code + * @param string $level Error level. This is NOT spell-checked + * @param array $params associative array of error parameters + * @param string $msg Error message, or a portion of it if the message + * is to be generated + * @param array $repackage If this error re-packages an error pushed by + * another package, place the array returned from + * {@link pop()} in this parameter + * @param array $backtrace Protected parameter: use this to pass in the + * {@link debug_backtrace()} that should be used + * to find error context + * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also + * thrown. If a PEAR_Error is returned, the userinfo + * property is set to the following array: + * + * + * array( + * 'code' => $code, + * 'params' => $params, + * 'package' => $this->_package, + * 'level' => $level, + * 'time' => time(), + * 'context' => $context, + * 'message' => $msg, + * //['repackage' => $err] repackaged error array/Exception class + * ); + * + * + * Normally, the previous array is returned. + */ + function push($code, $level = 'error', $params = array(), $msg = false, + $repackage = false, $backtrace = false) + { + $context = false; + // grab error context + if ($this->_contextCallback) { + if (!$backtrace) { + $backtrace = debug_backtrace(); } - $open_mode = 'r'; + $context = call_user_func($this->_contextCallback, $code, $params, $backtrace); } - - if (!is_resource($this->_lockFp)) { - $this->_lockFp = @fopen($this->_lockfile, $open_mode); + + // save error + $time = explode(' ', microtime()); + $time = $time[1] + $time[0]; + $err = array( + 'code' => $code, + 'params' => $params, + 'package' => $this->_package, + 'level' => $level, + 'time' => $time, + 'context' => $context, + 'message' => $msg, + ); + + if ($repackage) { + $err['repackage'] = $repackage; + } + + // set up the error message, if necessary + if ($this->_msgCallback) { + $msg = call_user_func_array($this->_msgCallback, + array(&$this, $err)); + $err['message'] = $msg; + } + $push = $log = true; + $die = false; + // try the overriding callback first + $callback = $this->staticPopCallback(); + if ($callback) { + $this->staticPushCallback($callback); } - - if (!is_resource($this->_lockFp)) { - return PEAR::raiseError("could not create Dependency lock file" . - (isset($php_errormsg) ? ": " . $php_errormsg : "")); + if (!is_callable($callback)) { + // try the local callback next + $callback = $this->popCallback(); + if (is_callable($callback)) { + $this->pushCallback($callback); + } else { + // try the default callback + $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ? + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] : + $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*']; + } } - - if (!(int)flock($this->_lockFp, $mode)) { - switch ($mode) { - case LOCK_SH: $str = 'shared'; break; - case LOCK_EX: $str = 'exclusive'; break; - case LOCK_UN: $str = 'unlock'; break; - default: $str = 'unknown'; break; + if (is_callable($callback)) { + switch(call_user_func($callback, $err)){ + case PEAR_ERRORSTACK_IGNORE: + return $err; + break; + case PEAR_ERRORSTACK_PUSH: + $log = false; + break; + case PEAR_ERRORSTACK_LOG: + $push = false; + break; + case PEAR_ERRORSTACK_DIE: + $die = true; + break; + // anything else returned has the same effect as pushandlog } - - return PEAR::raiseError("could not acquire $str lock ($this->_lockfile)"); } - - return true; - } - - /** - * Release usage of dependency DB - * @return true|PEAR_Error - * @access private - */ - function _unlock() - { - $ret = $this->_lock(LOCK_UN); - if (is_resource($this->_lockFp)) { - fclose($this->_lockFp); + if ($push) { + array_unshift($this->_errors, $err); + if (!isset($this->_errorsByLevel[$err['level']])) { + $this->_errorsByLevel[$err['level']] = array(); + } + $this->_errorsByLevel[$err['level']][] = &$this->_errors[0]; } - $this->_lockFp = null; - return $ret; - } - - /** - * Load the dependency database from disk, or return the cache - * @return array|PEAR_Error - */ - function _getDepDB() - { - if (!$this->hasWriteAccess()) { - return array('_version' => $this->_version); + if ($log) { + if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) { + $this->_log($err); + } } - - if (isset($this->_cache)) { - return $this->_cache; + if ($die) { + die(); } - - if (!$fp = fopen($this->_depdb, 'r')) { - $err = PEAR::raiseError("Could not open dependencies file `".$this->_depdb."'"); - return $err; + if ($this->_compat && $push) { + return $this->raiseError($msg, $code, null, null, $err); } - - $rt = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - clearstatcache(); - fclose($fp); - $data = unserialize(file_get_contents($this->_depdb)); - set_magic_quotes_runtime($rt); - $this->_cache = $data; - return $data; + return $err; } - + /** - * Write out the dependency database to disk - * @param array the database - * @return true|PEAR_Error - * @access private + * Static version of {@link push()} + * + * @param string $package Package name this error belongs to + * @param int $code Package-specific error code + * @param string $level Error level. This is NOT spell-checked + * @param array $params associative array of error parameters + * @param string $msg Error message, or a portion of it if the message + * is to be generated + * @param array $repackage If this error re-packages an error pushed by + * another package, place the array returned from + * {@link pop()} in this parameter + * @param array $backtrace Protected parameter: use this to pass in the + * {@link debug_backtrace()} that should be used + * to find error context + * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also + * thrown. see docs for {@link push()} + * @static */ - function _writeDepDB(&$deps) + function staticPush($package, $code, $level = 'error', $params = array(), + $msg = false, $repackage = false, $backtrace = false) { - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - - if (!$fp = fopen($this->_depdb, 'wb')) { - $this->_unlock(); - return PEAR::raiseError("Could not open dependencies file `".$this->_depdb."' for writing"); + $s = &PEAR_ErrorStack::singleton($package); + if ($s->_contextCallback) { + if (!$backtrace) { + if (function_exists('debug_backtrace')) { + $backtrace = debug_backtrace(); + } + } } - - $rt = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - fwrite($fp, serialize($deps)); - set_magic_quotes_runtime($rt); - fclose($fp); - $this->_unlock(); - $this->_cache = $deps; - return true; + return $s->push($code, $level, $params, $msg, $repackage, $backtrace); } - + /** - * Register all dependencies from a package in the dependencies database, in essence - * "installing" the package's dependency information - * @param array the database - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @access private - */ - function _setPackageDeps(&$data, &$pkg) - { - $pkg->setConfig($this->_config); - if ($pkg->getPackagexmlVersion() == '1.0') { - $gen = &$pkg->getDefaultGenerator(); - $deps = $gen->dependenciesToV2(); - } else { - $deps = $pkg->getDeps(true); - } - - if (!$deps) { - return; - } - - if (!is_array($data)) { - $data = array(); - } - - if (!isset($data['dependencies'])) { - $data['dependencies'] = array(); - } - - $channel = strtolower($pkg->getChannel()); - $package = strtolower($pkg->getPackage()); - - if (!isset($data['dependencies'][$channel])) { - $data['dependencies'][$channel] = array(); - } - - $data['dependencies'][$channel][$package] = array(); - if (isset($deps['required']['package'])) { - if (!isset($deps['required']['package'][0])) { - $deps['required']['package'] = array($deps['required']['package']); - } - - foreach ($deps['required']['package'] as $dep) { - $this->_registerDep($data, $pkg, $dep, 'required'); + * Log an error using PEAR::Log + * @param array $err Error array + * @param array $levels Error level => Log constant map + * @access protected + */ + function _log($err) + { + if ($this->_logger) { + $logger = &$this->_logger; + } else { + $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']; + } + if (is_a($logger, 'Log')) { + $levels = array( + 'exception' => PEAR_LOG_CRIT, + 'alert' => PEAR_LOG_ALERT, + 'critical' => PEAR_LOG_CRIT, + 'error' => PEAR_LOG_ERR, + 'warning' => PEAR_LOG_WARNING, + 'notice' => PEAR_LOG_NOTICE, + 'info' => PEAR_LOG_INFO, + 'debug' => PEAR_LOG_DEBUG); + if (isset($levels[$err['level']])) { + $level = $levels[$err['level']]; + } else { + $level = PEAR_LOG_INFO; } + $logger->log($err['message'], $level, $err); + } else { // support non-standard logs + call_user_func($logger, $err); } + } - if (isset($deps['optional']['package'])) { - if (!isset($deps['optional']['package'][0])) { - $deps['optional']['package'] = array($deps['optional']['package']); - } - - foreach ($deps['optional']['package'] as $dep) { - $this->_registerDep($data, $pkg, $dep, 'optional'); + + /** + * Pop an error off of the error stack + * + * @return false|array + * @since 0.4alpha it is no longer possible to specify a specific error + * level to return - the last error pushed will be returned, instead + */ + function pop() + { + $err = @array_shift($this->_errors); + if (!is_null($err)) { + @array_pop($this->_errorsByLevel[$err['level']]); + if (!count($this->_errorsByLevel[$err['level']])) { + unset($this->_errorsByLevel[$err['level']]); } } + return $err; + } - if (isset($deps['required']['subpackage'])) { - if (!isset($deps['required']['subpackage'][0])) { - $deps['required']['subpackage'] = array($deps['required']['subpackage']); + /** + * Pop an error off of the error stack, static method + * + * @param string package name + * @return boolean + * @since PEAR1.5.0a1 + */ + function staticPop($package) + { + if ($package) { + if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return false; } + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop(); + } + } - foreach ($deps['required']['subpackage'] as $dep) { - $this->_registerDep($data, $pkg, $dep, 'required'); + /** + * Determine whether there are any errors on the stack + * @param string|array Level name. Use to determine if any errors + * of level (string), or levels (array) have been pushed + * @return boolean + */ + function hasErrors($level = false) + { + if ($level) { + return isset($this->_errorsByLevel[$level]); + } + return count($this->_errors); + } + + /** + * Retrieve all errors since last purge + * + * @param boolean set in order to empty the error stack + * @param string level name, to return only errors of a particular severity + * @return array + */ + function getErrors($purge = false, $level = false) + { + if (!$purge) { + if ($level) { + if (!isset($this->_errorsByLevel[$level])) { + return array(); + } else { + return $this->_errorsByLevel[$level]; + } + } else { + return $this->_errors; } } - - if (isset($deps['optional']['subpackage'])) { - if (!isset($deps['optional']['subpackage'][0])) { - $deps['optional']['subpackage'] = array($deps['optional']['subpackage']); + if ($level) { + $ret = $this->_errorsByLevel[$level]; + foreach ($this->_errorsByLevel[$level] as $i => $unused) { + // entries are references to the $_errors array + $this->_errorsByLevel[$level][$i] = false; } - - foreach ($deps['optional']['subpackage'] as $dep) { - $this->_registerDep($data, $pkg, $dep, 'optional'); + // array_filter removes all entries === false + $this->_errors = array_filter($this->_errors); + unset($this->_errorsByLevel[$level]); + return $ret; + } + $ret = $this->_errors; + $this->_errors = array(); + $this->_errorsByLevel = array(); + return $ret; + } + + /** + * Determine whether there are any errors on a single error stack, or on any error stack + * + * The optional parameter can be used to test the existence of any errors without the need of + * singleton instantiation + * @param string|false Package name to check for errors + * @param string Level name to check for a particular severity + * @return boolean + * @static + */ + function staticHasErrors($package = false, $level = false) + { + if ($package) { + if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { + return false; } + return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level); } - - if (isset($deps['group'])) { - if (!isset($deps['group'][0])) { - $deps['group'] = array($deps['group']); + foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { + if ($obj->hasErrors($level)) { + return true; } - - foreach ($deps['group'] as $group) { - if (isset($group['package'])) { - if (!isset($group['package'][0])) { - $group['package'] = array($group['package']); - } - - foreach ($group['package'] as $dep) { - $this->_registerDep($data, $pkg, $dep, 'optional', - $group['attribs']['name']); - } - } - - if (isset($group['subpackage'])) { - if (!isset($group['subpackage'][0])) { - $group['subpackage'] = array($group['subpackage']); - } - - foreach ($group['subpackage'] as $dep) { - $this->_registerDep($data, $pkg, $dep, 'optional', - $group['attribs']['name']); - } + } + return false; + } + + /** + * Get a list of all errors since last purge, organized by package + * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be + * @param boolean $purge Set to purge the error stack of existing errors + * @param string $level Set to a level name in order to retrieve only errors of a particular level + * @param boolean $merge Set to return a flat array, not organized by package + * @param array $sortfunc Function used to sort a merged array - default + * sorts by time, and should be good for most cases + * @static + * @return array + */ + function staticGetErrors($purge = false, $level = false, $merge = false, + $sortfunc = array('PEAR_ErrorStack', '_sortErrors')) + { + $ret = array(); + if (!is_callable($sortfunc)) { + $sortfunc = array('PEAR_ErrorStack', '_sortErrors'); + } + foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { + $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level); + if ($test) { + if ($merge) { + $ret = array_merge($ret, $test); + } else { + $ret[$package] = $test; } } } - - if ($data['dependencies'][$channel][$package] == array()) { - unset($data['dependencies'][$channel][$package]); - if (!count($data['dependencies'][$channel])) { - unset($data['dependencies'][$channel]); - } + if ($merge) { + usort($ret, $sortfunc); } + return $ret; } - + /** - * @param array the database - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @param array the specific dependency - * @param required|optional whether this is a required or an optional dep - * @param string|false dependency group this dependency is from, or false for ordinary dep + * Error sorting function, sorts by time + * @access private */ - function _registerDep(&$data, &$pkg, $dep, $type, $group = false) + function _sortErrors($a, $b) { - $info = array( - 'dep' => $dep, - 'type' => $type, - 'group' => $group - ); - - $dep = array_map('strtolower', $dep); - $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; - if (!isset($data['dependencies'])) { - $data['dependencies'] = array(); + if ($a['time'] == $b['time']) { + return 0; } - - $channel = strtolower($pkg->getChannel()); - $package = strtolower($pkg->getPackage()); - - if (!isset($data['dependencies'][$channel])) { - $data['dependencies'][$channel] = array(); + if ($a['time'] < $b['time']) { + return 1; } + return -1; + } - if (!isset($data['dependencies'][$channel][$package])) { - $data['dependencies'][$channel][$package] = array(); + /** + * Standard file/line number/function/class context callback + * + * This function uses a backtrace generated from {@link debug_backtrace()} + * and so will not work at all in PHP < 4.3.0. The frame should + * reference the frame that contains the source of the error. + * @return array|false either array('file' => file, 'line' => line, + * 'function' => function name, 'class' => class name) or + * if this doesn't work, then false + * @param unused + * @param integer backtrace frame. + * @param array Results of debug_backtrace() + * @static + */ + function getFileLine($code, $params, $backtrace = null) + { + if ($backtrace === null) { + return false; } - - $data['dependencies'][$channel][$package][] = $info; - if (isset($data['packages'][$depchannel][$dep['name']])) { - $found = false; - foreach ($data['packages'][$depchannel][$dep['name']] as $i => $p) { - if ($p['channel'] == $channel && $p['package'] == $package) { - $found = true; - break; + $frame = 0; + $functionframe = 1; + if (!isset($backtrace[1])) { + $functionframe = 0; + } else { + while (isset($backtrace[$functionframe]['function']) && + $backtrace[$functionframe]['function'] == 'eval' && + isset($backtrace[$functionframe + 1])) { + $functionframe++; + } + } + if (isset($backtrace[$frame])) { + if (!isset($backtrace[$frame]['file'])) { + $frame++; + } + $funcbacktrace = $backtrace[$functionframe]; + $filebacktrace = $backtrace[$frame]; + $ret = array('file' => $filebacktrace['file'], + 'line' => $filebacktrace['line']); + // rearrange for eval'd code or create function errors + if (strpos($filebacktrace['file'], '(') && + preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'], + $matches)) { + $ret['file'] = $matches[1]; + $ret['line'] = $matches[2] + 0; + } + if (isset($funcbacktrace['function']) && isset($backtrace[1])) { + if ($funcbacktrace['function'] != 'eval') { + if ($funcbacktrace['function'] == '__lambda_func') { + $ret['function'] = 'create_function() code'; + } else { + $ret['function'] = $funcbacktrace['function']; + } } } - - if (!$found) { - $data['packages'][$depchannel][$dep['name']][] = array( - 'channel' => $channel, - 'package' => $package - ); + if (isset($funcbacktrace['class']) && isset($backtrace[1])) { + $ret['class'] = $funcbacktrace['class']; } + return $ret; + } + return false; + } + + /** + * Standard error message generation callback + * + * This method may also be called by a custom error message generator + * to fill in template values from the params array, simply + * set the third parameter to the error message template string to use + * + * The special variable %__msg% is reserved: use it only to specify + * where a message passed in by the user should be placed in the template, + * like so: + * + * Error message: %msg% - internal error + * + * If the message passed like so: + * + * + * $stack->push(ERROR_CODE, 'error', array(), 'server error 500'); + * + * + * The returned error message will be "Error message: server error 500 - + * internal error" + * @param PEAR_ErrorStack + * @param array + * @param string|false Pre-generated error message template + * @static + * @return string + */ + function getErrorMessage(&$stack, $err, $template = false) + { + if ($template) { + $mainmsg = $template; } else { - if (!isset($data['packages'])) { - $data['packages'] = array(); - } - - if (!isset($data['packages'][$depchannel])) { - $data['packages'][$depchannel] = array(); - } - - if (!isset($data['packages'][$depchannel][$dep['name']])) { - $data['packages'][$depchannel][$dep['name']] = array(); + $mainmsg = $stack->getErrorMessageTemplate($err['code']); + } + $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg); + if (is_array($err['params']) && count($err['params'])) { + foreach ($err['params'] as $name => $val) { + if (is_array($val)) { + // @ is needed in case $val is a multi-dimensional array + $val = @implode(', ', $val); + } + if (is_object($val)) { + if (method_exists($val, '__toString')) { + $val = $val->__toString(); + } else { + PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING, + 'warning', array('obj' => get_class($val)), + 'object %obj% passed into getErrorMessage, but has no __toString() method'); + $val = 'Object'; + } + } + $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg); } - - $data['packages'][$depchannel][$dep['name']][] = array( - 'channel' => $channel, - 'package' => $package - ); } + return $mainmsg; } -}_errorMsgs[$code])) { + return '%__msg%'; + } + return $this->_errorMsgs[$code]; + } + + /** + * Set the Error Message Template array + * + * The array format must be: + *
    +     * array(error code => 'message template',...)
    +     * 
    + * + * Error message parameters passed into {@link push()} will be used as input + * for the error message. If the template is 'message %foo% was %bar%', and the + * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will + * be 'message one was six' + * @return string + */ + function setErrorMessageTemplate($template) + { + $this->_errorMsgs = $template; + } + + + /** + * emulate PEAR::raiseError() + * + * @return PEAR_Error + */ + function raiseError() + { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; + $args = func_get_args(); + return call_user_func_array(array('PEAR', 'raiseError'), $args); + } +} +$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack'); +$stack->pushCallback(array('PEAR_ErrorStack', '_handleError')); +?> + - * @author Stig Bakken - * @author Tomas V. V. Cox - * @author Martin Jansen * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Downloader.php,v 1.159 2009/03/08 04:01:08 dufuz Exp $ + * @version CVS: $Id: Frontend.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.3.0 + * @since File available since Release 1.4.0a1 */ /** - * Needed for constants, extending + * Include error handling */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Common.php'; +//require_once 'PEAR.php'; -define('PEAR_INSTALLER_OK', 1); -define('PEAR_INSTALLER_FAILED', 0); -define('PEAR_INSTALLER_SKIPPED', -1); -define('PEAR_INSTALLER_ERROR_NO_PREF_STATE', 2); +/** + * Which user interface class is being used. + * @var string class name + */ +$GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI'; /** - * Administration class used to download anything from the internet (PEAR Packages, - * static URLs, xml files) + * Instance of $_PEAR_Command_uiclass. + * @var object + */ +$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null; + +/** + * Singleton-based frontend for PEAR user input/output * * @category pear * @package PEAR * @author Greg Beaver - * @author Stig Bakken - * @author Tomas V. V. Cox - * @author Martin Jansen * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.3.0 + * @since Class available since Release 1.4.0a1 */ -class PEAR_Downloader extends PEAR_Common +class PEAR_Frontend extends PEAR { /** - * @var PEAR_Registry - * @access private + * Retrieve the frontend object + * @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk + * @static */ - var $_registry; + function &singleton($type = null) + { + if ($type === null) { + if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) { + $a = false; + return $a; + } + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } + + $a = PEAR_Frontend::setFrontendClass($type); + return $a; + } /** - * Preferred Installation State (snapshot, devel, alpha, beta, stable) - * @var string|null - * @access private + * Set the frontend class that will be used by calls to {@link singleton()} + * + * Frontends are expected to conform to the PEAR naming standard of + * _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php) + * @param string $uiclass full class name + * @return PEAR_Frontend + * @static */ - var $_preferredState; + function &setFrontendClass($uiclass) + { + if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && + is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) { + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } + + if (!class_exists($uiclass)) { + $file = 'phar://install-pear-nozlib.phar/' . str_replace('_', '/', $uiclass) . '.php'; + if (PEAR_Frontend::isIncludeable($file)) { + include_once $file; + } + } + + if (class_exists($uiclass)) { + $obj = &new $uiclass; + // quick test to see if this class implements a few of the most + // important frontend methods + if (is_a($obj, 'PEAR_Frontend')) { + $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj; + $GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass; + return $obj; + } + + $err = PEAR::raiseError("not a frontend class: $uiclass"); + return $err; + } + + $err = PEAR::raiseError("no such class: $uiclass"); + return $err; + } /** - * Options from command-line passed to Install. + * Set the frontend class that will be used by calls to {@link singleton()} * - * Recognized options:
    - * - onlyreqdeps : install all required dependencies as well - * - alldeps : install all dependencies, including optional - * - installroot : base relative path to install files in - * - force : force a download even if warnings would prevent it - * - nocompress : download uncompressed tarballs - * @see PEAR_Command_Install - * @access private - * @var array + * Frontends are expected to be a descendant of PEAR_Frontend + * @param PEAR_Frontend + * @return PEAR_Frontend + * @static */ - var $_options; + function &setFrontendObject($uiobject) + { + if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && + is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) { + return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; + } + + if (!is_a($uiobject, 'PEAR_Frontend')) { + $err = PEAR::raiseError('not a valid frontend class: (' . + get_class($uiobject) . ')'); + return $err; + } + + $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject; + $GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject); + return $uiobject; + } /** - * Downloaded Packages after a call to download(). - * - * Format of each entry: - * - * - * array('pkg' => 'package_name', 'file' => '/path/to/local/file', - * 'info' => array() // parsed package.xml - * ); - * - * @access private - * @var array + * @param string $path relative or absolute include path + * @return boolean + * @static */ - var $_downloadedPackages = array(); + function isIncludeable($path) + { + if (file_exists($path) && is_readable($path)) { + return true; + } + + $fp = @fopen($path, 'r', true); + if ($fp) { + fclose($fp); + return true; + } + + return false; + } /** - * Packages slated for download. - * - * This is used to prevent downloading a package more than once should it be a dependency - * for two packages to be installed. - * Format of each entry: + * @param PEAR_Config + */ + function setConfig(&$config) + { + } + + /** + * This can be overridden to allow session-based temporary file management * - *
    -     * array('package_name1' => parsed package.xml, 'package_name2' => parsed package.xml,
    -     * );
    -     * 
    - * @access private - * @var array + * By default, all files are deleted at the end of a session. The web installer + * needs to be able to sustain a list over many sessions in order to support + * user interaction with install scripts */ - var $_toDownload = array(); + function addTempFile($file) + { + $GLOBALS['_PEAR_Common_tempfiles'][] = $file; + } /** - * Array of every package installed, with names lower-cased. + * Log an action * - * Format: - * - * array('package1' => 0, 'package2' => 1, ); - * - * @var array + * @param string $msg the message to log + * @param boolean $append_crlf + * @return boolean true + * @abstract */ - var $_installed = array(); + function log($msg, $append_crlf = true) + { + } /** - * @var array - * @access private + * Run a post-installation script + * + * @param array $scripts array of post-install scripts + * @abstract */ - var $_errorStack = array(); + function runPostinstallScripts(&$scripts) + { + } /** - * @var boolean - * @access private + * Display human-friendly output formatted depending on the + * $command parameter. + * + * This should be able to handle basic output data with no command + * @param mixed $data data structure containing the information to display + * @param string $command command from which this method was called + * @abstract */ - var $_internalDownload = false; + function outputData($data, $command = '_default') + { + } /** - * Temporary variable used in sorting packages by dependency in {@link sortPkgDeps()} - * @var array - * @access private + * Display a modal form dialog and return the given input + * + * A frontend that requires multiple requests to retrieve and process + * data must take these needs into account, and implement the request + * handling code. + * @param string $command command from which this method was called + * @param array $prompts associative array. keys are the input field names + * and values are the description + * @param array $types array of input field types (text, password, + * etc.) keys have to be the same like in $prompts + * @param array $defaults array of default values. again keys have + * to be the same like in $prompts. Do not depend + * on a default value being set. + * @return array input sent by the user + * @abstract */ - var $_packageSortTree; + function userDialog($command, $prompts, $types = array(), $defaults = array()) + { + } +} + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: CLI.php 278236 2009-04-04 00:09:14Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ +/** + * base class + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Frontend.php'; +/** + * Command-line Frontend for the PEAR Installer + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Frontend_CLI extends PEAR_Frontend +{ /** - * Temporary directory, or configuration value where downloads will occur + * What type of user interface this frontend is for. * @var string + * @access public */ - var $_downloadDir; - // {{{ PEAR_Downloader() + var $type = 'CLI'; + var $lp = ''; // line prefix + + var $params = array(); + var $term = array( + 'bold' => '', + 'normal' => '', + ); + + function PEAR_Frontend_CLI() + { + parent::PEAR(); + $term = getenv('TERM'); //(cox) $_ENV is empty for me in 4.1.1 + if (function_exists('posix_isatty') && !posix_isatty(1)) { + // output is being redirected to a file or through a pipe + } elseif ($term) { + if (preg_match('/^(xterm|vt220|linux)/', $term)) { + $this->term['bold'] = sprintf("%c%c%c%c", 27, 91, 49, 109); + $this->term['normal'] = sprintf("%c%c%c", 27, 91, 109); + } elseif (preg_match('/^vt100/', $term)) { + $this->term['bold'] = sprintf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); + $this->term['normal'] = sprintf("%c%c%c%c%c", 27, 91, 109, 0, 0); + } + } elseif (OS_WINDOWS) { + // XXX add ANSI codes here + } + } /** - * @param PEAR_Frontend_* - * @param array - * @param PEAR_Config + * @param object PEAR_Error object */ - function PEAR_Downloader(&$ui, $options, &$config) + function displayError($e) { - parent::PEAR_Common(); - $this->_options = $options; - $this->config = &$config; - $this->_preferredState = $this->config->get('preferred_state'); - $this->ui = &$ui; - if (!$this->_preferredState) { - // don't inadvertantly use a non-set preferred_state - $this->_preferredState = null; - } + return $this->_displayLine($e->getMessage()); + } - if (isset($this->_options['installroot'])) { - $this->config->setInstallRoot($this->_options['installroot']); - } - $this->_registry = &$config->getRegistry(); + /** + * @param object PEAR_Error object + */ + function displayFatalError($eobj) + { + $this->displayError($eobj); + if (class_exists('PEAR_Config')) { + $config = &PEAR_Config::singleton(); + if ($config->get('verbose') > 5) { + if (function_exists('debug_print_backtrace')) { + debug_print_backtrace(); + exit(1); + } - if (isset($this->_options['alldeps']) || isset($this->_options['onlyreqdeps'])) { - $this->_installed = $this->_registry->listAllPackages(); - foreach ($this->_installed as $key => $unused) { - if (!count($unused)) { - continue; + $raised = false; + foreach (debug_backtrace() as $i => $frame) { + if (!$raised) { + if (isset($frame['class']) + && strtolower($frame['class']) == 'pear' + && strtolower($frame['function']) == 'raiseerror' + ) { + $raised = true; + } else { + continue; + } + } + + $frame['class'] = !isset($frame['class']) ? '' : $frame['class']; + $frame['type'] = !isset($frame['type']) ? '' : $frame['type']; + $frame['function'] = !isset($frame['function']) ? '' : $frame['function']; + $frame['line'] = !isset($frame['line']) ? '' : $frame['line']; + $this->_displayLine("#$i: $frame[class]$frame[type]$frame[function] $frame[line]"); } - $strtolower = create_function('$a','return strtolower($a);'); - array_walk($this->_installed[$key], $strtolower); } } + + exit(1); } /** - * Attempt to discover a channel's remote capabilities from - * its server name + * Instruct the runInstallScript method to skip a paramgroup that matches the + * id value passed in. + * + * This method is useful for dynamically configuring which sections of a post-install script + * will be run based on the user's setup, which is very useful for making flexible + * post-install scripts without losing the cross-Frontend ability to retrieve user input * @param string - * @return boolean */ - function discover($channel) + function skipParamgroup($id) { - $this->log(1, 'Attempting to discover channel "' . $channel . '"...'); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $callback = $this->ui ? array(&$this, '_downloadCallback') : null; - if (!class_exists('System')) { - require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + $this->_skipSections[$id] = true; + } + + function runPostinstallScripts(&$scripts) + { + foreach ($scripts as $i => $script) { + $this->runInstallScript($scripts[$i]->_params, $scripts[$i]->_obj); } + } - $tmp = System::mktemp(array('-d')); - $a = $this->downloadHttp('http://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false); - PEAR::popErrorHandling(); - if (PEAR::isError($a)) { - // Attempt to fallback to https automatically. - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $this->log(1, 'Attempting fallback to https instead of http on channel "' . $channel . '"...'); - $a = $this->downloadHttp('https://' . $channel . '/channel.xml', $this->ui, $tmp, $callback, false); - PEAR::popErrorHandling(); - if (PEAR::isError($a)) { - return false; - } + /** + * @param array $xml contents of postinstallscript tag + * @param object $script post-installation script + * @param string install|upgrade + */ + function runInstallScript($xml, &$script) + { + $this->_skipSections = array(); + if (!is_array($xml) || !isset($xml['paramgroup'])) { + $script->run(array(), '_default'); + return; } - list($a, $lastmodified) = $a; - if (!class_exists('PEAR_ChannelFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + $completedPhases = array(); + if (!isset($xml['paramgroup'][0])) { + $xml['paramgroup'] = array($xml['paramgroup']); } - $b = new PEAR_ChannelFile; - if ($b->fromXmlFile($a)) { - unlink($a); - if ($this->config->get('auto_discover')) { - $this->_registry->addChannel($b, $lastmodified); - $alias = $b->getName(); - if ($b->getName() == $this->_registry->channelName($b->getAlias())) { - $alias = $b->getAlias(); + foreach ($xml['paramgroup'] as $group) { + if (isset($this->_skipSections[$group['id']])) { + // the post-install script chose to skip this section dynamically + continue; + } + + if (isset($group['name'])) { + $paramname = explode('::', $group['name']); + if ($lastgroup['id'] != $paramname[0]) { + continue; } - $this->log(1, 'Auto-discovered channel "' . $channel . - '", alias "' . $alias . '", adding to registry'); + $group['name'] = $paramname[1]; + if (!isset($answers)) { + return; + } + + if (isset($answers[$group['name']])) { + switch ($group['conditiontype']) { + case '=' : + if ($answers[$group['name']] != $group['value']) { + continue 2; + } + break; + case '!=' : + if ($answers[$group['name']] == $group['value']) { + continue 2; + } + break; + case 'preg_match' : + if (!@preg_match('/' . $group['value'] . '/', + $answers[$group['name']])) { + continue 2; + } + break; + default : + return; + } + } } - return true; - } + $lastgroup = $group; + if (isset($group['instructions'])) { + $this->_display($group['instructions']); + } - unlink($a); - return false; - } + if (!isset($group['param'][0])) { + $group['param'] = array($group['param']); + } - /** - * For simpler unit-testing - * @param PEAR_Downloader - * @return PEAR_Downloader_Package - */ - function &newDownloaderPackage(&$t) - { - if (!class_exists('PEAR_Downloader_Package')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Downloader/Package.php'; + if (isset($group['param'])) { + if (method_exists($script, 'postProcessPrompts')) { + $prompts = $script->postProcessPrompts($group['param'], $group['id']); + if (!is_array($prompts) || count($prompts) != count($group['param'])) { + $this->outputData('postinstall', 'Error: post-install script did not ' . + 'return proper post-processed prompts'); + $prompts = $group['param']; + } else { + foreach ($prompts as $i => $var) { + if (!is_array($var) || !isset($var['prompt']) || + !isset($var['name']) || + ($var['name'] != $group['param'][$i]['name']) || + ($var['type'] != $group['param'][$i]['type']) + ) { + $this->outputData('postinstall', 'Error: post-install script ' . + 'modified the variables or prompts, severe security risk. ' . + 'Will instead use the defaults from the package.xml'); + $prompts = $group['param']; + } + } + } + + $answers = $this->confirmDialog($prompts); + } else { + $answers = $this->confirmDialog($group['param']); + } + } + + if ((isset($answers) && $answers) || !isset($group['param'])) { + if (!isset($answers)) { + $answers = array(); + } + + array_unshift($completedPhases, $group['id']); + if (!$script->run($answers, $group['id'])) { + $script->run($completedPhases, '_undoOnError'); + return; + } + } else { + $script->run($completedPhases, '_undoOnError'); + return; + } } - $a = &new PEAR_Downloader_Package($t); - return $a; } /** - * For simpler unit-testing - * @param PEAR_Config - * @param array - * @param array - * @param int + * Ask for user input, confirm the answers and continue until the user is satisfied + * @param array an array of arrays, format array('name' => 'paramname', 'prompt' => + * 'text to display', 'type' => 'string'[, default => 'default value']) + * @return array */ - function &getDependency2Object(&$c, $i, $p, $s) + function confirmDialog($params) { - if (!class_exists('PEAR_Dependency2')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; + $answers = $prompts = $types = array(); + foreach ($params as $param) { + $prompts[$param['name']] = $param['prompt']; + $types[$param['name']] = $param['type']; + $answers[$param['name']] = isset($param['default']) ? $param['default'] : ''; } - $z = &new PEAR_Dependency2($c, $i, $p, $s); - return $z; + + $tried = false; + do { + if ($tried) { + $i = 1; + foreach ($answers as $var => $value) { + if (!strlen($value)) { + echo $this->bold("* Enter an answer for #" . $i . ": ({$prompts[$var]})\n"); + } + $i++; + } + } + + $answers = $this->userDialog('', $prompts, $types, $answers); + $tried = true; + } while (is_array($answers) && count(array_filter($answers)) != count($prompts)); + + return $answers; } - function &download($params) + function userDialog($command, $prompts, $types = array(), $defaults = array(), $screensize = 20) { - if (!count($params)) { - $a = array(); - return $a; + if (!is_array($prompts)) { + return array(); } - if (!isset($this->_registry)) { - $this->_registry = &$this->config->getRegistry(); + $testprompts = array_keys($prompts); + $result = $defaults; + + reset($prompts); + if (count($prompts) === 1) { + foreach ($prompts as $key => $prompt) { + $type = $types[$key]; + $default = @$defaults[$key]; + print "$prompt "; + if ($default) { + print "[$default] "; + } + print ": "; + + $line = fgets(STDIN, 2048); + $result[$key] = ($default && trim($line) == '') ? $default : trim($line); + } + + return $result; } - $channelschecked = array(); - // convert all parameters into PEAR_Downloader_Package objects - foreach ($params as $i => $param) { - $params[$i] = &$this->newDownloaderPackage($this); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $err = $params[$i]->initialize($param); - PEAR::staticPopErrorHandling(); - if (!$err) { - // skip parameters that were missed by preferred_state - continue; + $first_run = true; + while (true) { + $descLength = max(array_map('strlen', $prompts)); + $descFormat = "%-{$descLength}s"; + $last = count($prompts); + + $i = 0; + foreach ($prompts as $n => $var) { + $res = isset($result[$n]) ? $result[$n] : null; + printf("%2d. $descFormat : %s\n", ++$i, $prompts[$n], $res); } + print "\n1-$last, 'all', 'abort', or Enter to continue: "; - if (PEAR::isError($err)) { - if (!isset($this->_options['soft']) && $err->getMessage() !== '') { - $this->log(0, $err->getMessage()); - } + $tmp = trim(fgets(STDIN, 1024)); + if (empty($tmp)) { + break; + } - $params[$i] = false; - if (is_object($param)) { - $param = $param->getChannel() . '/' . $param->getPackage(); - } + if ($tmp == 'abort') { + return false; + } - if (!isset($this->_options['soft'])) { - $this->log(2, 'Package "' . $param . '" is not valid'); + if (isset($testprompts[(int)$tmp - 1])) { + $var = $testprompts[(int)$tmp - 1]; + $desc = $prompts[$var]; + $current = @$result[$var]; + print "$desc [$current] : "; + $tmp = trim(fgets(STDIN, 1024)); + if ($tmp !== '') { + $result[$var] = $tmp; } - - // Message logged above in a specific verbose mode, passing null to not show up on CLI - $this->pushError(null, PEAR_INSTALLER_SKIPPED); - } else { - do { - if ($params[$i] && $params[$i]->getType() == 'local') { - // bug #7090 skip channel.xml check for local packages - break; + } elseif ($tmp == 'all') { + foreach ($prompts as $var => $desc) { + $current = $result[$var]; + print "$desc [$current] : "; + $tmp = trim(fgets(STDIN, 1024)); + if (trim($tmp) !== '') { + $result[$var] = trim($tmp); } + } + } - if ($params[$i] && !isset($channelschecked[$params[$i]->getChannel()]) && - !isset($this->_options['offline'])) { - $channelschecked[$params[$i]->getChannel()] = true; - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - if (!class_exists('System')) { - require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; - } + $first_run = false; + } - $curchannel = &$this->_registry->getChannel($params[$i]->getChannel()); - if (PEAR::isError($curchannel)) { - PEAR::staticPopErrorHandling(); - return $this->raiseError($curchannel); - } + return $result; + } - if (PEAR::isError($dir = $this->getDownloadDir())) { - PEAR::staticPopErrorHandling(); - break; - } + function userConfirm($prompt, $default = 'yes') + { + trigger_error("PEAR_Frontend_CLI::userConfirm not yet converted", E_USER_ERROR); + static $positives = array('y', 'yes', 'on', '1'); + static $negatives = array('n', 'no', 'off', '0'); + print "$this->lp$prompt [$default] : "; + $fp = fopen("php://stdin", "r"); + $line = fgets($fp, 2048); + fclose($fp); + $answer = strtolower(trim($line)); + if (empty($answer)) { + $answer = $default; + } + if (in_array($answer, $positives)) { + return true; + } + if (in_array($answer, $negatives)) { + return false; + } + if (in_array($default, $positives)) { + return true; + } + return false; + } - $mirror = $this->config->get('preferred_mirror', null, - $params[$i]->getChannel()); - $a = $this->downloadHttp('http://' . $mirror . - '/channel.xml', $this->ui, $dir, null, $curchannel->lastModified()); + function outputData($data, $command = '_default') + { + switch ($command) { + case 'channel-info': + foreach ($data as $type => $section) { + if ($type == 'main') { + $section['data'] = array_values($section['data']); + } - PEAR::staticPopErrorHandling(); - if (PEAR::isError($a) || !$a) { - // Attempt fallback to https automatically - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $a = $this->downloadHttp('https://' . $mirror . - '/channel.xml', $this->ui, $dir, null, $curchannel->lastModified()); + $this->outputData($section); + } + break; + case 'install': + case 'upgrade': + case 'upgrade-all': + if (isset($data['release_warnings'])) { + $this->_displayLine(''); + $this->_startTable(array( + 'border' => false, + 'caption' => 'Release Warnings' + )); + $this->_tableRow(array($data['release_warnings']), null, array(1 => array('wrap' => 55))); + $this->_endTable(); + $this->_displayLine(''); + } - PEAR::staticPopErrorHandling(); - if (PEAR::isError($a) || !$a) { - break; - } - } - $this->log(0, 'WARNING: channel "' . $params[$i]->getChannel() . '" has ' . - 'updated its protocols, use "' . PEAR_RUNTYPE . ' channel-update ' . $params[$i]->getChannel() . - '" to update'); - } - } while (false); + $this->_displayLine($data['data']); + break; + case 'search': + $this->_startTable($data); + if (isset($data['headline']) && is_array($data['headline'])) { + $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55))); + } - if ($params[$i] && !isset($this->_options['downloadonly'])) { - if (isset($this->_options['packagingroot'])) { - $checkdir = $this->_prependPath( - $this->config->get('php_dir', null, $params[$i]->getChannel()), - $this->_options['packagingroot']); - } else { - $checkdir = $this->config->get('php_dir', - null, $params[$i]->getChannel()); + foreach($data['data'] as $category) { + foreach($category as $pkg) { + $this->_tableRow($pkg, null, array(1 => array('wrap' => 55))); } + } - while ($checkdir && $checkdir != '/' && !file_exists($checkdir)) { - $checkdir = dirname($checkdir); - } + $this->_endTable(); + break; + case 'list-all': + if (!isset($data['data'])) { + $this->_displayLine('No packages in channel'); + break; + } - if ($checkdir == '.') { - $checkdir = '/'; - } + $this->_startTable($data); + if (isset($data['headline']) && is_array($data['headline'])) { + $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55))); + } - if (!is_writeable($checkdir)) { - return PEAR::raiseError('Cannot install, php_dir for channel "' . - $params[$i]->getChannel() . '" is not writeable by the current user'); + foreach($data['data'] as $category) { + foreach($category as $pkg) { + unset($pkg[4], $pkg[5]); + $this->_tableRow($pkg, null, array(1 => array('wrap' => 55))); } } - } - } - unset($channelschecked); - PEAR_Downloader_Package::removeDuplicates($params); - if (!count($params)) { - $a = array(); - return $a; - } + $this->_endTable(); + break; + case 'config-show': + $data['border'] = false; + $opts = array( + 0 => array('wrap' => 30), + 1 => array('wrap' => 20), + 2 => array('wrap' => 35) + ); - if (!isset($this->_options['nodeps']) && !isset($this->_options['offline'])) { - $reverify = true; - while ($reverify) { - $reverify = false; - foreach ($params as $i => $param) { - //PHP Bug 40768 / PEAR Bug #10944 - //Nested foreaches fail in PHP 5.2.1 - key($params); - $ret = $params[$i]->detectDependencies($params); - if (PEAR::isError($ret)) { - $reverify = true; - $params[$i] = false; - PEAR_Downloader_Package::removeDuplicates($params); - if (!isset($this->_options['soft'])) { - $this->log(0, $ret->getMessage()); + $this->_startTable($data); + if (isset($data['headline']) && is_array($data['headline'])) { + $this->_tableRow($data['headline'], array('bold' => true), $opts); + } + + foreach ($data['data'] as $group) { + foreach ($group as $value) { + if ($value[2] == '') { + $value[2] = ""; } - continue 2; + + $this->_tableRow($value, null, $opts); + } + } + + $this->_endTable(); + break; + case 'remote-info': + $d = $data; + $data = array( + 'caption' => 'Package details:', + 'border' => false, + 'data' => array( + array("Latest", $data['stable']), + array("Installed", $data['installed']), + array("Package", $data['name']), + array("License", $data['license']), + array("Category", $data['category']), + array("Summary", $data['summary']), + array("Description", $data['description']), + ), + ); + + if (isset($d['deprecated']) && $d['deprecated']) { + $conf = &PEAR_Config::singleton(); + $reg = $conf->getRegistry(); + $name = $reg->parsedPackageNameToString($d['deprecated'], true); + $data['data'][] = array('Deprecated! use', $name); + } + default: { + if (is_array($data)) { + $this->_startTable($data); + $count = count($data['data'][0]); + if ($count == 2) { + $opts = array(0 => array('wrap' => 25), + 1 => array('wrap' => 48) + ); + } elseif ($count == 3) { + $opts = array(0 => array('wrap' => 30), + 1 => array('wrap' => 20), + 2 => array('wrap' => 35) + ); + } else { + $opts = null; + } + if (isset($data['headline']) && is_array($data['headline'])) { + $this->_tableRow($data['headline'], + array('bold' => true), + $opts); + } + + foreach($data['data'] as $row) { + $this->_tableRow($row, null, $opts); } + $this->_endTable(); + } else { + $this->_displayLine($data); } } } + } - if (isset($this->_options['offline'])) { - $this->log(3, 'Skipping dependency download check, --offline specified'); + function log($text, $append_crlf = true) + { + if ($append_crlf) { + return $this->_displayLine($text); } - if (!count($params)) { - $a = array(); - return $a; + return $this->_display($text); + } + + function bold($text) + { + if (empty($this->term['bold'])) { + return strtoupper($text); } - while (PEAR_Downloader_Package::mergeDependencies($params)); - PEAR_Downloader_Package::removeDuplicates($params, true); - $errorparams = array(); - if (PEAR_Downloader_Package::detectStupidDuplicates($params, $errorparams)) { - if (count($errorparams)) { - foreach ($errorparams as $param) { - $name = $this->_registry->parsedPackageNameToString($param->getParsedPackage()); - $this->pushError('Duplicate package ' . $name . ' found', PEAR_INSTALLER_FAILED); + return $this->term['bold'] . $text . $this->term['normal']; + } + + function _displayHeading($title) + { + print $this->lp.$this->bold($title)."\n"; + print $this->lp.str_repeat("=", strlen($title))."\n"; + } + + function _startTable($params = array()) + { + $params['table_data'] = array(); + $params['widest'] = array(); // indexed by column + $params['highest'] = array(); // indexed by row + $params['ncols'] = 0; + $this->params = $params; + } + + function _tableRow($columns, $rowparams = array(), $colparams = array()) + { + $highest = 1; + for ($i = 0; $i < count($columns); $i++) { + $col = &$columns[$i]; + if (isset($colparams[$i]) && !empty($colparams[$i]['wrap'])) { + $col = wordwrap($col, $colparams[$i]['wrap']); + } + + if (strpos($col, "\n") !== false) { + $multiline = explode("\n", $col); + $w = 0; + foreach ($multiline as $n => $line) { + $len = strlen($line); + if ($len > $w) { + $w = $len; + } } - $a = array(); - return $a; + $lines = count($multiline); + } else { + $w = strlen($col); + } + + if (isset($this->params['widest'][$i])) { + if ($w > $this->params['widest'][$i]) { + $this->params['widest'][$i] = $w; + } + } else { + $this->params['widest'][$i] = $w; + } + + $tmp = count_chars($columns[$i], 1); + // handle unix, mac and windows formats + $lines = (isset($tmp[10]) ? $tmp[10] : (isset($tmp[13]) ? $tmp[13] : 0)) + 1; + if ($lines > $highest) { + $highest = $lines; } } - PEAR_Downloader_Package::removeInstalled($params); - if (!count($params)) { - $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED); - $a = array(); - return $a; + if (count($columns) > $this->params['ncols']) { + $this->params['ncols'] = count($columns); } - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $err = $this->analyzeDependencies($params); - PEAR::popErrorHandling(); - if (!count($params)) { - $this->pushError('No valid packages found', PEAR_INSTALLER_FAILED); - $a = array(); - return $a; + $new_row = array( + 'data' => $columns, + 'height' => $highest, + 'rowparams' => $rowparams, + 'colparams' => $colparams, + ); + $this->params['table_data'][] = $new_row; + } + + function _endTable() + { + extract($this->params); + if (!empty($caption)) { + $this->_displayHeading($caption); } - $ret = array(); - $newparams = array(); - if (isset($this->_options['pretend'])) { - return $params; + if (count($table_data) === 0) { + return; } - $somefailed = false; - foreach ($params as $i => $package) { - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $pf = &$params[$i]->download(); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($pf)) { - if (!isset($this->_options['soft'])) { - $this->log(1, $pf->getMessage()); - $this->log(0, 'Error: cannot download "' . - $this->_registry->parsedPackageNameToString($package->getParsedPackage(), - true) . - '"'); + if (!isset($width)) { + $width = $widest; + } else { + for ($i = 0; $i < $ncols; $i++) { + if (!isset($width[$i])) { + $width[$i] = $widest[$i]; } - $somefailed = true; - continue; } - - $newparams[] = &$params[$i]; - $ret[] = array( - 'file' => $pf->getArchiveFile(), - 'info' => &$pf, - 'pkg' => $pf->getPackage() - ); } - if ($somefailed) { - // remove params that did not download successfully - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $err = $this->analyzeDependencies($newparams, true); - PEAR::popErrorHandling(); - if (!count($newparams)) { - $this->pushError('Download failed', PEAR_INSTALLER_FAILED); - $a = array(); - return $a; + $border = false; + if (empty($border)) { + $cellstart = ''; + $cellend = ' '; + $rowend = ''; + $padrowend = false; + $borderline = ''; + } else { + $cellstart = '| '; + $cellend = ' '; + $rowend = '|'; + $padrowend = true; + $borderline = '+'; + foreach ($width as $w) { + $borderline .= str_repeat('-', $w + strlen($cellstart) + strlen($cellend) - 1); + $borderline .= '+'; } } - $this->_downloadedPackages = $ret; - return $newparams; - } - - /** - * @param array all packages to be installed - */ - function analyzeDependencies(&$params, $force = false) - { - $hasfailed = $failed = false; - if (isset($this->_options['downloadonly'])) { - return; + if ($borderline) { + $this->_displayLine($borderline); } - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $redo = true; - $reset = false; - while ($redo) { - $redo = false; - foreach ($params as $i => $param) { - $deps = $param->getDeps(); - if (!$deps) { - $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(), - $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); - $send = $param->getPackageFile(); + for ($i = 0; $i < count($table_data); $i++) { + extract($table_data[$i]); + if (!is_array($rowparams)) { + $rowparams = array(); + } - $installcheck = $depchecker->validatePackage($send, $this, $params); - if (PEAR::isError($installcheck)) { - if (!isset($this->_options['soft'])) { - $this->log(0, $installcheck->getMessage()); - } - $hasfailed = true; - $params[$i] = false; - $reset = true; - $redo = true; - $failed = false; - PEAR_Downloader_Package::removeDuplicates($params); - continue 2; + if (!is_array($colparams)) { + $colparams = array(); + } + + $rowlines = array(); + if ($height > 1) { + for ($c = 0; $c < count($data); $c++) { + $rowlines[$c] = preg_split('/(\r?\n|\r)/', $data[$c]); + if (count($rowlines[$c]) < $height) { + $rowlines[$c] = array_pad($rowlines[$c], $height, ''); } - continue; } - - if (!$reset && $param->alreadyValidated() && !$force) { - continue; + } else { + for ($c = 0; $c < count($data); $c++) { + $rowlines[$c] = array($data[$c]); } + } - if (count($deps)) { - $depchecker = &$this->getDependency2Object($this->config, $this->getOptions(), - $param->getParsedPackage(), PEAR_VALIDATE_DOWNLOADING); - $send = $param->getPackageFile(); - if ($send === null) { - $send = $param->getDownloadURL(); + for ($r = 0; $r < $height; $r++) { + $rowtext = ''; + for ($c = 0; $c < count($data); $c++) { + if (isset($colparams[$c])) { + $attribs = array_merge($rowparams, $colparams); + } else { + $attribs = $rowparams; } - $installcheck = $depchecker->validatePackage($send, $this, $params); - if (PEAR::isError($installcheck)) { - if (!isset($this->_options['soft'])) { - $this->log(0, $installcheck->getMessage()); - } - $hasfailed = true; - $params[$i] = false; - $reset = true; - $redo = true; - $failed = false; - PEAR_Downloader_Package::removeDuplicates($params); - continue 2; + $w = isset($width[$c]) ? $width[$c] : 0; + //$cell = $data[$c]; + $cell = $rowlines[$c][$r]; + $l = strlen($cell); + if ($l > $w) { + $cell = substr($cell, 0, $w); } - $failed = false; - if (isset($deps['required'])) { - foreach ($deps['required'] as $type => $dep) { - // note: Dependency2 will never return a PEAR_Error if ignore-errors - // is specified, so soft is needed to turn off logging - if (!isset($dep[0])) { - if (PEAR::isError($e = $depchecker->{"validate{$type}Dependency"}($dep, - true, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } else { - foreach ($dep as $d) { - if (PEAR::isError($e = - $depchecker->{"validate{$type}Dependency"}($d, - true, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } - } - } - - if (isset($deps['optional'])) { - foreach ($deps['optional'] as $type => $dep) { - if (!isset($dep[0])) { - if (PEAR::isError($e = - $depchecker->{"validate{$type}Dependency"}($dep, - false, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } else { - foreach ($dep as $d) { - if (PEAR::isError($e = - $depchecker->{"validate{$type}Dependency"}($d, - false, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } - } - } - } - - $groupname = $param->getGroup(); - if (isset($deps['group']) && $groupname) { - if (!isset($deps['group'][0])) { - $deps['group'] = array($deps['group']); - } - - $found = false; - foreach ($deps['group'] as $group) { - if ($group['attribs']['name'] == $groupname) { - $found = true; - break; - } - } + if (isset($attribs['bold'])) { + $cell = $this->bold($cell); + } - if ($found) { - unset($group['attribs']); - foreach ($group as $type => $dep) { - if (!isset($dep[0])) { - if (PEAR::isError($e = - $depchecker->{"validate{$type}Dependency"}($dep, - false, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } else { - foreach ($dep as $d) { - if (PEAR::isError($e = - $depchecker->{"validate{$type}Dependency"}($d, - false, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } - } - } - } - } - } else { - foreach ($deps as $dep) { - if (PEAR::isError($e = $depchecker->validateDependency1($dep, $params))) { - $failed = true; - if (!isset($this->_options['soft'])) { - $this->log(0, $e->getMessage()); - } - } elseif (is_array($e) && !$param->alreadyValidated()) { - if (!isset($this->_options['soft'])) { - $this->log(0, $e[0]); - } - } - } + if ($l < $w) { + // not using str_pad here because we may + // add bold escape characters to $cell + $cell .= str_repeat(' ', $w - $l); } - $params[$i]->setValidated(); + + $rowtext .= $cellstart . $cell . $cellend; } - if ($failed) { - $hasfailed = true; - $params[$i] = false; - $reset = true; - $redo = true; - $failed = false; - PEAR_Downloader_Package::removeDuplicates($params); - continue 2; + if (!$border) { + $rowtext = rtrim($rowtext); } + + $rowtext .= $rowend; + $this->_displayLine($rowtext); } } - PEAR::staticPopErrorHandling(); - if ($hasfailed && (isset($this->_options['ignore-errors']) || - isset($this->_options['nodeps']))) { - // this is probably not needed, but just in case - if (!isset($this->_options['soft'])) { - $this->log(0, 'WARNING: dependencies failed'); - } + + if ($borderline) { + $this->_displayLine($borderline); } } + function _displayLine($text) + { + print "$this->lp$text\n"; + } + + function _display($text) + { + print $text; + } +} + * @author Tomas V.V. Cox + * @author Martin Jansen + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Installer.php 287446 2009-08-18 11:45:05Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 0.1 + */ + +/** + * Used for installation groups in package.xml 2.0 and platform exceptions + */ +require_once 'phar://install-pear-nozlib.phar/' . 'OS/Guess.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Downloader.php'; + +define('PEAR_INSTALLER_NOBINARY', -240); +/** + * Administration class used to install PEAR packages and maintain the + * installed package database. + * + * @category pear + * @package PEAR + * @author Stig Bakken + * @author Tomas V.V. Cox + * @author Martin Jansen + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 0.1 + */ +class PEAR_Installer extends PEAR_Downloader +{ + // {{{ properties + + /** name of the package directory, for example Foo-1.0 + * @var string + */ + var $pkgdir; + + /** directory where PHP code files go + * @var string + */ + var $phpdir; + + /** directory where PHP extension files go + * @var string + */ + var $extdir; + + /** directory where documentation goes + * @var string + */ + var $docdir; + + /** installation root directory (ala PHP's INSTALL_ROOT or + * automake's DESTDIR + * @var string + */ + var $installroot = ''; + + /** debug level + * @var int + */ + var $debug = 1; + + /** temporary directory + * @var string + */ + var $tmpdir; + /** - * Retrieve the directory that downloads will happen in - * @access private - * @return string + * PEAR_Registry object used by the installer + * @var PEAR_Registry */ - function getDownloadDir() - { - if (isset($this->_downloadDir)) { - return $this->_downloadDir; - } - $downloaddir = $this->config->get('download_dir'); - if (empty($downloaddir) || (is_dir($downloaddir) && !is_writable($downloaddir))) { - if (is_dir($downloaddir) && !is_writable($downloaddir)) { - $this->log(0, 'WARNING: configuration download directory "' . $downloaddir . - '" is not writeable. Change download_dir config variable to ' . - 'a writeable dir to avoid this warning'); - } - if (!class_exists('System')) { - require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; - } - if (PEAR::isError($downloaddir = System::mktemp('-d'))) { - return $downloaddir; - } - $this->log(3, '+ tmp dir created at ' . $downloaddir); - } - if (!is_writable($downloaddir)) { - if (PEAR::isError(System::mkdir(array('-p', $downloaddir))) || - !is_writable($downloaddir)) { - return PEAR::raiseError('download directory "' . $downloaddir . - '" is not writeable. Change download_dir config variable to ' . - 'a writeable dir'); - } - } - return $this->_downloadDir = $downloaddir; - } + var $registry; - function setDownloadDir($dir) - { - if (!@is_writable($dir)) { - if (PEAR::isError(System::mkdir(array('-p', $dir)))) { - return PEAR::raiseError('download directory "' . $dir . - '" is not writeable. Change download_dir config variable to ' . - 'a writeable dir'); - } - } - $this->_downloadDir = $dir; - } + /** + * array of PEAR_Downloader_Packages + * @var array + */ + var $_downloadedPackages; + + /** List of file transactions queued for an install/upgrade/uninstall. + * + * Format: + * array( + * 0 => array("rename => array("from-file", "to-file")), + * 1 => array("delete" => array("file-to-delete")), + * ... + * ) + * + * @var array + */ + var $file_operations = array(); // }}} - // {{{ configSet() - function configSet($key, $value, $layer = 'user', $channel = false) + + // {{{ constructor + + /** + * PEAR_Installer constructor. + * + * @param object $ui user interface object (instance of PEAR_Frontend_*) + * + * @access public + */ + function PEAR_Installer(&$ui) { - $this->config->set($key, $value, $layer, $channel); - $this->_preferredState = $this->config->get('preferred_state', null, $channel); - if (!$this->_preferredState) { - // don't inadvertantly use a non-set preferred_state - $this->_preferredState = null; - } + parent::PEAR_Common(); + $this->setFrontendObject($ui); + $this->debug = $this->config->get('verbose'); } - // }}} - // {{{ setOptions() function setOptions($options) { $this->_options = $options; } - // }}} - // {{{ setOptions() - function getOptions() + function setConfig(&$config) { - return $this->_options; + $this->config = &$config; + $this->_registry = &$config->getRegistry(); } // }}} - /** - * For simpler unit-testing - * @param PEAR_Config - * @param int - * @param string - */ - function &getPackagefileObject(&$c, $d, $t = false) + function _removeBackups($files) { - if (!class_exists('PEAR_PackageFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile.php'; + foreach ($files as $path) { + $this->addFileOperation('removebackup', array($path)); } - $a = &new PEAR_PackageFile($c, $d, $t); - return $a; } - // {{{ _getPackageDownloadUrl() + // {{{ _deletePackageFiles() /** - * @param array output of {@link parsePackageName()} - * @access private + * Delete a package's installed files, does not remove empty directories. + * + * @param string package name + * @param string channel name + * @param bool if true, then files are backed up first + * @return bool TRUE on success, or a PEAR error on failure + * @access protected */ - function _getPackageDownloadUrl($parr) + function _deletePackageFiles($package, $channel = false, $backup = false) { - $curchannel = $this->config->get('default_channel'); - $this->configSet('default_channel', $parr['channel']); - // getDownloadURL returns an array. On error, it only contains information - // on the latest release as array(version, info). On success it contains - // array(version, info, download url string) - $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state'); - if (!$this->_registry->channelExists($parr['channel'])) { - do { - if ($this->config->get('auto_discover') && $this->discover($parr['channel'])) { - break; - } - - $this->configSet('default_channel', $curchannel); - return PEAR::raiseError('Unknown remote channel: ' . $parr['channel']); - } while (false); - } - - $chan = &$this->_registry->getChannel($parr['channel']); - if (PEAR::isError($chan)) { - return $chan; - } - - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $version = $this->_registry->packageInfo($parr['package'], 'version', $parr['channel']); - $stability = $this->_registry->packageInfo($parr['package'], 'stability', $parr['channel']); - // package is installed - use the installed release stability level - if (!isset($parr['state']) && $stability !== null) { - $state = $stability['release']; - } - PEAR::staticPopErrorHandling(); - $base2 = false; - - $preferred_mirror = $this->config->get('preferred_mirror'); - if (!$chan->supportsREST($preferred_mirror) || - ( - !($base2 = $chan->getBaseURL('REST1.3', $preferred_mirror)) - && - !($base = $chan->getBaseURL('REST1.0', $preferred_mirror)) - ) - ) { - return $this->raiseError($parr['channel'] . ' is using a unsupported protocal - This should never happen.'); - } - - if ($base2) { - $rest = &$this->config->getREST('1.3', $this->_options); - $base = $base2; - } else { - $rest = &$this->config->getREST('1.0', $this->_options); - } - - if (!isset($parr['version']) && !isset($parr['state']) && $version - && !PEAR::isError($version) - && !isset($this->_options['downloadonly'])) { - $url = $rest->getDownloadURL($base, $parr, $state, $version, $chan->getName()); - } else { - $url = $rest->getDownloadURL($base, $parr, $state, false, $chan->getName()); - } - - if (PEAR::isError($url)) { - $this->configSet('default_channel', $curchannel); - return $url; + if (!$channel) { + $channel = 'pear.php.net'; } - if ($parr['channel'] != $curchannel) { - $this->configSet('default_channel', $curchannel); + if (!strlen($package)) { + return $this->raiseError("No package to uninstall given"); } - if (!is_array($url)) { - return $url; + if (strtolower($package) == 'pear' && $channel == 'pear.php.net') { + // to avoid race conditions, include all possible needed files + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Common.php'; + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Replace.php'; + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Unixeol.php'; + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Windowseol.php'; + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2.php'; + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/Generator/v1.php'; + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/Generator/v2.php'; } - $url['raw'] = false; // no checking is necessary for REST - if (!is_array($url['info'])) { - return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . - 'this should never happen'); + $filelist = $this->_registry->packageInfo($package, 'filelist', $channel); + if ($filelist == null) { + return $this->raiseError("$channel/$package not installed"); } - if (!isset($this->_options['force']) && - !isset($this->_options['downloadonly']) && - $version && - !PEAR::isError($version) && - !isset($parr['group']) - ) { - if (version_compare($version, $url['version'], '=')) { - return PEAR::raiseError($this->_registry->parsedPackageNameToString( - $parr, true) . ' is already installed and is the same as the ' . - 'released version ' . $url['version'], -976); - } - - if (version_compare($version, $url['version'], '>')) { - return PEAR::raiseError($this->_registry->parsedPackageNameToString( - $parr, true) . ' is already installed and is newer than detected ' . - 'released version ' . $url['version'], -976); + $ret = array(); + foreach ($filelist as $file => $props) { + if (empty($props['installed_as'])) { + continue; } - } - if (isset($url['info']['required']) || $url['compatible']) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2.php'; - $pf = new PEAR_PackageFile_v2; - $pf->setRawChannel($parr['channel']); - if ($url['compatible']) { - $pf->setRawCompatible($url['compatible']); + $path = $props['installed_as']; + if ($backup) { + $this->addFileOperation('backup', array($path)); + $ret[] = $path; } - } else { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; - $pf = new PEAR_PackageFile_v1; - } - - $pf->setRawPackage($url['package']); - $pf->setDeps($url['info']); - if ($url['compatible']) { - $pf->setCompatible($url['compatible']); - } - $pf->setRawState($url['stability']); - $url['info'] = &$pf; - if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) { - $ext = '.tar'; - } else { - $ext = '.tgz'; + $this->addFileOperation('delete', array($path)); } - if (is_array($url) && isset($url['url'])) { - $url['url'] .= $ext; + if ($backup) { + return $ret; } - return $url; + return true; } + // }}} - // {{{ getDepPackageDownloadUrl() + // {{{ _installFile() /** - * @param array dependency array + * @param string filename + * @param array attributes from tag in package.xml + * @param string path to install the file in + * @param array options from command-line * @access private */ - function _getDepPackageDownloadUrl($dep, $parr) + function _installFile($file, $atts, $tmp_path, $options) { - $xsdversion = isset($dep['rel']) ? '1.0' : '2.0'; - $curchannel = $this->config->get('default_channel'); - if (isset($dep['uri'])) { - $xsdversion = '2.0'; - $chan = &$this->_registry->getChannel('__uri'); - if (PEAR::isError($chan)) { - return $chan; - } - - $version = $this->_registry->packageInfo($dep['name'], 'version', '__uri'); - $this->configSet('default_channel', '__uri'); - } else { - if (isset($dep['channel'])) { - $remotechannel = $dep['channel']; - } else { - $remotechannel = 'pear.php.net'; - } - - if (!$this->_registry->channelExists($remotechannel)) { - do { - if ($this->config->get('auto_discover')) { - if ($this->discover($remotechannel)) { - break; - } - } - return PEAR::raiseError('Unknown remote channel: ' . $remotechannel); - } while (false); - } - - $chan = &$this->_registry->getChannel($remotechannel); - if (PEAR::isError($chan)) { - return $chan; - } - - $version = $this->_registry->packageInfo($dep['name'], 'version', $remotechannel); - $this->configSet('default_channel', $remotechannel); - } - - $state = isset($parr['state']) ? $parr['state'] : $this->config->get('preferred_state'); - if (isset($parr['state']) && isset($parr['version'])) { - unset($parr['state']); + // {{{ return if this file is meant for another platform + static $os; + if (!isset($this->_registry)) { + $this->_registry = &$this->config->getRegistry(); } - if (isset($dep['uri'])) { - $info = &$this->newDownloaderPackage($this); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $err = $info->initialize($dep); - PEAR::staticPopErrorHandling(); - if (!$err) { - // skip parameters that were missed by preferred_state - return PEAR::raiseError('Cannot initialize dependency'); - } - - if (PEAR::isError($err)) { - if (!isset($this->_options['soft'])) { - $this->log(0, $err->getMessage()); - } - - if (is_object($info)) { - $param = $info->getChannel() . '/' . $info->getPackage(); - } - return PEAR::raiseError('Package "' . $param . '" is not valid'); - } - return $info; - } elseif ($chan->supportsREST($this->config->get('preferred_mirror')) - && $base = $chan->getBaseURL('REST1.0', $this->config->get('preferred_mirror')) - ) { - $rest = &$this->config->getREST('1.0', $this->_options); - $url = $rest->getDepDownloadURL($base, $xsdversion, $dep, $parr, - $state, $version, $chan->getName()); - if (PEAR::isError($url)) { - return $url; - } - - if ($parr['channel'] != $curchannel) { - $this->configSet('default_channel', $curchannel); - } - - if (!is_array($url)) { - return $url; - } - - $url['raw'] = false; // no checking is necessary for REST - if (!is_array($url['info'])) { - return PEAR::raiseError('Invalid remote dependencies retrieved from REST - ' . - 'this should never happen'); - } - - if (isset($url['info']['required'])) { - if (!class_exists('PEAR_PackageFile_v2')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2.php'; - } - $pf = new PEAR_PackageFile_v2; - $pf->setRawChannel($remotechannel); - } else { - if (!class_exists('PEAR_PackageFile_v1')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; - } - $pf = new PEAR_PackageFile_v1; - - } - $pf->setRawPackage($url['package']); - $pf->setDeps($url['info']); - if ($url['compatible']) { - $pf->setCompatible($url['compatible']); + if (isset($atts['platform'])) { + if (empty($os)) { + $os = new OS_Guess(); } - $pf->setRawState($url['stability']); - $url['info'] = &$pf; - if (!extension_loaded("zlib") || isset($this->_options['nocompress'])) { - $ext = '.tar'; + if (strlen($atts['platform']) && $atts['platform']{0} == '!') { + $negate = true; + $platform = substr($atts['platform'], 1); } else { - $ext = '.tgz'; - } - - if (is_array($url) && isset($url['url'])) { - $url['url'] .= $ext; + $negate = false; + $platform = $atts['platform']; } - return $url; - } - - return $this->raiseError($parr['channel'] . ' is using a unsupported protocal - This should never happen.'); - } - // }}} - // {{{ getPackageDownloadUrl() - - /** - * @deprecated in favor of _getPackageDownloadUrl - */ - function getPackageDownloadUrl($package, $version = null, $channel = false) - { - if ($version) { - $package .= "-$version"; - } - if ($this === null || $this->_registry === null) { - $package = "http://pear.php.net/get/$package"; - } else { - $chan = $this->_registry->getChannel($channel); - if (PEAR::isError($chan)) { - return ''; + if ((bool) $os->matchSignature($platform) === $negate) { + $this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")"); + return PEAR_INSTALLER_SKIPPED; } - $package = "http://" . $chan->getServer() . "/get/$package"; - } - if (!extension_loaded("zlib")) { - $package .= '?uncompress=yes'; - } - return $package; - } - - // }}} - // {{{ getDownloadedPackages() - - /** - * Retrieve a list of downloaded packages after a call to {@link download()}. - * - * Also resets the list of downloaded packages. - * @return array - */ - function getDownloadedPackages() - { - $ret = $this->_downloadedPackages; - $this->_downloadedPackages = array(); - $this->_toDownload = array(); - return $ret; - } - - // }}} - // {{{ _downloadCallback() - - function _downloadCallback($msg, $params = null) - { - switch ($msg) { - case 'saveas': - $this->log(1, "downloading $params ..."); - break; - case 'done': - $this->log(1, '...done: ' . number_format($params, 0, '', ',') . ' bytes'); - break; - case 'bytesread': - static $bytes; - if (empty($bytes)) { - $bytes = 0; - } - if (!($bytes % 10240)) { - $this->log(1, '.', false); - } - $bytes += $params; - break; - case 'start': - if($params[1] == -1) { - $length = "Unknown size"; - } else { - $length = number_format($params[1], 0, '', ',')." bytes"; - } - $this->log(1, "Starting to download {$params[0]} ($length)"); - break; } - if (method_exists($this->ui, '_downloadCallback')) - $this->ui->_downloadCallback($msg, $params); - } - - // }}} - // {{{ _prependPath($path, $prepend) + // }}} - function _prependPath($path, $prepend) - { - if (strlen($prepend) > 0) { - if (OS_WINDOWS && preg_match('/^[a-z]:/i', $path)) { - if (preg_match('/^[a-z]:/i', $prepend)) { - $prepend = substr($prepend, 2); - } elseif ($prepend{0} != '\\') { - $prepend = "\\$prepend"; - } - $path = substr($path, 0, 2) . $prepend . substr($path, 2); - } else { - $path = $prepend . $path; - } + $channel = $this->pkginfo->getChannel(); + // {{{ assemble the destination paths + switch ($atts['role']) { + case 'src': + case 'extsrc': + $this->source_files++; + return; + case 'doc': + case 'data': + case 'test': + $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel) . + DIRECTORY_SEPARATOR . $this->pkginfo->getPackage(); + unset($atts['baseinstalldir']); + break; + case 'ext': + case 'php': + $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel); + break; + case 'script': + $dest_dir = $this->config->get('bin_dir', null, $channel); + break; + default: + return $this->raiseError("Invalid role `$atts[role]' for file $file"); } - return $path; - } - // }}} - // {{{ pushError($errmsg, $code) - - /** - * @param string - * @param integer - */ - function pushError($errmsg, $code = -1) - { - array_push($this->_errorStack, array($errmsg, $code)); - } - // }}} - // {{{ getErrorMsgs() + $save_destdir = $dest_dir; + if (!empty($atts['baseinstalldir'])) { + $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; + } - function getErrorMsgs() - { - $msgs = array(); - $errs = $this->_errorStack; - foreach ($errs as $err) { - $msgs[] = $err[0]; + if (dirname($file) != '.' && empty($atts['install-as'])) { + $dest_dir .= DIRECTORY_SEPARATOR . dirname($file); } - $this->_errorStack = array(); - return $msgs; - } - // }}} + if (empty($atts['install-as'])) { + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); + } else { + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as']; + } + $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file; - /** - * for BC - */ - function sortPkgDeps(&$packages, $uninstall = false) - { - $uninstall ? - $this->sortPackagesForUninstall($packages) : - $this->sortPackagesForInstall($packages); - } + // Clean up the DIRECTORY_SEPARATOR mess + $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; + list($dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), + array(DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR), + array($dest_file, $orig_file)); + $final_dest_file = $installed_as = $dest_file; + if (isset($this->_options['packagingroot'])) { + $installedas_dest_dir = dirname($final_dest_file); + $installedas_dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + $final_dest_file = $this->_prependPath($final_dest_file, $this->_options['packagingroot']); + } else { + $installedas_dest_dir = dirname($final_dest_file); + $installedas_dest_file = $installedas_dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + } - /** - * Sort a list of arrays of array(downloaded packagefilename) by dependency. - * - * This uses the topological sort method from graph theory, and the - * Structures_Graph package to properly sort dependencies for installation. - * @param array an array of downloaded PEAR_Downloader_Packages - * @return array array of array(packagefilename, package.xml contents) - */ - function sortPackagesForInstall(&$packages) - { - require_once 'phar://install-pear-nozlib.phar/' . 'Structures/Graph.php'; - require_once 'phar://install-pear-nozlib.phar/' . 'Structures/Graph/Node.php'; - require_once 'phar://install-pear-nozlib.phar/' . 'Structures/Graph/Manipulator/TopologicalSorter.php'; - $depgraph = new Structures_Graph(true); - $nodes = array(); - $reg = &$this->config->getRegistry(); - foreach ($packages as $i => $package) { - $pname = $reg->parsedPackageNameToString( - array( - 'channel' => $package->getChannel(), - 'package' => strtolower($package->getPackage()), - )); - $nodes[$pname] = new Structures_Graph_Node; - $nodes[$pname]->setData($packages[$i]); - $depgraph->addNode($nodes[$pname]); + $dest_dir = dirname($final_dest_file); + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { + return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); } + // }}} - $deplinks = array(); - foreach ($nodes as $package => $node) { - $pf = &$node->getData(); - $pdeps = $pf->getDeps(true); - if (!$pdeps) { - continue; + if (empty($this->_options['register-only']) && + (!file_exists($dest_dir) || !is_dir($dest_dir))) { + if (!$this->mkDirHier($dest_dir)) { + return $this->raiseError("failed to mkdir $dest_dir", + PEAR_INSTALLER_FAILED); } + $this->log(3, "+ mkdir $dest_dir"); + } - if ($pf->getPackagexmlVersion() == '1.0') { - foreach ($pdeps as $dep) { - if ($dep['type'] != 'pkg' || - (isset($dep['optional']) && $dep['optional'] == 'yes')) { - continue; - } - - $dname = $reg->parsedPackageNameToString( - array( - 'channel' => 'pear.php.net', - 'package' => strtolower($dep['name']), - )); - - if (isset($nodes[$dname])) { - if (!isset($deplinks[$dname])) { - $deplinks[$dname] = array(); - } - - $deplinks[$dname][$package] = 1; - // dependency is in installed packages - continue; - } - - $dname = $reg->parsedPackageNameToString( - array( - 'channel' => 'pecl.php.net', - 'package' => strtolower($dep['name']), - )); + // pretty much nothing happens if we are only registering the install + if (empty($this->_options['register-only'])) { + if (empty($atts['replacements'])) { + if (!file_exists($orig_file)) { + return $this->raiseError("file $orig_file does not exist", + PEAR_INSTALLER_FAILED); + } - if (isset($nodes[$dname])) { - if (!isset($deplinks[$dname])) { - $deplinks[$dname] = array(); - } + if (!@copy($orig_file, $dest_file)) { + return $this->raiseError("failed to write $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } - $deplinks[$dname][$package] = 1; - // dependency is in installed packages - continue; - } + $this->log(3, "+ cp $orig_file $dest_file"); + if (isset($atts['md5sum'])) { + $md5sum = md5_file($dest_file); } } else { - // the only ordering we care about is: - // 1) subpackages must be installed before packages that depend on them - // 2) required deps must be installed before packages that depend on them - if (isset($pdeps['required']['subpackage'])) { - $t = $pdeps['required']['subpackage']; - if (!isset($t[0])) { - $t = array($t); - } + // {{{ file with replacements + if (!file_exists($orig_file)) { + return $this->raiseError("file does not exist", + PEAR_INSTALLER_FAILED); + } - $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + $contents = file_get_contents($orig_file); + if ($contents === false) { + $contents = ''; } - if (isset($pdeps['group'])) { - if (!isset($pdeps['group'][0])) { - $pdeps['group'] = array($pdeps['group']); - } + if (isset($atts['md5sum'])) { + $md5sum = md5($contents); + } - foreach ($pdeps['group'] as $group) { - if (isset($group['subpackage'])) { - $t = $group['subpackage']; - if (!isset($t[0])) { - $t = array($t); + $subst_from = $subst_to = array(); + foreach ($atts['replacements'] as $a) { + $to = ''; + if ($a['type'] == 'php-const') { + if (preg_match('/^[a-z0-9_]+\\z/i', $a['to'])) { + eval("\$to = $a[to];"); + } else { + if (!isset($options['soft'])) { + $this->log(0, "invalid php-const replacement: $a[to]"); } - - $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + continue; + } + } elseif ($a['type'] == 'pear-config') { + if ($a['to'] == 'master_server') { + $chan = $this->_registry->getChannel($channel); + if (!PEAR::isError($chan)) { + $to = $chan->getServer(); + } else { + $to = $this->config->get($a['to'], null, $channel); + } + } else { + $to = $this->config->get($a['to'], null, $channel); + } + if (is_null($to)) { + if (!isset($options['soft'])) { + $this->log(0, "invalid pear-config replacement: $a[to]"); + } + continue; + } + } elseif ($a['type'] == 'package-info') { + if ($t = $this->pkginfo->packageInfo($a['to'])) { + $to = $t; + } else { + if (!isset($options['soft'])) { + $this->log(0, "invalid package-info replacement: $a[to]"); + } + continue; } } - } - - if (isset($pdeps['optional']['subpackage'])) { - $t = $pdeps['optional']['subpackage']; - if (!isset($t[0])) { - $t = array($t); + if (!is_null($to)) { + $subst_from[] = $a['from']; + $subst_to[] = $to; } + } - $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + $this->log(3, "doing ".sizeof($subst_from)." substitution(s) for $final_dest_file"); + if (sizeof($subst_from)) { + $contents = str_replace($subst_from, $subst_to, $contents); } - if (isset($pdeps['required']['package'])) { - $t = $pdeps['required']['package']; - if (!isset($t[0])) { - $t = array($t); - } + $wp = @fopen($dest_file, "wb"); + if (!is_resource($wp)) { + return $this->raiseError("failed to create $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } - $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + if (@fwrite($wp, $contents) === false) { + return $this->raiseError("failed writing to $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); } - if (isset($pdeps['group'])) { - if (!isset($pdeps['group'][0])) { - $pdeps['group'] = array($pdeps['group']); - } + fclose($wp); + // }}} + } - foreach ($pdeps['group'] as $group) { - if (isset($group['package'])) { - $t = $group['package']; - if (!isset($t[0])) { - $t = array($t); - } + // {{{ check the md5 + if (isset($md5sum)) { + if (strtolower($md5sum) === strtolower($atts['md5sum'])) { + $this->log(2, "md5sum ok: $final_dest_file"); + } else { + if (empty($options['force'])) { + // delete the file + if (file_exists($dest_file)) { + unlink($dest_file); + } - $this->_setupGraph($t, $reg, $deplinks, $nodes, $package); + if (!isset($options['ignore-errors'])) { + return $this->raiseError("bad md5sum for file $final_dest_file", + PEAR_INSTALLER_FAILED); + } + + if (!isset($options['soft'])) { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); + } + } else { + if (!isset($options['soft'])) { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); } } } } - } + // }}} + // {{{ set file permissions + if (!OS_WINDOWS) { + if ($atts['role'] == 'script') { + $mode = 0777 & ~(int)octdec($this->config->get('umask')); + $this->log(3, "+ chmod +x $dest_file"); + } else { + $mode = 0666 & ~(int)octdec($this->config->get('umask')); + } - $this->_detectDepCycle($deplinks); - foreach ($deplinks as $dependent => $parents) { - foreach ($parents as $parent => $unused) { - $nodes[$dependent]->connectTo($nodes[$parent]); + if ($atts['role'] != 'src') { + $this->addFileOperation("chmod", array($mode, $dest_file)); + if (!@chmod($dest_file, $mode)) { + if (!isset($options['soft'])) { + $this->log(0, "failed to change mode of $dest_file: $php_errormsg"); + } + } + } } - } + // }}} - $installOrder = Structures_Graph_Manipulator_TopologicalSorter::sort($depgraph); - $ret = array(); - for ($i = 0; $i < count($installOrder); $i++) { - foreach ($installOrder[$i] as $index => $sortedpackage) { - $data = &$installOrder[$i][$index]->getData(); - $ret[] = &$nodes[$reg->parsedPackageNameToString( - array( - 'channel' => $data->getChannel(), - 'package' => strtolower($data->getPackage()), - ))]->getData(); + if ($atts['role'] == 'src') { + rename($dest_file, $final_dest_file); + $this->log(2, "renamed source file $dest_file to $final_dest_file"); + } else { + $this->addFileOperation("rename", array($dest_file, $final_dest_file, + $atts['role'] == 'ext')); } } - $packages = $ret; - return; + // Store the full path where the file was installed for easy unistall + if ($atts['role'] != 'script') { + $loc = $this->config->get($atts['role'] . '_dir'); + } else { + $loc = $this->config->get('bin_dir'); + } + + if ($atts['role'] != 'src') { + $this->addFileOperation("installed_as", array($file, $installed_as, + $loc, + dirname(substr($installedas_dest_file, strlen($loc))))); + } + + //$this->log(2, "installed: $dest_file"); + return PEAR_INSTALLER_OK; } + // }}} + // {{{ _installFile2() + /** - * Detect recursive links between dependencies and break the cycles - * - * @param array + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param string filename + * @param array attributes from tag in package.xml + * @param string path to install the file in + * @param array options from command-line * @access private */ - function _detectDepCycle(&$deplinks) + function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options) { - do { - $keepgoing = false; - foreach ($deplinks as $dep => $parents) { - foreach ($parents as $parent => $unused) { - // reset the parent cycle detector - $this->_testCycle(null, null, null); - if ($this->_testCycle($dep, $deplinks, $parent)) { - $keepgoing = true; - unset($deplinks[$dep][$parent]); - if (count($deplinks[$dep]) == 0) { - unset($deplinks[$dep]); - } - continue 3; - } - } - } - } while ($keepgoing); - } + $atts = $real_atts; + if (!isset($this->_registry)) { + $this->_registry = &$this->config->getRegistry(); + } - function _testCycle($test, $deplinks, $dep) - { - static $visited = array(); - if ($test === null) { - $visited = array(); + $channel = $pkg->getChannel(); + // {{{ assemble the destination paths + if (!in_array($atts['attribs']['role'], + PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { + return $this->raiseError('Invalid role `' . $atts['attribs']['role'] . + "' for file $file"); + } + + $role = &PEAR_Installer_Role::factory($pkg, $atts['attribs']['role'], $this->config); + $err = $role->setup($this, $pkg, $atts['attribs'], $file); + if (PEAR::isError($err)) { + return $err; + } + + if (!$role->isInstallable()) { return; } - // this happens when a parent has a dep cycle on another dependency - // but the child is not part of the cycle - if (isset($visited[$dep])) { - return false; + + $info = $role->processInstallation($pkg, $atts['attribs'], $file, $tmp_path); + if (PEAR::isError($info)) { + return $info; } - $visited[$dep] = 1; - if ($test == $dep) { - return true; + + list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info; + if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { + return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); } - if (isset($deplinks[$dep])) { - if (in_array($test, array_keys($deplinks[$dep]), true)) { - return true; - } - foreach ($deplinks[$dep] as $parent => $unused) { - if ($this->_testCycle($test, $deplinks, $parent)) { - return true; + + $final_dest_file = $installed_as = $dest_file; + if (isset($this->_options['packagingroot'])) { + $final_dest_file = $this->_prependPath($final_dest_file, + $this->_options['packagingroot']); + } + + $dest_dir = dirname($final_dest_file); + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + // }}} + + if (empty($this->_options['register-only'])) { + if (!file_exists($dest_dir) || !is_dir($dest_dir)) { + if (!$this->mkDirHier($dest_dir)) { + return $this->raiseError("failed to mkdir $dest_dir", + PEAR_INSTALLER_FAILED); } + $this->log(3, "+ mkdir $dest_dir"); } } - return false; - } - /** - * Set up the dependency for installation parsing - * - * @param array $t dependency information - * @param PEAR_Registry $reg - * @param array $deplinks list of dependency links already established - * @param array $nodes all existing package nodes - * @param string $package parent package name - * @access private - */ - function _setupGraph($t, $reg, &$deplinks, &$nodes, $package) - { - foreach ($t as $dep) { - $depchannel = !isset($dep['channel']) ? '__uri': $dep['channel']; - $dname = $reg->parsedPackageNameToString( - array( - 'channel' => $depchannel, - 'package' => strtolower($dep['name']), - )); + $attribs = $atts['attribs']; + unset($atts['attribs']); + // pretty much nothing happens if we are only registering the install + if (empty($this->_options['register-only'])) { + if (!count($atts)) { // no tasks + if (!file_exists($orig_file)) { + return $this->raiseError("file $orig_file does not exist", + PEAR_INSTALLER_FAILED); + } + + if (!@copy($orig_file, $dest_file)) { + return $this->raiseError("failed to write $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + + $this->log(3, "+ cp $orig_file $dest_file"); + if (isset($attribs['md5sum'])) { + $md5sum = md5_file($dest_file); + } + } else { // file with tasks + if (!file_exists($orig_file)) { + return $this->raiseError("file $orig_file does not exist", + PEAR_INSTALLER_FAILED); + } + + $contents = file_get_contents($orig_file); + if ($contents === false) { + $contents = ''; + } + + if (isset($attribs['md5sum'])) { + $md5sum = md5($contents); + } + + foreach ($atts as $tag => $raw) { + $tag = str_replace(array($pkg->getTasksNs() . ':', '-'), array('', '_'), $tag); + $task = "PEAR_Task_$tag"; + $task = &new $task($this->config, $this, PEAR_TASK_INSTALL); + if (!$task->isScript()) { // scripts are only handled after installation + $task->init($raw, $attribs, $pkg->getLastInstalledVersion()); + $res = $task->startSession($pkg, $contents, $final_dest_file); + if ($res === false) { + continue; // skip this file + } + + if (PEAR::isError($res)) { + return $res; + } - if (isset($nodes[$dname])) { - if (!isset($deplinks[$dname])) { - $deplinks[$dname] = array(); + $contents = $res; // save changes + } + + $wp = @fopen($dest_file, "wb"); + if (!is_resource($wp)) { + return $this->raiseError("failed to create $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + + if (fwrite($wp, $contents) === false) { + return $this->raiseError("failed writing to $dest_file: $php_errormsg", + PEAR_INSTALLER_FAILED); + } + + fclose($wp); } - $deplinks[$dname][$package] = 1; } - } - } - function _dependsOn($a, $b) - { - return $this->_checkDepTree(strtolower($a->getChannel()), strtolower($a->getPackage()), $b); - } + // {{{ check the md5 + if (isset($md5sum)) { + // Make sure the original md5 sum matches with expected + if (strtolower($md5sum) === strtolower($attribs['md5sum'])) { + $this->log(2, "md5sum ok: $final_dest_file"); - function _checkDepTree($channel, $package, $b, $checked = array()) - { - $checked[$channel][$package] = true; - if (!isset($this->_depTree[$channel][$package])) { - return false; - } + if (isset($contents)) { + // set md5 sum based on $content in case any tasks were run. + $real_atts['attribs']['md5sum'] = md5($contents); + } + } else { + if (empty($options['force'])) { + // delete the file + if (file_exists($dest_file)) { + unlink($dest_file); + } - if (isset($this->_depTree[$channel][$package][strtolower($b->getChannel())] - [strtolower($b->getPackage())])) { - return true; - } + if (!isset($options['ignore-errors'])) { + return $this->raiseError("bad md5sum for file $final_dest_file", + PEAR_INSTALLER_FAILED); + } - foreach ($this->_depTree[$channel][$package] as $ch => $packages) { - foreach ($packages as $pa => $true) { - if ($this->_checkDepTree($ch, $pa, $b, $checked)) { - return true; + if (!isset($options['soft'])) { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); + } + } else { + if (!isset($options['soft'])) { + $this->log(0, "warning : bad md5sum for file $final_dest_file"); + } + } } + } else { + $real_atts['attribs']['md5sum'] = md5_file($dest_file); } - } - return false; - } + // }}} + // {{{ set file permissions + if (!OS_WINDOWS) { + if ($role->isExecutable()) { + $mode = 0777 & ~(int)octdec($this->config->get('umask')); + $this->log(3, "+ chmod +x $dest_file"); + } else { + $mode = 0666 & ~(int)octdec($this->config->get('umask')); + } - function _sortInstall($a, $b) - { - if (!$a->getDeps() && !$b->getDeps()) { - return 0; // neither package has dependencies, order is insignificant - } - if ($a->getDeps() && !$b->getDeps()) { - return 1; // $a must be installed after $b because $a has dependencies - } - if (!$a->getDeps() && $b->getDeps()) { - return -1; // $b must be installed after $a because $b has dependencies - } - // both packages have dependencies - if ($this->_dependsOn($a, $b)) { - return 1; + if ($attribs['role'] != 'src') { + $this->addFileOperation("chmod", array($mode, $dest_file)); + if (!@chmod($dest_file, $mode)) { + if (!isset($options['soft'])) { + $this->log(0, "failed to change mode of $dest_file: $php_errormsg"); + } + } + } + } + // }}} + + if ($attribs['role'] == 'src') { + rename($dest_file, $final_dest_file); + $this->log(2, "renamed source file $dest_file to $final_dest_file"); + } else { + $this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension())); + } } - if ($this->_dependsOn($b, $a)) { - return -1; + + // Store the full path where the file was installed for easy uninstall + if ($attribs['role'] != 'src') { + $loc = $this->config->get($role->getLocationConfig(), null, $channel); + $this->addFileOperation('installed_as', array($file, $installed_as, + $loc, + dirname(substr($installed_as, strlen($loc))))); } - return 0; + + //$this->log(2, "installed: $dest_file"); + return PEAR_INSTALLER_OK; } + // }}} + // {{{ addFileOperation() + /** - * Download a file through HTTP. Considers suggested file name in - * Content-disposition: header and can run a callback function for - * different events. The callback will be called with two - * parameters: the callback type, and parameters. The implemented - * callback types are: - * - * 'setup' called at the very beginning, parameter is a UI object - * that should be used for all output - * 'message' the parameter is a string with an informational message - * 'saveas' may be used to save with a different file name, the - * parameter is the filename that is about to be used. - * If a 'saveas' callback returns a non-empty string, - * that file name will be used as the filename instead. - * Note that $save_dir will not be affected by this, only - * the basename of the file. - * 'start' download is starting, parameter is number of bytes - * that are expected, or -1 if unknown - * 'bytesread' parameter is the number of bytes read so far - * 'done' download is complete, parameter is the total number - * of bytes read - * 'connfailed' if the TCP/SSL connection fails, this callback is called - * with array(host,port,errno,errmsg) - * 'writefailed' if writing to disk fails, this callback is called - * with array(destfile,errmsg) - * - * If an HTTP proxy has been configured (http_proxy PEAR_Config - * setting), the proxy will be used. + * Add a file operation to the current file transaction. * - * @param string $url the URL to download - * @param object $ui PEAR_Frontend_* instance - * @param object $config PEAR_Config instance - * @param string $save_dir directory to save file in - * @param mixed $callback function/method to call for status - * updates - * @param false|string|array $lastmodified header values to check against for caching - * use false to return the header values from this download - * @param false|array $accept Accept headers to send - * @param false|string $channel Channel to use for retrieving authentication - * @return string|array Returns the full path of the downloaded file or a PEAR - * error on failure. If the error is caused by - * socket-related errors, the error object will - * have the fsockopen error code available through - * getCode(). If caching is requested, then return the header - * values. + * @see startFileTransaction() + * @param string $type This can be one of: + * - rename: rename a file ($data has 3 values) + * - backup: backup an existing file ($data has 1 value) + * - removebackup: clean up backups created during install ($data has 1 value) + * - chmod: change permissions on a file ($data has 2 values) + * - delete: delete a file ($data has 1 value) + * - rmdir: delete a directory if empty ($data has 1 value) + * - installed_as: mark a file as installed ($data has 4 values). + * @param array $data For all file operations, this array must contain the + * full path to the file or directory that is being operated on. For + * the rename command, the first parameter must be the file to rename, + * the second its new name, the third whether this is a PHP extension. * - * @access public + * The installed_as operation contains 4 elements in this order: + * 1. Filename as listed in the filelist element from package.xml + * 2. Full path to the installed file + * 3. Full path from the php_dir configuration variable used in this + * installation + * 4. Relative path from the php_dir that this file is installed in */ - function downloadHttp($url, &$ui, $save_dir = '.', $callback = null, $lastmodified = null, - $accept = false, $channel = false) + function addFileOperation($type, $data) { - static $redirect = 0; - // always reset , so we are clean case of error - $wasredirect = $redirect; - $redirect = 0; - if ($callback) { - call_user_func($callback, 'setup', array(&$ui)); - } - - $info = parse_url($url); - if (!isset($info['scheme']) || !in_array($info['scheme'], array('http', 'https'))) { - return PEAR::raiseError('Cannot download non-http URL "' . $url . '"'); - } - - if (!isset($info['host'])) { - return PEAR::raiseError('Cannot download from non-URL "' . $url . '"'); + if (!is_array($data)) { + return $this->raiseError('Internal Error: $data in addFileOperation' + . ' must be an array, was ' . gettype($data)); } - $host = isset($info['host']) ? $info['host'] : null; - $port = isset($info['port']) ? $info['port'] : null; - $path = isset($info['path']) ? $info['path'] : null; - - if (isset($this)) { - $config = &$this->config; + if ($type == 'chmod') { + $octmode = decoct($data[0]); + $this->log(3, "adding to transaction: $type $octmode $data[1]"); } else { - $config = &PEAR_Config::singleton(); + $this->log(3, "adding to transaction: $type " . implode(" ", $data)); } + $this->file_operations[] = array($type, $data); + } - $proxy_host = $proxy_port = $proxy_user = $proxy_pass = ''; - if ($config->get('http_proxy') && - $proxy = parse_url($config->get('http_proxy'))) { - $proxy_host = isset($proxy['host']) ? $proxy['host'] : null; - if (isset($proxy['scheme']) && $proxy['scheme'] == 'https') { - $proxy_host = 'ssl://' . $proxy_host; - } - $proxy_port = isset($proxy['port']) ? $proxy['port'] : 8080; - $proxy_user = isset($proxy['user']) ? urldecode($proxy['user']) : null; - $proxy_pass = isset($proxy['pass']) ? urldecode($proxy['pass']) : null; - - if ($callback) { - call_user_func($callback, 'message', "Using HTTP proxy $host:$port"); - } - } + // }}} + // {{{ startFileTransaction() - if (empty($port)) { - $port = (isset($info['scheme']) && $info['scheme'] == 'https') ? 443 : 80; + function startFileTransaction($rollback_in_case = false) + { + if (count($this->file_operations) && $rollback_in_case) { + $this->rollbackFileTransaction(); } + $this->file_operations = array(); + } - $scheme = (isset($info['scheme']) && $info['scheme'] == 'https') ? 'https' : 'http'; + // }}} + // {{{ commitFileTransaction() - if ($proxy_host != '') { - $fp = @fsockopen($proxy_host, $proxy_port, $errno, $errstr); - if (!$fp) { - if ($callback) { - call_user_func($callback, 'connfailed', array($proxy_host, $proxy_port, - $errno, $errstr)); - } - return PEAR::raiseError("Connection to `$proxy_host:$proxy_port' failed: $errstr", $errno); - } + function commitFileTransaction() + { + $n = count($this->file_operations); + $this->log(2, "about to commit $n file operations"); + // {{{ first, check permissions and such manually + $errors = array(); + foreach ($this->file_operations as $tr) { + list($type, $data) = $tr; + switch ($type) { + case 'rename': + if (!file_exists($data[0])) { + $errors[] = "cannot rename file $data[0], doesn't exist"; + } - if ($lastmodified === false || $lastmodified) { - $request = "GET $url HTTP/1.1\r\n"; - $request .= "Host: $host:$port\r\n"; - } else { - $request = "GET $url HTTP/1.0\r\n"; - $request .= "Host: $host\r\n"; - } - } else { - $network_host = $host; - if (isset($info['scheme']) && $info['scheme'] == 'https') { - $network_host = 'ssl://' . $host; + // check that dest dir. is writable + if (!is_writable(dirname($data[1]))) { + $errors[] = "permission denied ($type): $data[1]"; + } + break; + case 'chmod': + // check that file is writable + if (!is_writable($data[1])) { + $errors[] = "permission denied ($type): $data[1] " . decoct($data[0]); + } + break; + case 'delete': + if (!file_exists($data[0])) { + $this->log(2, "warning: file $data[0] doesn't exist, can't be deleted"); + } + // check that directory is writable + if (file_exists($data[0])) { + if (!is_writable(dirname($data[0]))) { + $errors[] = "permission denied ($type): $data[0]"; + } else { + // make sure the file to be deleted can be opened for writing + $fp = false; + if (!is_dir($data[0]) && + (!is_writable($data[0]) || !($fp = @fopen($data[0], 'a')))) { + $errors[] = "permission denied ($type): $data[0]"; + } elseif ($fp) { + fclose($fp); + } + } + } + break; } - $fp = @fsockopen($network_host, $port, $errno, $errstr); - if (!$fp) { - if ($callback) { - call_user_func($callback, 'connfailed', array($host, $port, - $errno, $errstr)); + } + // }}} + $m = count($errors); + if ($m > 0) { + foreach ($errors as $error) { + if (!isset($this->_options['soft'])) { + $this->log(1, $error); } - return PEAR::raiseError("Connection to `$host:$port' failed: $errstr", $errno); } - if ($lastmodified === false || $lastmodified) { - $request = "GET $path HTTP/1.1\r\n"; - $request .= "Host: $host:$port\r\n"; - } else { - $request = "GET $path HTTP/1.0\r\n"; - $request .= "Host: $host\r\n"; + if (!isset($this->_options['ignore-errors'])) { + return false; } } - $ifmodifiedsince = ''; - if (is_array($lastmodified)) { - if (isset($lastmodified['Last-Modified'])) { - $ifmodifiedsince = 'If-Modified-Since: ' . $lastmodified['Last-Modified'] . "\r\n"; + $this->_dirtree = array(); + // {{{ really commit the transaction + foreach ($this->file_operations as $i => $tr) { + if (!$tr) { + // support removal of non-existing backups + continue; } - if (isset($lastmodified['ETag'])) { - $ifmodifiedsince .= "If-None-Match: $lastmodified[ETag]\r\n"; + list($type, $data) = $tr; + switch ($type) { + case 'backup': + if (!file_exists($data[0])) { + $this->file_operations[$i] = false; + break; + } + + if (!@copy($data[0], $data[0] . '.bak')) { + $this->log(1, 'Could not copy ' . $data[0] . ' to ' . $data[0] . + '.bak ' . $php_errormsg); + return false; + } + $this->log(3, "+ backup $data[0] to $data[0].bak"); + break; + case 'removebackup': + if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { + unlink($data[0] . '.bak'); + $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); + } + break; + case 'rename': + $test = file_exists($data[1]) ? @unlink($data[1]) : null; + if (!$test && file_exists($data[1])) { + if ($data[2]) { + $extra = ', this extension must be installed manually. Rename to "' . + basename($data[1]) . '"'; + } else { + $extra = ''; + } + + if (!isset($this->_options['soft'])) { + $this->log(1, 'Could not delete ' . $data[1] . ', cannot rename ' . + $data[0] . $extra); + } + + if (!isset($this->_options['ignore-errors'])) { + return false; + } + } + + // permissions issues with rename - copy() is far superior + $perms = @fileperms($data[0]); + if (!@copy($data[0], $data[1])) { + $this->log(1, 'Could not rename ' . $data[0] . ' to ' . $data[1] . + ' ' . $php_errormsg); + return false; + } + + // copy over permissions, otherwise they are lost + @chmod($data[1], $perms); + @unlink($data[0]); + $this->log(3, "+ mv $data[0] $data[1]"); + break; + case 'chmod': + if (!@chmod($data[1], $data[0])) { + $this->log(1, 'Could not chmod ' . $data[1] . ' to ' . + decoct($data[0]) . ' ' . $php_errormsg); + return false; + } + + $octmode = decoct($data[0]); + $this->log(3, "+ chmod $octmode $data[1]"); + break; + case 'delete': + if (file_exists($data[0])) { + if (!@unlink($data[0])) { + $this->log(1, 'Could not delete ' . $data[0] . ' ' . + $php_errormsg); + return false; + } + $this->log(3, "+ rm $data[0]"); + } + break; + case 'rmdir': + if (file_exists($data[0])) { + do { + $testme = opendir($data[0]); + while (false !== ($entry = readdir($testme))) { + if ($entry == '.' || $entry == '..') { + continue; + } + closedir($testme); + break 2; // this directory is not empty and can't be + // deleted + } + + closedir($testme); + if (!@rmdir($data[0])) { + $this->log(1, 'Could not rmdir ' . $data[0] . ' ' . + $php_errormsg); + return false; + } + $this->log(3, "+ rmdir $data[0]"); + } while (false); + } + break; + case 'installed_as': + $this->pkginfo->setInstalledAs($data[0], $data[1]); + if (!isset($this->_dirtree[dirname($data[1])])) { + $this->_dirtree[dirname($data[1])] = true; + $this->pkginfo->setDirtree(dirname($data[1])); + + while(!empty($data[3]) && dirname($data[3]) != $data[3] && + $data[3] != '/' && $data[3] != '\\') { + $this->pkginfo->setDirtree($pp = + $this->_prependPath($data[3], $data[2])); + $this->_dirtree[$pp] = true; + $data[3] = dirname($data[3]); + } + } + break; } - } else { - $ifmodifiedsince = ($lastmodified ? "If-Modified-Since: $lastmodified\r\n" : ''); } + // }}} + $this->log(2, "successfully committed $n file operations"); + $this->file_operations = array(); + return true; + } - $request .= $ifmodifiedsince . - "User-Agent: PEAR/1.8.0/PHP/" . PHP_VERSION . "\r\n"; + // }}} + // {{{ rollbackFileTransaction() - if (isset($this)) { // only pass in authentication for non-static calls - $username = $config->get('username', null, $channel); - $password = $config->get('password', null, $channel); - if ($username && $password) { - $tmp = base64_encode("$username:$password"); - $request .= "Authorization: Basic $tmp\r\n"; + function rollbackFileTransaction() + { + $n = count($this->file_operations); + $this->log(2, "rolling back $n file operations"); + foreach ($this->file_operations as $tr) { + list($type, $data) = $tr; + switch ($type) { + case 'backup': + if (file_exists($data[0] . '.bak')) { + if (file_exists($data[0] && is_writable($data[0]))) { + unlink($data[0]); + } + @copy($data[0] . '.bak', $data[0]); + $this->log(3, "+ restore $data[0] from $data[0].bak"); + } + break; + case 'removebackup': + if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { + unlink($data[0] . '.bak'); + $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); + } + break; + case 'rename': + @unlink($data[0]); + $this->log(3, "+ rm $data[0]"); + break; + case 'mkdir': + @rmdir($data[0]); + $this->log(3, "+ rmdir $data[0]"); + break; + case 'chmod': + break; + case 'delete': + break; + case 'installed_as': + $this->pkginfo->setInstalledAs($data[0], false); + break; } } + $this->pkginfo->resetDirtree(); + $this->file_operations = array(); + } - if ($proxy_host != '' && $proxy_user != '') { - $request .= 'Proxy-Authorization: Basic ' . - base64_encode($proxy_user . ':' . $proxy_pass) . "\r\n"; - } - - if ($accept) { - $request .= 'Accept: ' . implode(', ', $accept) . "\r\n"; - } - - $request .= "Connection: close\r\n"; - $request .= "\r\n"; - fwrite($fp, $request); - $headers = array(); - $reply = 0; - while (trim($line = fgets($fp, 1024))) { - if (preg_match('/^([^:]+):\s+(.*)\s*\\z/', $line, $matches)) { - $headers[strtolower($matches[1])] = trim($matches[2]); - } elseif (preg_match('|^HTTP/1.[01] ([0-9]{3}) |', $line, $matches)) { - $reply = (int)$matches[1]; - if ($reply == 304 && ($lastmodified || ($lastmodified === false))) { - return false; - } + // }}} + // {{{ mkDirHier($dir) - if (!in_array($reply, array(200, 301, 302, 303, 305, 307))) { - return PEAR::raiseError("File $scheme://$host:$port$path not valid (received: $line)"); - } - } - } + function mkDirHier($dir) + { + $this->addFileOperation('mkdir', array($dir)); + return parent::mkDirHier($dir); + } - if ($reply != 200) { - if (!isset($headers['location'])) { - return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirected but no location)"); - } + // }}} + // {{{ download() - if ($wasredirect > 4) { - return PEAR::raiseError("File $scheme://$host:$port$path not valid (redirection looped more than 5 times)"); - } + /** + * Download any files and their dependencies, if necessary + * + * @param array a mixed list of package names, local files, or package.xml + * @param PEAR_Config + * @param array options from the command line + * @param array this is the array that will be populated with packages to + * install. Format of each entry: + * + * + * array('pkg' => 'package_name', 'file' => '/path/to/local/file', + * 'info' => array() // parsed package.xml + * ); + * + * @param array this will be populated with any error messages + * @param false private recursion variable + * @param false private recursion variable + * @param false private recursion variable + * @deprecated in favor of PEAR_Downloader + */ + function download($packages, $options, &$config, &$installpackages, + &$errors, $installed = false, $willinstall = false, $state = false) + { + // trickiness: initialize here + parent::PEAR_Downloader($this->ui, $options, $config); + $ret = parent::download($packages); + $errors = $this->getErrorMsgs(); + $installpackages = $this->getDownloadedPackages(); + trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " . + "in favor of PEAR_Downloader class", E_USER_WARNING); + return $ret; + } - $redirect = $wasredirect + 1; - return $this->downloadHttp($headers['location'], - $ui, $save_dir, $callback, $lastmodified, $accept); - } + // }}} + // {{{ _parsePackageXml() - if (isset($headers['content-disposition']) && - preg_match('/\sfilename=\"([^;]*\S)\"\s*(;|\\z)/', $headers['content-disposition'], $matches)) { - $save_as = basename($matches[1]); + function _parsePackageXml(&$descfile, &$tmpdir) + { + if (substr($descfile, -4) == '.xml') { + $tmpdir = false; } else { - $save_as = basename($url); - } + // {{{ Decompress pack in tmp dir ------------------------------------- - if ($callback) { - $tmp = call_user_func($callback, 'saveas', $save_as); - if ($tmp) { - $save_as = $tmp; - } - } + // To allow relative package file names + $descfile = realpath($descfile); - $dest_file = $save_dir . DIRECTORY_SEPARATOR . $save_as; - if (!$wp = @fopen($dest_file, 'wb')) { - fclose($fp); - if ($callback) { - call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); + if (PEAR::isError($tmpdir = System::mktemp('-d'))) { + return $tmpdir; } - return PEAR::raiseError("could not open $dest_file for writing"); - } - - $length = isset($headers['content-length']) ? $headers['content-length'] : -1; - - $bytes = 0; - if ($callback) { - call_user_func($callback, 'start', array(basename($dest_file), $length)); + $this->log(3, '+ tmp dir created at ' . $tmpdir); + // }}} } - while ($data = fread($fp, 1024)) { - $bytes += strlen($data); - if ($callback) { - call_user_func($callback, 'bytesread', $bytes); - } - if (!@fwrite($wp, $data)) { - fclose($fp); - if ($callback) { - call_user_func($callback, 'writefailed', array($dest_file, $php_errormsg)); + // Parse xml file ----------------------------------------------- + $pkg = new PEAR_PackageFile($this->config, $this->debug, $tmpdir); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + $p = &$pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($p)) { + if (is_array($p->getUserInfo())) { + foreach ($p->getUserInfo() as $err) { + $loglevel = $err['level'] == 'error' ? 0 : 1; + if (!isset($this->_options['soft'])) { + $this->log($loglevel, ucfirst($err['level']) . ': ' . $err['message']); + } } - return PEAR::raiseError("$dest_file: write failed ($php_errormsg)"); } - } - fclose($fp); - fclose($wp); - if ($callback) { - call_user_func($callback, 'done', $bytes); + return $this->raiseError('Installation failed: invalid package file'); } - if ($lastmodified === false || $lastmodified) { - if (isset($headers['etag'])) { - $lastmodified = array('ETag' => $headers['etag']); - } - if (isset($headers['last-modified'])) { - if (is_array($lastmodified)) { - $lastmodified['Last-Modified'] = $headers['last-modified']; - } else { - $lastmodified = $headers['last-modified']; - } - } - return array($dest_file, $lastmodified, $headers); - } - return $dest_file; + $descfile = $p->getPackageFile(); + return $p; } -} -// }}} - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Package.php,v 1.126 2009/03/07 21:51:52 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * Error code when parameter initialization fails because no releases - * exist within preferred_state, but releases do exist - */ -define('PEAR_DOWNLOADER_PACKAGE_STATE', -1003); -/** - * Error code when parameter initialization fails because no releases - * exist that will work with the existing PHP version - */ -define('PEAR_DOWNLOADER_PACKAGE_PHPVERSION', -1004); -/** - * Coordinates download parameters and manages their dependencies - * prior to downloading them. - * - * Input can come from three sources: - * - * - local files (archives or package.xml) - * - remote files (downloadable urls) - * - abstract package names - * - * The first two elements are handled cleanly by PEAR_PackageFile, but the third requires - * accessing pearweb's xml-rpc interface to determine necessary dependencies, and the - * format returned of dependencies is slightly different from that used in package.xml. - * - * This class hides the differences between these elements, and makes automatic - * dependency resolution a piece of cake. It also manages conflicts when - * two classes depend on incompatible dependencies, or differing versions of the same - * package dependency. In addition, download will not be attempted if the php version is - * not supported, PEAR installer version is not supported, or non-PECL extensions are not - * installed. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Downloader_Package -{ - /** - * @var PEAR_Downloader - */ - var $_downloader; - /** - * @var PEAR_Config - */ - var $_config; - /** - * @var PEAR_Registry - */ - var $_registry; - /** - * Used to implement packagingroot properly - * @var PEAR_Registry - */ - var $_installRegistry; - /** - * @var PEAR_PackageFile_v1|PEAR_PackageFile|v2 - */ - var $_packagefile; - /** - * @var array - */ - var $_parsedname; - /** - * @var array - */ - var $_downloadURL; - /** - * @var array - */ - var $_downloadDeps = array(); - /** - * @var boolean - */ - var $_valid = false; - /** - * @var boolean - */ - var $_analyzed = false; - /** - * if this or a parent package was invoked with Package-state, this is set to the - * state variable. - * - * This allows temporary reassignment of preferred_state for a parent package and all of - * its dependencies. - * @var string|false - */ - var $_explicitState = false; - /** - * If this package is invoked with Package#group, this variable will be true - */ - var $_explicitGroup = false; - /** - * Package type local|url - * @var string - */ - var $_type; - /** - * Contents of package.xml, if downloaded from a remote channel - * @var string|false - * @access private - */ - var $_rawpackagefile; + // }}} /** - * @var boolean - * @access private + * Set the list of PEAR_Downloader_Package objects to allow more sane + * dependency validation + * @param array */ - var $_validated = false; + function setDownloadedPackages(&$pkgs) + { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $this->analyzeDependencies($pkgs); + PEAR::popErrorHandling(); + if (PEAR::isError($err)) { + return $err; + } + $this->_downloadedPackages = &$pkgs; + } /** - * @param PEAR_Downloader + * Set the list of PEAR_Downloader_Package objects to allow more sane + * dependency validation + * @param array */ - function PEAR_Downloader_Package(&$downloader) + function setUninstallPackages(&$pkgs) { - $this->_downloader = &$downloader; - $this->_config = &$this->_downloader->config; - $this->_registry = &$this->_config->getRegistry(); - $options = $downloader->getOptions(); - if (isset($options['packagingroot'])) { - $this->_config->setInstallRoot($options['packagingroot']); - $this->_installRegistry = &$this->_config->getRegistry(); - $this->_config->setInstallRoot(false); - } else { - $this->_installRegistry = &$this->_registry; - } - $this->_valid = $this->_analyzed = false; + $this->_downloadedPackages = &$pkgs; + } + + function getInstallPackages() + { + return $this->_downloadedPackages; } + // {{{ install() + /** - * Parse the input and determine whether this is a local file, a remote uri, or an - * abstract package name. + * Installs the files within the package file specified. * - * This is the heart of the PEAR_Downloader_Package(), and is used in - * {@link PEAR_Downloader::download()} - * @param string - * @return bool|PEAR_Error + * @param string|PEAR_Downloader_Package $pkgfile path to the package file, + * or a pre-initialized packagefile object + * @param array $options + * recognized options: + * - installroot : optional prefix directory for installation + * - force : force installation + * - register-only : update registry but don't install files + * - upgrade : upgrade existing install + * - soft : fail silently + * - nodeps : ignore dependency conflicts/missing dependencies + * - alldeps : install all dependencies + * - onlyreqdeps : install only required dependencies + * + * @return array|PEAR_Error package info if successful */ - function initialize($param) + function install($pkgfile, $options = array()) { - $origErr = $this->_fromFile($param); - if ($this->_valid) { - return true; + $this->_options = $options; + $this->_registry = &$this->config->getRegistry(); + if (is_object($pkgfile)) { + $dlpkg = &$pkgfile; + $pkg = $pkgfile->getPackageFile(); + $pkgfile = $pkg->getArchiveFile(); + $descfile = $pkg->getPackageFile(); + $tmpdir = dirname($descfile); + } else { + $descfile = $pkgfile; + $tmpdir = ''; + $pkg = $this->_parsePackageXml($descfile, $tmpdir); + if (PEAR::isError($pkg)) { + return $pkg; + } } - $options = $this->_downloader->getOptions(); - if (isset($options['offline'])) { - if (PEAR::isError($origErr) && !isset($options['soft'])) { - $this->_downloader->log(0, $origErr->getMessage()); + if (realpath($descfile) != realpath($pkgfile)) { + $tar = new Archive_Tar($pkgfile); + if (!$tar->extract($tmpdir)) { + return $this->raiseError("unable to unpack $pkgfile"); } + } - return PEAR::raiseError('Cannot download non-local package "' . $param . '"'); + $pkgname = $pkg->getName(); + $channel = $pkg->getChannel(); + if (isset($this->_options['packagingroot'])) { + $regdir = $this->_prependPath( + $this->config->get('php_dir', null, 'pear.php.net'), + $this->_options['packagingroot']); + + $packrootphp_dir = $this->_prependPath( + $this->config->get('php_dir', null, $channel), + $this->_options['packagingroot']); } - $err = $this->_fromUrl($param); - if (PEAR::isError($err) || !$this->_valid) { - if ($this->_type == 'url') { - if (PEAR::isError($err) && !isset($options['soft'])) { - $this->_downloader->log(0, $err->getMessage()); + if (isset($options['installroot'])) { + $this->config->setInstallRoot($options['installroot']); + $this->_registry = &$this->config->getRegistry(); + $installregistry = &$this->_registry; + $this->installroot = ''; // all done automagically now + $php_dir = $this->config->get('php_dir', null, $channel); + } else { + $this->config->setInstallRoot(false); + $this->_registry = &$this->config->getRegistry(); + if (isset($this->_options['packagingroot'])) { + $installregistry = &new PEAR_Registry($regdir); + if (!$installregistry->channelExists($channel, true)) { + // we need to fake a channel-discover of this channel + $chanobj = $this->_registry->getChannel($channel, true); + $installregistry->addChannel($chanobj); } + $php_dir = $packrootphp_dir; + } else { + $installregistry = &$this->_registry; + $php_dir = $this->config->get('php_dir', null, $channel); + } + $this->installroot = ''; + } - return PEAR::raiseError("Invalid or missing remote package file"); + // {{{ checks to do when not in "force" mode + if (empty($options['force']) && + (file_exists($this->config->get('php_dir')) && + is_dir($this->config->get('php_dir')))) { + $testp = $channel == 'pear.php.net' ? $pkgname : array($channel, $pkgname); + $instfilelist = $pkg->getInstallationFileList(true); + if (PEAR::isError($instfilelist)) { + return $instfilelist; } - $err = $this->_fromString($param); - if (PEAR::isError($err) || !$this->_valid) { - if (PEAR::isError($err) && $err->getCode() == PEAR_DOWNLOADER_PACKAGE_STATE) { - return false; // instruct the downloader to silently skip + // ensure we have the most accurate registry + $installregistry->flushFileMap(); + $test = $installregistry->checkFileMap($instfilelist, $testp, '1.1'); + if (PEAR::isError($test)) { + return $test; + } + + if (sizeof($test)) { + $pkgs = $this->getInstallPackages(); + $found = false; + foreach ($pkgs as $param) { + if ($pkg->isSubpackageOf($param)) { + $found = true; + break; + } } - if (isset($this->_type) && $this->_type == 'local' && PEAR::isError($origErr)) { - if (is_array($origErr->getUserInfo())) { - foreach ($origErr->getUserInfo() as $err) { - if (is_array($err)) { - $err = $err['message']; + if ($found) { + // subpackages can conflict with earlier versions of parent packages + $parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel()); + $tmp = $test; + foreach ($tmp as $file => $info) { + if (is_array($info)) { + if (strtolower($info[1]) == strtolower($param->getPackage()) && + strtolower($info[0]) == strtolower($param->getChannel()) + ) { + if (isset($parentreg['filelist'][$file])) { + unset($parentreg['filelist'][$file]); + } else{ + $pos = strpos($file, '/'); + $basedir = substr($file, 0, $pos); + $file2 = substr($file, $pos + 1); + if (isset($parentreg['filelist'][$file2]['baseinstalldir']) + && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir + ) { + unset($parentreg['filelist'][$file2]); + } + } + + unset($test[$file]); + } + } else { + if (strtolower($param->getChannel()) != 'pear.php.net') { + continue; } - if (!isset($options['soft'])) { - $this->_downloader->log(0, $err); + if (strtolower($info) == strtolower($param->getPackage())) { + if (isset($parentreg['filelist'][$file])) { + unset($parentreg['filelist'][$file]); + } else{ + $pos = strpos($file, '/'); + $basedir = substr($file, 0, $pos); + $file2 = substr($file, $pos + 1); + if (isset($parentreg['filelist'][$file2]['baseinstalldir']) + && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir + ) { + unset($parentreg['filelist'][$file2]); + } + } + + unset($test[$file]); + } + } + } + + $pfk = &new PEAR_PackageFile($this->config); + $parentpkg = &$pfk->fromArray($parentreg); + $installregistry->updatePackage2($parentpkg); + } + + if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) { + $tmp = $test; + foreach ($tmp as $file => $info) { + if (is_string($info)) { + // pear.php.net packages are always stored as strings + if (strtolower($info) == strtolower($param->getPackage())) { + // upgrading existing package + unset($test[$file]); } } } + } - if (!isset($options['soft'])) { - $this->_downloader->log(0, $origErr->getMessage()); + if (count($test)) { + $msg = "$channel/$pkgname: conflicting files found:\n"; + $longest = max(array_map("strlen", array_keys($test))); + $fmt = "%${longest}s (%s)\n"; + foreach ($test as $file => $info) { + if (!is_array($info)) { + $info = array('pear.php.net', $info); + } + $info = $info[0] . '/' . $info[1]; + $msg .= sprintf($fmt, $file, $info); } - if (is_array($param)) { - $param = $this->_registry->parsedPackageNameToString($param, true); + if (!isset($options['ignore-errors'])) { + return $this->raiseError($msg); } if (!isset($options['soft'])) { - $this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file"); + $this->log(0, "WARNING: $msg"); } - - // Passing no message back - already logged above - return PEAR::raiseError(); } + } + } + // }}} - if (PEAR::isError($err) && !isset($options['soft'])) { - $this->_downloader->log(0, $err->getMessage()); - } + $this->startFileTransaction(); - if (is_array($param)) { - $param = $this->_registry->parsedPackageNameToString($param, true); + if (empty($options['upgrade']) && empty($options['soft'])) { + // checks to do only when installing new packages + if ($channel == 'pecl.php.net') { + $test = $installregistry->packageExists($pkgname, $channel); + if (!$test) { + $test = $installregistry->packageExists($pkgname, 'pear.php.net'); } + } else { + $test = $installregistry->packageExists($pkgname, $channel); + } - if (!isset($options['soft'])) { - $this->_downloader->log(2, "Cannot initialize '$param', invalid or missing package file"); + if (empty($options['force']) && $test) { + return $this->raiseError("$channel/$pkgname is already installed"); + } + } else { + $usechannel = $channel; + if ($channel == 'pecl.php.net') { + $test = $installregistry->packageExists($pkgname, $channel); + if (!$test) { + $test = $installregistry->packageExists($pkgname, 'pear.php.net'); + $usechannel = 'pear.php.net'; } - - // Passing no message back - already logged above - return PEAR::raiseError(); + } else { + $test = $installregistry->packageExists($pkgname, $channel); } - } - return true; - } + if ($test) { + $v1 = $installregistry->packageInfo($pkgname, 'version', $usechannel); + $v2 = $pkg->getVersion(); + $cmp = version_compare("$v1", "$v2", 'gt'); + if (empty($options['force']) && !version_compare("$v2", "$v1", 'gt')) { + return $this->raiseError("upgrade to a newer version ($v2 is not newer than $v1)"); + } - /** - * Retrieve any non-local packages - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|PEAR_Error - */ - function &download() - { - if (isset($this->_packagefile)) { - return $this->_packagefile; - } + if (empty($options['register-only'])) { + // when upgrading, remove old release's files first: + if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel, + true))) { + if (!isset($options['ignore-errors'])) { + return $this->raiseError($err); + } - if (isset($this->_downloadURL['url'])) { - $this->_isvalid = false; - $info = $this->getParsedPackage(); - foreach ($info as $i => $p) { - $info[$i] = strtolower($p); + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: ' . $err->getMessage()); + } + } else { + $backedup = $err; + } + } } + } - $err = $this->_fromUrl($this->_downloadURL['url'], - $this->_registry->parsedPackageNameToString($this->_parsedname, true)); - $newinfo = $this->getParsedPackage(); - foreach ($newinfo as $i => $p) { - $newinfo[$i] = strtolower($p); - } + // {{{ Copy files to dest dir --------------------------------------- - if ($info != $newinfo) { - do { - if ($info['package'] == 'pecl.php.net' && $newinfo['package'] == 'pear.php.net') { - $info['package'] = 'pear.php.net'; - if ($info == $newinfo) { - // skip the channel check if a pecl package says it's a PEAR package - break; - } - } + // info from the package it self we want to access from _installFile + $this->pkginfo = &$pkg; + // used to determine whether we should build any C code + $this->source_files = 0; - return PEAR::raiseError('CRITICAL ERROR: We are ' . - $this->_registry->parsedPackageNameToString($info) . ', but the file ' . - 'downloaded claims to be ' . - $this->_registry->parsedPackageNameToString($this->getParsedPackage())); - } while (false); + $savechannel = $this->config->get('default_channel'); + if (empty($options['register-only']) && !is_dir($php_dir)) { + if (PEAR::isError(System::mkdir(array('-p'), $php_dir))) { + return $this->raiseError("no installation destination directory '$php_dir'\n"); } + } - if (PEAR::isError($err) || !$this->_valid) { - return $err; - } + $tmp_path = dirname($descfile); + if (substr($pkgfile, -4) != '.xml') { + $tmp_path .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion(); } - $this->_type = 'local'; - return $this->_packagefile; - } + $this->configSet('default_channel', $channel); + // {{{ install files - function &getPackageFile() - { - return $this->_packagefile; - } + $ver = $pkg->getPackagexmlVersion(); + if (version_compare($ver, '2.0', '>=')) { + $filelist = $pkg->getInstallationFilelist(); + } else { + $filelist = $pkg->getFileList(); + } - function &getDownloader() - { - return $this->_downloader; - } + if (PEAR::isError($filelist)) { + return $filelist; + } - function getType() - { - return $this->_type; - } + $p = &$installregistry->getPackage($pkgname, $channel); + $dirtree = (empty($options['register-only']) && $p) ? $p->getDirTree() : false; - /** - * Like {@link initialize()}, but operates on a dependency - */ - function fromDepURL($dep) - { - $this->_downloadURL = $dep; - if (isset($dep['uri'])) { - $options = $this->_downloader->getOptions(); - if (!extension_loaded("zlib") || isset($options['nocompress'])) { - $ext = '.tar'; + $pkg->resetFilelist(); + $pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(), + 'version', $pkg->getChannel())); + foreach ($filelist as $file => $atts) { + $this->expectError(PEAR_INSTALLER_FAILED); + if ($pkg->getPackagexmlVersion() == '1.0') { + $res = $this->_installFile($file, $atts, $tmp_path, $options); } else { - $ext = '.tgz'; + $res = $this->_installFile2($pkg, $file, $atts, $tmp_path, $options); } + $this->popExpect(); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $err = $this->_fromUrl($dep['uri'] . $ext); - PEAR::popErrorHandling(); - if (PEAR::isError($err)) { - if (!isset($options['soft'])) { - $this->_downloader->log(0, $err->getMessage()); + if (PEAR::isError($res)) { + if (empty($options['ignore-errors'])) { + $this->rollbackFileTransaction(); + if ($res->getMessage() == "file does not exist") { + $this->raiseError("file $file in package.xml does not exist"); + } + + return $this->raiseError($res); } - return PEAR::raiseError('Invalid uri dependency "' . $dep['uri'] . $ext . '", ' . - 'cannot download'); - } - } else { - $this->_parsedname = - array( - 'package' => $dep['info']->getPackage(), - 'channel' => $dep['info']->getChannel(), - 'version' => $dep['version'] - ); - if (!isset($dep['nodefault'])) { - $this->_parsedname['group'] = 'default'; // download the default dependency group - $this->_explicitGroup = false; + if (!isset($options['soft'])) { + $this->log(0, "Warning: " . $res->getMessage()); + } } - $this->_rawpackagefile = $dep['raw']; - } - } - - function detectDependencies($params) - { - $options = $this->_downloader->getOptions(); - if (isset($options['downloadonly'])) { - return; - } - - if (isset($options['offline'])) { - $this->_downloader->log(3, 'Skipping dependency download check, --offline specified'); - return; - } - - $pname = $this->getParsedPackage(); - if (!$pname) { - return; + $real = isset($atts['attribs']) ? $atts['attribs'] : $atts; + if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') { + // Register files that were installed + $pkg->installedFile($file, $atts); + } } + // }}} - $deps = $this->getDeps(); - if (!$deps) { - return; + // {{{ compile and install source files + if ($this->source_files > 0 && empty($options['nobuild'])) { + if (PEAR::isError($err = + $this->_compileSourceFiles($savechannel, $pkg))) { + return $err; + } } + // }}} - if (isset($deps['required'])) { // package.xml 2.0 - return $this->_detect2($deps, $pname, $options, $params); + if (isset($backedup)) { + $this->_removeBackups($backedup); } - return $this->_detect1($deps, $pname, $options, $params); - } - - function setValidated() - { - $this->_validated = true; - } - - function alreadyValidated() - { - return $this->_validated; - } - - /** - * Remove packages to be downloaded that are already installed - * @param array of PEAR_Downloader_Package objects - * @static - */ - function removeInstalled(&$params) - { - if (!isset($params[0])) { - return; + if (!$this->commitFileTransaction()) { + $this->rollbackFileTransaction(); + $this->configSet('default_channel', $savechannel); + return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED); } + // }}} - $options = $params[0]->_downloader->getOptions(); - if (!isset($options['downloadonly'])) { - foreach ($params as $i => $param) { - $package = $param->getPackage(); - $channel = $param->getChannel(); - // remove self if already installed with this version - // this does not need any pecl magic - we only remove exact matches - if ($param->_installRegistry->packageExists($package, $channel)) { - $packageVersion = $param->_installRegistry->packageInfo($package, 'version', $channel); - if (version_compare($packageVersion, $param->getVersion(), '==')) { - if (!isset($options['force'])) { - $info = $param->getParsedPackage(); - unset($info['version']); - unset($info['state']); - if (!isset($options['soft'])) { - $param->_downloader->log(1, 'Skipping package "' . - $param->getShortName() . - '", already installed as version ' . $packageVersion); - } - $params[$i] = false; - } - } elseif (!isset($options['force']) && !isset($options['upgrade']) && - !isset($options['soft'])) { - $info = $param->getParsedPackage(); - $param->_downloader->log(1, 'Skipping package "' . - $param->getShortName() . - '", already installed as version ' . $packageVersion); - $params[$i] = false; - } + $ret = false; + $installphase = 'install'; + $oldversion = false; + // {{{ Register that the package is installed ----------------------- + if (empty($options['upgrade'])) { + // if 'force' is used, replace the info in registry + $usechannel = $channel; + if ($channel == 'pecl.php.net') { + $test = $installregistry->packageExists($pkgname, $channel); + if (!$test) { + $test = $installregistry->packageExists($pkgname, 'pear.php.net'); + $usechannel = 'pear.php.net'; } + } else { + $test = $installregistry->packageExists($pkgname, $channel); } - } - PEAR_Downloader_Package::removeDuplicates($params); - } + if (!empty($options['force']) && $test) { + $oldversion = $installregistry->packageInfo($pkgname, 'version', $usechannel); + $installregistry->deletePackage($pkgname, $usechannel); + } + $ret = $installregistry->addPackage2($pkg); + } else { + if ($dirtree) { + $this->startFileTransaction(); + // attempt to delete empty directories + uksort($dirtree, array($this, '_sortDirs')); + foreach($dirtree as $dir => $notused) { + $this->addFileOperation('rmdir', array($dir)); + } + $this->commitFileTransaction(); + } - function _detect2($deps, $pname, $options, $params) - { - $this->_downloadDeps = array(); - $groupnotfound = false; - foreach (array('package', 'subpackage') as $packagetype) { - // get required dependency group - if (isset($deps['required'][$packagetype])) { - if (isset($deps['required'][$packagetype][0])) { - foreach ($deps['required'][$packagetype] as $dep) { - if (isset($dep['conflicts'])) { - // skip any package that this package conflicts with - continue; - } - $ret = $this->_detect2Dep($dep, $pname, 'required', $params); - if (is_array($ret)) { - $this->_downloadDeps[] = $ret; - } elseif (PEAR::isError($ret) && !isset($options['soft'])) { - $this->_downloader->log(0, $ret->getMessage()); - } - } - } else { - $dep = $deps['required'][$packagetype]; - if (!isset($dep['conflicts'])) { - // skip any package that this package conflicts with - $ret = $this->_detect2Dep($dep, $pname, 'required', $params); - if (is_array($ret)) { - $this->_downloadDeps[] = $ret; - } elseif (PEAR::isError($ret) && !isset($options['soft'])) { - $this->_downloader->log(0, $ret->getMessage()); - } - } + $usechannel = $channel; + if ($channel == 'pecl.php.net') { + $test = $installregistry->packageExists($pkgname, $channel); + if (!$test) { + $test = $installregistry->packageExists($pkgname, 'pear.php.net'); + $usechannel = 'pear.php.net'; } + } else { + $test = $installregistry->packageExists($pkgname, $channel); } - // get optional dependency group, if any - if (isset($deps['optional'][$packagetype])) { - $skipnames = array(); - if (!isset($deps['optional'][$packagetype][0])) { - $deps['optional'][$packagetype] = array($deps['optional'][$packagetype]); + // new: upgrade installs a package if it isn't installed + if (!$test) { + $ret = $installregistry->addPackage2($pkg); + } else { + if ($usechannel != $channel) { + $installregistry->deletePackage($pkgname, $usechannel); + $ret = $installregistry->addPackage2($pkg); + } else { + $ret = $installregistry->updatePackage2($pkg); } + $installphase = 'upgrade'; + } + } - foreach ($deps['optional'][$packagetype] as $dep) { - $skip = false; - if (!isset($options['alldeps'])) { - $dep['package'] = $dep['name']; - if (!isset($options['soft'])) { - $this->_downloader->log(3, 'Notice: package "' . - $this->_registry->parsedPackageNameToString($this->getParsedPackage(), - true) . '" optional dependency "' . - $this->_registry->parsedPackageNameToString(array('package' => - $dep['name'], 'channel' => 'pear.php.net'), true) . - '" will not be automatically downloaded'); - } - $skipnames[] = $this->_registry->parsedPackageNameToString($dep, true); - $skip = true; - unset($dep['package']); - } + if (!$ret) { + $this->configSet('default_channel', $savechannel); + return $this->raiseError("Adding package $channel/$pkgname to registry failed"); + } + // }}} - $ret = $this->_detect2Dep($dep, $pname, 'optional', $params); - if (PEAR::isError($ret) && !isset($options['soft'])) { - $this->_downloader->log(0, $ret->getMessage()); - } + $this->configSet('default_channel', $savechannel); + if (class_exists('PEAR_Task_Common')) { // this is auto-included if any tasks exist + if (PEAR_Task_Common::hasPostinstallTasks()) { + PEAR_Task_Common::runPostinstallTasks($installphase); + } + } - if (!$ret) { - $dep['package'] = $dep['name']; - $skip = count($skipnames) ? - $skipnames[count($skipnames) - 1] : ''; - if ($skip == - $this->_registry->parsedPackageNameToString($dep, true)) { - array_pop($skipnames); - } - } + return $pkg->toArray(true); + } - if (!$skip && is_array($ret)) { - $this->_downloadDeps[] = $ret; - } - } + // }}} - if (count($skipnames)) { - if (!isset($options['soft'])) { - $this->_downloader->log(1, 'Did not download optional dependencies: ' . - implode(', ', $skipnames) . - ', use --alldeps to download automatically'); - } - } - } + // {{{ _compileSourceFiles() + /** + * @param string + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + */ + function _compileSourceFiles($savechannel, &$filelist) + { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Builder.php'; + $this->log(1, "$this->source_files source files, building"); + $bob = &new PEAR_Builder($this->ui); + $bob->debug = $this->debug; + $built = $bob->build($filelist, array(&$this, '_buildCallback')); + if (PEAR::isError($built)) { + $this->rollbackFileTransaction(); + $this->configSet('default_channel', $savechannel); + return $built; + } - // get requested dependency group, if any - $groupname = $this->getGroup(); - $explicit = $this->_explicitGroup; - if (!$groupname) { - if (!$this->canDefault()) { - continue; + $this->log(1, "\nBuild process completed successfully"); + foreach ($built as $ext) { + $bn = basename($ext['file']); + list($_ext_name, $_ext_suff) = explode('.', $bn); + if ($_ext_suff == '.so' || $_ext_suff == '.dll') { + if (extension_loaded($_ext_name)) { + $this->raiseError("Extension '$_ext_name' already loaded. " . + 'Please unload it in your php.ini file ' . + 'prior to install or upgrade'); } - - $groupname = 'default'; // try the default dependency group - } - - if ($groupnotfound) { - continue; + $role = 'ext'; + } else { + $role = 'src'; } - if (isset($deps['group'])) { - if (isset($deps['group']['attribs'])) { - if (strtolower($deps['group']['attribs']['name']) == strtolower($groupname)) { - $group = $deps['group']; - } elseif ($explicit) { - if (!isset($options['soft'])) { - $this->_downloader->log(0, 'Warning: package "' . - $this->_registry->parsedPackageNameToString($pname, true) . - '" has no dependency ' . 'group named "' . $groupname . '"'); - } - - $groupnotfound = true; - continue; - } - } else { - $found = false; - foreach ($deps['group'] as $group) { - if (strtolower($group['attribs']['name']) == strtolower($groupname)) { - $found = true; - break; - } - } + $dest = $ext['dest']; + $packagingroot = ''; + if (isset($this->_options['packagingroot'])) { + $packagingroot = $this->_options['packagingroot']; + } - if (!$found) { - if ($explicit) { - if (!isset($options['soft'])) { - $this->_downloader->log(0, 'Warning: package "' . - $this->_registry->parsedPackageNameToString($pname, true) . - '" has no dependency ' . 'group named "' . $groupname . '"'); - } - } + $copyto = $this->_prependPath($dest, $packagingroot); + $extra = $copyto != $dest ? " as '$copyto'" : ''; + $this->log(1, "Installing '$dest'$extra"); - $groupnotfound = true; - continue; + $copydir = dirname($copyto); + // pretty much nothing happens if we are only registering the install + if (empty($this->_options['register-only'])) { + if (!file_exists($copydir) || !is_dir($copydir)) { + if (!$this->mkDirHier($copydir)) { + return $this->raiseError("failed to mkdir $copydir", + PEAR_INSTALLER_FAILED); } + + $this->log(3, "+ mkdir $copydir"); } - } - if (isset($group) && isset($group[$packagetype])) { - if (isset($group[$packagetype][0])) { - foreach ($group[$packagetype] as $dep) { - $ret = $this->_detect2Dep($dep, $pname, 'dependency group "' . - $group['attribs']['name'] . '"', $params); - if (is_array($ret)) { - $this->_downloadDeps[] = $ret; - } elseif (PEAR::isError($ret) && !isset($options['soft'])) { - $this->_downloader->log(0, $ret->getMessage()); - } - } - } else { - $ret = $this->_detect2Dep($group[$packagetype], $pname, - 'dependency group "' . - $group['attribs']['name'] . '"', $params); - if (is_array($ret)) { - $this->_downloadDeps[] = $ret; - } elseif (PEAR::isError($ret) && !isset($options['soft'])) { - $this->_downloader->log(0, $ret->getMessage()); + if (!@copy($ext['file'], $copyto)) { + return $this->raiseError("failed to write $copyto ($php_errormsg)", PEAR_INSTALLER_FAILED); + } + + $this->log(3, "+ cp $ext[file] $copyto"); + $this->addFileOperation('rename', array($ext['file'], $copyto)); + if (!OS_WINDOWS) { + $mode = 0666 & ~(int)octdec($this->config->get('umask')); + $this->addFileOperation('chmod', array($mode, $copyto)); + if (!@chmod($copyto, $mode)) { + $this->log(0, "failed to change mode of $copyto ($php_errormsg)"); } } } + + + $data = array( + 'role' => $role, + 'name' => $bn, + 'installed_as' => $dest, + 'php_api' => $ext['php_api'], + 'zend_mod_api' => $ext['zend_mod_api'], + 'zend_ext_api' => $ext['zend_ext_api'], + ); + + if ($filelist->getPackageXmlVersion() == '1.0') { + $filelist->installedFile($bn, $data); + } else { + $filelist->installedFile($bn, array('attribs' => $data)); + } } } - function _detect2Dep($dep, $pname, $group, $params) + // }}} + function &getUninstallPackages() { - if (isset($dep['conflicts'])) { - return true; - } + return $this->_downloadedPackages; + } + // {{{ uninstall() - $options = $this->_downloader->getOptions(); - if (isset($dep['uri'])) { - return array('uri' => $dep['uri'], 'dep' => $dep);; - } + /** + * Uninstall a package + * + * This method removes all files installed by the application, and then + * removes any empty directories. + * @param string package name + * @param array Command-line options. Possibilities include: + * + * - installroot: base installation dir, if not the default + * - register-only : update registry but don't remove files + * - nodeps: do not process dependencies of other packages to ensure + * uninstallation does not break things + */ + function uninstall($package, $options = array()) + { + $installRoot = isset($options['installroot']) ? $options['installroot'] : ''; + $this->config->setInstallRoot($installRoot); - $testdep = $dep; - $testdep['package'] = $dep['name']; - if (PEAR_Downloader_Package::willDownload($testdep, $params)) { - $dep['package'] = $dep['name']; - if (!isset($options['soft'])) { - $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group . - ' dependency "' . - $this->_registry->parsedPackageNameToString($dep, true) . - '", will be installed'); - } - return false; + $this->installroot = ''; + $this->_registry = &$this->config->getRegistry(); + if (is_object($package)) { + $channel = $package->getChannel(); + $pkg = $package; + $package = $pkg->getPackage(); + } else { + $pkg = false; + $info = $this->_registry->parsePackageName($package, + $this->config->get('default_channel')); + $channel = $info['channel']; + $package = $info['package']; } - $options = $this->_downloader->getOptions(); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - if ($this->_explicitState) { - $pname['state'] = $this->_explicitState; + $savechannel = $this->config->get('default_channel'); + $this->configSet('default_channel', $channel); + if (!is_object($pkg)) { + $pkg = $this->_registry->getPackage($package, $channel); } - $url = $this->_downloader->_getDepPackageDownloadUrl($dep, $pname); - if (PEAR::isError($url)) { - PEAR::popErrorHandling(); - return $url; + if (!$pkg) { + $this->configSet('default_channel', $savechannel); + return $this->raiseError($this->_registry->parsedPackageNameToString( + array( + 'channel' => $channel, + 'package' => $package + ), true) . ' not installed'); } - $dep['package'] = $dep['name']; - $ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params, $group == 'optional' && - !isset($options['alldeps']), true); - PEAR::popErrorHandling(); - if (PEAR::isError($ret)) { - if (!isset($options['soft'])) { - $this->_downloader->log(0, $ret->getMessage()); - } - - return false; + if ($pkg->getInstalledBinary()) { + // this is just an alias for a binary package + return $this->_registry->deletePackage($package, $channel); } - // check to see if a dep is already installed and is the same or newer - if (!isset($dep['min']) && !isset($dep['max']) && !isset($dep['recommended'])) { - $oper = 'has'; - } else { - $oper = 'gt'; + $filelist = $pkg->getFilelist(); + PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); + if (!class_exists('PEAR_Dependency2')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; } - // do not try to move this before getDepPackageDownloadURL - // we can't determine whether upgrade is necessary until we know what - // version would be downloaded - if (!isset($options['force']) && $this->isInstalled($ret, $oper)) { - $version = $this->_installRegistry->packageInfo($dep['name'], 'version', - $dep['channel']); - $dep['package'] = $dep['name']; - if (!isset($options['soft'])) { - $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group . - ' dependency "' . - $this->_registry->parsedPackageNameToString($dep, true) . - '" version ' . $url['version'] . ', already installed as version ' . - $version); + $depchecker = &new PEAR_Dependency2($this->config, $options, + array('channel' => $channel, 'package' => $package), + PEAR_VALIDATE_UNINSTALLING); + $e = $depchecker->validatePackageUninstall($this); + PEAR::staticPopErrorHandling(); + if (PEAR::isError($e)) { + if (!isset($options['ignore-errors'])) { + return $this->raiseError($e); } - return false; - } - - if (isset($dep['nodefault'])) { - $ret['nodefault'] = true; + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: ' . $e->getMessage()); + } + } elseif (is_array($e)) { + if (!isset($options['soft'])) { + $this->log(0, $e[0]); + } } - return $ret; - } - - function _detect1($deps, $pname, $options, $params) - { - $this->_downloadDeps = array(); - $skipnames = array(); - foreach ($deps as $dep) { - $nodownload = false; - if (isset ($dep['type']) && $dep['type'] === 'pkg') { - $dep['channel'] = 'pear.php.net'; - $dep['package'] = $dep['name']; - switch ($dep['rel']) { - case 'not' : - continue 2; - case 'ge' : - case 'eq' : - case 'gt' : - case 'has' : - $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ? - 'required' : - 'optional'; - if (PEAR_Downloader_Package::willDownload($dep, $params)) { - $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group - . ' dependency "' . - $this->_registry->parsedPackageNameToString($dep, true) . - '", will be installed'); - continue 2; - } - $fakedp = new PEAR_PackageFile_v1; - $fakedp->setPackage($dep['name']); - // skip internet check if we are not upgrading (bug #5810) - if (!isset($options['upgrade']) && $this->isInstalled( - $fakedp, $dep['rel'])) { - $this->_downloader->log(2, $this->getShortName() . ': Skipping ' . $group - . ' dependency "' . - $this->_registry->parsedPackageNameToString($dep, true) . - '", is already installed'); - continue 2; - } - } - - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - if ($this->_explicitState) { - $pname['state'] = $this->_explicitState; + $this->pkginfo = &$pkg; + // pretty much nothing happens if we are only registering the uninstall + if (empty($options['register-only'])) { + // {{{ Delete the files + $this->startFileTransaction(); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + if (PEAR::isError($err = $this->_deletePackageFiles($package, $channel))) { + PEAR::popErrorHandling(); + $this->rollbackFileTransaction(); + $this->configSet('default_channel', $savechannel); + if (!isset($options['ignore-errors'])) { + return $this->raiseError($err); } - $url = $this->_downloader->_getDepPackageDownloadUrl($dep, $pname); - $chan = 'pear.php.net'; - if (PEAR::isError($url)) { - // check to see if this is a pecl package that has jumped - // from pear.php.net to pecl.php.net channel - if (!class_exists('PEAR_Dependency2')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; - } - - $newdep = PEAR_Dependency2::normalizeDep($dep); - $newdep = $newdep[0]; - $newdep['channel'] = 'pecl.php.net'; - $chan = 'pecl.php.net'; - $url = - $this->_downloader->_getDepPackageDownloadUrl($newdep, $pname); - $obj = &$this->_installRegistry->getPackage($dep['name']); - if (PEAR::isError($url)) { - PEAR::popErrorHandling(); - if ($obj !== null && $this->isInstalled($obj, $dep['rel'])) { - $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ? - 'required' : - 'optional'; - $dep['package'] = $dep['name']; - if (!isset($options['soft'])) { - $this->_downloader->log(3, $this->getShortName() . - ': Skipping ' . $group . ' dependency "' . - $this->_registry->parsedPackageNameToString($dep, true) . - '", already installed as version ' . $obj->getVersion()); - } - $skip = count($skipnames) ? - $skipnames[count($skipnames) - 1] : ''; - if ($skip == - $this->_registry->parsedPackageNameToString($dep, true)) { - array_pop($skipnames); - } - continue; - } else { - if (isset($dep['optional']) && $dep['optional'] == 'yes') { - $this->_downloader->log(2, $this->getShortName() . - ': Skipping optional dependency "' . - $this->_registry->parsedPackageNameToString($dep, true) . - '", no releases exist'); - continue; - } else { - return $url; - } - } - } + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: ' . $err->getMessage()); } - + } else { PEAR::popErrorHandling(); - if (!isset($options['alldeps'])) { - if (isset($dep['optional']) && $dep['optional'] == 'yes') { - if (!isset($options['soft'])) { - $this->_downloader->log(3, 'Notice: package "' . - $this->getShortName() . - '" optional dependency "' . - $this->_registry->parsedPackageNameToString( - array('channel' => $chan, 'package' => - $dep['name']), true) . - '" will not be automatically downloaded'); - } - $skipnames[] = $this->_registry->parsedPackageNameToString( - array('channel' => $chan, 'package' => - $dep['name']), true); - $nodownload = true; - } - } + } - if (!isset($options['alldeps']) && !isset($options['onlyreqdeps'])) { - if (!isset($dep['optional']) || $dep['optional'] == 'no') { - if (!isset($options['soft'])) { - $this->_downloader->log(3, 'Notice: package "' . - $this->getShortName() . - '" required dependency "' . - $this->_registry->parsedPackageNameToString( - array('channel' => $chan, 'package' => - $dep['name']), true) . - '" will not be automatically downloaded'); - } - $skipnames[] = $this->_registry->parsedPackageNameToString( - array('channel' => $chan, 'package' => - $dep['name']), true); - $nodownload = true; - } + if (!$this->commitFileTransaction()) { + $this->rollbackFileTransaction(); + if (!isset($options['ignore-errors'])) { + return $this->raiseError("uninstall failed"); } - // check to see if a dep is already installed - // do not try to move this before getDepPackageDownloadURL - // we can't determine whether upgrade is necessary until we know what - // version would be downloaded - if (!isset($options['force']) && $this->isInstalled( - $url, $dep['rel'])) { - $group = (!isset($dep['optional']) || $dep['optional'] == 'no') ? - 'required' : - 'optional'; - $dep['package'] = $dep['name']; - if (isset($newdep)) { - $version = $this->_installRegistry->packageInfo($newdep['name'], 'version', - $newdep['channel']); - } else { - $version = $this->_installRegistry->packageInfo($dep['name'], 'version'); - } - - $dep['version'] = $url['version']; - if (!isset($options['soft'])) { - $this->_downloader->log(3, $this->getShortName() . ': Skipping ' . $group . - ' dependency "' . - $this->_registry->parsedPackageNameToString($dep, true) . - '", already installed as version ' . $version); - } - - $skip = count($skipnames) ? - $skipnames[count($skipnames) - 1] : ''; - if ($skip == - $this->_registry->parsedPackageNameToString($dep, true)) { - array_pop($skipnames); - } - - continue; + if (!isset($options['soft'])) { + $this->log(0, 'WARNING: uninstall failed'); } - - if ($nodownload) { - continue; + } else { + $this->startFileTransaction(); + $dirtree = $pkg->getDirTree(); + if ($dirtree === false) { + $this->configSet('default_channel', $savechannel); + return $this->_registry->deletePackage($package, $channel); } - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - if (isset($newdep)) { - $dep = $newdep; + // attempt to delete empty directories + uksort($dirtree, array($this, '_sortDirs')); + foreach($dirtree as $dir => $notused) { + $this->addFileOperation('rmdir', array($dir)); } - $dep['package'] = $dep['name']; - $ret = $this->_analyzeDownloadURL($url, 'dependency', $dep, $params, - isset($dep['optional']) && $dep['optional'] == 'yes' && - !isset($options['alldeps']), true); - PEAR::popErrorHandling(); - if (PEAR::isError($ret)) { + if (!$this->commitFileTransaction()) { + $this->rollbackFileTransaction(); + if (!isset($options['ignore-errors'])) { + return $this->raiseError("uninstall failed"); + } + if (!isset($options['soft'])) { - $this->_downloader->log(0, $ret->getMessage()); + $this->log(0, 'WARNING: uninstall failed'); } - continue; } - - $this->_downloadDeps[] = $ret; - } - } - - if (count($skipnames)) { - if (!isset($options['soft'])) { - $this->_downloader->log(1, 'Did not download dependencies: ' . - implode(', ', $skipnames) . - ', use --alldeps or --onlyreqdeps to download automatically'); } + // }}} } - } - function setDownloadURL($pkg) - { - $this->_downloadURL = $pkg; + $this->configSet('default_channel', $savechannel); + // Register that the package is no longer installed + return $this->_registry->deletePackage($package, $channel); } /** - * Set the package.xml object for this downloaded package + * Sort a list of arrays of array(downloaded packagefilename) by dependency. * - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 $pkg + * It also removes duplicate dependencies + * @param array an array of PEAR_PackageFile_v[1/2] objects + * @return array|PEAR_Error array of array(packagefilename, package.xml contents) */ - function setPackageFile(&$pkg) - { - $this->_packagefile = &$pkg; - } - - function getShortName() + function sortPackagesForUninstall(&$packages) { - return $this->_registry->parsedPackageNameToString(array('channel' => $this->getChannel(), - 'package' => $this->getPackage()), true); + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->config); + if (PEAR::isError($this->_dependencyDB)) { + return $this->_dependencyDB; + } + usort($packages, array(&$this, '_sortUninstall')); } - function getParsedPackage() + function _sortUninstall($a, $b) { - if (isset($this->_packagefile) || isset($this->_parsedname)) { - return array('channel' => $this->getChannel(), - 'package' => $this->getPackage(), - 'version' => $this->getVersion()); + if (!$a->getDeps() && !$b->getDeps()) { + return 0; // neither package has dependencies, order is insignificant } - - return false; + if ($a->getDeps() && !$b->getDeps()) { + return -1; // $a must be installed after $b because $a has dependencies + } + if (!$a->getDeps() && $b->getDeps()) { + return 1; // $b must be installed after $a because $b has dependencies + } + // both packages have dependencies + if ($this->_dependencyDB->dependsOn($a, $b)) { + return -1; + } + if ($this->_dependencyDB->dependsOn($b, $a)) { + return 1; + } + return 0; } - function getDownloadURL() + // }}} + // {{{ _sortDirs() + function _sortDirs($a, $b) { - return $this->_downloadURL; + if (strnatcmp($a, $b) == -1) return 1; + if (strnatcmp($a, $b) == 1) return -1; + return 0; } - function canDefault() + // }}} + + // {{{ _buildCallback() + + function _buildCallback($what, $data) { - if (isset($this->_downloadURL) && isset($this->_downloadURL['nodefault'])) { - return false; + if (($what == 'cmdoutput' && $this->debug > 1) || + ($what == 'output' && $this->debug > 0)) { + $this->ui->outputData(rtrim($data), 'build'); } - - return true; } - function getPackage() + // }}} +} + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Role.php 278552 2009-04-10 19:42:49Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * base class for installer roles + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role/Common.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role +{ + /** + * Set up any additional configuration variables that file roles require + * + * Never call this directly, it is called by the PEAR_Config constructor + * @param PEAR_Config + * @access private + * @static + */ + function initializeConfig(&$config) { - if (isset($this->_packagefile)) { - return $this->_packagefile->getPackage(); - } elseif (isset($this->_downloadURL['info'])) { - return $this->_downloadURL['info']->getPackage(); + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); } - return false; + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) { + if (!$info['config_vars']) { + continue; + } + + $config->_addConfigVars($class, $info['config_vars']); + } } /** - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param PEAR_PackageFile_v2 + * @param string role name + * @param PEAR_Config + * @return PEAR_Installer_Role_Common + * @static */ - function isSubpackage(&$pf) + function &factory($pkg, $role, &$config) { - if (isset($this->_packagefile)) { - return $this->_packagefile->isSubpackage($pf); - } elseif (isset($this->_downloadURL['info'])) { - return $this->_downloadURL['info']->isSubpackage($pf); + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); } - return false; - } + if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { + $a = false; + return $a; + } - function getPackageType() - { - if (isset($this->_packagefile)) { - return $this->_packagefile->getPackageType(); - } elseif (isset($this->_downloadURL['info'])) { - return $this->_downloadURL['info']->getPackageType(); + $a = 'PEAR_Installer_Role_' . ucfirst($role); + if (!class_exists($a)) { + require_once 'phar://install-pear-nozlib.phar/' . str_replace('_', '/', $a) . '.php'; } - return false; + $b = new $a($config); + return $b; } - function isBundle() + /** + * Get a list of file roles that are valid for the particular release type. + * + * For instance, src files serve no purpose in regular php releases. + * @param string + * @param bool clear cache + * @return array + * @static + */ + function getValidRoles($release, $clear = false) { - if (isset($this->_packagefile)) { - return $this->_packagefile->getPackageType() == 'bundle'; + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); } - return false; - } - - function getPackageXmlVersion() - { - if (isset($this->_packagefile)) { - return $this->_packagefile->getPackagexmlVersion(); - } elseif (isset($this->_downloadURL['info'])) { - return $this->_downloadURL['info']->getPackagexmlVersion(); + static $ret = array(); + if ($clear) { + $ret = array(); } - return '1.0'; - } + if (isset($ret[$release])) { + return $ret[$release]; + } - function getChannel() - { - if (isset($this->_packagefile)) { - return $this->_packagefile->getChannel(); - } elseif (isset($this->_downloadURL['info'])) { - return $this->_downloadURL['info']->getChannel(); + $ret[$release] = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if (in_array($release, $okreleases['releasetypes'])) { + $ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } } - return false; + return $ret[$release]; } - function getURI() + /** + * Get a list of roles that require their files to be installed + * + * Most roles must be installed, but src and package roles, for instance + * are pseudo-roles. src files are compiled into a new extension. Package + * roles are actually fully bundled releases of a package + * @param bool clear cache + * @return array + * @static + */ + function getInstallableRoles($clear = false) { - if (isset($this->_packagefile)) { - return $this->_packagefile->getURI(); - } elseif (isset($this->_downloadURL['info'])) { - return $this->_downloadURL['info']->getURI(); + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); } - return false; - } - - function getVersion() - { - if (isset($this->_packagefile)) { - return $this->_packagefile->getVersion(); - } elseif (isset($this->_downloadURL['version'])) { - return $this->_downloadURL['version']; + static $ret; + if ($clear) { + unset($ret); } - return false; - } + if (isset($ret)) { + return $ret; + } - function isCompatible($pf) - { - if (isset($this->_packagefile)) { - return $this->_packagefile->isCompatible($pf); - } elseif (isset($this->_downloadURL['info'])) { - return $this->_downloadURL['info']->isCompatible($pf); + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['installable']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } } - return true; + return $ret; } - function setGroup($group) + /** + * Return an array of roles that are affected by the baseinstalldir attribute + * + * Most roles ignore this attribute, and instead install directly into: + * PackageName/filepath + * so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php + * @param bool clear cache + * @return array + * @static + */ + function getBaseinstallRoles($clear = false) { - $this->_parsedname['group'] = $group; - } + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } - function getGroup() - { - if (isset($this->_parsedname['group'])) { - return $this->_parsedname['group']; + static $ret; + if ($clear) { + unset($ret); } - return ''; - } + if (isset($ret)) { + return $ret; + } - function isExtension($name) - { - if (isset($this->_packagefile)) { - return $this->_packagefile->isExtension($name); - } elseif (isset($this->_downloadURL['info'])) { - if ($this->_downloadURL['info']->getPackagexmlVersion() == '2.0') { - return $this->_downloadURL['info']->getProvidesExtension() == $name; + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['honorsbaseinstall']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); } - - return false; } - return false; + return $ret; } - function getDeps() + /** + * Return an array of file roles that should be analyzed for PHP content at package time, + * like the "php" role. + * @param bool clear cache + * @return array + * @static + */ + function getPhpRoles($clear = false) { - if (isset($this->_packagefile)) { - $ver = $this->_packagefile->getPackagexmlVersion(); - if (version_compare($ver, '2.0', '>=')) { - return $this->_packagefile->getDeps(true); - } + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { + PEAR_Installer_Role::registerRoles(); + } - return $this->_packagefile->getDeps(); - } elseif (isset($this->_downloadURL['info'])) { - $ver = $this->_downloadURL['info']->getPackagexmlVersion(); - if (version_compare($ver, '2.0', '>=')) { - return $this->_downloadURL['info']->getDeps(true); - } + static $ret; + if ($clear) { + unset($ret); + } - return $this->_downloadURL['info']->getDeps(); + if (isset($ret)) { + return $ret; } - return array(); + $ret = array(); + foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { + if ($okreleases['phpfile']) { + $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); + } + } + + return $ret; } /** - * @param array Parsed array from {@link PEAR_Registry::parsePackageName()} or a dependency - * returned from getDepDownloadURL() + * Scan through the Command directory looking for classes + * and see what commands they implement. + * @param string which directory to look for classes, defaults to + * the Installer/Roles subdirectory of + * the directory from where this file (__FILE__) is + * included. + * + * @return bool TRUE on success, a PEAR error on failure + * @access public + * @static */ - function isEqual($param) + function registerRoles($dir = null) { - if (is_object($param)) { - $channel = $param->getChannel(); - $package = $param->getPackage(); - if ($param->getURI()) { - $param = array( - 'channel' => $param->getChannel(), - 'package' => $param->getPackage(), - 'version' => $param->getVersion(), - 'uri' => $param->getURI(), - ); - } else { - $param = array( - 'channel' => $param->getChannel(), - 'package' => $param->getPackage(), - 'version' => $param->getVersion(), - ); - } - } else { - if (isset($param['uri'])) { - if ($this->getChannel() != '__uri') { - return false; - } - return $param['uri'] == $this->getURI(); + $GLOBALS['_PEAR_INSTALLER_ROLES'] = array(); + $parser = new PEAR_XMLParser; + if ($dir === null) { + $dir = dirname(__FILE__) . '/Role'; + } + + if (!file_exists($dir) || !is_dir($dir)) { + return PEAR::raiseError("registerRoles: opendir($dir) failed: does not exist/is not directory"); + } + + $dp = @opendir($dir); + if (empty($dp)) { + return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg"); + } + + while ($entry = readdir($dp)) { + if ($entry{0} == '.' || substr($entry, -4) != '.xml') { + continue; } - $package = isset($param['package']) ? $param['package'] : $param['info']->getPackage(); - $channel = isset($param['channel']) ? $param['channel'] : $param['info']->getChannel(); - if (isset($param['rel'])) { - if (!class_exists('PEAR_Dependency2')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; + $class = "PEAR_Installer_Role_".substr($entry, 0, -4); + // List of roles + if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) { + $file = "$dir/$entry"; + $parser->parse(file_get_contents($file)); + $data = $parser->getData(); + if (!is_array($data['releasetypes'])) { + $data['releasetypes'] = array($data['releasetypes']); } - $newdep = PEAR_Dependency2::normalizeDep($param); - $newdep = $newdep[0]; - } elseif (isset($param['min'])) { - $newdep = $param; + $GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data; } } - if (isset($newdep)) { - if (!isset($newdep['min'])) { - $newdep['min'] = '0'; - } + closedir($dp); + ksort($GLOBALS['_PEAR_INSTALLER_ROLES']); + PEAR_Installer_Role::getBaseinstallRoles(true); + PEAR_Installer_Role::getInstallableRoles(true); + PEAR_Installer_Role::getPhpRoles(true); + PEAR_Installer_Role::getValidRoles('****', true); + return true; + } +} + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Common.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * Base class for all installation roles. + * + * This class allows extensibility of file roles. Packages with complex + * customization can now provide custom file roles along with the possibility of + * adding configuration values to match. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2006 The PHP Group + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Common +{ + /** + * @var PEAR_Config + * @access protected + */ + var $config; - if (!isset($newdep['max'])) { - $newdep['max'] = '100000000000000000000'; - } + /** + * @param PEAR_Config + */ + function PEAR_Installer_Role_Common(&$config) + { + $this->config = $config; + } - // use magic to support pecl packages suddenly jumping to the pecl channel - // we need to support both dependency possibilities - if ($channel == 'pear.php.net' && $this->getChannel() == 'pecl.php.net') { - if ($package == $this->getPackage()) { - $channel = 'pecl.php.net'; - } - } - if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') { - if ($package == $this->getPackage()) { - $channel = 'pear.php.net'; - } - } - return (strtolower($package) == strtolower($this->getPackage()) && - $channel == $this->getChannel() && - version_compare($newdep['min'], $this->getVersion(), '<=') && - version_compare($newdep['max'], $this->getVersion(), '>=')); + /** + * Retrieve configuration information about a file role from its XML info + * + * @param string $role Role Classname, as in "PEAR_Installer_Role_Data" + * @return array + */ + function getInfo($role) + { + if (empty($GLOBALS['_PEAR_INSTALLER_ROLES'][$role])) { + return PEAR::raiseError('Unknown Role class: "' . $role . '"'); } + return $GLOBALS['_PEAR_INSTALLER_ROLES'][$role]; + } - // use magic to support pecl packages suddenly jumping to the pecl channel - if ($channel == 'pecl.php.net' && $this->getChannel() == 'pear.php.net') { - if (strtolower($package) == strtolower($this->getPackage())) { - $channel = 'pear.php.net'; + /** + * This is called for each file to set up the directories and files + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param array attributes from the tag + * @param string file name + * @return array an array consisting of: + * + * 1 the original, pre-baseinstalldir installation directory + * 2 the final installation directory + * 3 the full path to the final location of the file + * 4 the location of the pre-installation file + */ + function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null) + { + $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . + ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); + if (PEAR::isError($roleInfo)) { + return $roleInfo; + } + if (!$roleInfo['locationconfig']) { + return false; + } + if ($roleInfo['honorsbaseinstall']) { + $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], $layer, + $pkg->getChannel()); + if (!empty($atts['baseinstalldir'])) { + $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; + } + } elseif ($roleInfo['unusualbaseinstall']) { + $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], + $layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage(); + if (!empty($atts['baseinstalldir'])) { + $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; } + } else { + $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], + $layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage(); } - - if (isset($param['version'])) { - return (strtolower($package) == strtolower($this->getPackage()) && - $channel == $this->getChannel() && - $param['version'] == $this->getVersion()); + if (dirname($file) != '.' && empty($atts['install-as'])) { + $dest_dir .= DIRECTORY_SEPARATOR . dirname($file); + } + if (empty($atts['install-as'])) { + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); + } else { + $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as']; } + $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file; - return strtolower($package) == strtolower($this->getPackage()) && - $channel == $this->getChannel(); + // Clean up the DIRECTORY_SEPARATOR mess + $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; + + list($dest_dir, $dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), + array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, + DIRECTORY_SEPARATOR), + array($dest_dir, $dest_file, $orig_file)); + return array($save_destdir, $dest_dir, $dest_file, $orig_file); } - function isInstalled($dep, $oper = '==') + /** + * Get the name of the configuration variable that specifies the location of this file + * @return string|false + */ + function getLocationConfig() { - if (!$dep) { - return false; + $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . + ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); + if (PEAR::isError($roleInfo)) { + return $roleInfo; } + return $roleInfo['locationconfig']; + } - if ($oper != 'ge' && $oper != 'gt' && $oper != 'has' && $oper != '==') { - return false; + /** + * Do any unusual setup here + * @param PEAR_Installer + * @param PEAR_PackageFile_v2 + * @param array file attributes + * @param string file name + */ + function setup(&$installer, $pkg, $atts, $file) + { + } + + function isExecutable() + { + $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . + ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); + if (PEAR::isError($roleInfo)) { + return $roleInfo; } + return $roleInfo['executable']; + } - if (is_object($dep)) { - $package = $dep->getPackage(); - $channel = $dep->getChannel(); - if ($dep->getURI()) { - $dep = array( - 'uri' => $dep->getURI(), - 'version' => $dep->getVersion(), - ); - } else { - $dep = array( - 'version' => $dep->getVersion(), - ); - } - } else { - if (isset($dep['uri'])) { - $channel = '__uri'; - $package = $dep['dep']['name']; - } else { - $channel = $dep['info']->getChannel(); - $package = $dep['info']->getPackage(); - } + function isInstallable() + { + $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . + ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); + if (PEAR::isError($roleInfo)) { + return $roleInfo; } + return $roleInfo['installable']; + } - $options = $this->_downloader->getOptions(); - $test = $this->_installRegistry->packageExists($package, $channel); - if (!$test && $channel == 'pecl.php.net') { - // do magic to allow upgrading from old pecl packages to new ones - $test = $this->_installRegistry->packageExists($package, 'pear.php.net'); - $channel = 'pear.php.net'; + function isExtension() + { + $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . + ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); + if (PEAR::isError($roleInfo)) { + return $roleInfo; } + return $roleInfo['phpextension']; + } +} +?> + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Data.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ - if ($test) { - if (isset($dep['uri'])) { - if ($this->_installRegistry->packageInfo($package, 'uri', '__uri') == $dep['uri']) { - return true; - } - } +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {} +?> + php + extsrc + extbin + zendextsrc + zendextbin + 1 + data_dir + + + + + + + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Doc.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ + +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {} +?> + php + extsrc + extbin + zendextsrc + zendextbin + 1 + doc_dir + + + + + + + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Php.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ - if (isset($options['upgrade'])) { - $packageVersion = $this->_installRegistry->packageInfo($package, 'version', $channel); - if (version_compare($packageVersion, $dep['version'], '>=')) { - return true; - } +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {} +?> + php + extsrc + extbin + zendextsrc + zendextbin + 1 + php_dir + 1 + + 1 + + + + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Script.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ - return false; - } +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {} +?> + php + extsrc + extbin + zendextsrc + zendextbin + 1 + bin_dir + 1 + + + 1 + + + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: Test.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ - return true; - } +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {} +?> + php + extsrc + extbin + zendextsrc + zendextbin + 1 + test_dir + + + + + + + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: PackageFile.php 286670 2009-08-02 14:16:06Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ - return false; - } +/** + * needed for PEAR_VALIDATE_* constants + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validate.php'; +/** + * Error code if the package.xml tag does not contain a valid version + */ +define('PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION', 1); +/** + * Error code if the package.xml tag version is not supported (version 1.0 and 1.1 are the only supported versions, + * currently + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2); +/** + * Abstraction for the package.xml package description file + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile +{ + /** + * @var PEAR_Config + */ + var $_config; + var $_debug; + /** + * Temp directory for uncompressing tgz files. + * @var string|false + */ + var $_tmpdir; + var $_logger = false; + /** + * @var boolean + */ + var $_rawReturn = false; /** - * Detect duplicate package names with differing versions - * - * If a user requests to install Date 1.4.6 and Date 1.4.7, - * for instance, this is a logic error. This method - * detects this situation. * - * @param array $params array of PEAR_Downloader_Package objects - * @param array $errorparams empty array - * @return array array of stupid duplicated packages in PEAR_Downloader_Package obejcts + * @param PEAR_Config $config + * @param ? $debug + * @param string @tmpdir Optional temporary directory for uncompressing + * files */ - function detectStupidDuplicates($params, &$errorparams) + function PEAR_PackageFile(&$config, $debug = false, $tmpdir = false) { - $existing = array(); - foreach ($params as $i => $param) { - $package = $param->getPackage(); - $channel = $param->getChannel(); - $group = $param->getGroup(); - if (!isset($existing[$channel . '/' . $package])) { - $existing[$channel . '/' . $package] = array(); - } - - if (!isset($existing[$channel . '/' . $package][$group])) { - $existing[$channel . '/' . $package][$group] = array(); - } - - $existing[$channel . '/' . $package][$group][] = $i; - } - - $indices = array(); - foreach ($existing as $package => $groups) { - foreach ($groups as $group => $dupes) { - if (count($dupes) > 1) { - $indices = $indices + $dupes; - } - } - } - - $indices = array_unique($indices); - foreach ($indices as $index) { - $errorparams[] = $params[$index]; - } - - return count($errorparams); + $this->_config = $config; + $this->_debug = $debug; + $this->_tmpdir = $tmpdir; } /** - * @param array - * @param bool ignore install groups - for final removal of dupe packages - * @static + * Turn off validation - return a parsed package.xml without checking it + * + * This is used by the package-validate command */ - function removeDuplicates(&$params, $ignoreGroups = false) - { - $pnames = array(); - foreach ($params as $i => $param) { - if (!$param) { - continue; - } - if ($param->getPackage()) { - if ($ignoreGroups) { - $group = ''; - } else { - $group = $param->getGroup(); - } - - $pnames[$i] = $param->getChannel() . '/' . - $param->getPackage() . '-' . $param->getVersion() . '#' . $group; - } - } - - $pnames = array_unique($pnames); - $unset = array_diff(array_keys($params), array_keys($pnames)); - $testp = array_flip($pnames); - foreach ($params as $i => $param) { - if (!$param) { - $unset[] = $i; - continue; - } - - if (!is_a($param, 'PEAR_Downloader_Package')) { - $unset[] = $i; - continue; - } - - $group = $ignoreGroups ? '' : $param->getGroup(); - if (!isset($testp[$param->getChannel() . '/' . $param->getPackage() . '-' . - $param->getVersion() . '#' . $group])) { - $unset[] = $i; - } - } - - foreach ($unset as $i) { - unset($params[$i]); - } - - $ret = array(); - foreach ($params as $i => $param) { - $ret[] = &$params[$i]; - } - - $params = array(); - foreach ($ret as $i => $param) { - $params[] = &$ret[$i]; - } - } - - function explicitState() + function rawReturn() { - return $this->_explicitState; + $this->_rawReturn = true; } - function setExplicitState($s) + function setLogger(&$l) { - $this->_explicitState = $s; + $this->_logger = &$l; } /** - * @static + * Create a PEAR_PackageFile_Parser_v* of a given version. + * @param int $version + * @return PEAR_PackageFile_Parser_v1|PEAR_PackageFile_Parser_v1 */ - function mergeDependencies(&$params) + function &parserFactory($version) { - $bundles = $newparams = array(); - foreach ($params as $i => $param) { - if (!$param->isBundle()) { - continue; - } - - $bundles[] = $i; - $pf = &$param->getPackageFile(); - $newdeps = array(); - $contents = $pf->getBundledPackages(); - if (!is_array($contents)) { - $contents = array($contents); - } - - foreach ($contents as $file) { - $filecontents = $pf->getFileContents($file); - $dl = &$param->getDownloader(); - $options = $dl->getOptions(); - if (PEAR::isError($dir = $dl->getDownloadDir())) { - return $dir; - } - - $fp = @fopen($dir . DIRECTORY_SEPARATOR . $file, 'wb'); - if (!$fp) { - continue; - } - - fwrite($fp, $filecontents, strlen($filecontents)); - fclose($fp); - if ($s = $params[$i]->explicitState()) { - $obj->setExplicitState($s); - } - - $obj = &new PEAR_Downloader_Package($params[$i]->getDownloader()); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - if (PEAR::isError($dir = $dl->getDownloadDir())) { - PEAR::popErrorHandling(); - return $dir; - } - - $e = $obj->_fromFile($a = $dir . DIRECTORY_SEPARATOR . $file); - PEAR::popErrorHandling(); - if (PEAR::isError($e)) { - if (!isset($options['soft'])) { - $dl->log(0, $e->getMessage()); - } - continue; - } - - $j = &$obj; - if (!PEAR_Downloader_Package::willDownload($j, - array_merge($params, $newparams)) && !$param->isInstalled($j)) { - $newparams[] = &$j; - } - } - } - - foreach ($bundles as $i) { - unset($params[$i]); // remove bundles - only their contents matter for installation - } - - PEAR_Downloader_Package::removeDuplicates($params); // strip any unset indices - if (count($newparams)) { // add in bundled packages for install - foreach ($newparams as $i => $unused) { - $params[] = &$newparams[$i]; - } - $newparams = array(); - } - - foreach ($params as $i => $param) { - $newdeps = array(); - foreach ($param->_downloadDeps as $dep) { - $merge = array_merge($params, $newparams); - if (!PEAR_Downloader_Package::willDownload($dep, $merge) - && !$param->isInstalled($dep) - ) { - $newdeps[] = $dep; - } else { - //var_dump($dep); - // detect versioning conflicts here - } - } - - // convert the dependencies into PEAR_Downloader_Package objects for the next time around - $params[$i]->_downloadDeps = array(); - foreach ($newdeps as $dep) { - $obj = &new PEAR_Downloader_Package($params[$i]->getDownloader()); - if ($s = $params[$i]->explicitState()) { - $obj->setExplicitState($s); - } - - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $e = $obj->fromDepURL($dep); - PEAR::popErrorHandling(); - if (PEAR::isError($e)) { - if (!isset($options['soft'])) { - $obj->_downloader->log(0, $e->getMessage()); - } - continue; - } - - $e = $obj->detectDependencies($params); - if (PEAR::isError($e)) { - if (!isset($options['soft'])) { - $obj->_downloader->log(0, $e->getMessage()); - } - } - - $j = &$obj; - $newparams[] = &$j; - } - } - - if (count($newparams)) { - foreach ($newparams as $i => $unused) { - $params[] = &$newparams[$i]; - } - return true; + if (!in_array($version{0}, array('1', '2'))) { + $a = false; + return $a; } - return false; + include_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/Parser/v' . $version{0} . '.php'; + $version = $version{0}; + $class = "PEAR_PackageFile_Parser_v$version"; + $a = new $class; + return $a; } - /** - * @static + * For simpler unit-testing + * @return string */ - function willDownload($param, $params) + function getClassPrefix() { - if (!is_array($params)) { - return false; - } - - foreach ($params as $obj) { - if ($obj->isEqual($param)) { - return true; - } - } - - return false; + return 'PEAR_PackageFile_v'; } /** - * For simpler unit-testing - * @param PEAR_Config - * @param int - * @param string + * Create a PEAR_PackageFile_v* of a given version. + * @param int $version + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v1 */ - function &getPackagefileObject(&$c, $d, $t = false) + function &factory($version) { - $a = &new PEAR_PackageFile($c, $d, $t); + if (!in_array($version{0}, array('1', '2'))) { + $a = false; + return $a; + } + + include_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v' . $version{0} . '.php'; + $version = $version{0}; + $class = $this->getClassPrefix() . $version; + $a = new $class; return $a; } - /** - * This will retrieve from a local file if possible, and parse out - * a group name as well. The original parameter will be modified to reflect this. - * @param string|array can be a parsed package name as well - * @access private + * Create a PEAR_PackageFile_v* from its toArray() method + * + * WARNING: no validation is performed, the array is assumed to be valid, + * always parse from xml if you want validation. + * @param array $arr + * @return PEAR_PackageFileManager_v1|PEAR_PackageFileManager_v2 + * @uses factory() to construct the returned object. */ - function _fromFile(&$param) + function &fromArray($arr) { - $saveparam = $param; - if (is_string($param)) { - if (!@file_exists($param)) { - $test = explode('#', $param); - $group = array_pop($test); - if (@file_exists(implode('#', $test))) { - $this->setGroup($group); - $param = implode('#', $test); - $this->_explicitGroup = true; - } + if (isset($arr['xsdversion'])) { + $obj = &$this->factory($arr['xsdversion']); + if ($this->_logger) { + $obj->setLogger($this->_logger); } - if (@is_file($param)) { - $this->_type = 'local'; - $options = $this->_downloader->getOptions(); - if (isset($options['downloadonly'])) { - $pkg = &$this->getPackagefileObject($this->_config, - $this->_downloader->_debug); - } else { - if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) { - return $dir; - } - $pkg = &$this->getPackagefileObject($this->_config, - $this->_downloader->_debug, $dir); - } - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $pf = &$pkg->fromAnyFile($param, PEAR_VALIDATE_INSTALLING); - PEAR::popErrorHandling(); - if (PEAR::isError($pf)) { - $this->_valid = false; - $param = $saveparam; - return $pf; - } - $this->_packagefile = &$pf; - if (!$this->getGroup()) { - $this->setGroup('default'); // install the default dependency group - } - return $this->_valid = true; - } + $obj->setConfig($this->_config); + $obj->fromArray($arr); + return $obj; + } + + if (isset($arr['package']['attribs']['version'])) { + $obj = &$this->factory($arr['package']['attribs']['version']); + } else { + $obj = &$this->factory('1.0'); + } + + if ($this->_logger) { + $obj->setLogger($this->_logger); } - $param = $saveparam; - return $this->_valid = false; + + $obj->setConfig($this->_config); + $obj->fromArray($arr); + return $obj; } - function _fromUrl($param, $saveparam = '') + /** + * Create a PEAR_PackageFile_v* from an XML string. + * @access public + * @param string $data contents of package.xml file + * @param int $state package state (one of PEAR_VALIDATE_* constants) + * @param string $file full path to the package.xml file (and the files + * it references) + * @param string $archive optional name of the archive that the XML was + * extracted from, if any + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @uses parserFactory() to construct a parser to load the package. + */ + function &fromXmlString($data, $state, $file, $archive = false) { - if (!is_array($param) && (preg_match('#^(http|https|ftp)://#', $param))) { - $options = $this->_downloader->getOptions(); - $this->_type = 'url'; - $callback = $this->_downloader->ui ? - array(&$this->_downloader, '_downloadCallback') : null; - $this->_downloader->pushErrorHandling(PEAR_ERROR_RETURN); - if (PEAR::isError($dir = $this->_downloader->getDownloadDir())) { - $this->_downloader->popErrorHandling(); - return $dir; + if (preg_match('/]+version="([0-9]+\.[0-9]+)"/', $data, $packageversion)) { + if (!in_array($packageversion[1], array('1.0', '2.0', '2.1'))) { + return PEAR::raiseError('package.xml version "' . $packageversion[1] . + '" is not supported, only 1.0, 2.0, and 2.1 are supported.'); } - $this->_downloader->log(3, 'Downloading "' . $param . '"'); - $file = $this->_downloader->downloadHttp($param, $this->_downloader->ui, - $dir, $callback, null, false, $this->getChannel()); - $this->_downloader->popErrorHandling(); - if (PEAR::isError($file)) { - if (!empty($saveparam)) { - $saveparam = ", cannot download \"$saveparam\""; - } - $err = PEAR::raiseError('Could not download from "' . $param . - '"' . $saveparam . ' (' . $file->getMessage() . ')'); - return $err; + $object = &$this->parserFactory($packageversion[1]); + if ($this->_logger) { + $object->setLogger($this->_logger); } - if ($this->_rawpackagefile) { - require_once 'phar://install-pear-nozlib.phar/' . 'Archive/Tar.php'; - $tar = &new Archive_Tar($file); - $packagexml = $tar->extractInString('package2.xml'); - if (!$packagexml) { - $packagexml = $tar->extractInString('package.xml'); - } + $object->setConfig($this->_config); + $pf = $object->parse($data, $file, $archive); + if (PEAR::isError($pf)) { + return $pf; + } - if (str_replace(array("\n", "\r"), array('',''), $packagexml) != - str_replace(array("\n", "\r"), array('',''), $this->_rawpackagefile)) { - if ($this->getChannel() != 'pear.php.net') { - return PEAR::raiseError('CRITICAL ERROR: package.xml downloaded does ' . - 'not match value returned from xml-rpc'); - } + if ($this->_rawReturn) { + return $pf; + } - // be more lax for the existing PEAR packages that have not-ok - // characters in their package.xml - $this->_downloader->log(0, 'CRITICAL WARNING: The "' . - $this->getPackage() . '" package has invalid characters in its ' . - 'package.xml. The next version of PEAR may not be able to install ' . - 'this package for security reasons. Please open a bug report at ' . - 'http://pear.php.net/package/' . $this->getPackage() . '/bugs'); + if (!$pf->validate($state)) {; + if ($this->_config->get('verbose') > 0 + && $this->_logger && $pf->getValidationWarnings(false) + ) { + foreach ($pf->getValidationWarnings(false) as $warning) { + $this->_logger->log(0, 'ERROR: ' . $warning['message']); + } } + + $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', + 2, null, null, $pf->getValidationWarnings()); + return $a; } - // whew, download worked! - if (isset($options['downloadonly'])) { - $pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug); - } else { - $dir = $this->_downloader->getDownloadDir(); - if (PEAR::isError($dir)) { - return $dir; + if ($this->_logger && $pf->getValidationWarnings(false)) { + foreach ($pf->getValidationWarnings() as $warning) { + $this->_logger->log(0, 'WARNING: ' . $warning['message']); } - $pkg = &$this->getPackagefileObject($this->_config, $this->_downloader->debug, $dir); } - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $pf = &$pkg->fromAnyFile($file, PEAR_VALIDATE_INSTALLING); - PEAR::popErrorHandling(); + if (method_exists($pf, 'flattenFilelist')) { + $pf->flattenFilelist(); // for v2 + } + + return $pf; + } elseif (preg_match('/]+version="([^"]+)"/', $data, $packageversion)) { + $a = PEAR::raiseError('package.xml file "' . $file . + '" has unsupported package.xml version "' . $packageversion[1] . '"'); + return $a; + } else { + if (!class_exists('PEAR_ErrorStack')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ErrorStack.php'; + } + + PEAR_ErrorStack::staticPush('PEAR_PackageFile', + PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION, + 'warning', array('xml' => $data), 'package.xml "' . $file . + '" has no package.xml version'); + $object = &$this->parserFactory('1.0'); + $object->setConfig($this->_config); + $pf = $object->parse($data, $file, $archive); if (PEAR::isError($pf)) { - if (is_array($pf->getUserInfo())) { - foreach ($pf->getUserInfo() as $err) { - if (is_array($err)) { - $err = $err['message']; - } + return $pf; + } - if (!isset($options['soft'])) { - $this->_downloader->log(0, "Validation Error: $err"); - } - } - } + if ($this->_rawReturn) { + return $pf; + } - if (!isset($options['soft'])) { - $this->_downloader->log(0, $pf->getMessage()); + if (!$pf->validate($state)) { + $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', + 2, null, null, $pf->getValidationWarnings()); + return $a; + } + + if ($this->_logger && $pf->getValidationWarnings(false)) { + foreach ($pf->getValidationWarnings() as $warning) { + $this->_logger->log(0, 'WARNING: ' . $warning['message']); } + } - ///FIXME need to pass back some error code that we can use to match with to cancel all further operations - /// At least stop all deps of this package from being installed - $out = $saveparam ? $saveparam : $param; - $err = PEAR::raiseError('Download of "' . $out . '" succeeded, but it is not a valid package archive'); - $this->_valid = false; - return $err; + if (method_exists($pf, 'flattenFilelist')) { + $pf->flattenFilelist(); // for v2 } - $this->_packagefile = &$pf; - $this->setGroup('default'); // install the default dependency group - return $this->_valid = true; + return $pf; } - - return $this->_valid = false; } /** + * Register a temporary file or directory. When the destructor is + * executed, all registered temporary files and directories are + * removed. * - * @param string|array pass in an array of format - * array( - * 'package' => 'pname', - * ['channel' => 'channame',] - * ['version' => 'version',] - * ['state' => 'state',]) - * or a string of format [channame/]pname[-version|-state] + * @param string $file name of file or directory + * @return void */ - function _fromString($param) + function addTempFile($file) { - $options = $this->_downloader->getOptions(); - $channel = $this->_config->get('default_channel'); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $pname = $this->_registry->parsePackageName($param, $channel); - PEAR::popErrorHandling(); - if (PEAR::isError($pname)) { - if ($pname->getCode() == 'invalid') { - $this->_valid = false; - return false; - } - - if ($pname->getCode() == 'channel') { - $parsed = $pname->getUserInfo(); - if ($this->_downloader->discover($parsed['channel'])) { - if ($this->_config->get('auto_discover')) { - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $pname = $this->_registry->parsePackageName($param, $channel); - PEAR::popErrorHandling(); - } else { - if (!isset($options['soft'])) { - $this->_downloader->log(0, 'Channel "' . $parsed['channel'] . - '" is not initialized, use ' . - '"pear channel-discover ' . $parsed['channel'] . '" to initialize' . - 'or pear config-set auto_discover 1'); - } - } - } - - if (PEAR::isError($pname)) { - if (!isset($options['soft'])) { - $this->_downloader->log(0, $pname->getMessage()); - } - - if (is_array($param)) { - $param = $this->_registry->parsedPackageNameToString($param); - } - - $err = PEAR::raiseError('invalid package name/package file "' . $param . '"'); - $this->_valid = false; - return $err; - } - } else { - if (!isset($options['soft'])) { - $this->_downloader->log(0, $pname->getMessage()); - } + $GLOBALS['_PEAR_Common_tempfiles'][] = $file; + } - $err = PEAR::raiseError('invalid package name/package file "' . $param . '"'); - $this->_valid = false; - return $err; - } + /** + * Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file. + * @access public + * @param string contents of package.xml file + * @param int package state (one of PEAR_VALIDATE_* constants) + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @using Archive_Tar to extract the files + * @using fromPackageFile() to load the package after the package.xml + * file is extracted. + */ + function &fromTgzFile($file, $state) + { + if (!class_exists('Archive_Tar')) { + require_once 'phar://install-pear-nozlib.phar/' . 'Archive/Tar.php'; } - if (!isset($this->_type)) { - $this->_type = 'rest'; + $tar = new Archive_Tar($file); + if ($this->_debug <= 1) { + $tar->pushErrorHandling(PEAR_ERROR_RETURN); } - $this->_parsedname = $pname; - $this->_explicitState = isset($pname['state']) ? $pname['state'] : false; - $this->_explicitGroup = isset($pname['group']) ? true : false; + $content = $tar->listContent(); + if ($this->_debug <= 1) { + $tar->popErrorHandling(); + } - $info = $this->_downloader->_getPackageDownloadUrl($pname); - if (PEAR::isError($info)) { - if ($info->getCode() != -976 && $pname['channel'] == 'pear.php.net') { - // try pecl - $pname['channel'] = 'pecl.php.net'; - if ($test = $this->_downloader->_getPackageDownloadUrl($pname)) { - if (!PEAR::isError($test)) { - $info = PEAR::raiseError($info->getMessage() . ' - package ' . - $this->_registry->parsedPackageNameToString($pname, true) . - ' can be installed with "pecl install ' . $pname['package'] . - '"'); - } else { - $pname['channel'] = 'pear.php.net'; - } - } else { - $pname['channel'] = 'pear.php.net'; - } + if (!is_array($content)) { + if (is_string($file) && strlen($file < 255) && + (!file_exists($file) || !@is_file($file))) { + $ret = PEAR::raiseError("could not open file \"$file\""); + return $ret; } - return $info; - } - - $this->_rawpackagefile = $info['raw']; - $ret = $this->_analyzeDownloadURL($info, $param, $pname); - if (PEAR::isError($ret)) { + $file = realpath($file); + $ret = PEAR::raiseError("Could not get contents of package \"$file\"". + '. Invalid tgz file.'); return $ret; } - if ($ret) { - $this->_downloadURL = $ret; - return $this->_valid = (bool) $ret; - } - } - - /** - * @param array output of package.getDownloadURL - * @param string|array|object information for detecting packages to be downloaded, and - * for errors - * @param array name information of the package - * @param array|null packages to be downloaded - * @param bool is this an optional dependency? - * @param bool is this any kind of dependency? - * @access private - */ - function _analyzeDownloadURL($info, $param, $pname, $params = null, $optional = false, - $isdependency = false) - { - if (!is_string($param) && PEAR_Downloader_Package::willDownload($param, $params)) { - return false; - } - - if ($info === false) { - $saveparam = !is_string($param) ? ", cannot download \"$param\"" : ''; - - // no releases exist - return PEAR::raiseError('No releases for package "' . - $this->_registry->parsedPackageNameToString($pname, true) . '" exist' . $saveparam); + if (!count($content) && !@is_file($file)) { + $ret = PEAR::raiseError("could not open file \"$file\""); + return $ret; } - if (strtolower($info['info']->getChannel()) != strtolower($pname['channel'])) { - $err = false; - if ($pname['channel'] == 'pecl.php.net') { - if ($info['info']->getChannel() != 'pear.php.net') { - $err = true; - } - } elseif ($info['info']->getChannel() == 'pecl.php.net') { - if ($pname['channel'] != 'pear.php.net') { - $err = true; - } - } else { - $err = true; + $xml = null; + $origfile = $file; + foreach ($content as $file) { + $name = $file['filename']; + if ($name == 'package2.xml') { // allow a .tgz to distribute both versions + $xml = $name; + break; } - if ($err) { - return PEAR::raiseError('SECURITY ERROR: package in channel "' . $pname['channel'] . - '" retrieved another channel\'s name for download! ("' . - $info['info']->getChannel() . '")'); + if ($name == 'package.xml') { + $xml = $name; + break; + } elseif (preg_match('/package.xml$/', $name, $match)) { + $xml = $name; + break; } } - $preferred_state = $this->_config->get('preferred_state'); - if (!isset($info['url'])) { - $package_version = $this->_registry->packageInfo($info['info']->getPackage(), - 'version', $info['info']->getChannel()); - if ($this->isInstalled($info)) { - if ($isdependency && version_compare($info['version'], $package_version, '<=')) { - // ignore bogus errors of "failed to download dependency" - // if it is already installed and the one that would be - // downloaded is older or the same version (Bug #7219) - return false; - } + if ($this->_tmpdir) { + $tmpdir = $this->_tmpdir; + } else { + $tmpdir = System::mkTemp(array('-t', $this->_config->get('temp_dir'), '-d', 'pear')); + if ($tmpdir === false) { + $ret = PEAR::raiseError("there was a problem with getting the configured temp directory"); + return $ret; } - if ($info['version'] === $package_version) { - if (!isset($options['soft'])) { - $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . - '/' . $pname['package'] . '-' . $pname['version'] . ', additionally the suggested version' . - ' (' . $package_version . ') is the same as the locally installed one.'); - } + PEAR_PackageFile::addTempFile($tmpdir); + } - return false; + $this->_extractErrors(); + PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors')); + if (!$xml || !$tar->extractList(array($xml), $tmpdir)) { + $extra = implode("\n", $this->_extractErrors()); + if ($extra) { + $extra = ' ' . $extra; } - if (version_compare($info['version'], $package_version, '<=')) { - if (!isset($options['soft'])) { - $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . - '/' . $pname['package'] . '-' . $pname['version'] . ', additionally the suggested version' . - ' (' . $info['version'] . ') is a lower version than the locally installed one (' . $package_version . ').'); - } + PEAR::staticPopErrorHandling(); + $ret = PEAR::raiseError('could not extract the package.xml file from "' . + $origfile . '"' . $extra); + return $ret; + } - return false; - } + PEAR::staticPopErrorHandling(); + $ret = &PEAR_PackageFile::fromPackageFile("$tmpdir/$xml", $state, $origfile); + return $ret; + } - $instead = ', will instead download version ' . $info['version'] . - ', stability "' . $info['info']->getState() . '"'; - // releases exist, but we failed to get any - if (isset($this->_downloader->_options['force'])) { - if (isset($pname['version'])) { - $vs = ', version "' . $pname['version'] . '"'; - } elseif (isset($pname['state'])) { - $vs = ', stability "' . $pname['state'] . '"'; - } elseif ($param == 'dependency') { - if (!class_exists('PEAR_Common')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Common.php'; - } + /** + * helper for extracting Archive_Tar errors + * @var array + * @access private + */ + var $_extractErrors = array(); - if (!in_array($info['info']->getState(), - PEAR_Common::betterStates($preferred_state, true))) { - if ($optional) { - // don't spit out confusing error message - return $this->_downloader->_getPackageDownloadUrl( - array('package' => $pname['package'], - 'channel' => $pname['channel'], - 'version' => $info['version'])); - } - $vs = ' within preferred state "' . $preferred_state . - '"'; - } else { - if (!class_exists('PEAR_Dependency2')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; - } + /** + * helper callback for extracting Archive_Tar errors + * + * @param PEAR_Error|null $err + * @return array + * @access private + */ + function _extractErrors($err = null) + { + static $errors = array(); + if ($err === null) { + $e = $errors; + $errors = array(); + return $e; + } + $errors[] = $err->getMessage(); + } - if ($optional) { - // don't spit out confusing error message - return $this->_downloader->_getPackageDownloadUrl( - array('package' => $pname['package'], - 'channel' => $pname['channel'], - 'version' => $info['version'])); - } - $vs = PEAR_Dependency2::_getExtraString($pname); - $instead = ''; - } - } else { - $vs = ' within preferred state "' . $preferred_state . '"'; - } + /** + * Create a PEAR_PackageFile_v* from a package.xml file. + * + * @access public + * @param string $descfile name of package xml file + * @param int $state package state (one of PEAR_VALIDATE_* constants) + * @param string|false $archive name of the archive this package.xml came + * from, if any + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @uses PEAR_PackageFile::fromXmlString to create the oject after the + * XML is loaded from the package.xml file. + */ + function &fromPackageFile($descfile, $state, $archive = false) + { + $fp = false; + if (is_string($descfile) && strlen($descfile) < 255 && + ( + !file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) + || (!$fp = @fopen($descfile, 'r')) + ) + ) { + $a = PEAR::raiseError("Unable to open $descfile"); + return $a; + } - if (!isset($options['soft'])) { - $this->_downloader->log(1, 'WARNING: failed to download ' . $pname['channel'] . - '/' . $pname['package'] . $vs . $instead); - } + // read the whole thing so we only get one cdata callback + // for each block of cdata + fclose($fp); + $data = file_get_contents($descfile); + $ret = &PEAR_PackageFile::fromXmlString($data, $state, $descfile, $archive); + return $ret; + } - // download the latest release - return $this->_downloader->_getPackageDownloadUrl( - array('package' => $pname['package'], - 'channel' => $pname['channel'], - 'version' => $info['version'])); + + /** + * Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file. + * + * This method is able to extract information about a package from a .tgz + * archive or from a XML package definition file. + * + * @access public + * @param string $info file name + * @param int $state package state (one of PEAR_VALIDATE_* constants) + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @uses fromPackageFile() if the file appears to be XML + * @uses fromTgzFile() to load all non-XML files + */ + function &fromAnyFile($info, $state) + { + if (is_dir($info)) { + $dir_name = realpath($info); + if (file_exists($dir_name . '/package.xml')) { + $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package.xml', $state); + } elseif (file_exists($dir_name . '/package2.xml')) { + $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package2.xml', $state); } else { - if (isset($info['php']) && $info['php']) { - $err = PEAR::raiseError('Failed to download ' . - $this->_registry->parsedPackageNameToString( - array('channel' => $pname['channel'], - 'package' => $pname['package']), - true) . - ', latest release is version ' . $info['php']['v'] . - ', but it requires PHP version "' . - $info['php']['m'] . '", use "' . - $this->_registry->parsedPackageNameToString( - array('channel' => $pname['channel'], 'package' => $pname['package'], - 'version' => $info['php']['v'])) . '" to install', - PEAR_DOWNLOADER_PACKAGE_PHPVERSION); - return $err; - } - - // construct helpful error message - if (isset($pname['version'])) { - $vs = ', version "' . $pname['version'] . '"'; - } elseif (isset($pname['state'])) { - $vs = ', stability "' . $pname['state'] . '"'; - } elseif ($param == 'dependency') { - if (!class_exists('PEAR_Common')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Common.php'; - } + $info = PEAR::raiseError("No package definition found in '$info' directory"); + } - if (!in_array($info['info']->getState(), - PEAR_Common::betterStates($preferred_state, true))) { - if ($optional) { - // don't spit out confusing error message, and don't die on - // optional dep failure! - return $this->_downloader->_getPackageDownloadUrl( - array('package' => $pname['package'], - 'channel' => $pname['channel'], - 'version' => $info['version'])); - } - $vs = ' within preferred state "' . $preferred_state . '"'; - } else { - if (!class_exists('PEAR_Dependency2')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; - } + return $info; + } - if ($optional) { - // don't spit out confusing error message, and don't die on - // optional dep failure! - return $this->_downloader->_getPackageDownloadUrl( - array('package' => $pname['package'], - 'channel' => $pname['channel'], - 'version' => $info['version'])); - } - $vs = PEAR_Dependency2::_getExtraString($pname); - } - } else { - $vs = ' within preferred state "' . $this->_downloader->config->get('preferred_state') . '"'; - } + $fp = false; + if (is_string($info) && strlen($info) < 255 && + (file_exists($info) || ($fp = @fopen($info, 'r'))) + ) { - $options = $this->_downloader->getOptions(); - // this is only set by the "download-all" command - if (isset($options['ignorepreferred_state'])) { - $err = PEAR::raiseError( - 'Failed to download ' . $this->_registry->parsedPackageNameToString( - array('channel' => $pname['channel'], 'package' => $pname['package']), - true) - . $vs . - ', latest release is version ' . $info['version'] . - ', stability "' . $info['info']->getState() . '", use "' . - $this->_registry->parsedPackageNameToString( - array('channel' => $pname['channel'], 'package' => $pname['package'], - 'version' => $info['version'])) . '" to install', - PEAR_DOWNLOADER_PACKAGE_STATE); - return $err; - } + if ($fp) { + fclose($fp); + } - // Checks if the user has a package installed already and checks the release against - // the state against the installed package, this allows upgrades for packages - // with lower stability than the preferred_state - $stability = $this->_registry->packageInfo($pname['package'], 'stability', $pname['channel']); - if (!$this->isInstalled($info) - || !in_array($info['info']->getState(), PEAR_Common::betterStates($stability['release'], true)) - ) { - $err = PEAR::raiseError( - 'Failed to download ' . $this->_registry->parsedPackageNameToString( - array('channel' => $pname['channel'], 'package' => $pname['package']), - true) - . $vs . - ', latest release is version ' . $info['version'] . - ', stability "' . $info['info']->getState() . '", use "' . - $this->_registry->parsedPackageNameToString( - array('channel' => $pname['channel'], 'package' => $pname['package'], - 'version' => $info['version'])) . '" to install'); - return $err; + $tmp = substr($info, -4); + if ($tmp == '.xml') { + $info = &PEAR_PackageFile::fromPackageFile($info, $state); + } elseif ($tmp == '.tar' || $tmp == '.tgz') { + $info = &PEAR_PackageFile::fromTgzFile($info, $state); + } else { + $fp = fopen($info, 'r'); + $test = fread($fp, 5); + fclose($fp); + if ($test == '_downloader->log(0, - 'WARNING: "' . - $this->_registry->parsedPackageNameToString( - array('channel' => $info['info']->getChannel(), - 'package' => $info['info']->getPackage()), true) . - '" is deprecated in favor of "' . - $this->_registry->parsedPackageNameToString($info['deprecated'], true) . - '"'); + return $info; } + $info = PEAR::raiseError("Cannot open '$info' for parsing"); return $info; } -} - * @copyright 2004-2008 Greg Beaver - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: ErrorStack.php,v 1.29 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR_ErrorStack - */ - -/** - * Singleton storage - * - * Format: - *
    - * array(
    - *  'package1' => PEAR_ErrorStack object,
    - *  'package2' => PEAR_ErrorStack object,
    - *  ...
    - * )
    - * 
    - * @access private - * @global array $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] - */ -$GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] = array(); - -/** - * Global error callback (default) - * - * This is only used if set to non-false. * is the default callback for - * all packages, whereas specific packages may set a default callback - * for all instances, regardless of whether they are a singleton or not. - * - * To exclude non-singletons, only set the local callback for the singleton - * @see PEAR_ErrorStack::setDefaultCallback() - * @access private - * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] - */ -$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'] = array( - '*' => false, -); - -/** - * Global Log object (default) - * - * This is only used if set to non-false. Use to set a default log object for - * all stacks, regardless of instantiation order or location - * @see PEAR_ErrorStack::setDefaultLogger() - * @access private - * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] - */ -$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = false; - -/** - * Global Overriding Callback - * - * This callback will override any error callbacks that specific loggers have set. - * Use with EXTREME caution - * @see PEAR_ErrorStack::staticPushCallback() - * @access private - * @global array $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] - */ -$GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); - -/**#@+ - * One of four possible return values from the error Callback - * @see PEAR_ErrorStack::_errorCallback() - */ -/** - * If this is returned, then the error will be both pushed onto the stack - * and logged. - */ -define('PEAR_ERRORSTACK_PUSHANDLOG', 1); -/** - * If this is returned, then the error will only be pushed onto the stack, - * and not logged. - */ -define('PEAR_ERRORSTACK_PUSH', 2); -/** - * If this is returned, then the error will only be logged, but not pushed - * onto the error stack. - */ -define('PEAR_ERRORSTACK_LOG', 3); -/** - * If this is returned, then the error is completely ignored. - */ -define('PEAR_ERRORSTACK_IGNORE', 4); -/** - * If this is returned, then the error is logged and die() is called. - */ -define('PEAR_ERRORSTACK_DIE', 5); -/**#@-*/ - -/** - * Error code for an attempt to instantiate a non-class as a PEAR_ErrorStack in - * the singleton method. - */ -define('PEAR_ERRORSTACK_ERR_NONCLASS', 1); - -/** - * Error code for an attempt to pass an object into {@link PEAR_ErrorStack::getMessage()} - * that has no __toString() method - */ -define('PEAR_ERRORSTACK_ERR_OBJTOSTRING', 2); -/** - * Error Stack Implementation - * - * Usage: - * - * // global error stack - * $global_stack = &PEAR_ErrorStack::singleton('MyPackage'); - * // local error stack - * $local_stack = new PEAR_ErrorStack('MyPackage'); - * - * @author Greg Beaver - * @version 1.8.0 - * @package PEAR_ErrorStack - * @category Debugging - * @copyright 2004-2008 Greg Beaver - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: ErrorStack.php,v 1.29 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR_ErrorStack - */ -class PEAR_ErrorStack { - /** - * Errors are stored in the order that they are pushed on the stack. - * @since 0.4alpha Errors are no longer organized by error level. - * This renders pop() nearly unusable, and levels could be more easily - * handled in a callback anyway - * @var array - * @access private - */ - var $_errors = array(); - - /** - * Storage of errors by level. - * - * Allows easy retrieval and deletion of only errors from a particular level - * @since PEAR 1.4.0dev - * @var array - * @access private - */ - var $_errorsByLevel = array(); - - /** - * Package name this error stack represents - * @var string - * @access protected - */ - var $_package; - - /** - * Determines whether a PEAR_Error is thrown upon every error addition - * @var boolean - * @access private - */ - var $_compat = false; - - /** - * If set to a valid callback, this will be used to generate the error - * message from the error code, otherwise the message passed in will be - * used - * @var false|string|array - * @access private - */ - var $_msgCallback = false; - - /** - * If set to a valid callback, this will be used to generate the error - * context for an error. For PHP-related errors, this will be a file - * and line number as retrieved from debug_backtrace(), but can be - * customized for other purposes. The error might actually be in a separate - * configuration file, or in a database query. - * @var false|string|array - * @access protected - */ - var $_contextCallback = false; - - /** - * If set to a valid callback, this will be called every time an error - * is pushed onto the stack. The return value will be used to determine - * whether to allow an error to be pushed or logged. - * - * The return value must be one an PEAR_ERRORSTACK_* constant - * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG - * @var false|string|array - * @access protected - */ - var $_errorCallback = array(); - - /** - * PEAR::Log object for logging errors - * @var false|Log - * @access protected - */ - var $_logger = false; - - /** - * Error messages - designed to be overridden - * @var array - * @abstract - */ - var $_errorMsgs = array(); - - /** - * Set up a new error stack - * - * @param string $package name of the package this error stack represents - * @param callback $msgCallback callback used for error message generation - * @param callback $contextCallback callback used for context generation, - * defaults to {@link getFileLine()} - * @param boolean $throwPEAR_Error - */ - function PEAR_ErrorStack($package, $msgCallback = false, $contextCallback = false, - $throwPEAR_Error = false) - { - $this->_package = $package; - $this->setMessageCallback($msgCallback); - $this->setContextCallback($contextCallback); - $this->_compat = $throwPEAR_Error; - } - - /** - * Return a single error stack for this package. - * - * Note that all parameters are ignored if the stack for package $package - * has already been instantiated - * @param string $package name of the package this error stack represents - * @param callback $msgCallback callback used for error message generation - * @param callback $contextCallback callback used for context generation, - * defaults to {@link getFileLine()} - * @param boolean $throwPEAR_Error - * @param string $stackClass class to instantiate - * @static - * @return PEAR_ErrorStack - */ - function &singleton($package, $msgCallback = false, $contextCallback = false, - $throwPEAR_Error = false, $stackClass = 'PEAR_ErrorStack') - { - if (isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { - return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; - } - if (!class_exists($stackClass)) { - if (function_exists('debug_backtrace')) { - $trace = debug_backtrace(); - } - PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_NONCLASS, - 'exception', array('stackclass' => $stackClass), - 'stack class "%stackclass%" is not a valid class name (should be like PEAR_ErrorStack)', - false, $trace); - } - $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package] = - new $stackClass($package, $msgCallback, $contextCallback, $throwPEAR_Error); - - return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]; - } - - /** - * Internal error handler for PEAR_ErrorStack class - * - * Dies if the error is an exception (and would have died anyway) - * @access private - */ - function _handleError($err) - { - if ($err['level'] == 'exception') { - $message = $err['message']; - if (isset($_SERVER['REQUEST_URI'])) { - echo '
    '; - } else { - echo "\n"; - } - var_dump($err['context']); - die($message); - } - } - - /** - * Set up a PEAR::Log object for all error stacks that don't have one - * @param Log $log - * @static - */ - function setDefaultLogger(&$log) - { - if (is_object($log) && method_exists($log, 'log') ) { - $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; - } elseif (is_callable($log)) { - $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER'] = &$log; - } - } - - /** - * Set up a PEAR::Log object for this error stack - * @param Log $log - */ - function setLogger(&$log) - { - if (is_object($log) && method_exists($log, 'log') ) { - $this->_logger = &$log; - } elseif (is_callable($log)) { - $this->_logger = &$log; - } - } - - /** - * Set an error code => error message mapping callback - * - * This method sets the callback that can be used to generate error - * messages for any instance - * @param array|string Callback function/method - */ - function setMessageCallback($msgCallback) - { - if (!$msgCallback) { - $this->_msgCallback = array(&$this, 'getErrorMessage'); - } else { - if (is_callable($msgCallback)) { - $this->_msgCallback = $msgCallback; - } - } - } - - /** - * Get an error code => error message mapping callback - * - * This method returns the current callback that can be used to generate error - * messages - * @return array|string|false Callback function/method or false if none - */ - function getMessageCallback() - { - return $this->_msgCallback; - } - - /** - * Sets a default callback to be used by all error stacks - * - * This method sets the callback that can be used to generate error - * messages for a singleton - * @param array|string Callback function/method - * @param string Package name, or false for all packages - * @static - */ - function setDefaultCallback($callback = false, $package = false) - { - if (!is_callable($callback)) { - $callback = false; - } - $package = $package ? $package : '*'; - $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$package] = $callback; - } - - /** - * Set a callback that generates context information (location of error) for an error stack - * - * This method sets the callback that can be used to generate context - * information for an error. Passing in NULL will disable context generation - * and remove the expensive call to debug_backtrace() - * @param array|string|null Callback function/method - */ - function setContextCallback($contextCallback) - { - if ($contextCallback === null) { - return $this->_contextCallback = false; - } - if (!$contextCallback) { - $this->_contextCallback = array(&$this, 'getFileLine'); - } else { - if (is_callable($contextCallback)) { - $this->_contextCallback = $contextCallback; - } - } - } - - /** - * Set an error Callback - * If set to a valid callback, this will be called every time an error - * is pushed onto the stack. The return value will be used to determine - * whether to allow an error to be pushed or logged. - * - * The return value must be one of the ERRORSTACK_* constants. - * - * This functionality can be used to emulate PEAR's pushErrorHandling, and - * the PEAR_ERROR_CALLBACK mode, without affecting the integrity of - * the error stack or logging - * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG - * @see popCallback() - * @param string|array $cb - */ - function pushCallback($cb) - { - array_push($this->_errorCallback, $cb); - } - - /** - * Remove a callback from the error callback stack - * @see pushCallback() - * @return array|string|false - */ - function popCallback() - { - if (!count($this->_errorCallback)) { - return false; - } - return array_pop($this->_errorCallback); - } - - /** - * Set a temporary overriding error callback for every package error stack - * - * Use this to temporarily disable all existing callbacks (can be used - * to emulate the @ operator, for instance) - * @see PEAR_ERRORSTACK_PUSHANDLOG, PEAR_ERRORSTACK_PUSH, PEAR_ERRORSTACK_LOG - * @see staticPopCallback(), pushCallback() - * @param string|array $cb - * @static - */ - function staticPushCallback($cb) - { - array_push($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'], $cb); - } - - /** - * Remove a temporary overriding error callback - * @see staticPushCallback() - * @return array|string|false - * @static - */ - function staticPopCallback() - { - $ret = array_pop($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK']); - if (!is_array($GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'])) { - $GLOBALS['_PEAR_ERRORSTACK_OVERRIDE_CALLBACK'] = array(); - } - return $ret; - } - - /** - * Add an error to the stack - * - * If the message generator exists, it is called with 2 parameters. - * - the current Error Stack object - * - an array that is in the same format as an error. Available indices - * are 'code', 'package', 'time', 'params', 'level', and 'context' - * - * Next, if the error should contain context information, this is - * handled by the context grabbing method. - * Finally, the error is pushed onto the proper error stack - * @param int $code Package-specific error code - * @param string $level Error level. This is NOT spell-checked - * @param array $params associative array of error parameters - * @param string $msg Error message, or a portion of it if the message - * is to be generated - * @param array $repackage If this error re-packages an error pushed by - * another package, place the array returned from - * {@link pop()} in this parameter - * @param array $backtrace Protected parameter: use this to pass in the - * {@link debug_backtrace()} that should be used - * to find error context - * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also - * thrown. If a PEAR_Error is returned, the userinfo - * property is set to the following array: - * - * - * array( - * 'code' => $code, - * 'params' => $params, - * 'package' => $this->_package, - * 'level' => $level, - * 'time' => time(), - * 'context' => $context, - * 'message' => $msg, - * //['repackage' => $err] repackaged error array/Exception class - * ); - * - * - * Normally, the previous array is returned. - */ - function push($code, $level = 'error', $params = array(), $msg = false, - $repackage = false, $backtrace = false) - { - $context = false; - // grab error context - if ($this->_contextCallback) { - if (!$backtrace) { - $backtrace = debug_backtrace(); - } - $context = call_user_func($this->_contextCallback, $code, $params, $backtrace); - } - - // save error - $time = explode(' ', microtime()); - $time = $time[1] + $time[0]; - $err = array( - 'code' => $code, - 'params' => $params, - 'package' => $this->_package, - 'level' => $level, - 'time' => $time, - 'context' => $context, - 'message' => $msg, - ); - - if ($repackage) { - $err['repackage'] = $repackage; - } - - // set up the error message, if necessary - if ($this->_msgCallback) { - $msg = call_user_func_array($this->_msgCallback, - array(&$this, $err)); - $err['message'] = $msg; - } - $push = $log = true; - $die = false; - // try the overriding callback first - $callback = $this->staticPopCallback(); - if ($callback) { - $this->staticPushCallback($callback); - } - if (!is_callable($callback)) { - // try the local callback next - $callback = $this->popCallback(); - if (is_callable($callback)) { - $this->pushCallback($callback); - } else { - // try the default callback - $callback = isset($GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package]) ? - $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK'][$this->_package] : - $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_CALLBACK']['*']; - } - } - if (is_callable($callback)) { - switch(call_user_func($callback, $err)){ - case PEAR_ERRORSTACK_IGNORE: - return $err; - break; - case PEAR_ERRORSTACK_PUSH: - $log = false; - break; - case PEAR_ERRORSTACK_LOG: - $push = false; - break; - case PEAR_ERRORSTACK_DIE: - $die = true; - break; - // anything else returned has the same effect as pushandlog - } - } - if ($push) { - array_unshift($this->_errors, $err); - if (!isset($this->_errorsByLevel[$err['level']])) { - $this->_errorsByLevel[$err['level']] = array(); - } - $this->_errorsByLevel[$err['level']][] = &$this->_errors[0]; - } - if ($log) { - if ($this->_logger || $GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']) { - $this->_log($err); - } - } - if ($die) { - die(); - } - if ($this->_compat && $push) { - return $this->raiseError($msg, $code, null, null, $err); - } - return $err; - } - - /** - * Static version of {@link push()} - * - * @param string $package Package name this error belongs to - * @param int $code Package-specific error code - * @param string $level Error level. This is NOT spell-checked - * @param array $params associative array of error parameters - * @param string $msg Error message, or a portion of it if the message - * is to be generated - * @param array $repackage If this error re-packages an error pushed by - * another package, place the array returned from - * {@link pop()} in this parameter - * @param array $backtrace Protected parameter: use this to pass in the - * {@link debug_backtrace()} that should be used - * to find error context - * @return PEAR_Error|array if compatibility mode is on, a PEAR_Error is also - * thrown. see docs for {@link push()} - * @static - */ - function staticPush($package, $code, $level = 'error', $params = array(), - $msg = false, $repackage = false, $backtrace = false) - { - $s = &PEAR_ErrorStack::singleton($package); - if ($s->_contextCallback) { - if (!$backtrace) { - if (function_exists('debug_backtrace')) { - $backtrace = debug_backtrace(); - } - } - } - return $s->push($code, $level, $params, $msg, $repackage, $backtrace); - } - - /** - * Log an error using PEAR::Log - * @param array $err Error array - * @param array $levels Error level => Log constant map - * @access protected - */ - function _log($err) - { - if ($this->_logger) { - $logger = &$this->_logger; - } else { - $logger = &$GLOBALS['_PEAR_ERRORSTACK_DEFAULT_LOGGER']; - } - if (is_a($logger, 'Log')) { - $levels = array( - 'exception' => PEAR_LOG_CRIT, - 'alert' => PEAR_LOG_ALERT, - 'critical' => PEAR_LOG_CRIT, - 'error' => PEAR_LOG_ERR, - 'warning' => PEAR_LOG_WARNING, - 'notice' => PEAR_LOG_NOTICE, - 'info' => PEAR_LOG_INFO, - 'debug' => PEAR_LOG_DEBUG); - if (isset($levels[$err['level']])) { - $level = $levels[$err['level']]; - } else { - $level = PEAR_LOG_INFO; - } - $logger->log($err['message'], $level, $err); - } else { // support non-standard logs - call_user_func($logger, $err); - } - } - - - /** - * Pop an error off of the error stack - * - * @return false|array - * @since 0.4alpha it is no longer possible to specify a specific error - * level to return - the last error pushed will be returned, instead - */ - function pop() - { - $err = @array_shift($this->_errors); - if (!is_null($err)) { - @array_pop($this->_errorsByLevel[$err['level']]); - if (!count($this->_errorsByLevel[$err['level']])) { - unset($this->_errorsByLevel[$err['level']]); - } - } - return $err; - } - - /** - * Pop an error off of the error stack, static method - * - * @param string package name - * @return boolean - * @since PEAR1.5.0a1 - */ - function staticPop($package) - { - if ($package) { - if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { - return false; - } - return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->pop(); - } - } - - /** - * Determine whether there are any errors on the stack - * @param string|array Level name. Use to determine if any errors - * of level (string), or levels (array) have been pushed - * @return boolean - */ - function hasErrors($level = false) - { - if ($level) { - return isset($this->_errorsByLevel[$level]); - } - return count($this->_errors); - } - - /** - * Retrieve all errors since last purge - * - * @param boolean set in order to empty the error stack - * @param string level name, to return only errors of a particular severity - * @return array - */ - function getErrors($purge = false, $level = false) - { - if (!$purge) { - if ($level) { - if (!isset($this->_errorsByLevel[$level])) { - return array(); - } else { - return $this->_errorsByLevel[$level]; - } - } else { - return $this->_errors; - } - } - if ($level) { - $ret = $this->_errorsByLevel[$level]; - foreach ($this->_errorsByLevel[$level] as $i => $unused) { - // entries are references to the $_errors array - $this->_errorsByLevel[$level][$i] = false; - } - // array_filter removes all entries === false - $this->_errors = array_filter($this->_errors); - unset($this->_errorsByLevel[$level]); - return $ret; - } - $ret = $this->_errors; - $this->_errors = array(); - $this->_errorsByLevel = array(); - return $ret; - } - - /** - * Determine whether there are any errors on a single error stack, or on any error stack - * - * The optional parameter can be used to test the existence of any errors without the need of - * singleton instantiation - * @param string|false Package name to check for errors - * @param string Level name to check for a particular severity - * @return boolean - * @static - */ - function staticHasErrors($package = false, $level = false) - { - if ($package) { - if (!isset($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package])) { - return false; - } - return $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->hasErrors($level); - } - foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { - if ($obj->hasErrors($level)) { - return true; - } - } - return false; - } - - /** - * Get a list of all errors since last purge, organized by package - * @since PEAR 1.4.0dev BC break! $level is now in the place $merge used to be - * @param boolean $purge Set to purge the error stack of existing errors - * @param string $level Set to a level name in order to retrieve only errors of a particular level - * @param boolean $merge Set to return a flat array, not organized by package - * @param array $sortfunc Function used to sort a merged array - default - * sorts by time, and should be good for most cases - * @static - * @return array - */ - function staticGetErrors($purge = false, $level = false, $merge = false, - $sortfunc = array('PEAR_ErrorStack', '_sortErrors')) - { - $ret = array(); - if (!is_callable($sortfunc)) { - $sortfunc = array('PEAR_ErrorStack', '_sortErrors'); - } - foreach ($GLOBALS['_PEAR_ERRORSTACK_SINGLETON'] as $package => $obj) { - $test = $GLOBALS['_PEAR_ERRORSTACK_SINGLETON'][$package]->getErrors($purge, $level); - if ($test) { - if ($merge) { - $ret = array_merge($ret, $test); - } else { - $ret[$package] = $test; - } - } - } - if ($merge) { - usort($ret, $sortfunc); - } - return $ret; - } - - /** - * Error sorting function, sorts by time - * @access private - */ - function _sortErrors($a, $b) - { - if ($a['time'] == $b['time']) { - return 0; - } - if ($a['time'] < $b['time']) { - return 1; - } - return -1; - } - - /** - * Standard file/line number/function/class context callback - * - * This function uses a backtrace generated from {@link debug_backtrace()} - * and so will not work at all in PHP < 4.3.0. The frame should - * reference the frame that contains the source of the error. - * @return array|false either array('file' => file, 'line' => line, - * 'function' => function name, 'class' => class name) or - * if this doesn't work, then false - * @param unused - * @param integer backtrace frame. - * @param array Results of debug_backtrace() - * @static - */ - function getFileLine($code, $params, $backtrace = null) - { - if ($backtrace === null) { - return false; - } - $frame = 0; - $functionframe = 1; - if (!isset($backtrace[1])) { - $functionframe = 0; - } else { - while (isset($backtrace[$functionframe]['function']) && - $backtrace[$functionframe]['function'] == 'eval' && - isset($backtrace[$functionframe + 1])) { - $functionframe++; - } - } - if (isset($backtrace[$frame])) { - if (!isset($backtrace[$frame]['file'])) { - $frame++; - } - $funcbacktrace = $backtrace[$functionframe]; - $filebacktrace = $backtrace[$frame]; - $ret = array('file' => $filebacktrace['file'], - 'line' => $filebacktrace['line']); - // rearrange for eval'd code or create function errors - if (strpos($filebacktrace['file'], '(') && - preg_match(';^(.*?)\((\d+)\) : (.*?)\\z;', $filebacktrace['file'], - $matches)) { - $ret['file'] = $matches[1]; - $ret['line'] = $matches[2] + 0; - } - if (isset($funcbacktrace['function']) && isset($backtrace[1])) { - if ($funcbacktrace['function'] != 'eval') { - if ($funcbacktrace['function'] == '__lambda_func') { - $ret['function'] = 'create_function() code'; - } else { - $ret['function'] = $funcbacktrace['function']; - } - } - } - if (isset($funcbacktrace['class']) && isset($backtrace[1])) { - $ret['class'] = $funcbacktrace['class']; - } - return $ret; - } - return false; - } - - /** - * Standard error message generation callback - * - * This method may also be called by a custom error message generator - * to fill in template values from the params array, simply - * set the third parameter to the error message template string to use - * - * The special variable %__msg% is reserved: use it only to specify - * where a message passed in by the user should be placed in the template, - * like so: - * - * Error message: %msg% - internal error - * - * If the message passed like so: - * - * - * $stack->push(ERROR_CODE, 'error', array(), 'server error 500'); - * - * - * The returned error message will be "Error message: server error 500 - - * internal error" - * @param PEAR_ErrorStack - * @param array - * @param string|false Pre-generated error message template - * @static - * @return string - */ - function getErrorMessage(&$stack, $err, $template = false) - { - if ($template) { - $mainmsg = $template; - } else { - $mainmsg = $stack->getErrorMessageTemplate($err['code']); - } - $mainmsg = str_replace('%__msg%', $err['message'], $mainmsg); - if (is_array($err['params']) && count($err['params'])) { - foreach ($err['params'] as $name => $val) { - if (is_array($val)) { - // @ is needed in case $val is a multi-dimensional array - $val = @implode(', ', $val); - } - if (is_object($val)) { - if (method_exists($val, '__toString')) { - $val = $val->__toString(); - } else { - PEAR_ErrorStack::staticPush('PEAR_ErrorStack', PEAR_ERRORSTACK_ERR_OBJTOSTRING, - 'warning', array('obj' => get_class($val)), - 'object %obj% passed into getErrorMessage, but has no __toString() method'); - $val = 'Object'; - } - } - $mainmsg = str_replace('%' . $name . '%', $val, $mainmsg); - } - } - return $mainmsg; - } - - /** - * Standard Error Message Template generator from code - * @return string - */ - function getErrorMessageTemplate($code) - { - if (!isset($this->_errorMsgs[$code])) { - return '%__msg%'; - } - return $this->_errorMsgs[$code]; - } - - /** - * Set the Error Message Template array - * - * The array format must be: - *
    -     * array(error code => 'message template',...)
    -     * 
    - * - * Error message parameters passed into {@link push()} will be used as input - * for the error message. If the template is 'message %foo% was %bar%', and the - * parameters are array('foo' => 'one', 'bar' => 'six'), the error message returned will - * be 'message one was six' - * @return string - */ - function setErrorMessageTemplate($template) - { - $this->_errorMsgs = $template; - } - - - /** - * emulate PEAR::raiseError() - * - * @return PEAR_Error - */ - function raiseError() - { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; - $args = func_get_args(); - return call_user_func_array(array('PEAR', 'raiseError'), $args); - } -} -$stack = &PEAR_ErrorStack::singleton('PEAR_ErrorStack'); -$stack->pushCallback(array('PEAR_ErrorStack', '_handleError')); -?> - - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Frontend.php,v 1.18 2009/02/24 23:38:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * Include error handling - */ -//require_once 'PEAR.php'; - -/** - * Which user interface class is being used. - * @var string class name - */ -$GLOBALS['_PEAR_FRONTEND_CLASS'] = 'PEAR_Frontend_CLI'; - -/** - * Instance of $_PEAR_Command_uiclass. - * @var object - */ -$GLOBALS['_PEAR_FRONTEND_SINGLETON'] = null; - -/** - * Singleton-based frontend for PEAR user input/output - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Frontend extends PEAR -{ - /** - * Retrieve the frontend object - * @return PEAR_Frontend_CLI|PEAR_Frontend_Web|PEAR_Frontend_Gtk - * @static - */ - function &singleton($type = null) - { - if ($type === null) { - if (!isset($GLOBALS['_PEAR_FRONTEND_SINGLETON'])) { - $a = false; - return $a; - } - return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; - } - - $a = PEAR_Frontend::setFrontendClass($type); - return $a; - } - - /** - * Set the frontend class that will be used by calls to {@link singleton()} - * - * Frontends are expected to conform to the PEAR naming standard of - * _ => DIRECTORY_SEPARATOR (PEAR_Frontend_CLI is in PEAR/Frontend/CLI.php) - * @param string $uiclass full class name - * @return PEAR_Frontend - * @static - */ - function &setFrontendClass($uiclass) - { - if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && - is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], $uiclass)) { - return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; - } - - if (!class_exists($uiclass)) { - $file = 'phar://install-pear-nozlib.phar/' . str_replace('_', '/', $uiclass) . '.php'; - if (PEAR_Frontend::isIncludeable($file)) { - include_once $file; - } - } - - if (class_exists($uiclass)) { - $obj = &new $uiclass; - // quick test to see if this class implements a few of the most - // important frontend methods - if (is_a($obj, 'PEAR_Frontend')) { - $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$obj; - $GLOBALS['_PEAR_FRONTEND_CLASS'] = $uiclass; - return $obj; - } - - $err = PEAR::raiseError("not a frontend class: $uiclass"); - return $err; - } - - $err = PEAR::raiseError("no such class: $uiclass"); - return $err; - } - - /** - * Set the frontend class that will be used by calls to {@link singleton()} - * - * Frontends are expected to be a descendant of PEAR_Frontend - * @param PEAR_Frontend - * @return PEAR_Frontend - * @static - */ - function &setFrontendObject($uiobject) - { - if (is_object($GLOBALS['_PEAR_FRONTEND_SINGLETON']) && - is_a($GLOBALS['_PEAR_FRONTEND_SINGLETON'], get_class($uiobject))) { - return $GLOBALS['_PEAR_FRONTEND_SINGLETON']; - } - - if (!is_a($uiobject, 'PEAR_Frontend')) { - $err = PEAR::raiseError('not a valid frontend class: (' . - get_class($uiobject) . ')'); - return $err; - } - - $GLOBALS['_PEAR_FRONTEND_SINGLETON'] = &$uiobject; - $GLOBALS['_PEAR_FRONTEND_CLASS'] = get_class($uiobject); - return $uiobject; - } - - /** - * @param string $path relative or absolute include path - * @return boolean - * @static - */ - function isIncludeable($path) - { - if (file_exists($path) && is_readable($path)) { - return true; - } - - $fp = @fopen($path, 'r', true); - if ($fp) { - fclose($fp); - return true; - } - - return false; - } - - /** - * @param PEAR_Config - */ - function setConfig(&$config) - { - } - - /** - * This can be overridden to allow session-based temporary file management - * - * By default, all files are deleted at the end of a session. The web installer - * needs to be able to sustain a list over many sessions in order to support - * user interaction with install scripts - */ - function addTempFile($file) - { - $GLOBALS['_PEAR_Common_tempfiles'][] = $file; - } - - /** - * Log an action - * - * @param string $msg the message to log - * @param boolean $append_crlf - * @return boolean true - * @abstract - */ - function log($msg, $append_crlf = true) - { - } - - /** - * Run a post-installation script - * - * @param array $scripts array of post-install scripts - * @abstract - */ - function runPostinstallScripts(&$scripts) - { - } - - /** - * Display human-friendly output formatted depending on the - * $command parameter. - * - * This should be able to handle basic output data with no command - * @param mixed $data data structure containing the information to display - * @param string $command command from which this method was called - * @abstract - */ - function outputData($data, $command = '_default') - { - } - - /** - * Display a modal form dialog and return the given input - * - * A frontend that requires multiple requests to retrieve and process - * data must take these needs into account, and implement the request - * handling code. - * @param string $command command from which this method was called - * @param array $prompts associative array. keys are the input field names - * and values are the description - * @param array $types array of input field types (text, password, - * etc.) keys have to be the same like in $prompts - * @param array $defaults array of default values. again keys have - * to be the same like in $prompts. Do not depend - * on a default value being set. - * @return array input sent by the user - * @abstract - */ - function userDialog($command, $prompts, $types = array(), $defaults = array()) - { - } } * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: CLI.php,v 1.76 2009/04/04 00:09:14 dufuz Exp $ + * @version CVS: $Id: v1.php 286494 2009-07-29 06:57:11Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 + * @since File available since Release 1.4.0a1 */ /** - * base class + * needed for PEAR_VALIDATE_* constants */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Frontend.php'; - +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validate.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2.php'; /** - * Command-line Frontend for the PEAR Installer + * This class converts a PEAR_PackageFile_v1 object into any output format. + * + * Supported output formats include array, XML string, and a PEAR_PackageFile_v2 + * object, for converting package.xml 1.0 into package.xml 2.0 with no sweat. * @category pear * @package PEAR - * @author Stig Bakken * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 + * @since Class available since Release 1.4.0a1 */ -class PEAR_Frontend_CLI extends PEAR_Frontend +class PEAR_PackageFile_Generator_v1 { /** - * What type of user interface this frontend is for. - * @var string - * @access public + * @var PEAR_PackageFile_v1 */ - var $type = 'CLI'; - var $lp = ''; // line prefix + var $_packagefile; + function PEAR_PackageFile_Generator_v1(&$packagefile) + { + $this->_packagefile = &$packagefile; + } - var $params = array(); - var $term = array( - 'bold' => '', - 'normal' => '', - ); + function getPackagerVersion() + { + return '1.9.0'; + } - function PEAR_Frontend_CLI() + /** + * @param PEAR_Packager + * @param bool if true, a .tgz is written, otherwise a .tar is written + * @param string|null directory in which to save the .tgz + * @return string|PEAR_Error location of package or error object + */ + function toTgz(&$packager, $compress = true, $where = null) { - parent::PEAR(); - $term = getenv('TERM'); //(cox) $_ENV is empty for me in 4.1.1 - if (function_exists('posix_isatty') && !posix_isatty(1)) { - // output is being redirected to a file or through a pipe - } elseif ($term) { - if (preg_match('/^(xterm|vt220|linux)/', $term)) { - $this->term['bold'] = sprintf("%c%c%c%c", 27, 91, 49, 109); - $this->term['normal'] = sprintf("%c%c%c", 27, 91, 109); - } elseif (preg_match('/^vt100/', $term)) { - $this->term['bold'] = sprintf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); - $this->term['normal'] = sprintf("%c%c%c%c%c", 27, 91, 109, 0, 0); + require_once 'phar://install-pear-nozlib.phar/' . 'Archive/Tar.php'; + if ($where === null) { + if (!($where = System::mktemp(array('-d')))) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: mktemp failed'); } - } elseif (OS_WINDOWS) { - // XXX add ANSI codes here + } elseif (!@System::mkDir(array('-p', $where))) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: "' . $where . '" could' . + ' not be created'); + } + if (file_exists($where . DIRECTORY_SEPARATOR . 'package.xml') && + !is_file($where . DIRECTORY_SEPARATOR . 'package.xml')) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: unable to save package.xml as' . + ' "' . $where . DIRECTORY_SEPARATOR . 'package.xml"'); + } + if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: invalid package file'); + } + $pkginfo = $this->_packagefile->getArray(); + $ext = $compress ? '.tgz' : '.tar'; + $pkgver = $pkginfo['package'] . '-' . $pkginfo['version']; + $dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext; + if (file_exists(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext) && + !is_file(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext)) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: cannot create tgz file "' . + getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext . '"'); + } + if ($pkgfile = $this->_packagefile->getPackageFile()) { + $pkgdir = dirname(realpath($pkgfile)); + $pkgfile = basename($pkgfile); + } else { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: package file object must ' . + 'be created from a real file'); + } + // {{{ Create the package file list + $filelist = array(); + $i = 0; + + foreach ($this->_packagefile->getFilelist() as $fname => $atts) { + $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; + if (!file_exists($file)) { + return PEAR::raiseError("File does not exist: $fname"); + } else { + $filelist[$i++] = $file; + if (!isset($atts['md5sum'])) { + $this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($file)); + } + $packager->log(2, "Adding file $fname"); + } + } + // }}} + $packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true); + if ($packagexml) { + $tar =& new Archive_Tar($dest_package, $compress); + $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors + // ----- Creates with the package.xml file + $ok = $tar->createModify(array($packagexml), '', $where); + if (PEAR::isError($ok)) { + return $ok; + } elseif (!$ok) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed'); + } + // ----- Add the content of the package + if (!$tar->addModify($filelist, $pkgver, $pkgdir)) { + return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed'); + } + return $dest_package; } } /** - * @param object PEAR_Error object + * @param string|null directory to place the package.xml in, or null for a temporary dir + * @param int one of the PEAR_VALIDATE_* constants + * @param string name of the generated file + * @param bool if true, then no analysis will be performed on role="php" files + * @return string|PEAR_Error path to the created file on success */ - function displayError($e) + function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml', + $nofilechecking = false) { - return $this->_displayLine($e->getMessage()); + if (!$this->_packagefile->validate($state, $nofilechecking)) { + return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: invalid package.xml', + null, null, null, $this->_packagefile->getValidationWarnings()); + } + if ($where === null) { + if (!($where = System::mktemp(array('-d')))) { + return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: mktemp failed'); + } + } elseif (!@System::mkDir(array('-p', $where))) { + return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: "' . $where . '" could' . + ' not be created'); + } + $newpkgfile = $where . DIRECTORY_SEPARATOR . $name; + $np = @fopen($newpkgfile, 'wb'); + if (!$np) { + return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: unable to save ' . + "$name as $newpkgfile"); + } + fwrite($np, $this->toXml($state, true)); + fclose($np); + return $newpkgfile; } /** - * @param object PEAR_Error object + * fix both XML encoding to be UTF8, and replace standard XML entities < > " & ' + * + * @param string $string + * @return string + * @access private */ - function displayFatalError($eobj) + function _fixXmlEncoding($string) { - $this->displayError($eobj); - if (class_exists('PEAR_Config')) { - $config = &PEAR_Config::singleton(); - if ($config->get('verbose') > 5) { - if (function_exists('debug_print_backtrace')) { - debug_print_backtrace(); - exit(1); - } + if (version_compare(phpversion(), '5.0.0', 'lt')) { + $string = utf8_encode($string); + } + return strtr($string, array( + '&' => '&', + '>' => '>', + '<' => '<', + '"' => '"', + '\'' => ''' )); + } - $raised = false; - foreach (debug_backtrace() as $i => $frame) { - if (!$raised) { - if (isset($frame['class']) - && strtolower($frame['class']) == 'pear' - && strtolower($frame['function']) == 'raiseerror' - ) { - $raised = true; - } else { - continue; + /** + * Return an XML document based on the package info (as returned + * by the PEAR_Common::infoFrom* methods). + * + * @return string XML data + */ + function toXml($state = PEAR_VALIDATE_NORMAL, $nofilevalidation = false) + { + $this->_packagefile->setDate(date('Y-m-d')); + if (!$this->_packagefile->validate($state, $nofilevalidation)) { + return false; + } + $pkginfo = $this->_packagefile->getArray(); + static $maint_map = array( + "handle" => "user", + "name" => "name", + "email" => "email", + "role" => "role", + ); + $ret = "\n"; + $ret .= "\n"; + $ret .= "\n" . +" $pkginfo[package]"; + if (isset($pkginfo['extends'])) { + $ret .= "\n$pkginfo[extends]"; + } + $ret .= + "\n ".$this->_fixXmlEncoding($pkginfo['summary'])."\n" . +" ".trim($this->_fixXmlEncoding($pkginfo['description']))."\n \n" . +" \n"; + foreach ($pkginfo['maintainers'] as $maint) { + $ret .= " \n"; + foreach ($maint_map as $idx => $elm) { + $ret .= " <$elm>"; + $ret .= $this->_fixXmlEncoding($maint[$idx]); + $ret .= "\n"; + } + $ret .= " \n"; + } + $ret .= " \n"; + $ret .= $this->_makeReleaseXml($pkginfo, false, $state); + if (isset($pkginfo['changelog']) && count($pkginfo['changelog']) > 0) { + $ret .= " \n"; + foreach ($pkginfo['changelog'] as $oldrelease) { + $ret .= $this->_makeReleaseXml($oldrelease, true); + } + $ret .= " \n"; + } + $ret .= "\n"; + return $ret; + } + + // }}} + // {{{ _makeReleaseXml() + + /** + * Generate part of an XML description with release information. + * + * @param array $pkginfo array with release information + * @param bool $changelog whether the result will be in a changelog element + * + * @return string XML data + * + * @access private + */ + function _makeReleaseXml($pkginfo, $changelog = false, $state = PEAR_VALIDATE_NORMAL) + { + // XXX QUOTE ENTITIES IN PCDATA, OR EMBED IN CDATA BLOCKS!! + $indent = $changelog ? " " : ""; + $ret = "$indent \n"; + if (!empty($pkginfo['version'])) { + $ret .= "$indent $pkginfo[version]\n"; + } + if (!empty($pkginfo['release_date'])) { + $ret .= "$indent $pkginfo[release_date]\n"; + } + if (!empty($pkginfo['release_license'])) { + $ret .= "$indent $pkginfo[release_license]\n"; + } + if (!empty($pkginfo['release_state'])) { + $ret .= "$indent $pkginfo[release_state]\n"; + } + if (!empty($pkginfo['release_notes'])) { + $ret .= "$indent ".trim($this->_fixXmlEncoding($pkginfo['release_notes'])) + ."\n$indent \n"; + } + if (!empty($pkginfo['release_warnings'])) { + $ret .= "$indent ".$this->_fixXmlEncoding($pkginfo['release_warnings'])."\n"; + } + if (isset($pkginfo['release_deps']) && sizeof($pkginfo['release_deps']) > 0) { + $ret .= "$indent \n"; + foreach ($pkginfo['release_deps'] as $dep) { + $ret .= "$indent _fixXmlEncoding($c['name']) . "\""; + if (isset($c['default'])) { + $ret .= " default=\"" . $this->_fixXmlEncoding($c['default']) . "\""; + } + $ret .= " prompt=\"" . $this->_fixXmlEncoding($c['prompt']) . "\""; + $ret .= "/>\n"; + } + $ret .= "$indent \n"; + } + if (isset($pkginfo['provides'])) { + foreach ($pkginfo['provides'] as $key => $what) { + $ret .= "$indent recursiveXmlFilelist($pkginfo['filelist']); + } else { + foreach ($pkginfo['filelist'] as $file => $fa) { + if (!isset($fa['role'])) { + $fa['role'] = ''; + } + $ret .= "$indent _fixXmlEncoding($fa['baseinstalldir']) . '"'; + } + if (isset($fa['md5sum'])) { + $ret .= " md5sum=\"$fa[md5sum]\""; + } + if (isset($fa['platform'])) { + $ret .= " platform=\"$fa[platform]\""; + } + if (!empty($fa['install-as'])) { + $ret .= ' install-as="' . + $this->_fixXmlEncoding($fa['install-as']) . '"'; + } + $ret .= ' name="' . $this->_fixXmlEncoding($file) . '"'; + if (empty($fa['replacements'])) { + $ret .= "/>\n"; + } else { + $ret .= ">\n"; + foreach ($fa['replacements'] as $r) { + $ret .= "$indent $v) { + $ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"'; + } + $ret .= "/>\n"; } + $ret .= "$indent \n"; } - - $frame['class'] = !isset($frame['class']) ? '' : $frame['class']; - $frame['type'] = !isset($frame['type']) ? '' : $frame['type']; - $frame['function'] = !isset($frame['function']) ? '' : $frame['function']; - $frame['line'] = !isset($frame['line']) ? '' : $frame['line']; - $this->_displayLine("#$i: $frame[class]$frame[type]$frame[function] $frame[line]"); } } + $ret .= "$indent \n"; } - - exit(1); + $ret .= "$indent \n"; + return $ret; } /** - * Instruct the runInstallScript method to skip a paramgroup that matches the - * id value passed in. - * - * This method is useful for dynamically configuring which sections of a post-install script - * will be run based on the user's setup, which is very useful for making flexible - * post-install scripts without losing the cross-Frontend ability to retrieve user input - * @param string + * @param array + * @access protected */ - function skipParamgroup($id) - { - $this->_skipSections[$id] = true; - } - - function runPostinstallScripts(&$scripts) + function recursiveXmlFilelist($list) { - foreach ($scripts as $i => $script) { - $this->runInstallScript($scripts[$i]->_params, $scripts[$i]->_obj); + $this->_dirs = array(); + foreach ($list as $file => $attributes) { + $this->_addDir($this->_dirs, explode('/', dirname($file)), $file, $attributes); } + return $this->_formatDir($this->_dirs); } /** - * @param array $xml contents of postinstallscript tag - * @param object $script post-installation script - * @param string install|upgrade + * @param array + * @param array + * @param string|null + * @param array|null + * @access private */ - function runInstallScript($xml, &$script) + function _addDir(&$dirs, $dir, $file = null, $attributes = null) { - $this->_skipSections = array(); - if (!is_array($xml) || !isset($xml['paramgroup'])) { - $script->run(array(), '_default'); + if ($dir == array() || $dir == array('.')) { + $dirs['files'][basename($file)] = $attributes; return; } - - $completedPhases = array(); - if (!isset($xml['paramgroup'][0])) { - $xml['paramgroup'] = array($xml['paramgroup']); + $curdir = array_shift($dir); + if (!isset($dirs['dirs'][$curdir])) { + $dirs['dirs'][$curdir] = array(); } + $this->_addDir($dirs['dirs'][$curdir], $dir, $file, $attributes); + } - foreach ($xml['paramgroup'] as $group) { - if (isset($this->_skipSections[$group['id']])) { - // the post-install script chose to skip this section dynamically - continue; - } - - if (isset($group['name'])) { - $paramname = explode('::', $group['name']); - if ($lastgroup['id'] != $paramname[0]) { - continue; - } - - $group['name'] = $paramname[1]; - if (!isset($answers)) { - return; - } - - if (isset($answers[$group['name']])) { - switch ($group['conditiontype']) { - case '=' : - if ($answers[$group['name']] != $group['value']) { - continue 2; - } - break; - case '!=' : - if ($answers[$group['name']] == $group['value']) { - continue 2; - } - break; - case 'preg_match' : - if (!@preg_match('/' . $group['value'] . '/', - $answers[$group['name']])) { - continue 2; - } - break; - default : - return; - } - } - } - - $lastgroup = $group; - if (isset($group['instructions'])) { - $this->_display($group['instructions']); + /** + * @param array + * @param string + * @param string + * @access private + */ + function _formatDir($dirs, $indent = '', $curdir = '') + { + $ret = ''; + if (!count($dirs)) { + return ''; + } + if (isset($dirs['dirs'])) { + uksort($dirs['dirs'], 'strnatcasecmp'); + foreach ($dirs['dirs'] as $dir => $contents) { + $usedir = "$curdir/$dir"; + $ret .= "$indent \n"; + $ret .= $this->_formatDir($contents, "$indent ", $usedir); + $ret .= "$indent \n"; } - - if (!isset($group['param'][0])) { - $group['param'] = array($group['param']); + } + if (isset($dirs['files'])) { + uksort($dirs['files'], 'strnatcasecmp'); + foreach ($dirs['files'] as $file => $attribs) { + $ret .= $this->_formatFile($file, $attribs, $indent); } + } + return $ret; + } - if (isset($group['param'])) { - if (method_exists($script, 'postProcessPrompts')) { - $prompts = $script->postProcessPrompts($group['param'], $group['id']); - if (!is_array($prompts) || count($prompts) != count($group['param'])) { - $this->outputData('postinstall', 'Error: post-install script did not ' . - 'return proper post-processed prompts'); - $prompts = $group['param']; - } else { - foreach ($prompts as $i => $var) { - if (!is_array($var) || !isset($var['prompt']) || - !isset($var['name']) || - ($var['name'] != $group['param'][$i]['name']) || - ($var['type'] != $group['param'][$i]['type']) - ) { - $this->outputData('postinstall', 'Error: post-install script ' . - 'modified the variables or prompts, severe security risk. ' . - 'Will instead use the defaults from the package.xml'); - $prompts = $group['param']; - } - } - } - - $answers = $this->confirmDialog($prompts); - } else { - $answers = $this->confirmDialog($group['param']); + /** + * @param string + * @param array + * @param string + * @access private + */ + function _formatFile($file, $attributes, $indent) + { + $ret = "$indent _fixXmlEncoding($attributes['baseinstalldir']) . '"'; + } + if (isset($attributes['md5sum'])) { + $ret .= " md5sum=\"$attributes[md5sum]\""; + } + if (isset($attributes['platform'])) { + $ret .= " platform=\"$attributes[platform]\""; + } + if (!empty($attributes['install-as'])) { + $ret .= ' install-as="' . + $this->_fixXmlEncoding($attributes['install-as']) . '"'; + } + $ret .= ' name="' . $this->_fixXmlEncoding($file) . '"'; + if (empty($attributes['replacements'])) { + $ret .= "/>\n"; + } else { + $ret .= ">\n"; + foreach ($attributes['replacements'] as $r) { + $ret .= "$indent $v) { + $ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"'; } + $ret .= "/>\n"; } + $ret .= "$indent \n"; + } + return $ret; + } - if ((isset($answers) && $answers) || !isset($group['param'])) { - if (!isset($answers)) { - $answers = array(); - } + // {{{ _unIndent() - array_unshift($completedPhases, $group['id']); - if (!$script->run($answers, $group['id'])) { - $script->run($completedPhases, '_undoOnError'); - return; - } - } else { - $script->run($completedPhases, '_undoOnError'); - return; + /** + * Unindent given string (?) + * + * @param string $str The string that has to be unindented. + * @return string + * @access private + */ + function _unIndent($str) + { + // remove leading newlines + $str = preg_replace('/^[\r\n]+/', '', $str); + // find whitespace at the beginning of the first line + $indent_len = strspn($str, " \t"); + $indent = substr($str, 0, $indent_len); + $data = ''; + // remove the same amount of whitespace from following lines + foreach (explode("\n", $str) as $line) { + if (substr($line, 0, $indent_len) == $indent) { + $data .= substr($line, $indent_len) . "\n"; } } + return $data; } /** - * Ask for user input, confirm the answers and continue until the user is satisfied - * @param array an array of arrays, format array('name' => 'paramname', 'prompt' => - * 'text to display', 'type' => 'string'[, default => 'default value']) * @return array */ - function confirmDialog($params) + function dependenciesToV2() { - $answers = $prompts = $types = array(); - foreach ($params as $param) { - $prompts[$param['name']] = $param['prompt']; - $types[$param['name']] = $param['type']; - $answers[$param['name']] = isset($param['default']) ? $param['default'] : ''; - } - - $tried = false; - do { - if ($tried) { - $i = 1; - foreach ($answers as $var => $value) { - if (!strlen($value)) { - echo $this->bold("* Enter an answer for #" . $i . ": ({$prompts[$var]})\n"); - } - $i++; - } - } - - $answers = $this->userDialog('', $prompts, $types, $answers); - $tried = true; - } while (is_array($answers) && count(array_filter($answers)) != count($prompts)); - - return $answers; + $arr = array(); + $this->_convertDependencies2_0($arr); + return $arr['dependencies']; } - function userDialog($command, $prompts, $types = array(), $defaults = array(), $screensize = 20) + /** + * Convert a package.xml version 1.0 into version 2.0 + * + * Note that this does a basic conversion, to allow more advanced + * features like bundles and multiple releases + * @param string the classname to instantiate and return. This must be + * PEAR_PackageFile_v2 or a descendant + * @param boolean if true, only valid, deterministic package.xml 1.0 as defined by the + * strictest parameters will be converted + * @return PEAR_PackageFile_v2|PEAR_Error + */ + function &toV2($class = 'PEAR_PackageFile_v2', $strict = false) { - if (!is_array($prompts)) { - return array(); + if ($strict) { + if (!$this->_packagefile->validate()) { + $a = PEAR::raiseError('invalid package.xml version 1.0 cannot be converted' . + ' to version 2.0', null, null, null, + $this->_packagefile->getValidationWarnings(true)); + return $a; + } } - $testprompts = array_keys($prompts); - $result = $defaults; - - reset($prompts); - if (count($prompts) === 1) { - foreach ($prompts as $key => $prompt) { - $type = $types[$key]; - $default = @$defaults[$key]; - print "$prompt "; - if ($default) { - print "[$default] "; - } - print ": "; - - $line = fgets(STDIN, 2048); - $result[$key] = ($default && trim($line) == '') ? $default : trim($line); + $arr = array( + 'attribs' => array( + 'version' => '2.0', + 'xmlns' => 'http://pear.php.net/dtd/package-2.0', + 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation' => "http://pear.php.net/dtd/tasks-1.0\n" . +"http://pear.php.net/dtd/tasks-1.0.xsd\n" . +"http://pear.php.net/dtd/package-2.0\n" . +'http://pear.php.net/dtd/package-2.0.xsd', + ), + 'name' => $this->_packagefile->getPackage(), + 'channel' => 'pear.php.net', + ); + $arr['summary'] = $this->_packagefile->getSummary(); + $arr['description'] = $this->_packagefile->getDescription(); + $maintainers = $this->_packagefile->getMaintainers(); + foreach ($maintainers as $maintainer) { + if ($maintainer['role'] != 'lead') { + continue; } - - return $result; + $new = array( + 'name' => $maintainer['name'], + 'user' => $maintainer['handle'], + 'email' => $maintainer['email'], + 'active' => 'yes', + ); + $arr['lead'][] = $new; } - $first_run = true; - while (true) { - $descLength = max(array_map('strlen', $prompts)); - $descFormat = "%-{$descLength}s"; - $last = count($prompts); + if (!isset($arr['lead'])) { // some people... you know? + $arr['lead'] = array( + 'name' => 'unknown', + 'user' => 'unknown', + 'email' => 'noleadmaintainer@example.com', + 'active' => 'no', + ); + } - $i = 0; - foreach ($prompts as $n => $var) { - $res = isset($result[$n]) ? $result[$n] : null; - printf("%2d. $descFormat : %s\n", ++$i, $prompts[$n], $res); - } - print "\n1-$last, 'all', 'abort', or Enter to continue: "; + if (count($arr['lead']) == 1) { + $arr['lead'] = $arr['lead'][0]; + } - $tmp = trim(fgets(STDIN, 1024)); - if (empty($tmp)) { - break; + foreach ($maintainers as $maintainer) { + if ($maintainer['role'] == 'lead') { + continue; } + $new = array( + 'name' => $maintainer['name'], + 'user' => $maintainer['handle'], + 'email' => $maintainer['email'], + 'active' => 'yes', + ); + $arr[$maintainer['role']][] = $new; + } - if ($tmp == 'abort') { - return false; - } + if (isset($arr['developer']) && count($arr['developer']) == 1) { + $arr['developer'] = $arr['developer'][0]; + } - if (isset($testprompts[(int)$tmp - 1])) { - $var = $testprompts[(int)$tmp - 1]; - $desc = $prompts[$var]; - $current = @$result[$var]; - print "$desc [$current] : "; - $tmp = trim(fgets(STDIN, 1024)); - if ($tmp !== '') { - $result[$var] = $tmp; - } - } elseif ($tmp == 'all') { - foreach ($prompts as $var => $desc) { - $current = $result[$var]; - print "$desc [$current] : "; - $tmp = trim(fgets(STDIN, 1024)); - if (trim($tmp) !== '') { - $result[$var] = trim($tmp); - } - } - } + if (isset($arr['contributor']) && count($arr['contributor']) == 1) { + $arr['contributor'] = $arr['contributor'][0]; + } - $first_run = false; + if (isset($arr['helper']) && count($arr['helper']) == 1) { + $arr['helper'] = $arr['helper'][0]; } - return $result; - } + $arr['date'] = $this->_packagefile->getDate(); + $arr['version'] = + array( + 'release' => $this->_packagefile->getVersion(), + 'api' => $this->_packagefile->getVersion(), + ); + $arr['stability'] = + array( + 'release' => $this->_packagefile->getState(), + 'api' => $this->_packagefile->getState(), + ); + $licensemap = + array( + 'php' => 'http://www.php.net/license', + 'php license' => 'http://www.php.net/license', + 'lgpl' => 'http://www.gnu.org/copyleft/lesser.html', + 'bsd' => 'http://www.opensource.org/licenses/bsd-license.php', + 'bsd style' => 'http://www.opensource.org/licenses/bsd-license.php', + 'bsd-style' => 'http://www.opensource.org/licenses/bsd-license.php', + 'mit' => 'http://www.opensource.org/licenses/mit-license.php', + 'gpl' => 'http://www.gnu.org/copyleft/gpl.html', + 'apache' => 'http://www.opensource.org/licenses/apache2.0.php' + ); - function userConfirm($prompt, $default = 'yes') - { - trigger_error("PEAR_Frontend_CLI::userConfirm not yet converted", E_USER_ERROR); - static $positives = array('y', 'yes', 'on', '1'); - static $negatives = array('n', 'no', 'off', '0'); - print "$this->lp$prompt [$default] : "; - $fp = fopen("php://stdin", "r"); - $line = fgets($fp, 2048); - fclose($fp); - $answer = strtolower(trim($line)); - if (empty($answer)) { - $answer = $default; - } - if (in_array($answer, $positives)) { - return true; - } - if (in_array($answer, $negatives)) { - return false; - } - if (in_array($default, $positives)) { - return true; + if (isset($licensemap[strtolower($this->_packagefile->getLicense())])) { + $arr['license'] = array( + 'attribs' => array('uri' => + $licensemap[strtolower($this->_packagefile->getLicense())]), + '_content' => $this->_packagefile->getLicense() + ); + } else { + // don't use bogus uri + $arr['license'] = $this->_packagefile->getLicense(); } - return false; - } - function outputData($data, $command = '_default') - { - switch ($command) { - case 'channel-info': - foreach ($data as $type => $section) { - if ($type == 'main') { - $section['data'] = array_values($section['data']); - } - - $this->outputData($section); - } - break; - case 'install': - case 'upgrade': - case 'upgrade-all': - if (isset($data['release_warnings'])) { - $this->_displayLine(''); - $this->_startTable(array( - 'border' => false, - 'caption' => 'Release Warnings' - )); - $this->_tableRow(array($data['release_warnings']), null, array(1 => array('wrap' => 55))); - $this->_endTable(); - $this->_displayLine(''); - } + $arr['notes'] = $this->_packagefile->getNotes(); + $temp = array(); + $arr['contents'] = $this->_convertFilelist2_0($temp); + $this->_convertDependencies2_0($arr); + $release = ($this->_packagefile->getConfigureOptions() || $this->_isExtension) ? + 'extsrcrelease' : 'phprelease'; + if ($release == 'extsrcrelease') { + $arr['channel'] = 'pecl.php.net'; + $arr['providesextension'] = $arr['name']; // assumption + } - $this->_displayLine($data['data']); - break; - case 'search': - $this->_startTable($data); - if (isset($data['headline']) && is_array($data['headline'])) { - $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55))); - } + $arr[$release] = array(); + if ($this->_packagefile->getConfigureOptions()) { + $arr[$release]['configureoption'] = $this->_packagefile->getConfigureOptions(); + foreach ($arr[$release]['configureoption'] as $i => $opt) { + $arr[$release]['configureoption'][$i] = array('attribs' => $opt); + } + if (count($arr[$release]['configureoption']) == 1) { + $arr[$release]['configureoption'] = $arr[$release]['configureoption'][0]; + } + } - foreach($data['data'] as $category) { - foreach($category as $pkg) { - $this->_tableRow($pkg, null, array(1 => array('wrap' => 55))); - } - } + $this->_convertRelease2_0($arr[$release], $temp); + if ($release == 'extsrcrelease' && count($arr[$release]) > 1) { + // multiple extsrcrelease tags added in PEAR 1.4.1 + $arr['dependencies']['required']['pearinstaller']['min'] = '1.4.1'; + } - $this->_endTable(); - break; - case 'list-all': - if (!isset($data['data'])) { - $this->_displayLine('No packages in channel'); - break; + if ($cl = $this->_packagefile->getChangelog()) { + foreach ($cl as $release) { + $rel = array(); + $rel['version'] = + array( + 'release' => $release['version'], + 'api' => $release['version'], + ); + if (!isset($release['release_state'])) { + $release['release_state'] = 'stable'; } - $this->_startTable($data); - if (isset($data['headline']) && is_array($data['headline'])) { - $this->_tableRow($data['headline'], array('bold' => true), array(1 => array('wrap' => 55))); + $rel['stability'] = + array( + 'release' => $release['release_state'], + 'api' => $release['release_state'], + ); + if (isset($release['release_date'])) { + $rel['date'] = $release['release_date']; + } else { + $rel['date'] = date('Y-m-d'); } - foreach($data['data'] as $category) { - foreach($category as $pkg) { - unset($pkg[4], $pkg[5]); - $this->_tableRow($pkg, null, array(1 => array('wrap' => 55))); + if (isset($release['release_license'])) { + if (isset($licensemap[strtolower($release['release_license'])])) { + $uri = $licensemap[strtolower($release['release_license'])]; + } else { + $uri = 'http://www.example.com'; } + $rel['license'] = array( + 'attribs' => array('uri' => $uri), + '_content' => $release['release_license'] + ); + } else { + $rel['license'] = $arr['license']; } - $this->_endTable(); - break; - case 'config-show': - $data['border'] = false; - $opts = array( - 0 => array('wrap' => 30), - 1 => array('wrap' => 20), - 2 => array('wrap' => 35) - ); - - $this->_startTable($data); - if (isset($data['headline']) && is_array($data['headline'])) { - $this->_tableRow($data['headline'], array('bold' => true), $opts); + if (!isset($release['release_notes'])) { + $release['release_notes'] = 'no release notes'; } - foreach ($data['data'] as $group) { - foreach ($group as $value) { - if ($value[2] == '') { - $value[2] = ""; - } + $rel['notes'] = $release['release_notes']; + $arr['changelog']['release'][] = $rel; + } + } - $this->_tableRow($value, null, $opts); - } - } + $ret = new $class; + $ret->setConfig($this->_packagefile->_config); + if (isset($this->_packagefile->_logger) && is_object($this->_packagefile->_logger)) { + $ret->setLogger($this->_packagefile->_logger); + } - $this->_endTable(); - break; - case 'remote-info': - $d = $data; - $data = array( - 'caption' => 'Package details:', - 'border' => false, - 'data' => array( - array("Latest", $data['stable']), - array("Installed", $data['installed']), - array("Package", $data['name']), - array("License", $data['license']), - array("Category", $data['category']), - array("Summary", $data['summary']), - array("Description", $data['description']), - ), - ); + $ret->fromArray($arr); + return $ret; + } - if (isset($d['deprecated']) && $d['deprecated']) { - $conf = &PEAR_Config::singleton(); - $reg = $conf->getRegistry(); - $name = $reg->parsedPackageNameToString($d['deprecated'], true); - $data['data'][] = array('Deprecated! use', $name); + /** + * @param array + * @param bool + * @access private + */ + function _convertDependencies2_0(&$release, $internal = false) + { + $peardep = array('pearinstaller' => + array('min' => '1.4.0b1')); // this is a lot safer + $required = $optional = array(); + $release['dependencies'] = array('required' => array()); + if ($this->_packagefile->hasDeps()) { + foreach ($this->_packagefile->getDeps() as $dep) { + if (!isset($dep['optional']) || $dep['optional'] == 'no') { + $required[] = $dep; + } else { + $optional[] = $dep; } - default: { - if (is_array($data)) { - $this->_startTable($data); - $count = count($data['data'][0]); - if ($count == 2) { - $opts = array(0 => array('wrap' => 25), - 1 => array('wrap' => 48) - ); - } elseif ($count == 3) { - $opts = array(0 => array('wrap' => 30), - 1 => array('wrap' => 20), - 2 => array('wrap' => 35) - ); + } + foreach (array('required', 'optional') as $arr) { + $deps = array(); + foreach ($$arr as $dep) { + // organize deps by dependency type and name + if (!isset($deps[$dep['type']])) { + $deps[$dep['type']] = array(); + } + if (isset($dep['name'])) { + $deps[$dep['type']][$dep['name']][] = $dep; } else { - $opts = null; + $deps[$dep['type']][] = $dep; } - if (isset($data['headline']) && is_array($data['headline'])) { - $this->_tableRow($data['headline'], - array('bold' => true), - $opts); + } + do { + if (isset($deps['php'])) { + $php = array(); + if (count($deps['php']) > 1) { + $php = $this->_processPhpDeps($deps['php']); + } else { + if (!isset($deps['php'][0])) { + list($key, $blah) = each ($deps['php']); // stupid buggy versions + $deps['php'] = array($blah[0]); + } + $php = $this->_processDep($deps['php'][0]); + if (!$php) { + break; // poor mans throw + } + } + $release['dependencies'][$arr]['php'] = $php; } - - foreach($data['data'] as $row) { - $this->_tableRow($row, null, $opts); + } while (false); + do { + if (isset($deps['pkg'])) { + $pkg = array(); + $pkg = $this->_processMultipleDepsName($deps['pkg']); + if (!$pkg) { + break; // poor mans throw + } + $release['dependencies'][$arr]['package'] = $pkg; } - $this->_endTable(); - } else { - $this->_displayLine($data); - } + } while (false); + do { + if (isset($deps['ext'])) { + $pkg = array(); + $pkg = $this->_processMultipleDepsName($deps['ext']); + $release['dependencies'][$arr]['extension'] = $pkg; + } + } while (false); + // skip sapi - it's not supported so nobody will have used it + // skip os - it's not supported in 1.0 } } - } - - function log($text, $append_crlf = true) - { - if ($append_crlf) { - return $this->_displayLine($text); + if (isset($release['dependencies']['required'])) { + $release['dependencies']['required'] = + array_merge($peardep, $release['dependencies']['required']); + } else { + $release['dependencies']['required'] = $peardep; } - - return $this->_display($text); - } - - function bold($text) - { - if (empty($this->term['bold'])) { - return strtoupper($text); + if (!isset($release['dependencies']['required']['php'])) { + $release['dependencies']['required']['php'] = + array('min' => '4.0.0'); } - - return $this->term['bold'] . $text . $this->term['normal']; - } - - function _displayHeading($title) - { - print $this->lp.$this->bold($title)."\n"; - print $this->lp.str_repeat("=", strlen($title))."\n"; - } - - function _startTable($params = array()) - { - $params['table_data'] = array(); - $params['widest'] = array(); // indexed by column - $params['highest'] = array(); // indexed by row - $params['ncols'] = 0; - $this->params = $params; + $order = array(); + $bewm = $release['dependencies']['required']; + $order['php'] = $bewm['php']; + $order['pearinstaller'] = $bewm['pearinstaller']; + isset($bewm['package']) ? $order['package'] = $bewm['package'] :0; + isset($bewm['extension']) ? $order['extension'] = $bewm['extension'] :0; + $release['dependencies']['required'] = $order; } - function _tableRow($columns, $rowparams = array(), $colparams = array()) + /** + * @param array + * @access private + */ + function _convertFilelist2_0(&$package) { - $highest = 1; - for ($i = 0; $i < count($columns); $i++) { - $col = &$columns[$i]; - if (isset($colparams[$i]) && !empty($colparams[$i]['wrap'])) { - $col = wordwrap($col, $colparams[$i]['wrap']); + $ret = array('dir' => + array( + 'attribs' => array('name' => '/'), + 'file' => array() + ) + ); + $package['platform'] = + $package['install-as'] = array(); + $this->_isExtension = false; + foreach ($this->_packagefile->getFilelist() as $name => $file) { + $file['name'] = $name; + if (isset($file['role']) && $file['role'] == 'src') { + $this->_isExtension = true; } - - if (strpos($col, "\n") !== false) { - $multiline = explode("\n", $col); - $w = 0; - foreach ($multiline as $n => $line) { - $len = strlen($line); - if ($len > $w) { - $w = $len; - } - } - $lines = count($multiline); + if (isset($file['replacements'])) { + $repl = $file['replacements']; + unset($file['replacements']); } else { - $w = strlen($col); + unset($repl); } - - if (isset($this->params['widest'][$i])) { - if ($w > $this->params['widest'][$i]) { - $this->params['widest'][$i] = $w; - } - } else { - $this->params['widest'][$i] = $w; + if (isset($file['install-as'])) { + $package['install-as'][$name] = $file['install-as']; + unset($file['install-as']); } - - $tmp = count_chars($columns[$i], 1); - // handle unix, mac and windows formats - $lines = (isset($tmp[10]) ? $tmp[10] : (isset($tmp[13]) ? $tmp[13] : 0)) + 1; - if ($lines > $highest) { - $highest = $lines; + if (isset($file['platform'])) { + $package['platform'][$name] = $file['platform']; + unset($file['platform']); } + $file = array('attribs' => $file); + if (isset($repl)) { + foreach ($repl as $replace ) { + $file['tasks:replace'][] = array('attribs' => $replace); + } + if (count($repl) == 1) { + $file['tasks:replace'] = $file['tasks:replace'][0]; + } + } + $ret['dir']['file'][] = $file; } - - if (count($columns) > $this->params['ncols']) { - $this->params['ncols'] = count($columns); - } - - $new_row = array( - 'data' => $columns, - 'height' => $highest, - 'rowparams' => $rowparams, - 'colparams' => $colparams, - ); - $this->params['table_data'][] = $new_row; + return $ret; } - function _endTable() + /** + * Post-process special files with install-as/platform attributes and + * make the release tag. + * + * This complex method follows this work-flow to create the release tags: + * + *
    +     * - if any install-as/platform exist, create a generic release and fill it with
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     * - create a release for each platform encountered and fill with
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     *   o  tags for 
    +     * 
    + * + * It does this by accessing the $package parameter, which contains an array with + * indices: + * + * - platform: mapping of file => OS the file should be installed on + * - install-as: mapping of file => installed name + * - osmap: mapping of OS => list of files that should be installed + * on that OS + * - notosmap: mapping of OS => list of files that should not be + * installed on that OS + * + * @param array + * @param array + * @access private + */ + function _convertRelease2_0(&$release, $package) { - extract($this->params); - if (!empty($caption)) { - $this->_displayHeading($caption); - } - - if (count($table_data) === 0) { - return; - } - - if (!isset($width)) { - $width = $widest; - } else { - for ($i = 0; $i < $ncols; $i++) { - if (!isset($width[$i])) { - $width[$i] = $widest[$i]; + //- if any install-as/platform exist, create a generic release and fill it with + if (count($package['platform']) || count($package['install-as'])) { + $generic = array(); + $genericIgnore = array(); + foreach ($package['install-as'] as $file => $as) { + //o tags for + if (!isset($package['platform'][$file])) { + $generic[] = $file; + continue; + } + //o tags for + if (isset($package['platform'][$file]) && + $package['platform'][$file]{0} == '!') { + $generic[] = $file; + continue; + } + //o tags for + if (isset($package['platform'][$file]) && + $package['platform'][$file]{0} != '!') { + $genericIgnore[] = $file; + continue; } } - } - - $border = false; - if (empty($border)) { - $cellstart = ''; - $cellend = ' '; - $rowend = ''; - $padrowend = false; - $borderline = ''; - } else { - $cellstart = '| '; - $cellend = ' '; - $rowend = '|'; - $padrowend = true; - $borderline = '+'; - foreach ($width as $w) { - $borderline .= str_repeat('-', $w + strlen($cellstart) + strlen($cellend) - 1); - $borderline .= '+'; - } - } - - if ($borderline) { - $this->_displayLine($borderline); - } - - for ($i = 0; $i < count($table_data); $i++) { - extract($table_data[$i]); - if (!is_array($rowparams)) { - $rowparams = array(); - } - - if (!is_array($colparams)) { - $colparams = array(); + foreach ($package['platform'] as $file => $platform) { + if (isset($package['install-as'][$file])) { + continue; + } + if ($platform{0} != '!') { + //o tags for + $genericIgnore[] = $file; + } } - - $rowlines = array(); - if ($height > 1) { - for ($c = 0; $c < count($data); $c++) { - $rowlines[$c] = preg_split('/(\r?\n|\r)/', $data[$c]); - if (count($rowlines[$c]) < $height) { - $rowlines[$c] = array_pad($rowlines[$c], $height, ''); + if (count($package['platform'])) { + $oses = $notplatform = $platform = array(); + foreach ($package['platform'] as $file => $os) { + // get a list of oses + if ($os{0} == '!') { + if (isset($oses[substr($os, 1)])) { + continue; + } + $oses[substr($os, 1)] = count($oses); + } else { + if (isset($oses[$os])) { + continue; + } + $oses[$os] = count($oses); + } + } + //- create a release for each platform encountered and fill with + foreach ($oses as $os => $releaseNum) { + $release[$releaseNum]['installconditions']['os']['name'] = $os; + $release[$releaseNum]['filelist'] = array('install' => array(), + 'ignore' => array()); + foreach ($package['install-as'] as $file => $as) { + //o tags for + if (!isset($package['platform'][$file])) { + $release[$releaseNum]['filelist']['install'][] = + array( + 'attribs' => array( + 'name' => $file, + 'as' => $as, + ), + ); + continue; + } + //o tags for + // + if (isset($package['platform'][$file]) && + $package['platform'][$file] == $os) { + $release[$releaseNum]['filelist']['install'][] = + array( + 'attribs' => array( + 'name' => $file, + 'as' => $as, + ), + ); + continue; + } + //o tags for + // + if (isset($package['platform'][$file]) && + $package['platform'][$file] != "!$os" && + $package['platform'][$file]{0} == '!') { + $release[$releaseNum]['filelist']['install'][] = + array( + 'attribs' => array( + 'name' => $file, + 'as' => $as, + ), + ); + continue; + } + //o tags for + // + if (isset($package['platform'][$file]) && + $package['platform'][$file] == "!$os") { + $release[$releaseNum]['filelist']['ignore'][] = + array( + 'attribs' => array( + 'name' => $file, + ), + ); + continue; + } + //o tags for + // + if (isset($package['platform'][$file]) && + $package['platform'][$file]{0} != '!' && + $package['platform'][$file] != $os) { + $release[$releaseNum]['filelist']['ignore'][] = + array( + 'attribs' => array( + 'name' => $file, + ), + ); + continue; + } + } + foreach ($package['platform'] as $file => $platform) { + if (isset($package['install-as'][$file])) { + continue; + } + //o tags for + if ($platform == "!$os") { + $release[$releaseNum]['filelist']['ignore'][] = + array( + 'attribs' => array( + 'name' => $file, + ), + ); + continue; + } + //o tags for + if ($platform{0} != '!' && $platform != $os) { + $release[$releaseNum]['filelist']['ignore'][] = + array( + 'attribs' => array( + 'name' => $file, + ), + ); + } + } + if (!count($release[$releaseNum]['filelist']['install'])) { + unset($release[$releaseNum]['filelist']['install']); + } + if (!count($release[$releaseNum]['filelist']['ignore'])) { + unset($release[$releaseNum]['filelist']['ignore']); } } - } else { - for ($c = 0; $c < count($data); $c++) { - $rowlines[$c] = array($data[$c]); - } - } - - for ($r = 0; $r < $height; $r++) { - $rowtext = ''; - for ($c = 0; $c < count($data); $c++) { - if (isset($colparams[$c])) { - $attribs = array_merge($rowparams, $colparams); - } else { - $attribs = $rowparams; + if (count($generic) || count($genericIgnore)) { + $release[count($oses)] = array(); + if (count($generic)) { + foreach ($generic as $file) { + if (isset($package['install-as'][$file])) { + $installas = $package['install-as'][$file]; + } else { + $installas = $file; + } + $release[count($oses)]['filelist']['install'][] = + array( + 'attribs' => array( + 'name' => $file, + 'as' => $installas, + ) + ); + } } - - $w = isset($width[$c]) ? $width[$c] : 0; - //$cell = $data[$c]; - $cell = $rowlines[$c][$r]; - $l = strlen($cell); - if ($l > $w) { - $cell = substr($cell, 0, $w); + if (count($genericIgnore)) { + foreach ($genericIgnore as $file) { + $release[count($oses)]['filelist']['ignore'][] = + array( + 'attribs' => array( + 'name' => $file, + ) + ); + } } - - if (isset($attribs['bold'])) { - $cell = $this->bold($cell); + } + // cleanup + foreach ($release as $i => $rel) { + if (isset($rel['filelist']['install']) && + count($rel['filelist']['install']) == 1) { + $release[$i]['filelist']['install'] = + $release[$i]['filelist']['install'][0]; } - - if ($l < $w) { - // not using str_pad here because we may - // add bold escape characters to $cell - $cell .= str_repeat(' ', $w - $l); + if (isset($rel['filelist']['ignore']) && + count($rel['filelist']['ignore']) == 1) { + $release[$i]['filelist']['ignore'] = + $release[$i]['filelist']['ignore'][0]; } - - $rowtext .= $cellstart . $cell . $cellend; } - - if (!$border) { - $rowtext = rtrim($rowtext); + if (count($release) == 1) { + $release = $release[0]; + } + } else { + // no platform atts, but some install-as atts + foreach ($package['install-as'] as $file => $value) { + $release['filelist']['install'][] = + array( + 'attribs' => array( + 'name' => $file, + 'as' => $value + ) + ); + } + if (count($release['filelist']['install']) == 1) { + $release['filelist']['install'] = $release['filelist']['install'][0]; } - - $rowtext .= $rowend; - $this->_displayLine($rowtext); } } - - if ($borderline) { - $this->_displayLine($borderline); - } - } - - function _displayLine($text) - { - print "$this->lp$text\n"; - } - - function _display($text) - { - print $text; - } -} - * @author Tomas V.V. Cox - * @author Martin Jansen - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Installer.php,v 1.259 2009/04/09 00:55:07 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ - -/** - * Used for installation groups in package.xml 2.0 and platform exceptions - */ -require_once 'phar://install-pear-nozlib.phar/' . 'OS/Guess.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Downloader.php'; - -define('PEAR_INSTALLER_NOBINARY', -240); -/** - * Administration class used to install PEAR packages and maintain the - * installed package database. - * - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Tomas V.V. Cox - * @author Martin Jansen - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 0.1 - */ -class PEAR_Installer extends PEAR_Downloader -{ - // {{{ properties - - /** name of the package directory, for example Foo-1.0 - * @var string - */ - var $pkgdir; - - /** directory where PHP code files go - * @var string - */ - var $phpdir; - - /** directory where PHP extension files go - * @var string - */ - var $extdir; - - /** directory where documentation goes - * @var string - */ - var $docdir; - - /** installation root directory (ala PHP's INSTALL_ROOT or - * automake's DESTDIR - * @var string - */ - var $installroot = ''; - - /** debug level - * @var int - */ - var $debug = 1; - - /** temporary directory - * @var string - */ - var $tmpdir; - - /** - * PEAR_Registry object used by the installer - * @var PEAR_Registry - */ - var $registry; - - /** - * array of PEAR_Downloader_Packages - * @var array - */ - var $_downloadedPackages; - - /** List of file transactions queued for an install/upgrade/uninstall. - * - * Format: - * array( - * 0 => array("rename => array("from-file", "to-file")), - * 1 => array("delete" => array("file-to-delete")), - * ... - * ) - * - * @var array - */ - var $file_operations = array(); - - // }}} - - // {{{ constructor - - /** - * PEAR_Installer constructor. - * - * @param object $ui user interface object (instance of PEAR_Frontend_*) - * - * @access public - */ - function PEAR_Installer(&$ui) - { - parent::PEAR_Common(); - $this->setFrontendObject($ui); - $this->debug = $this->config->get('verbose'); - } - - function setOptions($options) - { - $this->_options = $options; - } - - function setConfig(&$config) - { - $this->config = &$config; - $this->_registry = &$config->getRegistry(); - } - - // }}} - - function _removeBackups($files) - { - foreach ($files as $path) { - $this->addFileOperation('removebackup', array($path)); - } } - // {{{ _deletePackageFiles() - /** - * Delete a package's installed files, does not remove empty directories. - * - * @param string package name - * @param string channel name - * @param bool if true, then files are backed up first - * @return bool TRUE on success, or a PEAR error on failure - * @access protected + * @param array + * @return array + * @access private */ - function _deletePackageFiles($package, $channel = false, $backup = false) + function _processDep($dep) { - if (!$channel) { - $channel = 'pear.php.net'; - } - - if (!strlen($package)) { - return $this->raiseError("No package to uninstall given"); - } - - if (strtolower($package) == 'pear' && $channel == 'pear.php.net') { - // to avoid race conditions, include all possible needed files - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Common.php'; - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Replace.php'; - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Unixeol.php'; - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Windowseol.php'; - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2.php'; - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/Generator/v1.php'; - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/Generator/v2.php'; - } - - $filelist = $this->_registry->packageInfo($package, 'filelist', $channel); - if ($filelist == null) { - return $this->raiseError("$channel/$package not installed"); - } - - $ret = array(); - foreach ($filelist as $file => $props) { - if (empty($props['installed_as'])) { - continue; + if ($dep['type'] == 'php') { + if ($dep['rel'] == 'has') { + // come on - everyone has php! + return false; } - - $path = $props['installed_as']; - if ($backup) { - $this->addFileOperation('backup', array($path)); - $ret[] = $path; + } + $php = array(); + if ($dep['type'] != 'php') { + $php['name'] = $dep['name']; + if ($dep['type'] == 'pkg') { + $php['channel'] = 'pear.php.net'; } - - $this->addFileOperation('delete', array($path)); } - - if ($backup) { - return $ret; + switch ($dep['rel']) { + case 'gt' : + $php['min'] = $dep['version']; + $php['exclude'] = $dep['version']; + break; + case 'ge' : + if (!isset($dep['version'])) { + if ($dep['type'] == 'php') { + if (isset($dep['name'])) { + $dep['version'] = $dep['name']; + } + } + } + $php['min'] = $dep['version']; + break; + case 'lt' : + $php['max'] = $dep['version']; + $php['exclude'] = $dep['version']; + break; + case 'le' : + $php['max'] = $dep['version']; + break; + case 'eq' : + $php['min'] = $dep['version']; + $php['max'] = $dep['version']; + break; + case 'ne' : + $php['exclude'] = $dep['version']; + break; + case 'not' : + $php['conflicts'] = 'yes'; + break; } - - return true; + return $php; } - // }}} - // {{{ _installFile() - /** - * @param string filename - * @param array attributes from tag in package.xml - * @param string path to install the file in - * @param array options from command-line - * @access private + * @param array + * @return array */ - function _installFile($file, $atts, $tmp_path, $options) + function _processPhpDeps($deps) { - // {{{ return if this file is meant for another platform - static $os; - if (!isset($this->_registry)) { - $this->_registry = &$this->config->getRegistry(); + $test = array(); + foreach ($deps as $dep) { + $test[] = $this->_processDep($dep); } - - if (isset($atts['platform'])) { - if (empty($os)) { - $os = new OS_Guess(); + $min = array(); + $max = array(); + foreach ($test as $dep) { + if (!$dep) { + continue; } - - if (strlen($atts['platform']) && $atts['platform']{0} == '!') { - $negate = true; - $platform = substr($atts['platform'], 1); - } else { - $negate = false; - $platform = $atts['platform']; + if (isset($dep['min'])) { + $min[$dep['min']] = count($min); } - - if ((bool) $os->matchSignature($platform) === $negate) { - $this->log(3, "skipped $file (meant for $atts[platform], we are ".$os->getSignature().")"); - return PEAR_INSTALLER_SKIPPED; + if (isset($dep['max'])) { + $max[$dep['max']] = count($max); } } - // }}} - - $channel = $this->pkginfo->getChannel(); - // {{{ assemble the destination paths - switch ($atts['role']) { - case 'src': - case 'extsrc': - $this->source_files++; - return; - case 'doc': - case 'data': - case 'test': - $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel) . - DIRECTORY_SEPARATOR . $this->pkginfo->getPackage(); - unset($atts['baseinstalldir']); - break; - case 'ext': - case 'php': - $dest_dir = $this->config->get($atts['role'] . '_dir', null, $channel); - break; - case 'script': - $dest_dir = $this->config->get('bin_dir', null, $channel); - break; - default: - return $this->raiseError("Invalid role `$atts[role]' for file $file"); - } - - $save_destdir = $dest_dir; - if (!empty($atts['baseinstalldir'])) { - $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; + if (count($min) > 0) { + uksort($min, 'version_compare'); } - - if (dirname($file) != '.' && empty($atts['install-as'])) { - $dest_dir .= DIRECTORY_SEPARATOR . dirname($file); + if (count($max) > 0) { + uksort($max, 'version_compare'); } - - if (empty($atts['install-as'])) { - $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); + if (count($min)) { + // get the highest minimum + $min = array_pop($a = array_flip($min)); } else { - $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as']; + $min = false; } - $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file; - - // Clean up the DIRECTORY_SEPARATOR mess - $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; - list($dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), - array(DIRECTORY_SEPARATOR, - DIRECTORY_SEPARATOR, - DIRECTORY_SEPARATOR), - array($dest_file, $orig_file)); - $final_dest_file = $installed_as = $dest_file; - if (isset($this->_options['packagingroot'])) { - $installedas_dest_dir = dirname($final_dest_file); - $installedas_dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); - $final_dest_file = $this->_prependPath($final_dest_file, $this->_options['packagingroot']); + if (count($max)) { + // get the lowest maximum + $max = array_shift($a = array_flip($max)); } else { - $installedas_dest_dir = dirname($final_dest_file); - $installedas_dest_file = $installedas_dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); + $max = false; + } + if ($min) { + $php['min'] = $min; + } + if ($max) { + $php['max'] = $max; } - - $dest_dir = dirname($final_dest_file); - $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); - if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { - return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); + $exclude = array(); + foreach ($test as $dep) { + if (!isset($dep['exclude'])) { + continue; + } + $exclude[] = $dep['exclude']; } - // }}} + if (count($exclude)) { + $php['exclude'] = $exclude; + } + return $php; + } - if (empty($this->_options['register-only']) && - (!file_exists($dest_dir) || !is_dir($dest_dir))) { - if (!$this->mkDirHier($dest_dir)) { - return $this->raiseError("failed to mkdir $dest_dir", - PEAR_INSTALLER_FAILED); + /** + * process multiple dependencies that have a name, like package deps + * @param array + * @return array + * @access private + */ + function _processMultipleDepsName($deps) + { + $ret = $tests = array(); + foreach ($deps as $name => $dep) { + foreach ($dep as $d) { + $tests[$name][] = $this->_processDep($d); } - $this->log(3, "+ mkdir $dest_dir"); } - // pretty much nothing happens if we are only registering the install - if (empty($this->_options['register-only'])) { - if (empty($atts['replacements'])) { - if (!file_exists($orig_file)) { - return $this->raiseError("file $orig_file does not exist", - PEAR_INSTALLER_FAILED); - } - - if (!@copy($orig_file, $dest_file)) { - return $this->raiseError("failed to write $dest_file: $php_errormsg", - PEAR_INSTALLER_FAILED); - } - - $this->log(3, "+ cp $orig_file $dest_file"); - if (isset($atts['md5sum'])) { - $md5sum = md5_file($dest_file); - } - } else { - // {{{ file with replacements - if (!file_exists($orig_file)) { - return $this->raiseError("file does not exist", - PEAR_INSTALLER_FAILED); - } - - $contents = file_get_contents($orig_file); - if ($contents === false) { - $contents = ''; - } - - if (isset($atts['md5sum'])) { - $md5sum = md5($contents); + foreach ($tests as $name => $test) { + $max = $min = $php = array(); + $php['name'] = $name; + foreach ($test as $dep) { + if (!$dep) { + continue; } - - $subst_from = $subst_to = array(); - foreach ($atts['replacements'] as $a) { - $to = ''; - if ($a['type'] == 'php-const') { - if (preg_match('/^[a-z0-9_]+\\z/i', $a['to'])) { - eval("\$to = $a[to];"); - } else { - if (!isset($options['soft'])) { - $this->log(0, "invalid php-const replacement: $a[to]"); - } - continue; - } - } elseif ($a['type'] == 'pear-config') { - if ($a['to'] == 'master_server') { - $chan = $this->_registry->getChannel($channel); - if (!PEAR::isError($chan)) { - $to = $chan->getServer(); - } else { - $to = $this->config->get($a['to'], null, $channel); - } - } else { - $to = $this->config->get($a['to'], null, $channel); - } - if (is_null($to)) { - if (!isset($options['soft'])) { - $this->log(0, "invalid pear-config replacement: $a[to]"); - } - continue; - } - } elseif ($a['type'] == 'package-info') { - if ($t = $this->pkginfo->packageInfo($a['to'])) { - $to = $t; - } else { - if (!isset($options['soft'])) { - $this->log(0, "invalid package-info replacement: $a[to]"); - } - continue; - } - } - if (!is_null($to)) { - $subst_from[] = $a['from']; - $subst_to[] = $to; - } + if (isset($dep['channel'])) { + $php['channel'] = 'pear.php.net'; } - - $this->log(3, "doing ".sizeof($subst_from)." substitution(s) for $final_dest_file"); - if (sizeof($subst_from)) { - $contents = str_replace($subst_from, $subst_to, $contents); + if (isset($dep['conflicts']) && $dep['conflicts'] == 'yes') { + $php['conflicts'] = 'yes'; } - - $wp = @fopen($dest_file, "wb"); - if (!is_resource($wp)) { - return $this->raiseError("failed to create $dest_file: $php_errormsg", - PEAR_INSTALLER_FAILED); + if (isset($dep['min'])) { + $min[$dep['min']] = count($min); } - - if (@fwrite($wp, $contents) === false) { - return $this->raiseError("failed writing to $dest_file: $php_errormsg", - PEAR_INSTALLER_FAILED); + if (isset($dep['max'])) { + $max[$dep['max']] = count($max); } - - fclose($wp); - // }}} } - - // {{{ check the md5 - if (isset($md5sum)) { - if (strtolower($md5sum) === strtolower($atts['md5sum'])) { - $this->log(2, "md5sum ok: $final_dest_file"); - } else { - if (empty($options['force'])) { - // delete the file - if (file_exists($dest_file)) { - unlink($dest_file); - } - - if (!isset($options['ignore-errors'])) { - return $this->raiseError("bad md5sum for file $final_dest_file", - PEAR_INSTALLER_FAILED); - } - - if (!isset($options['soft'])) { - $this->log(0, "warning : bad md5sum for file $final_dest_file"); - } - } else { - if (!isset($options['soft'])) { - $this->log(0, "warning : bad md5sum for file $final_dest_file"); - } - } - } + if (count($min) > 0) { + uksort($min, 'version_compare'); } - // }}} - // {{{ set file permissions - if (!OS_WINDOWS) { - if ($atts['role'] == 'script') { - $mode = 0777 & ~(int)octdec($this->config->get('umask')); - $this->log(3, "+ chmod +x $dest_file"); - } else { - $mode = 0666 & ~(int)octdec($this->config->get('umask')); - } - - if ($atts['role'] != 'src') { - $this->addFileOperation("chmod", array($mode, $dest_file)); - if (!@chmod($dest_file, $mode)) { - if (!isset($options['soft'])) { - $this->log(0, "failed to change mode of $dest_file: $php_errormsg"); - } - } - } + if (count($max) > 0) { + uksort($max, 'version_compare'); } - // }}} - - if ($atts['role'] == 'src') { - rename($dest_file, $final_dest_file); - $this->log(2, "renamed source file $dest_file to $final_dest_file"); + if (count($min)) { + // get the highest minimum + $min = array_pop($a = array_flip($min)); } else { - $this->addFileOperation("rename", array($dest_file, $final_dest_file, - $atts['role'] == 'ext')); + $min = false; + } + if (count($max)) { + // get the lowest maximum + $max = array_shift($a = array_flip($max)); + } else { + $max = false; + } + if ($min) { + $php['min'] = $min; + } + if ($max) { + $php['max'] = $max; + } + $exclude = array(); + foreach ($test as $dep) { + if (!isset($dep['exclude'])) { + continue; + } + $exclude[] = $dep['exclude']; + } + if (count($exclude)) { + $php['exclude'] = $exclude; } + $ret[] = $php; } + return $ret; + } +} +?> + * @author Stephan Schmidt (original XML_Serializer code) + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: v2.php 278907 2009-04-17 21:10:04Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * file/dir manipulation routines + */ +require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'XML/Util.php'; - // Store the full path where the file was installed for easy unistall - if ($atts['role'] != 'script') { - $loc = $this->config->get($atts['role'] . '_dir'); - } else { - $loc = $this->config->get('bin_dir'); - } +/** + * This class converts a PEAR_PackageFile_v2 object into any output format. + * + * Supported output formats include array, XML string (using S. Schmidt's + * XML_Serializer, slightly customized) + * @category pear + * @package PEAR + * @author Greg Beaver + * @author Stephan Schmidt (original XML_Serializer code) + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_Generator_v2 +{ + /** + * default options for the serialization + * @access private + * @var array $_defaultOptions + */ + var $_defaultOptions = array( + 'indent' => ' ', // string used for indentation + 'linebreak' => "\n", // string used for newlines + 'typeHints' => false, // automatically add type hin attributes + 'addDecl' => true, // add an XML declaration + 'defaultTagName' => 'XML_Serializer_Tag', // tag used for indexed arrays or invalid names + 'classAsTagName' => false, // use classname for objects in indexed arrays + 'keyAttribute' => '_originalKey', // attribute where original key is stored + 'typeAttribute' => '_type', // attribute for type (only if typeHints => true) + 'classAttribute' => '_class', // attribute for class of objects (only if typeHints => true) + 'scalarAsAttributes' => false, // scalar values (strings, ints,..) will be serialized as attribute + 'prependAttributes' => '', // prepend string for attributes + 'indentAttributes' => false, // indent the attributes, if set to '_auto', it will indent attributes so they all start at the same column + 'mode' => 'simplexml', // use 'simplexml' to use parent name as tagname if transforming an indexed array + 'addDoctype' => false, // add a doctype declaration + 'doctype' => null, // supply a string or an array with id and uri ({@see XML_Util::getDoctypeDeclaration()} + 'rootName' => 'package', // name of the root tag + 'rootAttributes' => array( + 'version' => '2.0', + 'xmlns' => 'http://pear.php.net/dtd/package-2.0', + 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', + 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', + 'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 +http://pear.php.net/dtd/tasks-1.0.xsd +http://pear.php.net/dtd/package-2.0 +http://pear.php.net/dtd/package-2.0.xsd', + ), // attributes of the root tag + 'attributesArray' => 'attribs', // all values in this key will be treated as attributes + 'contentName' => '_content', // this value will be used directly as content, instead of creating a new tag, may only be used in conjuction with attributesArray + 'beautifyFilelist' => false, + 'encoding' => 'UTF-8', + ); - if ($atts['role'] != 'src') { - $this->addFileOperation("installed_as", array($file, $installed_as, - $loc, - dirname(substr($installedas_dest_file, strlen($loc))))); - } + /** + * options for the serialization + * @access private + * @var array $options + */ + var $options = array(); - //$this->log(2, "installed: $dest_file"); - return PEAR_INSTALLER_OK; + /** + * current tag depth + * @var integer $_tagDepth + */ + var $_tagDepth = 0; + + /** + * serilialized representation of the data + * @var string $_serializedData + */ + var $_serializedData = null; + /** + * @var PEAR_PackageFile_v2 + */ + var $_packagefile; + /** + * @param PEAR_PackageFile_v2 + */ + function PEAR_PackageFile_Generator_v2(&$packagefile) + { + $this->_packagefile = &$packagefile; + if (isset($this->_packagefile->encoding)) { + $this->_defaultOptions['encoding'] = $this->_packagefile->encoding; + } } - // }}} - // {{{ _installFile2() + /** + * @return string + */ + function getPackagerVersion() + { + return '1.9.0'; + } /** - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @param string filename - * @param array attributes from tag in package.xml - * @param string path to install the file in - * @param array options from command-line - * @access private + * @param PEAR_Packager + * @param bool generate a .tgz or a .tar + * @param string|null temporary directory to package in */ - function _installFile2(&$pkg, $file, &$real_atts, $tmp_path, $options) + function toTgz(&$packager, $compress = true, $where = null) { - $atts = $real_atts; - if (!isset($this->_registry)) { - $this->_registry = &$this->config->getRegistry(); - } + $a = null; + return $this->toTgz2($packager, $a, $compress, $where); + } - $channel = $pkg->getChannel(); - // {{{ assemble the destination paths - if (!in_array($atts['attribs']['role'], - PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { - return $this->raiseError('Invalid role `' . $atts['attribs']['role'] . - "' for file $file"); + /** + * Package up both a package.xml and package2.xml for the same release + * @param PEAR_Packager + * @param PEAR_PackageFile_v1 + * @param bool generate a .tgz or a .tar + * @param string|null temporary directory to package in + */ + function toTgz2(&$packager, &$pf1, $compress = true, $where = null) + { + require_once 'phar://install-pear-nozlib.phar/' . 'Archive/Tar.php'; + if (!$this->_packagefile->isEquivalent($pf1)) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . + basename($pf1->getPackageFile()) . + '" is not equivalent to "' . basename($this->_packagefile->getPackageFile()) + . '"'); } - $role = &PEAR_Installer_Role::factory($pkg, $atts['attribs']['role'], $this->config); - $err = $role->setup($this, $pkg, $atts['attribs'], $file); - if (PEAR::isError($err)) { - return $err; + if ($where === null) { + if (!($where = System::mktemp(array('-d')))) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: mktemp failed'); + } + } elseif (!@System::mkDir(array('-p', $where))) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . $where . '" could' . + ' not be created'); } - if (!$role->isInstallable()) { - return; + $file = $where . DIRECTORY_SEPARATOR . 'package.xml'; + if (file_exists($file) && !is_file($file)) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: unable to save package.xml as' . + ' "' . $file .'"'); } - $info = $role->processInstallation($pkg, $atts['attribs'], $file, $tmp_path); - if (PEAR::isError($info)) { - return $info; + if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: invalid package.xml'); } - list($save_destdir, $dest_dir, $dest_file, $orig_file) = $info; - if (preg_match('~/\.\.(/|\\z)|^\.\./~', str_replace('\\', '/', $dest_file))) { - return $this->raiseError("SECURITY ERROR: file $file (installed to $dest_file) contains parent directory reference ..", PEAR_INSTALLER_FAILED); + $ext = $compress ? '.tgz' : '.tar'; + $pkgver = $this->_packagefile->getPackage() . '-' . $this->_packagefile->getVersion(); + $dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext; + if (file_exists($dest_package) && !is_file($dest_package)) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: cannot create tgz file "' . + $dest_package . '"'); } - $final_dest_file = $installed_as = $dest_file; - if (isset($this->_options['packagingroot'])) { - $final_dest_file = $this->_prependPath($final_dest_file, - $this->_options['packagingroot']); + $pkgfile = $this->_packagefile->getPackageFile(); + if (!$pkgfile) { + return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: package file object must ' . + 'be created from a real file'); } - $dest_dir = dirname($final_dest_file); - $dest_file = $dest_dir . DIRECTORY_SEPARATOR . '.tmp' . basename($final_dest_file); - // }}} + $pkgdir = dirname(realpath($pkgfile)); + $pkgfile = basename($pkgfile); - if (empty($this->_options['register-only'])) { - if (!file_exists($dest_dir) || !is_dir($dest_dir)) { - if (!$this->mkDirHier($dest_dir)) { - return $this->raiseError("failed to mkdir $dest_dir", - PEAR_INSTALLER_FAILED); - } - $this->log(3, "+ mkdir $dest_dir"); + // {{{ Create the package file list + $filelist = array(); + $i = 0; + $this->_packagefile->flattenFilelist(); + $contents = $this->_packagefile->getContents(); + if (isset($contents['bundledpackage'])) { // bundles of packages + $contents = $contents['bundledpackage']; + if (!isset($contents[0])) { + $contents = array($contents); } - } - $attribs = $atts['attribs']; - unset($atts['attribs']); - // pretty much nothing happens if we are only registering the install - if (empty($this->_options['register-only'])) { - if (!count($atts)) { // no tasks - if (!file_exists($orig_file)) { - return $this->raiseError("file $orig_file does not exist", - PEAR_INSTALLER_FAILED); - } - - if (!@copy($orig_file, $dest_file)) { - return $this->raiseError("failed to write $dest_file: $php_errormsg", - PEAR_INSTALLER_FAILED); - } - - $this->log(3, "+ cp $orig_file $dest_file"); - if (isset($attribs['md5sum'])) { - $md5sum = md5_file($dest_file); - } - } else { // file with tasks - if (!file_exists($orig_file)) { - return $this->raiseError("file $orig_file does not exist", - PEAR_INSTALLER_FAILED); + $packageDir = $where; + foreach ($contents as $i => $package) { + $fname = $package; + $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; + if (!file_exists($file)) { + return $packager->raiseError("File does not exist: $fname"); } - $contents = file_get_contents($orig_file); - if ($contents === false) { - $contents = ''; - } + $tfile = $packageDir . DIRECTORY_SEPARATOR . $fname; + System::mkdir(array('-p', dirname($tfile))); + copy($file, $tfile); + $filelist[$i++] = $tfile; + $packager->log(2, "Adding package $fname"); + } + } else { // normal packages + $contents = $contents['dir']['file']; + if (!isset($contents[0])) { + $contents = array($contents); + } - if (isset($attribs['md5sum'])) { - $md5sum = md5($contents); + $packageDir = $where; + foreach ($contents as $i => $file) { + $fname = $file['attribs']['name']; + $atts = $file['attribs']; + $orig = $file; + $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; + if (!file_exists($file)) { + return $packager->raiseError("File does not exist: $fname"); } - foreach ($atts as $tag => $raw) { - $tag = str_replace(array($pkg->getTasksNs() . ':', '-'), array('', '_'), $tag); - $task = "PEAR_Task_$tag"; - $task = &new $task($this->config, $this, PEAR_TASK_INSTALL); - if (!$task->isScript()) { // scripts are only handled after installation - $task->init($raw, $attribs, $pkg->getLastInstalledVersion()); - $res = $task->startSession($pkg, $contents, $final_dest_file); - if ($res === false) { - continue; // skip this file + $origperms = fileperms($file); + $tfile = $packageDir . DIRECTORY_SEPARATOR . $fname; + unset($orig['attribs']); + if (count($orig)) { // file with tasks + // run any package-time tasks + $contents = file_get_contents($file); + foreach ($orig as $tag => $raw) { + $tag = str_replace( + array($this->_packagefile->getTasksNs() . ':', '-'), + array('', '_'), $tag); + $task = "PEAR_Task_$tag"; + $task = &new $task($this->_packagefile->_config, + $this->_packagefile->_logger, + PEAR_TASK_PACKAGE); + $task->init($raw, $atts, null); + $res = $task->startSession($this->_packagefile, $contents, $tfile); + if (!$res) { + continue; // skip this task } if (PEAR::isError($res)) { @@ -70622,1894 +75133,1223 @@ class PEAR_Installer extends PEAR_Downloader } $contents = $res; // save changes + System::mkdir(array('-p', dirname($tfile))); + $wp = fopen($tfile, "wb"); + fwrite($wp, $contents); + fclose($wp); } + } - $wp = @fopen($dest_file, "wb"); - if (!is_resource($wp)) { - return $this->raiseError("failed to create $dest_file: $php_errormsg", - PEAR_INSTALLER_FAILED); - } - - if (fwrite($wp, $contents) === false) { - return $this->raiseError("failed writing to $dest_file: $php_errormsg", - PEAR_INSTALLER_FAILED); - } - - fclose($wp); + if (!file_exists($tfile)) { + System::mkdir(array('-p', dirname($tfile))); + copy($file, $tfile); } - } - // {{{ check the md5 - if (isset($md5sum)) { - // Make sure the original md5 sum matches with expected - if (strtolower($md5sum) === strtolower($attribs['md5sum'])) { - $this->log(2, "md5sum ok: $final_dest_file"); + chmod($tfile, $origperms); + $filelist[$i++] = $tfile; + $this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($tfile), $i - 1); + $packager->log(2, "Adding file $fname"); + } + } + // }}} - if (isset($contents)) { - // set md5 sum based on $content in case any tasks were run. - $real_atts['attribs']['md5sum'] = md5($contents); - } - } else { - if (empty($options['force'])) { - // delete the file - if (file_exists($dest_file)) { - unlink($dest_file); - } + $name = $pf1 !== null ? 'package2.xml' : 'package.xml'; + $packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, $name); + if ($packagexml) { + $tar =& new Archive_Tar($dest_package, $compress); + $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors + // ----- Creates with the package.xml file + $ok = $tar->createModify(array($packagexml), '', $where); + if (PEAR::isError($ok)) { + return $packager->raiseError($ok); + } elseif (!$ok) { + return $packager->raiseError('PEAR_Packagefile_v2::toTgz(): adding ' . $name . + ' failed'); + } - if (!isset($options['ignore-errors'])) { - return $this->raiseError("bad md5sum for file $final_dest_file", - PEAR_INSTALLER_FAILED); - } + // ----- Add the content of the package + if (!$tar->addModify($filelist, $pkgver, $where)) { + return $packager->raiseError( + 'PEAR_Packagefile_v2::toTgz(): tarball creation failed'); + } - if (!isset($options['soft'])) { - $this->log(0, "warning : bad md5sum for file $final_dest_file"); - } - } else { - if (!isset($options['soft'])) { - $this->log(0, "warning : bad md5sum for file $final_dest_file"); - } - } + // add the package.xml version 1.0 + if ($pf1 !== null) { + $pfgen = &$pf1->getDefaultGenerator(); + $packagexml1 = $pfgen->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true); + if (!$tar->addModify(array($packagexml1), '', $where)) { + return $packager->raiseError( + 'PEAR_Packagefile_v2::toTgz(): adding package.xml failed'); } - } else { - $real_atts['attribs']['md5sum'] = md5_file($dest_file); } - // }}} - // {{{ set file permissions - if (!OS_WINDOWS) { - if ($role->isExecutable()) { - $mode = 0777 & ~(int)octdec($this->config->get('umask')); - $this->log(3, "+ chmod +x $dest_file"); - } else { - $mode = 0666 & ~(int)octdec($this->config->get('umask')); - } + return $dest_package; + } + } - if ($attribs['role'] != 'src') { - $this->addFileOperation("chmod", array($mode, $dest_file)); - if (!@chmod($dest_file, $mode)) { - if (!isset($options['soft'])) { - $this->log(0, "failed to change mode of $dest_file: $php_errormsg"); - } - } - } - } - // }}} + function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml') + { + if (!$this->_packagefile->validate($state)) { + return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: invalid package.xml', + null, null, null, $this->_packagefile->getValidationWarnings()); + } - if ($attribs['role'] == 'src') { - rename($dest_file, $final_dest_file); - $this->log(2, "renamed source file $dest_file to $final_dest_file"); - } else { - $this->addFileOperation("rename", array($dest_file, $final_dest_file, $role->isExtension())); + if ($where === null) { + if (!($where = System::mktemp(array('-d')))) { + return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: mktemp failed'); } + } elseif (!@System::mkDir(array('-p', $where))) { + return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: "' . $where . '" could' . + ' not be created'); } - // Store the full path where the file was installed for easy uninstall - if ($attribs['role'] != 'src') { - $loc = $this->config->get($role->getLocationConfig(), null, $channel); - $this->addFileOperation('installed_as', array($file, $installed_as, - $loc, - dirname(substr($installed_as, strlen($loc))))); + $newpkgfile = $where . DIRECTORY_SEPARATOR . $name; + $np = @fopen($newpkgfile, 'wb'); + if (!$np) { + return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: unable to save ' . + "$name as $newpkgfile"); } - - //$this->log(2, "installed: $dest_file"); - return PEAR_INSTALLER_OK; + fwrite($np, $this->toXml($state)); + fclose($np); + return $newpkgfile; } - // }}} - // {{{ addFileOperation() + function &toV2() + { + return $this->_packagefile; + } /** - * Add a file operation to the current file transaction. - * - * @see startFileTransaction() - * @param string $type This can be one of: - * - rename: rename a file ($data has 3 values) - * - backup: backup an existing file ($data has 1 value) - * - removebackup: clean up backups created during install ($data has 1 value) - * - chmod: change permissions on a file ($data has 2 values) - * - delete: delete a file ($data has 1 value) - * - rmdir: delete a directory if empty ($data has 1 value) - * - installed_as: mark a file as installed ($data has 4 values). - * @param array $data For all file operations, this array must contain the - * full path to the file or directory that is being operated on. For - * the rename command, the first parameter must be the file to rename, - * the second its new name, the third whether this is a PHP extension. + * Return an XML document based on the package info (as returned + * by the PEAR_Common::infoFrom* methods). * - * The installed_as operation contains 4 elements in this order: - * 1. Filename as listed in the filelist element from package.xml - * 2. Full path to the installed file - * 3. Full path from the php_dir configuration variable used in this - * installation - * 4. Relative path from the php_dir that this file is installed in + * @return string XML data */ - function addFileOperation($type, $data) + function toXml($state = PEAR_VALIDATE_NORMAL, $options = array()) { - if (!is_array($data)) { - return $this->raiseError('Internal Error: $data in addFileOperation' - . ' must be an array, was ' . gettype($data)); + $this->_packagefile->setDate(date('Y-m-d')); + $this->_packagefile->setTime(date('H:i:s')); + if (!$this->_packagefile->validate($state)) { + return false; } - if ($type == 'chmod') { - $octmode = decoct($data[0]); - $this->log(3, "adding to transaction: $type $octmode $data[1]"); + if (is_array($options)) { + $this->options = array_merge($this->_defaultOptions, $options); } else { - $this->log(3, "adding to transaction: $type " . implode(" ", $data)); + $this->options = $this->_defaultOptions; } - $this->file_operations[] = array($type, $data); - } - // }}} - // {{{ startFileTransaction() + $arr = $this->_packagefile->getArray(); + if (isset($arr['filelist'])) { + unset($arr['filelist']); + } - function startFileTransaction($rollback_in_case = false) - { - if (count($this->file_operations) && $rollback_in_case) { - $this->rollbackFileTransaction(); + if (isset($arr['_lastversion'])) { + unset($arr['_lastversion']); } - $this->file_operations = array(); - } - // }}} - // {{{ commitFileTransaction() + // Fix the notes a little bit + if (isset($arr['notes'])) { + // This trims out the indenting, needs fixing + $arr['notes'] = "\n" . trim($arr['notes']) . "\n"; + } - function commitFileTransaction() - { - $n = count($this->file_operations); - $this->log(2, "about to commit $n file operations"); - // {{{ first, check permissions and such manually - $errors = array(); - foreach ($this->file_operations as $tr) { - list($type, $data) = $tr; - switch ($type) { - case 'rename': - if (!file_exists($data[0])) { - $errors[] = "cannot rename file $data[0], doesn't exist"; - } + if (isset($arr['changelog']) && !empty($arr['changelog'])) { + // Fix for inconsistency how the array is filled depending on the changelog release amount + if (!isset($arr['changelog']['release'][0])) { + $release = $arr['changelog']['release']; + unset($arr['changelog']['release']); - // check that dest dir. is writable - if (!is_writable(dirname($data[1]))) { - $errors[] = "permission denied ($type): $data[1]"; - } - break; - case 'chmod': - // check that file is writable - if (!is_writable($data[1])) { - $errors[] = "permission denied ($type): $data[1] " . decoct($data[0]); - } - break; - case 'delete': - if (!file_exists($data[0])) { - $this->log(2, "warning: file $data[0] doesn't exist, can't be deleted"); - } - // check that directory is writable - if (file_exists($data[0])) { - if (!is_writable(dirname($data[0]))) { - $errors[] = "permission denied ($type): $data[0]"; - } else { - // make sure the file to be deleted can be opened for writing - $fp = false; - if (!is_dir($data[0]) && - (!is_writable($data[0]) || !($fp = @fopen($data[0], 'a')))) { - $errors[] = "permission denied ($type): $data[0]"; - } elseif ($fp) { - fclose($fp); - } - } - } - break; + $arr['changelog']['release'] = array(); + $arr['changelog']['release'][0] = $release; } - } - // }}} - $m = count($errors); - if ($m > 0) { - foreach ($errors as $error) { - if (!isset($this->_options['soft'])) { - $this->log(1, $error); + foreach (array_keys($arr['changelog']['release']) as $key) { + $c =& $arr['changelog']['release'][$key]; + if (isset($c['notes'])) { + // This trims out the indenting, needs fixing + $c['notes'] = "\n" . trim($c['notes']) . "\n"; } } - - if (!isset($this->_options['ignore-errors'])) { - return false; - } } - $this->_dirtree = array(); - // {{{ really commit the transaction - foreach ($this->file_operations as $i => $tr) { - if (!$tr) { - // support removal of non-existing backups - continue; - } - - list($type, $data) = $tr; - switch ($type) { - case 'backup': - if (!file_exists($data[0])) { - $this->file_operations[$i] = false; - break; - } - - if (!@copy($data[0], $data[0] . '.bak')) { - $this->log(1, 'Could not copy ' . $data[0] . ' to ' . $data[0] . - '.bak ' . $php_errormsg); - return false; - } - $this->log(3, "+ backup $data[0] to $data[0].bak"); - break; - case 'removebackup': - if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { - unlink($data[0] . '.bak'); - $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); - } - break; - case 'rename': - $test = file_exists($data[1]) ? @unlink($data[1]) : null; - if (!$test && file_exists($data[1])) { - if ($data[2]) { - $extra = ', this extension must be installed manually. Rename to "' . - basename($data[1]) . '"'; - } else { - $extra = ''; - } - - if (!isset($this->_options['soft'])) { - $this->log(1, 'Could not delete ' . $data[1] . ', cannot rename ' . - $data[0] . $extra); - } - - if (!isset($this->_options['ignore-errors'])) { - return false; - } - } - - // permissions issues with rename - copy() is far superior - $perms = @fileperms($data[0]); - if (!@copy($data[0], $data[1])) { - $this->log(1, 'Could not rename ' . $data[0] . ' to ' . $data[1] . - ' ' . $php_errormsg); - return false; - } - - // copy over permissions, otherwise they are lost - @chmod($data[1], $perms); - @unlink($data[0]); - $this->log(3, "+ mv $data[0] $data[1]"); - break; - case 'chmod': - if (!@chmod($data[1], $data[0])) { - $this->log(1, 'Could not chmod ' . $data[1] . ' to ' . - decoct($data[0]) . ' ' . $php_errormsg); - return false; - } - - $octmode = decoct($data[0]); - $this->log(3, "+ chmod $octmode $data[1]"); - break; - case 'delete': - if (file_exists($data[0])) { - if (!@unlink($data[0])) { - $this->log(1, 'Could not delete ' . $data[0] . ' ' . - $php_errormsg); - return false; - } - $this->log(3, "+ rm $data[0]"); - } - break; - case 'rmdir': - if (file_exists($data[0])) { - do { - $testme = opendir($data[0]); - while (false !== ($entry = readdir($testme))) { - if ($entry == '.' || $entry == '..') { - continue; - } - closedir($testme); - break 2; // this directory is not empty and can't be - // deleted - } - - closedir($testme); - if (!@rmdir($data[0])) { - $this->log(1, 'Could not rmdir ' . $data[0] . ' ' . - $php_errormsg); - return false; - } - $this->log(3, "+ rmdir $data[0]"); - } while (false); - } - break; - case 'installed_as': - $this->pkginfo->setInstalledAs($data[0], $data[1]); - if (!isset($this->_dirtree[dirname($data[1])])) { - $this->_dirtree[dirname($data[1])] = true; - $this->pkginfo->setDirtree(dirname($data[1])); - - while(!empty($data[3]) && dirname($data[3]) != $data[3] && - $data[3] != '/' && $data[3] != '\\') { - $this->pkginfo->setDirtree($pp = - $this->_prependPath($data[3], $data[2])); - $this->_dirtree[$pp] = true; - $data[3] = dirname($data[3]); - } - } - break; + if ($state ^ PEAR_VALIDATE_PACKAGING && !isset($arr['bundle'])) { + $use = $this->_recursiveXmlFilelist($arr['contents']['dir']['file']); + unset($arr['contents']['dir']['file']); + if (isset($use['dir'])) { + $arr['contents']['dir']['dir'] = $use['dir']; } - } - // }}} - $this->log(2, "successfully committed $n file operations"); - $this->file_operations = array(); - return true; - } - - // }}} - // {{{ rollbackFileTransaction() - - function rollbackFileTransaction() - { - $n = count($this->file_operations); - $this->log(2, "rolling back $n file operations"); - foreach ($this->file_operations as $tr) { - list($type, $data) = $tr; - switch ($type) { - case 'backup': - if (file_exists($data[0] . '.bak')) { - if (file_exists($data[0] && is_writable($data[0]))) { - unlink($data[0]); - } - @copy($data[0] . '.bak', $data[0]); - $this->log(3, "+ restore $data[0] from $data[0].bak"); - } - break; - case 'removebackup': - if (file_exists($data[0] . '.bak') && is_writable($data[0] . '.bak')) { - unlink($data[0] . '.bak'); - $this->log(3, "+ rm backup of $data[0] ($data[0].bak)"); - } - break; - case 'rename': - @unlink($data[0]); - $this->log(3, "+ rm $data[0]"); - break; - case 'mkdir': - @rmdir($data[0]); - $this->log(3, "+ rmdir $data[0]"); - break; - case 'chmod': - break; - case 'delete': - break; - case 'installed_as': - $this->pkginfo->setInstalledAs($data[0], false); - break; + if (isset($use['file'])) { + $arr['contents']['dir']['file'] = $use['file']; } + $this->options['beautifyFilelist'] = true; } - $this->pkginfo->resetDirtree(); - $this->file_operations = array(); - } - - // }}} - // {{{ mkDirHier($dir) - - function mkDirHier($dir) - { - $this->addFileOperation('mkdir', array($dir)); - return parent::mkDirHier($dir); - } - // }}} - // {{{ download() - - /** - * Download any files and their dependencies, if necessary - * - * @param array a mixed list of package names, local files, or package.xml - * @param PEAR_Config - * @param array options from the command line - * @param array this is the array that will be populated with packages to - * install. Format of each entry: - * - * - * array('pkg' => 'package_name', 'file' => '/path/to/local/file', - * 'info' => array() // parsed package.xml - * ); - * - * @param array this will be populated with any error messages - * @param false private recursion variable - * @param false private recursion variable - * @param false private recursion variable - * @deprecated in favor of PEAR_Downloader - */ - function download($packages, $options, &$config, &$installpackages, - &$errors, $installed = false, $willinstall = false, $state = false) - { - // trickiness: initialize here - parent::PEAR_Downloader($this->ui, $options, $config); - $ret = parent::download($packages); - $errors = $this->getErrorMsgs(); - $installpackages = $this->getDownloadedPackages(); - trigger_error("PEAR Warning: PEAR_Installer::download() is deprecated " . - "in favor of PEAR_Downloader class", E_USER_WARNING); - return $ret; + $arr['attribs']['packagerversion'] = '1.9.0'; + if ($this->serialize($arr, $options)) { + return $this->_serializedData . "\n"; + } + + return false; } - // }}} - // {{{ _parsePackageXml() - function _parsePackageXml(&$descfile, &$tmpdir) + function _recursiveXmlFilelist($list) { - if (substr($descfile, -4) == '.xml') { - $tmpdir = false; + $dirs = array(); + if (isset($list['attribs'])) { + $file = $list['attribs']['name']; + unset($list['attribs']['name']); + $attributes = $list['attribs']; + $this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes); } else { - // {{{ Decompress pack in tmp dir ------------------------------------- + foreach ($list as $a) { + $file = $a['attribs']['name']; + $attributes = $a['attribs']; + unset($a['attribs']); + $this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes, $a); + } + } + $this->_formatDir($dirs); + $this->_deFormat($dirs); + return $dirs; + } - // To allow relative package file names - $descfile = realpath($descfile); + function _addDir(&$dirs, $dir, $file = null, $attributes = null, $tasks = null) + { + if (!$tasks) { + $tasks = array(); + } + if ($dir == array() || $dir == array('.')) { + $dirs['file'][basename($file)] = $tasks; + $attributes['name'] = basename($file); + $dirs['file'][basename($file)]['attribs'] = $attributes; + return; + } + $curdir = array_shift($dir); + if (!isset($dirs['dir'][$curdir])) { + $dirs['dir'][$curdir] = array(); + } + $this->_addDir($dirs['dir'][$curdir], $dir, $file, $attributes, $tasks); + } - if (PEAR::isError($tmpdir = System::mktemp('-d'))) { - return $tmpdir; + function _formatDir(&$dirs) + { + if (!count($dirs)) { + return array(); + } + $newdirs = array(); + if (isset($dirs['dir'])) { + $newdirs['dir'] = $dirs['dir']; + } + if (isset($dirs['file'])) { + $newdirs['file'] = $dirs['file']; + } + $dirs = $newdirs; + if (isset($dirs['dir'])) { + uksort($dirs['dir'], 'strnatcasecmp'); + foreach ($dirs['dir'] as $dir => $contents) { + $this->_formatDir($dirs['dir'][$dir]); } - $this->log(3, '+ tmp dir created at ' . $tmpdir); - // }}} } + if (isset($dirs['file'])) { + uksort($dirs['file'], 'strnatcasecmp'); + }; + } - // Parse xml file ----------------------------------------------- - $pkg = new PEAR_PackageFile($this->config, $this->debug, $tmpdir); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - $p = &$pkg->fromAnyFile($descfile, PEAR_VALIDATE_INSTALLING); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($p)) { - if (is_array($p->getUserInfo())) { - foreach ($p->getUserInfo() as $err) { - $loglevel = $err['level'] == 'error' ? 0 : 1; - if (!isset($this->_options['soft'])) { - $this->log($loglevel, ucfirst($err['level']) . ': ' . $err['message']); - } + function _deFormat(&$dirs) + { + if (!count($dirs)) { + return array(); + } + $newdirs = array(); + if (isset($dirs['dir'])) { + foreach ($dirs['dir'] as $dir => $contents) { + $newdir = array(); + $newdir['attribs']['name'] = $dir; + $this->_deFormat($contents); + foreach ($contents as $tag => $val) { + $newdir[$tag] = $val; } + $newdirs['dir'][] = $newdir; + } + if (count($newdirs['dir']) == 1) { + $newdirs['dir'] = $newdirs['dir'][0]; } - return $this->raiseError('Installation failed: invalid package file'); } - - $descfile = $p->getPackageFile(); - return $p; + if (isset($dirs['file'])) { + foreach ($dirs['file'] as $name => $file) { + $newdirs['file'][] = $file; + } + if (count($newdirs['file']) == 1) { + $newdirs['file'] = $newdirs['file'][0]; + } + } + $dirs = $newdirs; } - // }}} /** - * Set the list of PEAR_Downloader_Package objects to allow more sane - * dependency validation - * @param array - */ - function setDownloadedPackages(&$pkgs) + * reset all options to default options + * + * @access public + * @see setOption(), XML_Unserializer() + */ + function resetOptions() { - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $err = $this->analyzeDependencies($pkgs); - PEAR::popErrorHandling(); - if (PEAR::isError($err)) { - return $err; - } - $this->_downloadedPackages = &$pkgs; + $this->options = $this->_defaultOptions; } - /** - * Set the list of PEAR_Downloader_Package objects to allow more sane - * dependency validation - * @param array - */ - function setUninstallPackages(&$pkgs) + /** + * set an option + * + * You can use this method if you do not want to set all options in the constructor + * + * @access public + * @see resetOption(), XML_Serializer() + */ + function setOption($name, $value) { - $this->_downloadedPackages = &$pkgs; + $this->options[$name] = $value; } - function getInstallPackages() + /** + * sets several options at once + * + * You can use this method if you do not want to set all options in the constructor + * + * @access public + * @see resetOption(), XML_Unserializer(), setOption() + */ + function setOptions($options) { - return $this->_downloadedPackages; + $this->options = array_merge($this->options, $options); } - // {{{ install() - - /** - * Installs the files within the package file specified. - * - * @param string|PEAR_Downloader_Package $pkgfile path to the package file, - * or a pre-initialized packagefile object - * @param array $options - * recognized options: - * - installroot : optional prefix directory for installation - * - force : force installation - * - register-only : update registry but don't install files - * - upgrade : upgrade existing install - * - soft : fail silently - * - nodeps : ignore dependency conflicts/missing dependencies - * - alldeps : install all dependencies - * - onlyreqdeps : install only required dependencies - * - * @return array|PEAR_Error package info if successful - */ - - function install($pkgfile, $options = array()) + /** + * serialize data + * + * @access public + * @param mixed $data data to serialize + * @return boolean true on success, pear error on failure + */ + function serialize($data, $options = null) { - $this->_options = $options; - $this->_registry = &$this->config->getRegistry(); - if (is_object($pkgfile)) { - $dlpkg = &$pkgfile; - $pkg = $pkgfile->getPackageFile(); - $pkgfile = $pkg->getArchiveFile(); - $descfile = $pkg->getPackageFile(); - $tmpdir = dirname($descfile); - } else { - $descfile = $pkgfile; - $tmpdir = ''; - $pkg = &$this->_parsePackageXml($descfile, $tmpdir); - if (PEAR::isError($pkg)) { - return $pkg; + // if options have been specified, use them instead + // of the previously defined ones + if (is_array($options)) { + $optionsBak = $this->options; + if (isset($options['overrideOptions']) && $options['overrideOptions'] == true) { + $this->options = array_merge($this->_defaultOptions, $options); + } else { + $this->options = array_merge($this->options, $options); } + } else { + $optionsBak = null; } - if (realpath($descfile) != realpath($pkgfile)) { - $tar = new Archive_Tar($pkgfile); - if (!$tar->extract($tmpdir)) { - return $this->raiseError("unable to unpack $pkgfile"); - } + // start depth is zero + $this->_tagDepth = 0; + $this->_serializedData = ''; + // serialize an array + if (is_array($data)) { + $tagName = isset($this->options['rootName']) ? $this->options['rootName'] : 'array'; + $this->_serializedData .= $this->_serializeArray($data, $tagName, $this->options['rootAttributes']); } - $pkgname = $pkg->getName(); - $channel = $pkg->getChannel(); - if (isset($this->_options['packagingroot'])) { - $regdir = $this->_prependPath( - $this->config->get('php_dir', null, 'pear.php.net'), - $this->_options['packagingroot']); - - $packrootphp_dir = $this->_prependPath( - $this->config->get('php_dir', null, $channel), - $this->_options['packagingroot']); + // add doctype declaration + if ($this->options['addDoctype'] === true) { + $this->_serializedData = XML_Util::getDoctypeDeclaration($tagName, $this->options['doctype']) + . $this->options['linebreak'] + . $this->_serializedData; } - if (isset($options['installroot'])) { - $this->config->setInstallRoot($options['installroot']); - $this->_registry = &$this->config->getRegistry(); - $installregistry = &$this->_registry; - $this->installroot = ''; // all done automagically now - $php_dir = $this->config->get('php_dir', null, $channel); - } else { - $this->config->setInstallRoot(false); - $this->_registry = &$this->config->getRegistry(); - if (isset($this->_options['packagingroot'])) { - $installregistry = &new PEAR_Registry($regdir); - if (!$installregistry->channelExists($channel, true)) { - // we need to fake a channel-discover of this channel - $chanobj = $this->_registry->getChannel($channel, true); - $installregistry->addChannel($chanobj); - } - $php_dir = $packrootphp_dir; - } else { - $installregistry = &$this->_registry; - $php_dir = $this->config->get('php_dir', null, $channel); - } - $this->installroot = ''; + // build xml declaration + if ($this->options['addDecl']) { + $atts = array(); + $encoding = isset($this->options['encoding']) ? $this->options['encoding'] : null; + $this->_serializedData = XML_Util::getXMLDeclaration('1.0', $encoding) + . $this->options['linebreak'] + . $this->_serializedData; } - // {{{ checks to do when not in "force" mode - if (empty($options['force']) && - (file_exists($this->config->get('php_dir')) && - is_dir($this->config->get('php_dir')))) { - $testp = $channel == 'pear.php.net' ? $pkgname : array($channel, $pkgname); - $instfilelist = $pkg->getInstallationFileList(true); - if (PEAR::isError($instfilelist)) { - return $instfilelist; - } - - // ensure we have the most accurate registry - $installregistry->flushFileMap(); - $test = $installregistry->checkFileMap($instfilelist, $testp, '1.1'); - if (PEAR::isError($test)) { - return $test; - } - - if (sizeof($test)) { - $pkgs = $this->getInstallPackages(); - $found = false; - foreach ($pkgs as $param) { - if ($pkg->isSubpackageOf($param)) { - $found = true; - break; - } - } - - if ($found) { - // subpackages can conflict with earlier versions of parent packages - $parentreg = $installregistry->packageInfo($param->getPackage(), null, $param->getChannel()); - $tmp = $test; - foreach ($tmp as $file => $info) { - if (is_array($info)) { - if (strtolower($info[1]) == strtolower($param->getPackage()) && - strtolower($info[0]) == strtolower($param->getChannel()) - ) { - if (isset($parentreg['filelist'][$file])) { - unset($parentreg['filelist'][$file]); - } else{ - $pos = strpos($file, '/'); - $basedir = substr($file, 0, $pos); - $file2 = substr($file, $pos + 1); - if (isset($parentreg['filelist'][$file2]['baseinstalldir']) - && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir - ) { - unset($parentreg['filelist'][$file2]); - } - } - - unset($test[$file]); - } - } else { - if (strtolower($param->getChannel()) != 'pear.php.net') { - continue; - } - - if (strtolower($info) == strtolower($param->getPackage())) { - if (isset($parentreg['filelist'][$file])) { - unset($parentreg['filelist'][$file]); - } else{ - $pos = strpos($file, '/'); - $basedir = substr($file, 0, $pos); - $file2 = substr($file, $pos + 1); - if (isset($parentreg['filelist'][$file2]['baseinstalldir']) - && $parentreg['filelist'][$file2]['baseinstalldir'] === $basedir - ) { - unset($parentreg['filelist'][$file2]); - } - } - - unset($test[$file]); - } - } - } - - $pfk = &new PEAR_PackageFile($this->config); - $parentpkg = &$pfk->fromArray($parentreg); - $installregistry->updatePackage2($parentpkg); - } - if ($param->getChannel() == 'pecl.php.net' && isset($options['upgrade'])) { - $tmp = $test; - foreach ($tmp as $file => $info) { - if (is_string($info)) { - // pear.php.net packages are always stored as strings - if (strtolower($info) == strtolower($param->getPackage())) { - // upgrading existing package - unset($test[$file]); - } - } - } - } + if ($optionsBak !== null) { + $this->options = $optionsBak; + } - if (count($test)) { - $msg = "$channel/$pkgname: conflicting files found:\n"; - $longest = max(array_map("strlen", array_keys($test))); - $fmt = "%${longest}s (%s)\n"; - foreach ($test as $file => $info) { - if (!is_array($info)) { - $info = array('pear.php.net', $info); - } - $info = $info[0] . '/' . $info[1]; - $msg .= sprintf($fmt, $file, $info); - } + return true; + } - if (!isset($options['ignore-errors'])) { - return $this->raiseError($msg); - } + /** + * get the result of the serialization + * + * @access public + * @return string serialized XML + */ + function getSerializedData() + { + if ($this->_serializedData === null) { + return $this->raiseError('No serialized data available. Use XML_Serializer::serialize() first.', XML_SERIALIZER_ERROR_NO_SERIALIZATION); + } + return $this->_serializedData; + } - if (!isset($options['soft'])) { - $this->log(0, "WARNING: $msg"); - } - } - } + /** + * serialize any value + * + * This method checks for the type of the value and calls the appropriate method + * + * @access private + * @param mixed $value + * @param string $tagName + * @param array $attributes + * @return string + */ + function _serializeValue($value, $tagName = null, $attributes = array()) + { + if (is_array($value)) { + $xml = $this->_serializeArray($value, $tagName, $attributes); + } elseif (is_object($value)) { + $xml = $this->_serializeObject($value, $tagName); + } else { + $tag = array( + 'qname' => $tagName, + 'attributes' => $attributes, + 'content' => $value + ); + $xml = $this->_createXMLTag($tag); } - // }}} + return $xml; + } - $this->startFileTransaction(); + /** + * serialize an array + * + * @access private + * @param array $array array to serialize + * @param string $tagName name of the root tag + * @param array $attributes attributes for the root tag + * @return string $string serialized data + * @uses XML_Util::isValidName() to check, whether key has to be substituted + */ + function _serializeArray(&$array, $tagName = null, $attributes = array()) + { + $_content = null; - if (empty($options['upgrade']) && empty($options['soft'])) { - // checks to do only when installing new packages - if ($channel == 'pecl.php.net') { - $test = $installregistry->packageExists($pkgname, $channel); - if (!$test) { - $test = $installregistry->packageExists($pkgname, 'pear.php.net'); + /** + * check for special attributes + */ + if ($this->options['attributesArray'] !== null) { + if (isset($array[$this->options['attributesArray']])) { + $attributes = $array[$this->options['attributesArray']]; + unset($array[$this->options['attributesArray']]); + } + /** + * check for special content + */ + if ($this->options['contentName'] !== null) { + if (isset($array[$this->options['contentName']])) { + $_content = $array[$this->options['contentName']]; + unset($array[$this->options['contentName']]); } - } else { - $test = $installregistry->packageExists($pkgname, $channel); } + } - if (empty($options['force']) && $test) { - return $this->raiseError("$channel/$pkgname is already installed"); + /* + * if mode is set to simpleXML, check whether + * the array is associative or indexed + */ + if (is_array($array) && $this->options['mode'] == 'simplexml') { + $indexed = true; + if (!count($array)) { + $indexed = false; } - } else { - $usechannel = $channel; - if ($channel == 'pecl.php.net') { - $test = $installregistry->packageExists($pkgname, $channel); - if (!$test) { - $test = $installregistry->packageExists($pkgname, 'pear.php.net'); - $usechannel = 'pear.php.net'; + foreach ($array as $key => $val) { + if (!is_int($key)) { + $indexed = false; + break; } - } else { - $test = $installregistry->packageExists($pkgname, $channel); } - if ($test) { - $v1 = $installregistry->packageInfo($pkgname, 'version', $usechannel); - $v2 = $pkg->getVersion(); - $cmp = version_compare("$v1", "$v2", 'gt'); - if (empty($options['force']) && !version_compare("$v2", "$v1", 'gt')) { - return $this->raiseError("upgrade to a newer version ($v2 is not newer than $v1)"); - } - - if (empty($options['register-only'])) { - // when upgrading, remove old release's files first: - if (PEAR::isError($err = $this->_deletePackageFiles($pkgname, $usechannel, - true))) { - if (!isset($options['ignore-errors'])) { - return $this->raiseError($err); + if ($indexed && $this->options['mode'] == 'simplexml') { + $string = ''; + foreach ($array as $key => $val) { + if ($this->options['beautifyFilelist'] && $tagName == 'dir') { + if (!isset($this->_curdir)) { + $this->_curdir = ''; + } + $savedir = $this->_curdir; + if (isset($val['attribs'])) { + if ($val['attribs']['name'] == '/') { + $this->_curdir = '/'; + } else { + if ($this->_curdir == '/') { + $this->_curdir = ''; + } + $this->_curdir .= '/' . $val['attribs']['name']; + } } - - if (!isset($options['soft'])) { - $this->log(0, 'WARNING: ' . $err->getMessage()); + } + $string .= $this->_serializeValue( $val, $tagName, $attributes); + if ($this->options['beautifyFilelist'] && $tagName == 'dir') { + $string .= ' '; + if (empty($savedir)) { + unset($this->_curdir); + } else { + $this->_curdir = $savedir; } - } else { - $backedup = $err; + } + + $string .= $this->options['linebreak']; + // do indentation + if ($this->options['indent'] !== null && $this->_tagDepth > 0) { + $string .= str_repeat($this->options['indent'], $this->_tagDepth); } } + return rtrim($string); } } - // {{{ Copy files to dest dir --------------------------------------- - - // info from the package it self we want to access from _installFile - $this->pkginfo = &$pkg; - // used to determine whether we should build any C code - $this->source_files = 0; - - $savechannel = $this->config->get('default_channel'); - if (empty($options['register-only']) && !is_dir($php_dir)) { - if (PEAR::isError(System::mkdir(array('-p'), $php_dir))) { - return $this->raiseError("no installation destination directory '$php_dir'\n"); + if ($this->options['scalarAsAttributes'] === true) { + foreach ($array as $key => $value) { + if (is_scalar($value) && (XML_Util::isValidName($key) === true)) { + unset($array[$key]); + $attributes[$this->options['prependAttributes'].$key] = $value; + } } } - $tmp_path = dirname($descfile); - if (substr($pkgfile, -4) != '.xml') { - $tmp_path .= DIRECTORY_SEPARATOR . $pkgname . '-' . $pkg->getVersion(); - } - - $this->configSet('default_channel', $channel); - // {{{ install files - - $ver = $pkg->getPackagexmlVersion(); - if (version_compare($ver, '2.0', '>=')) { - $filelist = $pkg->getInstallationFilelist(); - } else { - $filelist = $pkg->getFileList(); - } - - if (PEAR::isError($filelist)) { - return $filelist; - } + // check for empty array => create empty tag + if (empty($array)) { + $tag = array( + 'qname' => $tagName, + 'content' => $_content, + 'attributes' => $attributes + ); - $p = &$installregistry->getPackage($pkgname, $channel); - if (empty($options['register-only']) && $p) { - $dirtree = $p->getDirTree(); } else { - $dirtree = false; - } - - $pkg->resetFilelist(); - $pkg->setLastInstalledVersion($installregistry->packageInfo($pkg->getPackage(), - 'version', $pkg->getChannel())); - foreach ($filelist as $file => $atts) { - $this->expectError(PEAR_INSTALLER_FAILED); - if ($pkg->getPackagexmlVersion() == '1.0') { - $res = $this->_installFile($file, $atts, $tmp_path, $options); - } else { - $res = $this->_installFile2($pkg, $file, $atts, $tmp_path, $options); - } - $this->popExpect(); + $this->_tagDepth++; + $tmp = $this->options['linebreak']; + foreach ($array as $key => $value) { + // do indentation + if ($this->options['indent'] !== null && $this->_tagDepth > 0) { + $tmp .= str_repeat($this->options['indent'], $this->_tagDepth); + } - if (PEAR::isError($res)) { - if (empty($options['ignore-errors'])) { - $this->rollbackFileTransaction(); - if ($res->getMessage() == "file does not exist") { - $this->raiseError("file $file in package.xml does not exist"); + // copy key + $origKey = $key; + // key cannot be used as tagname => use default tag + $valid = XML_Util::isValidName($key); + if (PEAR::isError($valid)) { + if ($this->options['classAsTagName'] && is_object($value)) { + $key = get_class($value); + } else { + $key = $this->options['defaultTagName']; + } + } + $atts = array(); + if ($this->options['typeHints'] === true) { + $atts[$this->options['typeAttribute']] = gettype($value); + if ($key !== $origKey) { + $atts[$this->options['keyAttribute']] = (string)$origKey; } - return $this->raiseError($res); + } + if ($this->options['beautifyFilelist'] && $key == 'dir') { + if (!isset($this->_curdir)) { + $this->_curdir = ''; + } + $savedir = $this->_curdir; + if (isset($value['attribs'])) { + if ($value['attribs']['name'] == '/') { + $this->_curdir = '/'; + } else { + $this->_curdir .= '/' . $value['attribs']['name']; + } + } } - if (!isset($options['soft'])) { - $this->log(0, "Warning: " . $res->getMessage()); + if (is_string($value) && $value && ($value{strlen($value) - 1} == "\n")) { + $value .= str_repeat($this->options['indent'], $this->_tagDepth); } + $tmp .= $this->_createXMLTag(array( + 'qname' => $key, + 'attributes' => $atts, + 'content' => $value ) + ); + if ($this->options['beautifyFilelist'] && $key == 'dir') { + if (isset($value['attribs'])) { + $tmp .= ' '; + if (empty($savedir)) { + unset($this->_curdir); + } else { + $this->_curdir = $savedir; + } + } + } + $tmp .= $this->options['linebreak']; } - $real = isset($atts['attribs']) ? $atts['attribs'] : $atts; - if ($res == PEAR_INSTALLER_OK && $real['role'] != 'src') { - // Register files that were installed - $pkg->installedFile($file, $atts); + $this->_tagDepth--; + if ($this->options['indent']!==null && $this->_tagDepth>0) { + $tmp .= str_repeat($this->options['indent'], $this->_tagDepth); } - } - // }}} - // {{{ compile and install source files - if ($this->source_files > 0 && empty($options['nobuild'])) { - if (PEAR::isError($err = - $this->_compileSourceFiles($savechannel, $pkg))) { - return $err; + if (trim($tmp) === '') { + $tmp = null; } - } - // }}} - if (isset($backedup)) { - $this->_removeBackups($backedup); + $tag = array( + 'qname' => $tagName, + 'content' => $tmp, + 'attributes' => $attributes + ); } - - if (!$this->commitFileTransaction()) { - $this->rollbackFileTransaction(); - $this->configSet('default_channel', $savechannel); - return $this->raiseError("commit failed", PEAR_INSTALLER_FAILED); + if ($this->options['typeHints'] === true) { + if (!isset($tag['attributes'][$this->options['typeAttribute']])) { + $tag['attributes'][$this->options['typeAttribute']] = 'array'; + } } - // }}} - $ret = false; - $installphase = 'install'; - $oldversion = false; - // {{{ Register that the package is installed ----------------------- - if (empty($options['upgrade'])) { - // if 'force' is used, replace the info in registry - $usechannel = $channel; - if ($channel == 'pecl.php.net') { - $test = $installregistry->packageExists($pkgname, $channel); - if (!$test) { - $test = $installregistry->packageExists($pkgname, 'pear.php.net'); - $usechannel = 'pear.php.net'; - } - } else { - $test = $installregistry->packageExists($pkgname, $channel); - } + $string = $this->_createXMLTag($tag, false); + return $string; + } - if (!empty($options['force']) && $test) { - $oldversion = $installregistry->packageInfo($pkgname, 'version', $usechannel); - $installregistry->deletePackage($pkgname, $usechannel); - } - $ret = $installregistry->addPackage2($pkg); - } else { - if ($dirtree) { - $this->startFileTransaction(); - // attempt to delete empty directories - uksort($dirtree, array($this, '_sortDirs')); - foreach($dirtree as $dir => $notused) { - $this->addFileOperation('rmdir', array($dir)); - } - $this->commitFileTransaction(); - } + /** + * create a tag from an array + * this method awaits an array in the following format + * array( + * 'qname' => $tagName, + * 'attributes' => array(), + * 'content' => $content, // optional + * 'namespace' => $namespace // optional + * 'namespaceUri' => $namespaceUri // optional + * ) + * + * @access private + * @param array $tag tag definition + * @param boolean $replaceEntities whether to replace XML entities in content or not + * @return string $string XML tag + */ + function _createXMLTag($tag, $replaceEntities = true) + { + if ($this->options['indentAttributes'] !== false) { + $multiline = true; + $indent = str_repeat($this->options['indent'], $this->_tagDepth); - $usechannel = $channel; - if ($channel == 'pecl.php.net') { - $test = $installregistry->packageExists($pkgname, $channel); - if (!$test) { - $test = $installregistry->packageExists($pkgname, 'pear.php.net'); - $usechannel = 'pear.php.net'; - } - } else { - $test = $installregistry->packageExists($pkgname, $channel); - } + if ($this->options['indentAttributes'] == '_auto') { + $indent .= str_repeat(' ', (strlen($tag['qname'])+2)); - // new: upgrade installs a package if it isn't installed - if (!$test) { - $ret = $installregistry->addPackage2($pkg); } else { - if ($usechannel != $channel) { - $installregistry->deletePackage($pkgname, $usechannel); - $ret = $installregistry->addPackage2($pkg); - } else { - $ret = $installregistry->updatePackage2($pkg); - } - $installphase = 'upgrade'; + $indent .= $this->options['indentAttributes']; } + } else { + $indent = $multiline = false; } - if (!$ret) { - $this->configSet('default_channel', $savechannel); - return $this->raiseError("Adding package $channel/$pkgname to registry failed"); + if (is_array($tag['content'])) { + if (empty($tag['content'])) { + $tag['content'] = ''; + } + } elseif(is_scalar($tag['content']) && (string)$tag['content'] == '') { + $tag['content'] = ''; } - // }}} - $this->configSet('default_channel', $savechannel); - if (class_exists('PEAR_Task_Common')) { // this is auto-included if any tasks exist - if (PEAR_Task_Common::hasPostinstallTasks()) { - PEAR_Task_Common::runPostinstallTasks($installphase); + if (is_scalar($tag['content']) || is_null($tag['content'])) { + if ($this->options['encoding'] == 'UTF-8' && + version_compare(phpversion(), '5.0.0', 'lt') + ) { + $tag['content'] = utf8_encode($tag['content']); + } + + if ($replaceEntities === true) { + $replaceEntities = XML_UTIL_ENTITIES_XML; } + + $tag = XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $this->options['linebreak']); + } elseif (is_array($tag['content'])) { + $tag = $this->_serializeArray($tag['content'], $tag['qname'], $tag['attributes']); + } elseif (is_object($tag['content'])) { + $tag = $this->_serializeObject($tag['content'], $tag['qname'], $tag['attributes']); + } elseif (is_resource($tag['content'])) { + settype($tag['content'], 'string'); + $tag = XML_Util::createTagFromArray($tag, $replaceEntities); } + return $tag; + } +} + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: v1.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * package.xml abstraction class + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; +/** + * Parser for package.xml version 1.0 + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_Parser_v1 +{ + var $_registry; + var $_config; + var $_logger; + /** + * BC hack to allow PEAR_Common::infoFromString() to sort of + * work with the version 2.0 format - there's no filelist though + * @param PEAR_PackageFile_v2 + */ + function fromV2($packagefile) + { + $info = $packagefile->getArray(true); + $ret = new PEAR_PackageFile_v1; + $ret->fromArray($info['old']); + } - return $pkg->toArray(true); + function setConfig(&$c) + { + $this->_config = &$c; + $this->_registry = &$c->getRegistry(); } - // }}} + function setLogger(&$l) + { + $this->_logger = &$l; + } - // {{{ _compileSourceFiles() /** - * @param string - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @param string contents of package.xml file, version 1.0 + * @return bool success of parsing */ - function _compileSourceFiles($savechannel, &$filelist) + function &parse($data, $file, $archive = false) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Builder.php'; - $this->log(1, "$this->source_files source files, building"); - $bob = &new PEAR_Builder($this->ui); - $bob->debug = $this->debug; - $built = $bob->build($filelist, array(&$this, '_buildCallback')); - if (PEAR::isError($built)) { - $this->rollbackFileTransaction(); - $this->configSet('default_channel', $savechannel); - return $built; + if (!extension_loaded('xml')) { + return PEAR::raiseError('Cannot create xml parser for parsing package.xml, no xml extension'); + } + $xp = xml_parser_create(); + if (!$xp) { + $a = &PEAR::raiseError('Cannot create xml parser for parsing package.xml'); + return $a; } + xml_set_object($xp, $this); + xml_set_element_handler($xp, '_element_start_1_0', '_element_end_1_0'); + xml_set_character_data_handler($xp, '_pkginfo_cdata_1_0'); + xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false); - $this->log(1, "\nBuild process completed successfully"); - foreach ($built as $ext) { - $bn = basename($ext['file']); - list($_ext_name, $_ext_suff) = explode('.', $bn); - if ($_ext_suff == '.so' || $_ext_suff == '.dll') { - if (extension_loaded($_ext_name)) { - $this->raiseError("Extension '$_ext_name' already loaded. " . - 'Please unload it in your php.ini file ' . - 'prior to install or upgrade'); - } - $role = 'ext'; - } else { - $role = 'src'; - } + $this->element_stack = array(); + $this->_packageInfo = array('provides' => array()); + $this->current_element = false; + unset($this->dir_install); + $this->_packageInfo['filelist'] = array(); + $this->filelist =& $this->_packageInfo['filelist']; + $this->dir_names = array(); + $this->in_changelog = false; + $this->d_i = 0; + $this->cdata = ''; + $this->_isValid = true; - $dest = $ext['dest']; - $packagingroot = ''; - if (isset($this->_options['packagingroot'])) { - $packagingroot = $this->_options['packagingroot']; - } + if (!xml_parse($xp, $data, 1)) { + $code = xml_get_error_code($xp); + $line = xml_get_current_line_number($xp); + xml_parser_free($xp); + $a = &PEAR::raiseError(sprintf("XML error: %s at line %d", + $str = xml_error_string($code), $line), 2); + return $a; + } - $copyto = $this->_prependPath($dest, $packagingroot); - if ($copyto != $dest) { - $this->log(1, "Installing '$dest' as '$copyto'"); - } else { - $this->log(1, "Installing '$dest'"); + xml_parser_free($xp); + + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->_config); + if (isset($this->_logger)) { + $pf->setLogger($this->_logger); + } + $pf->setPackagefile($file, $archive); + $pf->fromArray($this->_packageInfo); + return $pf; + } + // {{{ _unIndent() + + /** + * Unindent given string + * + * @param string $str The string that has to be unindented. + * @return string + * @access private + */ + function _unIndent($str) + { + // remove leading newlines + $str = preg_replace('/^[\r\n]+/', '', $str); + // find whitespace at the beginning of the first line + $indent_len = strspn($str, " \t"); + $indent = substr($str, 0, $indent_len); + $data = ''; + // remove the same amount of whitespace from following lines + foreach (explode("\n", $str) as $line) { + if (substr($line, 0, $indent_len) == $indent) { + $data .= substr($line, $indent_len) . "\n"; + } elseif (trim(substr($line, 0, $indent_len))) { + $data .= ltrim($line); } + } + return $data; + } - $copydir = dirname($copyto); - // pretty much nothing happens if we are only registering the install - if (empty($this->_options['register-only'])) { - if (!file_exists($copydir) || !is_dir($copydir)) { - if (!$this->mkDirHier($copydir)) { - return $this->raiseError("failed to mkdir $copydir", - PEAR_INSTALLER_FAILED); + // Support for package DTD v1.0: + // {{{ _element_start_1_0() + + /** + * XML parser callback for ending elements. Used for version 1.0 + * packages. + * + * @param resource $xp XML parser resource + * @param string $name name of ending element + * + * @return void + * + * @access private + */ + function _element_start_1_0($xp, $name, $attribs) + { + array_push($this->element_stack, $name); + $this->current_element = $name; + $spos = sizeof($this->element_stack) - 2; + $this->prev_element = ($spos >= 0) ? $this->element_stack[$spos] : ''; + $this->current_attributes = $attribs; + $this->cdata = ''; + switch ($name) { + case 'dir': + if ($this->in_changelog) { + break; + } + if (array_key_exists('name', $attribs) && $attribs['name'] != '/') { + $attribs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), + $attribs['name']); + if (strrpos($attribs['name'], '/') === strlen($attribs['name']) - 1) { + $attribs['name'] = substr($attribs['name'], 0, + strlen($attribs['name']) - 1); + } + if (strpos($attribs['name'], '/') === 0) { + $attribs['name'] = substr($attribs['name'], 1); + } + $this->dir_names[] = $attribs['name']; + } + if (isset($attribs['baseinstalldir'])) { + $this->dir_install = $attribs['baseinstalldir']; + } + if (isset($attribs['role'])) { + $this->dir_role = $attribs['role']; + } + break; + case 'file': + if ($this->in_changelog) { + break; + } + if (isset($attribs['name'])) { + $path = ''; + if (count($this->dir_names)) { + foreach ($this->dir_names as $dir) { + $path .= $dir . '/'; + } + } + $path .= preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), + $attribs['name']); + unset($attribs['name']); + $this->current_path = $path; + $this->filelist[$path] = $attribs; + // Set the baseinstalldir only if the file don't have this attrib + if (!isset($this->filelist[$path]['baseinstalldir']) && + isset($this->dir_install)) + { + $this->filelist[$path]['baseinstalldir'] = $this->dir_install; + } + // Set the Role + if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) { + $this->filelist[$path]['role'] = $this->dir_role; } - - $this->log(3, "+ mkdir $copydir"); } - - if (!@copy($ext['file'], $copyto)) { - return $this->raiseError("failed to write $copyto ($php_errormsg)", PEAR_INSTALLER_FAILED); + break; + case 'replace': + if (!$this->in_changelog) { + $this->filelist[$this->current_path]['replacements'][] = $attribs; } - - $this->log(3, "+ cp $ext[file] $copyto"); - $this->addFileOperation('rename', array($ext['file'], $copyto)); - if (!OS_WINDOWS) { - $mode = 0666 & ~(int)octdec($this->config->get('umask')); - $this->addFileOperation('chmod', array($mode, $copyto)); - if (!@chmod($copyto, $mode)) { - $this->log(0, "failed to change mode of $copyto ($php_errormsg)"); - } + break; + case 'maintainers': + $this->_packageInfo['maintainers'] = array(); + $this->m_i = 0; // maintainers array index + break; + case 'maintainer': + // compatibility check + if (!isset($this->_packageInfo['maintainers'])) { + $this->_packageInfo['maintainers'] = array(); + $this->m_i = 0; } - } - - if ($filelist->getPackageXmlVersion() == '1.0') { - $filelist->installedFile($bn, array( - 'role' => $role, - 'name' => $bn, - 'installed_as' => $dest, - 'php_api' => $ext['php_api'], - 'zend_mod_api' => $ext['zend_mod_api'], - 'zend_ext_api' => $ext['zend_ext_api'], - )); - } else { - $filelist->installedFile($bn, array('attribs' => array( - 'role' => $role, - 'name' => $bn, - 'installed_as' => $dest, - 'php_api' => $ext['php_api'], - 'zend_mod_api' => $ext['zend_mod_api'], - 'zend_ext_api' => $ext['zend_ext_api'], - ))); - } + $this->_packageInfo['maintainers'][$this->m_i] = array(); + $this->current_maintainer =& $this->_packageInfo['maintainers'][$this->m_i]; + break; + case 'changelog': + $this->_packageInfo['changelog'] = array(); + $this->c_i = 0; // changelog array index + $this->in_changelog = true; + break; + case 'release': + if ($this->in_changelog) { + $this->_packageInfo['changelog'][$this->c_i] = array(); + $this->current_release = &$this->_packageInfo['changelog'][$this->c_i]; + } else { + $this->current_release = &$this->_packageInfo; + } + break; + case 'deps': + if (!$this->in_changelog) { + $this->_packageInfo['release_deps'] = array(); + } + break; + case 'dep': + // dependencies array index + if (!$this->in_changelog) { + $this->d_i++; + isset($attribs['type']) ? ($attribs['type'] = strtolower($attribs['type'])) : false; + $this->_packageInfo['release_deps'][$this->d_i] = $attribs; + } + break; + case 'configureoptions': + if (!$this->in_changelog) { + $this->_packageInfo['configure_options'] = array(); + } + break; + case 'configureoption': + if (!$this->in_changelog) { + $this->_packageInfo['configure_options'][] = $attribs; + } + break; + case 'provides': + if (empty($attribs['type']) || empty($attribs['name'])) { + break; + } + $attribs['explicit'] = true; + $this->_packageInfo['provides']["$attribs[type];$attribs[name]"] = $attribs; + break; + case 'package' : + if (isset($attribs['version'])) { + $this->_packageInfo['xsdversion'] = trim($attribs['version']); + } else { + $this->_packageInfo['xsdversion'] = '1.0'; + } + if (isset($attribs['packagerversion'])) { + $this->_packageInfo['packagerversion'] = $attribs['packagerversion']; + } + break; } } // }}} - function &getUninstallPackages() - { - return $this->_downloadedPackages; - } - // {{{ uninstall() + // {{{ _element_end_1_0() /** - * Uninstall a package + * XML parser callback for ending elements. Used for version 1.0 + * packages. * - * This method removes all files installed by the application, and then - * removes any empty directories. - * @param string package name - * @param array Command-line options. Possibilities include: + * @param resource $xp XML parser resource + * @param string $name name of ending element * - * - installroot: base installation dir, if not the default - * - register-only : update registry but don't remove files - * - nodeps: do not process dependencies of other packages to ensure - * uninstallation does not break things + * @return void + * + * @access private */ - function uninstall($package, $options = array()) + function _element_end_1_0($xp, $name) { - if (isset($options['installroot'])) { - $this->config->setInstallRoot($options['installroot']); - } else { - $this->config->setInstallRoot(''); - } - - $this->installroot = ''; - $this->_registry = &$this->config->getRegistry(); - if (is_object($package)) { - $channel = $package->getChannel(); - $pkg = $package; - $package = $pkg->getPackage(); - } else { - $pkg = false; - $info = $this->_registry->parsePackageName($package, - $this->config->get('default_channel')); - $channel = $info['channel']; - $package = $info['package']; - } - - $savechannel = $this->config->get('default_channel'); - $this->configSet('default_channel', $channel); - if (!is_object($pkg)) { - $pkg = $this->_registry->getPackage($package, $channel); - } - - if (!$pkg) { - $this->configSet('default_channel', $savechannel); - return $this->raiseError($this->_registry->parsedPackageNameToString( - array( - 'channel' => $channel, - 'package' => $package - ), true) . ' not installed'); - } - - if ($pkg->getInstalledBinary()) { - // this is just an alias for a binary package - return $this->_registry->deletePackage($package, $channel); - } - - $filelist = $pkg->getFilelist(); - PEAR::staticPushErrorHandling(PEAR_ERROR_RETURN); - if (!class_exists('PEAR_Dependency2')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; - } - - $depchecker = &new PEAR_Dependency2($this->config, $options, - array('channel' => $channel, 'package' => $package), - PEAR_VALIDATE_UNINSTALLING); - $e = $depchecker->validatePackageUninstall($this); - PEAR::staticPopErrorHandling(); - if (PEAR::isError($e)) { - if (!isset($options['ignore-errors'])) { - return $this->raiseError($e); - } - - if (!isset($options['soft'])) { - $this->log(0, 'WARNING: ' . $e->getMessage()); - } - } elseif (is_array($e)) { - if (!isset($options['soft'])) { - $this->log(0, $e[0]); - } - } - - $this->pkginfo = &$pkg; - // pretty much nothing happens if we are only registering the uninstall - if (empty($options['register-only'])) { - // {{{ Delete the files - $this->startFileTransaction(); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - if (PEAR::isError($err = $this->_deletePackageFiles($package, $channel))) { - PEAR::popErrorHandling(); - $this->rollbackFileTransaction(); - $this->configSet('default_channel', $savechannel); - if (!isset($options['ignore-errors'])) { - return $this->raiseError($err); + $data = trim($this->cdata); + switch ($name) { + case 'name': + switch ($this->prev_element) { + case 'package': + $this->_packageInfo['package'] = $data; + break; + case 'maintainer': + $this->current_maintainer['name'] = $data; + break; } - - if (!isset($options['soft'])) { - $this->log(0, 'WARNING: ' . $err->getMessage()); + break; + case 'extends' : + $this->_packageInfo['extends'] = $data; + break; + case 'summary': + $this->_packageInfo['summary'] = $data; + break; + case 'description': + $data = $this->_unIndent($this->cdata); + $this->_packageInfo['description'] = $data; + break; + case 'user': + $this->current_maintainer['handle'] = $data; + break; + case 'email': + $this->current_maintainer['email'] = $data; + break; + case 'role': + $this->current_maintainer['role'] = $data; + break; + case 'version': + if ($this->in_changelog) { + $this->current_release['version'] = $data; + } else { + $this->_packageInfo['version'] = $data; } - } else { - PEAR::popErrorHandling(); - } - - if (!$this->commitFileTransaction()) { - $this->rollbackFileTransaction(); - if (!isset($options['ignore-errors'])) { - return $this->raiseError("uninstall failed"); + break; + case 'date': + if ($this->in_changelog) { + $this->current_release['release_date'] = $data; + } else { + $this->_packageInfo['release_date'] = $data; } - - if (!isset($options['soft'])) { - $this->log(0, 'WARNING: uninstall failed'); + break; + case 'notes': + // try to "de-indent" release notes in case someone + // has been over-indenting their xml ;-) + // Trim only on the right side + $data = rtrim($this->_unIndent($this->cdata)); + if ($this->in_changelog) { + $this->current_release['release_notes'] = $data; + } else { + $this->_packageInfo['release_notes'] = $data; } - } else { - $this->startFileTransaction(); - if ($dirtree = $pkg->getDirTree()) { - // attempt to delete empty directories - uksort($dirtree, array($this, '_sortDirs')); - foreach($dirtree as $dir => $notused) { - $this->addFileOperation('rmdir', array($dir)); - } + break; + case 'warnings': + if ($this->in_changelog) { + $this->current_release['release_warnings'] = $data; } else { - $this->configSet('default_channel', $savechannel); - return $this->_registry->deletePackage($package, $channel); + $this->_packageInfo['release_warnings'] = $data; } - - if (!$this->commitFileTransaction()) { - $this->rollbackFileTransaction(); - if (!isset($options['ignore-errors'])) { - return $this->raiseError("uninstall failed"); + break; + case 'state': + if ($this->in_changelog) { + $this->current_release['release_state'] = $data; + } else { + $this->_packageInfo['release_state'] = $data; + } + break; + case 'license': + if ($this->in_changelog) { + $this->current_release['release_license'] = $data; + } else { + $this->_packageInfo['release_license'] = $data; + } + break; + case 'dep': + if ($data && !$this->in_changelog) { + $this->_packageInfo['release_deps'][$this->d_i]['name'] = $data; + } + break; + case 'dir': + if ($this->in_changelog) { + break; + } + array_pop($this->dir_names); + break; + case 'file': + if ($this->in_changelog) { + break; + } + if ($data) { + $path = ''; + if (count($this->dir_names)) { + foreach ($this->dir_names as $dir) { + $path .= $dir . '/'; + } } - - if (!isset($options['soft'])) { - $this->log(0, 'WARNING: uninstall failed'); + $path .= $data; + $this->filelist[$path] = $this->current_attributes; + // Set the baseinstalldir only if the file don't have this attrib + if (!isset($this->filelist[$path]['baseinstalldir']) && + isset($this->dir_install)) + { + $this->filelist[$path]['baseinstalldir'] = $this->dir_install; + } + // Set the Role + if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) { + $this->filelist[$path]['role'] = $this->dir_role; } } - } - // }}} + break; + case 'maintainer': + if (empty($this->_packageInfo['maintainers'][$this->m_i]['role'])) { + $this->_packageInfo['maintainers'][$this->m_i]['role'] = 'lead'; + } + $this->m_i++; + break; + case 'release': + if ($this->in_changelog) { + $this->c_i++; + } + break; + case 'changelog': + $this->in_changelog = false; + break; } - - $this->configSet('default_channel', $savechannel); - // Register that the package is no longer installed - return $this->_registry->deletePackage($package, $channel); + array_pop($this->element_stack); + $spos = sizeof($this->element_stack) - 1; + $this->current_element = ($spos > 0) ? $this->element_stack[$spos] : ''; + $this->cdata = ''; } + // }}} + // {{{ _pkginfo_cdata_1_0() + /** - * Sort a list of arrays of array(downloaded packagefilename) by dependency. + * XML parser callback for character data. Used for version 1.0 + * packages. * - * It also removes duplicate dependencies - * @param array an array of PEAR_PackageFile_v[1/2] objects - * @return array|PEAR_Error array of array(packagefilename, package.xml contents) + * @param resource $xp XML parser resource + * @param string $name character data + * + * @return void + * + * @access private */ - function sortPackagesForUninstall(&$packages) - { - $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->config); - if (PEAR::isError($this->_dependencyDB)) { - return $this->_dependencyDB; - } - usort($packages, array(&$this, '_sortUninstall')); - } - - function _sortUninstall($a, $b) - { - if (!$a->getDeps() && !$b->getDeps()) { - return 0; // neither package has dependencies, order is insignificant - } - if ($a->getDeps() && !$b->getDeps()) { - return -1; // $a must be installed after $b because $a has dependencies - } - if (!$a->getDeps() && $b->getDeps()) { - return 1; // $b must be installed after $a because $b has dependencies - } - // both packages have dependencies - if ($this->_dependencyDB->dependsOn($a, $b)) { - return -1; - } - if ($this->_dependencyDB->dependsOn($b, $a)) { - return 1; - } - return 0; - } - - // }}} - // {{{ _sortDirs() - function _sortDirs($a, $b) - { - if (strnatcmp($a, $b) == -1) return 1; - if (strnatcmp($a, $b) == 1) return -1; - return 0; - } - - // }}} - - // {{{ _buildCallback() - - function _buildCallback($what, $data) + function _pkginfo_cdata_1_0($xp, $data) { - if (($what == 'cmdoutput' && $this->debug > 1) || - ($what == 'output' && $this->debug > 0)) { - $this->ui->outputData(rtrim($data), 'build'); + if (isset($this->cdata)) { + $this->cdata .= $data; } } // }}} -} - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Role.php,v 1.22 2009/04/10 19:42:49 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * base class for installer roles - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role/Common.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role -{ - /** - * Set up any additional configuration variables that file roles require - * - * Never call this directly, it is called by the PEAR_Config constructor - * @param PEAR_Config - * @access private - * @static - */ - function initializeConfig(&$config) - { - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { - PEAR_Installer_Role::registerRoles(); - } - - foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $class => $info) { - if (!$info['config_vars']) { - continue; - } - - $config->_addConfigVars($class, $info['config_vars']); - } - } - - /** - * @param PEAR_PackageFile_v2 - * @param string role name - * @param PEAR_Config - * @return PEAR_Installer_Role_Common - * @static - */ - function &factory($pkg, $role, &$config) - { - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { - PEAR_Installer_Role::registerRoles(); - } - - if (!in_array($role, PEAR_Installer_Role::getValidRoles($pkg->getPackageType()))) { - $a = false; - return $a; - } - - $a = 'PEAR_Installer_Role_' . ucfirst($role); - if (!class_exists($a)) { - require_once 'phar://install-pear-nozlib.phar/' . str_replace('_', '/', $a) . '.php'; - } - - $b = new $a($config); - return $b; - } - - /** - * Get a list of file roles that are valid for the particular release type. - * - * For instance, src files serve no purpose in regular php releases. - * @param string - * @param bool clear cache - * @return array - * @static - */ - function getValidRoles($release, $clear = false) - { - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { - PEAR_Installer_Role::registerRoles(); - } - - static $ret = array(); - if ($clear) { - $ret = array(); - } - - if (isset($ret[$release])) { - return $ret[$release]; - } - - $ret[$release] = array(); - foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { - if (in_array($release, $okreleases['releasetypes'])) { - $ret[$release][] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); - } - } - - return $ret[$release]; - } - - /** - * Get a list of roles that require their files to be installed - * - * Most roles must be installed, but src and package roles, for instance - * are pseudo-roles. src files are compiled into a new extension. Package - * roles are actually fully bundled releases of a package - * @param bool clear cache - * @return array - * @static - */ - function getInstallableRoles($clear = false) - { - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { - PEAR_Installer_Role::registerRoles(); - } - - static $ret; - if ($clear) { - unset($ret); - } - - if (isset($ret)) { - return $ret; - } - - $ret = array(); - foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { - if ($okreleases['installable']) { - $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); - } - } - - return $ret; - } - - /** - * Return an array of roles that are affected by the baseinstalldir attribute - * - * Most roles ignore this attribute, and instead install directly into: - * PackageName/filepath - * so a tests file tests/file.phpt is installed into PackageName/tests/filepath.php - * @param bool clear cache - * @return array - * @static - */ - function getBaseinstallRoles($clear = false) - { - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { - PEAR_Installer_Role::registerRoles(); - } - - static $ret; - if ($clear) { - unset($ret); - } - - if (isset($ret)) { - return $ret; - } - - $ret = array(); - foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { - if ($okreleases['honorsbaseinstall']) { - $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); - } - } - - return $ret; - } - - /** - * Return an array of file roles that should be analyzed for PHP content at package time, - * like the "php" role. - * @param bool clear cache - * @return array - * @static - */ - function getPhpRoles($clear = false) - { - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'])) { - PEAR_Installer_Role::registerRoles(); - } - - static $ret; - if ($clear) { - unset($ret); - } - - if (isset($ret)) { - return $ret; - } - - $ret = array(); - foreach ($GLOBALS['_PEAR_INSTALLER_ROLES'] as $role => $okreleases) { - if ($okreleases['phpfile']) { - $ret[] = strtolower(str_replace('PEAR_Installer_Role_', '', $role)); - } - } - - return $ret; - } - - /** - * Scan through the Command directory looking for classes - * and see what commands they implement. - * @param string which directory to look for classes, defaults to - * the Installer/Roles subdirectory of - * the directory from where this file (__FILE__) is - * included. - * - * @return bool TRUE on success, a PEAR error on failure - * @access public - * @static - */ - function registerRoles($dir = null) - { - $GLOBALS['_PEAR_INSTALLER_ROLES'] = array(); - $parser = new PEAR_XMLParser; - if ($dir === null) { - $dir = dirname(__FILE__) . '/Role'; - } - - if (!file_exists($dir) || !is_dir($dir)) { - return PEAR::raiseError("registerRoles: opendir($dir) failed: does not exist/is not directory"); - } - - $dp = @opendir($dir); - if (empty($dp)) { - return PEAR::raiseError("registerRoles: opendir($dir) failed: $php_errmsg"); - } - - while ($entry = readdir($dp)) { - if ($entry{0} == '.' || substr($entry, -4) != '.xml') { - continue; - } - - $class = "PEAR_Installer_Role_".substr($entry, 0, -4); - // List of roles - if (!isset($GLOBALS['_PEAR_INSTALLER_ROLES'][$class])) { - $file = "$dir/$entry"; - $parser->parse(file_get_contents($file)); - $data = $parser->getData(); - if (!is_array($data['releasetypes'])) { - $data['releasetypes'] = array($data['releasetypes']); - } - - $GLOBALS['_PEAR_INSTALLER_ROLES'][$class] = $data; - } - } - - closedir($dp); - ksort($GLOBALS['_PEAR_INSTALLER_ROLES']); - PEAR_Installer_Role::getBaseinstallRoles(true); - PEAR_Installer_Role::getInstallableRoles(true); - PEAR_Installer_Role::getPhpRoles(true); - PEAR_Installer_Role::getValidRoles('****', true); - return true; - } -} - * @copyright 1997-2006 The PHP Group + * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.13 2009/02/24 23:39:37 dufuz Exp $ + * @version CVS: $Id: v2.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ /** - * Base class for all installation roles. - * - * This class allows extensibility of file roles. Packages with complex - * customization can now provide custom file roles along with the possibility of - * adding configuration values to match. + * base xml parser class + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2.php'; +/** + * Parser for package.xml version 2.0 * @category pear * @package PEAR * @author Greg Beaver - * @copyright 1997-2006 The PHP Group + * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ -class PEAR_Installer_Role_Common +class PEAR_PackageFile_Parser_v2 extends PEAR_XMLParser { - /** - * @var PEAR_Config - * @access protected - */ - var $config; - - /** - * @param PEAR_Config - */ - function PEAR_Installer_Role_Common(&$config) - { - $this->config = $config; - } + var $_config; + var $_logger; + var $_registry; - /** - * Retrieve configuration information about a file role from its XML info - * - * @param string $role Role Classname, as in "PEAR_Installer_Role_Data" - * @return array - */ - function getInfo($role) + function setConfig(&$c) { - if (empty($GLOBALS['_PEAR_INSTALLER_ROLES'][$role])) { - return PEAR::raiseError('Unknown Role class: "' . $role . '"'); - } - return $GLOBALS['_PEAR_INSTALLER_ROLES'][$role]; + $this->_config = &$c; + $this->_registry = &$c->getRegistry(); } + function setLogger(&$l) + { + $this->_logger = &$l; + } /** - * This is called for each file to set up the directories and files - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @param array attributes from the tag - * @param string file name - * @return array an array consisting of: + * Unindent given string * - * 1 the original, pre-baseinstalldir installation directory - * 2 the final installation directory - * 3 the full path to the final location of the file - * 4 the location of the pre-installation file + * @param string $str The string that has to be unindented. + * @return string + * @access private */ - function processInstallation($pkg, $atts, $file, $tmp_path, $layer = null) + function _unIndent($str) { - $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . - ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); - if (PEAR::isError($roleInfo)) { - return $roleInfo; - } - if (!$roleInfo['locationconfig']) { - return false; - } - if ($roleInfo['honorsbaseinstall']) { - $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], $layer, - $pkg->getChannel()); - if (!empty($atts['baseinstalldir'])) { - $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; - } - } elseif ($roleInfo['unusualbaseinstall']) { - $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], - $layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage(); - if (!empty($atts['baseinstalldir'])) { - $dest_dir .= DIRECTORY_SEPARATOR . $atts['baseinstalldir']; + // remove leading newlines + $str = preg_replace('/^[\r\n]+/', '', $str); + // find whitespace at the beginning of the first line + $indent_len = strspn($str, " \t"); + $indent = substr($str, 0, $indent_len); + $data = ''; + // remove the same amount of whitespace from following lines + foreach (explode("\n", $str) as $line) { + if (substr($line, 0, $indent_len) == $indent) { + $data .= substr($line, $indent_len) . "\n"; + } else { + $data .= $line . "\n"; } - } else { - $dest_dir = $save_destdir = $this->config->get($roleInfo['locationconfig'], - $layer, $pkg->getChannel()) . DIRECTORY_SEPARATOR . $pkg->getPackage(); - } - if (dirname($file) != '.' && empty($atts['install-as'])) { - $dest_dir .= DIRECTORY_SEPARATOR . dirname($file); } - if (empty($atts['install-as'])) { - $dest_file = $dest_dir . DIRECTORY_SEPARATOR . basename($file); - } else { - $dest_file = $dest_dir . DIRECTORY_SEPARATOR . $atts['install-as']; - } - $orig_file = $tmp_path . DIRECTORY_SEPARATOR . $file; - - // Clean up the DIRECTORY_SEPARATOR mess - $ds2 = DIRECTORY_SEPARATOR . DIRECTORY_SEPARATOR; - - list($dest_dir, $dest_file, $orig_file) = preg_replace(array('!\\\\+!', '!/!', "!$ds2+!"), - array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR, - DIRECTORY_SEPARATOR), - array($dest_dir, $dest_file, $orig_file)); - return array($save_destdir, $dest_dir, $dest_file, $orig_file); + return $data; } /** - * Get the name of the configuration variable that specifies the location of this file - * @return string|false + * post-process data + * + * @param string $data + * @param string $element element name */ - function getLocationConfig() + function postProcess($data, $element) { - $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . - ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); - if (PEAR::isError($roleInfo)) { - return $roleInfo; + if ($element == 'notes') { + return trim($this->_unIndent($data)); } - return $roleInfo['locationconfig']; + return trim($data); } /** - * Do any unusual setup here - * @param PEAR_Installer - * @param PEAR_PackageFile_v2 - * @param array file attributes - * @param string file name + * @param string + * @param string file name of the package.xml + * @param string|false name of the archive this package.xml came from, if any + * @param string class name to instantiate and return. This must be PEAR_PackageFile_v2 or + * a subclass + * @return PEAR_PackageFile_v2 */ - function setup(&$installer, $pkg, $atts, $file) - { - } - - function isExecutable() + function &parse($data, $file, $archive = false, $class = 'PEAR_PackageFile_v2') { - $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . - ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); - if (PEAR::isError($roleInfo)) { - return $roleInfo; + if (PEAR::isError($err = parent::parse($data, $file))) { + return $err; } - return $roleInfo['executable']; - } - function isInstallable() - { - $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . - ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); - if (PEAR::isError($roleInfo)) { - return $roleInfo; + $ret = new $class; + $ret->encoding = $this->encoding; + $ret->setConfig($this->_config); + if (isset($this->_logger)) { + $ret->setLogger($this->_logger); } - return $roleInfo['installable']; - } - function isExtension() - { - $roleInfo = PEAR_Installer_Role_Common::getInfo('PEAR_Installer_Role_' . - ucfirst(str_replace('pear_installer_role_', '', strtolower(get_class($this))))); - if (PEAR::isError($roleInfo)) { - return $roleInfo; - } - return $roleInfo['phpextension']; + $ret->fromArray($this->_unserializedData); + $ret->setPackagefile($file, $archive); + return $ret; } -} -?> - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Data.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role_Data extends PEAR_Installer_Role_Common {} -?> - php - extsrc - extbin - zendextsrc - zendextbin - 1 - data_dir - - - - - - - - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Doc.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role_Doc extends PEAR_Installer_Role_Common {} -?> - php - extsrc - extbin - zendextsrc - zendextbin - 1 - doc_dir - - - - - - - - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Php.php,v 1.9 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role_Php extends PEAR_Installer_Role_Common {} -?> - php - extsrc - extbin - zendextsrc - zendextbin - 1 - php_dir - 1 - - 1 - - - - - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Script.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role_Script extends PEAR_Installer_Role_Common {} -?> - php - extsrc - extbin - zendextsrc - zendextbin - 1 - bin_dir - 1 - - - 1 - - - - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Test.php,v 1.8 2009/02/24 23:39:37 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ - -/** - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Installer_Role_Test extends PEAR_Installer_Role_Common {} -?> - php - extsrc - extbin - zendextsrc - zendextbin - 1 - test_dir - - - - - - - * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PackageFile.php,v 1.48 2009/04/09 22:16:26 dufuz Exp $ + * @version CVS: $Id: v1.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ +/** + * For error handling + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ErrorStack.php'; /** - * needed for PEAR_VALIDATE_* constants + * Error code if parsing is attempted with no xml extension */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validate.php'; +define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3); + /** - * Error code if the package.xml tag does not contain a valid version + * Error code if creating the xml parser resource fails */ -define('PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION', 1); +define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4); + /** - * Error code if the package.xml tag version is not supported (version 1.0 and 1.1 are the only supported versions, - * currently + * Error code used for all sax xml parsing errors */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_PACKAGEVERSION', 2); +define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5); + /** - * Abstraction for the package.xml package description file - * + * Error code used when there is no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6); + +/** + * Error code when a package name is not valid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7); + +/** + * Error code used when no summary is parsed + */ +define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8); + +/** + * Error code for summaries that are more than 1 line + */ +define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9); + +/** + * Error code used when no description is present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10); + +/** + * Error code used when no license is present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11); + +/** + * Error code used when a version number is not present + */ +define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12); + +/** + * Error code used when a version number is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13); + +/** + * Error code when release state is missing + */ +define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14); + +/** + * Error code when release state is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15); + +/** + * Error code when release state is missing + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16); + +/** + * Error code when release state is invalid + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17); + +/** + * Error code when no release notes are found + */ +define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18); + +/** + * Error code when no maintainers are found + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21); + +/** + * Error code when a maintainer has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22); + +/** + * Error code when a maintainer has no email + */ +define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23); + +/** + * Error code when a maintainer has no handle + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24); + +/** + * Error code when a dependency is not a PHP dependency, but has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25); + +/** + * Error code when a dependency has no type (pkg, php, etc.) + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26); + +/** + * Error code when a dependency has no relation (lt, ge, has, etc.) + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27); + +/** + * Error code when a dependency is not a 'has' relation, but has no version + */ +define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28); + +/** + * Error code when a dependency has an invalid relation + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29); + +/** + * Error code when a dependency has an invalid type + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30); + +/** + * Error code when a dependency has an invalid optional option + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31); + +/** + * Error code when a dependency is a pkg dependency, and has an invalid package name + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32); + +/** + * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel + */ +define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33); + +/** + * Error code when rel="has" and version attribute is present. + */ +define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34); + +/** + * Error code when type="php" and dependency name is present + */ +define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35); + +/** + * Error code when a configure option has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36); + +/** + * Error code when a configure option has no name + */ +define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37); + +/** + * Error code when a file in the filelist has an invalid role + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38); + +/** + * Error code when a file in the filelist has no role + */ +define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39); + +/** + * Error code when analyzing a php source file that has parse errors + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40); + +/** + * Error code when analyzing a php source file reveals a source element + * without a package name prefix + */ +define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41); + +/** + * Error code when an unknown channel is specified + */ +define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42); + +/** + * Error code when no files are found in the filelist + */ +define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43); + +/** + * Error code when a file is not valid php according to _analyzeSourceCode() + */ +define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44); + +/** + * Error code when the channel validator returns an error or warning + */ +define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45); + +/** + * Error code when a php5 package is packaged in php4 (analysis doesn't work) + */ +define('PEAR_PACKAGEFILE_ERROR_PHP5', 46); + +/** + * Error code when a file is listed in package.xml but does not exist + */ +define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47); + +/** + * Error code when a * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ -class PEAR_PackageFile +class PEAR_PackageFile_v1 { /** - * @var PEAR_Config + * @access private + * @var PEAR_ErrorStack + * @access private */ - var $_config; - var $_debug; + var $_stack; + /** - * Temp directory for uncompressing tgz files. - * @var string|false + * A registry object, used to access the package name validation regex for non-standard channels + * @var PEAR_Registry + * @access private */ - var $_tmpdir; - var $_logger = false; + var $_registry; + + /** + * An object that contains a log method that matches PEAR_Common::log's signature + * @var object + * @access private + */ + var $_logger; + + /** + * Parsed package information + * @var array + * @access private + */ + var $_packageInfo; + + /** + * path to package.xml + * @var string + * @access private + */ + var $_packageFile; + + /** + * path to package .tgz or false if this is a local/extracted package.xml + * @var string + * @access private + */ + var $_archiveFile; + + /** + * @var int + * @access private + */ + var $_isValid = 0; + /** + * Determines whether this packagefile was initialized only with partial package info + * + * If this package file was constructed via parsing REST, it will only contain + * + * - package name + * - channel name + * - dependencies * @var boolean + * @access private */ - var $_rawReturn = false; + var $_incomplete = true; + + /** + * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack + * @param string Name of Error Stack class to use. + */ + function PEAR_PackageFile_v1() + { + $this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1'); + $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); + $this->_isValid = 0; + } + + function installBinary($installer) + { + return false; + } + + function isExtension($name) + { + return false; + } + + function setConfig(&$config) + { + $this->_config = &$config; + $this->_registry = &$config->getRegistry(); + } + + function setRequestedGroup() + { + // placeholder + } /** + * For saving in the registry. * - * @param PEAR_Config $config - * @param ? $debug - * @param string @tmpdir Optional temporary directory for uncompressing - * files + * Set the last version that was installed + * @param string */ - function PEAR_PackageFile(&$config, $debug = false, $tmpdir = false) + function setLastInstalledVersion($version) + { + $this->_packageInfo['_lastversion'] = $version; + } + + /** + * @return string|false + */ + function getLastInstalledVersion() + { + if (isset($this->_packageInfo['_lastversion'])) { + return $this->_packageInfo['_lastversion']; + } + return false; + } + + function getInstalledBinary() + { + return false; + } + + function listPostinstallScripts() + { + return false; + } + + function initPostinstallScripts() + { + return false; + } + + function setLogger(&$logger) + { + if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) { + return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); + } + $this->_logger = &$logger; + } + + function setPackagefile($file, $archive = false) + { + $this->_packageFile = $file; + $this->_archiveFile = $archive ? $archive : $file; + } + + function getPackageFile() + { + return isset($this->_packageFile) ? $this->_packageFile : false; + } + + function getPackageType() { - $this->_config = $config; - $this->_debug = $debug; - $this->_tmpdir = $tmpdir; + return 'php'; } - /** - * Turn off validation - return a parsed package.xml without checking it - * - * This is used by the package-validate command - */ - function rawReturn() + function getArchiveFile() { - $this->_rawReturn = true; + return $this->_archiveFile; } - function setLogger(&$l) + function packageInfo($field) { - $this->_logger = &$l; + if (!is_string($field) || empty($field) || + !isset($this->_packageInfo[$field])) { + return false; + } + return $this->_packageInfo[$field]; } - /** - * Create a PEAR_PackageFile_Parser_v* of a given version. - * @param int $version - * @return PEAR_PackageFile_Parser_v1|PEAR_PackageFile_Parser_v1 - */ - function &parserFactory($version) + function setDirtree($path) { - if (!in_array($version{0}, array('1', '2'))) { - $a = false; - return $a; + if (!isset($this->_packageInfo['dirtree'])) { + $this->_packageInfo['dirtree'] = array(); } + $this->_packageInfo['dirtree'][$path] = true; + } - include_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/Parser/v' . $version{0} . '.php'; - $version = $version{0}; - $class = "PEAR_PackageFile_Parser_v$version"; - $a = new $class; - return $a; + function getDirtree() + { + if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { + return $this->_packageInfo['dirtree']; + } + return false; } - /** - * For simpler unit-testing - * @return string - */ - function getClassPrefix() + function resetDirtree() { - return 'PEAR_PackageFile_v'; + unset($this->_packageInfo['dirtree']); } - /** - * Create a PEAR_PackageFile_v* of a given version. - * @param int $version - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v1 - */ - function &factory($version) + function fromArray($pinfo) { - if (!in_array($version{0}, array('1', '2'))) { - $a = false; - return $a; - } + $this->_incomplete = false; + $this->_packageInfo = $pinfo; + } - include_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v' . $version{0} . '.php'; - $version = $version{0}; - $class = $this->getClassPrefix() . $version; - $a = new $class; - return $a; + function isIncomplete() + { + return $this->_incomplete; } - /** - * Create a PEAR_PackageFile_v* from its toArray() method - * - * WARNING: no validation is performed, the array is assumed to be valid, - * always parse from xml if you want validation. - * @param array $arr - * @return PEAR_PackageFileManager_v1|PEAR_PackageFileManager_v2 - * @uses factory() to construct the returned object. - */ - function &fromArray($arr) + function getChannel() { - if (isset($arr['xsdversion'])) { - $obj = &$this->factory($arr['xsdversion']); - if ($this->_logger) { - $obj->setLogger($this->_logger); - } + return 'pear.php.net'; + } - $obj->setConfig($this->_config); - $obj->fromArray($arr); - return $obj; - } + function getUri() + { + return false; + } - if (isset($arr['package']['attribs']['version'])) { - $obj = &$this->factory($arr['package']['attribs']['version']); - } else { - $obj = &$this->factory('1.0'); - } + function getTime() + { + return false; + } - if ($this->_logger) { - $obj->setLogger($this->_logger); + function getExtends() + { + if (isset($this->_packageInfo['extends'])) { + return $this->_packageInfo['extends']; } - - $obj->setConfig($this->_config); - $obj->fromArray($arr); - return $obj; + return false; } /** - * Create a PEAR_PackageFile_v* from an XML string. - * @access public - * @param string $data contents of package.xml file - * @param int $state package state (one of PEAR_VALIDATE_* constants) - * @param string $file full path to the package.xml file (and the files - * it references) - * @param string $archive optional name of the archive that the XML was - * extracted from, if any - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @uses parserFactory() to construct a parser to load the package. + * @return array */ - function &fromXmlString($data, $state, $file, $archive = false) + function toArray() { - if (preg_match('/]+version="([0-9]+\.[0-9]+)"/', $data, $packageversion)) { - if (!in_array($packageversion[1], array('1.0', '2.0', '2.1'))) { - return PEAR::raiseError('package.xml version "' . $packageversion[1] . - '" is not supported, only 1.0, 2.0, and 2.1 are supported.'); - } - - $object = &$this->parserFactory($packageversion[1]); - if ($this->_logger) { - $object->setLogger($this->_logger); - } + if (!$this->validate(PEAR_VALIDATE_NORMAL)) { + return false; + } + return $this->getArray(); + } - $object->setConfig($this->_config); - $pf = $object->parse($data, $file, $archive); - if (PEAR::isError($pf)) { - return $pf; - } + function getArray() + { + return $this->_packageInfo; + } - if ($this->_rawReturn) { - return $pf; - } + function getName() + { + return $this->getPackage(); + } - if (!$pf->validate($state)) { - if ($this->_config->get('verbose') > 0 - && $this->_logger && $pf->getValidationWarnings(false)) { - foreach ($pf->getValidationWarnings(false) as $warning) { - $this->_logger->log(0, 'ERROR: ' . $warning['message']); - } - } + function getPackage() + { + if (isset($this->_packageInfo['package'])) { + return $this->_packageInfo['package']; + } + return false; + } - $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', - 2, null, null, $pf->getValidationWarnings()); - return $a; - } + /** + * WARNING - don't use this unless you know what you are doing + */ + function setRawPackage($package) + { + $this->_packageInfo['package'] = $package; + } - if ($this->_logger && $pf->getValidationWarnings(false)) { - foreach ($pf->getValidationWarnings() as $warning) { - $this->_logger->log(0, 'WARNING: ' . $warning['message']); - } - } + function setPackage($package) + { + $this->_packageInfo['package'] = $package; + $this->_isValid = false; + } - if (method_exists($pf, 'flattenFilelist')) { - $pf->flattenFilelist(); // for v2 - } + function getVersion() + { + if (isset($this->_packageInfo['version'])) { + return $this->_packageInfo['version']; + } + return false; + } - return $pf; - } elseif (preg_match('/]+version="([^"]+)"/', $data, $packageversion)) { - $a = PEAR::raiseError('package.xml file "' . $file . - '" has unsupported package.xml version "' . $packageversion[1] . '"'); - return $a; - } else { - if (!class_exists('PEAR_ErrorStack')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ErrorStack.php'; - } + function setVersion($version) + { + $this->_packageInfo['version'] = $version; + $this->_isValid = false; + } - PEAR_ErrorStack::staticPush('PEAR_PackageFile', - PEAR_PACKAGEFILE_ERROR_NO_PACKAGEVERSION, - 'warning', array('xml' => $data), 'package.xml "' . $file . - '" has no package.xml version'); - $object = &$this->parserFactory('1.0'); - $object->setConfig($this->_config); - $pf = $object->parse($data, $file, $archive); - if (PEAR::isError($pf)) { - return $pf; - } + function clearMaintainers() + { + unset($this->_packageInfo['maintainers']); + } - if ($this->_rawReturn) { - return $pf; - } + function getMaintainers() + { + if (isset($this->_packageInfo['maintainers'])) { + return $this->_packageInfo['maintainers']; + } + return false; + } - if (!$pf->validate($state)) { - $a = PEAR::raiseError('Parsing of package.xml from file "' . $file . '" failed', - 2, null, null, $pf->getValidationWarnings()); - return $a; - } + /** + * Adds a new maintainer - no checking of duplicates is performed, use + * updatemaintainer for that purpose. + */ + function addMaintainer($role, $handle, $name, $email) + { + $this->_packageInfo['maintainers'][] = + array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name); + $this->_isValid = false; + } - if ($this->_logger && $pf->getValidationWarnings(false)) { - foreach ($pf->getValidationWarnings() as $warning) { - $this->_logger->log(0, 'WARNING: ' . $warning['message']); - } + function updateMaintainer($role, $handle, $name, $email) + { + $found = false; + if (!isset($this->_packageInfo['maintainers']) || + !is_array($this->_packageInfo['maintainers'])) { + return $this->addMaintainer($role, $handle, $name, $email); + } + foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { + if ($maintainer['handle'] == $handle) { + $found = $i; + break; } + } + if ($found !== false) { + unset($this->_packageInfo['maintainers'][$found]); + $this->_packageInfo['maintainers'] = + array_values($this->_packageInfo['maintainers']); + } + $this->addMaintainer($role, $handle, $name, $email); + } - if (method_exists($pf, 'flattenFilelist')) { - $pf->flattenFilelist(); // for v2 + function deleteMaintainer($handle) + { + $found = false; + foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { + if ($maintainer['handle'] == $handle) { + $found = $i; + break; } + } + if ($found !== false) { + unset($this->_packageInfo['maintainers'][$found]); + $this->_packageInfo['maintainers'] = + array_values($this->_packageInfo['maintainers']); + return true; + } + return false; + } - return $pf; + function getState() + { + if (isset($this->_packageInfo['release_state'])) { + return $this->_packageInfo['release_state']; } + return false; } - /** - * Register a temporary file or directory. When the destructor is - * executed, all registered temporary files and directories are - * removed. - * - * @param string $file name of file or directory - * @return void - */ - function addTempFile($file) + function setRawState($state) { - $GLOBALS['_PEAR_Common_tempfiles'][] = $file; + $this->_packageInfo['release_state'] = $state; } - /** - * Create a PEAR_PackageFile_v* from a compresed Tar or Tgz file. - * @access public - * @param string contents of package.xml file - * @param int package state (one of PEAR_VALIDATE_* constants) - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @using Archive_Tar to extract the files - * @using fromPackageFile() to load the package after the package.xml - * file is extracted. - */ - function &fromTgzFile($file, $state) + function setState($state) { - if (!class_exists('Archive_Tar')) { - require_once 'phar://install-pear-nozlib.phar/' . 'Archive/Tar.php'; - } + $this->_packageInfo['release_state'] = $state; + $this->_isValid = false; + } - $tar = new Archive_Tar($file); - if ($this->_debug <= 1) { - $tar->pushErrorHandling(PEAR_ERROR_RETURN); + function getDate() + { + if (isset($this->_packageInfo['release_date'])) { + return $this->_packageInfo['release_date']; } + return false; + } - $content = $tar->listContent(); - if ($this->_debug <= 1) { - $tar->popErrorHandling(); + function setDate($date) + { + $this->_packageInfo['release_date'] = $date; + $this->_isValid = false; + } + + function getLicense() + { + if (isset($this->_packageInfo['release_license'])) { + return $this->_packageInfo['release_license']; } + return false; + } - if (!is_array($content)) { - if (is_string($file) && strlen($file < 255) && - (!file_exists($file) || !@is_file($file))) { - $ret = PEAR::raiseError("could not open file \"$file\""); - return $ret; - } + function setLicense($date) + { + $this->_packageInfo['release_license'] = $date; + $this->_isValid = false; + } - $file = realpath($file); - $ret = PEAR::raiseError("Could not get contents of package \"$file\"". - '. Invalid tgz file.'); - return $ret; - } else { - if (!count($content) && !@is_file($file)) { - $ret = PEAR::raiseError("could not open file \"$file\""); - return $ret; - } + function getSummary() + { + if (isset($this->_packageInfo['summary'])) { + return $this->_packageInfo['summary']; } + return false; + } - $xml = null; - $origfile = $file; - foreach ($content as $file) { - $name = $file['filename']; - if ($name == 'package2.xml') { // allow a .tgz to distribute both versions - $xml = $name; - break; - } + function setSummary($summary) + { + $this->_packageInfo['summary'] = $summary; + $this->_isValid = false; + } - if ($name == 'package.xml') { - $xml = $name; - break; - } elseif (preg_match('/package.xml$/', $name, $match)) { - $xml = $name; - break; - } + function getDescription() + { + if (isset($this->_packageInfo['description'])) { + return $this->_packageInfo['description']; } + return false; + } - if ($this->_tmpdir) { - $tmpdir = $this->_tmpdir; - } else { - $tmpdir = System::mkTemp(array('-t', $this->_config->get('temp_dir'), '-d', 'pear')); - if ($tmpdir === false) { - $ret = PEAR::raiseError("there was a problem with getting the configured temp directory"); - return $ret; - } + function setDescription($desc) + { + $this->_packageInfo['description'] = $desc; + $this->_isValid = false; + } - PEAR_PackageFile::addTempFile($tmpdir); + function getNotes() + { + if (isset($this->_packageInfo['release_notes'])) { + return $this->_packageInfo['release_notes']; } + return false; + } - $this->_extractErrors(); - PEAR::staticPushErrorHandling(PEAR_ERROR_CALLBACK, array($this, '_extractErrors')); - if (!$xml || !$tar->extractList(array($xml), $tmpdir)) { - $extra = implode("\n", $this->_extractErrors()); - if ($extra) { - $extra = ' ' . $extra; - } + function setNotes($notes) + { + $this->_packageInfo['release_notes'] = $notes; + $this->_isValid = false; + } - PEAR::staticPopErrorHandling(); - $ret = PEAR::raiseError('could not extract the package.xml file from "' . - $origfile . '"' . $extra); - return $ret; + function getDeps() + { + if (isset($this->_packageInfo['release_deps'])) { + return $this->_packageInfo['release_deps']; } - - PEAR::staticPopErrorHandling(); - $ret = &PEAR_PackageFile::fromPackageFile("$tmpdir/$xml", $state, $origfile); - return $ret; + return false; } /** - * helper for extracting Archive_Tar errors - * @var array - * @access private + * Reset dependencies prior to adding new ones */ - var $_extractErrors = array(); + function clearDeps() + { + unset($this->_packageInfo['release_deps']); + } - /** - * helper callback for extracting Archive_Tar errors - * - * @param PEAR_Error|null $err - * @return array - * @access private - */ - function _extractErrors($err = null) + function addPhpDep($version, $rel) { - static $errors = array(); - if ($err === null) { - $e = $errors; - $errors = array(); - return $e; + $this->_isValid = false; + $this->_packageInfo['release_deps'][] = + array('type' => 'php', + 'rel' => $rel, + 'version' => $version); + } + + function addPackageDep($name, $version, $rel, $optional = 'no') + { + $this->_isValid = false; + $dep = + array('type' => 'pkg', + 'name' => $name, + 'rel' => $rel, + 'optional' => $optional); + if ($rel != 'has' && $rel != 'not') { + $dep['version'] = $version; } - $errors[] = $err->getMessage(); + $this->_packageInfo['release_deps'][] = $dep; + } + + function addExtensionDep($name, $version, $rel, $optional = 'no') + { + $this->_isValid = false; + $this->_packageInfo['release_deps'][] = + array('type' => 'ext', + 'name' => $name, + 'rel' => $rel, + 'version' => $version, + 'optional' => $optional); } /** - * Create a PEAR_PackageFile_v* from a package.xml file. - * - * @access public - * @param string $descfile name of package xml file - * @param int $state package state (one of PEAR_VALIDATE_* constants) - * @param string|false $archive name of the archive this package.xml came - * from, if any - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @uses PEAR_PackageFile::fromXmlString to create the oject after the - * XML is loaded from the package.xml file. + * WARNING - do not use this function directly unless you know what you're doing */ - function &fromPackageFile($descfile, $state, $archive = false) + function setDeps($deps) { - $fp = false; - if (is_string($descfile) && strlen($descfile) < 255 && - ( - !file_exists($descfile) || !is_file($descfile) || !is_readable($descfile) - || (!$fp = @fopen($descfile, 'r')) - ) - ) { - $a = PEAR::raiseError("Unable to open $descfile"); - return $a; - } + $this->_packageInfo['release_deps'] = $deps; + } - // read the whole thing so we only get one cdata callback - // for each block of cdata - fclose($fp); - $data = file_get_contents($descfile); - $ret = &PEAR_PackageFile::fromXmlString($data, $state, $descfile, $archive); - return $ret; + function hasDeps() + { + return isset($this->_packageInfo['release_deps']) && + count($this->_packageInfo['release_deps']); } + function getDependencyGroup($group) + { + return false; + } - /** - * Create a PEAR_PackageFile_v* from a .tgz archive or package.xml file. - * - * This method is able to extract information about a package from a .tgz - * archive or from a XML package definition file. - * - * @access public - * @param string $info file name - * @param int $state package state (one of PEAR_VALIDATE_* constants) - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @uses fromPackageFile() if the file appears to be XML - * @uses fromTgzFile() to load all non-XML files - */ - function &fromAnyFile($info, $state) + function isCompatible($pf) { - if (is_dir($info)) { - $dir_name = realpath($info); - if (file_exists($dir_name . '/package.xml')) { - $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package.xml', $state); - } elseif (file_exists($dir_name . '/package2.xml')) { - $info = PEAR_PackageFile::fromPackageFile($dir_name . '/package2.xml', $state); - } else { - $info = PEAR::raiseError("No package definition found in '$info' directory"); + return false; + } + + function isSubpackageOf($p) + { + return $p->isSubpackage($this); + } + + function isSubpackage($p) + { + return false; + } + + function dependsOn($package, $channel) + { + if (strtolower($channel) != 'pear.php.net') { + return false; + } + if (!($deps = $this->getDeps())) { + return false; + } + foreach ($deps as $dep) { + if ($dep['type'] != 'pkg') { + continue; + } + if (strtolower($dep['name']) == strtolower($package)) { + return true; } + } + return false; + } - return $info; + function getConfigureOptions() + { + if (isset($this->_packageInfo['configure_options'])) { + return $this->_packageInfo['configure_options']; } + return false; + } - $fp = false; - if (is_string($info) && strlen($info) < 255 && - (file_exists($info) || ($fp = @fopen($info, 'r'))) - ) { + function hasConfigureOptions() + { + return isset($this->_packageInfo['configure_options']) && + count($this->_packageInfo['configure_options']); + } - if ($fp) { - fclose($fp); - } + function addConfigureOption($name, $prompt, $default = false) + { + $o = array('name' => $name, 'prompt' => $prompt); + if ($default !== false) { + $o['default'] = $default; + } + if (!isset($this->_packageInfo['configure_options'])) { + $this->_packageInfo['configure_options'] = array(); + } + $this->_packageInfo['configure_options'][] = $o; + } - $tmp = substr($info, -4); - if ($tmp == '.xml') { - $info = &PEAR_PackageFile::fromPackageFile($info, $state); - } elseif ($tmp == '.tar' || $tmp == '.tgz') { - $info = &PEAR_PackageFile::fromTgzFile($info, $state); - } else { - $fp = fopen($info, 'r'); - $test = fread($fp, 5); - fclose($fp); - if ($test == '_packageInfo['configure_options']); + } - return $info; + function getProvides() + { + if (isset($this->_packageInfo['provides'])) { + return $this->_packageInfo['provides']; } + return false; + } - $info = PEAR::raiseError("Cannot open '$info' for parsing"); - return $info; + function getProvidesExtension() + { + return false; } -} - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v1.php,v 1.76 2009/02/24 23:45:26 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/** - * needed for PEAR_VALIDATE_* constants - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validate.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2.php'; -/** - * This class converts a PEAR_PackageFile_v1 object into any output format. - * - * Supported output formats include array, XML string, and a PEAR_PackageFile_v2 - * object, for converting package.xml 1.0 into package.xml 2.0 with no sweat. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_PackageFile_Generator_v1 -{ - /** - * @var PEAR_PackageFile_v1 - */ - var $_packagefile; - function PEAR_PackageFile_Generator_v1(&$packagefile) + + function addFile($dir, $file, $attrs) { - $this->_packagefile = &$packagefile; + $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); + if ($dir == '/' || $dir == '') { + $dir = ''; + } else { + $dir .= '/'; + } + $file = $dir . $file; + $file = preg_replace('![\\/]+!', '/', $file); + $this->_packageInfo['filelist'][$file] = $attrs; } - function getPackagerVersion() + function getInstallationFilelist() { - return '1.8.0'; + return $this->getFilelist(); } - /** - * @param PEAR_Packager - * @param bool if true, a .tgz is written, otherwise a .tar is written - * @param string|null directory in which to save the .tgz - * @return string|PEAR_Error location of package or error object - */ - function toTgz(&$packager, $compress = true, $where = null) + function getFilelist() { - require_once 'phar://install-pear-nozlib.phar/' . 'Archive/Tar.php'; - if ($where === null) { - if (!($where = System::mktemp(array('-d')))) { - return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: mktemp failed'); - } - } elseif (!@System::mkDir(array('-p', $where))) { - return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: "' . $where . '" could' . - ' not be created'); - } - if (file_exists($where . DIRECTORY_SEPARATOR . 'package.xml') && - !is_file($where . DIRECTORY_SEPARATOR . 'package.xml')) { - return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: unable to save package.xml as' . - ' "' . $where . DIRECTORY_SEPARATOR . 'package.xml"'); - } - if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) { - return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: invalid package file'); + if (isset($this->_packageInfo['filelist'])) { + return $this->_packageInfo['filelist']; } - $pkginfo = $this->_packagefile->getArray(); - $ext = $compress ? '.tgz' : '.tar'; - $pkgver = $pkginfo['package'] . '-' . $pkginfo['version']; - $dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext; - if (file_exists(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext) && - !is_file(getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext)) { - return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: cannot create tgz file "' . - getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext . '"'); + return false; + } + + function setFileAttribute($file, $attr, $value) + { + $this->_packageInfo['filelist'][$file][$attr] = $value; + } + + function resetFilelist() + { + $this->_packageInfo['filelist'] = array(); + } + + function setInstalledAs($file, $path) + { + if ($path) { + return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; } - if ($pkgfile = $this->_packagefile->getPackageFile()) { - $pkgdir = dirname(realpath($pkgfile)); - $pkgfile = basename($pkgfile); + unset($this->_packageInfo['filelist'][$file]['installed_as']); + } + + function installedFile($file, $atts) + { + if (isset($this->_packageInfo['filelist'][$file])) { + $this->_packageInfo['filelist'][$file] = + array_merge($this->_packageInfo['filelist'][$file], $atts); } else { - return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: package file object must ' . - 'be created from a real file'); + $this->_packageInfo['filelist'][$file] = $atts; } - // {{{ Create the package file list - $filelist = array(); - $i = 0; + } - foreach ($this->_packagefile->getFilelist() as $fname => $atts) { - $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; - if (!file_exists($file)) { - return PEAR::raiseError("File does not exist: $fname"); - } else { - $filelist[$i++] = $file; - if (!isset($atts['md5sum'])) { - $this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($file)); - } - $packager->log(2, "Adding file $fname"); - } - } - // }}} - $packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true); - if ($packagexml) { - $tar =& new Archive_Tar($dest_package, $compress); - $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors - // ----- Creates with the package.xml file - $ok = $tar->createModify(array($packagexml), '', $where); - if (PEAR::isError($ok)) { - return $ok; - } elseif (!$ok) { - return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed'); - } - // ----- Add the content of the package - if (!$tar->addModify($filelist, $pkgver, $pkgdir)) { - return PEAR::raiseError('PEAR_Packagefile_v1::toTgz: tarball creation failed'); - } - return $dest_package; + function getChangelog() + { + if (isset($this->_packageInfo['changelog'])) { + return $this->_packageInfo['changelog']; } + return false; + } + + function getPackagexmlVersion() + { + return '1.0'; } /** - * @param string|null directory to place the package.xml in, or null for a temporary dir - * @param int one of the PEAR_VALIDATE_* constants - * @param string name of the generated file - * @param bool if true, then no analysis will be performed on role="php" files - * @return string|PEAR_Error path to the created file on success + * Wrapper to {@link PEAR_ErrorStack::getErrors()} + * @param boolean determines whether to purge the error stack after retrieving + * @return array */ - function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml', - $nofilechecking = false) + function getValidationWarnings($purge = true) { - if (!$this->_packagefile->validate($state, $nofilechecking)) { - return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: invalid package.xml', - null, null, null, $this->_packagefile->getValidationWarnings()); - } - if ($where === null) { - if (!($where = System::mktemp(array('-d')))) { - return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: mktemp failed'); - } - } elseif (!@System::mkDir(array('-p', $where))) { - return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: "' . $where . '" could' . - ' not be created'); - } - $newpkgfile = $where . DIRECTORY_SEPARATOR . $name; - $np = @fopen($newpkgfile, 'wb'); - if (!$np) { - return PEAR::raiseError('PEAR_Packagefile_v1::toPackageFile: unable to save ' . - "$name as $newpkgfile"); - } - fwrite($np, $this->toXml($state, true)); - fclose($np); - return $newpkgfile; + return $this->_stack->getErrors($purge); } + // }}} /** - * fix both XML encoding to be UTF8, and replace standard XML entities < > " & ' - * - * @param string $string - * @return string + * Validation error. Also marks the object contents as invalid + * @param error code + * @param array error information * @access private */ - function _fixXmlEncoding($string) + function _validateError($code, $params = array()) { - if (version_compare(phpversion(), '5.0.0', 'lt')) { - $string = utf8_encode($string); - } - return strtr($string, array( - '&' => '&', - '>' => '>', - '<' => '<', - '"' => '"', - '\'' => ''' )); + $this->_stack->push($code, 'error', $params, false, false, debug_backtrace()); + $this->_isValid = false; } /** - * Return an XML document based on the package info (as returned - * by the PEAR_Common::infoFrom* methods). - * - * @return string XML data + * Validation warning. Does not mark the object contents invalid. + * @param error code + * @param array error information + * @access private */ - function toXml($state = PEAR_VALIDATE_NORMAL, $nofilevalidation = false) + function _validateWarning($code, $params = array()) { - $this->_packagefile->setDate(date('Y-m-d')); - if (!$this->_packagefile->validate($state, $nofilevalidation)) { - return false; - } - $pkginfo = $this->_packagefile->getArray(); - static $maint_map = array( - "handle" => "user", - "name" => "name", - "email" => "email", - "role" => "role", - ); - $ret = "\n"; - $ret .= "\n"; - $ret .= "\n" . -" $pkginfo[package]"; - if (isset($pkginfo['extends'])) { - $ret .= "\n$pkginfo[extends]"; - } - $ret .= - "\n ".$this->_fixXmlEncoding($pkginfo['summary'])."\n" . -" ".trim($this->_fixXmlEncoding($pkginfo['description']))."\n \n" . -" \n"; - foreach ($pkginfo['maintainers'] as $maint) { - $ret .= " \n"; - foreach ($maint_map as $idx => $elm) { - $ret .= " <$elm>"; - $ret .= $this->_fixXmlEncoding($maint[$idx]); - $ret .= "\n"; - } - $ret .= " \n"; - } - $ret .= " \n"; - $ret .= $this->_makeReleaseXml($pkginfo, false, $state); - if (isset($pkginfo['changelog']) && count($pkginfo['changelog']) > 0) { - $ret .= " \n"; - foreach ($pkginfo['changelog'] as $oldrelease) { - $ret .= $this->_makeReleaseXml($oldrelease, true); - } - $ret .= " \n"; - } - $ret .= "\n"; - return $ret; + $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace()); } - // }}} - // {{{ _makeReleaseXml() + /** + * @param integer error code + * @access protected + */ + function _getErrorMessage() + { + return array( + PEAR_PACKAGEFILE_ERROR_NO_NAME => + 'Missing Package Name', + PEAR_PACKAGEFILE_ERROR_NO_SUMMARY => + 'No summary found', + PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY => + 'Summary should be on one line', + PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION => + 'Missing description', + PEAR_PACKAGEFILE_ERROR_NO_LICENSE => + 'Missing license', + PEAR_PACKAGEFILE_ERROR_NO_VERSION => + 'No release version found', + PEAR_PACKAGEFILE_ERROR_NO_STATE => + 'No release state found', + PEAR_PACKAGEFILE_ERROR_NO_DATE => + 'No release date found', + PEAR_PACKAGEFILE_ERROR_NO_NOTES => + 'No release notes found', + PEAR_PACKAGEFILE_ERROR_NO_LEAD => + 'Package must have at least one lead maintainer', + PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS => + 'No maintainers found, at least one must be defined', + PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE => + 'Maintainer %index% has no handle (user ID at channel server)', + PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE => + 'Maintainer %index% has no role', + PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME => + 'Maintainer %index% has no name', + PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL => + 'Maintainer %index% has no email', + PEAR_PACKAGEFILE_ERROR_NO_DEPNAME => + 'Dependency %index% is not a php dependency, and has no name', + PEAR_PACKAGEFILE_ERROR_NO_DEPREL => + 'Dependency %index% has no relation (rel)', + PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE => + 'Dependency %index% has no type', + PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED => + 'PHP Dependency %index% has a name attribute of "%name%" which will be' . + ' ignored!', + PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION => + 'Dependency %index% is not a rel="has" or rel="not" dependency, ' . + 'and has no version', + PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION => + 'Dependency %index% is a type="php" dependency, ' . + 'and has no version', + PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED => + 'Dependency %index% is a rel="%rel%" dependency, versioning is ignored', + PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL => + 'Dependency %index% has invalid optional value "%opt%", should be yes or no', + PEAR_PACKAGEFILE_PHP_NO_NOT => + 'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' . + ' to exclude specific versions', + PEAR_PACKAGEFILE_ERROR_NO_CONFNAME => + 'Configure Option %index% has no name', + PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT => + 'Configure Option %index% has no prompt', + PEAR_PACKAGEFILE_ERROR_NO_FILES => + 'No files in section of package.xml', + PEAR_PACKAGEFILE_ERROR_NO_FILEROLE => + 'File "%file%" has no role, expecting one of "%roles%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE => + 'File "%file%" has invalid role "%role%", expecting one of "%roles%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME => + 'File "%file%" cannot start with ".", cannot package or install', + PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE => + 'Parser error: invalid PHP found in file "%file%"', + PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX => + 'in %file%: %type% "%name%" not prefixed with package name "%package%"', + PEAR_PACKAGEFILE_ERROR_INVALID_FILE => + 'Parser error: invalid PHP file "%file%"', + PEAR_PACKAGEFILE_ERROR_CHANNELVAL => + 'Channel validator error: field "%field%" - %reason%', + PEAR_PACKAGEFILE_ERROR_PHP5 => + 'Error, PHP5 token encountered in %file%, analysis should be in PHP5', + PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND => + 'File "%file%" in package.xml does not exist', + PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS => + 'Package.xml contains non-ISO-8859-1 characters, and may not validate', + ); + } /** - * Generate part of an XML description with release information. - * - * @param array $pkginfo array with release information - * @param bool $changelog whether the result will be in a changelog element - * - * @return string XML data + * Validate XML package definition file. * - * @access private + * @access public + * @return boolean */ - function _makeReleaseXml($pkginfo, $changelog = false, $state = PEAR_VALIDATE_NORMAL) + function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false) { - // XXX QUOTE ENTITIES IN PCDATA, OR EMBED IN CDATA BLOCKS!! - $indent = $changelog ? " " : ""; - $ret = "$indent \n"; - if (!empty($pkginfo['version'])) { - $ret .= "$indent $pkginfo[version]\n"; + if (($this->_isValid & $state) == $state) { + return true; } - if (!empty($pkginfo['release_date'])) { - $ret .= "$indent $pkginfo[release_date]\n"; + $this->_isValid = true; + $info = $this->_packageInfo; + if (empty($info['package'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME); + $this->_packageName = $pn = 'unknown'; + } else { + $this->_packageName = $pn = $info['package']; } - if (!empty($pkginfo['release_license'])) { - $ret .= "$indent $pkginfo[release_license]\n"; + + if (empty($info['summary'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY); + } elseif (strpos(trim($info['summary']), "\n") !== false) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY, + array('summary' => $info['summary'])); } - if (!empty($pkginfo['release_state'])) { - $ret .= "$indent $pkginfo[release_state]\n"; + if (empty($info['description'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION); } - if (!empty($pkginfo['release_notes'])) { - $ret .= "$indent ".trim($this->_fixXmlEncoding($pkginfo['release_notes'])) - ."\n$indent \n"; + if (empty($info['release_license'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE); } - if (!empty($pkginfo['release_warnings'])) { - $ret .= "$indent ".$this->_fixXmlEncoding($pkginfo['release_warnings'])."\n"; + if (empty($info['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION); } - if (isset($pkginfo['release_deps']) && sizeof($pkginfo['release_deps']) > 0) { - $ret .= "$indent \n"; - foreach ($pkginfo['release_deps'] as $dep) { - $ret .= "$indent _validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE); + } + if (empty($info['release_date'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE); + } + if (empty($info['release_notes'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES); + } + if (empty($info['maintainers'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS); + } else { + $haslead = false; + $i = 1; + foreach ($info['maintainers'] as $m) { + if (empty($m['handle'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE, + array('index' => $i)); + } + if (empty($m['role'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE, + array('index' => $i, 'roles' => PEAR_Common::getUserRoles())); + } elseif ($m['role'] == 'lead') { + $haslead = true; + } + if (empty($m['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME, + array('index' => $i)); + } + if (empty($m['email'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL, + array('index' => $i)); + } + $i++; + } + if (!$haslead) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD); + } + } + if (!empty($info['release_deps'])) { + $i = 1; + foreach ($info['release_deps'] as $d) { + if (!isset($d['type']) || empty($d['type'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE, + array('index' => $i, 'types' => PEAR_Common::getDependencyTypes())); + continue; } - if (isset($dep['optional'])) { - $ret .= " optional=\"$dep[optional]\""; + if (!isset($d['rel']) || empty($d['rel'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL, + array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations())); + continue; } - if (isset($dep['name'])) { - $ret .= ">$dep[name]\n"; - } else { - $ret .= "/>\n"; + if (!empty($d['optional'])) { + if (!in_array($d['optional'], array('yes', 'no'))) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL, + array('index' => $i, 'opt' => $d['optional'])); + } } - } - $ret .= "$indent \n"; - } - if (isset($pkginfo['configure_options'])) { - $ret .= "$indent \n"; - foreach ($pkginfo['configure_options'] as $c) { - $ret .= "$indent _fixXmlEncoding($c['name']) . "\""; - if (isset($c['default'])) { - $ret .= " default=\"" . $this->_fixXmlEncoding($c['default']) . "\""; + if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION, + array('index' => $i)); + } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED, + array('index' => $i, 'rel' => $d['rel'])); } - $ret .= " prompt=\"" . $this->_fixXmlEncoding($c['prompt']) . "\""; - $ret .= "/>\n"; + if ($d['type'] == 'php' && !empty($d['name'])) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED, + array('index' => $i, 'name' => $d['name'])); + } elseif ($d['type'] != 'php' && empty($d['name'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME, + array('index' => $i)); + } + if ($d['type'] == 'php' && empty($d['version'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION, + array('index' => $i)); + } + if (($d['rel'] == 'not') && ($d['type'] == 'php')) { + $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT, + array('index' => $i)); + } + $i++; } - $ret .= "$indent \n"; } - if (isset($pkginfo['provides'])) { - foreach ($pkginfo['provides'] as $key => $what) { - $ret .= "$indent _validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME, + array('index' => $i)); } - $ret .= "/>\n"; + if (empty($c['prompt'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT, + array('index' => $i)); + } + $i++; } } - if (isset($pkginfo['filelist'])) { - $ret .= "$indent \n"; - if ($state ^ PEAR_VALIDATE_PACKAGING) { - $ret .= $this->recursiveXmlFilelist($pkginfo['filelist']); - } else { - foreach ($pkginfo['filelist'] as $file => $fa) { - if (!isset($fa['role'])) { - $fa['role'] = ''; - } - $ret .= "$indent _fixXmlEncoding($fa['baseinstalldir']) . '"'; - } - if (isset($fa['md5sum'])) { - $ret .= " md5sum=\"$fa[md5sum]\""; - } - if (isset($fa['platform'])) { - $ret .= " platform=\"$fa[platform]\""; - } - if (!empty($fa['install-as'])) { - $ret .= ' install-as="' . - $this->_fixXmlEncoding($fa['install-as']) . '"'; - } - $ret .= ' name="' . $this->_fixXmlEncoding($file) . '"'; - if (empty($fa['replacements'])) { - $ret .= "/>\n"; - } else { - $ret .= ">\n"; - foreach ($fa['replacements'] as $r) { - $ret .= "$indent $v) { - $ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"'; - } - $ret .= "/>\n"; - } - $ret .= "$indent \n"; - } + if (empty($info['filelist'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES); + $errors[] = 'no files'; + } else { + foreach ($info['filelist'] as $file => $fa) { + if (empty($fa['role'])) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE, + array('file' => $file, 'roles' => PEAR_Common::getFileRoles())); + continue; + } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE, + array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles())); + } + if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) { + // file contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file)); + } + if (isset($fa['install-as']) && + preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $fa['install-as']))) { + // install-as contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file . ' [installed as ' . $fa['install-as'] . ']')); + } + if (isset($fa['baseinstalldir']) && + preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $fa['baseinstalldir']))) { + // install-as contains .. parent directory or . cur directory references + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, + array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']')); } } - $ret .= "$indent \n"; } - $ret .= "$indent \n"; - return $ret; - } - - /** - * @param array - * @access protected - */ - function recursiveXmlFilelist($list) - { - $this->_dirs = array(); - foreach ($list as $file => $attributes) { - $this->_addDir($this->_dirs, explode('/', dirname($file)), $file, $attributes); + if (isset($this->_registry) && $this->_isValid) { + $chan = $this->_registry->getChannel('pear.php.net'); + if (PEAR::isError($chan)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage()); + return $this->_isValid = 0; + } + $validator = $chan->getValidationObject(); + $validator->setPackageFile($this); + $validator->validate($state); + $failures = $validator->getFailures(); + foreach ($failures['errors'] as $error) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error); + } + foreach ($failures['warnings'] as $warning) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning); + } } - return $this->_formatDir($this->_dirs); - } - - /** - * @param array - * @param array - * @param string|null - * @param array|null - * @access private - */ - function _addDir(&$dirs, $dir, $file = null, $attributes = null) - { - if ($dir == array() || $dir == array('.')) { - $dirs['files'][basename($file)] = $attributes; - return; + if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) { + if ($this->_analyzePhpFiles()) { + $this->_isValid = true; + } } - $curdir = array_shift($dir); - if (!isset($dirs['dirs'][$curdir])) { - $dirs['dirs'][$curdir] = array(); + if ($this->_isValid) { + return $this->_isValid = $state; } - $this->_addDir($dirs['dirs'][$curdir], $dir, $file, $attributes); + return $this->_isValid = 0; } - /** - * @param array - * @param string - * @param string - * @access private - */ - function _formatDir($dirs, $indent = '', $curdir = '') + function _analyzePhpFiles() { - $ret = ''; - if (!count($dirs)) { - return ''; + if (!$this->_isValid) { + return false; } - if (isset($dirs['dirs'])) { - uksort($dirs['dirs'], 'strnatcasecmp'); - foreach ($dirs['dirs'] as $dir => $contents) { - $usedir = "$curdir/$dir"; - $ret .= "$indent \n"; - $ret .= $this->_formatDir($contents, "$indent ", $usedir); - $ret .= "$indent \n"; + if (!isset($this->_packageFile)) { + return false; + } + $dir_prefix = dirname($this->_packageFile); + $common = new PEAR_Common; + $log = isset($this->_logger) ? array(&$this->_logger, 'log') : + array($common, 'log'); + $info = $this->getFilelist(); + foreach ($info as $file => $fa) { + if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND, + array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file)); + continue; + } + if ($fa['role'] == 'php' && $dir_prefix) { + call_user_func_array($log, array(1, "Analyzing $file")); + $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); + if ($srcinfo) { + $this->_buildProvidesArray($srcinfo); + } } } - if (isset($dirs['files'])) { - uksort($dirs['files'], 'strnatcasecmp'); - foreach ($dirs['files'] as $file => $attribs) { - $ret .= $this->_formatFile($file, $attribs, $indent); + $this->_packageName = $pn = $this->getPackage(); + $pnl = strlen($pn); + if (isset($this->_packageInfo['provides'])) { + foreach ((array) $this->_packageInfo['provides'] as $key => $what) { + if (isset($what['explicit'])) { + // skip conformance checks if the provides entry is + // specified in the package.xml file + continue; + } + extract($what); + if ($type == 'class') { + if (!strncasecmp($name, $pn, $pnl)) { + continue; + } + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); + } elseif ($type == 'function') { + if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { + continue; + } + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); + } } } - return $ret; + return $this->_isValid; } /** - * @param string - * @param array - * @param string - * @access private + * Get the default xml generator object + * + * @return PEAR_PackageFile_Generator_v1 */ - function _formatFile($file, $attributes, $indent) + function &getDefaultGenerator() { - $ret = "$indent _fixXmlEncoding($attributes['baseinstalldir']) . '"'; - } - if (isset($attributes['md5sum'])) { - $ret .= " md5sum=\"$attributes[md5sum]\""; - } - if (isset($attributes['platform'])) { - $ret .= " platform=\"$attributes[platform]\""; - } - if (!empty($attributes['install-as'])) { - $ret .= ' install-as="' . - $this->_fixXmlEncoding($attributes['install-as']) . '"'; - } - $ret .= ' name="' . $this->_fixXmlEncoding($file) . '"'; - if (empty($attributes['replacements'])) { - $ret .= "/>\n"; - } else { - $ret .= ">\n"; - foreach ($attributes['replacements'] as $r) { - $ret .= "$indent $v) { - $ret .= " $k=\"" . $this->_fixXmlEncoding($v) .'"'; - } - $ret .= "/>\n"; - } - $ret .= "$indent \n"; + if (!class_exists('PEAR_PackageFile_Generator_v1')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/Generator/v1.php'; } - return $ret; + $a = &new PEAR_PackageFile_Generator_v1($this); + return $a; } - // {{{ _unIndent() - /** - * Unindent given string (?) - * - * @param string $str The string that has to be unindented. + * Get the contents of a file listed within the package.xml + * @param string * @return string - * @access private */ - function _unIndent($str) + function getFileContents($file) { - // remove leading newlines - $str = preg_replace('/^[\r\n]+/', '', $str); - // find whitespace at the beginning of the first line - $indent_len = strspn($str, " \t"); - $indent = substr($str, 0, $indent_len); - $data = ''; - // remove the same amount of whitespace from following lines - foreach (explode("\n", $str) as $line) { - if (substr($line, 0, $indent_len) == $indent) { - $data .= substr($line, $indent_len) . "\n"; + if ($this->_archiveFile == $this->_packageFile) { // unpacked + $dir = dirname($this->_packageFile); + $file = $dir . DIRECTORY_SEPARATOR . $file; + $file = str_replace(array('/', '\\'), + array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); + if (file_exists($file) && is_readable($file)) { + return implode('', file($file)); + } + } else { // tgz + if (!class_exists('Archive_Tar')) { + require_once 'phar://install-pear-nozlib.phar/' . 'Archive/Tar.php'; + } + $tar = &new Archive_Tar($this->_archiveFile); + $tar->pushErrorHandling(PEAR_ERROR_RETURN); + if ($file != 'package.xml' && $file != 'package2.xml') { + $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; + } + $file = $tar->extractInString($file); + $tar->popErrorHandling(); + if (PEAR::isError($file)) { + return PEAR::raiseError("Cannot locate file '$file' in archive"); } + return $file; } - return $data; } + // {{{ analyzeSourceCode() /** - * @return array + * Analyze the source code of the given PHP file + * + * @param string Filename of the PHP file + * @return mixed + * @access private */ - function dependenciesToV2() + function _analyzeSourceCode($file) { - $arr = array(); - $this->_convertDependencies2_0($arr); - return $arr['dependencies']; + if (!function_exists("token_get_all")) { + return false; + } + if (!defined('T_DOC_COMMENT')) { + define('T_DOC_COMMENT', T_COMMENT); + } + if (!defined('T_INTERFACE')) { + define('T_INTERFACE', -1); + } + if (!defined('T_IMPLEMENTS')) { + define('T_IMPLEMENTS', -1); + } + if (!$fp = @fopen($file, "r")) { + return false; + } + fclose($fp); + $contents = file_get_contents($file); + $tokens = token_get_all($contents); +/* + for ($i = 0; $i < sizeof($tokens); $i++) { + @list($token, $data) = $tokens[$i]; + if (is_string($token)) { + var_dump($token); + } else { + print token_name($token) . ' '; + var_dump(rtrim($data)); + } + } +*/ + $look_for = 0; + $paren_level = 0; + $bracket_level = 0; + $brace_level = 0; + $lastphpdoc = ''; + $current_class = ''; + $current_interface = ''; + $current_class_level = -1; + $current_function = ''; + $current_function_level = -1; + $declared_classes = array(); + $declared_interfaces = array(); + $declared_functions = array(); + $declared_methods = array(); + $used_classes = array(); + $used_functions = array(); + $extends = array(); + $implements = array(); + $nodeps = array(); + $inquote = false; + $interface = false; + for ($i = 0; $i < sizeof($tokens); $i++) { + if (is_array($tokens[$i])) { + list($token, $data) = $tokens[$i]; + } else { + $token = $tokens[$i]; + $data = ''; + } + if ($inquote) { + if ($token != '"' && $token != T_END_HEREDOC) { + continue; + } else { + $inquote = false; + continue; + } + } + switch ($token) { + case T_WHITESPACE : + continue; + case ';': + if ($interface) { + $current_function = ''; + $current_function_level = -1; + } + break; + case '"': + case T_START_HEREDOC: + $inquote = true; + break; + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + case '{': $brace_level++; continue 2; + case '}': + $brace_level--; + if ($current_class_level == $brace_level) { + $current_class = ''; + $current_class_level = -1; + } + if ($current_function_level == $brace_level) { + $current_function = ''; + $current_function_level = -1; + } + continue 2; + case '[': $bracket_level++; continue 2; + case ']': $bracket_level--; continue 2; + case '(': $paren_level++; continue 2; + case ')': $paren_level--; continue 2; + case T_INTERFACE: + $interface = true; + case T_CLASS: + if (($current_class_level != -1) || ($current_function_level != -1)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, + array('file' => $file)); + return false; + } + case T_FUNCTION: + case T_NEW: + case T_EXTENDS: + case T_IMPLEMENTS: + $look_for = $token; + continue 2; + case T_STRING: + if (version_compare(zend_version(), '2.0', '<')) { + if (in_array(strtolower($data), + array('public', 'private', 'protected', 'abstract', + 'interface', 'implements', 'throw') + )) { + $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5, + array($file)); + } + } + if ($look_for == T_CLASS) { + $current_class = $data; + $current_class_level = $brace_level; + $declared_classes[] = $current_class; + } elseif ($look_for == T_INTERFACE) { + $current_interface = $data; + $current_class_level = $brace_level; + $declared_interfaces[] = $current_interface; + } elseif ($look_for == T_IMPLEMENTS) { + $implements[$current_class] = $data; + } elseif ($look_for == T_EXTENDS) { + $extends[$current_class] = $data; + } elseif ($look_for == T_FUNCTION) { + if ($current_class) { + $current_function = "$current_class::$data"; + $declared_methods[$current_class][] = $data; + } elseif ($current_interface) { + $current_function = "$current_interface::$data"; + $declared_methods[$current_interface][] = $data; + } else { + $current_function = $data; + $declared_functions[] = $current_function; + } + $current_function_level = $brace_level; + $m = array(); + } elseif ($look_for == T_NEW) { + $used_classes[$data] = true; + } + $look_for = 0; + continue 2; + case T_VARIABLE: + $look_for = 0; + continue 2; + case T_DOC_COMMENT: + case T_COMMENT: + if (preg_match('!^/\*\*\s!', $data)) { + $lastphpdoc = $data; + if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { + $nodeps = array_merge($nodeps, $m[1]); + } + } + continue 2; + case T_DOUBLE_COLON: + if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { + $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, + array('file' => $file)); + return false; + } + $class = $tokens[$i - 1][1]; + if (strtolower($class) != 'parent') { + $used_classes[$class] = true; + } + continue 2; + } + } + return array( + "source_file" => $file, + "declared_classes" => $declared_classes, + "declared_interfaces" => $declared_interfaces, + "declared_methods" => $declared_methods, + "declared_functions" => $declared_functions, + "used_classes" => array_diff(array_keys($used_classes), $nodeps), + "inheritance" => $extends, + "implements" => $implements, + ); } /** - * Convert a package.xml version 1.0 into version 2.0 + * Build a "provides" array from data returned by + * analyzeSourceCode(). The format of the built array is like + * this: + * + * array( + * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), + * ... + * ) + * + * + * @param array $srcinfo array with information about a source file + * as returned by the analyzeSourceCode() method. + * + * @return void + * + * @access private * - * Note that this does a basic conversion, to allow more advanced - * features like bundles and multiple releases - * @param string the classname to instantiate and return. This must be - * PEAR_PackageFile_v2 or a descendant - * @param boolean if true, only valid, deterministic package.xml 1.0 as defined by the - * strictest parameters will be converted - * @return PEAR_PackageFile_v2|PEAR_Error */ - function &toV2($class = 'PEAR_PackageFile_v2', $strict = false) + function _buildProvidesArray($srcinfo) { - if ($strict) { - if (!$this->_packagefile->validate()) { - $a = PEAR::raiseError('invalid package.xml version 1.0 cannot be converted' . - ' to version 2.0', null, null, null, - $this->_packagefile->getValidationWarnings(true)); - return $a; - } + if (!$this->_isValid) { + return false; } - - $arr = array( - 'attribs' => array( - 'version' => '2.0', - 'xmlns' => 'http://pear.php.net/dtd/package-2.0', - 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', - 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:schemaLocation' => "http://pear.php.net/dtd/tasks-1.0\n" . -"http://pear.php.net/dtd/tasks-1.0.xsd\n" . -"http://pear.php.net/dtd/package-2.0\n" . -'http://pear.php.net/dtd/package-2.0.xsd', - ), - 'name' => $this->_packagefile->getPackage(), - 'channel' => 'pear.php.net', - ); - $arr['summary'] = $this->_packagefile->getSummary(); - $arr['description'] = $this->_packagefile->getDescription(); - $maintainers = $this->_packagefile->getMaintainers(); - foreach ($maintainers as $maintainer) { - if ($maintainer['role'] != 'lead') { + $file = basename($srcinfo['source_file']); + $pn = $this->getPackage(); + $pnl = strlen($pn); + foreach ($srcinfo['declared_classes'] as $class) { + $key = "class;$class"; + if (isset($this->_packageInfo['provides'][$key])) { continue; } - $new = array( - 'name' => $maintainer['name'], - 'user' => $maintainer['handle'], - 'email' => $maintainer['email'], - 'active' => 'yes', - ); - $arr['lead'][] = $new; - } - - if (!isset($arr['lead'])) { // some people... you know? - $arr['lead'] = array( - 'name' => 'unknown', - 'user' => 'unknown', - 'email' => 'noleadmaintainer@example.com', - 'active' => 'no', - ); + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'class', 'name' => $class); + if (isset($srcinfo['inheritance'][$class])) { + $this->_packageInfo['provides'][$key]['extends'] = + $srcinfo['inheritance'][$class]; + } } - - if (count($arr['lead']) == 1) { - $arr['lead'] = $arr['lead'][0]; + foreach ($srcinfo['declared_methods'] as $class => $methods) { + foreach ($methods as $method) { + $function = "$class::$method"; + $key = "function;$function"; + if ($method{0} == '_' || !strcasecmp($method, $class) || + isset($this->_packageInfo['provides'][$key])) { + continue; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); + } } - foreach ($maintainers as $maintainer) { - if ($maintainer['role'] == 'lead') { + foreach ($srcinfo['declared_functions'] as $function) { + $key = "function;$function"; + if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) { continue; } - $new = array( - 'name' => $maintainer['name'], - 'user' => $maintainer['handle'], - 'email' => $maintainer['email'], - 'active' => 'yes', - ); - $arr[$maintainer['role']][] = $new; + if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { + $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; + } + $this->_packageInfo['provides'][$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); } + } - if (isset($arr['developer']) && count($arr['developer']) == 1) { - $arr['developer'] = $arr['developer'][0]; - } + // }}} +} +?> + + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: v2.php 276383 2009-02-24 23:39:37Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a1 + */ +/** + * For error handling + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ErrorStack.php'; +/** + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a1 + */ +class PEAR_PackageFile_v2 +{ - if (isset($arr['contributor']) && count($arr['contributor']) == 1) { - $arr['contributor'] = $arr['contributor'][0]; - } + /** + * Parsed package information + * @var array + * @access private + */ + var $_packageInfo = array(); - if (isset($arr['helper']) && count($arr['helper']) == 1) { - $arr['helper'] = $arr['helper'][0]; - } + /** + * path to package .tgz or false if this is a local/extracted package.xml + * @var string|false + * @access private + */ + var $_archiveFile; - $arr['date'] = $this->_packagefile->getDate(); - $arr['version'] = - array( - 'release' => $this->_packagefile->getVersion(), - 'api' => $this->_packagefile->getVersion(), - ); - $arr['stability'] = - array( - 'release' => $this->_packagefile->getState(), - 'api' => $this->_packagefile->getState(), - ); - $licensemap = - array( - 'php' => 'http://www.php.net/license', - 'php license' => 'http://www.php.net/license', - 'lgpl' => 'http://www.gnu.org/copyleft/lesser.html', - 'bsd' => 'http://www.opensource.org/licenses/bsd-license.php', - 'bsd style' => 'http://www.opensource.org/licenses/bsd-license.php', - 'bsd-style' => 'http://www.opensource.org/licenses/bsd-license.php', - 'mit' => 'http://www.opensource.org/licenses/mit-license.php', - 'gpl' => 'http://www.gnu.org/copyleft/gpl.html', - 'apache' => 'http://www.opensource.org/licenses/apache2.0.php' - ); + /** + * path to package .xml or false if this is an abstract parsed-from-string xml + * @var string|false + * @access private + */ + var $_packageFile; - if (isset($licensemap[strtolower($this->_packagefile->getLicense())])) { - $arr['license'] = array( - 'attribs' => array('uri' => - $licensemap[strtolower($this->_packagefile->getLicense())]), - '_content' => $this->_packagefile->getLicense() - ); - } else { - // don't use bogus uri - $arr['license'] = $this->_packagefile->getLicense(); - } + /** + * This is used by file analysis routines to log progress information + * @var PEAR_Common + * @access protected + */ + var $_logger; - $arr['notes'] = $this->_packagefile->getNotes(); - $temp = array(); - $arr['contents'] = $this->_convertFilelist2_0($temp); - $this->_convertDependencies2_0($arr); - $release = ($this->_packagefile->getConfigureOptions() || $this->_isExtension) ? - 'extsrcrelease' : 'phprelease'; - if ($release == 'extsrcrelease') { - $arr['channel'] = 'pecl.php.net'; - $arr['providesextension'] = $arr['name']; // assumption - } + /** + * This is set to the highest validation level that has been validated + * + * If the package.xml is invalid or unknown, this is set to 0. If + * normal validation has occurred, this is set to PEAR_VALIDATE_NORMAL. If + * downloading/installation validation has occurred it is set to PEAR_VALIDATE_DOWNLOADING + * or INSTALLING, and so on up to PEAR_VALIDATE_PACKAGING. This allows validation + * "caching" to occur, which is particularly important for package validation, so + * that PHP files are not validated twice + * @var int + * @access private + */ + var $_isValid = 0; - $arr[$release] = array(); - if ($this->_packagefile->getConfigureOptions()) { - $arr[$release]['configureoption'] = $this->_packagefile->getConfigureOptions(); - foreach ($arr[$release]['configureoption'] as $i => $opt) { - $arr[$release]['configureoption'][$i] = array('attribs' => $opt); - } - if (count($arr[$release]['configureoption']) == 1) { - $arr[$release]['configureoption'] = $arr[$release]['configureoption'][0]; - } - } + /** + * True if the filelist has been validated + * @param bool + */ + var $_filesValid = false; - $this->_convertRelease2_0($arr[$release], $temp); - if ($release == 'extsrcrelease' && count($arr[$release]) > 1) { - // multiple extsrcrelease tags added in PEAR 1.4.1 - $arr['dependencies']['required']['pearinstaller']['min'] = '1.4.1'; - } + /** + * @var PEAR_Registry + * @access protected + */ + var $_registry; - if ($cl = $this->_packagefile->getChangelog()) { - foreach ($cl as $release) { - $rel = array(); - $rel['version'] = - array( - 'release' => $release['version'], - 'api' => $release['version'], - ); - if (!isset($release['release_state'])) { - $release['release_state'] = 'stable'; - } + /** + * @var PEAR_Config + * @access protected + */ + var $_config; - $rel['stability'] = - array( - 'release' => $release['release_state'], - 'api' => $release['release_state'], - ); - if (isset($release['release_date'])) { - $rel['date'] = $release['release_date']; - } else { - $rel['date'] = date('Y-m-d'); - } + /** + * Optional Dependency group requested for installation + * @var string + * @access private + */ + var $_requestedGroup = false; - if (isset($release['release_license'])) { - if (isset($licensemap[strtolower($release['release_license'])])) { - $uri = $licensemap[strtolower($release['release_license'])]; - } else { - $uri = 'http://www.example.com'; - } - $rel['license'] = array( - 'attribs' => array('uri' => $uri), - '_content' => $release['release_license'] - ); - } else { - $rel['license'] = $arr['license']; - } + /** + * @var PEAR_ErrorStack + * @access protected + */ + var $_stack; - if (!isset($release['release_notes'])) { - $release['release_notes'] = 'no release notes'; - } + /** + * Namespace prefix used for tasks in this package.xml - use tasks: whenever possible + */ + var $_tasksNs; - $rel['notes'] = $release['release_notes']; - $arr['changelog']['release'][] = $rel; - } - } + /** + * Determines whether this packagefile was initialized only with partial package info + * + * If this package file was constructed via parsing REST, it will only contain + * + * - package name + * - channel name + * - dependencies + * @var boolean + * @access private + */ + var $_incomplete = true; - $ret = new $class; - $ret->setConfig($this->_packagefile->_config); - if (isset($this->_packagefile->_logger) && is_object($this->_packagefile->_logger)) { - $ret->setLogger($this->_packagefile->_logger); - } + /** + * @var PEAR_PackageFile_v2_Validator + */ + var $_v2Validator; - $ret->fromArray($arr); - return $ret; + /** + * The constructor merely sets up the private error stack + */ + function PEAR_PackageFile_v2() + { + $this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null); + $this->_isValid = false; } /** - * @param array - * @param bool - * @access private + * To make unit-testing easier + * @param PEAR_Frontend_* + * @param array options + * @param PEAR_Config + * @return PEAR_Downloader + * @access protected */ - function _convertDependencies2_0(&$release, $internal = false) + function &getPEARDownloader(&$i, $o, &$c) { - $peardep = array('pearinstaller' => - array('min' => '1.4.0b1')); // this is a lot safer - $required = $optional = array(); - $release['dependencies'] = array('required' => array()); - if ($this->_packagefile->hasDeps()) { - foreach ($this->_packagefile->getDeps() as $dep) { - if (!isset($dep['optional']) || $dep['optional'] == 'no') { - $required[] = $dep; - } else { - $optional[] = $dep; - } - } - foreach (array('required', 'optional') as $arr) { - $deps = array(); - foreach ($$arr as $dep) { - // organize deps by dependency type and name - if (!isset($deps[$dep['type']])) { - $deps[$dep['type']] = array(); - } - if (isset($dep['name'])) { - $deps[$dep['type']][$dep['name']][] = $dep; - } else { - $deps[$dep['type']][] = $dep; - } - } - do { - if (isset($deps['php'])) { - $php = array(); - if (count($deps['php']) > 1) { - $php = $this->_processPhpDeps($deps['php']); - } else { - if (!isset($deps['php'][0])) { - list($key, $blah) = each ($deps['php']); // stupid buggy versions - $deps['php'] = array($blah[0]); - } - $php = $this->_processDep($deps['php'][0]); - if (!$php) { - break; // poor mans throw - } - } - $release['dependencies'][$arr]['php'] = $php; - } - } while (false); - do { - if (isset($deps['pkg'])) { - $pkg = array(); - $pkg = $this->_processMultipleDepsName($deps['pkg']); - if (!$pkg) { - break; // poor mans throw - } - $release['dependencies'][$arr]['package'] = $pkg; - } - } while (false); - do { - if (isset($deps['ext'])) { - $pkg = array(); - $pkg = $this->_processMultipleDepsName($deps['ext']); - $release['dependencies'][$arr]['extension'] = $pkg; - } - } while (false); - // skip sapi - it's not supported so nobody will have used it - // skip os - it's not supported in 1.0 - } - } - if (isset($release['dependencies']['required'])) { - $release['dependencies']['required'] = - array_merge($peardep, $release['dependencies']['required']); - } else { - $release['dependencies']['required'] = $peardep; - } - if (!isset($release['dependencies']['required']['php'])) { - $release['dependencies']['required']['php'] = - array('min' => '4.0.0'); - } - $order = array(); - $bewm = $release['dependencies']['required']; - $order['php'] = $bewm['php']; - $order['pearinstaller'] = $bewm['pearinstaller']; - isset($bewm['package']) ? $order['package'] = $bewm['package'] :0; - isset($bewm['extension']) ? $order['extension'] = $bewm['extension'] :0; - $release['dependencies']['required'] = $order; + $z = &new PEAR_Downloader($i, $o, $c); + return $z; } /** - * @param array - * @access private + * To make unit-testing easier + * @param PEAR_Config + * @param array options + * @param array package name as returned from {@link PEAR_Registry::parsePackageName()} + * @param int PEAR_VALIDATE_* constant + * @return PEAR_Dependency2 + * @access protected */ - function _convertFilelist2_0(&$package) + function &getPEARDependency2(&$c, $o, $p, $s = PEAR_VALIDATE_INSTALLING) { - $ret = array('dir' => - array( - 'attribs' => array('name' => '/'), - 'file' => array() - ) - ); - $package['platform'] = - $package['install-as'] = array(); - $this->_isExtension = false; - foreach ($this->_packagefile->getFilelist() as $name => $file) { - $file['name'] = $name; - if (isset($file['role']) && $file['role'] == 'src') { - $this->_isExtension = true; - } - if (isset($file['replacements'])) { - $repl = $file['replacements']; - unset($file['replacements']); - } else { - unset($repl); - } - if (isset($file['install-as'])) { - $package['install-as'][$name] = $file['install-as']; - unset($file['install-as']); - } - if (isset($file['platform'])) { - $package['platform'][$name] = $file['platform']; - unset($file['platform']); - } - $file = array('attribs' => $file); - if (isset($repl)) { - foreach ($repl as $replace ) { - $file['tasks:replace'][] = array('attribs' => $replace); - } - if (count($repl) == 1) { - $file['tasks:replace'] = $file['tasks:replace'][0]; - } - } - $ret['dir']['file'][] = $file; + if (!class_exists('PEAR_Dependency2')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; } - return $ret; + $z = &new PEAR_Dependency2($c, $o, $p, $s); + return $z; + } + + function getInstalledBinary() + { + return isset($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] : + false; } /** - * Post-process special files with install-as/platform attributes and - * make the release tag. - * - * This complex method follows this work-flow to create the release tags: - * - *
    -     * - if any install-as/platform exist, create a generic release and fill it with
    -     *   o  tags for 
    -     *   o  tags for 
    -     *   o  tags for 
    -     *   o  tags for 
    -     * - create a release for each platform encountered and fill with
    -     *   o  tags for 
    -     *   o  tags for 
    -     *   o  tags for 
    -     *   o  tags for 
    -     *   o  tags for 
    -     *   o  tags for 
    -     *   o  tags for 
    -     * 
    - * - * It does this by accessing the $package parameter, which contains an array with - * indices: - * - * - platform: mapping of file => OS the file should be installed on - * - install-as: mapping of file => installed name - * - osmap: mapping of OS => list of files that should be installed - * on that OS - * - notosmap: mapping of OS => list of files that should not be - * installed on that OS - * - * @param array - * @param array - * @access private + * Installation of source package has failed, attempt to download and install the + * binary version of this package. + * @param PEAR_Installer + * @return array|false */ - function _convertRelease2_0(&$release, $package) + function installBinary(&$installer) { - //- if any install-as/platform exist, create a generic release and fill it with - if (count($package['platform']) || count($package['install-as'])) { - $generic = array(); - $genericIgnore = array(); - foreach ($package['install-as'] as $file => $as) { - //o tags for - if (!isset($package['platform'][$file])) { - $generic[] = $file; - continue; - } - //o tags for - if (isset($package['platform'][$file]) && - $package['platform'][$file]{0} == '!') { - $generic[] = $file; - continue; - } - //o tags for - if (isset($package['platform'][$file]) && - $package['platform'][$file]{0} != '!') { - $genericIgnore[] = $file; - continue; - } - } - foreach ($package['platform'] as $file => $platform) { - if (isset($package['install-as'][$file])) { - continue; - } - if ($platform{0} != '!') { - //o tags for - $genericIgnore[] = $file; - } + if (!OS_WINDOWS) { + $a = false; + return $a; + } + if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { + $releasetype = $this->getPackageType() . 'release'; + if (!is_array($installer->getInstallPackages())) { + $a = false; + return $a; } - if (count($package['platform'])) { - $oses = $notplatform = $platform = array(); - foreach ($package['platform'] as $file => $os) { - // get a list of oses - if ($os{0} == '!') { - if (isset($oses[substr($os, 1)])) { - continue; - } - $oses[substr($os, 1)] = count($oses); - } else { - if (isset($oses[$os])) { - continue; - } - $oses[$os] = count($oses); - } - } - //- create a release for each platform encountered and fill with - foreach ($oses as $os => $releaseNum) { - $release[$releaseNum]['installconditions']['os']['name'] = $os; - $release[$releaseNum]['filelist'] = array('install' => array(), - 'ignore' => array()); - foreach ($package['install-as'] as $file => $as) { - //o tags for - if (!isset($package['platform'][$file])) { - $release[$releaseNum]['filelist']['install'][] = - array( - 'attribs' => array( - 'name' => $file, - 'as' => $as, - ), - ); - continue; - } - //o tags for - // - if (isset($package['platform'][$file]) && - $package['platform'][$file] == $os) { - $release[$releaseNum]['filelist']['install'][] = - array( - 'attribs' => array( - 'name' => $file, - 'as' => $as, - ), - ); - continue; - } - //o tags for - // - if (isset($package['platform'][$file]) && - $package['platform'][$file] != "!$os" && - $package['platform'][$file]{0} == '!') { - $release[$releaseNum]['filelist']['install'][] = - array( - 'attribs' => array( - 'name' => $file, - 'as' => $as, - ), - ); - continue; - } - //o tags for - // - if (isset($package['platform'][$file]) && - $package['platform'][$file] == "!$os") { - $release[$releaseNum]['filelist']['ignore'][] = - array( - 'attribs' => array( - 'name' => $file, - ), - ); - continue; - } - //o tags for - // - if (isset($package['platform'][$file]) && - $package['platform'][$file]{0} != '!' && - $package['platform'][$file] != $os) { - $release[$releaseNum]['filelist']['ignore'][] = - array( - 'attribs' => array( - 'name' => $file, - ), - ); - continue; - } - } - foreach ($package['platform'] as $file => $platform) { - if (isset($package['install-as'][$file])) { - continue; - } - //o tags for - if ($platform == "!$os") { - $release[$releaseNum]['filelist']['ignore'][] = - array( - 'attribs' => array( - 'name' => $file, - ), - ); - continue; - } - //o tags for - if ($platform{0} != '!' && $platform != $os) { - $release[$releaseNum]['filelist']['ignore'][] = - array( - 'attribs' => array( - 'name' => $file, - ), - ); - } - } - if (!count($release[$releaseNum]['filelist']['install'])) { - unset($release[$releaseNum]['filelist']['install']); - } - if (!count($release[$releaseNum]['filelist']['ignore'])) { - unset($release[$releaseNum]['filelist']['ignore']); - } - } - if (count($generic) || count($genericIgnore)) { - $release[count($oses)] = array(); - if (count($generic)) { - foreach ($generic as $file) { - if (isset($package['install-as'][$file])) { - $installas = $package['install-as'][$file]; - } else { - $installas = $file; - } - $release[count($oses)]['filelist']['install'][] = - array( - 'attribs' => array( - 'name' => $file, - 'as' => $installas, - ) - ); - } - } - if (count($genericIgnore)) { - foreach ($genericIgnore as $file) { - $release[count($oses)]['filelist']['ignore'][] = - array( - 'attribs' => array( - 'name' => $file, - ) - ); - } + foreach ($installer->getInstallPackages() as $p) { + if ($p->isExtension($this->_packageInfo['providesextension'])) { + if ($p->getPackageType() != 'extsrc' && $p->getPackageType() != 'zendextsrc') { + $a = false; + return $a; // the user probably downloaded it separately } } - // cleanup - foreach ($release as $i => $rel) { - if (isset($rel['filelist']['install']) && - count($rel['filelist']['install']) == 1) { - $release[$i]['filelist']['install'] = - $release[$i]['filelist']['install'][0]; - } - if (isset($rel['filelist']['ignore']) && - count($rel['filelist']['ignore']) == 1) { - $release[$i]['filelist']['ignore'] = - $release[$i]['filelist']['ignore'][0]; - } + } + if (isset($this->_packageInfo[$releasetype]['binarypackage'])) { + $installer->log(0, 'Attempting to download binary version of extension "' . + $this->_packageInfo['providesextension'] . '"'); + $params = $this->_packageInfo[$releasetype]['binarypackage']; + if (!is_array($params) || !isset($params[0])) { + $params = array($params); } - if (count($release) == 1) { - $release = $release[0]; + if (isset($this->_packageInfo['channel'])) { + foreach ($params as $i => $param) { + $params[$i] = array('channel' => $this->_packageInfo['channel'], + 'package' => $param, 'version' => $this->getVersion()); + } } - } else { - // no platform atts, but some install-as atts - foreach ($package['install-as'] as $file => $value) { - $release['filelist']['install'][] = - array( - 'attribs' => array( - 'name' => $file, - 'as' => $value - ) - ); + $dl = &$this->getPEARDownloader($installer->ui, $installer->getOptions(), + $installer->config); + $verbose = $dl->config->get('verbose'); + $dl->config->set('verbose', -1); + foreach ($params as $param) { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $ret = $dl->download(array($param)); + PEAR::popErrorHandling(); + if (is_array($ret) && count($ret)) { + break; + } } - if (count($release['filelist']['install']) == 1) { - $release['filelist']['install'] = $release['filelist']['install'][0]; + $dl->config->set('verbose', $verbose); + if (is_array($ret)) { + if (count($ret) == 1) { + $pf = $ret[0]->getPackageFile(); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $err = $installer->install($ret[0]); + PEAR::popErrorHandling(); + if (is_array($err)) { + $this->_packageInfo['#binarypackage'] = $ret[0]->getPackage(); + // "install" self, so all dependencies will work transparently + $this->_registry->addPackage2($this); + $installer->log(0, 'Download and install of binary extension "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pf->getChannel(), + 'package' => $pf->getPackage()), true) . '" successful'); + $a = array($ret[0], $err); + return $a; + } + $installer->log(0, 'Download and install of binary extension "' . + $this->_registry->parsedPackageNameToString( + array('channel' => $pf->getChannel(), + 'package' => $pf->getPackage()), true) . '" failed'); + } } } } + $a = false; + return $a; } /** - * @param array - * @return array - * @access private + * @return string|false Extension name */ - function _processDep($dep) + function getProvidesExtension() { - if ($dep['type'] == 'php') { - if ($dep['rel'] == 'has') { - // come on - everyone has php! - return false; - } - } - $php = array(); - if ($dep['type'] != 'php') { - $php['name'] = $dep['name']; - if ($dep['type'] == 'pkg') { - $php['channel'] = 'pear.php.net'; + if (in_array($this->getPackageType(), + array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { + if (isset($this->_packageInfo['providesextension'])) { + return $this->_packageInfo['providesextension']; } } - switch ($dep['rel']) { - case 'gt' : - $php['min'] = $dep['version']; - $php['exclude'] = $dep['version']; - break; - case 'ge' : - if (!isset($dep['version'])) { - if ($dep['type'] == 'php') { - if (isset($dep['name'])) { - $dep['version'] = $dep['name']; - } - } - } - $php['min'] = $dep['version']; - break; - case 'lt' : - $php['max'] = $dep['version']; - $php['exclude'] = $dep['version']; - break; - case 'le' : - $php['max'] = $dep['version']; - break; - case 'eq' : - $php['min'] = $dep['version']; - $php['max'] = $dep['version']; - break; - case 'ne' : - $php['exclude'] = $dep['version']; - break; - case 'not' : - $php['conflicts'] = 'yes'; - break; + return false; + } + + /** + * @param string Extension name + * @return bool + */ + function isExtension($extension) + { + if (in_array($this->getPackageType(), + array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { + return $this->_packageInfo['providesextension'] == $extension; } - return $php; + return false; } /** - * @param array - * @return array + * Tests whether every part of the package.xml 1.0 is represented in + * this package.xml 2.0 + * @param PEAR_PackageFile_v1 + * @return bool */ - function _processPhpDeps($deps) + function isEquivalent($pf1) { - $test = array(); - foreach ($deps as $dep) { - $test[] = $this->_processDep($dep); + if (!$pf1) { + return true; } - $min = array(); - $max = array(); - foreach ($test as $dep) { - if (!$dep) { - continue; - } - if (isset($dep['min'])) { - $min[$dep['min']] = count($min); - } - if (isset($dep['max'])) { - $max[$dep['max']] = count($max); - } + if ($this->getPackageType() == 'bundle') { + return false; } - if (count($min) > 0) { - uksort($min, 'version_compare'); + $this->_stack->getErrors(true); + if (!$pf1->validate(PEAR_VALIDATE_NORMAL)) { + return false; } - if (count($max) > 0) { - uksort($max, 'version_compare'); + $pass = true; + if ($pf1->getPackage() != $this->getPackage()) { + $this->_differentPackage($pf1->getPackage()); + $pass = false; } - if (count($min)) { - // get the highest minimum - $min = array_pop($a = array_flip($min)); - } else { - $min = false; + if ($pf1->getVersion() != $this->getVersion()) { + $this->_differentVersion($pf1->getVersion()); + $pass = false; } - if (count($max)) { - // get the lowest maximum - $max = array_shift($a = array_flip($max)); - } else { - $max = false; + if (trim($pf1->getSummary()) != $this->getSummary()) { + $this->_differentSummary($pf1->getSummary()); + $pass = false; } - if ($min) { - $php['min'] = $min; + if (preg_replace('/\s+/', '', $pf1->getDescription()) != + preg_replace('/\s+/', '', $this->getDescription())) { + $this->_differentDescription($pf1->getDescription()); + $pass = false; } - if ($max) { - $php['max'] = $max; + if ($pf1->getState() != $this->getState()) { + $this->_differentState($pf1->getState()); + $pass = false; } - $exclude = array(); - foreach ($test as $dep) { - if (!isset($dep['exclude'])) { - continue; + if (!strstr(preg_replace('/\s+/', '', $this->getNotes()), + preg_replace('/\s+/', '', $pf1->getNotes()))) { + $this->_differentNotes($pf1->getNotes()); + $pass = false; + } + $mymaintainers = $this->getMaintainers(); + $yourmaintainers = $pf1->getMaintainers(); + for ($i1 = 0; $i1 < count($yourmaintainers); $i1++) { + $reset = false; + for ($i2 = 0; $i2 < count($mymaintainers); $i2++) { + if ($mymaintainers[$i2]['handle'] == $yourmaintainers[$i1]['handle']) { + if ($mymaintainers[$i2]['role'] != $yourmaintainers[$i1]['role']) { + $this->_differentRole($mymaintainers[$i2]['handle'], + $yourmaintainers[$i1]['role'], $mymaintainers[$i2]['role']); + $pass = false; + } + if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) { + $this->_differentEmail($mymaintainers[$i2]['handle'], + $yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']); + $pass = false; + } + if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) { + $this->_differentName($mymaintainers[$i2]['handle'], + $yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']); + $pass = false; + } + unset($mymaintainers[$i2]); + $mymaintainers = array_values($mymaintainers); + unset($yourmaintainers[$i1]); + $yourmaintainers = array_values($yourmaintainers); + $reset = true; + break; + } + } + if ($reset) { + $i1 = -1; } - $exclude[] = $dep['exclude']; } - if (count($exclude)) { - $php['exclude'] = $exclude; + $this->_unmatchedMaintainers($mymaintainers, $yourmaintainers); + $filelist = $this->getFilelist(); + foreach ($pf1->getFilelist() as $file => $atts) { + if (!isset($filelist[$file])) { + $this->_missingFile($file); + $pass = false; + } } - return $php; + return $pass; } - /** - * process multiple dependencies that have a name, like package deps - * @param array - * @return array - * @access private - */ - function _processMultipleDepsName($deps) + function _differentPackage($package) { - $tests = array(); - foreach ($deps as $name => $dep) { - foreach ($dep as $d) { - $tests[$name][] = $this->_processDep($d); - } + $this->_stack->push(__FUNCTION__, 'error', array('package' => $package, + 'self' => $this->getPackage()), + 'package.xml 1.0 package "%package%" does not match "%self%"'); + } + + function _differentVersion($version) + { + $this->_stack->push(__FUNCTION__, 'error', array('version' => $version, + 'self' => $this->getVersion()), + 'package.xml 1.0 version "%version%" does not match "%self%"'); + } + + function _differentState($state) + { + $this->_stack->push(__FUNCTION__, 'error', array('state' => $state, + 'self' => $this->getState()), + 'package.xml 1.0 state "%state%" does not match "%self%"'); + } + + function _differentRole($handle, $role, $selfrole) + { + $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, + 'role' => $role, 'self' => $selfrole), + 'package.xml 1.0 maintainer "%handle%" role "%role%" does not match "%self%"'); + } + + function _differentEmail($handle, $email, $selfemail) + { + $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, + 'email' => $email, 'self' => $selfemail), + 'package.xml 1.0 maintainer "%handle%" email "%email%" does not match "%self%"'); + } + + function _differentName($handle, $name, $selfname) + { + $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, + 'name' => $name, 'self' => $selfname), + 'package.xml 1.0 maintainer "%handle%" name "%name%" does not match "%self%"'); + } + + function _unmatchedMaintainers($my, $yours) + { + if ($my) { + array_walk($my, create_function('&$i, $k', '$i = $i["handle"];')); + $this->_stack->push(__FUNCTION__, 'error', array('handles' => $my), + 'package.xml 2.0 has unmatched extra maintainers "%handles%"'); } - foreach ($tests as $name => $test) { - $php = array(); - $min = array(); - $max = array(); - $php['name'] = $name; - foreach ($test as $dep) { - if (!$dep) { - continue; - } - if (isset($dep['channel'])) { - $php['channel'] = 'pear.php.net'; - } - if (isset($dep['conflicts']) && $dep['conflicts'] == 'yes') { - $php['conflicts'] = 'yes'; - } - if (isset($dep['min'])) { - $min[$dep['min']] = count($min); - } - if (isset($dep['max'])) { - $max[$dep['max']] = count($max); - } - } - if (count($min) > 0) { - uksort($min, 'version_compare'); - } - if (count($max) > 0) { - uksort($max, 'version_compare'); - } - if (count($min)) { - // get the highest minimum - $min = array_pop($a = array_flip($min)); - } else { - $min = false; - } - if (count($max)) { - // get the lowest maximum - $max = array_shift($a = array_flip($max)); - } else { - $max = false; - } - if ($min) { - $php['min'] = $min; - } - if ($max) { - $php['max'] = $max; - } - $exclude = array(); - foreach ($test as $dep) { - if (!isset($dep['exclude'])) { - continue; - } - $exclude[] = $dep['exclude']; - } - if (count($exclude)) { - $php['exclude'] = $exclude; - } - $ret[] = $php; + if ($yours) { + array_walk($yours, create_function('&$i, $k', '$i = $i["handle"];')); + $this->_stack->push(__FUNCTION__, 'error', array('handles' => $yours), + 'package.xml 1.0 has unmatched extra maintainers "%handles%"'); } - return $ret; } -} -?> - * @author Stephan Schmidt (original XML_Serializer code) - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v2.php,v 1.51 2009/03/27 17:11:18 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/** - * file/dir manipulation routines - */ -require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'XML/Util.php'; -/** - * This class converts a PEAR_PackageFile_v2 object into any output format. - * - * Supported output formats include array, XML string (using S. Schmidt's - * XML_Serializer, slightly customized) - * @category pear - * @package PEAR - * @author Greg Beaver - * @author Stephan Schmidt (original XML_Serializer code) - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_PackageFile_Generator_v2 -{ - /** - * default options for the serialization - * @access private - * @var array $_defaultOptions - */ - var $_defaultOptions = array( - 'indent' => ' ', // string used for indentation - 'linebreak' => "\n", // string used for newlines - 'typeHints' => false, // automatically add type hin attributes - 'addDecl' => true, // add an XML declaration - 'defaultTagName' => 'XML_Serializer_Tag', // tag used for indexed arrays or invalid names - 'classAsTagName' => false, // use classname for objects in indexed arrays - 'keyAttribute' => '_originalKey', // attribute where original key is stored - 'typeAttribute' => '_type', // attribute for type (only if typeHints => true) - 'classAttribute' => '_class', // attribute for class of objects (only if typeHints => true) - 'scalarAsAttributes' => false, // scalar values (strings, ints,..) will be serialized as attribute - 'prependAttributes' => '', // prepend string for attributes - 'indentAttributes' => false, // indent the attributes, if set to '_auto', it will indent attributes so they all start at the same column - 'mode' => 'simplexml', // use 'simplexml' to use parent name as tagname if transforming an indexed array - 'addDoctype' => false, // add a doctype declaration - 'doctype' => null, // supply a string or an array with id and uri ({@see XML_Util::getDoctypeDeclaration()} - 'rootName' => 'package', // name of the root tag - 'rootAttributes' => array( - 'version' => '2.0', - 'xmlns' => 'http://pear.php.net/dtd/package-2.0', - 'xmlns:tasks' => 'http://pear.php.net/dtd/tasks-1.0', - 'xmlns:xsi' => 'http://www.w3.org/2001/XMLSchema-instance', - 'xsi:schemaLocation' => 'http://pear.php.net/dtd/tasks-1.0 -http://pear.php.net/dtd/tasks-1.0.xsd -http://pear.php.net/dtd/package-2.0 -http://pear.php.net/dtd/package-2.0.xsd', - ), // attributes of the root tag - 'attributesArray' => 'attribs', // all values in this key will be treated as attributes - 'contentName' => '_content', // this value will be used directly as content, instead of creating a new tag, may only be used in conjuction with attributesArray - 'beautifyFilelist' => false, - 'encoding' => 'UTF-8', - ); + function _differentNotes($notes) + { + $truncnotes = strlen($notes) < 25 ? $notes : substr($notes, 0, 24) . '...'; + $truncmynotes = strlen($this->getNotes()) < 25 ? $this->getNotes() : + substr($this->getNotes(), 0, 24) . '...'; + $this->_stack->push(__FUNCTION__, 'error', array('notes' => $truncnotes, + 'self' => $truncmynotes), + 'package.xml 1.0 release notes "%notes%" do not match "%self%"'); + } - /** - * options for the serialization - * @access private - * @var array $options - */ - var $options = array(); + function _differentSummary($summary) + { + $truncsummary = strlen($summary) < 25 ? $summary : substr($summary, 0, 24) . '...'; + $truncmysummary = strlen($this->getsummary()) < 25 ? $this->getSummary() : + substr($this->getsummary(), 0, 24) . '...'; + $this->_stack->push(__FUNCTION__, 'error', array('summary' => $truncsummary, + 'self' => $truncmysummary), + 'package.xml 1.0 summary "%summary%" does not match "%self%"'); + } - /** - * current tag depth - * @var integer $_tagDepth - */ - var $_tagDepth = 0; + function _differentDescription($description) + { + $truncdescription = trim(strlen($description) < 25 ? $description : substr($description, 0, 24) . '...'); + $truncmydescription = trim(strlen($this->getDescription()) < 25 ? $this->getDescription() : + substr($this->getdescription(), 0, 24) . '...'); + $this->_stack->push(__FUNCTION__, 'error', array('description' => $truncdescription, + 'self' => $truncmydescription), + 'package.xml 1.0 description "%description%" does not match "%self%"'); + } + + function _missingFile($file) + { + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'package.xml 1.0 file "%file%" is not present in '); + } - /** - * serilialized representation of the data - * @var string $_serializedData - */ - var $_serializedData = null; /** - * @var PEAR_PackageFile_v2 + * WARNING - do not use this function unless you know what you're doing */ - var $_packagefile; + function setRawState($state) + { + if (!isset($this->_packageInfo['stability'])) { + $this->_packageInfo['stability'] = array(); + } + $this->_packageInfo['stability']['release'] = $state; + } + /** - * @param PEAR_PackageFile_v2 + * WARNING - do not use this function unless you know what you're doing */ - function PEAR_PackageFile_Generator_v2(&$packagefile) + function setRawCompatible($compatible) + { + $this->_packageInfo['compatible'] = $compatible; + } + + /** + * WARNING - do not use this function unless you know what you're doing + */ + function setRawPackage($package) + { + $this->_packageInfo['name'] = $package; + } + + /** + * WARNING - do not use this function unless you know what you're doing + */ + function setRawChannel($channel) + { + $this->_packageInfo['channel'] = $channel; + } + + function setRequestedGroup($group) + { + $this->_requestedGroup = $group; + } + + function getRequestedGroup() { - $this->_packagefile = &$packagefile; - if (isset($this->_packagefile->encoding)) { - $this->_defaultOptions['encoding'] = $this->_packagefile->encoding; + if (isset($this->_requestedGroup)) { + return $this->_requestedGroup; } + return false; } /** - * @return string + * For saving in the registry. + * + * Set the last version that was installed + * @param string */ - function getPackagerVersion() + function setLastInstalledVersion($version) { - return '1.8.0'; + $this->_packageInfo['_lastversion'] = $version; } /** - * @param PEAR_Packager - * @param bool generate a .tgz or a .tar - * @param string|null temporary directory to package in + * @return string|false */ - function toTgz(&$packager, $compress = true, $where = null) + function getLastInstalledVersion() { - $a = null; - return $this->toTgz2($packager, $a, $compress, $where); + if (isset($this->_packageInfo['_lastversion'])) { + return $this->_packageInfo['_lastversion']; + } + return false; } /** - * Package up both a package.xml and package2.xml for the same release - * @param PEAR_Packager - * @param PEAR_PackageFile_v1 - * @param bool generate a .tgz or a .tar - * @param string|null temporary directory to package in + * Determines whether this package.xml has post-install scripts or not + * @return array|false */ - function toTgz2(&$packager, &$pf1, $compress = true, $where = null) + function listPostinstallScripts() { - require_once 'phar://install-pear-nozlib.phar/' . 'Archive/Tar.php'; - if (!$this->_packagefile->isEquivalent($pf1)) { - return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . - basename($pf1->getPackageFile()) . - '" is not equivalent to "' . basename($this->_packagefile->getPackageFile()) - . '"'); + $filelist = $this->getFilelist(); + $contents = $this->getContents(); + $contents = $contents['dir']['file']; + if (!is_array($contents) || !isset($contents[0])) { + $contents = array($contents); } - - if ($where === null) { - if (!($where = System::mktemp(array('-d')))) { - return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: mktemp failed'); + $taskfiles = array(); + foreach ($contents as $file) { + $atts = $file['attribs']; + unset($file['attribs']); + if (count($file)) { + $taskfiles[$atts['name']] = $file; } - } elseif (!@System::mkDir(array('-p', $where))) { - return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: "' . $where . '" could' . - ' not be created'); } - - $file = $where . DIRECTORY_SEPARATOR . 'package.xml'; - if (file_exists($file) && !is_file($file)) { - return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: unable to save package.xml as' . - ' "' . $file .'"'); + $common = new PEAR_Common; + $common->debug = $this->_config->get('verbose'); + $this->_scripts = array(); + $ret = array(); + foreach ($taskfiles as $name => $tasks) { + if (!isset($filelist[$name])) { + // ignored files will not be in the filelist + continue; + } + $atts = $filelist[$name]; + foreach ($tasks as $tag => $raw) { + $task = $this->getTask($tag); + $task = &new $task($this->_config, $common, PEAR_TASK_INSTALL); + if ($task->isScript()) { + $ret[] = $filelist[$name]['installed_as']; + } + } } - - if (!$this->_packagefile->validate(PEAR_VALIDATE_PACKAGING)) { - return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: invalid package.xml'); + if (count($ret)) { + return $ret; } + return false; + } - $ext = $compress ? '.tgz' : '.tar'; - $pkgver = $this->_packagefile->getPackage() . '-' . $this->_packagefile->getVersion(); - $dest_package = getcwd() . DIRECTORY_SEPARATOR . $pkgver . $ext; - if (file_exists($dest_package) && !is_file($dest_package)) { - return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: cannot create tgz file "' . - $dest_package . '"'); + /** + * Initialize post-install scripts for running + * + * This method can be used to detect post-install scripts, as the return value + * indicates whether any exist + * @return bool + */ + function initPostinstallScripts() + { + $filelist = $this->getFilelist(); + $contents = $this->getContents(); + $contents = $contents['dir']['file']; + if (!is_array($contents) || !isset($contents[0])) { + $contents = array($contents); + } + $taskfiles = array(); + foreach ($contents as $file) { + $atts = $file['attribs']; + unset($file['attribs']); + if (count($file)) { + $taskfiles[$atts['name']] = $file; + } + } + $common = new PEAR_Common; + $common->debug = $this->_config->get('verbose'); + $this->_scripts = array(); + foreach ($taskfiles as $name => $tasks) { + if (!isset($filelist[$name])) { + // file was not installed due to installconditions + continue; + } + $atts = $filelist[$name]; + foreach ($tasks as $tag => $raw) { + $taskname = $this->getTask($tag); + $task = &new $taskname($this->_config, $common, PEAR_TASK_INSTALL); + if (!$task->isScript()) { + continue; // scripts are only handled after installation + } + $lastversion = isset($this->_packageInfo['_lastversion']) ? + $this->_packageInfo['_lastversion'] : null; + $task->init($raw, $atts, $lastversion); + $res = $task->startSession($this, $atts['installed_as']); + if (!$res) { + continue; // skip this file + } + if (PEAR::isError($res)) { + return $res; + } + $assign = &$task; + $this->_scripts[] = &$assign; + } + } + if (count($this->_scripts)) { + return true; } + return false; + } - $pkgfile = $this->_packagefile->getPackageFile(); - if (!$pkgfile) { - return PEAR::raiseError('PEAR_Packagefile_v2::toTgz: package file object must ' . - 'be created from a real file'); + function runPostinstallScripts() + { + if ($this->initPostinstallScripts()) { + $ui = &PEAR_Frontend::singleton(); + if ($ui) { + $ui->runPostinstallScripts($this->_scripts, $this); + } } + } - $pkgdir = dirname(realpath($pkgfile)); - $pkgfile = basename($pkgfile); - // {{{ Create the package file list + /** + * Convert a recursive set of and tags into a single tag with + * tags. + */ + function flattenFilelist() + { + if (isset($this->_packageInfo['bundle'])) { + return; + } $filelist = array(); - $i = 0; - $this->_packagefile->flattenFilelist(); - $contents = $this->_packagefile->getContents(); - if (isset($contents['bundledpackage'])) { // bundles of packages - $contents = $contents['bundledpackage']; - if (!isset($contents[0])) { - $contents = array($contents); + if (isset($this->_packageInfo['contents']['dir']['dir'])) { + $this->_getFlattenedFilelist($filelist, $this->_packageInfo['contents']['dir']); + if (!isset($filelist[1])) { + $filelist = $filelist[0]; } - - $packageDir = $where; - foreach ($contents as $i => $package) { - $fname = $package; - $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; - if (!file_exists($file)) { - return $packager->raiseError("File does not exist: $fname"); + $this->_packageInfo['contents']['dir']['file'] = $filelist; + unset($this->_packageInfo['contents']['dir']['dir']); + } else { + // else already flattened but check for baseinstalldir propagation + if (isset($this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'])) { + if (isset($this->_packageInfo['contents']['dir']['file'][0])) { + foreach ($this->_packageInfo['contents']['dir']['file'] as $i => $file) { + if (isset($file['attribs']['baseinstalldir'])) { + continue; + } + $this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir'] + = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; + } + } else { + if (!isset($this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'])) { + $this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'] + = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; + } } + } + } + } - $tfile = $packageDir . DIRECTORY_SEPARATOR . $fname; - System::mkdir(array('-p', dirname($tfile))); - copy($file, $tfile); - $filelist[$i++] = $tfile; - $packager->log(2, "Adding package $fname"); + /** + * @param array the final flattened file list + * @param array the current directory being processed + * @param string|false any recursively inherited baeinstalldir attribute + * @param string private recursion variable + * @return array + * @access protected + */ + function _getFlattenedFilelist(&$files, $dir, $baseinstall = false, $path = '') + { + if (isset($dir['attribs']) && isset($dir['attribs']['baseinstalldir'])) { + $baseinstall = $dir['attribs']['baseinstalldir']; + } + if (isset($dir['dir'])) { + if (!isset($dir['dir'][0])) { + $dir['dir'] = array($dir['dir']); } - } else { // normal packages - $contents = $contents['dir']['file']; - if (!isset($contents[0])) { - $contents = array($contents); + foreach ($dir['dir'] as $subdir) { + if (!isset($subdir['attribs']) || !isset($subdir['attribs']['name'])) { + $name = '*unknown*'; + } else { + $name = $subdir['attribs']['name']; + } + $newpath = empty($path) ? $name : + $path . '/' . $name; + $this->_getFlattenedFilelist($files, $subdir, + $baseinstall, $newpath); } - - $packageDir = $where; - foreach ($contents as $i => $file) { - $fname = $file['attribs']['name']; - $atts = $file['attribs']; - $orig = $file; - $file = $pkgdir . DIRECTORY_SEPARATOR . $fname; - if (!file_exists($file)) { - return $packager->raiseError("File does not exist: $fname"); + } + if (isset($dir['file'])) { + if (!isset($dir['file'][0])) { + $dir['file'] = array($dir['file']); + } + foreach ($dir['file'] as $file) { + $attrs = $file['attribs']; + $name = $attrs['name']; + if ($baseinstall && !isset($attrs['baseinstalldir'])) { + $attrs['baseinstalldir'] = $baseinstall; } + $attrs['name'] = empty($path) ? $name : $path . '/' . $name; + $attrs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), + $attrs['name']); + $file['attribs'] = $attrs; + $files[] = $file; + } + } + } - $origperms = fileperms($file); - $tfile = $packageDir . DIRECTORY_SEPARATOR . $fname; - unset($orig['attribs']); - if (count($orig)) { // file with tasks - // run any package-time tasks - $contents = file_get_contents($file); - foreach ($orig as $tag => $raw) { - $tag = str_replace( - array($this->_packagefile->getTasksNs() . ':', '-'), - array('', '_'), $tag); - $task = "PEAR_Task_$tag"; - $task = &new $task($this->_packagefile->_config, - $this->_packagefile->_logger, - PEAR_TASK_PACKAGE); - $task->init($raw, $atts, null); - $res = $task->startSession($this->_packagefile, $contents, $tfile); - if (!$res) { - continue; // skip this task - } + function setConfig(&$config) + { + $this->_config = &$config; + $this->_registry = &$config->getRegistry(); + } - if (PEAR::isError($res)) { - return $res; - } + function setLogger(&$logger) + { + if (!is_object($logger) || !method_exists($logger, 'log')) { + return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); + } + $this->_logger = &$logger; + } - $contents = $res; // save changes - System::mkdir(array('-p', dirname($tfile))); - $wp = fopen($tfile, "wb"); - fwrite($wp, $contents); - fclose($wp); - } - } + /** + * WARNING - do not use this function directly unless you know what you're doing + */ + function setDeps($deps) + { + $this->_packageInfo['dependencies'] = $deps; + } - if (!file_exists($tfile)) { - System::mkdir(array('-p', dirname($tfile))); - copy($file, $tfile); - } + /** + * WARNING - do not use this function directly unless you know what you're doing + */ + function setCompatible($compat) + { + $this->_packageInfo['compatible'] = $compat; + } - chmod($tfile, $origperms); - $filelist[$i++] = $tfile; - $this->_packagefile->setFileAttribute($fname, 'md5sum', md5_file($tfile), $i - 1); - $packager->log(2, "Adding file $fname"); - } - } - // }}} + function setPackagefile($file, $archive = false) + { + $this->_packageFile = $file; + $this->_archiveFile = $archive ? $archive : $file; + } - $name = $pf1 !== null ? 'package2.xml' : 'package.xml'; - $packagexml = $this->toPackageFile($where, PEAR_VALIDATE_PACKAGING, $name); - if ($packagexml) { - $tar =& new Archive_Tar($dest_package, $compress); - $tar->setErrorHandling(PEAR_ERROR_RETURN); // XXX Don't print errors - // ----- Creates with the package.xml file - $ok = $tar->createModify(array($packagexml), '', $where); - if (PEAR::isError($ok)) { - return $packager->raiseError($ok); - } elseif (!$ok) { - return $packager->raiseError('PEAR_Packagefile_v2::toTgz(): adding ' . $name . - ' failed'); - } + /** + * Wrapper to {@link PEAR_ErrorStack::getErrors()} + * @param boolean determines whether to purge the error stack after retrieving + * @return array + */ + function getValidationWarnings($purge = true) + { + return $this->_stack->getErrors($purge); + } - // ----- Add the content of the package - if (!$tar->addModify($filelist, $pkgver, $where)) { - return $packager->raiseError( - 'PEAR_Packagefile_v2::toTgz(): tarball creation failed'); - } + function getPackageFile() + { + return $this->_packageFile; + } - // add the package.xml version 1.0 - if ($pf1 !== null) { - $pfgen = &$pf1->getDefaultGenerator(); - $packagexml1 = $pfgen->toPackageFile($where, PEAR_VALIDATE_PACKAGING, 'package.xml', true); - if (!$tar->addModify(array($packagexml1), '', $where)) { - return $packager->raiseError( - 'PEAR_Packagefile_v2::toTgz(): adding package.xml failed'); - } - } + function getArchiveFile() + { + return $this->_archiveFile; + } - return $dest_package; - } + + /** + * Directly set the array that defines this packagefile + * + * WARNING: no validation. This should only be performed by internal methods + * inside PEAR or by inputting an array saved from an existing PEAR_PackageFile_v2 + * @param array + */ + function fromArray($pinfo) + { + unset($pinfo['old']); + unset($pinfo['xsdversion']); + $this->_incomplete = false; + $this->_packageInfo = $pinfo; } - function toPackageFile($where = null, $state = PEAR_VALIDATE_NORMAL, $name = 'package.xml') + function isIncomplete() { - if (!$this->_packagefile->validate($state)) { - return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: invalid package.xml', - null, null, null, $this->_packagefile->getValidationWarnings()); + return $this->_incomplete; + } + + /** + * @return array + */ + function toArray($forreg = false) + { + if (!$this->validate(PEAR_VALIDATE_NORMAL)) { + return false; } + return $this->getArray($forreg); + } - if ($where === null) { - if (!($where = System::mktemp(array('-d')))) { - return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: mktemp failed'); + function getArray($forReg = false) + { + if ($forReg) { + $arr = $this->_packageInfo; + $arr['old'] = array(); + $arr['old']['version'] = $this->getVersion(); + $arr['old']['release_date'] = $this->getDate(); + $arr['old']['release_state'] = $this->getState(); + $arr['old']['release_license'] = $this->getLicense(); + $arr['old']['release_notes'] = $this->getNotes(); + $arr['old']['release_deps'] = $this->getDeps(); + $arr['old']['maintainers'] = $this->getMaintainers(); + $arr['xsdversion'] = '2.0'; + return $arr; + } else { + $info = $this->_packageInfo; + unset($info['dirtree']); + if (isset($info['_lastversion'])) { + unset($info['_lastversion']); } - } elseif (!@System::mkDir(array('-p', $where))) { - return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: "' . $where . '" could' . - ' not be created'); + if (isset($info['#binarypackage'])) { + unset($info['#binarypackage']); + } + return $info; } + } - $newpkgfile = $where . DIRECTORY_SEPARATOR . $name; - $np = @fopen($newpkgfile, 'wb'); - if (!$np) { - return PEAR::raiseError('PEAR_Packagefile_v2::toPackageFile: unable to save ' . - "$name as $newpkgfile"); + function packageInfo($field) + { + $arr = $this->getArray(true); + if ($field == 'state') { + return $arr['stability']['release']; } - fwrite($np, $this->toXml($state)); - fclose($np); - return $newpkgfile; + if ($field == 'api-version') { + return $arr['version']['api']; + } + if ($field == 'api-state') { + return $arr['stability']['api']; + } + if (isset($arr['old'][$field])) { + if (!is_string($arr['old'][$field])) { + return null; + } + return $arr['old'][$field]; + } + if (isset($arr[$field])) { + if (!is_string($arr[$field])) { + return null; + } + return $arr[$field]; + } + return null; } - function &toV2() + function getName() { - return $this->_packagefile; + return $this->getPackage(); } - /** - * Return an XML document based on the package info (as returned - * by the PEAR_Common::infoFrom* methods). - * - * @return string XML data - */ - function toXml($state = PEAR_VALIDATE_NORMAL, $options = array()) + function getPackage() { - $this->_packagefile->setDate(date('Y-m-d')); - $this->_packagefile->setTime(date('H:i:s')); - if (!$this->_packagefile->validate($state)) { - return false; + if (isset($this->_packageInfo['name'])) { + return $this->_packageInfo['name']; + } + return false; + } + + function getChannel() + { + if (isset($this->_packageInfo['uri'])) { + return '__uri'; } - - if (is_array($options)) { - $this->options = array_merge($this->_defaultOptions, $options); - } else { - $this->options = $this->_defaultOptions; + if (isset($this->_packageInfo['channel'])) { + return strtolower($this->_packageInfo['channel']); } + return false; + } - $arr = $this->_packagefile->getArray(); - if (isset($arr['filelist'])) { - unset($arr['filelist']); + function getUri() + { + if (isset($this->_packageInfo['uri'])) { + return $this->_packageInfo['uri']; } + return false; + } - if (isset($arr['_lastversion'])) { - unset($arr['_lastversion']); + function getExtends() + { + if (isset($this->_packageInfo['extends'])) { + return $this->_packageInfo['extends']; } + return false; + } - // Fix the notes a little bit - if (isset($arr['notes'])) { - // This trims out the indenting, needs fixing - $arr['notes'] = "\n" . trim($arr['notes']) . "\n"; + function getSummary() + { + if (isset($this->_packageInfo['summary'])) { + return $this->_packageInfo['summary']; } + return false; + } - if (isset($arr['changelog']) && !empty($arr['changelog'])) { - // Fix for inconsistency how the array is filled depending on the changelog release amount - if (!isset($arr['changelog']['release'][0])) { - $release = $arr['changelog']['release']; - unset($arr['changelog']['release']); + function getDescription() + { + if (isset($this->_packageInfo['description'])) { + return $this->_packageInfo['description']; + } + return false; + } - $arr['changelog']['release'] = array(); - $arr['changelog']['release'][0] = $release; + function getMaintainers($raw = false) + { + if (!isset($this->_packageInfo['lead'])) { + return false; + } + if ($raw) { + $ret = array('lead' => $this->_packageInfo['lead']); + (isset($this->_packageInfo['developer'])) ? + $ret['developer'] = $this->_packageInfo['developer'] :null; + (isset($this->_packageInfo['contributor'])) ? + $ret['contributor'] = $this->_packageInfo['contributor'] :null; + (isset($this->_packageInfo['helper'])) ? + $ret['helper'] = $this->_packageInfo['helper'] :null; + return $ret; + } else { + $ret = array(); + $leads = isset($this->_packageInfo['lead'][0]) ? $this->_packageInfo['lead'] : + array($this->_packageInfo['lead']); + foreach ($leads as $lead) { + $s = $lead; + $s['handle'] = $s['user']; + unset($s['user']); + $s['role'] = 'lead'; + $ret[] = $s; } - - foreach ($arr['changelog']['release'] as &$c) { - if (isset($c['notes'])) { - // This trims out the indenting, needs fixing - $c['notes'] = "\n" . trim($c['notes']) . "\n"; + if (isset($this->_packageInfo['developer'])) { + $leads = isset($this->_packageInfo['developer'][0]) ? + $this->_packageInfo['developer'] : + array($this->_packageInfo['developer']); + foreach ($leads as $maintainer) { + $s = $maintainer; + $s['handle'] = $s['user']; + unset($s['user']); + $s['role'] = 'developer'; + $ret[] = $s; } } - } - - if ($state ^ PEAR_VALIDATE_PACKAGING && !isset($arr['bundle'])) { - $use = $this->_recursiveXmlFilelist($arr['contents']['dir']['file']); - unset($arr['contents']['dir']['file']); - if (isset($use['dir'])) { - $arr['contents']['dir']['dir'] = $use['dir']; + if (isset($this->_packageInfo['contributor'])) { + $leads = isset($this->_packageInfo['contributor'][0]) ? + $this->_packageInfo['contributor'] : + array($this->_packageInfo['contributor']); + foreach ($leads as $maintainer) { + $s = $maintainer; + $s['handle'] = $s['user']; + unset($s['user']); + $s['role'] = 'contributor'; + $ret[] = $s; + } } - if (isset($use['file'])) { - $arr['contents']['dir']['file'] = $use['file']; + if (isset($this->_packageInfo['helper'])) { + $leads = isset($this->_packageInfo['helper'][0]) ? + $this->_packageInfo['helper'] : + array($this->_packageInfo['helper']); + foreach ($leads as $maintainer) { + $s = $maintainer; + $s['handle'] = $s['user']; + unset($s['user']); + $s['role'] = 'helper'; + $ret[] = $s; + } } - $this->options['beautifyFilelist'] = true; + return $ret; } + return false; + } - $arr['attribs']['packagerversion'] = '1.8.0'; - if ($this->serialize($arr, $options)) { - return $this->_serializedData . "\n"; + function getLeads() + { + if (isset($this->_packageInfo['lead'])) { + return $this->_packageInfo['lead']; } - return false; } - - function _recursiveXmlFilelist($list) + function getDevelopers() { - $dirs = array(); - if (isset($list['attribs'])) { - $file = $list['attribs']['name']; - unset($list['attribs']['name']); - $attributes = $list['attribs']; - $this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes); - } else { - foreach ($list as $a) { - $file = $a['attribs']['name']; - $attributes = $a['attribs']; - unset($a['attribs']); - $this->_addDir($dirs, explode('/', dirname($file)), $file, $attributes, $a); - } + if (isset($this->_packageInfo['developer'])) { + return $this->_packageInfo['developer']; } - $this->_formatDir($dirs); - $this->_deFormat($dirs); - return $dirs; + return false; } - function _addDir(&$dirs, $dir, $file = null, $attributes = null, $tasks = null) + function getContributors() { - if (!$tasks) { - $tasks = array(); - } - if ($dir == array() || $dir == array('.')) { - $dirs['file'][basename($file)] = $tasks; - $attributes['name'] = basename($file); - $dirs['file'][basename($file)]['attribs'] = $attributes; - return; - } - $curdir = array_shift($dir); - if (!isset($dirs['dir'][$curdir])) { - $dirs['dir'][$curdir] = array(); + if (isset($this->_packageInfo['contributor'])) { + return $this->_packageInfo['contributor']; } - $this->_addDir($dirs['dir'][$curdir], $dir, $file, $attributes, $tasks); + return false; } - function _formatDir(&$dirs) + function getHelpers() { - if (!count($dirs)) { - return array(); - } - $newdirs = array(); - if (isset($dirs['dir'])) { - $newdirs['dir'] = $dirs['dir']; - } - if (isset($dirs['file'])) { - $newdirs['file'] = $dirs['file']; + if (isset($this->_packageInfo['helper'])) { + return $this->_packageInfo['helper']; } - $dirs = $newdirs; - if (isset($dirs['dir'])) { - uksort($dirs['dir'], 'strnatcasecmp'); - foreach ($dirs['dir'] as $dir => $contents) { - $this->_formatDir($dirs['dir'][$dir]); - } + return false; + } + + function setDate($date) + { + if (!isset($this->_packageInfo['date'])) { + // ensure that the extends tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('time', 'version', + 'stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', + 'zendextbinrelease', 'bundle', 'changelog'), array(), 'date'); } - if (isset($dirs['file'])) { - uksort($dirs['file'], 'strnatcasecmp'); - }; + $this->_packageInfo['date'] = $date; + $this->_isValid = 0; } - function _deFormat(&$dirs) + function setTime($time) { - if (!count($dirs)) { - return array(); + $this->_isValid = 0; + if (!isset($this->_packageInfo['time'])) { + // ensure that the time tag is set up in the right location + $this->_packageInfo = $this->_insertBefore($this->_packageInfo, + array('version', + 'stability', 'license', 'notes', 'contents', 'compatible', + 'dependencies', 'providesextension', 'srcpackage', 'srcuri', + 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', + 'zendextbinrelease', 'bundle', 'changelog'), $time, 'time'); } - $newdirs = array(); - if (isset($dirs['dir'])) { - foreach ($dirs['dir'] as $dir => $contents) { - $newdir = array(); - $newdir['attribs']['name'] = $dir; - $this->_deFormat($contents); - foreach ($contents as $tag => $val) { - $newdir[$tag] = $val; - } - $newdirs['dir'][] = $newdir; - } - if (count($newdirs['dir']) == 1) { - $newdirs['dir'] = $newdirs['dir'][0]; - } + $this->_packageInfo['time'] = $time; + } + + function getDate() + { + if (isset($this->_packageInfo['date'])) { + return $this->_packageInfo['date']; } - if (isset($dirs['file'])) { - foreach ($dirs['file'] as $name => $file) { - $newdirs['file'][] = $file; - } - if (count($newdirs['file']) == 1) { - $newdirs['file'] = $newdirs['file'][0]; - } + return false; + } + + function getTime() + { + if (isset($this->_packageInfo['time'])) { + return $this->_packageInfo['time']; } - $dirs = $newdirs; + return false; } /** - * reset all options to default options - * - * @access public - * @see setOption(), XML_Unserializer() - */ - function resetOptions() + * @param package|api version category to return + */ + function getVersion($key = 'release') { - $this->options = $this->_defaultOptions; + if (isset($this->_packageInfo['version'][$key])) { + return $this->_packageInfo['version'][$key]; + } + return false; } - /** - * set an option - * - * You can use this method if you do not want to set all options in the constructor - * - * @access public - * @see resetOption(), XML_Serializer() - */ - function setOption($name, $value) + function getStability() { - $this->options[$name] = $value; + if (isset($this->_packageInfo['stability'])) { + return $this->_packageInfo['stability']; + } + return false; } - /** - * sets several options at once - * - * You can use this method if you do not want to set all options in the constructor - * - * @access public - * @see resetOption(), XML_Unserializer(), setOption() - */ - function setOptions($options) + function getState($key = 'release') { - $this->options = array_merge($this->options, $options); + if (isset($this->_packageInfo['stability'][$key])) { + return $this->_packageInfo['stability'][$key]; + } + return false; } - /** - * serialize data - * - * @access public - * @param mixed $data data to serialize - * @return boolean true on success, pear error on failure - */ - function serialize($data, $options = null) + function getLicense($raw = false) { - // if options have been specified, use them instead - // of the previously defined ones - if (is_array($options)) { - $optionsBak = $this->options; - if (isset($options['overrideOptions']) && $options['overrideOptions'] == true) { - $this->options = array_merge($this->_defaultOptions, $options); + if (isset($this->_packageInfo['license'])) { + if ($raw) { + return $this->_packageInfo['license']; + } + if (is_array($this->_packageInfo['license'])) { + return $this->_packageInfo['license']['_content']; } else { - $this->options = array_merge($this->options, $options); + return $this->_packageInfo['license']; } - } else { - $optionsBak = null; - } - - // start depth is zero - $this->_tagDepth = 0; - $this->_serializedData = ''; - // serialize an array - if (is_array($data)) { - $tagName = isset($this->options['rootName']) ? $this->options['rootName'] : 'array'; - $this->_serializedData .= $this->_serializeArray($data, $tagName, $this->options['rootAttributes']); - } - - // add doctype declaration - if ($this->options['addDoctype'] === true) { - $this->_serializedData = XML_Util::getDoctypeDeclaration($tagName, $this->options['doctype']) - . $this->options['linebreak'] - . $this->_serializedData; } + return false; + } - // build xml declaration - if ($this->options['addDecl']) { - $atts = array(); - $encoding = isset($this->options['encoding']) ? $this->options['encoding'] : null; - $this->_serializedData = XML_Util::getXMLDeclaration('1.0', $encoding) - . $this->options['linebreak'] - . $this->_serializedData; + function getLicenseLocation() + { + if (!isset($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) { + return false; } + return $this->_packageInfo['license']['attribs']; + } - - if ($optionsBak !== null) { - $this->options = $optionsBak; + function getNotes() + { + if (isset($this->_packageInfo['notes'])) { + return $this->_packageInfo['notes']; } - - return true; + return false; } - /** - * get the result of the serialization - * - * @access public - * @return string serialized XML - */ - function getSerializedData() + /** + * Return the tag contents, if any + * @return array|false + */ + function getUsesrole() { - if ($this->_serializedData === null) { - return $this->raiseError('No serialized data available. Use XML_Serializer::serialize() first.', XML_SERIALIZER_ERROR_NO_SERIALIZATION); + if (isset($this->_packageInfo['usesrole'])) { + return $this->_packageInfo['usesrole']; } - return $this->_serializedData; + return false; } - /** - * serialize any value - * - * This method checks for the type of the value and calls the appropriate method - * - * @access private - * @param mixed $value - * @param string $tagName - * @param array $attributes - * @return string - */ - function _serializeValue($value, $tagName = null, $attributes = array()) + /** + * Return the tag contents, if any + * @return array|false + */ + function getUsestask() { - if (is_array($value)) { - $xml = $this->_serializeArray($value, $tagName, $attributes); - } elseif (is_object($value)) { - $xml = $this->_serializeObject($value, $tagName); - } else { - $tag = array( - 'qname' => $tagName, - 'attributes' => $attributes, - 'content' => $value - ); - $xml = $this->_createXMLTag($tag); + if (isset($this->_packageInfo['usestask'])) { + return $this->_packageInfo['usestask']; } - return $xml; + return false; } - /** - * serialize an array - * - * @access private - * @param array $array array to serialize - * @param string $tagName name of the root tag - * @param array $attributes attributes for the root tag - * @return string $string serialized data - * @uses XML_Util::isValidName() to check, whether key has to be substituted - */ - function _serializeArray(&$array, $tagName = null, $attributes = array()) + /** + * This should only be used to retrieve filenames and install attributes + */ + function getFilelist($preserve = false) { - $_content = null; - - /** - * check for special attributes - */ - if ($this->options['attributesArray'] !== null) { - if (isset($array[$this->options['attributesArray']])) { - $attributes = $array[$this->options['attributesArray']]; - unset($array[$this->options['attributesArray']]); - } - /** - * check for special content - */ - if ($this->options['contentName'] !== null) { - if (isset($array[$this->options['contentName']])) { - $_content = $array[$this->options['contentName']]; - unset($array[$this->options['contentName']]); - } - } + if (isset($this->_packageInfo['filelist']) && !$preserve) { + return $this->_packageInfo['filelist']; } - - /* - * if mode is set to simpleXML, check whether - * the array is associative or indexed - */ - if (is_array($array) && $this->options['mode'] == 'simplexml') { - $indexed = true; - if (!count($array)) { - $indexed = false; - } - foreach ($array as $key => $val) { - if (!is_int($key)) { - $indexed = false; - break; - } - } - - if ($indexed && $this->options['mode'] == 'simplexml') { - $string = ''; - foreach ($array as $key => $val) { - if ($this->options['beautifyFilelist'] && $tagName == 'dir') { - if (!isset($this->_curdir)) { - $this->_curdir = ''; - } - $savedir = $this->_curdir; - if (isset($val['attribs'])) { - if ($val['attribs']['name'] == '/') { - $this->_curdir = '/'; - } else { - if ($this->_curdir == '/') { - $this->_curdir = ''; - } - $this->_curdir .= '/' . $val['attribs']['name']; - } - } - } - $string .= $this->_serializeValue( $val, $tagName, $attributes); - if ($this->options['beautifyFilelist'] && $tagName == 'dir') { - $string .= ' '; - if (empty($savedir)) { - unset($this->_curdir); - } else { - $this->_curdir = $savedir; - } - } - - $string .= $this->options['linebreak']; - // do indentation - if ($this->options['indent'] !== null && $this->_tagDepth > 0) { - $string .= str_repeat($this->options['indent'], $this->_tagDepth); - } + $this->flattenFilelist(); + if ($contents = $this->getContents()) { + $ret = array(); + if (!isset($contents['dir'])) { + return false; + } + if (!isset($contents['dir']['file'][0])) { + $contents['dir']['file'] = array($contents['dir']['file']); + } + foreach ($contents['dir']['file'] as $file) { + $name = $file['attribs']['name']; + if (!$preserve) { + $file = $file['attribs']; } - return rtrim($string); + $ret[$name] = $file; + } + if (!$preserve) { + $this->_packageInfo['filelist'] = $ret; } + return $ret; } + return false; + } - if ($this->options['scalarAsAttributes'] === true) { - foreach ($array as $key => $value) { - if (is_scalar($value) && (XML_Util::isValidName($key) === true)) { - unset($array[$key]); - $attributes[$this->options['prependAttributes'].$key] = $value; - } + /** + * Return configure options array, if any + * + * @return array|false + */ + function getConfigureOptions() + { + if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { + return false; + } + + $releases = $this->getReleases(); + if (isset($releases[0])) { + $releases = $releases[0]; + } + + if (isset($releases['configureoption'])) { + if (!isset($releases['configureoption'][0])) { + $releases['configureoption'] = array($releases['configureoption']); + } + + for ($i = 0; $i < count($releases['configureoption']); $i++) { + $releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs']; } + + return $releases['configureoption']; } - // check for empty array => create empty tag - if (empty($array)) { - $tag = array( - 'qname' => $tagName, - 'content' => $_content, - 'attributes' => $attributes - ); + return false; + } - } else { - $this->_tagDepth++; - $tmp = $this->options['linebreak']; - foreach ($array as $key => $value) { - // do indentation - if ($this->options['indent'] !== null && $this->_tagDepth > 0) { - $tmp .= str_repeat($this->options['indent'], $this->_tagDepth); - } + /** + * This is only used at install-time, after all serialization + * is over. + */ + function resetFilelist() + { + $this->_packageInfo['filelist'] = array(); + } - // copy key - $origKey = $key; - // key cannot be used as tagname => use default tag - $valid = XML_Util::isValidName($key); - if (PEAR::isError($valid)) { - if ($this->options['classAsTagName'] && is_object($value)) { - $key = get_class($value); - } else { - $key = $this->options['defaultTagName']; + /** + * Retrieve a list of files that should be installed on this computer + * @return array + */ + function getInstallationFilelist($forfilecheck = false) + { + $contents = $this->getFilelist(true); + if (isset($contents['dir']['attribs']['baseinstalldir'])) { + $base = $contents['dir']['attribs']['baseinstalldir']; + } + if (isset($this->_packageInfo['bundle'])) { + return PEAR::raiseError( + 'Exception: bundles should be handled in download code only'); + } + $release = $this->getReleases(); + if ($release) { + if (!isset($release[0])) { + if (!isset($release['installconditions']) && !isset($release['filelist'])) { + if ($forfilecheck) { + return $this->getFilelist(); } + return $contents; } - $atts = array(); - if ($this->options['typeHints'] === true) { - $atts[$this->options['typeAttribute']] = gettype($value); - if ($key !== $origKey) { - $atts[$this->options['keyAttribute']] = (string)$origKey; + $release = array($release); + } + $depchecker = &$this->getPEARDependency2($this->_config, array(), + array('channel' => $this->getChannel(), 'package' => $this->getPackage()), + PEAR_VALIDATE_INSTALLING); + foreach ($release as $instance) { + if (isset($instance['installconditions'])) { + $installconditions = $instance['installconditions']; + if (is_array($installconditions)) { + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + foreach ($installconditions as $type => $conditions) { + if (!isset($conditions[0])) { + $conditions = array($conditions); + } + foreach ($conditions as $condition) { + $ret = $depchecker->{"validate{$type}Dependency"}($condition); + if (PEAR::isError($ret)) { + PEAR::popErrorHandling(); + continue 3; // skip this release + } + } + } + PEAR::popErrorHandling(); } - } - if ($this->options['beautifyFilelist'] && $key == 'dir') { - if (!isset($this->_curdir)) { - $this->_curdir = ''; + // this is the release to use + if (isset($instance['filelist'])) { + // ignore files + if (isset($instance['filelist']['ignore'])) { + $ignore = isset($instance['filelist']['ignore'][0]) ? + $instance['filelist']['ignore'] : + array($instance['filelist']['ignore']); + foreach ($ignore as $ig) { + unset ($contents[$ig['attribs']['name']]); + } } - $savedir = $this->_curdir; - if (isset($value['attribs'])) { - if ($value['attribs']['name'] == '/') { - $this->_curdir = '/'; - } else { - $this->_curdir .= '/' . $value['attribs']['name']; + // install files as this name + if (isset($instance['filelist']['install'])) { + $installas = isset($instance['filelist']['install'][0]) ? + $instance['filelist']['install'] : + array($instance['filelist']['install']); + foreach ($installas as $as) { + $contents[$as['attribs']['name']]['attribs']['install-as'] = + $as['attribs']['as']; } } } - - if (is_string($value) && $value && ($value{strlen($value) - 1} == "\n")) { - $value .= str_repeat($this->options['indent'], $this->_tagDepth); - } - $tmp .= $this->_createXMLTag(array( - 'qname' => $key, - 'attributes' => $atts, - 'content' => $value ) - ); - if ($this->options['beautifyFilelist'] && $key == 'dir') { - if (isset($value['attribs'])) { - $tmp .= ' '; - if (empty($savedir)) { - unset($this->_curdir); - } else { - $this->_curdir = $savedir; - } + if ($forfilecheck) { + foreach ($contents as $file => $attrs) { + $contents[$file] = $attrs['attribs']; } } - $tmp .= $this->options['linebreak']; - } - - $this->_tagDepth--; - if ($this->options['indent']!==null && $this->_tagDepth>0) { - $tmp .= str_repeat($this->options['indent'], $this->_tagDepth); - } - - if (trim($tmp) === '') { - $tmp = null; + return $contents; } - - $tag = array( - 'qname' => $tagName, - 'content' => $tmp, - 'attributes' => $attributes - ); - } - if ($this->options['typeHints'] === true) { - if (!isset($tag['attributes'][$this->options['typeAttribute']])) { - $tag['attributes'][$this->options['typeAttribute']] = 'array'; + } else { // simple release - no installconditions or install-as + if ($forfilecheck) { + return $this->getFilelist(); } + return $contents; } - - $string = $this->_createXMLTag($tag, false); - return $string; + // no releases matched + return PEAR::raiseError('No releases in package.xml matched the existing operating ' . + 'system, extensions installed, or architecture, cannot install'); } - /** - * create a tag from an array - * this method awaits an array in the following format - * array( - * 'qname' => $tagName, - * 'attributes' => array(), - * 'content' => $content, // optional - * 'namespace' => $namespace // optional - * 'namespaceUri' => $namespaceUri // optional - * ) - * - * @access private - * @param array $tag tag definition - * @param boolean $replaceEntities whether to replace XML entities in content or not - * @return string $string XML tag - */ - function _createXMLTag($tag, $replaceEntities = true) + /** + * This is only used at install-time, after all serialization + * is over. + * @param string file name + * @param string installed path + */ + function setInstalledAs($file, $path) { - if ($this->options['indentAttributes'] !== false) { - $multiline = true; - $indent = str_repeat($this->options['indent'], $this->_tagDepth); + if ($path) { + return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; + } + unset($this->_packageInfo['filelist'][$file]['installed_as']); + } - if ($this->options['indentAttributes'] == '_auto') { - $indent .= str_repeat(' ', (strlen($tag['qname'])+2)); + function getInstalledLocation($file) + { + if (isset($this->_packageInfo['filelist'][$file]['installed_as'])) { + return $this->_packageInfo['filelist'][$file]['installed_as']; + } + return false; + } - } else { - $indent .= $this->options['indentAttributes']; - } + /** + * This is only used at install-time, after all serialization + * is over. + */ + function installedFile($file, $atts) + { + if (isset($this->_packageInfo['filelist'][$file])) { + $this->_packageInfo['filelist'][$file] = + array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']); } else { - $indent = $multiline = false; + $this->_packageInfo['filelist'][$file] = $atts['attribs']; } + } - if (is_array($tag['content'])) { - if (empty($tag['content'])) { - $tag['content'] = ''; - } - } elseif(is_scalar($tag['content']) && (string)$tag['content'] == '') { - $tag['content'] = ''; + /** + * Retrieve the contents tag + */ + function getContents() + { + if (isset($this->_packageInfo['contents'])) { + return $this->_packageInfo['contents']; } + return false; + } - if (is_scalar($tag['content']) || is_null($tag['content'])) { - if ($this->options['encoding'] == 'UTF-8' && - version_compare(phpversion(), '5.0.0', 'lt') - ) { - $tag = utf8_encode($tag); - } - - if ($replaceEntities === true) { - $replaceEntities = XML_UTIL_ENTITIES_XML; + /** + * @param string full path to file + * @param string attribute name + * @param string attribute value + * @param int risky but fast - use this to choose a file based on its position in the list + * of files. Index is zero-based like PHP arrays. + * @return bool success of operation + */ + function setFileAttribute($filename, $attr, $value, $index = false) + { + $this->_isValid = 0; + if (in_array($attr, array('role', 'name', 'baseinstalldir'))) { + $this->_filesValid = false; + } + if ($index !== false && + isset($this->_packageInfo['contents']['dir']['file'][$index]['attribs'])) { + $this->_packageInfo['contents']['dir']['file'][$index]['attribs'][$attr] = $value; + return true; + } + if (!isset($this->_packageInfo['contents']['dir']['file'])) { + return false; + } + $files = $this->_packageInfo['contents']['dir']['file']; + if (!isset($files[0])) { + $files = array($files); + $ind = false; + } else { + $ind = true; + } + foreach ($files as $i => $file) { + if (isset($file['attribs'])) { + if ($file['attribs']['name'] == $filename) { + if ($ind) { + $this->_packageInfo['contents']['dir']['file'][$i]['attribs'][$attr] = $value; + } else { + $this->_packageInfo['contents']['dir']['file']['attribs'][$attr] = $value; + } + return true; + } } - - $tag = XML_Util::createTagFromArray($tag, $replaceEntities, $multiline, $indent, $this->options['linebreak']); - } elseif (is_array($tag['content'])) { - $tag = $this->_serializeArray($tag['content'], $tag['qname'], $tag['attributes']); - } elseif (is_object($tag['content'])) { - $tag = $this->_serializeObject($tag['content'], $tag['qname'], $tag['attributes']); - } elseif (is_resource($tag['content'])) { - settype($tag['content'], 'string'); - $tag = XML_Util::createTagFromArray($tag, $replaceEntities); } - return $tag; + return false; } -} - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v1.php,v 1.30 2009/02/24 23:45:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/** - * package.xml abstraction class - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; -/** - * Parser for package.xml version 1.0 - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_PackageFile_Parser_v1 -{ - var $_registry; - var $_config; - var $_logger; - /** - * BC hack to allow PEAR_Common::infoFromString() to sort of - * work with the version 2.0 format - there's no filelist though - * @param PEAR_PackageFile_v2 - */ - function fromV2($packagefile) + + function setDirtree($path) { - $info = $packagefile->getArray(true); - $ret = new PEAR_PackageFile_v1; - $ret->fromArray($info['old']); + if (!isset($this->_packageInfo['dirtree'])) { + $this->_packageInfo['dirtree'] = array(); + } + $this->_packageInfo['dirtree'][$path] = true; } - function setConfig(&$c) + function getDirtree() { - $this->_config = &$c; - $this->_registry = &$c->getRegistry(); + if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { + return $this->_packageInfo['dirtree']; + } + return false; } - function setLogger(&$l) + function resetDirtree() { - $this->_logger = &$l; + unset($this->_packageInfo['dirtree']); } /** - * @param string contents of package.xml file, version 1.0 - * @return bool success of parsing + * Determines whether this package claims it is compatible with the version of + * the package that has a recommended version dependency + * @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package + * @return boolean */ - function &parse($data, $file, $archive = false) + function isCompatible($pf) { - if (!extension_loaded('xml')) { - return PEAR::raiseError('Cannot create xml parser for parsing package.xml, no xml extension'); + if (!isset($this->_packageInfo['compatible'])) { + return false; } - $xp = xml_parser_create(); - if (!$xp) { - $a = &PEAR::raiseError('Cannot create xml parser for parsing package.xml'); - return $a; + if (!isset($this->_packageInfo['channel'])) { + return false; } - xml_set_object($xp, $this); - xml_set_element_handler($xp, '_element_start_1_0', '_element_end_1_0'); - xml_set_character_data_handler($xp, '_pkginfo_cdata_1_0'); - xml_parser_set_option($xp, XML_OPTION_CASE_FOLDING, false); - - $this->element_stack = array(); - $this->_packageInfo = array('provides' => array()); - $this->current_element = false; - unset($this->dir_install); - $this->_packageInfo['filelist'] = array(); - $this->filelist =& $this->_packageInfo['filelist']; - $this->dir_names = array(); - $this->in_changelog = false; - $this->d_i = 0; - $this->cdata = ''; - $this->_isValid = true; - - if (!xml_parse($xp, $data, 1)) { - $code = xml_get_error_code($xp); - $line = xml_get_current_line_number($xp); - xml_parser_free($xp); - $a = &PEAR::raiseError(sprintf("XML error: %s at line %d", - $str = xml_error_string($code), $line), 2); - return $a; + $me = $pf->getVersion(); + $compatible = $this->_packageInfo['compatible']; + if (!isset($compatible[0])) { + $compatible = array($compatible); } - - xml_parser_free($xp); - - $pf = new PEAR_PackageFile_v1; - $pf->setConfig($this->_config); - if (isset($this->_logger)) { - $pf->setLogger($this->_logger); + $found = false; + foreach ($compatible as $info) { + if (strtolower($info['name']) == strtolower($pf->getPackage())) { + if (strtolower($info['channel']) == strtolower($pf->getChannel())) { + $found = true; + break; + } + } } - $pf->setPackagefile($file, $archive); - $pf->fromArray($this->_packageInfo); - return $pf; + if (!$found) { + return false; + } + if (isset($info['exclude'])) { + if (!isset($info['exclude'][0])) { + $info['exclude'] = array($info['exclude']); + } + foreach ($info['exclude'] as $exclude) { + if (version_compare($me, $exclude, '==')) { + return false; + } + } + } + if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) { + return true; + } + return false; } - // {{{ _unIndent() /** - * Unindent given string - * - * @param string $str The string that has to be unindented. - * @return string - * @access private + * @return array|false */ - function _unIndent($str) + function getCompatible() { - // remove leading newlines - $str = preg_replace('/^[\r\n]+/', '', $str); - // find whitespace at the beginning of the first line - $indent_len = strspn($str, " \t"); - $indent = substr($str, 0, $indent_len); - $data = ''; - // remove the same amount of whitespace from following lines - foreach (explode("\n", $str) as $line) { - if (substr($line, 0, $indent_len) == $indent) { - $data .= substr($line, $indent_len) . "\n"; - } elseif (trim(substr($line, 0, $indent_len))) { - $data .= ltrim($line); - } + if (isset($this->_packageInfo['compatible'])) { + return $this->_packageInfo['compatible']; } - return $data; + return false; + } + + function getDependencies() + { + if (isset($this->_packageInfo['dependencies'])) { + return $this->_packageInfo['dependencies']; + } + return false; } - // Support for package DTD v1.0: - // {{{ _element_start_1_0() + function isSubpackageOf($p) + { + return $p->isSubpackage($this); + } /** - * XML parser callback for ending elements. Used for version 1.0 - * packages. - * - * @param resource $xp XML parser resource - * @param string $name name of ending element - * - * @return void + * Determines whether the passed in package is a subpackage of this package. * - * @access private + * No version checking is done, only name verification. + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return bool */ - function _element_start_1_0($xp, $name, $attribs) + function isSubpackage($p) { - array_push($this->element_stack, $name); - $this->current_element = $name; - $spos = sizeof($this->element_stack) - 2; - $this->prev_element = ($spos >= 0) ? $this->element_stack[$spos] : ''; - $this->current_attributes = $attribs; - $this->cdata = ''; - switch ($name) { - case 'dir': - if ($this->in_changelog) { - break; + $sub = array(); + if (isset($this->_packageInfo['dependencies']['required']['subpackage'])) { + $sub = $this->_packageInfo['dependencies']['required']['subpackage']; + if (!isset($sub[0])) { + $sub = array($sub); + } + } + if (isset($this->_packageInfo['dependencies']['optional']['subpackage'])) { + $sub1 = $this->_packageInfo['dependencies']['optional']['subpackage']; + if (!isset($sub1[0])) { + $sub1 = array($sub1); + } + $sub = array_merge($sub, $sub1); + } + if (isset($this->_packageInfo['dependencies']['group'])) { + $group = $this->_packageInfo['dependencies']['group']; + if (!isset($group[0])) { + $group = array($group); + } + foreach ($group as $deps) { + if (isset($deps['subpackage'])) { + $sub2 = $deps['subpackage']; + if (!isset($sub2[0])) { + $sub2 = array($sub2); + } + $sub = array_merge($sub, $sub2); } - if (array_key_exists('name', $attribs) && $attribs['name'] != '/') { - $attribs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), - $attribs['name']); - if (strrpos($attribs['name'], '/') === strlen($attribs['name']) - 1) { - $attribs['name'] = substr($attribs['name'], 0, - strlen($attribs['name']) - 1); + } + } + foreach ($sub as $dep) { + if (strtolower($dep['name']) == strtolower($p->getPackage())) { + if (isset($dep['channel'])) { + if (strtolower($dep['channel']) == strtolower($p->getChannel())) { + return true; } - if (strpos($attribs['name'], '/') === 0) { - $attribs['name'] = substr($attribs['name'], 1); + } else { + if ($dep['uri'] == $p->getURI()) { + return true; } - $this->dir_names[] = $attribs['name']; - } - if (isset($attribs['baseinstalldir'])) { - $this->dir_install = $attribs['baseinstalldir']; - } - if (isset($attribs['role'])) { - $this->dir_role = $attribs['role']; - } - break; - case 'file': - if ($this->in_changelog) { - break; } - if (isset($attribs['name'])) { - $path = ''; - if (count($this->dir_names)) { - foreach ($this->dir_names as $dir) { - $path .= $dir . '/'; - } - } - $path .= preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), - $attribs['name']); - unset($attribs['name']); - $this->current_path = $path; - $this->filelist[$path] = $attribs; - // Set the baseinstalldir only if the file don't have this attrib - if (!isset($this->filelist[$path]['baseinstalldir']) && - isset($this->dir_install)) - { - $this->filelist[$path]['baseinstalldir'] = $this->dir_install; + } + } + return false; + } + + function dependsOn($package, $channel) + { + if (!($deps = $this->getDependencies())) { + return false; + } + foreach (array('package', 'subpackage') as $type) { + foreach (array('required', 'optional') as $needed) { + if (isset($deps[$needed][$type])) { + if (!isset($deps[$needed][$type][0])) { + $deps[$needed][$type] = array($deps[$needed][$type]); } - // Set the Role - if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) { - $this->filelist[$path]['role'] = $this->dir_role; + foreach ($deps[$needed][$type] as $dep) { + $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; + if (strtolower($dep['name']) == strtolower($package) && + $depchannel == $channel) { + return true; + } } } - break; - case 'replace': - if (!$this->in_changelog) { - $this->filelist[$this->current_path]['replacements'][] = $attribs; - } - break; - case 'maintainers': - $this->_packageInfo['maintainers'] = array(); - $this->m_i = 0; // maintainers array index - break; - case 'maintainer': - // compatibility check - if (!isset($this->_packageInfo['maintainers'])) { - $this->_packageInfo['maintainers'] = array(); - $this->m_i = 0; - } - $this->_packageInfo['maintainers'][$this->m_i] = array(); - $this->current_maintainer =& $this->_packageInfo['maintainers'][$this->m_i]; - break; - case 'changelog': - $this->_packageInfo['changelog'] = array(); - $this->c_i = 0; // changelog array index - $this->in_changelog = true; - break; - case 'release': - if ($this->in_changelog) { - $this->_packageInfo['changelog'][$this->c_i] = array(); - $this->current_release = &$this->_packageInfo['changelog'][$this->c_i]; - } else { - $this->current_release = &$this->_packageInfo; - } - break; - case 'deps': - if (!$this->in_changelog) { - $this->_packageInfo['release_deps'] = array(); - } - break; - case 'dep': - // dependencies array index - if (!$this->in_changelog) { - $this->d_i++; - isset($attribs['type']) ? ($attribs['type'] = strtolower($attribs['type'])) : false; - $this->_packageInfo['release_deps'][$this->d_i] = $attribs; - } - break; - case 'configureoptions': - if (!$this->in_changelog) { - $this->_packageInfo['configure_options'] = array(); - } - break; - case 'configureoption': - if (!$this->in_changelog) { - $this->_packageInfo['configure_options'][] = $attribs; - } - break; - case 'provides': - if (empty($attribs['type']) || empty($attribs['name'])) { - break; - } - $attribs['explicit'] = true; - $this->_packageInfo['provides']["$attribs[type];$attribs[name]"] = $attribs; - break; - case 'package' : - if (isset($attribs['version'])) { - $this->_packageInfo['xsdversion'] = trim($attribs['version']); - } else { - $this->_packageInfo['xsdversion'] = '1.0'; + } + if (isset($deps['group'])) { + if (!isset($deps['group'][0])) { + $dep['group'] = array($deps['group']); } - if (isset($attribs['packagerversion'])) { - $this->_packageInfo['packagerversion'] = $attribs['packagerversion']; + foreach ($deps['group'] as $group) { + if (isset($group[$type])) { + if (!is_array($group[$type])) { + $group[$type] = array($group[$type]); + } + foreach ($group[$type] as $dep) { + $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; + if (strtolower($dep['name']) == strtolower($package) && + $depchannel == $channel) { + return true; + } + } + } } - break; + } } + return false; } - // }}} - // {{{ _element_end_1_0() + /** + * Get the contents of a dependency group + * @param string + * @return array|false + */ + function getDependencyGroup($name) + { + $name = strtolower($name); + if (!isset($this->_packageInfo['dependencies']['group'])) { + return false; + } + $groups = $this->_packageInfo['dependencies']['group']; + if (!isset($groups[0])) { + $groups = array($groups); + } + foreach ($groups as $group) { + if (strtolower($group['attribs']['name']) == $name) { + return $group; + } + } + return false; + } /** - * XML parser callback for ending elements. Used for version 1.0 - * packages. - * - * @param resource $xp XML parser resource - * @param string $name name of ending element - * - * @return void + * Retrieve a partial package.xml 1.0 representation of dependencies * - * @access private + * a very limited representation of dependencies is returned by this method. + * The tag for excluding certain versions of a dependency is + * completely ignored. In addition, dependency groups are ignored, with the + * assumption that all dependencies in dependency groups are also listed in + * the optional group that work with all dependency groups + * @param boolean return package.xml 2.0 tag + * @return array|false */ - function _element_end_1_0($xp, $name) + function getDeps($raw = false, $nopearinstaller = false) { - $data = trim($this->cdata); - switch ($name) { - case 'name': - switch ($this->prev_element) { - case 'package': - $this->_packageInfo['package'] = $data; - break; - case 'maintainer': - $this->current_maintainer['name'] = $data; - break; - } - break; - case 'extends' : - $this->_packageInfo['extends'] = $data; - break; - case 'summary': - $this->_packageInfo['summary'] = $data; - break; - case 'description': - $data = $this->_unIndent($this->cdata); - $this->_packageInfo['description'] = $data; - break; - case 'user': - $this->current_maintainer['handle'] = $data; - break; - case 'email': - $this->current_maintainer['email'] = $data; - break; - case 'role': - $this->current_maintainer['role'] = $data; - break; - case 'version': - if ($this->in_changelog) { - $this->current_release['version'] = $data; - } else { - $this->_packageInfo['version'] = $data; - } - break; - case 'date': - if ($this->in_changelog) { - $this->current_release['release_date'] = $data; - } else { - $this->_packageInfo['release_date'] = $data; - } - break; - case 'notes': - // try to "de-indent" release notes in case someone - // has been over-indenting their xml ;-) - // Trim only on the right side - $data = rtrim($this->_unIndent($this->cdata)); - if ($this->in_changelog) { - $this->current_release['release_notes'] = $data; - } else { - $this->_packageInfo['release_notes'] = $data; - } - break; - case 'warnings': - if ($this->in_changelog) { - $this->current_release['release_warnings'] = $data; - } else { - $this->_packageInfo['release_warnings'] = $data; - } - break; - case 'state': - if ($this->in_changelog) { - $this->current_release['release_state'] = $data; - } else { - $this->_packageInfo['release_state'] = $data; - } - break; - case 'license': - if ($this->in_changelog) { - $this->current_release['release_license'] = $data; - } else { - $this->_packageInfo['release_license'] = $data; - } - break; - case 'dep': - if ($data && !$this->in_changelog) { - $this->_packageInfo['release_deps'][$this->d_i]['name'] = $data; - } - break; - case 'dir': - if ($this->in_changelog) { - break; - } - array_pop($this->dir_names); - break; - case 'file': - if ($this->in_changelog) { - break; + if (isset($this->_packageInfo['dependencies'])) { + if ($raw) { + return $this->_packageInfo['dependencies']; + } + $ret = array(); + $map = array( + 'php' => 'php', + 'package' => 'pkg', + 'subpackage' => 'pkg', + 'extension' => 'ext', + 'os' => 'os', + 'pearinstaller' => 'pkg', + ); + foreach (array('required', 'optional') as $type) { + $optional = ($type == 'optional') ? 'yes' : 'no'; + if (!isset($this->_packageInfo['dependencies'][$type]) + || empty($this->_packageInfo['dependencies'][$type])) { + continue; } - if ($data) { - $path = ''; - if (count($this->dir_names)) { - foreach ($this->dir_names as $dir) { - $path .= $dir . '/'; - } + foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) { + if ($dtype == 'pearinstaller' && $nopearinstaller) { + continue; } - $path .= $data; - $this->filelist[$path] = $this->current_attributes; - // Set the baseinstalldir only if the file don't have this attrib - if (!isset($this->filelist[$path]['baseinstalldir']) && - isset($this->dir_install)) - { - $this->filelist[$path]['baseinstalldir'] = $this->dir_install; + if (!isset($deps[0])) { + $deps = array($deps); } - // Set the Role - if (!isset($this->filelist[$path]['role']) && isset($this->dir_role)) { - $this->filelist[$path]['role'] = $this->dir_role; + foreach ($deps as $dep) { + if (!isset($map[$dtype])) { + // no support for arch type + continue; + } + if ($dtype == 'pearinstaller') { + $dep['name'] = 'PEAR'; + $dep['channel'] = 'pear.php.net'; + } + $s = array('type' => $map[$dtype]); + if (isset($dep['channel'])) { + $s['channel'] = $dep['channel']; + } + if (isset($dep['uri'])) { + $s['uri'] = $dep['uri']; + } + if (isset($dep['name'])) { + $s['name'] = $dep['name']; + } + if (isset($dep['conflicts'])) { + $s['rel'] = 'not'; + } else { + if (!isset($dep['min']) && + !isset($dep['max'])) { + $s['rel'] = 'has'; + $s['optional'] = $optional; + } elseif (isset($dep['min']) && + isset($dep['max'])) { + $s['rel'] = 'ge'; + $s1 = $s; + $s1['rel'] = 'le'; + $s['version'] = $dep['min']; + $s1['version'] = $dep['max']; + if (isset($dep['channel'])) { + $s1['channel'] = $dep['channel']; + } + if ($dtype != 'php') { + $s['name'] = $dep['name']; + $s1['name'] = $dep['name']; + } + $s['optional'] = $optional; + $s1['optional'] = $optional; + $ret[] = $s1; + } elseif (isset($dep['min'])) { + if (isset($dep['exclude']) && + $dep['exclude'] == $dep['min']) { + $s['rel'] = 'gt'; + } else { + $s['rel'] = 'ge'; + } + $s['version'] = $dep['min']; + $s['optional'] = $optional; + if ($dtype != 'php') { + $s['name'] = $dep['name']; + } + } elseif (isset($dep['max'])) { + if (isset($dep['exclude']) && + $dep['exclude'] == $dep['max']) { + $s['rel'] = 'lt'; + } else { + $s['rel'] = 'le'; + } + $s['version'] = $dep['max']; + $s['optional'] = $optional; + if ($dtype != 'php') { + $s['name'] = $dep['name']; + } + } + } + $ret[] = $s; } } - break; - case 'maintainer': - if (empty($this->_packageInfo['maintainers'][$this->m_i]['role'])) { - $this->_packageInfo['maintainers'][$this->m_i]['role'] = 'lead'; - } - $this->m_i++; - break; - case 'release': - if ($this->in_changelog) { - $this->c_i++; - } - break; - case 'changelog': - $this->in_changelog = false; - break; + } + if (count($ret)) { + return $ret; + } + } + return false; + } + + /** + * @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false + */ + function getPackageType() + { + if (isset($this->_packageInfo['phprelease'])) { + return 'php'; + } + if (isset($this->_packageInfo['extsrcrelease'])) { + return 'extsrc'; + } + if (isset($this->_packageInfo['extbinrelease'])) { + return 'extbin'; + } + if (isset($this->_packageInfo['zendextsrcrelease'])) { + return 'zendextsrc'; + } + if (isset($this->_packageInfo['zendextbinrelease'])) { + return 'zendextbin'; + } + if (isset($this->_packageInfo['bundle'])) { + return 'bundle'; + } + return false; + } + + /** + * @return array|false + */ + function getReleases() + { + $type = $this->getPackageType(); + if ($type != 'bundle') { + $type .= 'release'; } - array_pop($this->element_stack); - $spos = sizeof($this->element_stack) - 1; - $this->current_element = ($spos > 0) ? $this->element_stack[$spos] : ''; - $this->cdata = ''; + if ($this->getPackageType() && isset($this->_packageInfo[$type])) { + return $this->_packageInfo[$type]; + } + return false; } - // }}} - // {{{ _pkginfo_cdata_1_0() - /** - * XML parser callback for character data. Used for version 1.0 - * packages. - * - * @param resource $xp XML parser resource - * @param string $name character data - * - * @return void - * - * @access private + * @return array */ - function _pkginfo_cdata_1_0($xp, $data) + function getChangelog() { - if (isset($this->cdata)) { - $this->cdata .= $data; + if (isset($this->_packageInfo['changelog'])) { + return $this->_packageInfo['changelog']; } + return false; } - // }}} -} -?> - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v2.php,v 1.24 2009/02/24 23:45:22 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/** - * base xml parser class - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2.php'; -/** - * Parser for package.xml version 2.0 - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_PackageFile_Parser_v2 extends PEAR_XMLParser -{ - var $_config; - var $_logger; - var $_registry; + function hasDeps() + { + return isset($this->_packageInfo['dependencies']); + } - function setConfig(&$c) + function getPackagexmlVersion() { - $this->_config = &$c; - $this->_registry = &$c->getRegistry(); + if (isset($this->_packageInfo['zendextsrcrelease'])) { + return '2.1'; + } + if (isset($this->_packageInfo['zendextbinrelease'])) { + return '2.1'; + } + return '2.0'; } - function setLogger(&$l) + /** + * @return array|false + */ + function getSourcePackage() { - $this->_logger = &$l; + if (isset($this->_packageInfo['extbinrelease']) || + isset($this->_packageInfo['zendextbinrelease'])) { + return array('channel' => $this->_packageInfo['srcchannel'], + 'package' => $this->_packageInfo['srcpackage']); + } + return false; + } + + function getBundledPackages() + { + if (isset($this->_packageInfo['bundle'])) { + return $this->_packageInfo['contents']['bundledpackage']; + } + return false; + } + + function getLastModified() + { + if (isset($this->_packageInfo['_lastmodified'])) { + return $this->_packageInfo['_lastmodified']; + } + return false; } + /** - * Unindent given string - * - * @param string $str The string that has to be unindented. + * Get the contents of a file listed within the package.xml + * @param string * @return string - * @access private */ - function _unIndent($str) + function getFileContents($file) { - // remove leading newlines - $str = preg_replace('/^[\r\n]+/', '', $str); - // find whitespace at the beginning of the first line - $indent_len = strspn($str, " \t"); - $indent = substr($str, 0, $indent_len); - $data = ''; - // remove the same amount of whitespace from following lines - foreach (explode("\n", $str) as $line) { - if (substr($line, 0, $indent_len) == $indent) { - $data .= substr($line, $indent_len) . "\n"; + if ($this->_archiveFile == $this->_packageFile) { // unpacked + $dir = dirname($this->_packageFile); + $file = $dir . DIRECTORY_SEPARATOR . $file; + $file = str_replace(array('/', '\\'), + array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); + if (file_exists($file) && is_readable($file)) { + return implode('', file($file)); + } + } else { // tgz + $tar = &new Archive_Tar($this->_archiveFile); + $tar->pushErrorHandling(PEAR_ERROR_RETURN); + if ($file != 'package.xml' && $file != 'package2.xml') { + $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; + } + $file = $tar->extractInString($file); + $tar->popErrorHandling(); + if (PEAR::isError($file)) { + return PEAR::raiseError("Cannot locate file '$file' in archive"); + } + return $file; + } + } + + function &getRW() + { + if (!class_exists('PEAR_PackageFile_v2_rw')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2/rw.php'; + } + $a = new PEAR_PackageFile_v2_rw; + foreach (get_object_vars($this) as $name => $unused) { + if (!isset($this->$name)) { + continue; + } + if ($name == '_config' || $name == '_logger'|| $name == '_registry' || + $name == '_stack') { + $a->$name = &$this->$name; } else { - $data .= $line . "\n"; + $a->$name = $this->$name; } } - return $data; + return $a; + } + + function &getDefaultGenerator() + { + if (!class_exists('PEAR_PackageFile_Generator_v2')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/Generator/v2.php'; + } + $a = &new PEAR_PackageFile_Generator_v2($this); + return $a; + } + + function analyzeSourceCode($file, $string = false) + { + if (!isset($this->_v2Validator) || + !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { + if (!class_exists('PEAR_PackageFile_v2_Validator')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2/Validator.php'; + } + $this->_v2Validator = new PEAR_PackageFile_v2_Validator; + } + return $this->_v2Validator->analyzeSourceCode($file, $string); + } + + function validate($state = PEAR_VALIDATE_NORMAL) + { + if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { + return false; + } + if (!isset($this->_v2Validator) || + !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { + if (!class_exists('PEAR_PackageFile_v2_Validator')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2/Validator.php'; + } + $this->_v2Validator = new PEAR_PackageFile_v2_Validator; + } + if (isset($this->_packageInfo['xsdversion'])) { + unset($this->_packageInfo['xsdversion']); + } + return $this->_v2Validator->validate($this, $state); + } + + function getTasksNs() + { + if (!isset($this->_tasksNs)) { + if (isset($this->_packageInfo['attribs'])) { + foreach ($this->_packageInfo['attribs'] as $name => $value) { + if ($value == 'http://pear.php.net/dtd/tasks-1.0') { + $this->_tasksNs = str_replace('xmlns:', '', $name); + break; + } + } + } + } + return $this->_tasksNs; } /** - * post-process data + * Determine whether a task name is a valid task. Custom tasks may be defined + * using subdirectories by putting a "-" in the name, as in * - * @param string $data - * @param string $element element name + * Note that this method will auto-load the task class file and test for the existence + * of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class + * PEAR_Task_mycustom_task + * @param string + * @return boolean */ - function postProcess($data, $element) + function getTask($task) { - if ($element == 'notes') { - return trim($this->_unIndent($data)); + $this->getTasksNs(); + // transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace + $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task); + $taskfile = str_replace(' ', '/', ucwords($task)); + $task = str_replace(array(' ', '/'), '_', ucwords($task)); + if (class_exists("PEAR_Task_$task")) { + return "PEAR_Task_$task"; } - return trim($data); + $fp = @fopen("phar://install-pear-nozlib.phar/PEAR/Task/$taskfile.php", 'r', true); + if ($fp) { + fclose($fp); + require_once 'phar://install-pear-nozlib.phar/' . "PEAR/Task/$taskfile.php"; + return "PEAR_Task_$task"; + } + return false; } /** - * @param string - * @param string file name of the package.xml - * @param string|false name of the archive this package.xml came from, if any - * @param string class name to instantiate and return. This must be PEAR_PackageFile_v2 or - * a subclass - * @return PEAR_PackageFile_v2 + * Key-friendly array_splice + * @param tagname to splice a value in before + * @param mixed the value to splice in + * @param string the new tag name */ - function &parse($data, $file, $archive = false, $class = 'PEAR_PackageFile_v2') + function _ksplice($array, $key, $value, $newkey) { - if (PEAR::isError($err = parent::parse($data, $file))) { - return $err; - } + $offset = array_search($key, array_keys($array)); + $after = array_slice($array, $offset); + $before = array_slice($array, 0, $offset); + $before[$newkey] = $value; + return array_merge($before, $after); + } - $ret = new $class; - $ret->encoding = $this->encoding; - $ret->setConfig($this->_config); - if (isset($this->_logger)) { - $ret->setLogger($this->_logger); + /** + * @param array a list of possible keys, in the order they may occur + * @param mixed contents of the new package.xml tag + * @param string tag name + * @access private + */ + function _insertBefore($array, $keys, $contents, $newkey) + { + foreach ($keys as $key) { + if (isset($array[$key])) { + return $array = $this->_ksplice($array, $key, $contents, $newkey); + } } + $array[$newkey] = $contents; + return $array; + } - $ret->fromArray($this->_unserializedData); - $ret->setPackagefile($file, $archive); - return $ret; + /** + * @param subsection of {@link $_packageInfo} + * @param array|string tag contents + * @param array format: + *
    +     * array(
    +     *   tagname => array(list of tag names that follow this one),
    +     *   childtagname => array(list of child tag names that follow this one),
    +     * )
    +     * 
    + * + * This allows construction of nested tags + * @access private + */ + function _mergeTag($manip, $contents, $order) + { + if (count($order)) { + foreach ($order as $tag => $curorder) { + if (!isset($manip[$tag])) { + // ensure that the tag is set up + $manip = $this->_insertBefore($manip, $curorder, array(), $tag); + } + if (count($order) > 1) { + $manip[$tag] = $this->_mergeTag($manip[$tag], $contents, array_slice($order, 1)); + return $manip; + } + } + } else { + return $manip; + } + if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) { + $manip[$tag][] = $contents; + } else { + if (!count($manip[$tag])) { + $manip[$tag] = $contents; + } else { + $manip[$tag] = array($manip[$tag]); + $manip[$tag][] = $contents; + } + } + return $manip; } -} - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v1.php,v 1.75 2009/02/24 23:39:16 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/** - * For error handling - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ErrorStack.php'; - -/** - * Error code if parsing is attempted with no xml extension - */ -define('PEAR_PACKAGEFILE_ERROR_NO_XML_EXT', 3); - -/** - * Error code if creating the xml parser resource fails - */ -define('PEAR_PACKAGEFILE_ERROR_CANT_MAKE_PARSER', 4); - -/** - * Error code used for all sax xml parsing errors - */ -define('PEAR_PACKAGEFILE_ERROR_PARSER_ERROR', 5); - -/** - * Error code used when there is no name - */ -define('PEAR_PACKAGEFILE_ERROR_NO_NAME', 6); - -/** - * Error code when a package name is not valid - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_NAME', 7); - -/** - * Error code used when no summary is parsed - */ -define('PEAR_PACKAGEFILE_ERROR_NO_SUMMARY', 8); - -/** - * Error code for summaries that are more than 1 line - */ -define('PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY', 9); - -/** - * Error code used when no description is present - */ -define('PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION', 10); - -/** - * Error code used when no license is present - */ -define('PEAR_PACKAGEFILE_ERROR_NO_LICENSE', 11); - -/** - * Error code used when a version number is not present - */ -define('PEAR_PACKAGEFILE_ERROR_NO_VERSION', 12); - -/** - * Error code used when a version number is invalid - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_VERSION', 13); - -/** - * Error code when release state is missing - */ -define('PEAR_PACKAGEFILE_ERROR_NO_STATE', 14); - -/** - * Error code when release state is invalid - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_STATE', 15); - -/** - * Error code when release state is missing - */ -define('PEAR_PACKAGEFILE_ERROR_NO_DATE', 16); - -/** - * Error code when release state is invalid - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_DATE', 17); - -/** - * Error code when no release notes are found - */ -define('PEAR_PACKAGEFILE_ERROR_NO_NOTES', 18); - -/** - * Error code when no maintainers are found - */ -define('PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS', 19); - -/** - * Error code when a maintainer has no handle - */ -define('PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE', 20); - -/** - * Error code when a maintainer has no handle - */ -define('PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE', 21); - -/** - * Error code when a maintainer has no name - */ -define('PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME', 22); - -/** - * Error code when a maintainer has no email - */ -define('PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL', 23); - -/** - * Error code when a maintainer has no handle - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_MAINTROLE', 24); - -/** - * Error code when a dependency is not a PHP dependency, but has no name - */ -define('PEAR_PACKAGEFILE_ERROR_NO_DEPNAME', 25); - -/** - * Error code when a dependency has no type (pkg, php, etc.) - */ -define('PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE', 26); - -/** - * Error code when a dependency has no relation (lt, ge, has, etc.) - */ -define('PEAR_PACKAGEFILE_ERROR_NO_DEPREL', 27); - -/** - * Error code when a dependency is not a 'has' relation, but has no version - */ -define('PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION', 28); - -/** - * Error code when a dependency has an invalid relation - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPREL', 29); - -/** - * Error code when a dependency has an invalid type - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPTYPE', 30); - -/** - * Error code when a dependency has an invalid optional option - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL', 31); - -/** - * Error code when a dependency is a pkg dependency, and has an invalid package name - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_DEPNAME', 32); - -/** - * Error code when a dependency has a channel="foo" attribute, and foo is not a registered channel - */ -define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_DEPCHANNEL', 33); - -/** - * Error code when rel="has" and version attribute is present. - */ -define('PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED', 34); - -/** - * Error code when type="php" and dependency name is present - */ -define('PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED', 35); - -/** - * Error code when a configure option has no name - */ -define('PEAR_PACKAGEFILE_ERROR_NO_CONFNAME', 36); - -/** - * Error code when a configure option has no name - */ -define('PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT', 37); - -/** - * Error code when a file in the filelist has an invalid role - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE', 38); - -/** - * Error code when a file in the filelist has no role - */ -define('PEAR_PACKAGEFILE_ERROR_NO_FILEROLE', 39); - -/** - * Error code when analyzing a php source file that has parse errors - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE', 40); - -/** - * Error code when analyzing a php source file reveals a source element - * without a package name prefix - */ -define('PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX', 41); - -/** - * Error code when an unknown channel is specified - */ -define('PEAR_PACKAGEFILE_ERROR_UNKNOWN_CHANNEL', 42); - -/** - * Error code when no files are found in the filelist - */ -define('PEAR_PACKAGEFILE_ERROR_NO_FILES', 43); - -/** - * Error code when a file is not valid php according to _analyzeSourceCode() - */ -define('PEAR_PACKAGEFILE_ERROR_INVALID_FILE', 44); - -/** - * Error code when the channel validator returns an error or warning - */ -define('PEAR_PACKAGEFILE_ERROR_CHANNELVAL', 45); - -/** - * Error code when a php5 package is packaged in php4 (analysis doesn't work) - */ -define('PEAR_PACKAGEFILE_ERROR_PHP5', 46); - -/** - * Error code when a file is listed in package.xml but does not exist - */ -define('PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND', 47); - -/** - * Error code when a - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_PackageFile_v1 -{ - /** - * @access private - * @var PEAR_ErrorStack - * @access private - */ - var $_stack; - - /** - * A registry object, used to access the package name validation regex for non-standard channels - * @var PEAR_Registry - * @access private - */ - var $_registry; - - /** - * An object that contains a log method that matches PEAR_Common::log's signature - * @var object - * @access private - */ - var $_logger; - - /** - * Parsed package information - * @var array - * @access private - */ - var $_packageInfo; - - /** - * path to package.xml - * @var string - * @access private - */ - var $_packageFile; - - /** - * path to package .tgz or false if this is a local/extracted package.xml - * @var string - * @access private - */ - var $_archiveFile; - - /** - * @var int - * @access private - */ - var $_isValid = 0; - - /** - * Determines whether this packagefile was initialized only with partial package info - * - * If this package file was constructed via parsing REST, it will only contain - * - * - package name - * - channel name - * - dependencies - * @var boolean - * @access private - */ - var $_incomplete = true; - - /** - * @param bool determines whether to return a PEAR_Error object, or use the PEAR_ErrorStack - * @param string Name of Error Stack class to use. - */ - function PEAR_PackageFile_v1() - { - $this->_stack = &new PEAR_ErrorStack('PEAR_PackageFile_v1'); - $this->_stack->setErrorMessageTemplate($this->_getErrorMessage()); - $this->_isValid = 0; - } - - function installBinary($installer) - { - return false; - } - - function isExtension($name) - { - return false; - } - - function setConfig(&$config) - { - $this->_config = &$config; - $this->_registry = &$config->getRegistry(); - } - - function setRequestedGroup() - { - // placeholder - } - - /** - * For saving in the registry. - * - * Set the last version that was installed - * @param string - */ - function setLastInstalledVersion($version) - { - $this->_packageInfo['_lastversion'] = $version; - } - - /** - * @return string|false - */ - function getLastInstalledVersion() - { - if (isset($this->_packageInfo['_lastversion'])) { - return $this->_packageInfo['_lastversion']; - } - return false; - } - - function getInstalledBinary() - { - return false; - } - - function listPostinstallScripts() - { - return false; - } - - function initPostinstallScripts() - { - return false; - } - - function setLogger(&$logger) - { - if ($logger && (!is_object($logger) || !method_exists($logger, 'log'))) { - return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); - } - $this->_logger = &$logger; - } - - function setPackagefile($file, $archive = false) - { - $this->_packageFile = $file; - $this->_archiveFile = $archive ? $archive : $file; - } - - function getPackageFile() - { - return isset($this->_packageFile) ? $this->_packageFile : false; - } - - function getPackageType() - { - return 'php'; - } - - function getArchiveFile() - { - return $this->_archiveFile; - } - - function packageInfo($field) - { - if (!is_string($field) || empty($field) || - !isset($this->_packageInfo[$field])) { - return false; - } - return $this->_packageInfo[$field]; - } - - function setDirtree($path) - { - if (!isset($this->_packageInfo['dirtree'])) { - $this->_packageInfo['dirtree'] = array(); - } - $this->_packageInfo['dirtree'][$path] = true; - } - - function getDirtree() - { - if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { - return $this->_packageInfo['dirtree']; - } - return false; - } - - function resetDirtree() - { - unset($this->_packageInfo['dirtree']); - } - - function fromArray($pinfo) - { - $this->_incomplete = false; - $this->_packageInfo = $pinfo; - } - - function isIncomplete() - { - return $this->_incomplete; - } - - function getChannel() - { - return 'pear.php.net'; - } - - function getUri() - { - return false; - } - - function getTime() - { - return false; - } - - function getExtends() - { - if (isset($this->_packageInfo['extends'])) { - return $this->_packageInfo['extends']; - } - return false; - } - - /** - * @return array - */ - function toArray() - { - if (!$this->validate(PEAR_VALIDATE_NORMAL)) { - return false; - } - return $this->getArray(); - } - - function getArray() - { - return $this->_packageInfo; - } - - function getName() - { - return $this->getPackage(); - } - - function getPackage() - { - if (isset($this->_packageInfo['package'])) { - return $this->_packageInfo['package']; - } - return false; - } - - /** - * WARNING - don't use this unless you know what you are doing - */ - function setRawPackage($package) - { - $this->_packageInfo['package'] = $package; - } - - function setPackage($package) - { - $this->_packageInfo['package'] = $package; - $this->_isValid = false; - } - - function getVersion() - { - if (isset($this->_packageInfo['version'])) { - return $this->_packageInfo['version']; - } - return false; - } - - function setVersion($version) - { - $this->_packageInfo['version'] = $version; - $this->_isValid = false; - } - - function clearMaintainers() - { - unset($this->_packageInfo['maintainers']); - } - - function getMaintainers() - { - if (isset($this->_packageInfo['maintainers'])) { - return $this->_packageInfo['maintainers']; - } - return false; - } - - /** - * Adds a new maintainer - no checking of duplicates is performed, use - * updatemaintainer for that purpose. - */ - function addMaintainer($role, $handle, $name, $email) - { - $this->_packageInfo['maintainers'][] = - array('handle' => $handle, 'role' => $role, 'email' => $email, 'name' => $name); - $this->_isValid = false; - } - - function updateMaintainer($role, $handle, $name, $email) - { - $found = false; - if (!isset($this->_packageInfo['maintainers']) || - !is_array($this->_packageInfo['maintainers'])) { - return $this->addMaintainer($role, $handle, $name, $email); - } - foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { - if ($maintainer['handle'] == $handle) { - $found = $i; - break; - } - } - if ($found !== false) { - unset($this->_packageInfo['maintainers'][$found]); - $this->_packageInfo['maintainers'] = - array_values($this->_packageInfo['maintainers']); - } - $this->addMaintainer($role, $handle, $name, $email); - } - - function deleteMaintainer($handle) - { - $found = false; - foreach ($this->_packageInfo['maintainers'] as $i => $maintainer) { - if ($maintainer['handle'] == $handle) { - $found = $i; - break; - } - } - if ($found !== false) { - unset($this->_packageInfo['maintainers'][$found]); - $this->_packageInfo['maintainers'] = - array_values($this->_packageInfo['maintainers']); - return true; - } - return false; - } - - function getState() - { - if (isset($this->_packageInfo['release_state'])) { - return $this->_packageInfo['release_state']; - } - return false; - } - - function setRawState($state) - { - $this->_packageInfo['release_state'] = $state; - } - - function setState($state) - { - $this->_packageInfo['release_state'] = $state; - $this->_isValid = false; - } - - function getDate() - { - if (isset($this->_packageInfo['release_date'])) { - return $this->_packageInfo['release_date']; - } - return false; - } - - function setDate($date) - { - $this->_packageInfo['release_date'] = $date; - $this->_isValid = false; - } - - function getLicense() - { - if (isset($this->_packageInfo['release_license'])) { - return $this->_packageInfo['release_license']; - } - return false; - } - - function setLicense($date) - { - $this->_packageInfo['release_license'] = $date; - $this->_isValid = false; - } - - function getSummary() - { - if (isset($this->_packageInfo['summary'])) { - return $this->_packageInfo['summary']; - } - return false; - } - - function setSummary($summary) - { - $this->_packageInfo['summary'] = $summary; - $this->_isValid = false; - } - - function getDescription() - { - if (isset($this->_packageInfo['description'])) { - return $this->_packageInfo['description']; - } - return false; - } - - function setDescription($desc) - { - $this->_packageInfo['description'] = $desc; - $this->_isValid = false; - } - - function getNotes() - { - if (isset($this->_packageInfo['release_notes'])) { - return $this->_packageInfo['release_notes']; - } - return false; - } - - function setNotes($notes) - { - $this->_packageInfo['release_notes'] = $notes; - $this->_isValid = false; - } - - function getDeps() - { - if (isset($this->_packageInfo['release_deps'])) { - return $this->_packageInfo['release_deps']; - } - return false; - } - - /** - * Reset dependencies prior to adding new ones - */ - function clearDeps() - { - unset($this->_packageInfo['release_deps']); - } - - function addPhpDep($version, $rel) - { - $this->_isValid = false; - $this->_packageInfo['release_deps'][] = - array('type' => 'php', - 'rel' => $rel, - 'version' => $version); - } - - function addPackageDep($name, $version, $rel, $optional = 'no') - { - $this->_isValid = false; - $dep = - array('type' => 'pkg', - 'name' => $name, - 'rel' => $rel, - 'optional' => $optional); - if ($rel != 'has' && $rel != 'not') { - $dep['version'] = $version; - } - $this->_packageInfo['release_deps'][] = $dep; - } - - function addExtensionDep($name, $version, $rel, $optional = 'no') - { - $this->_isValid = false; - $this->_packageInfo['release_deps'][] = - array('type' => 'ext', - 'name' => $name, - 'rel' => $rel, - 'version' => $version, - 'optional' => $optional); - } - - /** - * WARNING - do not use this function directly unless you know what you're doing - */ - function setDeps($deps) - { - $this->_packageInfo['release_deps'] = $deps; - } - - function hasDeps() - { - return isset($this->_packageInfo['release_deps']) && - count($this->_packageInfo['release_deps']); - } - - function getDependencyGroup($group) - { - return false; - } - - function isCompatible($pf) - { - return false; - } - - function isSubpackageOf($p) - { - return $p->isSubpackage($this); - } - - function isSubpackage($p) - { - return false; - } - - function dependsOn($package, $channel) - { - if (strtolower($channel) != 'pear.php.net') { - return false; - } - if (!($deps = $this->getDeps())) { - return false; - } - foreach ($deps as $dep) { - if ($dep['type'] != 'pkg') { - continue; - } - if (strtolower($dep['name']) == strtolower($package)) { - return true; - } - } - return false; - } - - function getConfigureOptions() - { - if (isset($this->_packageInfo['configure_options'])) { - return $this->_packageInfo['configure_options']; - } - return false; - } - - function hasConfigureOptions() - { - return isset($this->_packageInfo['configure_options']) && - count($this->_packageInfo['configure_options']); - } - - function addConfigureOption($name, $prompt, $default = false) - { - $o = array('name' => $name, 'prompt' => $prompt); - if ($default !== false) { - $o['default'] = $default; - } - if (!isset($this->_packageInfo['configure_options'])) { - $this->_packageInfo['configure_options'] = array(); - } - $this->_packageInfo['configure_options'][] = $o; - } - - function clearConfigureOptions() - { - unset($this->_packageInfo['configure_options']); - } - - function getProvides() - { - if (isset($this->_packageInfo['provides'])) { - return $this->_packageInfo['provides']; - } - return false; - } - - function getProvidesExtension() - { - return false; - } - - function addFile($dir, $file, $attrs) - { - $dir = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), $dir); - if ($dir == '/' || $dir == '') { - $dir = ''; - } else { - $dir .= '/'; - } - $file = $dir . $file; - $file = preg_replace('![\\/]+!', '/', $file); - $this->_packageInfo['filelist'][$file] = $attrs; - } - - function getInstallationFilelist() - { - return $this->getFilelist(); - } - - function getFilelist() - { - if (isset($this->_packageInfo['filelist'])) { - return $this->_packageInfo['filelist']; - } - return false; - } - - function setFileAttribute($file, $attr, $value) - { - $this->_packageInfo['filelist'][$file][$attr] = $value; - } - - function resetFilelist() - { - $this->_packageInfo['filelist'] = array(); - } - - function setInstalledAs($file, $path) - { - if ($path) { - return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; - } - unset($this->_packageInfo['filelist'][$file]['installed_as']); - } - - function installedFile($file, $atts) - { - if (isset($this->_packageInfo['filelist'][$file])) { - $this->_packageInfo['filelist'][$file] = - array_merge($this->_packageInfo['filelist'][$file], $atts); - } else { - $this->_packageInfo['filelist'][$file] = $atts; - } - } - - function getChangelog() - { - if (isset($this->_packageInfo['changelog'])) { - return $this->_packageInfo['changelog']; - } - return false; - } - - function getPackagexmlVersion() - { - return '1.0'; - } - - /** - * Wrapper to {@link PEAR_ErrorStack::getErrors()} - * @param boolean determines whether to purge the error stack after retrieving - * @return array - */ - function getValidationWarnings($purge = true) - { - return $this->_stack->getErrors($purge); - } - - // }}} - /** - * Validation error. Also marks the object contents as invalid - * @param error code - * @param array error information - * @access private - */ - function _validateError($code, $params = array()) - { - $this->_stack->push($code, 'error', $params, false, false, debug_backtrace()); - $this->_isValid = false; - } - - /** - * Validation warning. Does not mark the object contents invalid. - * @param error code - * @param array error information - * @access private - */ - function _validateWarning($code, $params = array()) - { - $this->_stack->push($code, 'warning', $params, false, false, debug_backtrace()); - } - - /** - * @param integer error code - * @access protected - */ - function _getErrorMessage() - { - return array( - PEAR_PACKAGEFILE_ERROR_NO_NAME => - 'Missing Package Name', - PEAR_PACKAGEFILE_ERROR_NO_SUMMARY => - 'No summary found', - PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY => - 'Summary should be on one line', - PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION => - 'Missing description', - PEAR_PACKAGEFILE_ERROR_NO_LICENSE => - 'Missing license', - PEAR_PACKAGEFILE_ERROR_NO_VERSION => - 'No release version found', - PEAR_PACKAGEFILE_ERROR_NO_STATE => - 'No release state found', - PEAR_PACKAGEFILE_ERROR_NO_DATE => - 'No release date found', - PEAR_PACKAGEFILE_ERROR_NO_NOTES => - 'No release notes found', - PEAR_PACKAGEFILE_ERROR_NO_LEAD => - 'Package must have at least one lead maintainer', - PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS => - 'No maintainers found, at least one must be defined', - PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE => - 'Maintainer %index% has no handle (user ID at channel server)', - PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE => - 'Maintainer %index% has no role', - PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME => - 'Maintainer %index% has no name', - PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL => - 'Maintainer %index% has no email', - PEAR_PACKAGEFILE_ERROR_NO_DEPNAME => - 'Dependency %index% is not a php dependency, and has no name', - PEAR_PACKAGEFILE_ERROR_NO_DEPREL => - 'Dependency %index% has no relation (rel)', - PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE => - 'Dependency %index% has no type', - PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED => - 'PHP Dependency %index% has a name attribute of "%name%" which will be' . - ' ignored!', - PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION => - 'Dependency %index% is not a rel="has" or rel="not" dependency, ' . - 'and has no version', - PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION => - 'Dependency %index% is a type="php" dependency, ' . - 'and has no version', - PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED => - 'Dependency %index% is a rel="%rel%" dependency, versioning is ignored', - PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL => - 'Dependency %index% has invalid optional value "%opt%", should be yes or no', - PEAR_PACKAGEFILE_PHP_NO_NOT => - 'Dependency %index%: php dependencies cannot use "not" rel, use "ne"' . - ' to exclude specific versions', - PEAR_PACKAGEFILE_ERROR_NO_CONFNAME => - 'Configure Option %index% has no name', - PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT => - 'Configure Option %index% has no prompt', - PEAR_PACKAGEFILE_ERROR_NO_FILES => - 'No files in section of package.xml', - PEAR_PACKAGEFILE_ERROR_NO_FILEROLE => - 'File "%file%" has no role, expecting one of "%roles%"', - PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE => - 'File "%file%" has invalid role "%role%", expecting one of "%roles%"', - PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME => - 'File "%file%" cannot start with ".", cannot package or install', - PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE => - 'Parser error: invalid PHP found in file "%file%"', - PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX => - 'in %file%: %type% "%name%" not prefixed with package name "%package%"', - PEAR_PACKAGEFILE_ERROR_INVALID_FILE => - 'Parser error: invalid PHP file "%file%"', - PEAR_PACKAGEFILE_ERROR_CHANNELVAL => - 'Channel validator error: field "%field%" - %reason%', - PEAR_PACKAGEFILE_ERROR_PHP5 => - 'Error, PHP5 token encountered in %file%, analysis should be in PHP5', - PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND => - 'File "%file%" in package.xml does not exist', - PEAR_PACKAGEFILE_ERROR_NON_ISO_CHARS => - 'Package.xml contains non-ISO-8859-1 characters, and may not validate', - ); - } - - /** - * Validate XML package definition file. - * - * @access public - * @return boolean - */ - function validate($state = PEAR_VALIDATE_NORMAL, $nofilechecking = false) - { - if (($this->_isValid & $state) == $state) { - return true; - } - $this->_isValid = true; - $info = $this->_packageInfo; - if (empty($info['package'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NAME); - $this->_packageName = $pn = 'unknown'; - } else { - $this->_packageName = $pn = $info['package']; - } - - if (empty($info['summary'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_SUMMARY); - } elseif (strpos(trim($info['summary']), "\n") !== false) { - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_MULTILINE_SUMMARY, - array('summary' => $info['summary'])); - } - if (empty($info['description'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DESCRIPTION); - } - if (empty($info['release_license'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LICENSE); - } - if (empty($info['version'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_VERSION); - } - if (empty($info['release_state'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_STATE); - } - if (empty($info['release_date'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DATE); - } - if (empty($info['release_notes'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_NOTES); - } - if (empty($info['maintainers'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTAINERS); - } else { - $haslead = false; - $i = 1; - foreach ($info['maintainers'] as $m) { - if (empty($m['handle'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTHANDLE, - array('index' => $i)); - } - if (empty($m['role'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTROLE, - array('index' => $i, 'roles' => PEAR_Common::getUserRoles())); - } elseif ($m['role'] == 'lead') { - $haslead = true; - } - if (empty($m['name'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTNAME, - array('index' => $i)); - } - if (empty($m['email'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_MAINTEMAIL, - array('index' => $i)); - } - $i++; - } - if (!$haslead) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_LEAD); - } - } - if (!empty($info['release_deps'])) { - $i = 1; - foreach ($info['release_deps'] as $d) { - if (!isset($d['type']) || empty($d['type'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPTYPE, - array('index' => $i, 'types' => PEAR_Common::getDependencyTypes())); - continue; - } - if (!isset($d['rel']) || empty($d['rel'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPREL, - array('index' => $i, 'rels' => PEAR_Common::getDependencyRelations())); - continue; - } - if (!empty($d['optional'])) { - if (!in_array($d['optional'], array('yes', 'no'))) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_DEPOPTIONAL, - array('index' => $i, 'opt' => $d['optional'])); - } - } - if ($d['rel'] != 'has' && $d['rel'] != 'not' && empty($d['version'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPVERSION, - array('index' => $i)); - } elseif (($d['rel'] == 'has' || $d['rel'] == 'not') && !empty($d['version'])) { - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPVERSION_IGNORED, - array('index' => $i, 'rel' => $d['rel'])); - } - if ($d['type'] == 'php' && !empty($d['name'])) { - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_DEPNAME_IGNORED, - array('index' => $i, 'name' => $d['name'])); - } elseif ($d['type'] != 'php' && empty($d['name'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPNAME, - array('index' => $i)); - } - if ($d['type'] == 'php' && empty($d['version'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_DEPPHPVERSION, - array('index' => $i)); - } - if (($d['rel'] == 'not') && ($d['type'] == 'php')) { - $this->_validateError(PEAR_PACKAGEFILE_PHP_NO_NOT, - array('index' => $i)); - } - $i++; - } - } - if (!empty($info['configure_options'])) { - $i = 1; - foreach ($info['configure_options'] as $c) { - if (empty($c['name'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFNAME, - array('index' => $i)); - } - if (empty($c['prompt'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_CONFPROMPT, - array('index' => $i)); - } - $i++; - } - } - if (empty($info['filelist'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILES); - $errors[] = 'no files'; - } else { - foreach ($info['filelist'] as $file => $fa) { - if (empty($fa['role'])) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_NO_FILEROLE, - array('file' => $file, 'roles' => PEAR_Common::getFileRoles())); - continue; - } elseif (!in_array($fa['role'], PEAR_Common::getFileRoles())) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILEROLE, - array('file' => $file, 'role' => $fa['role'], 'roles' => PEAR_Common::getFileRoles())); - } - if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', str_replace('\\', '/', $file))) { - // file contains .. parent directory or . cur directory references - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, - array('file' => $file)); - } - if (isset($fa['install-as']) && - preg_match('~/\.\.?(/|\\z)|^\.\.?/~', - str_replace('\\', '/', $fa['install-as']))) { - // install-as contains .. parent directory or . cur directory references - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, - array('file' => $file . ' [installed as ' . $fa['install-as'] . ']')); - } - if (isset($fa['baseinstalldir']) && - preg_match('~/\.\.?(/|\\z)|^\.\.?/~', - str_replace('\\', '/', $fa['baseinstalldir']))) { - // install-as contains .. parent directory or . cur directory references - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_FILENAME, - array('file' => $file . ' [baseinstalldir ' . $fa['baseinstalldir'] . ']')); - } - } - } - if (isset($this->_registry) && $this->_isValid) { - $chan = $this->_registry->getChannel('pear.php.net'); - if (PEAR::isError($chan)) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $chan->getMessage()); - return $this->_isValid = 0; - } - $validator = $chan->getValidationObject(); - $validator->setPackageFile($this); - $validator->validate($state); - $failures = $validator->getFailures(); - foreach ($failures['errors'] as $error) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $error); - } - foreach ($failures['warnings'] as $warning) { - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_CHANNELVAL, $warning); - } - } - if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$nofilechecking) { - if ($this->_analyzePhpFiles()) { - $this->_isValid = true; - } - } - if ($this->_isValid) { - return $this->_isValid = $state; - } - return $this->_isValid = 0; - } - - function _analyzePhpFiles() - { - if (!$this->_isValid) { - return false; - } - if (!isset($this->_packageFile)) { - return false; - } - $dir_prefix = dirname($this->_packageFile); - $common = new PEAR_Common; - $log = isset($this->_logger) ? array(&$this->_logger, 'log') : - array($common, 'log'); - $info = $this->getFilelist(); - foreach ($info as $file => $fa) { - if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_FILE_NOTFOUND, - array('file' => realpath($dir_prefix) . DIRECTORY_SEPARATOR . $file)); - continue; - } - if ($fa['role'] == 'php' && $dir_prefix) { - call_user_func_array($log, array(1, "Analyzing $file")); - $srcinfo = $this->_analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); - if ($srcinfo) { - $this->_buildProvidesArray($srcinfo); - } - } - } - $this->_packageName = $pn = $this->getPackage(); - $pnl = strlen($pn); - if (isset($this->_packageInfo['provides'])) { - foreach ((array) $this->_packageInfo['provides'] as $key => $what) { - if (isset($what['explicit'])) { - // skip conformance checks if the provides entry is - // specified in the package.xml file - continue; - } - extract($what); - if ($type == 'class') { - if (!strncasecmp($name, $pn, $pnl)) { - continue; - } - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, - array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); - } elseif ($type == 'function') { - if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { - continue; - } - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_NO_PNAME_PREFIX, - array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn)); - } - } - } - return $this->_isValid; - } - - /** - * Get the default xml generator object - * - * @return PEAR_PackageFile_Generator_v1 - */ - function &getDefaultGenerator() - { - if (!class_exists('PEAR_PackageFile_Generator_v1')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/Generator/v1.php'; - } - $a = &new PEAR_PackageFile_Generator_v1($this); - return $a; - } - - /** - * Get the contents of a file listed within the package.xml - * @param string - * @return string - */ - function getFileContents($file) - { - if ($this->_archiveFile == $this->_packageFile) { // unpacked - $dir = dirname($this->_packageFile); - $file = $dir . DIRECTORY_SEPARATOR . $file; - $file = str_replace(array('/', '\\'), - array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); - if (file_exists($file) && is_readable($file)) { - return implode('', file($file)); - } - } else { // tgz - if (!class_exists('Archive_Tar')) { - require_once 'phar://install-pear-nozlib.phar/' . 'Archive/Tar.php'; - } - $tar = &new Archive_Tar($this->_archiveFile); - $tar->pushErrorHandling(PEAR_ERROR_RETURN); - if ($file != 'package.xml' && $file != 'package2.xml') { - $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; - } - $file = $tar->extractInString($file); - $tar->popErrorHandling(); - if (PEAR::isError($file)) { - return PEAR::raiseError("Cannot locate file '$file' in archive"); - } - return $file; - } - } - - // {{{ analyzeSourceCode() - /** - * Analyze the source code of the given PHP file - * - * @param string Filename of the PHP file - * @return mixed - * @access private - */ - function _analyzeSourceCode($file) - { - if (!function_exists("token_get_all")) { - return false; - } - if (!defined('T_DOC_COMMENT')) { - define('T_DOC_COMMENT', T_COMMENT); - } - if (!defined('T_INTERFACE')) { - define('T_INTERFACE', -1); - } - if (!defined('T_IMPLEMENTS')) { - define('T_IMPLEMENTS', -1); - } - if (!$fp = @fopen($file, "r")) { - return false; - } - fclose($fp); - $contents = file_get_contents($file); - $tokens = token_get_all($contents); -/* - for ($i = 0; $i < sizeof($tokens); $i++) { - @list($token, $data) = $tokens[$i]; - if (is_string($token)) { - var_dump($token); - } else { - print token_name($token) . ' '; - var_dump(rtrim($data)); - } - } -*/ - $look_for = 0; - $paren_level = 0; - $bracket_level = 0; - $brace_level = 0; - $lastphpdoc = ''; - $current_class = ''; - $current_interface = ''; - $current_class_level = -1; - $current_function = ''; - $current_function_level = -1; - $declared_classes = array(); - $declared_interfaces = array(); - $declared_functions = array(); - $declared_methods = array(); - $used_classes = array(); - $used_functions = array(); - $extends = array(); - $implements = array(); - $nodeps = array(); - $inquote = false; - $interface = false; - for ($i = 0; $i < sizeof($tokens); $i++) { - if (is_array($tokens[$i])) { - list($token, $data) = $tokens[$i]; - } else { - $token = $tokens[$i]; - $data = ''; - } - if ($inquote) { - if ($token != '"' && $token != T_END_HEREDOC) { - continue; - } else { - $inquote = false; - continue; - } - } - switch ($token) { - case T_WHITESPACE : - continue; - case ';': - if ($interface) { - $current_function = ''; - $current_function_level = -1; - } - break; - case '"': - case T_START_HEREDOC: - $inquote = true; - break; - case T_CURLY_OPEN: - case T_DOLLAR_OPEN_CURLY_BRACES: - case '{': $brace_level++; continue 2; - case '}': - $brace_level--; - if ($current_class_level == $brace_level) { - $current_class = ''; - $current_class_level = -1; - } - if ($current_function_level == $brace_level) { - $current_function = ''; - $current_function_level = -1; - } - continue 2; - case '[': $bracket_level++; continue 2; - case ']': $bracket_level--; continue 2; - case '(': $paren_level++; continue 2; - case ')': $paren_level--; continue 2; - case T_INTERFACE: - $interface = true; - case T_CLASS: - if (($current_class_level != -1) || ($current_function_level != -1)) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, - array('file' => $file)); - return false; - } - case T_FUNCTION: - case T_NEW: - case T_EXTENDS: - case T_IMPLEMENTS: - $look_for = $token; - continue 2; - case T_STRING: - if (version_compare(zend_version(), '2.0', '<')) { - if (in_array(strtolower($data), - array('public', 'private', 'protected', 'abstract', - 'interface', 'implements', 'throw') - )) { - $this->_validateWarning(PEAR_PACKAGEFILE_ERROR_PHP5, - array($file)); - } - } - if ($look_for == T_CLASS) { - $current_class = $data; - $current_class_level = $brace_level; - $declared_classes[] = $current_class; - } elseif ($look_for == T_INTERFACE) { - $current_interface = $data; - $current_class_level = $brace_level; - $declared_interfaces[] = $current_interface; - } elseif ($look_for == T_IMPLEMENTS) { - $implements[$current_class] = $data; - } elseif ($look_for == T_EXTENDS) { - $extends[$current_class] = $data; - } elseif ($look_for == T_FUNCTION) { - if ($current_class) { - $current_function = "$current_class::$data"; - $declared_methods[$current_class][] = $data; - } elseif ($current_interface) { - $current_function = "$current_interface::$data"; - $declared_methods[$current_interface][] = $data; - } else { - $current_function = $data; - $declared_functions[] = $current_function; - } - $current_function_level = $brace_level; - $m = array(); - } elseif ($look_for == T_NEW) { - $used_classes[$data] = true; - } - $look_for = 0; - continue 2; - case T_VARIABLE: - $look_for = 0; - continue 2; - case T_DOC_COMMENT: - case T_COMMENT: - if (preg_match('!^/\*\*\s!', $data)) { - $lastphpdoc = $data; - if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { - $nodeps = array_merge($nodeps, $m[1]); - } - } - continue 2; - case T_DOUBLE_COLON: - if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { - $this->_validateError(PEAR_PACKAGEFILE_ERROR_INVALID_PHPFILE, - array('file' => $file)); - return false; - } - $class = $tokens[$i - 1][1]; - if (strtolower($class) != 'parent') { - $used_classes[$class] = true; - } - continue 2; - } - } - return array( - "source_file" => $file, - "declared_classes" => $declared_classes, - "declared_interfaces" => $declared_interfaces, - "declared_methods" => $declared_methods, - "declared_functions" => $declared_functions, - "used_classes" => array_diff(array_keys($used_classes), $nodeps), - "inheritance" => $extends, - "implements" => $implements, - ); - } - - /** - * Build a "provides" array from data returned by - * analyzeSourceCode(). The format of the built array is like - * this: - * - * array( - * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), - * ... - * ) - * - * - * @param array $srcinfo array with information about a source file - * as returned by the analyzeSourceCode() method. - * - * @return void - * - * @access private - * - */ - function _buildProvidesArray($srcinfo) - { - if (!$this->_isValid) { - return false; - } - $file = basename($srcinfo['source_file']); - $pn = $this->getPackage(); - $pnl = strlen($pn); - foreach ($srcinfo['declared_classes'] as $class) { - $key = "class;$class"; - if (isset($this->_packageInfo['provides'][$key])) { - continue; - } - $this->_packageInfo['provides'][$key] = - array('file'=> $file, 'type' => 'class', 'name' => $class); - if (isset($srcinfo['inheritance'][$class])) { - $this->_packageInfo['provides'][$key]['extends'] = - $srcinfo['inheritance'][$class]; - } - } - foreach ($srcinfo['declared_methods'] as $class => $methods) { - foreach ($methods as $method) { - $function = "$class::$method"; - $key = "function;$function"; - if ($method{0} == '_' || !strcasecmp($method, $class) || - isset($this->_packageInfo['provides'][$key])) { - continue; - } - $this->_packageInfo['provides'][$key] = - array('file'=> $file, 'type' => 'function', 'name' => $function); - } - } - - foreach ($srcinfo['declared_functions'] as $function) { - $key = "function;$function"; - if ($function{0} == '_' || isset($this->_packageInfo['provides'][$key])) { - continue; - } - if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { - $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; - } - $this->_packageInfo['provides'][$key] = - array('file'=> $file, 'type' => 'function', 'name' => $function); - } - } - - // }}} -} -?> +} +?> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: v2.php,v 1.145 2009/02/24 23:39:16 dufuz Exp $ + * @version CVS: $Id: Validator.php 277885 2009-03-27 19:29:31Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a1 - */ -/** - * For error handling + * @since File available since Release 1.4.0a8 */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ErrorStack.php'; /** + * Private validation class used by PEAR_PackageFile_v2 - do not use directly, its + * sole purpose is to split up the PEAR/PackageFile/v2.php file to make it smaller * @category pear * @package PEAR * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 + * @since Class available since Release 1.4.0a8 + * @access private */ -class PEAR_PackageFile_v2 +class PEAR_PackageFile_v2_Validator { - - /** - * Parsed package information - * @var array - * @access private - */ - var $_packageInfo = array(); - /** - * path to package .tgz or false if this is a local/extracted package.xml - * @var string|false - * @access private + * @var array */ - var $_archiveFile; - + var $_packageInfo; /** - * path to package .xml or false if this is an abstract parsed-from-string xml - * @var string|false - * @access private + * @var PEAR_PackageFile_v2 */ - var $_packageFile; - + var $_pf; /** - * This is used by file analysis routines to log progress information - * @var PEAR_Common - * @access protected + * @var PEAR_ErrorStack */ - var $_logger; - + var $_stack; /** - * This is set to the highest validation level that has been validated - * - * If the package.xml is invalid or unknown, this is set to 0. If - * normal validation has occurred, this is set to PEAR_VALIDATE_NORMAL. If - * downloading/installation validation has occurred it is set to PEAR_VALIDATE_DOWNLOADING - * or INSTALLING, and so on up to PEAR_VALIDATE_PACKAGING. This allows validation - * "caching" to occur, which is particularly important for package validation, so - * that PHP files are not validated twice * @var int - * @access private */ var $_isValid = 0; - - /** - * True if the filelist has been validated - * @param bool - */ - var $_filesValid = false; - - /** - * @var PEAR_Registry - * @access protected - */ - var $_registry; - - /** - * @var PEAR_Config - * @access protected - */ - var $_config; - /** - * Optional Dependency group requested for installation - * @var string - * @access private + * @var int */ - var $_requestedGroup = false; - + var $_filesValid = 0; /** - * @var PEAR_ErrorStack - * @access protected + * @var int */ - var $_stack; - + var $_curState = 0; /** - * Namespace prefix used for tasks in this package.xml - use tasks: whenever possible + * @param PEAR_PackageFile_v2 + * @param int */ - var $_tasksNs; + function validate(&$pf, $state = PEAR_VALIDATE_NORMAL) + { + $this->_pf = &$pf; + $this->_curState = $state; + $this->_packageInfo = $this->_pf->getArray(); + $this->_isValid = $this->_pf->_isValid; + $this->_filesValid = $this->_pf->_filesValid; + $this->_stack = &$pf->_stack; + $this->_stack->getErrors(true); + if (($this->_isValid & $state) == $state) { + return true; + } + if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { + return false; + } + if (!isset($this->_packageInfo['attribs']['version']) || + ($this->_packageInfo['attribs']['version'] != '2.0' && + $this->_packageInfo['attribs']['version'] != '2.1') + ) { + $this->_noPackageVersion(); + } + $structure = + array( + 'name', + 'channel|uri', + '*extends', // can't be multiple, but this works fine + 'summary', + 'description', + '+lead', // these all need content checks + '*developer', + '*contributor', + '*helper', + 'date', + '*time', + 'version', + 'stability', + 'license->?uri->?filesource', + 'notes', + 'contents', //special validation needed + '*compatible', + 'dependencies', //special validation needed + '*usesrole', + '*usestask', // reserve these for 1.4.0a1 to implement + // this will allow a package.xml to gracefully say it + // needs a certain package installed in order to implement a role or task + '*providesextension', + '*srcpackage|*srcuri', + '+phprelease|+extsrcrelease|+extbinrelease|' . + '+zendextsrcrelease|+zendextbinrelease|bundle', //special validation needed + '*changelog', + ); + $test = $this->_packageInfo; + if (isset($test['dependencies']) && + isset($test['dependencies']['required']) && + isset($test['dependencies']['required']['pearinstaller']) && + isset($test['dependencies']['required']['pearinstaller']['min']) && + version_compare('1.9.0', + $test['dependencies']['required']['pearinstaller']['min'], '<') + ) { + $this->_pearVersionTooLow($test['dependencies']['required']['pearinstaller']['min']); + return false; + } + // ignore post-installation array fields + if (array_key_exists('filelist', $test)) { + unset($test['filelist']); + } + if (array_key_exists('_lastmodified', $test)) { + unset($test['_lastmodified']); + } + if (array_key_exists('#binarypackage', $test)) { + unset($test['#binarypackage']); + } + if (array_key_exists('old', $test)) { + unset($test['old']); + } + if (array_key_exists('_lastversion', $test)) { + unset($test['_lastversion']); + } + if (!$this->_stupidSchemaValidate($structure, $test, '')) { + return false; + } + if (empty($this->_packageInfo['name'])) { + $this->_tagCannotBeEmpty('name'); + } + $test = isset($this->_packageInfo['uri']) ? 'uri' :'channel'; + if (empty($this->_packageInfo[$test])) { + $this->_tagCannotBeEmpty($test); + } + if (is_array($this->_packageInfo['license']) && + (!isset($this->_packageInfo['license']['_content']) || + empty($this->_packageInfo['license']['_content']))) { + $this->_tagCannotBeEmpty('license'); + } elseif (empty($this->_packageInfo['license'])) { + $this->_tagCannotBeEmpty('license'); + } + if (empty($this->_packageInfo['summary'])) { + $this->_tagCannotBeEmpty('summary'); + } + if (empty($this->_packageInfo['description'])) { + $this->_tagCannotBeEmpty('description'); + } + if (empty($this->_packageInfo['date'])) { + $this->_tagCannotBeEmpty('date'); + } + if (empty($this->_packageInfo['notes'])) { + $this->_tagCannotBeEmpty('notes'); + } + if (isset($this->_packageInfo['time']) && empty($this->_packageInfo['time'])) { + $this->_tagCannotBeEmpty('time'); + } + if (isset($this->_packageInfo['dependencies'])) { + $this->_validateDependencies(); + } + if (isset($this->_packageInfo['compatible'])) { + $this->_validateCompatible(); + } + if (!isset($this->_packageInfo['bundle'])) { + if (empty($this->_packageInfo['contents'])) { + $this->_tagCannotBeEmpty('contents'); + } + if (!isset($this->_packageInfo['contents']['dir'])) { + $this->_filelistMustContainDir('contents'); + return false; + } + if (isset($this->_packageInfo['contents']['file'])) { + $this->_filelistCannotContainFile('contents'); + return false; + } + } + $this->_validateMaintainers(); + $this->_validateStabilityVersion(); + $fail = false; + if (array_key_exists('usesrole', $this->_packageInfo)) { + $roles = $this->_packageInfo['usesrole']; + if (!is_array($roles) || !isset($roles[0])) { + $roles = array($roles); + } + foreach ($roles as $role) { + if (!isset($role['role'])) { + $this->_usesroletaskMustHaveRoleTask('usesrole', 'role'); + $fail = true; + } else { + if (!isset($role['channel'])) { + if (!isset($role['uri'])) { + $this->_usesroletaskMustHaveChannelOrUri($role['role'], 'usesrole'); + $fail = true; + } + } elseif (!isset($role['package'])) { + $this->_usesroletaskMustHavePackage($role['role'], 'usesrole'); + $fail = true; + } + } + } + } + if (array_key_exists('usestask', $this->_packageInfo)) { + $roles = $this->_packageInfo['usestask']; + if (!is_array($roles) || !isset($roles[0])) { + $roles = array($roles); + } + foreach ($roles as $role) { + if (!isset($role['task'])) { + $this->_usesroletaskMustHaveRoleTask('usestask', 'task'); + $fail = true; + } else { + if (!isset($role['channel'])) { + if (!isset($role['uri'])) { + $this->_usesroletaskMustHaveChannelOrUri($role['task'], 'usestask'); + $fail = true; + } + } elseif (!isset($role['package'])) { + $this->_usesroletaskMustHavePackage($role['task'], 'usestask'); + $fail = true; + } + } + } + } - /** - * Determines whether this packagefile was initialized only with partial package info - * - * If this package file was constructed via parsing REST, it will only contain - * - * - package name - * - channel name - * - dependencies - * @var boolean - * @access private - */ - var $_incomplete = true; + if ($fail) { + return false; + } - /** - * @var PEAR_PackageFile_v2_Validator - */ - var $_v2Validator; + $list = $this->_packageInfo['contents']; + if (isset($list['dir']) && is_array($list['dir']) && isset($list['dir'][0])) { + $this->_multipleToplevelDirNotAllowed(); + return $this->_isValid = 0; + } - /** - * The constructor merely sets up the private error stack - */ - function PEAR_PackageFile_v2() - { - $this->_stack = new PEAR_ErrorStack('PEAR_PackageFile_v2', false, null); - $this->_isValid = false; - } + $this->_validateFilelist(); + $this->_validateRelease(); + if (!$this->_stack->hasErrors()) { + $chan = $this->_pf->_registry->getChannel($this->_pf->getChannel(), true); + if (PEAR::isError($chan)) { + $this->_unknownChannel($this->_pf->getChannel()); + } else { + $valpack = $chan->getValidationPackage(); + // for channel validator packages, always use the default PEAR validator. + // otherwise, they can't be installed or packaged + $validator = $chan->getValidationObject($this->_pf->getPackage()); + if (!$validator) { + $this->_stack->push(__FUNCTION__, 'error', + array_merge( + array('channel' => $chan->getName(), + 'package' => $this->_pf->getPackage()), + $valpack + ), + 'package "%channel%/%package%" cannot be properly validated without ' . + 'validation package "%channel%/%name%-%version%"'); + return $this->_isValid = 0; + } + $validator->setPackageFile($this->_pf); + $validator->validate($state); + $failures = $validator->getFailures(); + foreach ($failures['errors'] as $error) { + $this->_stack->push(__FUNCTION__, 'error', $error, + 'Channel validator error: field "%field%" - %reason%'); + } + foreach ($failures['warnings'] as $warning) { + $this->_stack->push(__FUNCTION__, 'warning', $warning, + 'Channel validator warning: field "%field%" - %reason%'); + } + } + } - /** - * To make unit-testing easier - * @param PEAR_Frontend_* - * @param array options - * @param PEAR_Config - * @return PEAR_Downloader - * @access protected - */ - function &getPEARDownloader(&$i, $o, &$c) - { - $z = &new PEAR_Downloader($i, $o, $c); - return $z; - } + $this->_pf->_isValid = $this->_isValid = !$this->_stack->hasErrors('error'); + if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$this->_filesValid) { + if ($this->_pf->getPackageType() == 'bundle') { + if ($this->_analyzeBundledPackages()) { + $this->_filesValid = $this->_pf->_filesValid = true; + } else { + $this->_pf->_isValid = $this->_isValid = 0; + } + } else { + if (!$this->_analyzePhpFiles()) { + $this->_pf->_isValid = $this->_isValid = 0; + } else { + $this->_filesValid = $this->_pf->_filesValid = true; + } + } + } - /** - * To make unit-testing easier - * @param PEAR_Config - * @param array options - * @param array package name as returned from {@link PEAR_Registry::parsePackageName()} - * @param int PEAR_VALIDATE_* constant - * @return PEAR_Dependency2 - * @access protected - */ - function &getPEARDependency2(&$c, $o, $p, $s = PEAR_VALIDATE_INSTALLING) - { - if (!class_exists('PEAR_Dependency2')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Dependency2.php'; + if ($this->_isValid) { + return $this->_pf->_isValid = $this->_isValid = $state; } - $z = &new PEAR_Dependency2($c, $o, $p, $s); - return $z; - } - function getInstalledBinary() - { - return isset($this->_packageInfo['#binarypackage']) ? $this->_packageInfo['#binarypackage'] : - false; + return $this->_pf->_isValid = $this->_isValid = 0; } - /** - * Installation of source package has failed, attempt to download and install the - * binary version of this package. - * @param PEAR_Installer - * @return array|false - */ - function installBinary(&$installer) + function _stupidSchemaValidate($structure, $xml, $root) { - if (!OS_WINDOWS) { - $a = false; - return $a; + if (!is_array($xml)) { + $xml = array(); } - if ($this->getPackageType() == 'extsrc' || $this->getPackageType() == 'zendextsrc') { - $releasetype = $this->getPackageType() . 'release'; - if (!is_array($installer->getInstallPackages())) { - $a = false; - return $a; + $keys = array_keys($xml); + reset($keys); + $key = current($keys); + while ($key == 'attribs' || $key == '_contents') { + $key = next($keys); + } + $unfoundtags = $optionaltags = array(); + $ret = true; + $mismatch = false; + foreach ($structure as $struc) { + if ($key) { + $tag = $xml[$key]; } - foreach ($installer->getInstallPackages() as $p) { - if ($p->isExtension($this->_packageInfo['providesextension'])) { - if ($p->getPackageType() != 'extsrc' && $p->getPackageType() != 'zendextsrc') { - $a = false; - return $a; // the user probably downloaded it separately + $test = $this->_processStructure($struc); + if (isset($test['choices'])) { + $loose = true; + foreach ($test['choices'] as $choice) { + if ($key == $choice['tag']) { + $key = next($keys); + while ($key == 'attribs' || $key == '_contents') { + $key = next($keys); + } + $unfoundtags = $optionaltags = array(); + $mismatch = false; + if ($key && $key != $choice['tag'] && isset($choice['multiple'])) { + $unfoundtags[] = $choice['tag']; + $optionaltags[] = $choice['tag']; + if ($key) { + $mismatch = true; + } + } + $ret &= $this->_processAttribs($choice, $tag, $root); + continue 2; + } else { + $unfoundtags[] = $choice['tag']; + $mismatch = true; + } + if (!isset($choice['multiple']) || $choice['multiple'] != '*') { + $loose = false; + } else { + $optionaltags[] = $choice['tag']; } } - } - if (isset($this->_packageInfo[$releasetype]['binarypackage'])) { - $installer->log(0, 'Attempting to download binary version of extension "' . - $this->_packageInfo['providesextension'] . '"'); - $params = $this->_packageInfo[$releasetype]['binarypackage']; - if (!is_array($params) || !isset($params[0])) { - $params = array($params); + if (!$loose) { + $this->_invalidTagOrder($unfoundtags, $key, $root); + return false; } - if (isset($this->_packageInfo['channel'])) { - foreach ($params as $i => $param) { - $params[$i] = array('channel' => $this->_packageInfo['channel'], - 'package' => $param, 'version' => $this->getVersion()); + } else { + if ($key != $test['tag']) { + if (isset($test['multiple']) && $test['multiple'] != '*') { + $unfoundtags[] = $test['tag']; + $this->_invalidTagOrder($unfoundtags, $key, $root); + return false; + } else { + if ($key) { + $mismatch = true; + } + $unfoundtags[] = $test['tag']; + $optionaltags[] = $test['tag']; + } + if (!isset($test['multiple'])) { + $this->_invalidTagOrder($unfoundtags, $key, $root); + return false; } + continue; + } else { + $unfoundtags = $optionaltags = array(); + $mismatch = false; } - $dl = &$this->getPEARDownloader($installer->ui, $installer->getOptions(), - $installer->config); - $verbose = $dl->config->get('verbose'); - $dl->config->set('verbose', -1); - foreach ($params as $param) { - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $ret = $dl->download(array($param)); - PEAR::popErrorHandling(); - if (is_array($ret) && count($ret)) { - break; + $key = next($keys); + while ($key == 'attribs' || $key == '_contents') { + $key = next($keys); + } + if ($key && $key != $test['tag'] && isset($test['multiple'])) { + $unfoundtags[] = $test['tag']; + $optionaltags[] = $test['tag']; + $mismatch = true; + } + $ret &= $this->_processAttribs($test, $tag, $root); + continue; + } + } + if (!$mismatch && count($optionaltags)) { + // don't error out on any optional tags + $unfoundtags = array_diff($unfoundtags, $optionaltags); + } + if (count($unfoundtags)) { + $this->_invalidTagOrder($unfoundtags, $key, $root); + } elseif ($key) { + // unknown tags + $this->_invalidTagOrder('*no tags allowed here*', $key, $root); + while ($key = next($keys)) { + $this->_invalidTagOrder('*no tags allowed here*', $key, $root); + } + } + return $ret; + } + + function _processAttribs($choice, $tag, $context) + { + if (isset($choice['attribs'])) { + if (!is_array($tag)) { + $tag = array($tag); + } + $tags = $tag; + if (!isset($tags[0])) { + $tags = array($tags); + } + $ret = true; + foreach ($tags as $i => $tag) { + if (!is_array($tag) || !isset($tag['attribs'])) { + foreach ($choice['attribs'] as $attrib) { + if ($attrib{0} != '?') { + $ret &= $this->_tagHasNoAttribs($choice['tag'], + $context); + continue 2; + } } } - $dl->config->set('verbose', $verbose); - if (is_array($ret)) { - if (count($ret) == 1) { - $pf = $ret[0]->getPackageFile(); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $err = $installer->install($ret[0]); - PEAR::popErrorHandling(); - if (is_array($err)) { - $this->_packageInfo['#binarypackage'] = $ret[0]->getPackage(); - // "install" self, so all dependencies will work transparently - $this->_registry->addPackage2($this); - $installer->log(0, 'Download and install of binary extension "' . - $this->_registry->parsedPackageNameToString( - array('channel' => $pf->getChannel(), - 'package' => $pf->getPackage()), true) . '" successful'); - $a = array($ret[0], $err); - return $a; + foreach ($choice['attribs'] as $attrib) { + if ($attrib{0} != '?') { + if (!isset($tag['attribs'][$attrib])) { + $ret &= $this->_tagMissingAttribute($choice['tag'], + $attrib, $context); } - $installer->log(0, 'Download and install of binary extension "' . - $this->_registry->parsedPackageNameToString( - array('channel' => $pf->getChannel(), - 'package' => $pf->getPackage()), true) . '" failed'); } } } + return $ret; } - $a = false; - return $a; + return true; } - /** - * @return string|false Extension name - */ - function getProvidesExtension() + function _processStructure($key) { - if (in_array($this->getPackageType(), - array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { - if (isset($this->_packageInfo['providesextension'])) { - return $this->_packageInfo['providesextension']; + $ret = array(); + if (count($pieces = explode('|', $key)) > 1) { + $ret['choices'] = array(); + foreach ($pieces as $piece) { + $ret['choices'][] = $this->_processStructure($piece); } + return $ret; } - return false; + $multi = $key{0}; + if ($multi == '+' || $multi == '*') { + $ret['multiple'] = $key{0}; + $key = substr($key, 1); + } + if (count($attrs = explode('->', $key)) > 1) { + $ret['tag'] = array_shift($attrs); + $ret['attribs'] = $attrs; + } else { + $ret['tag'] = $key; + } + return $ret; } - /** - * @param string Extension name - * @return bool - */ - function isExtension($extension) + function _validateStabilityVersion() { - if (in_array($this->getPackageType(), - array('extsrc', 'extbin', 'zendextsrc', 'zendextbin'))) { - return $this->_packageInfo['providesextension'] == $extension; + $structure = array('release', 'api'); + $a = $this->_stupidSchemaValidate($structure, $this->_packageInfo['version'], ''); + $a &= $this->_stupidSchemaValidate($structure, $this->_packageInfo['stability'], ''); + if ($a) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $this->_packageInfo['version']['release'])) { + $this->_invalidVersion('release', $this->_packageInfo['version']['release']); + } + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $this->_packageInfo['version']['api'])) { + $this->_invalidVersion('api', $this->_packageInfo['version']['api']); + } + if (!in_array($this->_packageInfo['stability']['release'], + array('snapshot', 'devel', 'alpha', 'beta', 'stable'))) { + $this->_invalidState('release', $this->_packageInfo['stability']['release']); + } + if (!in_array($this->_packageInfo['stability']['api'], + array('devel', 'alpha', 'beta', 'stable'))) { + $this->_invalidState('api', $this->_packageInfo['stability']['api']); + } } - return false; } - /** - * Tests whether every part of the package.xml 1.0 is represented in - * this package.xml 2.0 - * @param PEAR_PackageFile_v1 - * @return bool - */ - function isEquivalent($pf1) + function _validateMaintainers() { - if (!$pf1) { - return true; + $structure = + array( + 'name', + 'user', + 'email', + 'active', + ); + foreach (array('lead', 'developer', 'contributor', 'helper') as $type) { + if (!isset($this->_packageInfo[$type])) { + continue; + } + if (isset($this->_packageInfo[$type][0])) { + foreach ($this->_packageInfo[$type] as $lead) { + $this->_stupidSchemaValidate($structure, $lead, '<' . $type . '>'); + } + } else { + $this->_stupidSchemaValidate($structure, $this->_packageInfo[$type], + '<' . $type . '>'); + } } - if ($this->getPackageType() == 'bundle') { - return false; + } + + function _validatePhpDep($dep, $installcondition = false) + { + $structure = array( + 'min', + '*max', + '*exclude', + ); + $type = $installcondition ? '' : ''; + $this->_stupidSchemaValidate($structure, $dep, $type); + if (isset($dep['min'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/', + $dep['min'])) { + $this->_invalidVersion($type . '', $dep['min']); + } } - $this->_stack->getErrors(true); - if (!$pf1->validate(PEAR_VALIDATE_NORMAL)) { - return false; + if (isset($dep['max'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/', + $dep['max'])) { + $this->_invalidVersion($type . '', $dep['max']); + } } - $pass = true; - if ($pf1->getPackage() != $this->getPackage()) { - $this->_differentPackage($pf1->getPackage()); - $pass = false; + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + foreach ($dep['exclude'] as $exclude) { + if (!preg_match( + '/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/', + $exclude)) { + $this->_invalidVersion($type . '', $exclude); + } + } } - if ($pf1->getVersion() != $this->getVersion()) { - $this->_differentVersion($pf1->getVersion()); - $pass = false; + } + + function _validatePearinstallerDep($dep) + { + $structure = array( + 'min', + '*max', + '*recommended', + '*exclude', + ); + $this->_stupidSchemaValidate($structure, $dep, ''); + if (isset($dep['min'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['min'])) { + $this->_invalidVersion('', + $dep['min']); + } } - if (trim($pf1->getSummary()) != $this->getSummary()) { - $this->_differentSummary($pf1->getSummary()); - $pass = false; + if (isset($dep['max'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['max'])) { + $this->_invalidVersion('', + $dep['max']); + } } - if (preg_replace('/\s+/', '', $pf1->getDescription()) != - preg_replace('/\s+/', '', $this->getDescription())) { - $this->_differentDescription($pf1->getDescription()); - $pass = false; + if (isset($dep['recommended'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['recommended'])) { + $this->_invalidVersion('', + $dep['recommended']); + } } - if ($pf1->getState() != $this->getState()) { - $this->_differentState($pf1->getState()); - $pass = false; + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + foreach ($dep['exclude'] as $exclude) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $exclude)) { + $this->_invalidVersion('', + $exclude); + } + } } - if (!strstr(preg_replace('/\s+/', '', $this->getNotes()), - preg_replace('/\s+/', '', $pf1->getNotes()))) { - $this->_differentNotes($pf1->getNotes()); - $pass = false; + } + + function _validatePackageDep($dep, $group, $type = '') + { + if (isset($dep['uri'])) { + if (isset($dep['conflicts'])) { + $structure = array( + 'name', + 'uri', + 'conflicts', + '*providesextension', + ); + } else { + $structure = array( + 'name', + 'uri', + '*providesextension', + ); + } + } else { + if (isset($dep['conflicts'])) { + $structure = array( + 'name', + 'channel', + '*min', + '*max', + '*exclude', + 'conflicts', + '*providesextension', + ); + } else { + $structure = array( + 'name', + 'channel', + '*min', + '*max', + '*recommended', + '*exclude', + '*nodefault', + '*providesextension', + ); + } } - $mymaintainers = $this->getMaintainers(); - $yourmaintainers = $pf1->getMaintainers(); - for ($i1 = 0; $i1 < count($yourmaintainers); $i1++) { - $reset = false; - for ($i2 = 0; $i2 < count($mymaintainers); $i2++) { - if ($mymaintainers[$i2]['handle'] == $yourmaintainers[$i1]['handle']) { - if ($mymaintainers[$i2]['role'] != $yourmaintainers[$i1]['role']) { - $this->_differentRole($mymaintainers[$i2]['handle'], - $yourmaintainers[$i1]['role'], $mymaintainers[$i2]['role']); - $pass = false; - } - if ($mymaintainers[$i2]['email'] != $yourmaintainers[$i1]['email']) { - $this->_differentEmail($mymaintainers[$i2]['handle'], - $yourmaintainers[$i1]['email'], $mymaintainers[$i2]['email']); - $pass = false; - } - if ($mymaintainers[$i2]['name'] != $yourmaintainers[$i1]['name']) { - $this->_differentName($mymaintainers[$i2]['handle'], - $yourmaintainers[$i1]['name'], $mymaintainers[$i2]['name']); - $pass = false; - } - unset($mymaintainers[$i2]); - $mymaintainers = array_values($mymaintainers); - unset($yourmaintainers[$i1]); - $yourmaintainers = array_values($yourmaintainers); - $reset = true; - break; - } + if (isset($dep['name'])) { + $type .= '' . $dep['name'] . ''; + } + $this->_stupidSchemaValidate($structure, $dep, '' . $group . $type); + if (isset($dep['uri']) && (isset($dep['min']) || isset($dep['max']) || + isset($dep['recommended']) || isset($dep['exclude']))) { + $this->_uriDepsCannotHaveVersioning('' . $group . $type); + } + if (isset($dep['channel']) && strtolower($dep['channel']) == '__uri') { + $this->_DepchannelCannotBeUri('' . $group . $type); + } + if (isset($dep['min'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['min'])) { + $this->_invalidVersion('' . $group . $type . '', $dep['min']); } - if ($reset) { - $i1 = -1; + } + if (isset($dep['max'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['max'])) { + $this->_invalidVersion('' . $group . $type . '', $dep['max']); } } - $this->_unmatchedMaintainers($mymaintainers, $yourmaintainers); - $filelist = $this->getFilelist(); - foreach ($pf1->getFilelist() as $file => $atts) { - if (!isset($filelist[$file])) { - $this->_missingFile($file); - $pass = false; + if (isset($dep['recommended'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['recommended'])) { + $this->_invalidVersion('' . $group . $type . '', + $dep['recommended']); + } + } + if (isset($dep['exclude'])) { + if (!is_array($dep['exclude'])) { + $dep['exclude'] = array($dep['exclude']); + } + foreach ($dep['exclude'] as $exclude) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $exclude)) { + $this->_invalidVersion('' . $group . $type . '', + $exclude); + } } } - return $pass; - } - - function _differentPackage($package) - { - $this->_stack->push(__FUNCTION__, 'error', array('package' => $package, - 'self' => $this->getPackage()), - 'package.xml 1.0 package "%package%" does not match "%self%"'); - } - - function _differentVersion($version) - { - $this->_stack->push(__FUNCTION__, 'error', array('version' => $version, - 'self' => $this->getVersion()), - 'package.xml 1.0 version "%version%" does not match "%self%"'); - } - - function _differentState($state) - { - $this->_stack->push(__FUNCTION__, 'error', array('state' => $state, - 'self' => $this->getState()), - 'package.xml 1.0 state "%state%" does not match "%self%"'); - } - - function _differentRole($handle, $role, $selfrole) - { - $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, - 'role' => $role, 'self' => $selfrole), - 'package.xml 1.0 maintainer "%handle%" role "%role%" does not match "%self%"'); - } - - function _differentEmail($handle, $email, $selfemail) - { - $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, - 'email' => $email, 'self' => $selfemail), - 'package.xml 1.0 maintainer "%handle%" email "%email%" does not match "%self%"'); - } - - function _differentName($handle, $name, $selfname) - { - $this->_stack->push(__FUNCTION__, 'error', array('handle' => $handle, - 'name' => $name, 'self' => $selfname), - 'package.xml 1.0 maintainer "%handle%" name "%name%" does not match "%self%"'); } - function _unmatchedMaintainers($my, $yours) + function _validateSubpackageDep($dep, $group) { - if ($my) { - array_walk($my, create_function('&$i, $k', '$i = $i["handle"];')); - $this->_stack->push(__FUNCTION__, 'error', array('handles' => $my), - 'package.xml 2.0 has unmatched extra maintainers "%handles%"'); + $this->_validatePackageDep($dep, $group, ''); + if (isset($dep['providesextension'])) { + $this->_subpackageCannotProvideExtension(isset($dep['name']) ? $dep['name'] : ''); } - if ($yours) { - array_walk($yours, create_function('&$i, $k', '$i = $i["handle"];')); - $this->_stack->push(__FUNCTION__, 'error', array('handles' => $yours), - 'package.xml 1.0 has unmatched extra maintainers "%handles%"'); + if (isset($dep['conflicts'])) { + $this->_subpackagesCannotConflict(isset($dep['name']) ? $dep['name'] : ''); } } - function _differentNotes($notes) - { - $truncnotes = strlen($notes) < 25 ? $notes : substr($notes, 0, 24) . '...'; - $truncmynotes = strlen($this->getNotes()) < 25 ? $this->getNotes() : - substr($this->getNotes(), 0, 24) . '...'; - $this->_stack->push(__FUNCTION__, 'error', array('notes' => $truncnotes, - 'self' => $truncmynotes), - 'package.xml 1.0 release notes "%notes%" do not match "%self%"'); - } - - function _differentSummary($summary) - { - $truncsummary = strlen($summary) < 25 ? $summary : substr($summary, 0, 24) . '...'; - $truncmysummary = strlen($this->getsummary()) < 25 ? $this->getSummary() : - substr($this->getsummary(), 0, 24) . '...'; - $this->_stack->push(__FUNCTION__, 'error', array('summary' => $truncsummary, - 'self' => $truncmysummary), - 'package.xml 1.0 summary "%summary%" does not match "%self%"'); - } - - function _differentDescription($description) - { - $truncdescription = trim(strlen($description) < 25 ? $description : substr($description, 0, 24) . '...'); - $truncmydescription = trim(strlen($this->getDescription()) < 25 ? $this->getDescription() : - substr($this->getdescription(), 0, 24) . '...'); - $this->_stack->push(__FUNCTION__, 'error', array('description' => $truncdescription, - 'self' => $truncmydescription), - 'package.xml 1.0 description "%description%" does not match "%self%"'); - } - - function _missingFile($file) - { - $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), - 'package.xml 1.0 file "%file%" is not present in '); - } - - /** - * WARNING - do not use this function unless you know what you're doing - */ - function setRawState($state) + function _validateExtensionDep($dep, $group = false, $installcondition = false) { - if (!isset($this->_packageInfo['stability'])) { - $this->_packageInfo['stability'] = array(); + if (isset($dep['conflicts'])) { + $structure = array( + 'name', + '*min', + '*max', + '*exclude', + 'conflicts', + ); + } else { + $structure = array( + 'name', + '*min', + '*max', + '*recommended', + '*exclude', + ); + } + if ($installcondition) { + $type = ''; + } else { + $type = '' . $group . ''; + } + if (isset($dep['name'])) { + $type .= '' . $dep['name'] . ''; + } + $this->_stupidSchemaValidate($structure, $dep, $type); + if (isset($dep['min'])) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $dep['min'])) { + $this->_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_packageInfo['stability']['release'] = $state; - } - - /** - * WARNING - do not use this function unless you know what you're doing - */ - function setRawCompatible($compatible) - { - $this->_packageInfo['compatible'] = $compatible; } - /** - * WARNING - do not use this function unless you know what you're doing - */ - function setRawPackage($package) + function _validateOsDep($dep, $installcondition = false) { - $this->_packageInfo['name'] = $package; + $structure = array( + 'name', + '*conflicts', + ); + $type = $installcondition ? '' : ''; + if ($this->_stupidSchemaValidate($structure, $dep, $type)) { + if ($dep['name'] == '*') { + if (array_key_exists('conflicts', $dep)) { + $this->_cannotConflictWithAllOs($type); + } + } + } } - /** - * WARNING - do not use this function unless you know what you're doing - */ - function setRawChannel($channel) + function _validateArchDep($dep, $installcondition = false) { - $this->_packageInfo['channel'] = $channel; + $structure = array( + 'pattern', + '*conflicts', + ); + $type = $installcondition ? '' : ''; + $this->_stupidSchemaValidate($structure, $dep, $type); } - function setRequestedGroup($group) + function _validateInstallConditions($cond, $release) { - $this->_requestedGroup = $group; + $structure = array( + '*php', + '*extension', + '*os', + '*arch', + ); + if (!$this->_stupidSchemaValidate($structure, + $cond, $release)) { + return false; + } + foreach (array('php', 'extension', 'os', 'arch') as $type) { + if (isset($cond[$type])) { + $iter = $cond[$type]; + if (!is_array($iter) || !isset($iter[0])) { + $iter = array($iter); + } + foreach ($iter as $package) { + if ($type == 'extension') { + $this->{"_validate{$type}Dep"}($package, false, true); + } else { + $this->{"_validate{$type}Dep"}($package, true); + } + } + } + } } - function getRequestedGroup() + function _validateDependencies() { - if (isset($this->_requestedGroup)) { - return $this->_requestedGroup; + $structure = array( + 'required', + '*optional', + '*group->name->hint' + ); + if (!$this->_stupidSchemaValidate($structure, + $this->_packageInfo['dependencies'], '')) { + return false; + } + foreach (array('required', 'optional') as $simpledep) { + if (isset($this->_packageInfo['dependencies'][$simpledep])) { + if ($simpledep == 'optional') { + $structure = array( + '*package', + '*subpackage', + '*extension', + ); + } else { + $structure = array( + 'php', + 'pearinstaller', + '*package', + '*subpackage', + '*extension', + '*os', + '*arch', + ); + } + if ($this->_stupidSchemaValidate($structure, + $this->_packageInfo['dependencies'][$simpledep], + "<$simpledep>")) { + foreach (array('package', 'subpackage', 'extension') as $type) { + if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) { + $iter = $this->_packageInfo['dependencies'][$simpledep][$type]; + if (!isset($iter[0])) { + $iter = array($iter); + } + foreach ($iter as $package) { + if ($type != 'extension') { + if (isset($package['uri'])) { + if (isset($package['channel'])) { + $this->_UrlOrChannel($type, + $package['name']); + } + } else { + if (!isset($package['channel'])) { + $this->_NoChannel($type, $package['name']); + } + } + } + $this->{"_validate{$type}Dep"}($package, "<$simpledep>"); + } + } + } + if ($simpledep == 'optional') { + continue; + } + foreach (array('php', 'pearinstaller', 'os', 'arch') as $type) { + if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) { + $iter = $this->_packageInfo['dependencies'][$simpledep][$type]; + if (!isset($iter[0])) { + $iter = array($iter); + } + foreach ($iter as $package) { + $this->{"_validate{$type}Dep"}($package); + } + } + } + } + } + } + if (isset($this->_packageInfo['dependencies']['group'])) { + $groups = $this->_packageInfo['dependencies']['group']; + if (!isset($groups[0])) { + $groups = array($groups); + } + $structure = array( + '*package', + '*subpackage', + '*extension', + ); + foreach ($groups as $group) { + if ($this->_stupidSchemaValidate($structure, $group, '')) { + if (!PEAR_Validate::validGroupName($group['attribs']['name'])) { + $this->_invalidDepGroupName($group['attribs']['name']); + } + foreach (array('package', 'subpackage', 'extension') as $type) { + if (isset($group[$type])) { + $iter = $group[$type]; + if (!isset($iter[0])) { + $iter = array($iter); + } + foreach ($iter as $package) { + if ($type != 'extension') { + if (isset($package['uri'])) { + if (isset($package['channel'])) { + $this->_UrlOrChannelGroup($type, + $package['name'], + $group['name']); + } + } else { + if (!isset($package['channel'])) { + $this->_NoChannelGroup($type, + $package['name'], + $group['name']); + } + } + } + $this->{"_validate{$type}Dep"}($package, ''); + } + } + } + } + } } - return false; } - /** - * For saving in the registry. - * - * Set the last version that was installed - * @param string - */ - function setLastInstalledVersion($version) + function _validateCompatible() { - $this->_packageInfo['_lastversion'] = $version; + $compat = $this->_packageInfo['compatible']; + if (!isset($compat[0])) { + $compat = array($compat); + } + $required = array('name', 'channel', 'min', 'max', '*exclude'); + foreach ($compat as $package) { + $type = ''; + if (is_array($package) && array_key_exists('name', $package)) { + $type .= '' . $package['name'] . ''; + } + $this->_stupidSchemaValidate($required, $package, $type); + if (is_array($package) && array_key_exists('min', $package)) { + if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', + $package['min'])) { + $this->_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_packageInfo['_lastversion'])) { - return $this->_packageInfo['_lastversion']; + if (!is_array($list) || !isset($list['bundledpackage'])) { + return $this->_NoBundledPackages(); + } + if (!is_array($list['bundledpackage']) || !isset($list['bundledpackage'][0])) { + return $this->_AtLeast2BundledPackages(); + } + foreach ($list['bundledpackage'] as $package) { + if (!is_string($package)) { + $this->_bundledPackagesMustBeFilename(); + } } - return false; } - /** - * Determines whether this package.xml has post-install scripts or not - * @return array|false - */ - function listPostinstallScripts() + function _validateFilelist($list = false, $allowignore = false, $dirs = '') { - $filelist = $this->getFilelist(); - $contents = $this->getContents(); - $contents = $contents['dir']['file']; - if (!is_array($contents) || !isset($contents[0])) { - $contents = array($contents); + $iscontents = false; + if (!$list) { + $iscontents = true; + $list = $this->_packageInfo['contents']; + if (isset($this->_packageInfo['bundle'])) { + return $this->_validateBundle($list); + } } - $taskfiles = array(); - foreach ($contents as $file) { - $atts = $file['attribs']; - unset($file['attribs']); - if (count($file)) { - $taskfiles[$atts['name']] = $file; + if ($allowignore) { + $struc = array( + '*install->name->as', + '*ignore->name' + ); + } else { + $struc = array( + '*dir->name->?baseinstalldir', + '*file->name->role->?baseinstalldir->?md5sum' + ); + if (isset($list['dir']) && isset($list['file'])) { + // stave off validation errors without requiring a set order. + $_old = $list; + if (isset($list['attribs'])) { + $list = array('attribs' => $_old['attribs']); + } + $list['dir'] = $_old['dir']; + $list['file'] = $_old['file']; } } - $common = new PEAR_Common; - $common->debug = $this->_config->get('verbose'); - $this->_scripts = array(); - $ret = array(); - foreach ($taskfiles as $name => $tasks) { - if (!isset($filelist[$name])) { - // ignored files will not be in the filelist - continue; + if (!isset($list['attribs']) || !isset($list['attribs']['name'])) { + $unknown = $allowignore ? '' : ''; + $dirname = $iscontents ? '' : $unknown; + } else { + $dirname = ''; + if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $list['attribs']['name']))) { + // file contains .. parent directory or . cur directory + $this->_invalidDirName($list['attribs']['name']); } - $atts = $filelist[$name]; - foreach ($tasks as $tag => $raw) { - $task = $this->getTask($tag); - $task = &new $task($this->_config, $common, PEAR_TASK_INSTALL); - if ($task->isScript()) { - $ret[] = $filelist[$name]['installed_as']; + } + $res = $this->_stupidSchemaValidate($struc, $list, $dirname); + if ($allowignore && $res) { + $ignored_or_installed = array(); + $this->_pf->getFilelist(); + $fcontents = $this->_pf->getContents(); + $filelist = array(); + if (!isset($fcontents['dir']['file'][0])) { + $fcontents['dir']['file'] = array($fcontents['dir']['file']); + } + foreach ($fcontents['dir']['file'] as $file) { + $filelist[$file['attribs']['name']] = true; + } + if (isset($list['install'])) { + if (!isset($list['install'][0])) { + $list['install'] = array($list['install']); + } + foreach ($list['install'] as $file) { + if (!isset($filelist[$file['attribs']['name']])) { + $this->_notInContents($file['attribs']['name'], 'install'); + continue; + } + if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) { + $this->_multipleInstallAs($file['attribs']['name']); + } + if (!isset($ignored_or_installed[$file['attribs']['name']])) { + $ignored_or_installed[$file['attribs']['name']] = array(); + } + $ignored_or_installed[$file['attribs']['name']][] = 1; + if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $file['attribs']['as']))) { + // file contains .. parent directory or . cur directory references + $this->_invalidFileInstallAs($file['attribs']['name'], + $file['attribs']['as']); + } + } + } + if (isset($list['ignore'])) { + if (!isset($list['ignore'][0])) { + $list['ignore'] = array($list['ignore']); + } + foreach ($list['ignore'] as $file) { + if (!isset($filelist[$file['attribs']['name']])) { + $this->_notInContents($file['attribs']['name'], 'ignore'); + continue; + } + if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) { + $this->_ignoreAndInstallAs($file['attribs']['name']); + } } } } - if (count($ret)) { - return $ret; + if (!$allowignore && isset($list['file'])) { + if (is_string($list['file'])) { + $this->_oldStyleFileNotAllowed(); + return false; + } + if (!isset($list['file'][0])) { + // single file + $list['file'] = array($list['file']); + } + foreach ($list['file'] as $i => $file) + { + if (isset($file['attribs']) && isset($file['attribs']['name'])) { + if ($file['attribs']['name']{0} == '.' && + $file['attribs']['name']{1} == '/') { + // name is something like "./doc/whatever.txt" + $this->_invalidFileName($file['attribs']['name'], $dirname); + } + if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', + str_replace('\\', '/', $file['attribs']['name']))) { + // file contains .. parent directory or . cur directory + $this->_invalidFileName($file['attribs']['name'], $dirname); + } + } + if (isset($file['attribs']) && isset($file['attribs']['role'])) { + if (!$this->_validateRole($file['attribs']['role'])) { + if (isset($this->_packageInfo['usesrole'])) { + $roles = $this->_packageInfo['usesrole']; + if (!isset($roles[0])) { + $roles = array($roles); + } + foreach ($roles as $role) { + if ($role['role'] = $file['attribs']['role']) { + $msg = 'This package contains role "%role%" and requires ' . + 'package "%package%" to be used'; + if (isset($role['uri'])) { + $params = array('role' => $role['role'], + 'package' => $role['uri']); + } else { + $params = array('role' => $role['role'], + 'package' => $this->_pf->_registry-> + parsedPackageNameToString(array('package' => + $role['package'], 'channel' => $role['channel']), + true)); + } + $this->_stack->push('_mustInstallRole', 'error', $params, $msg); + } + } + } + $this->_invalidFileRole($file['attribs']['name'], + $dirname, $file['attribs']['role']); + } + } + if (!isset($file['attribs'])) { + continue; + } + $save = $file['attribs']; + if ($dirs) { + $save['name'] = $dirs . '/' . $save['name']; + } + unset($file['attribs']); + if (count($file) && $this->_curState != PEAR_VALIDATE_DOWNLOADING) { // has tasks + foreach ($file as $task => $value) { + if ($tagClass = $this->_pf->getTask($task)) { + if (!is_array($value) || !isset($value[0])) { + $value = array($value); + } + foreach ($value as $v) { + $ret = call_user_func(array($tagClass, 'validateXml'), + $this->_pf, $v, $this->_pf->_config, $save); + if (is_array($ret)) { + $this->_invalidTask($task, $ret, isset($save['name']) ? + $save['name'] : ''); + } + } + } else { + if (isset($this->_packageInfo['usestask'])) { + $roles = $this->_packageInfo['usestask']; + if (!isset($roles[0])) { + $roles = array($roles); + } + foreach ($roles as $role) { + if ($role['task'] = $task) { + $msg = 'This package contains task "%task%" and requires ' . + 'package "%package%" to be used'; + if (isset($role['uri'])) { + $params = array('task' => $role['task'], + 'package' => $role['uri']); + } else { + $params = array('task' => $role['task'], + 'package' => $this->_pf->_registry-> + parsedPackageNameToString(array('package' => + $role['package'], 'channel' => $role['channel']), + true)); + } + $this->_stack->push('_mustInstallTask', 'error', + $params, $msg); + } + } + } + $this->_unknownTask($task, $save['name']); + } + } + } + } } - return false; - } - - /** - * Initialize post-install scripts for running - * - * This method can be used to detect post-install scripts, as the return value - * indicates whether any exist - * @return bool - */ - function initPostinstallScripts() - { - $filelist = $this->getFilelist(); - $contents = $this->getContents(); - $contents = $contents['dir']['file']; - if (!is_array($contents) || !isset($contents[0])) { - $contents = array($contents); + if (isset($list['ignore'])) { + if (!$allowignore) { + $this->_ignoreNotAllowed('ignore'); + } } - $taskfiles = array(); - foreach ($contents as $file) { - $atts = $file['attribs']; - unset($file['attribs']); - if (count($file)) { - $taskfiles[$atts['name']] = $file; + if (isset($list['install'])) { + if (!$allowignore) { + $this->_ignoreNotAllowed('install'); } } - $common = new PEAR_Common; - $common->debug = $this->_config->get('verbose'); - $this->_scripts = array(); - foreach ($taskfiles as $name => $tasks) { - if (!isset($filelist[$name])) { - // file was not installed due to installconditions - continue; + if (isset($list['file'])) { + if ($allowignore) { + $this->_fileNotAllowed('file'); } - $atts = $filelist[$name]; - foreach ($tasks as $tag => $raw) { - $taskname = $this->getTask($tag); - $task = &new $taskname($this->_config, $common, PEAR_TASK_INSTALL); - if (!$task->isScript()) { - continue; // scripts are only handled after installation - } - $lastversion = isset($this->_packageInfo['_lastversion']) ? - $this->_packageInfo['_lastversion'] : null; - $task->init($raw, $atts, $lastversion); - $res = $task->startSession($this, $atts['installed_as']); - if (!$res) { - continue; // skip this file + } + if (isset($list['dir'])) { + if ($allowignore) { + $this->_fileNotAllowed('dir'); + } else { + if (!isset($list['dir'][0])) { + $list['dir'] = array($list['dir']); } - if (PEAR::isError($res)) { - return $res; + foreach ($list['dir'] as $dir) { + if (isset($dir['attribs']) && isset($dir['attribs']['name'])) { + if ($dir['attribs']['name'] == '/' || + !isset($this->_packageInfo['contents']['dir']['dir'])) { + // always use nothing if the filelist has already been flattened + $newdirs = ''; + } elseif ($dirs == '') { + $newdirs = $dir['attribs']['name']; + } else { + $newdirs = $dirs . '/' . $dir['attribs']['name']; + } + } else { + $newdirs = $dirs; + } + $this->_validateFilelist($dir, $allowignore, $newdirs); } - $assign = &$task; - $this->_scripts[] = &$assign; } } - if (count($this->_scripts)) { - return true; - } - return false; } - function runPostinstallScripts() + function _validateRelease() { - if ($this->initPostinstallScripts()) { - $ui = &PEAR_Frontend::singleton(); - if ($ui) { - $ui->runPostinstallScripts($this->_scripts, $this); + if (isset($this->_packageInfo['phprelease'])) { + $release = 'phprelease'; + if (isset($this->_packageInfo['providesextension'])) { + $this->_cannotProvideExtension($release); } - } - } - - - /** - * Convert a recursive set of and tags into a single tag with - * tags. - */ - function flattenFilelist() - { - if (isset($this->_packageInfo['bundle'])) { - return; - } - $filelist = array(); - if (isset($this->_packageInfo['contents']['dir']['dir'])) { - $this->_getFlattenedFilelist($filelist, $this->_packageInfo['contents']['dir']); - if (!isset($filelist[1])) { - $filelist = $filelist[0]; + if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { + $this->_cannotHaveSrcpackage($release); } - $this->_packageInfo['contents']['dir']['file'] = $filelist; - unset($this->_packageInfo['contents']['dir']['dir']); - } else { - // else already flattened but check for baseinstalldir propagation - if (isset($this->_packageInfo['contents']['dir']['attribs']['baseinstalldir'])) { - if (isset($this->_packageInfo['contents']['dir']['file'][0])) { - foreach ($this->_packageInfo['contents']['dir']['file'] as $i => $file) { - if (isset($file['attribs']['baseinstalldir'])) { - continue; + $releases = $this->_packageInfo['phprelease']; + if (!is_array($releases)) { + return true; + } + if (!isset($releases[0])) { + $releases = array($releases); + } + foreach ($releases as $rel) { + $this->_stupidSchemaValidate(array( + '*installconditions', + '*filelist', + ), $rel, ''); + } + } + foreach (array('', 'zend') as $prefix) { + $releasetype = $prefix . 'extsrcrelease'; + if (isset($this->_packageInfo[$releasetype])) { + $release = $releasetype; + if (!isset($this->_packageInfo['providesextension'])) { + $this->_mustProvideExtension($release); + } + if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { + $this->_cannotHaveSrcpackage($release); + } + $releases = $this->_packageInfo[$releasetype]; + if (!is_array($releases)) { + return true; + } + if (!isset($releases[0])) { + $releases = array($releases); + } + foreach ($releases as $rel) { + $this->_stupidSchemaValidate(array( + '*installconditions', + '*configureoption->name->prompt->?default', + '*binarypackage', + '*filelist', + ), $rel, '<' . $releasetype . '>'); + if (isset($rel['binarypackage'])) { + if (!is_array($rel['binarypackage']) || !isset($rel['binarypackage'][0])) { + $rel['binarypackage'] = array($rel['binarypackage']); + } + foreach ($rel['binarypackage'] as $bin) { + if (!is_string($bin)) { + $this->_binaryPackageMustBePackagename(); + } } - $this->_packageInfo['contents']['dir']['file'][$i]['attribs']['baseinstalldir'] - = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; - } - } else { - if (!isset($this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'])) { - $this->_packageInfo['contents']['dir']['file']['attribs']['baseinstalldir'] - = $this->_packageInfo['contents']['dir']['attribs']['baseinstalldir']; } } } + $releasetype = 'extbinrelease'; + if (isset($this->_packageInfo[$releasetype])) { + $release = $releasetype; + if (!isset($this->_packageInfo['providesextension'])) { + $this->_mustProvideExtension($release); + } + if (isset($this->_packageInfo['channel']) && + !isset($this->_packageInfo['srcpackage'])) { + $this->_mustSrcPackage($release); + } + if (isset($this->_packageInfo['uri']) && !isset($this->_packageInfo['srcuri'])) { + $this->_mustSrcuri($release); + } + $releases = $this->_packageInfo[$releasetype]; + if (!is_array($releases)) { + return true; + } + if (!isset($releases[0])) { + $releases = array($releases); + } + foreach ($releases as $rel) { + $this->_stupidSchemaValidate(array( + '*installconditions', + '*filelist', + ), $rel, '<' . $releasetype . '>'); + } + } } - } - - /** - * @param array the final flattened file list - * @param array the current directory being processed - * @param string|false any recursively inherited baeinstalldir attribute - * @param string private recursion variable - * @return array - * @access protected - */ - function _getFlattenedFilelist(&$files, $dir, $baseinstall = false, $path = '') - { - if (isset($dir['attribs']) && isset($dir['attribs']['baseinstalldir'])) { - $baseinstall = $dir['attribs']['baseinstalldir']; - } - if (isset($dir['dir'])) { - if (!isset($dir['dir'][0])) { - $dir['dir'] = array($dir['dir']); + if (isset($this->_packageInfo['bundle'])) { + $release = 'bundle'; + if (isset($this->_packageInfo['providesextension'])) { + $this->_cannotProvideExtension($release); } - foreach ($dir['dir'] as $subdir) { - if (!isset($subdir['attribs']) || !isset($subdir['attribs']['name'])) { - $name = '*unknown*'; - } else { - $name = $subdir['attribs']['name']; - } - $newpath = empty($path) ? $name : - $path . '/' . $name; - $this->_getFlattenedFilelist($files, $subdir, - $baseinstall, $newpath); + if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { + $this->_cannotHaveSrcpackage($release); + } + $releases = $this->_packageInfo['bundle']; + if (!is_array($releases) || !isset($releases[0])) { + $releases = array($releases); + } + foreach ($releases as $rel) { + $this->_stupidSchemaValidate(array( + '*installconditions', + '*filelist', + ), $rel, ''); } } - if (isset($dir['file'])) { - if (!isset($dir['file'][0])) { - $dir['file'] = array($dir['file']); + foreach ($releases as $rel) { + if (is_array($rel) && array_key_exists('installconditions', $rel)) { + $this->_validateInstallConditions($rel['installconditions'], + "<$release>"); } - foreach ($dir['file'] as $file) { - $attrs = $file['attribs']; - $name = $attrs['name']; - if ($baseinstall && !isset($attrs['baseinstalldir'])) { - $attrs['baseinstalldir'] = $baseinstall; + if (is_array($rel) && array_key_exists('filelist', $rel)) { + if ($rel['filelist']) { + + $this->_validateFilelist($rel['filelist'], true); } - $attrs['name'] = empty($path) ? $name : $path . '/' . $name; - $attrs['name'] = preg_replace(array('!\\\\+!', '!/+!'), array('/', '/'), - $attrs['name']); - $file['attribs'] = $attrs; - $files[] = $file; } } } - function setConfig(&$config) + /** + * This is here to allow role extension through plugins + * @param string + */ + function _validateRole($role) { - $this->_config = &$config; - $this->_registry = &$config->getRegistry(); + return in_array($role, PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType())); } - function setLogger(&$logger) + function _pearVersionTooLow($version) { - if (!is_object($logger) || !method_exists($logger, 'log')) { - return PEAR::raiseError('Logger must be compatible with PEAR_Common::log'); - } - $this->_logger = &$logger; + $this->_stack->push(__FUNCTION__, 'error', + array('version' => $version), + 'This package.xml requires PEAR version %version% to parse properly, we are ' . + 'version 1.9.0'); } - /** - * WARNING - do not use this function directly unless you know what you're doing - */ - function setDeps($deps) + function _invalidTagOrder($oktags, $actual, $root) { - $this->_packageInfo['dependencies'] = $deps; + $this->_stack->push(__FUNCTION__, 'error', + array('oktags' => $oktags, 'actual' => $actual, 'root' => $root), + 'Invalid tag order in %root%, found <%actual%> expected one of "%oktags%"'); } - /** - * WARNING - do not use this function directly unless you know what you're doing - */ - function setCompatible($compat) + function _ignoreNotAllowed($type) { - $this->_packageInfo['compatible'] = $compat; + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), + '<%type%> is not allowed inside global , only inside ' . + '//, use and only'); } - function setPackagefile($file, $archive = false) + function _fileNotAllowed($type) { - $this->_packageFile = $file; - $this->_archiveFile = $archive ? $archive : $file; + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), + '<%type%> is not allowed inside release , only inside ' . + ', use and only'); } - /** - * Wrapper to {@link PEAR_ErrorStack::getErrors()} - * @param boolean determines whether to purge the error stack after retrieving - * @return array - */ - function getValidationWarnings($purge = true) + function _oldStyleFileNotAllowed() { - return $this->_stack->getErrors($purge); + $this->_stack->push(__FUNCTION__, 'error', array(), + 'Old-style name is not allowed. Use' . + ''); } - function getPackageFile() + function _tagMissingAttribute($tag, $attr, $context) { - return $this->_packageFile; + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, + 'attribute' => $attr, 'context' => $context), + 'tag <%tag%> in context "%context%" has no attribute "%attribute%"'); } - function getArchiveFile() + function _tagHasNoAttribs($tag, $context) { - return $this->_archiveFile; + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, + 'context' => $context), + 'tag <%tag%> has no attributes in context "%context%"'); } - - /** - * Directly set the array that defines this packagefile - * - * WARNING: no validation. This should only be performed by internal methods - * inside PEAR or by inputting an array saved from an existing PEAR_PackageFile_v2 - * @param array - */ - function fromArray($pinfo) + function _invalidInternalStructure() { - unset($pinfo['old']); - unset($pinfo['xsdversion']); - $this->_incomplete = false; - $this->_packageInfo = $pinfo; + $this->_stack->push(__FUNCTION__, 'exception', array(), + 'internal array was not generated by compatible parser, or extreme parser error, cannot continue'); } - function isIncomplete() + function _invalidFileRole($file, $dir, $role) { - return $this->_incomplete; + $this->_stack->push(__FUNCTION__, 'error', array( + 'file' => $file, 'dir' => $dir, 'role' => $role, + 'roles' => PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType())), + 'File "%file%" in directory "%dir%" has invalid role "%role%", should be one of %roles%'); } - /** - * @return array - */ - function toArray($forreg = false) + function _invalidFileName($file, $dir) { - if (!$this->validate(PEAR_VALIDATE_NORMAL)) { - return false; - } - return $this->getArray($forreg); + $this->_stack->push(__FUNCTION__, 'error', array( + 'file' => $file), + 'File "%file%" in directory "%dir%" cannot begin with "./" or contain ".."'); } - function getArray($forReg = false) + function _invalidFileInstallAs($file, $as) { - if ($forReg) { - $arr = $this->_packageInfo; - $arr['old'] = array(); - $arr['old']['version'] = $this->getVersion(); - $arr['old']['release_date'] = $this->getDate(); - $arr['old']['release_state'] = $this->getState(); - $arr['old']['release_license'] = $this->getLicense(); - $arr['old']['release_notes'] = $this->getNotes(); - $arr['old']['release_deps'] = $this->getDeps(); - $arr['old']['maintainers'] = $this->getMaintainers(); - $arr['xsdversion'] = '2.0'; - return $arr; - } else { - $info = $this->_packageInfo; - unset($info['dirtree']); - if (isset($info['_lastversion'])) { - unset($info['_lastversion']); - } - if (isset($info['#binarypackage'])) { - unset($info['#binarypackage']); - } - return $info; - } + $this->_stack->push(__FUNCTION__, 'error', array( + 'file' => $file, 'as' => $as), + 'File "%file%" cannot contain "./" or contain ".."'); } - function packageInfo($field) + function _invalidDirName($dir) { - $arr = $this->getArray(true); - if ($field == 'state') { - return $arr['stability']['release']; - } - if ($field == 'api-version') { - return $arr['version']['api']; - } - if ($field == 'api-state') { - return $arr['stability']['api']; - } - if (isset($arr['old'][$field])) { - if (!is_string($arr['old'][$field])) { - return null; - } - return $arr['old'][$field]; - } - if (isset($arr[$field])) { - if (!is_string($arr[$field])) { - return null; - } - return $arr[$field]; - } - return null; + $this->_stack->push(__FUNCTION__, 'error', array( + 'dir' => $file), + 'Directory "%dir%" cannot begin with "./" or contain ".."'); } - function getName() + function _filelistCannotContainFile($filelist) { - return $this->getPackage(); + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist), + '<%tag%> can only contain , contains . Use ' . + ' as the first dir element'); } - function getPackage() + function _filelistMustContainDir($filelist) { - if (isset($this->_packageInfo['name'])) { - return $this->_packageInfo['name']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist), + '<%tag%> must contain . Use as the ' . + 'first dir element'); } - function getChannel() + function _tagCannotBeEmpty($tag) { - if (isset($this->_packageInfo['uri'])) { - return '__uri'; - } - if (isset($this->_packageInfo['channel'])) { - return strtolower($this->_packageInfo['channel']); - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag), + '<%tag%> cannot be empty (<%tag%/>)'); } - function getUri() + function _UrlOrChannel($type, $name) { - if (isset($this->_packageInfo['uri'])) { - return $this->_packageInfo['uri']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, + 'name' => $name), + 'Required dependency <%type%> "%name%" can have either url OR ' . + 'channel attributes, and not both'); } - function getExtends() + function _NoChannel($type, $name) { - if (isset($this->_packageInfo['extends'])) { - return $this->_packageInfo['extends']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, + 'name' => $name), + 'Required dependency <%type%> "%name%" must have either url OR ' . + 'channel attributes'); } - function getSummary() + function _UrlOrChannelGroup($type, $name, $group) { - if (isset($this->_packageInfo['summary'])) { - return $this->_packageInfo['summary']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, + 'name' => $name, 'group' => $group), + 'Group "%group%" dependency <%type%> "%name%" can have either url OR ' . + 'channel attributes, and not both'); } - function getDescription() + function _NoChannelGroup($type, $name, $group) { - if (isset($this->_packageInfo['description'])) { - return $this->_packageInfo['description']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, + 'name' => $name, 'group' => $group), + 'Group "%group%" dependency <%type%> "%name%" must have either url OR ' . + 'channel attributes'); } - function getMaintainers($raw = false) + function _unknownChannel($channel) { - if (!isset($this->_packageInfo['lead'])) { - return false; - } - if ($raw) { - $ret = array('lead' => $this->_packageInfo['lead']); - (isset($this->_packageInfo['developer'])) ? - $ret['developer'] = $this->_packageInfo['developer'] :null; - (isset($this->_packageInfo['contributor'])) ? - $ret['contributor'] = $this->_packageInfo['contributor'] :null; - (isset($this->_packageInfo['helper'])) ? - $ret['helper'] = $this->_packageInfo['helper'] :null; - return $ret; - } else { - $ret = array(); - $leads = isset($this->_packageInfo['lead'][0]) ? $this->_packageInfo['lead'] : - array($this->_packageInfo['lead']); - foreach ($leads as $lead) { - $s = $lead; - $s['handle'] = $s['user']; - unset($s['user']); - $s['role'] = 'lead'; - $ret[] = $s; - } - if (isset($this->_packageInfo['developer'])) { - $leads = isset($this->_packageInfo['developer'][0]) ? - $this->_packageInfo['developer'] : - array($this->_packageInfo['developer']); - foreach ($leads as $maintainer) { - $s = $maintainer; - $s['handle'] = $s['user']; - unset($s['user']); - $s['role'] = 'developer'; - $ret[] = $s; - } - } - if (isset($this->_packageInfo['contributor'])) { - $leads = isset($this->_packageInfo['contributor'][0]) ? - $this->_packageInfo['contributor'] : - array($this->_packageInfo['contributor']); - foreach ($leads as $maintainer) { - $s = $maintainer; - $s['handle'] = $s['user']; - unset($s['user']); - $s['role'] = 'contributor'; - $ret[] = $s; - } - } - if (isset($this->_packageInfo['helper'])) { - $leads = isset($this->_packageInfo['helper'][0]) ? - $this->_packageInfo['helper'] : - array($this->_packageInfo['helper']); - foreach ($leads as $maintainer) { - $s = $maintainer; - $s['handle'] = $s['user']; - unset($s['user']); - $s['role'] = 'helper'; - $ret[] = $s; - } - } - return $ret; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('channel' => $channel), + 'Unknown channel "%channel%"'); } - function getLeads() + function _noPackageVersion() { - if (isset($this->_packageInfo['lead'])) { - return $this->_packageInfo['lead']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array(), + 'package.xml tag has no version attribute, or version is not 2.0'); } - function getDevelopers() + function _NoBundledPackages() { - if (isset($this->_packageInfo['developer'])) { - return $this->_packageInfo['developer']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array(), + 'No tag was found in , required for bundle packages'); } - function getContributors() + function _AtLeast2BundledPackages() { - if (isset($this->_packageInfo['contributor'])) { - return $this->_packageInfo['contributor']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array(), + 'At least 2 packages must be bundled in a bundle package'); } - function getHelpers() + function _ChannelOrUri($name) { - if (isset($this->_packageInfo['helper'])) { - return $this->_packageInfo['helper']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), + 'Bundled package "%name%" can have either a uri or a channel, not both'); } - function setDate($date) + function _noChildTag($child, $tag) { - if (!isset($this->_packageInfo['date'])) { - // ensure that the extends tag is set up in the right location - $this->_packageInfo = $this->_insertBefore($this->_packageInfo, - array('time', 'version', - 'stability', 'license', 'notes', 'contents', 'compatible', - 'dependencies', 'providesextension', 'srcpackage', 'srcuri', - 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', - 'zendextbinrelease', 'bundle', 'changelog'), array(), 'date'); - } - $this->_packageInfo['date'] = $date; - $this->_isValid = 0; + $this->_stack->push(__FUNCTION__, 'error', array('child' => $child, 'tag' => $tag), + 'Tag <%tag%> is missing child tag <%child%>'); } - function setTime($time) + function _invalidVersion($type, $value) { - $this->_isValid = 0; - if (!isset($this->_packageInfo['time'])) { - // ensure that the time tag is set up in the right location - $this->_packageInfo = $this->_insertBefore($this->_packageInfo, - array('version', - 'stability', 'license', 'notes', 'contents', 'compatible', - 'dependencies', 'providesextension', 'srcpackage', 'srcuri', - 'phprelease', 'extsrcrelease', 'extbinrelease', 'zendextsrcrelease', - 'zendextbinrelease', 'bundle', 'changelog'), $time, 'time'); - } - $this->_packageInfo['time'] = $time; + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value), + 'Version type <%type%> is not a valid version (%value%)'); } - function getDate() + function _invalidState($type, $value) { - if (isset($this->_packageInfo['date'])) { - return $this->_packageInfo['date']; + $states = array('stable', 'beta', 'alpha', 'devel'); + if ($type != 'api') { + $states[] = 'snapshot'; } - return false; + if (strtolower($value) == 'rc') { + $this->_stack->push(__FUNCTION__, 'error', + array('version' => $this->_packageInfo['version']['release']), + 'RC is not a state, it is a version postfix, try %version%RC1, stability beta'); + } + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value, + 'types' => $states), + 'Stability type <%type%> is not a valid stability (%value%), must be one of ' . + '%types%'); } - function getTime() + function _invalidTask($task, $ret, $file) { - if (isset($this->_packageInfo['time'])) { - return $this->_packageInfo['time']; + switch ($ret[0]) { + case PEAR_TASK_ERROR_MISSING_ATTRIB : + $info = array('attrib' => $ret[1], 'task' => $task, 'file' => $file); + $msg = 'task <%task%> is missing attribute "%attrib%" in file %file%'; + break; + case PEAR_TASK_ERROR_NOATTRIBS : + $info = array('task' => $task, 'file' => $file); + $msg = 'task <%task%> has no attributes in file %file%'; + break; + case PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE : + $info = array('attrib' => $ret[1], 'values' => $ret[3], + 'was' => $ret[2], 'task' => $task, 'file' => $file); + $msg = 'task <%task%> attribute "%attrib%" has the wrong value "%was%" '. + 'in file %file%, expecting one of "%values%"'; + break; + case PEAR_TASK_ERROR_INVALID : + $info = array('reason' => $ret[1], 'task' => $task, 'file' => $file); + $msg = 'task <%task%> in file %file% is invalid because of "%reason%"'; + break; } - return false; + $this->_stack->push(__FUNCTION__, 'error', $info, $msg); } - /** - * @param package|api version category to return - */ - function getVersion($key = 'release') + function _unknownTask($task, $file) { - if (isset($this->_packageInfo['version'][$key])) { - return $this->_packageInfo['version'][$key]; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('task' => $task, 'file' => $file), + 'Unknown task "%task%" passed in file '); } - function getStability() + function _subpackageCannotProvideExtension($name) { - if (isset($this->_packageInfo['stability'])) { - return $this->_packageInfo['stability']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), + 'Subpackage dependency "%name%" cannot use , ' . + 'only package dependencies can use this tag'); } - function getState($key = 'release') + function _subpackagesCannotConflict($name) { - if (isset($this->_packageInfo['stability'][$key])) { - return $this->_packageInfo['stability'][$key]; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), + 'Subpackage dependency "%name%" cannot use , ' . + 'only package dependencies can use this tag'); } - function getLicense($raw = false) + function _cannotProvideExtension($release) { - if (isset($this->_packageInfo['license'])) { - if ($raw) { - return $this->_packageInfo['license']; - } - if (is_array($this->_packageInfo['license'])) { - return $this->_packageInfo['license']['_content']; - } else { - return $this->_packageInfo['license']; - } - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), + '<%release%> packages cannot use , only extbinrelease, extsrcrelease, zendextsrcrelease, and zendextbinrelease can provide a PHP extension'); } - function getLicenseLocation() + function _mustProvideExtension($release) { - if (!isset($this->_packageInfo['license']) || !is_array($this->_packageInfo['license'])) { - return false; - } - return $this->_packageInfo['license']['attribs']; + $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), + '<%release%> packages must use to indicate which PHP extension is provided'); } - function getNotes() + function _cannotHaveSrcpackage($release) { - if (isset($this->_packageInfo['notes'])) { - return $this->_packageInfo['notes']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), + '<%release%> packages cannot specify a source code package, only extension binaries may use the tag'); } - /** - * Return the tag contents, if any - * @return array|false - */ - function getUsesrole() + function _mustSrcPackage($release) { - if (isset($this->_packageInfo['usesrole'])) { - return $this->_packageInfo['usesrole']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), + '/ packages must specify a source code package with '); } - /** - * Return the tag contents, if any - * @return array|false - */ - function getUsestask() + function _mustSrcuri($release) { - if (isset($this->_packageInfo['usestask'])) { - return $this->_packageInfo['usestask']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), + '/ packages must specify a source code package with '); } - /** - * This should only be used to retrieve filenames and install attributes - */ - function getFilelist($preserve = false) + function _uriDepsCannotHaveVersioning($type) { - if (isset($this->_packageInfo['filelist']) && !$preserve) { - return $this->_packageInfo['filelist']; - } - $this->flattenFilelist(); - if ($contents = $this->getContents()) { - $ret = array(); - if (!isset($contents['dir'])) { - return false; - } - if (!isset($contents['dir']['file'][0])) { - $contents['dir']['file'] = array($contents['dir']['file']); - } - foreach ($contents['dir']['file'] as $file) { - $name = $file['attribs']['name']; - if (!$preserve) { - $file = $file['attribs']; - } - $ret[$name] = $file; - } - if (!$preserve) { - $this->_packageInfo['filelist'] = $ret; - } - return $ret; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), + '%type%: dependencies with a tag cannot have any versioning information'); } - /** - * Return configure options array, if any - * - * @return array|false - */ - function getConfigureOptions() + function _conflictingDepsCannotHaveVersioning($type) { - if ($this->getPackageType() != 'extsrc' && $this->getPackageType() != 'zendextsrc') { - return false; - } - - $releases = $this->getReleases(); - if (isset($releases[0])) { - $releases = $releases[0]; - } - - if (isset($releases['configureoption'])) { - if (!isset($releases['configureoption'][0])) { - $releases['configureoption'] = array($releases['configureoption']); - } - - for ($i = 0; $i < count($releases['configureoption']); $i++) { - $releases['configureoption'][$i] = $releases['configureoption'][$i]['attribs']; - } - - return $releases['configureoption']; - } - - return false; + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), + '%type%: conflicting dependencies cannot have versioning info, use to ' . + 'exclude specific versions of a dependency'); } - /** - * This is only used at install-time, after all serialization - * is over. - */ - function resetFilelist() + function _DepchannelCannotBeUri($type) { - $this->_packageInfo['filelist'] = array(); + $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), + '%type%: channel cannot be __uri, this is a pseudo-channel reserved for uri ' . + 'dependencies only'); } - /** - * Retrieve a list of files that should be installed on this computer - * @return array - */ - function getInstallationFilelist($forfilecheck = false) + function _bundledPackagesMustBeFilename() { - $contents = $this->getFilelist(true); - if (isset($contents['dir']['attribs']['baseinstalldir'])) { - $base = $contents['dir']['attribs']['baseinstalldir']; - } - if (isset($this->_packageInfo['bundle'])) { - return PEAR::raiseError( - 'Exception: bundles should be handled in download code only'); - } - $release = $this->getReleases(); - if ($release) { - if (!isset($release[0])) { - if (!isset($release['installconditions']) && !isset($release['filelist'])) { - if ($forfilecheck) { - return $this->getFilelist(); - } - return $contents; - } - $release = array($release); - } - $depchecker = &$this->getPEARDependency2($this->_config, array(), - array('channel' => $this->getChannel(), 'package' => $this->getPackage()), - PEAR_VALIDATE_INSTALLING); - foreach ($release as $instance) { - if (isset($instance['installconditions'])) { - $installconditions = $instance['installconditions']; - if (is_array($installconditions)) { - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - foreach ($installconditions as $type => $conditions) { - if (!isset($conditions[0])) { - $conditions = array($conditions); - } - foreach ($conditions as $condition) { - $ret = $depchecker->{"validate{$type}Dependency"}($condition); - if (PEAR::isError($ret)) { - PEAR::popErrorHandling(); - continue 3; // skip this release - } - } - } - PEAR::popErrorHandling(); - } - } - // this is the release to use - if (isset($instance['filelist'])) { - // ignore files - if (isset($instance['filelist']['ignore'])) { - $ignore = isset($instance['filelist']['ignore'][0]) ? - $instance['filelist']['ignore'] : - array($instance['filelist']['ignore']); - foreach ($ignore as $ig) { - unset ($contents[$ig['attribs']['name']]); - } - } - // install files as this name - if (isset($instance['filelist']['install'])) { - $installas = isset($instance['filelist']['install'][0]) ? - $instance['filelist']['install'] : - array($instance['filelist']['install']); - foreach ($installas as $as) { - $contents[$as['attribs']['name']]['attribs']['install-as'] = - $as['attribs']['as']; - } - } - } - if ($forfilecheck) { - foreach ($contents as $file => $attrs) { - $contents[$file] = $attrs['attribs']; - } - } - return $contents; - } - } else { // simple release - no installconditions or install-as - if ($forfilecheck) { - return $this->getFilelist(); - } - return $contents; - } - // no releases matched - return PEAR::raiseError('No releases in package.xml matched the existing operating ' . - 'system, extensions installed, or architecture, cannot install'); + $this->_stack->push(__FUNCTION__, 'error', array(), + ' tags must contain only the filename of a package release ' . + 'in the bundle'); } - /** - * This is only used at install-time, after all serialization - * is over. - * @param string file name - * @param string installed path - */ - function setInstalledAs($file, $path) + function _binaryPackageMustBePackagename() { - if ($path) { - return $this->_packageInfo['filelist'][$file]['installed_as'] = $path; - } - unset($this->_packageInfo['filelist'][$file]['installed_as']); + $this->_stack->push(__FUNCTION__, 'error', array(), + ' tags must contain the name of a package that is ' . + 'a compiled version of this extsrc/zendextsrc package'); } - function getInstalledLocation($file) + function _fileNotFound($file) { - if (isset($this->_packageInfo['filelist'][$file]['installed_as'])) { - return $this->_packageInfo['filelist'][$file]['installed_as']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'File "%file%" in package.xml does not exist'); } - /** - * This is only used at install-time, after all serialization - * is over. - */ - function installedFile($file, $atts) + function _notInContents($file, $tag) { - if (isset($this->_packageInfo['filelist'][$file])) { - $this->_packageInfo['filelist'][$file] = - array_merge($this->_packageInfo['filelist'][$file], $atts['attribs']); - } else { - $this->_packageInfo['filelist'][$file] = $atts['attribs']; - } + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file, 'tag' => $tag), + '<%tag% name="%file%"> is invalid, file is not in '); } - /** - * Retrieve the contents tag - */ - function getContents() + function _cannotValidateNoPathSet() { - if (isset($this->_packageInfo['contents'])) { - return $this->_packageInfo['contents']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array(), + 'Cannot validate files, no path to package file is set (use setPackageFile())'); } - /** - * @param string full path to file - * @param string attribute name - * @param string attribute value - * @param int risky but fast - use this to choose a file based on its position in the list - * of files. Index is zero-based like PHP arrays. - * @return bool success of operation - */ - function setFileAttribute($filename, $attr, $value, $index = false) + function _usesroletaskMustHaveChannelOrUri($role, $tag) { - $this->_isValid = 0; - if (in_array($attr, array('role', 'name', 'baseinstalldir'))) { - $this->_filesValid = false; - } - if ($index !== false && - isset($this->_packageInfo['contents']['dir']['file'][$index]['attribs'])) { - $this->_packageInfo['contents']['dir']['file'][$index]['attribs'][$attr] = $value; - return true; - } - if (!isset($this->_packageInfo['contents']['dir']['file'])) { - return false; - } - $files = $this->_packageInfo['contents']['dir']['file']; - if (!isset($files[0])) { - $files = array($files); - $ind = false; - } else { - $ind = true; - } - foreach ($files as $i => $file) { - if (isset($file['attribs'])) { - if ($file['attribs']['name'] == $filename) { - if ($ind) { - $this->_packageInfo['contents']['dir']['file'][$i]['attribs'][$attr] = $value; - } else { - $this->_packageInfo['contents']['dir']['file']['attribs'][$attr] = $value; - } - return true; - } - } - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag), + '<%tag%> for role "%role%" must contain either , or and '); } - function setDirtree($path) + function _usesroletaskMustHavePackage($role, $tag) { - if (!isset($this->_packageInfo['dirtree'])) { - $this->_packageInfo['dirtree'] = array(); - } - $this->_packageInfo['dirtree'][$path] = true; + $this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag), + '<%tag%> for role "%role%" must contain '); } - function getDirtree() + function _usesroletaskMustHaveRoleTask($tag, $type) { - if (isset($this->_packageInfo['dirtree']) && count($this->_packageInfo['dirtree'])) { - return $this->_packageInfo['dirtree']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, 'type' => $type), + '<%tag%> must contain <%type%> defining the %type% to be used'); } - function resetDirtree() + function _cannotConflictWithAllOs($type) { - unset($this->_packageInfo['dirtree']); + $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag), + '%tag% cannot conflict with all OSes'); } - /** - * Determines whether this package claims it is compatible with the version of - * the package that has a recommended version dependency - * @param PEAR_PackageFile_v2|PEAR_PackageFile_v1|PEAR_Downloader_Package - * @return boolean - */ - function isCompatible($pf) + function _invalidDepGroupName($name) { - if (!isset($this->_packageInfo['compatible'])) { - return false; - } - if (!isset($this->_packageInfo['channel'])) { - return false; - } - $me = $pf->getVersion(); - $compatible = $this->_packageInfo['compatible']; - if (!isset($compatible[0])) { - $compatible = array($compatible); - } - $found = false; - foreach ($compatible as $info) { - if (strtolower($info['name']) == strtolower($pf->getPackage())) { - if (strtolower($info['channel']) == strtolower($pf->getChannel())) { - $found = true; - break; - } - } - } - if (!$found) { - return false; - } - if (isset($info['exclude'])) { - if (!isset($info['exclude'][0])) { - $info['exclude'] = array($info['exclude']); - } - foreach ($info['exclude'] as $exclude) { - if (version_compare($me, $exclude, '==')) { - return false; - } - } - } - if (version_compare($me, $info['min'], '>=') && version_compare($me, $info['max'], '<=')) { - return true; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), + 'Invalid dependency group name "%name%"'); } - /** - * @return array|false - */ - function getCompatible() + function _multipleToplevelDirNotAllowed() { - if (isset($this->_packageInfo['compatible'])) { - return $this->_packageInfo['compatible']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array(), + 'Multiple top-level tags are not allowed. Enclose them ' . + 'in a '); } - function getDependencies() + function _multipleInstallAs($file) { - if (isset($this->_packageInfo['dependencies'])) { - return $this->_packageInfo['dependencies']; - } - return false; + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'Only one tag is allowed for file "%file%"'); } - function isSubpackageOf($p) + function _ignoreAndInstallAs($file) { - return $p->isSubpackage($this); + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'Cannot have both and tags for file "%file%"'); } - /** - * Determines whether the passed in package is a subpackage of this package. - * - * No version checking is done, only name verification. - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @return bool - */ - function isSubpackage($p) + function _analyzeBundledPackages() { - $sub = array(); - if (isset($this->_packageInfo['dependencies']['required']['subpackage'])) { - $sub = $this->_packageInfo['dependencies']['required']['subpackage']; - if (!isset($sub[0])) { - $sub = array($sub); - } + if (!$this->_isValid) { + return false; } - if (isset($this->_packageInfo['dependencies']['optional']['subpackage'])) { - $sub1 = $this->_packageInfo['dependencies']['optional']['subpackage']; - if (!isset($sub1[0])) { - $sub1 = array($sub1); - } - $sub = array_merge($sub, $sub1); + if (!$this->_pf->getPackageType() == 'bundle') { + return false; } - if (isset($this->_packageInfo['dependencies']['group'])) { - $group = $this->_packageInfo['dependencies']['group']; - if (!isset($group[0])) { - $group = array($group); - } - foreach ($group as $deps) { - if (isset($deps['subpackage'])) { - $sub2 = $deps['subpackage']; - if (!isset($sub2[0])) { - $sub2 = array($sub2); - } - $sub = array_merge($sub, $sub2); - } - } + if (!isset($this->_pf->_packageFile)) { + return false; } - foreach ($sub as $dep) { - if (strtolower($dep['name']) == strtolower($p->getPackage())) { - if (isset($dep['channel'])) { - if (strtolower($dep['channel']) == strtolower($p->getChannel())) { - return true; - } - } else { - if ($dep['uri'] == $p->getURI()) { - return true; + $dir_prefix = dirname($this->_pf->_packageFile); + $common = new PEAR_Common; + $log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') : + array($common, 'log'); + $info = $this->_pf->getContents(); + $info = $info['bundledpackage']; + if (!is_array($info)) { + $info = array($info); + } + $pkg = &new PEAR_PackageFile($this->_pf->_config); + foreach ($info as $package) { + if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $package)) { + $this->_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $package); + $this->_isValid = 0; + continue; + } + call_user_func_array($log, array(1, "Analyzing bundled package $package")); + PEAR::pushErrorHandling(PEAR_ERROR_RETURN); + $ret = $pkg->fromAnyFile($dir_prefix . DIRECTORY_SEPARATOR . $package, + PEAR_VALIDATE_NORMAL); + PEAR::popErrorHandling(); + if (PEAR::isError($ret)) { + call_user_func_array($log, array(0, "ERROR: package $package is not a valid " . + 'package')); + $inf = $ret->getUserInfo(); + if (is_array($inf)) { + foreach ($inf as $err) { + call_user_func_array($log, array(1, $err['message'])); } } + return false; } } - return false; + return true; } - function dependsOn($package, $channel) + function _analyzePhpFiles() { - if (!($deps = $this->getDependencies())) { + if (!$this->_isValid) { return false; } - foreach (array('package', 'subpackage') as $type) { - foreach (array('required', 'optional') as $needed) { - if (isset($deps[$needed][$type])) { - if (!isset($deps[$needed][$type][0])) { - $deps[$needed][$type] = array($deps[$needed][$type]); - } - foreach ($deps[$needed][$type] as $dep) { - $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; - if (strtolower($dep['name']) == strtolower($package) && - $depchannel == $channel) { - return true; - } - } + if (!isset($this->_pf->_packageFile)) { + $this->_cannotValidateNoPathSet(); + return false; + } + $dir_prefix = dirname($this->_pf->_packageFile); + $common = new PEAR_Common; + $log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') : + array(&$common, 'log'); + $info = $this->_pf->getContents(); + if (!$info || !isset($info['dir']['file'])) { + $this->_tagCannotBeEmpty('contents>_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $file); + $this->_isValid = 0; + continue; + } + if (in_array($fa['role'], PEAR_Installer_Role::getPhpRoles()) && $dir_prefix) { + call_user_func_array($log, array(1, "Analyzing $file")); + $srcinfo = $this->analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); + if ($srcinfo) { + $provides = array_merge($provides, $this->_buildProvidesArray($srcinfo)); } } - if (isset($deps['group'])) { - if (!isset($deps['group'][0])) { - $dep['group'] = array($deps['group']); + } + $this->_packageName = $pn = $this->_pf->getPackage(); + $pnl = strlen($pn); + foreach ($provides as $key => $what) { + if (isset($what['explicit']) || !$what) { + // skip conformance checks if the provides entry is + // specified in the package.xml file + continue; + } + extract($what); + if ($type == 'class') { + if (!strncasecmp($name, $pn, $pnl)) { + continue; } - foreach ($deps['group'] as $group) { - if (isset($group[$type])) { - if (!is_array($group[$type])) { - $group[$type] = array($group[$type]); - } - foreach ($group[$type] as $dep) { - $depchannel = isset($dep['channel']) ? $dep['channel'] : '__uri'; - if (strtolower($dep['name']) == strtolower($package) && - $depchannel == $channel) { - return true; - } - } - } + $this->_stack->push(__FUNCTION__, 'warning', + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn), + 'in %file%: %type% "%name%" not prefixed with package name "%package%"'); + } elseif ($type == 'function') { + if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { + continue; } + $this->_stack->push(__FUNCTION__, 'warning', + array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn), + 'in %file%: %type% "%name%" not prefixed with package name "%package%"'); } } - return false; + return $this->_isValid; } /** - * Get the contents of a dependency group - * @param string - * @return array|false + * Analyze the source code of the given PHP file + * + * @param string Filename of the PHP file + * @param boolean whether to analyze $file as the file contents + * @return mixed */ - function getDependencyGroup($name) + function analyzeSourceCode($file, $string = false) { - $name = strtolower($name); - if (!isset($this->_packageInfo['dependencies']['group'])) { + if (!function_exists("token_get_all")) { + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'Parser error: token_get_all() function must exist to analyze source code, PHP may have been compiled with --disable-tokenizer'); return false; } - $groups = $this->_packageInfo['dependencies']['group']; - if (!isset($groups[0])) { - $groups = array($groups); + + if (!defined('T_DOC_COMMENT')) { + define('T_DOC_COMMENT', T_COMMENT); } - foreach ($groups as $group) { - if (strtolower($group['attribs']['name']) == $name) { - return $group; + + if (!defined('T_INTERFACE')) { + define('T_INTERFACE', -1); + } + + if (!defined('T_IMPLEMENTS')) { + define('T_IMPLEMENTS', -1); + } + + if ($string) { + $contents = $file; + } else { + if (!$fp = @fopen($file, "r")) { + return false; } + fclose($fp); + $contents = file_get_contents($file); } - return false; - } - /** - * Retrieve a partial package.xml 1.0 representation of dependencies - * - * a very limited representation of dependencies is returned by this method. - * The tag for excluding certain versions of a dependency is - * completely ignored. In addition, dependency groups are ignored, with the - * assumption that all dependencies in dependency groups are also listed in - * the optional group that work with all dependency groups - * @param boolean return package.xml 2.0 tag - * @return array|false - */ - function getDeps($raw = false, $nopearinstaller = false) - { - if (isset($this->_packageInfo['dependencies'])) { - if ($raw) { - return $this->_packageInfo['dependencies']; + // Silence this function so we can catch PHP Warnings and show our own custom message + $tokens = @token_get_all($contents); + if (isset($php_errormsg)) { + if (isset($this->_stack)) { + $pn = $this->_pf->getPackage(); + $this->_stack->push(__FUNCTION__, 'warning', + array('file' => $file, 'package' => $pn), + 'in %file%: Could not process file for unkown reasons,' . + ' possibly a PHP parse error in %file% from %package%'); } - $ret = array(); - $map = array( - 'php' => 'php', - 'package' => 'pkg', - 'subpackage' => 'pkg', - 'extension' => 'ext', - 'os' => 'os', - 'pearinstaller' => 'pkg', - ); - foreach (array('required', 'optional') as $type) { - $optional = ($type == 'optional') ? 'yes' : 'no'; - if (!isset($this->_packageInfo['dependencies'][$type]) - || empty($this->_packageInfo['dependencies'][$type])) { + } +/* + for ($i = 0; $i < sizeof($tokens); $i++) { + @list($token, $data) = $tokens[$i]; + if (is_string($token)) { + var_dump($token); + } else { + print token_name($token) . ' '; + var_dump(rtrim($data)); + } + } +*/ + $look_for = 0; + $paren_level = 0; + $bracket_level = 0; + $brace_level = 0; + $lastphpdoc = ''; + $current_class = ''; + $current_interface = ''; + $current_class_level = -1; + $current_function = ''; + $current_function_level = -1; + $declared_classes = array(); + $declared_interfaces = array(); + $declared_functions = array(); + $declared_methods = array(); + $used_classes = array(); + $used_functions = array(); + $extends = array(); + $implements = array(); + $nodeps = array(); + $inquote = false; + $interface = false; + for ($i = 0; $i < sizeof($tokens); $i++) { + if (is_array($tokens[$i])) { + list($token, $data) = $tokens[$i]; + } else { + $token = $tokens[$i]; + $data = ''; + } + + if ($inquote) { + if ($token != '"' && $token != T_END_HEREDOC) { + continue; + } else { + $inquote = false; continue; } - foreach ($this->_packageInfo['dependencies'][$type] as $dtype => $deps) { - if ($dtype == 'pearinstaller' && $nopearinstaller) { - continue; + } + + switch ($token) { + case T_WHITESPACE : + continue; + case ';': + if ($interface) { + $current_function = ''; + $current_function_level = -1; } - if (!isset($deps[0])) { - $deps = array($deps); + break; + case '"': + case T_START_HEREDOC: + $inquote = true; + break; + case T_CURLY_OPEN: + case T_DOLLAR_OPEN_CURLY_BRACES: + case '{': $brace_level++; continue 2; + case '}': + $brace_level--; + if ($current_class_level == $brace_level) { + $current_class = ''; + $current_class_level = -1; } - foreach ($deps as $dep) { - if (!isset($map[$dtype])) { - // no support for arch type - continue; - } - if ($dtype == 'pearinstaller') { - $dep['name'] = 'PEAR'; - $dep['channel'] = 'pear.php.net'; - } - $s = array('type' => $map[$dtype]); - if (isset($dep['channel'])) { - $s['channel'] = $dep['channel']; - } - if (isset($dep['uri'])) { - $s['uri'] = $dep['uri']; - } - if (isset($dep['name'])) { - $s['name'] = $dep['name']; - } - if (isset($dep['conflicts'])) { - $s['rel'] = 'not'; + if ($current_function_level == $brace_level) { + $current_function = ''; + $current_function_level = -1; + } + continue 2; + case '[': $bracket_level++; continue 2; + case ']': $bracket_level--; continue 2; + case '(': $paren_level++; continue 2; + case ')': $paren_level--; continue 2; + case T_INTERFACE: + $interface = true; + case T_CLASS: + if (($current_class_level != -1) || ($current_function_level != -1)) { + if (isset($this->_stack)) { + $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), + 'Parser error: invalid PHP found in file "%file%"'); } else { - if (!isset($dep['min']) && - !isset($dep['max'])) { - $s['rel'] = 'has'; - $s['optional'] = $optional; - } elseif (isset($dep['min']) && - isset($dep['max'])) { - $s['rel'] = 'ge'; - $s1 = $s; - $s1['rel'] = 'le'; - $s['version'] = $dep['min']; - $s1['version'] = $dep['max']; - if (isset($dep['channel'])) { - $s1['channel'] = $dep['channel']; - } - if ($dtype != 'php') { - $s['name'] = $dep['name']; - $s1['name'] = $dep['name']; - } - $s['optional'] = $optional; - $s1['optional'] = $optional; - $ret[] = $s1; - } elseif (isset($dep['min'])) { - if (isset($dep['exclude']) && - $dep['exclude'] == $dep['min']) { - $s['rel'] = 'gt'; - } else { - $s['rel'] = 'ge'; - } - $s['version'] = $dep['min']; - $s['optional'] = $optional; - if ($dtype != 'php') { - $s['name'] = $dep['name']; - } - } elseif (isset($dep['max'])) { - if (isset($dep['exclude']) && - $dep['exclude'] == $dep['max']) { - $s['rel'] = 'lt'; - } else { - $s['rel'] = 'le'; - } - $s['version'] = $dep['max']; - $s['optional'] = $optional; - if ($dtype != 'php') { - $s['name'] = $dep['name']; - } + PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"", + PEAR_COMMON_ERROR_INVALIDPHP); + } + + return false; + } + case T_FUNCTION: + case T_NEW: + case T_EXTENDS: + case T_IMPLEMENTS: + $look_for = $token; + continue 2; + case T_STRING: + if (version_compare(zend_version(), '2.0', '<')) { + if (in_array(strtolower($data), + array('public', 'private', 'protected', 'abstract', + 'interface', 'implements', 'throw') + ) + ) { + if (isset($this->_stack)) { + $this->_stack->push(__FUNCTION__, 'warning', array( + 'file' => $file), + 'Error, PHP5 token encountered in %file%,' . + ' analysis should be in PHP5'); + } else { + PEAR::raiseError('Error: PHP5 token encountered in ' . $file . + 'packaging should be done in PHP 5'); + return false; } } - $ret[] = $s; } - } - } - if (count($ret)) { - return $ret; - } - } - return false; - } - - /** - * @return php|extsrc|extbin|zendextsrc|zendextbin|bundle|false - */ - function getPackageType() - { - if (isset($this->_packageInfo['phprelease'])) { - return 'php'; - } - if (isset($this->_packageInfo['extsrcrelease'])) { - return 'extsrc'; - } - if (isset($this->_packageInfo['extbinrelease'])) { - return 'extbin'; - } - if (isset($this->_packageInfo['zendextsrcrelease'])) { - return 'zendextsrc'; - } - if (isset($this->_packageInfo['zendextbinrelease'])) { - return 'zendextbin'; - } - if (isset($this->_packageInfo['bundle'])) { - return 'bundle'; - } - return false; - } - - /** - * @return array|false - */ - function getReleases() - { - $type = $this->getPackageType(); - if ($type != 'bundle') { - $type .= 'release'; - } - if ($this->getPackageType() && isset($this->_packageInfo[$type])) { - return $this->_packageInfo[$type]; - } - return false; - } - /** - * @return array - */ - function getChangelog() - { - if (isset($this->_packageInfo['changelog'])) { - return $this->_packageInfo['changelog']; - } - return false; - } + if ($look_for == T_CLASS) { + $current_class = $data; + $current_class_level = $brace_level; + $declared_classes[] = $current_class; + } elseif ($look_for == T_INTERFACE) { + $current_interface = $data; + $current_class_level = $brace_level; + $declared_interfaces[] = $current_interface; + } elseif ($look_for == T_IMPLEMENTS) { + $implements[$current_class] = $data; + } elseif ($look_for == T_EXTENDS) { + $extends[$current_class] = $data; + } elseif ($look_for == T_FUNCTION) { + if ($current_class) { + $current_function = "$current_class::$data"; + $declared_methods[$current_class][] = $data; + } elseif ($current_interface) { + $current_function = "$current_interface::$data"; + $declared_methods[$current_interface][] = $data; + } else { + $current_function = $data; + $declared_functions[] = $current_function; + } - function hasDeps() - { - return isset($this->_packageInfo['dependencies']); - } + $current_function_level = $brace_level; + $m = array(); + } elseif ($look_for == T_NEW) { + $used_classes[$data] = true; + } - function getPackagexmlVersion() - { - if (isset($this->_packageInfo['zendextsrcrelease'])) { - return '2.1'; - } - if (isset($this->_packageInfo['zendextbinrelease'])) { - return '2.1'; - } - return '2.0'; - } + $look_for = 0; + continue 2; + case T_VARIABLE: + $look_for = 0; + continue 2; + case T_DOC_COMMENT: + case T_COMMENT: + if (preg_match('!^/\*\*\s!', $data)) { + $lastphpdoc = $data; + if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { + $nodeps = array_merge($nodeps, $m[1]); + } + } + continue 2; + case T_DOUBLE_COLON: + if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { + if (isset($this->_stack)) { + $this->_stack->push(__FUNCTION__, 'warning', array('file' => $file), + 'Parser error: invalid PHP found in file "%file%"'); + } else { + PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"", + PEAR_COMMON_ERROR_INVALIDPHP); + } - /** - * @return array|false - */ - function getSourcePackage() - { - if (isset($this->_packageInfo['extbinrelease']) || - isset($this->_packageInfo['zendextbinrelease'])) { - return array('channel' => $this->_packageInfo['srcchannel'], - 'package' => $this->_packageInfo['srcpackage']); - } - return false; - } + return false; + } - function getBundledPackages() - { - if (isset($this->_packageInfo['bundle'])) { - return $this->_packageInfo['contents']['bundledpackage']; - } - return false; - } + $class = $tokens[$i - 1][1]; + if (strtolower($class) != 'parent') { + $used_classes[$class] = true; + } - function getLastModified() - { - if (isset($this->_packageInfo['_lastmodified'])) { - return $this->_packageInfo['_lastmodified']; + continue 2; + } } - return false; + + return array( + "source_file" => $file, + "declared_classes" => $declared_classes, + "declared_interfaces" => $declared_interfaces, + "declared_methods" => $declared_methods, + "declared_functions" => $declared_functions, + "used_classes" => array_diff(array_keys($used_classes), $nodeps), + "inheritance" => $extends, + "implements" => $implements, + ); } /** - * Get the contents of a file listed within the package.xml - * @param string - * @return string + * Build a "provides" array from data returned by + * analyzeSourceCode(). The format of the built array is like + * this: + * + * array( + * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), + * ... + * ) + * + * + * @param array $srcinfo array with information about a source file + * as returned by the analyzeSourceCode() method. + * + * @return void + * + * @access private + * */ - function getFileContents($file) + function _buildProvidesArray($srcinfo) { - if ($this->_archiveFile == $this->_packageFile) { // unpacked - $dir = dirname($this->_packageFile); - $file = $dir . DIRECTORY_SEPARATOR . $file; - $file = str_replace(array('/', '\\'), - array(DIRECTORY_SEPARATOR, DIRECTORY_SEPARATOR), $file); - if (file_exists($file) && is_readable($file)) { - return implode('', file($file)); - } - } else { // tgz - $tar = &new Archive_Tar($this->_archiveFile); - $tar->pushErrorHandling(PEAR_ERROR_RETURN); - if ($file != 'package.xml' && $file != 'package2.xml') { - $file = $this->getPackage() . '-' . $this->getVersion() . '/' . $file; - } - $file = $tar->extractInString($file); - $tar->popErrorHandling(); - if (PEAR::isError($file)) { - return PEAR::raiseError("Cannot locate file '$file' in archive"); - } - return $file; + if (!$this->_isValid) { + return array(); } - } - function &getRW() - { - if (!class_exists('PEAR_PackageFile_v2_rw')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2/rw.php'; - } - $a = new PEAR_PackageFile_v2_rw; - foreach (get_object_vars($this) as $name => $unused) { - if (!isset($this->$name)) { + $providesret = array(); + $file = basename($srcinfo['source_file']); + $pn = isset($this->_pf) ? $this->_pf->getPackage() : ''; + $pnl = strlen($pn); + foreach ($srcinfo['declared_classes'] as $class) { + $key = "class;$class"; + if (isset($providesret[$key])) { continue; } - if ($name == '_config' || $name == '_logger'|| $name == '_registry' || - $name == '_stack') { - $a->$name = &$this->$name; - } else { - $a->$name = $this->$name; + + $providesret[$key] = + array('file'=> $file, 'type' => 'class', 'name' => $class); + if (isset($srcinfo['inheritance'][$class])) { + $providesret[$key]['extends'] = + $srcinfo['inheritance'][$class]; } } - return $a; - } - function &getDefaultGenerator() - { - if (!class_exists('PEAR_PackageFile_Generator_v2')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/Generator/v2.php'; - } - $a = &new PEAR_PackageFile_Generator_v2($this); - return $a; - } + foreach ($srcinfo['declared_methods'] as $class => $methods) { + foreach ($methods as $method) { + $function = "$class::$method"; + $key = "function;$function"; + if ($method{0} == '_' || !strcasecmp($method, $class) || + isset($providesret[$key])) { + continue; + } - function analyzeSourceCode($file, $string = false) - { - if (!isset($this->_v2Validator) || - !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { - if (!class_exists('PEAR_PackageFile_v2_Validator')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2/Validator.php'; + $providesret[$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); } - $this->_v2Validator = new PEAR_PackageFile_v2_Validator; } - return $this->_v2Validator->analyzeSourceCode($file, $string); - } - function validate($state = PEAR_VALIDATE_NORMAL) - { - if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { - return false; - } - if (!isset($this->_v2Validator) || - !is_a($this->_v2Validator, 'PEAR_PackageFile_v2_Validator')) { - if (!class_exists('PEAR_PackageFile_v2_Validator')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v2/Validator.php'; + foreach ($srcinfo['declared_functions'] as $function) { + $key = "function;$function"; + if ($function{0} == '_' || isset($providesret[$key])) { + continue; } - $this->_v2Validator = new PEAR_PackageFile_v2_Validator; - } - if (isset($this->_packageInfo['xsdversion'])) { - unset($this->_packageInfo['xsdversion']); - } - return $this->_v2Validator->validate($this, $state); - } - function getTasksNs() - { - if (!isset($this->_tasksNs)) { - if (isset($this->_packageInfo['attribs'])) { - foreach ($this->_packageInfo['attribs'] as $name => $value) { - if ($value == 'http://pear.php.net/dtd/tasks-1.0') { - $this->_tasksNs = str_replace('xmlns:', '', $name); - break; - } - } + if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { + $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; } - } - return $this->_tasksNs; - } - - /** - * Determine whether a task name is a valid task. Custom tasks may be defined - * using subdirectories by putting a "-" in the name, as in - * - * Note that this method will auto-load the task class file and test for the existence - * of the name with "-" replaced by "_" as in PEAR/Task/mycustom/task.php makes class - * PEAR_Task_mycustom_task - * @param string - * @return boolean - */ - function getTask($task) - { - $this->getTasksNs(); - // transform all '-' to '/' and 'tasks:' to '' so tasks:replace becomes replace - $task = str_replace(array($this->_tasksNs . ':', '-'), array('', ' '), $task); - $taskfile = str_replace(' ', '/', ucwords($task)); - $task = str_replace(array(' ', '/'), '_', ucwords($task)); - if (class_exists("PEAR_Task_$task")) { - return "PEAR_Task_$task"; - } - $fp = @fopen("phar://install-pear-nozlib.phar/PEAR/Task/$taskfile.php", 'r', true); - if ($fp) { - fclose($fp); - require_once 'phar://install-pear-nozlib.phar/' . "PEAR/Task/$taskfile.php"; - return "PEAR_Task_$task"; - } - return false; - } - - /** - * Key-friendly array_splice - * @param tagname to splice a value in before - * @param mixed the value to splice in - * @param string the new tag name - */ - function _ksplice($array, $key, $value, $newkey) - { - $offset = array_search($key, array_keys($array)); - $after = array_slice($array, $offset); - $before = array_slice($array, 0, $offset); - $before[$newkey] = $value; - return array_merge($before, $after); - } - /** - * @param array a list of possible keys, in the order they may occur - * @param mixed contents of the new package.xml tag - * @param string tag name - * @access private - */ - function _insertBefore($array, $keys, $contents, $newkey) - { - foreach ($keys as $key) { - if (isset($array[$key])) { - return $array = $this->_ksplice($array, $key, $contents, $newkey); - } + $providesret[$key] = + array('file'=> $file, 'type' => 'function', 'name' => $function); } - $array[$newkey] = $contents; - return $array; - } - /** - * @param subsection of {@link $_packageInfo} - * @param array|string tag contents - * @param array format: - *
    -     * array(
    -     *   tagname => array(list of tag names that follow this one),
    -     *   childtagname => array(list of child tag names that follow this one),
    -     * )
    -     * 
    - * - * This allows construction of nested tags - * @access private - */ - function _mergeTag($manip, $contents, $order) - { - if (count($order)) { - foreach ($order as $tag => $curorder) { - if (!isset($manip[$tag])) { - // ensure that the tag is set up - $manip = $this->_insertBefore($manip, $curorder, array(), $tag); - } - if (count($order) > 1) { - $manip[$tag] = $this->_mergeTag($manip[$tag], $contents, array_slice($order, 1)); - return $manip; - } - } - } else { - return $manip; - } - if (is_array($manip[$tag]) && !empty($manip[$tag]) && isset($manip[$tag][0])) { - $manip[$tag][] = $contents; - } else { - if (!count($manip[$tag])) { - $manip[$tag] = $contents; - } else { - $manip[$tag] = array($manip[$tag]); - $manip[$tag][] = $contents; - } - } - return $manip; + return $providesret; } -} -?> - + * @author Tomas V. V. Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Validator.php,v 1.110 2009/03/27 19:29:31 dufuz Exp $ + * @version CVS: $Id: Registry.php 287555 2009-08-21 21:27:27Z dufuz $ * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a8 + * @since File available since Release 0.1 */ + /** - * Private validation class used by PEAR_PackageFile_v2 - do not use directly, its - * sole purpose is to split up the PEAR/PackageFile/v2.php file to make it smaller + * for PEAR_Error + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/DependencyDB.php'; + +define('PEAR_REGISTRY_ERROR_LOCK', -2); +define('PEAR_REGISTRY_ERROR_FORMAT', -3); +define('PEAR_REGISTRY_ERROR_FILE', -4); +define('PEAR_REGISTRY_ERROR_CONFLICT', -5); +define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6); + +/** + * Administration class used to maintain the installed package database. * @category pear * @package PEAR + * @author Stig Bakken + * @author Tomas V. V. Cox * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a8 - * @access private + * @since Class available since Release 1.4.0a1 */ -class PEAR_PackageFile_v2_Validator +class PEAR_Registry extends PEAR { /** + * File containing all channel information. + * @var string + */ + var $channels = ''; + + /** Directory where registry files are stored. + * @var string + */ + var $statedir = ''; + + /** File where the file map is stored + * @var string + */ + var $filemap = ''; + + /** Directory where registry files for channels are stored. + * @var string + */ + var $channelsdir = ''; + + /** Name of file used for locking the registry + * @var string + */ + var $lockfile = ''; + + /** File descriptor used during locking + * @var resource + */ + var $lock_fp = null; + + /** Mode used during locking + * @var int + */ + var $lock_mode = 0; // XXX UNUSED + + /** Cache of package information. Structure: + * array( + * 'package' => array('id' => ... ), + * ... ) * @var array */ - var $_packageInfo; + var $pkginfo_cache = array(); + + /** Cache of file map. Structure: + * array( '/path/to/file' => 'package', ... ) + * @var array + */ + var $filemap_cache = array(); + /** - * @var PEAR_PackageFile_v2 + * @var false|PEAR_ChannelFile */ - var $_pf; + var $_pearChannel; + /** - * @var PEAR_ErrorStack + * @var false|PEAR_ChannelFile */ - var $_stack; + var $_peclChannel; + /** - * @var int + * @var false|PEAR_ChannelFile */ - var $_isValid = 0; + var $_docChannel; + /** - * @var int + * @var PEAR_DependencyDB */ - var $_filesValid = 0; + var $_dependencyDB; + /** - * @var int + * @var PEAR_Config */ - var $_curState = 0; + var $_config; + /** - * @param PEAR_PackageFile_v2 - * @param int + * PEAR_Registry constructor. + * + * @param string (optional) PEAR install directory (for .php files) + * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PEAR channel, if + * default values are not desired. Only used the very first time a PEAR + * repository is initialized + * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PECL channel, if + * default values are not desired. Only used the very first time a PEAR + * repository is initialized + * + * @access public */ - function validate(&$pf, $state = PEAR_VALIDATE_NORMAL) + function PEAR_Registry($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false, + $pecl_channel = false) { - $this->_pf = &$pf; - $this->_curState = $state; - $this->_packageInfo = $this->_pf->getArray(); - $this->_isValid = $this->_pf->_isValid; - $this->_filesValid = $this->_pf->_filesValid; - $this->_stack = &$pf->_stack; - $this->_stack->getErrors(true); - if (($this->_isValid & $state) == $state) { - return true; - } - if (!isset($this->_packageInfo) || !is_array($this->_packageInfo)) { - return false; - } - if (!isset($this->_packageInfo['attribs']['version']) || - ($this->_packageInfo['attribs']['version'] != '2.0' && - $this->_packageInfo['attribs']['version'] != '2.1') - ) { - $this->_noPackageVersion(); - } - $structure = - array( - 'name', - 'channel|uri', - '*extends', // can't be multiple, but this works fine - 'summary', - 'description', - '+lead', // these all need content checks - '*developer', - '*contributor', - '*helper', - 'date', - '*time', - 'version', - 'stability', - 'license->?uri->?filesource', - 'notes', - 'contents', //special validation needed - '*compatible', - 'dependencies', //special validation needed - '*usesrole', - '*usestask', // reserve these for 1.4.0a1 to implement - // this will allow a package.xml to gracefully say it - // needs a certain package installed in order to implement a role or task - '*providesextension', - '*srcpackage|*srcuri', - '+phprelease|+extsrcrelease|+extbinrelease|' . - '+zendextsrcrelease|+zendextbinrelease|bundle', //special validation needed - '*changelog', - ); - $test = $this->_packageInfo; - if (isset($test['dependencies']) && - isset($test['dependencies']['required']) && - isset($test['dependencies']['required']['pearinstaller']) && - isset($test['dependencies']['required']['pearinstaller']['min']) && - version_compare('1.8.0', - $test['dependencies']['required']['pearinstaller']['min'], '<') - ) { - $this->_pearVersionTooLow($test['dependencies']['required']['pearinstaller']['min']); + parent::PEAR(); + $this->setInstallDir($pear_install_dir); + $this->_pearChannel = $pear_channel; + $this->_peclChannel = $pecl_channel; + $this->_config = false; + } + + function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR) + { + $ds = DIRECTORY_SEPARATOR; + $this->install_dir = $pear_install_dir; + $this->channelsdir = $pear_install_dir.$ds.'.channels'; + $this->statedir = $pear_install_dir.$ds.'.registry'; + $this->filemap = $pear_install_dir.$ds.'.filemap'; + $this->lockfile = $pear_install_dir.$ds.'.lock'; + } + + function hasWriteAccess() + { + if (!file_exists($this->install_dir)) { + $dir = $this->install_dir; + while ($dir && $dir != '.') { + $olddir = $dir; + $dir = dirname($dir); + if ($dir != '.' && file_exists($dir)) { + if (is_writeable($dir)) { + return true; + } + + return false; + } + + if ($dir == $olddir) { // this can happen in safe mode + return @is_writable($dir); + } + } + return false; } - // ignore post-installation array fields - if (array_key_exists('filelist', $test)) { - unset($test['filelist']); - } - if (array_key_exists('_lastmodified', $test)) { - unset($test['_lastmodified']); + + return is_writeable($this->install_dir); + } + + function setConfig(&$config, $resetInstallDir = true) + { + $this->_config = &$config; + if ($resetInstallDir) { + $this->setInstallDir($config->get('php_dir')); + } + } + + function _initializeChannelDirs() + { + static $running = false; + if (!$running) { + $running = true; + $ds = DIRECTORY_SEPARATOR; + if (!is_dir($this->channelsdir) || + !file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || + !file_exists($this->channelsdir . $ds . '__uri.reg')) { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $pear_channel = $this->_pearChannel; + if (!is_a($pear_channel, 'PEAR_ChannelFile') || !$pear_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setAlias('pear'); + $pear_channel->setServer('pear.php.net'); + $pear_channel->setSummary('PHP Extension and Application Repository'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/'); + //$pear_channel->setBaseURL('REST1.4', 'http://pear.php.net/rest/'); + } else { + $pear_channel->setServer('pear.php.net'); + $pear_channel->setAlias('pear'); + } + + $pear_channel->validate(); + $this->_addChannel($pear_channel); + } + + if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) { + $pecl_channel = $this->_peclChannel; + if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $pecl_channel = new PEAR_ChannelFile; + $pecl_channel->setAlias('pecl'); + $pecl_channel->setServer('pecl.php.net'); + $pecl_channel->setSummary('PHP Extension Community Library'); + $pecl_channel->setDefaultPEARProtocols(); + $pecl_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); + $pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); + $pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); + } else { + $pecl_channel->setServer('pecl.php.net'); + $pecl_channel->setAlias('pecl'); + } + + $pecl_channel->validate(); + $this->_addChannel($pecl_channel); + } + + if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) { + $doc_channel = $this->_docChannel; + if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $doc_channel = new PEAR_ChannelFile; + $doc_channel->setAlias('phpdocs'); + $doc_channel->setServer('doc.php.net'); + $doc_channel->setSummary('PHP Documentation Team'); + $doc_channel->setDefaultPEARProtocols(); + $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/'); + } else { + $doc_channel->setServer('doc.php.net'); + $doc_channel->setAlias('doc'); + } + + $doc_channel->validate(); + $this->_addChannel($doc_channel); + } + + if (!file_exists($this->channelsdir . $ds . '__uri.reg')) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $private = new PEAR_ChannelFile; + $private->setName('__uri'); + $private->setDefaultPEARProtocols(); + $private->setBaseURL('REST1.0', '****'); + $private->setSummary('Pseudo-channel for static packages'); + $this->_addChannel($private); + } + $this->_rebuildFileMap(); + } + + $running = false; } - if (array_key_exists('#binarypackage', $test)) { - unset($test['#binarypackage']); + } + + function _initializeDirs() + { + $ds = DIRECTORY_SEPARATOR; + // XXX Compatibility code should be removed in the future + // rename all registry files if any to lowercase + if (!OS_WINDOWS && file_exists($this->statedir) && is_dir($this->statedir) && + $handle = opendir($this->statedir)) { + $dest = $this->statedir . $ds; + while (false !== ($file = readdir($handle))) { + if (preg_match('/^.*[A-Z].*\.reg\\z/', $file)) { + rename($dest . $file, $dest . strtolower($file)); + } + } + closedir($handle); } - if (array_key_exists('old', $test)) { - unset($test['old']); + + $this->_initializeChannelDirs(); + if (!file_exists($this->filemap)) { + $this->_rebuildFileMap(); } - if (array_key_exists('_lastversion', $test)) { - unset($test['_lastversion']); + $this->_initializeDepDB(); + } + + function _initializeDepDB() + { + if (!isset($this->_dependencyDB)) { + static $initializing = false; + if (!$initializing) { + $initializing = true; + if (!$this->_config) { // never used? + $file = OS_WINDOWS ? 'pear.ini' : '.pearrc'; + $this->_config = &new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR . + $file); + $this->_config->setRegistry($this); + $this->_config->set('php_dir', $this->install_dir); + } + + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); + if (PEAR::isError($this->_dependencyDB)) { + // attempt to recover by removing the dep db + if (file_exists($this->_config->get('php_dir', null, 'pear.php.net') . + DIRECTORY_SEPARATOR . '.depdb')) { + @unlink($this->_config->get('php_dir', null, 'pear.php.net') . + DIRECTORY_SEPARATOR . '.depdb'); + } + + $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); + if (PEAR::isError($this->_dependencyDB)) { + echo $this->_dependencyDB->getMessage(); + echo 'Unrecoverable error'; + exit(1); + } + } + + $initializing = false; + } } - if (!$this->_stupidSchemaValidate($structure, $test, '')) { - return false; + } + + /** + * PEAR_Registry destructor. Makes sure no locks are forgotten. + * + * @access private + */ + function _PEAR_Registry() + { + parent::_PEAR(); + if (is_resource($this->lock_fp)) { + $this->_unlock(); } - if (empty($this->_packageInfo['name'])) { - $this->_tagCannotBeEmpty('name'); + } + + /** + * Make sure the directory where we keep registry files exists. + * + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertStateDir($channel = false) + { + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_assertChannelStateDir($channel); } - $test = isset($this->_packageInfo['uri']) ? 'uri' :'channel'; - if (empty($this->_packageInfo[$test])) { - $this->_tagCannotBeEmpty($test); + + static $init = false; + if (!file_exists($this->statedir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + if (!System::mkdir(array('-p', $this->statedir))) { + return $this->raiseError("could not create directory '{$this->statedir}'"); + } + $init = true; + } elseif (!is_dir($this->statedir)) { + return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' . + 'it already exists and is not a directory'); } - if (is_array($this->_packageInfo['license']) && - (!isset($this->_packageInfo['license']['_content']) || - empty($this->_packageInfo['license']['_content']))) { - $this->_tagCannotBeEmpty('license'); - } elseif (empty($this->_packageInfo['license'])) { - $this->_tagCannotBeEmpty('license'); + + $ds = DIRECTORY_SEPARATOR; + if (!file_exists($this->channelsdir)) { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || + !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || + !file_exists($this->channelsdir . $ds . '__uri.reg')) { + $init = true; + } + } elseif (!is_dir($this->channelsdir)) { + return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' . + 'it already exists and is not a directory'); } - if (empty($this->_packageInfo['summary'])) { - $this->_tagCannotBeEmpty('summary'); + + if ($init) { + static $running = false; + if (!$running) { + $running = true; + $this->_initializeDirs(); + $running = false; + $init = false; + } + } else { + $this->_initializeDepDB(); } - if (empty($this->_packageInfo['description'])) { - $this->_tagCannotBeEmpty('description'); + + return true; + } + + /** + * Make sure the directory where we keep registry files exists for a non-standard channel. + * + * @param string channel name + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertChannelStateDir($channel) + { + $ds = DIRECTORY_SEPARATOR; + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $this->_initializeChannelDirs(); + } + return $this->_assertStateDir($channel); } - if (empty($this->_packageInfo['date'])) { - $this->_tagCannotBeEmpty('date'); + + $channelDir = $this->_channelDirectoryName($channel); + if (!is_dir($this->channelsdir) || + !file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { + $this->_initializeChannelDirs(); } - if (empty($this->_packageInfo['notes'])) { - $this->_tagCannotBeEmpty('notes'); + + if (!file_exists($channelDir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + if (!System::mkdir(array('-p', $channelDir))) { + return $this->raiseError("could not create directory '" . $channelDir . + "'"); + } + } elseif (!is_dir($channelDir)) { + return $this->raiseError("could not create directory '" . $channelDir . + "', already exists and is not a directory"); } - if (isset($this->_packageInfo['time']) && empty($this->_packageInfo['time'])) { - $this->_tagCannotBeEmpty('time'); + + return true; + } + + /** + * Make sure the directory where we keep registry files for channels exists + * + * @return bool TRUE if directory exists, FALSE if it could not be + * created + * + * @access private + */ + function _assertChannelDir() + { + if (!file_exists($this->channelsdir)) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + if (!System::mkdir(array('-p', $this->channelsdir))) { + return $this->raiseError("could not create directory '{$this->channelsdir}'"); + } + } elseif (!is_dir($this->channelsdir)) { + return $this->raiseError("could not create directory '{$this->channelsdir}" . + "', it already exists and is not a directory"); } - if (isset($this->_packageInfo['dependencies'])) { - $this->_validateDependencies(); + + if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { + if (!$this->hasWriteAccess()) { + return false; + } + + require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; + if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) { + return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'"); + } + } elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { + return $this->raiseError("could not create directory '{$this->channelsdir}" . + "/.alias', it already exists and is not a directory"); } - if (isset($this->_packageInfo['compatible'])) { - $this->_validateCompatible(); + + return true; + } + + /** + * Get the name of the file where data for a given package is stored. + * + * @param string channel name, or false if this is a PEAR package + * @param string package name + * + * @return string registry file name + * + * @access public + */ + function _packageFileName($package, $channel = false) + { + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR . + strtolower($package) . '.reg'; } - if (!isset($this->_packageInfo['bundle'])) { - if (empty($this->_packageInfo['contents'])) { - $this->_tagCannotBeEmpty('contents'); + + return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg'; + } + + /** + * Get the name of the file where data for a given channel is stored. + * @param string channel name + * @return string registry file name + */ + function _channelFileName($channel, $noaliases = false) + { + if (!$noaliases) { + if (file_exists($this->_getChannelAliasFileName($channel))) { + $channel = implode('', file($this->_getChannelAliasFileName($channel))); } - if (!isset($this->_packageInfo['contents']['dir'])) { - $this->_filelistMustContainDir('contents'); - return false; + } + return $this->channelsdir . DIRECTORY_SEPARATOR . str_replace('/', '_', + strtolower($channel)) . '.reg'; + } + + /** + * @param string + * @return string + */ + function _getChannelAliasFileName($alias) + { + return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' . + DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt'; + } + + /** + * Get the name of a channel from its alias + */ + function _getChannelFromAlias($channel) + { + if (!$this->_channelExists($channel)) { + if ($channel == 'pear.php.net') { + return 'pear.php.net'; } - if (isset($this->_packageInfo['contents']['file'])) { - $this->_filelistCannotContainFile('contents'); - return false; + + if ($channel == 'pecl.php.net') { + return 'pecl.php.net'; } - } - $this->_validateMaintainers(); - $this->_validateStabilityVersion(); - $fail = false; - if (array_key_exists('usesrole', $this->_packageInfo)) { - $roles = $this->_packageInfo['usesrole']; - if (!is_array($roles) || !isset($roles[0])) { - $roles = array($roles); + + if ($channel == 'doc.php.net') { + return 'doc.php.net'; } - foreach ($roles as $role) { - if (!isset($role['role'])) { - $this->_usesroletaskMustHaveRoleTask('usesrole', 'role'); - $fail = true; - } else { - if (!isset($role['channel'])) { - if (!isset($role['uri'])) { - $this->_usesroletaskMustHaveChannelOrUri($role['role'], 'usesrole'); - $fail = true; - } - } elseif (!isset($role['package'])) { - $this->_usesroletaskMustHavePackage($role['role'], 'usesrole'); - $fail = true; - } - } + + if ($channel == '__uri') { + return '__uri'; } + + return false; } - if (array_key_exists('usestask', $this->_packageInfo)) { - $roles = $this->_packageInfo['usestask']; - if (!is_array($roles) || !isset($roles[0])) { - $roles = array($roles); + + $channel = strtolower($channel); + if (file_exists($this->_getChannelAliasFileName($channel))) { + // translate an alias to an actual channel + return implode('', file($this->_getChannelAliasFileName($channel))); + } + + return $channel; + } + + /** + * Get the alias of a channel from its alias or its name + */ + function _getAlias($channel) + { + if (!$this->_channelExists($channel)) { + if ($channel == 'pear.php.net') { + return 'pear'; } - foreach ($roles as $role) { - if (!isset($role['task'])) { - $this->_usesroletaskMustHaveRoleTask('usestask', 'task'); - $fail = true; - } else { - if (!isset($role['channel'])) { - if (!isset($role['uri'])) { - $this->_usesroletaskMustHaveChannelOrUri($role['task'], 'usestask'); - $fail = true; - } - } elseif (!isset($role['package'])) { - $this->_usesroletaskMustHavePackage($role['task'], 'usestask'); - $fail = true; - } - } + + if ($channel == 'pecl.php.net') { + return 'pecl'; + } + + if ($channel == 'doc.php.net') { + return 'phpdocs'; } - } - if ($fail) { return false; } - $list = $this->_packageInfo['contents']; - if (isset($list['dir']) && is_array($list['dir']) && isset($list['dir'][0])) { - $this->_multipleToplevelDirNotAllowed(); - return $this->_isValid = 0; + $channel = $this->_getChannel($channel); + if (PEAR::isError($channel)) { + return $channel; } - $this->_validateFilelist(); - $this->_validateRelease(); - if (!$this->_stack->hasErrors()) { - $chan = $this->_pf->_registry->getChannel($this->_pf->getChannel(), true); - if (PEAR::isError($chan)) { - $this->_unknownChannel($this->_pf->getChannel()); - } else { - $valpack = $chan->getValidationPackage(); - // for channel validator packages, always use the default PEAR validator. - // otherwise, they can't be installed or packaged - $validator = $chan->getValidationObject($this->_pf->getPackage()); - if (!$validator) { - $this->_stack->push(__FUNCTION__, 'error', - array_merge( - array('channel' => $chan->getName(), - 'package' => $this->_pf->getPackage()), - $valpack - ), - 'package "%channel%/%package%" cannot be properly validated without ' . - 'validation package "%channel%/%name%-%version%"'); - return $this->_isValid = 0; - } - $validator->setPackageFile($this->_pf); - $validator->validate($state); - $failures = $validator->getFailures(); - foreach ($failures['errors'] as $error) { - $this->_stack->push(__FUNCTION__, 'error', $error, - 'Channel validator error: field "%field%" - %reason%'); - } - foreach ($failures['warnings'] as $warning) { - $this->_stack->push(__FUNCTION__, 'warning', $warning, - 'Channel validator warning: field "%field%" - %reason%'); - } - } + return $channel->getAlias(); + } + + /** + * Get the name of the file where data for a given package is stored. + * + * @param string channel name, or false if this is a PEAR package + * @param string package name + * + * @return string registry file name + * + * @access public + */ + function _channelDirectoryName($channel) + { + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { + return $this->statedir; } - $this->_pf->_isValid = $this->_isValid = !$this->_stack->hasErrors('error'); - if ($this->_isValid && $state == PEAR_VALIDATE_PACKAGING && !$this->_filesValid) { - if ($this->_pf->getPackageType() == 'bundle') { - if ($this->_analyzeBundledPackages()) { - $this->_filesValid = $this->_pf->_filesValid = true; - } else { - $this->_pf->_isValid = $this->_isValid = 0; - } - } else { - if (!$this->_analyzePhpFiles()) { - $this->_pf->_isValid = $this->_isValid = 0; - } else { - $this->_filesValid = $this->_pf->_filesValid = true; - } - } + $ch = $this->_getChannelFromAlias($channel); + if (!$ch) { + $ch = $channel; } - if ($this->_isValid) { - return $this->_pf->_isValid = $this->_isValid = $state; + return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' . + str_replace('/', '_', $ch)); + } + + function _openPackageFile($package, $mode, $channel = false) + { + if (!$this->_assertStateDir($channel)) { + return null; } - return $this->_pf->_isValid = $this->_isValid = 0; + if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { + return null; + } + + $file = $this->_packageFileName($package, $channel); + if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { + return null; + } + + $fp = @fopen($file, $mode); + if (!$fp) { + return null; + } + + return $fp; } - function _stupidSchemaValidate($structure, $xml, $root) + function _closePackageFile($fp) { - if (!is_array($xml)) { - $xml = array(); + fclose($fp); + } + + function _openChannelFile($channel, $mode) + { + if (!$this->_assertChannelDir()) { + return null; } - $keys = array_keys($xml); - reset($keys); - $key = current($keys); - while ($key == 'attribs' || $key == '_contents') { - $key = next($keys); + + if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { + return null; } - $unfoundtags = $optionaltags = array(); - $ret = true; - $mismatch = false; - foreach ($structure as $struc) { - if ($key) { - $tag = $xml[$key]; - } - $test = $this->_processStructure($struc); - if (isset($test['choices'])) { - $loose = true; - foreach ($test['choices'] as $choice) { - if ($key == $choice['tag']) { - $key = next($keys); - while ($key == 'attribs' || $key == '_contents') { - $key = next($keys); - } - $unfoundtags = $optionaltags = array(); - $mismatch = false; - if ($key && $key != $choice['tag'] && isset($choice['multiple'])) { - $unfoundtags[] = $choice['tag']; - $optionaltags[] = $choice['tag']; - if ($key) { - $mismatch = true; - } - } - $ret &= $this->_processAttribs($choice, $tag, $root); - continue 2; - } else { - $unfoundtags[] = $choice['tag']; - $mismatch = true; + + $file = $this->_channelFileName($channel); + if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { + return null; + } + + $fp = @fopen($file, $mode); + if (!$fp) { + return null; + } + + return $fp; + } + + function _closeChannelFile($fp) + { + fclose($fp); + } + + function _rebuildFileMap() + { + if (!class_exists('PEAR_Installer_Role')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role.php'; + } + + $channels = $this->_listAllPackages(); + $files = array(); + foreach ($channels as $channel => $packages) { + foreach ($packages as $package) { + $version = $this->_packageInfo($package, 'version', $channel); + $filelist = $this->_packageInfo($package, 'filelist', $channel); + if (!is_array($filelist)) { + continue; + } + + foreach ($filelist as $name => $attrs) { + if (isset($attrs['attribs'])) { + $attrs = $attrs['attribs']; } - if (!isset($choice['multiple']) || $choice['multiple'] != '*') { - $loose = false; + + // it is possible for conflicting packages in different channels to + // conflict with data files/doc files + if ($name == 'dirtree') { + continue; + } + + if (isset($attrs['role']) && !in_array($attrs['role'], + PEAR_Installer_Role::getInstallableRoles())) { + // these are not installed + continue; + } + + if (isset($attrs['role']) && !in_array($attrs['role'], + PEAR_Installer_Role::getBaseinstallRoles())) { + $attrs['baseinstalldir'] = $package; + } + + if (isset($attrs['baseinstalldir'])) { + $file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name; } else { - $optionaltags[] = $choice['tag']; + $file = $name; } - } - if (!$loose) { - $this->_invalidTagOrder($unfoundtags, $key, $root); - return false; - } - } else { - if ($key != $test['tag']) { - if (isset($test['multiple']) && $test['multiple'] != '*') { - $unfoundtags[] = $test['tag']; - $this->_invalidTagOrder($unfoundtags, $key, $root); - return false; + + $file = preg_replace(',^/+,', '', $file); + if ($channel != 'pear.php.net') { + if (!isset($files[$attrs['role']])) { + $files[$attrs['role']] = array(); + } + $files[$attrs['role']][$file] = array(strtolower($channel), + strtolower($package)); } else { - if ($key) { - $mismatch = true; + if (!isset($files[$attrs['role']])) { + $files[$attrs['role']] = array(); } - $unfoundtags[] = $test['tag']; - $optionaltags[] = $test['tag']; - } - if (!isset($test['multiple'])) { - $this->_invalidTagOrder($unfoundtags, $key, $root); - return false; + $files[$attrs['role']][$file] = strtolower($package); } - continue; - } else { - $unfoundtags = $optionaltags = array(); - $mismatch = false; - } - $key = next($keys); - while ($key == 'attribs' || $key == '_contents') { - $key = next($keys); - } - if ($key && $key != $test['tag'] && isset($test['multiple'])) { - $unfoundtags[] = $test['tag']; - $optionaltags[] = $test['tag']; - $mismatch = true; } - $ret &= $this->_processAttribs($test, $tag, $root); - continue; } } - if (!$mismatch && count($optionaltags)) { - // don't error out on any optional tags - $unfoundtags = array_diff($unfoundtags, $optionaltags); + + + $this->_assertStateDir(); + if (!$this->hasWriteAccess()) { + return false; } - if (count($unfoundtags)) { - $this->_invalidTagOrder($unfoundtags, $key, $root); - } elseif ($key) { - // unknown tags - $this->_invalidTagOrder('*no tags allowed here*', $key, $root); - while ($key = next($keys)) { - $this->_invalidTagOrder('*no tags allowed here*', $key, $root); - } + + $fp = @fopen($this->filemap, 'wb'); + if (!$fp) { + return false; } - return $ret; + + $this->filemap_cache = $files; + fwrite($fp, serialize($files)); + fclose($fp); + return true; } - function _processAttribs($choice, $tag, $context) + function _readFileMap() { - if (isset($choice['attribs'])) { - if (!is_array($tag)) { - $tag = array($tag); + if (!file_exists($this->filemap)) { + return array(); + } + + $fp = @fopen($this->filemap, 'r'); + if (!$fp) { + return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg); + } + + clearstatcache(); + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + $fsize = filesize($this->filemap); + fclose($fp); + $data = file_get_contents($this->filemap); + set_magic_quotes_runtime($rt); + $tmp = unserialize($data); + if (!$tmp && $fsize > 7) { + return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data); + } + + $this->filemap_cache = $tmp; + return true; + } + + /** + * Lock the registry. + * + * @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN. + * See flock manual for more information. + * + * @return bool TRUE on success, FALSE if locking failed, or a + * PEAR error if some other error occurs (such as the + * lock file not being writable). + * + * @access private + */ + function _lock($mode = LOCK_EX) + { + if (stristr(php_uname(), 'Windows 9')) { + return true; + } + + if ($mode != LOCK_UN && is_resource($this->lock_fp)) { + // XXX does not check type of lock (LOCK_SH/LOCK_EX) + return true; + } + + if (!$this->_assertStateDir()) { + if ($mode == LOCK_EX) { + return $this->raiseError('Registry directory is not writeable by the current user'); } - $tags = $tag; - if (!isset($tags[0])) { - $tags = array($tags); + + return true; + } + + $open_mode = 'w'; + // XXX People reported problems with LOCK_SH and 'w' + if ($mode === LOCK_SH || $mode === LOCK_UN) { + if (!file_exists($this->lockfile)) { + touch($this->lockfile); } - $ret = true; - foreach ($tags as $i => $tag) { - if (!is_array($tag) || !isset($tag['attribs'])) { - foreach ($choice['attribs'] as $attrib) { - if ($attrib{0} != '?') { - $ret &= $this->_tagHasNoAttribs($choice['tag'], - $context); - continue 2; - } - } - } - foreach ($choice['attribs'] as $attrib) { - if ($attrib{0} != '?') { - if (!isset($tag['attribs'][$attrib])) { - $ret &= $this->_tagMissingAttribute($choice['tag'], - $attrib, $context); - } - } - } + $open_mode = 'r'; + } + + if (!is_resource($this->lock_fp)) { + $this->lock_fp = @fopen($this->lockfile, $open_mode); + } + + if (!is_resource($this->lock_fp)) { + $this->lock_fp = null; + return $this->raiseError("could not create lock file" . + (isset($php_errormsg) ? ": " . $php_errormsg : "")); + } + + if (!(int)flock($this->lock_fp, $mode)) { + switch ($mode) { + case LOCK_SH: $str = 'shared'; break; + case LOCK_EX: $str = 'exclusive'; break; + case LOCK_UN: $str = 'unlock'; break; + default: $str = 'unknown'; break; } - return $ret; + + //is resource at this point, close it on error. + fclose($this->lock_fp); + $this->lock_fp = null; + return $this->raiseError("could not acquire $str lock ($this->lockfile)", + PEAR_REGISTRY_ERROR_LOCK); } + return true; } - function _processStructure($key) + function _unlock() { - $ret = array(); - if (count($pieces = explode('|', $key)) > 1) { - $ret['choices'] = array(); - foreach ($pieces as $piece) { - $ret['choices'][] = $this->_processStructure($piece); - } - return $ret; - } - $multi = $key{0}; - if ($multi == '+' || $multi == '*') { - $ret['multiple'] = $key{0}; - $key = substr($key, 1); - } - if (count($attrs = explode('->', $key)) > 1) { - $ret['tag'] = array_shift($attrs); - $ret['attribs'] = $attrs; - } else { - $ret['tag'] = $key; + $ret = $this->_lock(LOCK_UN); + if (is_resource($this->lock_fp)) { + fclose($this->lock_fp); } + + $this->lock_fp = null; return $ret; } - function _validateStabilityVersion() + function _packageExists($package, $channel = false) { - $structure = array('release', 'api'); - $a = $this->_stupidSchemaValidate($structure, $this->_packageInfo['version'], ''); - $a &= $this->_stupidSchemaValidate($structure, $this->_packageInfo['stability'], ''); - if ($a) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $this->_packageInfo['version']['release'])) { - $this->_invalidVersion('release', $this->_packageInfo['version']['release']); - } - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $this->_packageInfo['version']['api'])) { - $this->_invalidVersion('api', $this->_packageInfo['version']['api']); - } - if (!in_array($this->_packageInfo['stability']['release'], - array('snapshot', 'devel', 'alpha', 'beta', 'stable'))) { - $this->_invalidState('release', $this->_packageInfo['stability']['release']); - } - if (!in_array($this->_packageInfo['stability']['api'], - array('devel', 'alpha', 'beta', 'stable'))) { - $this->_invalidState('api', $this->_packageInfo['stability']['api']); - } - } + return file_exists($this->_packageFileName($package, $channel)); } - function _validateMaintainers() + /** + * Determine whether a channel exists in the registry + * + * @param string Channel name + * @param bool if true, then aliases will be ignored + * @return boolean + */ + function _channelExists($channel, $noaliases = false) { - $structure = - array( - 'name', - 'user', - 'email', - 'active', - ); - foreach (array('lead', 'developer', 'contributor', 'helper') as $type) { - if (!isset($this->_packageInfo[$type])) { - continue; - } - if (isset($this->_packageInfo[$type][0])) { - foreach ($this->_packageInfo[$type] as $lead) { - $this->_stupidSchemaValidate($structure, $lead, '<' . $type . '>'); - } - } else { - $this->_stupidSchemaValidate($structure, $this->_packageInfo[$type], - '<' . $type . '>'); - } + $a = file_exists($this->_channelFileName($channel, $noaliases)); + if (!$a && $channel == 'pear.php.net') { + return true; } + + if (!$a && $channel == 'pecl.php.net') { + return true; + } + + if (!$a && $channel == 'doc.php.net') { + return true; + } + + return $a; } - function _validatePhpDep($dep, $installcondition = false) + /** + * Determine whether a mirror exists within the deafult channel in the registry + * + * @param string Channel name + * @param string Mirror name + * + * @return boolean + */ + function _mirrorExists($channel, $mirror) { - $structure = array( - 'min', - '*max', - '*exclude', - ); - $type = $installcondition ? '' : ''; - $this->_stupidSchemaValidate($structure, $dep, $type); - if (isset($dep['min'])) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/', - $dep['min'])) { - $this->_invalidVersion($type . '', $dep['min']); - } - } - if (isset($dep['max'])) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/', - $dep['max'])) { - $this->_invalidVersion($type . '', $dep['max']); - } + $data = $this->_channelInfo($channel); + if (!isset($data['servers']['mirror'])) { + return false; } - if (isset($dep['exclude'])) { - if (!is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); - } - foreach ($dep['exclude'] as $exclude) { - if (!preg_match( - '/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?(?:-[a-zA-Z0-9]+)?\\z/', - $exclude)) { - $this->_invalidVersion($type . '', $exclude); - } + + foreach ($data['servers']['mirror'] as $m) { + if ($m['attribs']['host'] == $mirror) { + return true; } } + + return false; } - function _validatePearinstallerDep($dep) + /** + * @param PEAR_ChannelFile Channel object + * @param donotuse + * @param string Last-Modified HTTP tag from remote request + * @return boolean|PEAR_Error True on creation, false if it already exists + */ + function _addChannel($channel, $update = false, $lastmodified = false) { - $structure = array( - 'min', - '*max', - '*recommended', - '*exclude', - ); - $this->_stupidSchemaValidate($structure, $dep, ''); - if (isset($dep['min'])) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $dep['min'])) { - $this->_invalidVersion('', - $dep['min']); - } - } - if (isset($dep['max'])) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $dep['max'])) { - $this->_invalidVersion('', - $dep['max']); - } + if (!is_a($channel, 'PEAR_ChannelFile')) { + return false; } - if (isset($dep['recommended'])) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $dep['recommended'])) { - $this->_invalidVersion('', - $dep['recommended']); - } + + if (!$channel->validate()) { + return false; } - if (isset($dep['exclude'])) { - if (!is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); + + if (file_exists($this->_channelFileName($channel->getName()))) { + if (!$update) { + return false; } - foreach ($dep['exclude'] as $exclude) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $exclude)) { - $this->_invalidVersion('', - $exclude); - } + + $checker = $this->_getChannel($channel->getName()); + if (PEAR::isError($checker)) { + return $checker; } - } - } - function _validatePackageDep($dep, $group, $type = '') - { - if (isset($dep['uri'])) { - if (isset($dep['conflicts'])) { - $structure = array( - 'name', - 'uri', - 'conflicts', - '*providesextension', - ); - } else { - $structure = array( - 'name', - 'uri', - '*providesextension', - ); + if ($channel->getAlias() != $checker->getAlias()) { + if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) { + @unlink($this->_getChannelAliasFileName($checker->getAlias())); + } } } else { - if (isset($dep['conflicts'])) { - $structure = array( - 'name', - 'channel', - '*min', - '*max', - '*exclude', - 'conflicts', - '*providesextension', - ); - } else { - $structure = array( - 'name', - 'channel', - '*min', - '*max', - '*recommended', - '*exclude', - '*nodefault', - '*providesextension', - ); + if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net', 'doc.php.net'))) { + return false; } } - if (isset($dep['name'])) { - $type .= '' . $dep['name'] . ''; - } - $this->_stupidSchemaValidate($structure, $dep, '' . $group . $type); - if (isset($dep['uri']) && (isset($dep['min']) || isset($dep['max']) || - isset($dep['recommended']) || isset($dep['exclude']))) { - $this->_uriDepsCannotHaveVersioning('' . $group . $type); + + $ret = $this->_assertChannelDir(); + if (PEAR::isError($ret)) { + return $ret; } - if (isset($dep['channel']) && strtolower($dep['channel']) == '__uri') { - $this->_DepchannelCannotBeUri('' . $group . $type); + + $ret = $this->_assertChannelStateDir($channel->getName()); + if (PEAR::isError($ret)) { + return $ret; } - if (isset($dep['min'])) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $dep['min'])) { - $this->_invalidVersion('' . $group . $type . '', $dep['min']); + + if ($channel->getAlias() != $channel->getName()) { + if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) && + $this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) { + $channel->setAlias($channel->getName()); } - } - if (isset($dep['max'])) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $dep['max'])) { - $this->_invalidVersion('' . $group . $type . '', $dep['max']); + + if (!$this->hasWriteAccess()) { + return false; } - } - if (isset($dep['recommended'])) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $dep['recommended'])) { - $this->_invalidVersion('' . $group . $type . '', - $dep['recommended']); + + $fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w'); + if (!$fp) { + return false; } + + fwrite($fp, $channel->getName()); + fclose($fp); } - if (isset($dep['exclude'])) { - if (!is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); - } - foreach ($dep['exclude'] as $exclude) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $exclude)) { - $this->_invalidVersion('' . $group . $type . '', - $exclude); - } - } + + if (!$this->hasWriteAccess()) { + return false; } - } - function _validateSubpackageDep($dep, $group) - { - $this->_validatePackageDep($dep, $group, ''); - if (isset($dep['providesextension'])) { - $this->_subpackageCannotProvideExtension(isset($dep['name']) ? $dep['name'] : ''); + $fp = @fopen($this->_channelFileName($channel->getName()), 'wb'); + if (!$fp) { + return false; } - if (isset($dep['conflicts'])) { - $this->_subpackagesCannotConflict(isset($dep['name']) ? $dep['name'] : ''); + + $info = $channel->toArray(); + if ($lastmodified) { + $info['_lastmodified'] = $lastmodified; + } else { + $info['_lastmodified'] = date('r'); } + + fwrite($fp, serialize($info)); + fclose($fp); + return true; } - function _validateExtensionDep($dep, $group = false, $installcondition = false) + /** + * Deletion fails if there are any packages installed from the channel + * @param string|PEAR_ChannelFile channel name + * @return boolean|PEAR_Error True on deletion, false if it doesn't exist + */ + function _deleteChannel($channel) { - if (isset($dep['conflicts'])) { - $structure = array( - 'name', - '*min', - '*max', - '*exclude', - 'conflicts', - ); - } else { - $structure = array( - 'name', - '*min', - '*max', - '*recommended', - '*exclude', - ); - } - if ($installcondition) { - $type = ''; - } else { - $type = '' . $group . ''; - } - if (isset($dep['name'])) { - $type .= '' . $dep['name'] . ''; - } - $this->_stupidSchemaValidate($structure, $dep, $type); - if (isset($dep['min'])) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $dep['min'])) { - $this->_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . 'validate()) { + return false; } + $channel = $channel->getName(); } - if (isset($dep['recommended'])) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $dep['recommended'])) { - $this->_invalidVersion(substr($type, 1) . '_getChannelFromAlias($channel) == '__uri') { + return false; } - if (isset($dep['exclude'])) { - if (!is_array($dep['exclude'])) { - $dep['exclude'] = array($dep['exclude']); - } - foreach ($dep['exclude'] as $exclude) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $exclude)) { - $this->_invalidVersion(substr($type, 1) . '_getChannelFromAlias($channel) == 'pecl.php.net') { + return false; } - } - function _validateOsDep($dep, $installcondition = false) - { - $structure = array( - 'name', - '*conflicts', - ); - $type = $installcondition ? '' : ''; - if ($this->_stupidSchemaValidate($structure, $dep, $type)) { - if ($dep['name'] == '*') { - if (array_key_exists('conflicts', $dep)) { - $this->_cannotConflictWithAllOs($type); - } - } + if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { + return false; } - } - function _validateArchDep($dep, $installcondition = false) - { - $structure = array( - 'pattern', - '*conflicts', - ); - $type = $installcondition ? '' : ''; - $this->_stupidSchemaValidate($structure, $dep, $type); - } + if (!$this->_channelExists($channel)) { + return false; + } - function _validateInstallConditions($cond, $release) - { - $structure = array( - '*php', - '*extension', - '*os', - '*arch', - ); - if (!$this->_stupidSchemaValidate($structure, - $cond, $release)) { + if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { return false; } - foreach (array('php', 'extension', 'os', 'arch') as $type) { - if (isset($cond[$type])) { - $iter = $cond[$type]; - if (!is_array($iter) || !isset($iter[0])) { - $iter = array($iter); - } - foreach ($iter as $package) { - if ($type == 'extension') { - $this->{"_validate{$type}Dep"}($package, false, true); - } else { - $this->{"_validate{$type}Dep"}($package, true); - } - } - } + + $channel = $this->_getChannelFromAlias($channel); + if ($channel == 'pear.php.net') { + return false; } - } - function _validateDependencies() - { - $structure = array( - 'required', - '*optional', - '*group->name->hint' - ); - if (!$this->_stupidSchemaValidate($structure, - $this->_packageInfo['dependencies'], '')) { + $test = $this->_listChannelPackages($channel); + if (count($test)) { return false; } - foreach (array('required', 'optional') as $simpledep) { - if (isset($this->_packageInfo['dependencies'][$simpledep])) { - if ($simpledep == 'optional') { - $structure = array( - '*package', - '*subpackage', - '*extension', - ); - } else { - $structure = array( - 'php', - 'pearinstaller', - '*package', - '*subpackage', - '*extension', - '*os', - '*arch', - ); - } - if ($this->_stupidSchemaValidate($structure, - $this->_packageInfo['dependencies'][$simpledep], - "<$simpledep>")) { - foreach (array('package', 'subpackage', 'extension') as $type) { - if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) { - $iter = $this->_packageInfo['dependencies'][$simpledep][$type]; - if (!isset($iter[0])) { - $iter = array($iter); - } - foreach ($iter as $package) { - if ($type != 'extension') { - if (isset($package['uri'])) { - if (isset($package['channel'])) { - $this->_UrlOrChannel($type, - $package['name']); - } - } else { - if (!isset($package['channel'])) { - $this->_NoChannel($type, $package['name']); - } - } - } - $this->{"_validate{$type}Dep"}($package, "<$simpledep>"); - } - } - } - if ($simpledep == 'optional') { - continue; - } - foreach (array('php', 'pearinstaller', 'os', 'arch') as $type) { - if (isset($this->_packageInfo['dependencies'][$simpledep][$type])) { - $iter = $this->_packageInfo['dependencies'][$simpledep][$type]; - if (!isset($iter[0])) { - $iter = array($iter); - } - foreach ($iter as $package) { - $this->{"_validate{$type}Dep"}($package); - } - } - } - } - } + + $test = @rmdir($this->_channelDirectoryName($channel)); + if (!$test) { + return false; } - if (isset($this->_packageInfo['dependencies']['group'])) { - $groups = $this->_packageInfo['dependencies']['group']; - if (!isset($groups[0])) { - $groups = array($groups); - } - $structure = array( - '*package', - '*subpackage', - '*extension', - ); - foreach ($groups as $group) { - if ($this->_stupidSchemaValidate($structure, $group, '')) { - if (!PEAR_Validate::validGroupName($group['attribs']['name'])) { - $this->_invalidDepGroupName($group['attribs']['name']); - } - foreach (array('package', 'subpackage', 'extension') as $type) { - if (isset($group[$type])) { - $iter = $group[$type]; - if (!isset($iter[0])) { - $iter = array($iter); - } - foreach ($iter as $package) { - if ($type != 'extension') { - if (isset($package['uri'])) { - if (isset($package['channel'])) { - $this->_UrlOrChannelGroup($type, - $package['name'], - $group['name']); - } - } else { - if (!isset($package['channel'])) { - $this->_NoChannelGroup($type, - $package['name'], - $group['name']); - } - } - } - $this->{"_validate{$type}Dep"}($package, ''); - } - } - } - } + + $file = $this->_getChannelAliasFileName($this->_getAlias($channel)); + if (file_exists($file)) { + $test = @unlink($file); + if (!$test) { + return false; } } + + $file = $this->_channelFileName($channel); + $ret = true; + if (file_exists($file)) { + $ret = @unlink($file); + } + + return $ret; } - function _validateCompatible() + /** + * Determine whether a channel exists in the registry + * @param string Channel Alias + * @return boolean + */ + function _isChannelAlias($alias) { - $compat = $this->_packageInfo['compatible']; - if (!isset($compat[0])) { - $compat = array($compat); - } - $required = array('name', 'channel', 'min', 'max', '*exclude'); - foreach ($compat as $package) { - $type = ''; - if (is_array($package) && array_key_exists('name', $package)) { - $type .= '' . $package['name'] . ''; - } - $this->_stupidSchemaValidate($required, $package, $type); - if (is_array($package) && array_key_exists('min', $package)) { - if (!preg_match('/^\d+(?:\.\d+)*(?:[a-zA-Z]+\d*)?\\z/', - $package['min'])) { - $this->_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_invalidVersion(substr($type, 1) . '_getChannelAliasFileName($alias)); + } + + /** + * @param string|null + * @param string|null + * @param string|null + * @return array|null + * @access private + */ + function _packageInfo($package = null, $key = null, $channel = 'pear.php.net') + { + if ($package === null) { + if ($channel === null) { + $channels = $this->_listChannels(); + $ret = array(); + foreach ($channels as $channel) { + $channel = strtolower($channel); + $ret[$channel] = array(); + $packages = $this->_listPackages($channel); + foreach ($packages as $package) { + $ret[$channel][] = $this->_packageInfo($package, null, $channel); } } + + return $ret; + } + + $ps = $this->_listPackages($channel); + if (!count($ps)) { + return array(); } + return array_map(array(&$this, '_packageInfo'), + $ps, array_fill(0, count($ps), null), + array_fill(0, count($ps), $channel)); + } + + $fp = $this->_openPackageFile($package, 'r', $channel); + if ($fp === null) { + return null; + } + + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + clearstatcache(); + $this->_closePackageFile($fp); + $data = file_get_contents($this->_packageFileName($package, $channel)); + set_magic_quotes_runtime($rt); + $data = unserialize($data); + if ($key === null) { + return $data; + } + + // compatibility for package.xml version 2.0 + if (isset($data['old'][$key])) { + return $data['old'][$key]; + } + + if (isset($data[$key])) { + return $data[$key]; } + + return null; } - function _validateBundle($list) + /** + * @param string Channel name + * @param bool whether to strictly retrieve info of channels, not just aliases + * @return array|null + */ + function _channelInfo($channel, $noaliases = false) { - if (!is_array($list) || !isset($list['bundledpackage'])) { - return $this->_NoBundledPackages(); + if (!$this->_channelExists($channel, $noaliases)) { + return null; } - if (!is_array($list['bundledpackage']) || !isset($list['bundledpackage'][0])) { - return $this->_AtLeast2BundledPackages(); + + $fp = $this->_openChannelFile($channel, 'r'); + if ($fp === null) { + return null; } - foreach ($list['bundledpackage'] as $package) { - if (!is_string($package)) { - $this->_bundledPackagesMustBeFilename(); + + $rt = get_magic_quotes_runtime(); + set_magic_quotes_runtime(0); + clearstatcache(); + $this->_closeChannelFile($fp); + $data = file_get_contents($this->_channelFileName($channel)); + set_magic_quotes_runtime($rt); + $data = unserialize($data); + return $data; + } + + function _listChannels() + { + $channellist = array(); + if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) { + return array('pear.php.net', 'pecl.php.net', 'doc.php.net', '__uri'); + } + + $dp = opendir($this->channelsdir); + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; } + + if ($ent == '__uri.reg') { + $channellist[] = '__uri'; + continue; + } + + $channellist[] = str_replace('_', '/', substr($ent, 0, -4)); + } + + closedir($dp); + if (!in_array('pear.php.net', $channellist)) { + $channellist[] = 'pear.php.net'; + } + + if (!in_array('pecl.php.net', $channellist)) { + $channellist[] = 'pecl.php.net'; + } + + if (!in_array('doc.php.net', $channellist)) { + $channellist[] = 'doc.php.net'; + } + + + if (!in_array('__uri', $channellist)) { + $channellist[] = '__uri'; } + + natsort($channellist); + return $channellist; } - function _validateFilelist($list = false, $allowignore = false, $dirs = '') + function _listPackages($channel = false) { - $iscontents = false; - if (!$list) { - $iscontents = true; - $list = $this->_packageInfo['contents']; - if (isset($this->_packageInfo['bundle'])) { - return $this->_validateBundle($list); - } + if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { + return $this->_listChannelPackages($channel); } - if ($allowignore) { - $struc = array( - '*install->name->as', - '*ignore->name' - ); - } else { - $struc = array( - '*dir->name->?baseinstalldir', - '*file->name->role->?baseinstalldir->?md5sum' - ); - if (isset($list['dir']) && isset($list['file'])) { - // stave off validation errors without requiring a set order. - $_old = $list; - if (isset($list['attribs'])) { - $list = array('attribs' => $_old['attribs']); - } - $list['dir'] = $_old['dir']; - $list['file'] = $_old['file']; - } + + if (!file_exists($this->statedir) || !is_dir($this->statedir)) { + return array(); } - if (!isset($list['attribs']) || !isset($list['attribs']['name'])) { - $unknown = $allowignore ? '' : ''; - $dirname = $iscontents ? '' : $unknown; - } else { - $dirname = ''; - if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', - str_replace('\\', '/', $list['attribs']['name']))) { - // file contains .. parent directory or . cur directory - $this->_invalidDirName($list['attribs']['name']); - } + + $pkglist = array(); + $dp = opendir($this->statedir); + if (!$dp) { + return $pkglist; } - $res = $this->_stupidSchemaValidate($struc, $list, $dirname); - if ($allowignore && $res) { - $ignored_or_installed = array(); - $this->_pf->getFilelist(); - $fcontents = $this->_pf->getContents(); - $filelist = array(); - if (!isset($fcontents['dir']['file'][0])) { - $fcontents['dir']['file'] = array($fcontents['dir']['file']); - } - foreach ($fcontents['dir']['file'] as $file) { - $filelist[$file['attribs']['name']] = true; - } - if (isset($list['install'])) { - if (!isset($list['install'][0])) { - $list['install'] = array($list['install']); - } - foreach ($list['install'] as $file) { - if (!isset($filelist[$file['attribs']['name']])) { - $this->_notInContents($file['attribs']['name'], 'install'); - continue; - } - if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) { - $this->_multipleInstallAs($file['attribs']['name']); - } - if (!isset($ignored_or_installed[$file['attribs']['name']])) { - $ignored_or_installed[$file['attribs']['name']] = array(); - } - $ignored_or_installed[$file['attribs']['name']][] = 1; - if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', - str_replace('\\', '/', $file['attribs']['as']))) { - // file contains .. parent directory or . cur directory references - $this->_invalidFileInstallAs($file['attribs']['name'], - $file['attribs']['as']); - } - } - } - if (isset($list['ignore'])) { - if (!isset($list['ignore'][0])) { - $list['ignore'] = array($list['ignore']); - } - foreach ($list['ignore'] as $file) { - if (!isset($filelist[$file['attribs']['name']])) { - $this->_notInContents($file['attribs']['name'], 'ignore'); - continue; - } - if (array_key_exists($file['attribs']['name'], $ignored_or_installed)) { - $this->_ignoreAndInstallAs($file['attribs']['name']); - } - } + + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; } + + $pkglist[] = substr($ent, 0, -4); } - if (!$allowignore && isset($list['file'])) { - if (is_string($list['file'])) { - $this->_oldStyleFileNotAllowed(); - return false; - } - if (!isset($list['file'][0])) { - // single file - $list['file'] = array($list['file']); - } - foreach ($list['file'] as $i => $file) - { - if (isset($file['attribs']) && isset($file['attribs']['name'])) { - if ($file['attribs']['name']{0} == '.' && - $file['attribs']['name']{1} == '/') { - // name is something like "./doc/whatever.txt" - $this->_invalidFileName($file['attribs']['name'], $dirname); - } - if (preg_match('~/\.\.?(/|\\z)|^\.\.?/~', - str_replace('\\', '/', $file['attribs']['name']))) { - // file contains .. parent directory or . cur directory - $this->_invalidFileName($file['attribs']['name'], $dirname); - } - } - if (isset($file['attribs']) && isset($file['attribs']['role'])) { - if (!$this->_validateRole($file['attribs']['role'])) { - if (isset($this->_packageInfo['usesrole'])) { - $roles = $this->_packageInfo['usesrole']; - if (!isset($roles[0])) { - $roles = array($roles); - } - foreach ($roles as $role) { - if ($role['role'] = $file['attribs']['role']) { - $msg = 'This package contains role "%role%" and requires ' . - 'package "%package%" to be used'; - if (isset($role['uri'])) { - $params = array('role' => $role['role'], - 'package' => $role['uri']); - } else { - $params = array('role' => $role['role'], - 'package' => $this->_pf->_registry-> - parsedPackageNameToString(array('package' => - $role['package'], 'channel' => $role['channel']), - true)); - } - $this->_stack->push('_mustInstallRole', 'error', $params, $msg); - } - } - } - $this->_invalidFileRole($file['attribs']['name'], - $dirname, $file['attribs']['role']); - } - } - if (!isset($file['attribs'])) { - continue; - } - $save = $file['attribs']; - if ($dirs) { - $save['name'] = $dirs . '/' . $save['name']; - } - unset($file['attribs']); - if (count($file) && $this->_curState != PEAR_VALIDATE_DOWNLOADING) { // has tasks - foreach ($file as $task => $value) { - if ($tagClass = $this->_pf->getTask($task)) { - if (!is_array($value) || !isset($value[0])) { - $value = array($value); - } - foreach ($value as $v) { - $ret = call_user_func(array($tagClass, 'validateXml'), - $this->_pf, $v, $this->_pf->_config, $save); - if (is_array($ret)) { - $this->_invalidTask($task, $ret, isset($save['name']) ? - $save['name'] : ''); - } - } - } else { - if (isset($this->_packageInfo['usestask'])) { - $roles = $this->_packageInfo['usestask']; - if (!isset($roles[0])) { - $roles = array($roles); - } - foreach ($roles as $role) { - if ($role['task'] = $task) { - $msg = 'This package contains task "%task%" and requires ' . - 'package "%package%" to be used'; - if (isset($role['uri'])) { - $params = array('task' => $role['task'], - 'package' => $role['uri']); - } else { - $params = array('task' => $role['task'], - 'package' => $this->_pf->_registry-> - parsedPackageNameToString(array('package' => - $role['package'], 'channel' => $role['channel']), - true)); - } - $this->_stack->push('_mustInstallTask', 'error', - $params, $msg); - } - } - } - $this->_unknownTask($task, $save['name']); - } - } - } - } + closedir($dp); + return $pkglist; + } + + function _listChannelPackages($channel) + { + $pkglist = array(); + if (!file_exists($this->_channelDirectoryName($channel)) || + !is_dir($this->_channelDirectoryName($channel))) { + return array(); } - if (isset($list['ignore'])) { - if (!$allowignore) { - $this->_ignoreNotAllowed('ignore'); - } + + $dp = opendir($this->_channelDirectoryName($channel)); + if (!$dp) { + return $pkglist; } - if (isset($list['install'])) { - if (!$allowignore) { - $this->_ignoreNotAllowed('install'); + + while ($ent = readdir($dp)) { + if ($ent{0} == '.' || substr($ent, -4) != '.reg') { + continue; } + $pkglist[] = substr($ent, 0, -4); } - if (isset($list['file'])) { - if ($allowignore) { - $this->_fileNotAllowed('file'); - } + + closedir($dp); + return $pkglist; + } + + function _listAllPackages() + { + $ret = array(); + foreach ($this->_listChannels() as $channel) { + $ret[$channel] = $this->_listPackages($channel); } - if (isset($list['dir'])) { - if ($allowignore) { - $this->_fileNotAllowed('dir'); - } else { - if (!isset($list['dir'][0])) { - $list['dir'] = array($list['dir']); - } - foreach ($list['dir'] as $dir) { - if (isset($dir['attribs']) && isset($dir['attribs']['name'])) { - if ($dir['attribs']['name'] == '/' || - !isset($this->_packageInfo['contents']['dir']['dir'])) { - // always use nothing if the filelist has already been flattened - $newdirs = ''; - } elseif ($dirs == '') { - $newdirs = $dir['attribs']['name']; - } else { - $newdirs = $dirs . '/' . $dir['attribs']['name']; - } - } else { - $newdirs = $dirs; - } - $this->_validateFilelist($dir, $allowignore, $newdirs); - } - } + + return $ret; + } + + /** + * Add an installed package to the registry + * @param string package name + * @param array package info (parsed by PEAR_Common::infoFrom*() methods) + * @return bool success of saving + * @access private + */ + function _addPackage($package, $info) + { + if ($this->_packageExists($package)) { + return false; + } + + $fp = $this->_openPackageFile($package, 'wb'); + if ($fp === null) { + return false; + } + + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + if (isset($info['filelist'])) { + $this->_rebuildFileMap(); } + + return true; } - function _validateRelease() + /** + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return bool + * @access private + */ + function _addPackage2($info) { - if (isset($this->_packageInfo['phprelease'])) { - $release = 'phprelease'; - if (isset($this->_packageInfo['providesextension'])) { - $this->_cannotProvideExtension($release); - } - if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { - $this->_cannotHaveSrcpackage($release); - } - $releases = $this->_packageInfo['phprelease']; - if (!is_array($releases)) { - return true; - } - if (!isset($releases[0])) { - $releases = array($releases); - } - foreach ($releases as $rel) { - $this->_stupidSchemaValidate(array( - '*installconditions', - '*filelist', - ), $rel, ''); - } + if (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) { + return false; } - foreach (array('', 'zend') as $prefix) { - $releasetype = $prefix . 'extsrcrelease'; - if (isset($this->_packageInfo[$releasetype])) { - $release = $releasetype; - if (!isset($this->_packageInfo['providesextension'])) { - $this->_mustProvideExtension($release); - } - if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { - $this->_cannotHaveSrcpackage($release); - } - $releases = $this->_packageInfo[$releasetype]; - if (!is_array($releases)) { - return true; - } - if (!isset($releases[0])) { - $releases = array($releases); - } - foreach ($releases as $rel) { - $this->_stupidSchemaValidate(array( - '*installconditions', - '*configureoption->name->prompt->?default', - '*binarypackage', - '*filelist', - ), $rel, '<' . $releasetype . '>'); - if (isset($rel['binarypackage'])) { - if (!is_array($rel['binarypackage']) || !isset($rel['binarypackage'][0])) { - $rel['binarypackage'] = array($rel['binarypackage']); - } - foreach ($rel['binarypackage'] as $bin) { - if (!is_string($bin)) { - $this->_binaryPackageMustBePackagename(); - } - } + + if (!$info->validate()) { + if (class_exists('PEAR_Common')) { + $ui = PEAR_Frontend::singleton(); + if ($ui) { + foreach ($info->getValidationWarnings() as $err) { + $ui->log($err['message'], true); } } } - $releasetype = 'extbinrelease'; - if (isset($this->_packageInfo[$releasetype])) { - $release = $releasetype; - if (!isset($this->_packageInfo['providesextension'])) { - $this->_mustProvideExtension($release); - } - if (isset($this->_packageInfo['channel']) && - !isset($this->_packageInfo['srcpackage'])) { - $this->_mustSrcPackage($release); - } - if (isset($this->_packageInfo['uri']) && !isset($this->_packageInfo['srcuri'])) { - $this->_mustSrcuri($release); - } - $releases = $this->_packageInfo[$releasetype]; - if (!is_array($releases)) { - return true; - } - if (!isset($releases[0])) { - $releases = array($releases); - } - foreach ($releases as $rel) { - $this->_stupidSchemaValidate(array( - '*installconditions', - '*filelist', - ), $rel, '<' . $releasetype . '>'); - } - } + return false; } - if (isset($this->_packageInfo['bundle'])) { - $release = 'bundle'; - if (isset($this->_packageInfo['providesextension'])) { - $this->_cannotProvideExtension($release); - } - if (isset($this->_packageInfo['srcpackage']) || isset($this->_packageInfo['srcuri'])) { - $this->_cannotHaveSrcpackage($release); - } - $releases = $this->_packageInfo['bundle']; - if (!is_array($releases) || !isset($releases[0])) { - $releases = array($releases); - } - foreach ($releases as $rel) { - $this->_stupidSchemaValidate(array( - '*installconditions', - '*filelist', - ), $rel, ''); - } + + $channel = $info->getChannel(); + $package = $info->getPackage(); + $save = $info; + if ($this->_packageExists($package, $channel)) { + return false; + } + + if (!$this->_channelExists($channel, true)) { + return false; + } + + $info = $info->toArray(true); + if (!$info) { + return false; + } + + $fp = $this->_openPackageFile($package, 'wb', $channel); + if ($fp === null) { + return false; + } + + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + $this->_rebuildFileMap(); + return true; + } + + /** + * @param string Package name + * @param array parsed package.xml 1.0 + * @param bool this parameter is only here for BC. Don't use it. + * @access private + */ + function _updatePackage($package, $info, $merge = true) + { + $oldinfo = $this->_packageInfo($package); + if (empty($oldinfo)) { + return false; + } + + $fp = $this->_openPackageFile($package, 'w'); + if ($fp === null) { + return false; } - foreach ($releases as $rel) { - if (is_array($rel) && array_key_exists('installconditions', $rel)) { - $this->_validateInstallConditions($rel['installconditions'], - "<$release>"); - } - if (is_array($rel) && array_key_exists('filelist', $rel)) { - if ($rel['filelist']) { - $this->_validateFilelist($rel['filelist'], true); - } - } + if (is_object($info)) { + $info = $info->toArray(); + } + $info['_lastmodified'] = time(); + + $newinfo = $info; + if ($merge) { + $info = array_merge($oldinfo, $info); + } else { + $diff = $info; + } + + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + if (isset($newinfo['filelist'])) { + $this->_rebuildFileMap(); } + + return true; } /** - * This is here to allow role extension through plugins - * @param string + * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 + * @return bool + * @access private */ - function _validateRole($role) + function _updatePackage2($info) { - return in_array($role, PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType())); - } + if (!$this->_packageExists($info->getPackage(), $info->getChannel())) { + return false; + } - function _pearVersionTooLow($version) - { - $this->_stack->push(__FUNCTION__, 'error', - array('version' => $version), - 'This package.xml requires PEAR version %version% to parse properly, we are ' . - 'version 1.8.0'); - } + $fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel()); + if ($fp === null) { + return false; + } - function _invalidTagOrder($oktags, $actual, $root) - { - $this->_stack->push(__FUNCTION__, 'error', - array('oktags' => $oktags, 'actual' => $actual, 'root' => $root), - 'Invalid tag order in %root%, found <%actual%> expected one of "%oktags%"'); + $save = $info; + $info = $save->getArray(true); + $info['_lastmodified'] = time(); + fwrite($fp, serialize($info)); + $this->_closePackageFile($fp); + $this->_rebuildFileMap(); + return true; } - function _ignoreNotAllowed($type) + /** + * @param string Package name + * @param string Channel name + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null + * @access private + */ + function &_getPackage($package, $channel = 'pear.php.net') { - $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), - '<%type%> is not allowed inside global , only inside ' . - '//, use and only'); - } + $info = $this->_packageInfo($package, null, $channel); + if ($info === null) { + return $info; + } - function _fileNotAllowed($type) - { - $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), - '<%type%> is not allowed inside release , only inside ' . - ', use and only'); - } + $a = $this->_config; + if (!$a) { + $this->_config = &new PEAR_Config; + $this->_config->set('php_dir', $this->statedir); + } - function _oldStyleFileNotAllowed() - { - $this->_stack->push(__FUNCTION__, 'error', array(), - 'Old-style name is not allowed. Use' . - ''); - } + if (!class_exists('PEAR_PackageFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile.php'; + } - function _tagMissingAttribute($tag, $attr, $context) - { - $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, - 'attribute' => $attr, 'context' => $context), - 'tag <%tag%> in context "%context%" has no attribute "%attribute%"'); + $pkg = &new PEAR_PackageFile($this->_config); + $pf = &$pkg->fromArray($info); + return $pf; } - function _tagHasNoAttribs($tag, $context) + /** + * @param string channel name + * @param bool whether to strictly retrieve channel names + * @return PEAR_ChannelFile|PEAR_Error + * @access private + */ + function &_getChannel($channel, $noaliases = false) { - $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, - 'context' => $context), - 'tag <%tag%> has no attributes in context "%context%"'); - } + $ch = false; + if ($this->_channelExists($channel, $noaliases)) { + $chinfo = $this->_channelInfo($channel, $noaliases); + if ($chinfo) { + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } - function _invalidInternalStructure() - { - $this->_stack->push(__FUNCTION__, 'exception', array(), - 'internal array was not generated by compatible parser, or extreme parser error, cannot continue'); - } + $ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo); + } + } - function _invalidFileRole($file, $dir, $role) - { - $this->_stack->push(__FUNCTION__, 'error', array( - 'file' => $file, 'dir' => $dir, 'role' => $role, - 'roles' => PEAR_Installer_Role::getValidRoles($this->_pf->getPackageType())), - 'File "%file%" in directory "%dir%" has invalid role "%role%", should be one of %roles%'); - } + if ($ch) { + if ($ch->validate()) { + return $ch; + } - function _invalidFileName($file, $dir) - { - $this->_stack->push(__FUNCTION__, 'error', array( - 'file' => $file), - 'File "%file%" in directory "%dir%" cannot begin with "./" or contain ".."'); - } + foreach ($ch->getErrors(true) as $err) { + $message = $err['message'] . "\n"; + } - function _invalidFileInstallAs($file, $as) - { - $this->_stack->push(__FUNCTION__, 'error', array( - 'file' => $file, 'as' => $as), - 'File "%file%" cannot contain "./" or contain ".."'); - } + $ch = PEAR::raiseError($message); + return $ch; + } - function _invalidDirName($dir) - { - $this->_stack->push(__FUNCTION__, 'error', array( - 'dir' => $file), - 'Directory "%dir%" cannot begin with "./" or contain ".."'); - } + if ($this->_getChannelFromAlias($channel) == 'pear.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } - function _filelistCannotContainFile($filelist) - { - $this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist), - '<%tag%> can only contain , contains . Use ' . - ' as the first dir element'); - } + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setServer('pear.php.net'); + $pear_channel->setAlias('pear'); + $pear_channel->setSummary('PHP Extension and Application Repository'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); + $pear_channel->setBaseURL('REST1.3', 'http://pear.php.net/rest/'); + return $pear_channel; + } - function _filelistMustContainDir($filelist) - { - $this->_stack->push(__FUNCTION__, 'error', array('tag' => $filelist), - '<%tag%> must contain . Use as the ' . - 'first dir element'); - } + if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + $pear_channel = new PEAR_ChannelFile; + $pear_channel->setServer('pecl.php.net'); + $pear_channel->setAlias('pecl'); + $pear_channel->setSummary('PHP Extension Community Library'); + $pear_channel->setDefaultPEARProtocols(); + $pear_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); + $pear_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); + $pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); + return $pear_channel; + } - function _tagCannotBeEmpty($tag) - { - $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag), - '<%tag%> cannot be empty (<%tag%/>)'); + if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $doc_channel = new PEAR_ChannelFile; + $doc_channel->setServer('doc.php.net'); + $doc_channel->setAlias('phpdocs'); + $doc_channel->setSummary('PHP Documentation Team'); + $doc_channel->setDefaultPEARProtocols(); + $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/rest/'); + $doc_channel->setBaseURL('REST1.3', 'http://doc.php.net/rest/'); + return $doc_channel; + } + + + if ($this->_getChannelFromAlias($channel) == '__uri') { + // the registry is not properly set up, so use defaults + if (!class_exists('PEAR_ChannelFile')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; + } + + $private = new PEAR_ChannelFile; + $private->setName('__uri'); + $private->setDefaultPEARProtocols(); + $private->setBaseURL('REST1.0', '****'); + $private->setSummary('Pseudo-channel for static packages'); + return $private; + } + + return $ch; } - function _UrlOrChannel($type, $name) + /** + * @param string Package name + * @param string Channel name + * @return bool + */ + function packageExists($package, $channel = 'pear.php.net') { - $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, - 'name' => $name), - 'Required dependency <%type%> "%name%" can have either url OR ' . - 'channel attributes, and not both'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_packageExists($package, $channel); + $this->_unlock(); + return $ret; } - function _NoChannel($type, $name) + // }}} + + // {{{ channelExists() + + /** + * @param string channel name + * @param bool if true, then aliases will be ignored + * @return bool + */ + function channelExists($channel, $noaliases = false) { - $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, - 'name' => $name), - 'Required dependency <%type%> "%name%" must have either url OR ' . - 'channel attributes'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_channelExists($channel, $noaliases); + $this->_unlock(); + return $ret; } - function _UrlOrChannelGroup($type, $name, $group) + // }}} + + /** + * @param string channel name mirror is in + * @param string mirror name + * + * @return bool + */ + function mirrorExists($channel, $mirror) { - $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, - 'name' => $name, 'group' => $group), - 'Group "%group%" dependency <%type%> "%name%" can have either url OR ' . - 'channel attributes, and not both'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + + $ret = $this->_mirrorExists($channel, $mirror); + $this->_unlock(); + return $ret; } - function _NoChannelGroup($type, $name, $group) + // {{{ isAlias() + + /** + * Determines whether the parameter is an alias of a channel + * @param string + * @return bool + */ + function isAlias($alias) { - $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, - 'name' => $name, 'group' => $group), - 'Group "%group%" dependency <%type%> "%name%" must have either url OR ' . - 'channel attributes'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_isChannelAlias($alias); + $this->_unlock(); + return $ret; } - function _unknownChannel($channel) + // }}} + // {{{ packageInfo() + + /** + * @param string|null + * @param string|null + * @param string + * @return array|null + */ + function packageInfo($package = null, $key = null, $channel = 'pear.php.net') { - $this->_stack->push(__FUNCTION__, 'error', array('channel' => $channel), - 'Unknown channel "%channel%"'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_packageInfo($package, $key, $channel); + $this->_unlock(); + return $ret; } - function _noPackageVersion() + // }}} + // {{{ channelInfo() + + /** + * Retrieve a raw array of channel data. + * + * Do not use this, instead use {@link getChannel()} for normal + * operations. Array structure is undefined in this method + * @param string channel name + * @param bool whether to strictly retrieve information only on non-aliases + * @return array|null|PEAR_Error + */ + function channelInfo($channel = null, $noaliases = false) { - $this->_stack->push(__FUNCTION__, 'error', array(), - 'package.xml tag has no version attribute, or version is not 2.0'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_channelInfo($channel, $noaliases); + $this->_unlock(); + return $ret; } - function _NoBundledPackages() + // }}} + + /** + * @param string + */ + function channelName($channel) { - $this->_stack->push(__FUNCTION__, 'error', array(), - 'No tag was found in , required for bundle packages'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_getChannelFromAlias($channel); + $this->_unlock(); + return $ret; } - function _AtLeast2BundledPackages() + /** + * @param string + */ + function channelAlias($channel) { - $this->_stack->push(__FUNCTION__, 'error', array(), - 'At least 2 packages must be bundled in a bundle package'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_getAlias($channel); + $this->_unlock(); + return $ret; } + // {{{ listPackages() - function _ChannelOrUri($name) + function listPackages($channel = false) { - $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), - 'Bundled package "%name%" can have either a uri or a channel, not both'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listPackages($channel); + $this->_unlock(); + return $ret; } - function _noChildTag($child, $tag) + // }}} + // {{{ listAllPackages() + + function listAllPackages() { - $this->_stack->push(__FUNCTION__, 'error', array('child' => $child, 'tag' => $tag), - 'Tag <%tag%> is missing child tag <%child%>'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listAllPackages(); + $this->_unlock(); + return $ret; } - function _invalidVersion($type, $value) + // }}} + // {{{ listChannel() + + function listChannels() { - $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value), - 'Version type <%type%> is not a valid version (%value%)'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = $this->_listChannels(); + $this->_unlock(); + return $ret; } - function _invalidState($type, $value) + // }}} + // {{{ addPackage() + + /** + * Add an installed package to the registry + * @param string|PEAR_PackageFile_v1|PEAR_PackageFile_v2 package name or object + * that will be passed to {@link addPackage2()} + * @param array package info (parsed by PEAR_Common::infoFrom*() methods) + * @return bool success of saving + */ + function addPackage($package, $info) { - $states = array('stable', 'beta', 'alpha', 'devel'); - if ($type != 'api') { - $states[] = 'snapshot'; + if (is_object($info)) { + return $this->addPackage2($info); } - if (strtolower($value) == 'rc') { - $this->_stack->push(__FUNCTION__, 'error', - array('version' => $this->_packageInfo['version']['release']), - 'RC is not a state, it is a version postfix, try %version%RC1, stability beta'); + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; } - $this->_stack->push(__FUNCTION__, 'error', array('type' => $type, 'value' => $value, - 'types' => $states), - 'Stability type <%type%> is not a valid stability (%value%), must be one of ' . - '%types%'); + $ret = $this->_addPackage($package, $info); + $this->_unlock(); + if ($ret) { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->_config); + $pf->fromArray($info); + $this->_dependencyDB->uninstallPackage($pf); + $this->_dependencyDB->installPackage($pf); + } + return $ret; } - function _invalidTask($task, $ret, $file) + // }}} + // {{{ addPackage2() + + function addPackage2($info) { - switch ($ret[0]) { - case PEAR_TASK_ERROR_MISSING_ATTRIB : - $info = array('attrib' => $ret[1], 'task' => $task, 'file' => $file); - $msg = 'task <%task%> is missing attribute "%attrib%" in file %file%'; - break; - case PEAR_TASK_ERROR_NOATTRIBS : - $info = array('task' => $task, 'file' => $file); - $msg = 'task <%task%> has no attributes in file %file%'; - break; - case PEAR_TASK_ERROR_WRONG_ATTRIB_VALUE : - $info = array('attrib' => $ret[1], 'values' => $ret[3], - 'was' => $ret[2], 'task' => $task, 'file' => $file); - $msg = 'task <%task%> attribute "%attrib%" has the wrong value "%was%" '. - 'in file %file%, expecting one of "%values%"'; - break; - case PEAR_TASK_ERROR_INVALID : - $info = array('reason' => $ret[1], 'task' => $task, 'file' => $file); - $msg = 'task <%task%> in file %file% is invalid because of "%reason%"'; - break; + if (!is_object($info)) { + return $this->addPackage($info['package'], $info); } - $this->_stack->push(__FUNCTION__, 'error', $info, $msg); + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_addPackage2($info); + $this->_unlock(); + if ($ret) { + $this->_dependencyDB->uninstallPackage($info); + $this->_dependencyDB->installPackage($info); + } + return $ret; } - function _unknownTask($task, $file) - { - $this->_stack->push(__FUNCTION__, 'error', array('task' => $task, 'file' => $file), - 'Unknown task "%task%" passed in file '); - } + // }}} + // {{{ updateChannel() - function _subpackageCannotProvideExtension($name) + /** + * For future expandibility purposes, separate this + * @param PEAR_ChannelFile + */ + function updateChannel($channel, $lastmodified = null) { - $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), - 'Subpackage dependency "%name%" cannot use , ' . - 'only package dependencies can use this tag'); + if ($channel->getName() == '__uri') { + return false; + } + return $this->addChannel($channel, $lastmodified, true); } - function _subpackagesCannotConflict($name) - { - $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), - 'Subpackage dependency "%name%" cannot use , ' . - 'only package dependencies can use this tag'); - } + // }}} + // {{{ deleteChannel() - function _cannotProvideExtension($release) + /** + * Deletion fails if there are any packages installed from the channel + * @param string|PEAR_ChannelFile channel name + * @return boolean|PEAR_Error True on deletion, false if it doesn't exist + */ + function deleteChannel($channel) { - $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), - '<%release%> packages cannot use , only extbinrelease, extsrcrelease, zendextsrcrelease, and zendextbinrelease can provide a PHP extension'); - } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } - function _mustProvideExtension($release) - { - $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), - '<%release%> packages must use to indicate which PHP extension is provided'); - } + $ret = $this->_deleteChannel($channel); + $this->_unlock(); + if ($ret && is_a($this->_config, 'PEAR_Config')) { + $this->_config->setChannels($this->listChannels()); + } - function _cannotHaveSrcpackage($release) - { - $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), - '<%release%> packages cannot specify a source code package, only extension binaries may use the tag'); + return $ret; } - function _mustSrcPackage($release) - { - $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), - '/ packages must specify a source code package with '); - } + // }}} + // {{{ addChannel() - function _mustSrcuri($release) + /** + * @param PEAR_ChannelFile Channel object + * @param string Last-Modified header from HTTP for caching + * @return boolean|PEAR_Error True on creation, false if it already exists + */ + function addChannel($channel, $lastmodified = false, $update = false) { - $this->_stack->push(__FUNCTION__, 'error', array('release' => $release), - '/ packages must specify a source code package with '); - } + if (!is_a($channel, 'PEAR_ChannelFile') || !$channel->validate()) { + return false; + } - function _uriDepsCannotHaveVersioning($type) - { - $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), - '%type%: dependencies with a tag cannot have any versioning information'); - } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } - function _conflictingDepsCannotHaveVersioning($type) - { - $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), - '%type%: conflicting dependencies cannot have versioning info, use to ' . - 'exclude specific versions of a dependency'); - } + $ret = $this->_addChannel($channel, $update, $lastmodified); + $this->_unlock(); + if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) { + $this->_config->setChannels($this->listChannels()); + } - function _DepchannelCannotBeUri($type) - { - $this->_stack->push(__FUNCTION__, 'error', array('type' => $type), - '%type%: channel cannot be __uri, this is a pseudo-channel reserved for uri ' . - 'dependencies only'); + return $ret; } - function _bundledPackagesMustBeFilename() - { - $this->_stack->push(__FUNCTION__, 'error', array(), - ' tags must contain only the filename of a package release ' . - 'in the bundle'); - } + // }}} + // {{{ deletePackage() - function _binaryPackageMustBePackagename() + function deletePackage($package, $channel = 'pear.php.net') { - $this->_stack->push(__FUNCTION__, 'error', array(), - ' tags must contain the name of a package that is ' . - 'a compiled version of this extsrc/zendextsrc package'); - } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } - function _fileNotFound($file) - { - $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), - 'File "%file%" in package.xml does not exist'); + $file = $this->_packageFileName($package, $channel); + $ret = file_exists($file) ? @unlink($file) : false; + $this->_rebuildFileMap(); + $this->_unlock(); + $p = array('channel' => $channel, 'package' => $package); + $this->_dependencyDB->uninstallPackage($p); + return $ret; } - function _notInContents($file, $tag) - { - $this->_stack->push(__FUNCTION__, 'error', array('file' => $file, 'tag' => $tag), - '<%tag% name="%file%"> is invalid, file is not in '); - } + // }}} + // {{{ updatePackage() - function _cannotValidateNoPathSet() + function updatePackage($package, $info, $merge = true) { - $this->_stack->push(__FUNCTION__, 'error', array(), - 'Cannot validate files, no path to package file is set (use setPackageFile())'); + if (is_object($info)) { + return $this->updatePackage2($info, $merge); + } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } + $ret = $this->_updatePackage($package, $info, $merge); + $this->_unlock(); + if ($ret) { + if (!class_exists('PEAR_PackageFile_v1')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; + } + $pf = new PEAR_PackageFile_v1; + $pf->setConfig($this->_config); + $pf->fromArray($this->packageInfo($package)); + $this->_dependencyDB->uninstallPackage($pf); + $this->_dependencyDB->installPackage($pf); + } + return $ret; } - function _usesroletaskMustHaveChannelOrUri($role, $tag) - { - $this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag), - '<%tag%> for role "%role%" must contain either , or and '); - } + // }}} + // {{{ updatePackage2() - function _usesroletaskMustHavePackage($role, $tag) + function updatePackage2($info) { - $this->_stack->push(__FUNCTION__, 'error', array('role' => $role, 'tag' => $tag), - '<%tag%> for role "%role%" must contain '); - } - function _usesroletaskMustHaveRoleTask($tag, $type) - { - $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag, 'type' => $type), - '<%tag%> must contain <%type%> defining the %type% to be used'); - } + if (!is_object($info)) { + return $this->updatePackage($info['package'], $info, $merge); + } - function _cannotConflictWithAllOs($type) - { - $this->_stack->push(__FUNCTION__, 'error', array('tag' => $tag), - '%tag% cannot conflict with all OSes'); - } + if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) { + return false; + } - function _invalidDepGroupName($name) - { - $this->_stack->push(__FUNCTION__, 'error', array('name' => $name), - 'Invalid dependency group name "%name%"'); - } + if (PEAR::isError($e = $this->_lock(LOCK_EX))) { + return $e; + } - function _multipleToplevelDirNotAllowed() - { - $this->_stack->push(__FUNCTION__, 'error', array(), - 'Multiple top-level tags are not allowed. Enclose them ' . - 'in a '); + $ret = $this->_updatePackage2($info); + $this->_unlock(); + if ($ret) { + $this->_dependencyDB->uninstallPackage($info); + $this->_dependencyDB->installPackage($info); + } + + return $ret; } - function _multipleInstallAs($file) + // }}} + // {{{ getChannel() + /** + * @param string channel name + * @param bool whether to strictly return raw channels (no aliases) + * @return PEAR_ChannelFile|PEAR_Error + */ + function &getChannel($channel, $noaliases = false) { - $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), - 'Only one tag is allowed for file "%file%"'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $ret = &$this->_getChannel($channel, $noaliases); + $this->_unlock(); + if (!$ret) { + return PEAR::raiseError('Unknown channel: ' . $channel); + } + return $ret; } - function _ignoreAndInstallAs($file) + // }}} + // {{{ getPackage() + /** + * @param string package name + * @param string channel name + * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null + */ + function &getPackage($package, $channel = 'pear.php.net') { - $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), - 'Cannot have both and tags for file "%file%"'); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; + } + $pf = &$this->_getPackage($package, $channel); + $this->_unlock(); + return $pf; } - function _analyzeBundledPackages() + // }}} + + /** + * Get PEAR_PackageFile_v[1/2] objects representing the contents of + * a dependency group that are installed. + * + * This is used at uninstall-time + * @param array + * @return array|false + */ + function getInstalledGroup($group) { - if (!$this->_isValid) { - return false; - } - if (!$this->_pf->getPackageType() == 'bundle') { - return false; - } - if (!isset($this->_pf->_packageFile)) { - return false; - } - $dir_prefix = dirname($this->_pf->_packageFile); - $common = new PEAR_Common; - $log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') : - array($common, 'log'); - $info = $this->_pf->getContents(); - $info = $info['bundledpackage']; - if (!is_array($info)) { - $info = array($info); + $ret = array(); + if (isset($group['package'])) { + if (!isset($group['package'][0])) { + $group['package'] = array($group['package']); + } + foreach ($group['package'] as $package) { + $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; + $p = &$this->getPackage($package['name'], $depchannel); + if ($p) { + $save = &$p; + $ret[] = &$save; + } + } } - $pkg = &new PEAR_PackageFile($this->_pf->_config); - foreach ($info as $package) { - if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $package)) { - $this->_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $package); - $this->_isValid = 0; - continue; + if (isset($group['subpackage'])) { + if (!isset($group['subpackage'][0])) { + $group['subpackage'] = array($group['subpackage']); } - call_user_func_array($log, array(1, "Analyzing bundled package $package")); - PEAR::pushErrorHandling(PEAR_ERROR_RETURN); - $ret = $pkg->fromAnyFile($dir_prefix . DIRECTORY_SEPARATOR . $package, - PEAR_VALIDATE_NORMAL); - PEAR::popErrorHandling(); - if (PEAR::isError($ret)) { - call_user_func_array($log, array(0, "ERROR: package $package is not a valid " . - 'package')); - $inf = $ret->getUserInfo(); - if (is_array($inf)) { - foreach ($inf as $err) { - call_user_func_array($log, array(1, $err['message'])); - } + foreach ($group['subpackage'] as $package) { + $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; + $p = &$this->getPackage($package['name'], $depchannel); + if ($p) { + $save = &$p; + $ret[] = &$save; } - return false; } } - return true; + if (!count($ret)) { + return false; + } + return $ret; } - function _analyzePhpFiles() + // {{{ getChannelValidator() + /** + * @param string channel name + * @return PEAR_Validate|false + */ + function &getChannelValidator($channel) { - if (!$this->_isValid) { - return false; - } - if (!isset($this->_pf->_packageFile)) { - $this->_cannotValidateNoPathSet(); - return false; - } - $dir_prefix = dirname($this->_pf->_packageFile); - $common = new PEAR_Common; - $log = isset($this->_pf->_logger) ? array(&$this->_pf->_logger, 'log') : - array(&$common, 'log'); - $info = $this->_pf->getContents(); - if (!$info || !isset($info['dir']['file'])) { - $this->_tagCannotBeEmpty('contents>getChannel($channel); + if (PEAR::isError($chan)) { + return $chan; } - $info = $info['dir']['file']; - if (isset($info['attribs'])) { - $info = array($info); + $val = $chan->getValidationObject(); + return $val; + } + // }}} + // {{{ getChannels() + /** + * @param string channel name + * @return array an array of PEAR_ChannelFile objects representing every installed channel + */ + function &getChannels() + { + $ret = array(); + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; } - $provides = array(); - foreach ($info as $fa) { - $fa = $fa['attribs']; - $file = $fa['name']; - if (!file_exists($dir_prefix . DIRECTORY_SEPARATOR . $file)) { - $this->_fileNotFound($dir_prefix . DIRECTORY_SEPARATOR . $file); - $this->_isValid = 0; + foreach ($this->_listChannels() as $channel) { + $e = &$this->_getChannel($channel); + if (!$e || PEAR::isError($e)) { continue; } - if (in_array($fa['role'], PEAR_Installer_Role::getPhpRoles()) && $dir_prefix) { - call_user_func_array($log, array(1, "Analyzing $file")); - $srcinfo = $this->analyzeSourceCode($dir_prefix . DIRECTORY_SEPARATOR . $file); - if ($srcinfo) { - $provides = array_merge($provides, $this->_buildProvidesArray($srcinfo)); + $ret[] = $e; + } + $this->_unlock(); + return $ret; + } + + // }}} + // {{{ checkFileMap() + + /** + * Test whether a file or set of files belongs to a package. + * + * If an array is passed in + * @param string|array file path, absolute or relative to the pear + * install dir + * @param string|array name of PEAR package or array('package' => name, 'channel' => + * channel) of a package that will be ignored + * @param string API version - 1.1 will exclude any files belonging to a package + * @param array private recursion variable + * @return array|false which package and channel the file belongs to, or an empty + * string if the file does not belong to an installed package, + * or belongs to the second parameter's package + */ + function checkFileMap($path, $package = false, $api = '1.0', $attrs = false) + { + if (is_array($path)) { + static $notempty; + if (empty($notempty)) { + if (!class_exists('PEAR_Installer_Role')) { + require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role.php'; + } + $notempty = create_function('$a','return !empty($a);'); + } + $package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1])) + : strtolower($package); + $pkgs = array(); + foreach ($path as $name => $attrs) { + if (is_array($attrs)) { + if (isset($attrs['install-as'])) { + $name = $attrs['install-as']; + } + if (!in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) { + // these are not installed + continue; + } + if (!in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) { + $attrs['baseinstalldir'] = is_array($package) ? $package[1] : $package; + } + if (isset($attrs['baseinstalldir'])) { + $name = $attrs['baseinstalldir'] . DIRECTORY_SEPARATOR . $name; + } + } + $pkgs[$name] = $this->checkFileMap($name, $package, $api, $attrs); + if (PEAR::isError($pkgs[$name])) { + return $pkgs[$name]; } } + return array_filter($pkgs, $notempty); } - $this->_packageName = $pn = $this->_pf->getPackage(); - $pnl = strlen($pn); - foreach ($provides as $key => $what) { - if (isset($what['explicit']) || !$what) { - // skip conformance checks if the provides entry is - // specified in the package.xml file - continue; + if (empty($this->filemap_cache)) { + if (PEAR::isError($e = $this->_lock(LOCK_SH))) { + return $e; } - extract($what); - if ($type == 'class') { - if (!strncasecmp($name, $pn, $pnl)) { - continue; - } - $this->_stack->push(__FUNCTION__, 'warning', - array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn), - 'in %file%: %type% "%name%" not prefixed with package name "%package%"'); - } elseif ($type == 'function') { - if (strstr($name, '::') || !strncasecmp($name, $pn, $pnl)) { - continue; - } - $this->_stack->push(__FUNCTION__, 'warning', - array('file' => $file, 'type' => $type, 'name' => $name, 'package' => $pn), - 'in %file%: %type% "%name%" not prefixed with package name "%package%"'); + $err = $this->_readFileMap(); + $this->_unlock(); + if (PEAR::isError($err)) { + return $err; } } - return $this->_isValid; + if (!$attrs) { + $attrs = array('role' => 'php'); // any old call would be for PHP role only + } + if (isset($this->filemap_cache[$attrs['role']][$path])) { + if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { + return false; + } + return $this->filemap_cache[$attrs['role']][$path]; + } + $l = strlen($this->install_dir); + if (substr($path, 0, $l) == $this->install_dir) { + $path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l)); + } + if (isset($this->filemap_cache[$attrs['role']][$path])) { + if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { + return false; + } + return $this->filemap_cache[$attrs['role']][$path]; + } + return false; } + // }}} + // {{{ flush() /** - * Analyze the source code of the given PHP file - * - * @param string Filename of the PHP file - * @param boolean whether to analyze $file as the file contents - * @return mixed + * Force a reload of the filemap + * @since 1.5.0RC3 */ - function analyzeSourceCode($file, $string = false) + function flushFileMap() { - if (!function_exists("token_get_all")) { - $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), - 'Parser error: token_get_all() function must exist to analyze source code, PHP may have been compiled with --disable-tokenizer'); - return false; - } - - if (!defined('T_DOC_COMMENT')) { - define('T_DOC_COMMENT', T_COMMENT); - } + $this->filemap_cache = null; + clearstatcache(); // ensure that the next read gets the full, current filemap + } - if (!defined('T_INTERFACE')) { - define('T_INTERFACE', -1); - } + // }}} + // {{{ apiVersion() + /** + * Get the expected API version. Channels API is version 1.1, as it is backwards + * compatible with 1.0 + * @return string + */ + function apiVersion() + { + return '1.1'; + } + // }}} - if (!defined('T_IMPLEMENTS')) { - define('T_IMPLEMENTS', -1); - } - if ($string) { - $contents = $file; + /** + * Parse a package name, or validate a parsed package name array + * @param string|array pass in an array of format + * array( + * 'package' => 'pname', + * ['channel' => 'channame',] + * ['version' => 'version',] + * ['state' => 'state',] + * ['group' => 'groupname']) + * or a string of format + * [channel://][channame/]pname[-version|-state][/group=groupname] + * @return array|PEAR_Error + */ + function parsePackageName($param, $defaultchannel = 'pear.php.net') + { + $saveparam = $param; + if (is_array($param)) { + // convert to string for error messages + $saveparam = $this->parsedPackageNameToString($param); + // process the array + if (!isset($param['package'])) { + return PEAR::raiseError('parsePackageName(): array $param ' . + 'must contain a valid package name in index "param"', + 'package', null, null, $param); + } + if (!isset($param['uri'])) { + if (!isset($param['channel'])) { + $param['channel'] = $defaultchannel; + } + } else { + $param['channel'] = '__uri'; + } } else { - if (!$fp = @fopen($file, "r")) { - return false; + $components = @parse_url((string) $param); + if (isset($components['scheme'])) { + if ($components['scheme'] == 'http') { + // uri package + $param = array('uri' => $param, 'channel' => '__uri'); + } elseif($components['scheme'] != 'channel') { + return PEAR::raiseError('parsePackageName(): only channel:// uris may ' . + 'be downloaded, not "' . $param . '"', 'invalid', null, null, $param); + } + } + if (!isset($components['path'])) { + return PEAR::raiseError('parsePackageName(): array $param ' . + 'must contain a valid package name in "' . $param . '"', + 'package', null, null, $param); + } + if (isset($components['host'])) { + // remove the leading "/" + $components['path'] = substr($components['path'], 1); + } + if (!isset($components['scheme'])) { + if (strpos($components['path'], '/') !== false) { + if ($components['path']{0} == '/') { + return PEAR::raiseError('parsePackageName(): this is not ' . + 'a package name, it begins with "/" in "' . $param . '"', + 'invalid', null, null, $param); + } + $parts = explode('/', $components['path']); + $components['host'] = array_shift($parts); + if (count($parts) > 1) { + $components['path'] = array_pop($parts); + $components['host'] .= '/' . implode('/', $parts); + } else { + $components['path'] = implode('/', $parts); + } + } else { + $components['host'] = $defaultchannel; + } + } else { + if (strpos($components['path'], '/')) { + $parts = explode('/', $components['path']); + $components['path'] = array_pop($parts); + $components['host'] .= '/' . implode('/', $parts); + } } - fclose($fp); - $contents = file_get_contents($file); - } - // Silence this function so we can catch PHP Warnings and show our own custom message - $tokens = @token_get_all($contents); - if (isset($php_errormsg)) { - if (isset($this->_stack)) { - $pn = $this->_pf->getPackage(); - $this->_stack->push(__FUNCTION__, 'warning', - array('file' => $file, 'package' => $pn), - 'in %file%: Could not process file for unkown reasons,' . - ' possibly a PHP parse error in %file% from %package%'); + if (is_array($param)) { + $param['package'] = $components['path']; + } else { + $param = array( + 'package' => $components['path'] + ); + if (isset($components['host'])) { + $param['channel'] = $components['host']; + } + } + if (isset($components['fragment'])) { + $param['group'] = $components['fragment']; + } + if (isset($components['user'])) { + $param['user'] = $components['user']; + } + if (isset($components['pass'])) { + $param['pass'] = $components['pass']; + } + if (isset($components['query'])) { + parse_str($components['query'], $param['opts']); + } + // check for extension + $pathinfo = pathinfo($param['package']); + if (isset($pathinfo['extension']) && + in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) { + $param['extension'] = $pathinfo['extension']; + $param['package'] = substr($pathinfo['basename'], 0, + strlen($pathinfo['basename']) - 4); + } + // check for version + if (strpos($param['package'], '-')) { + $test = explode('-', $param['package']); + if (count($test) != 2) { + return PEAR::raiseError('parsePackageName(): only one version/state ' . + 'delimiter "-" is allowed in "' . $saveparam . '"', + 'version', null, null, $param); + } + list($param['package'], $param['version']) = $test; } } -/* - for ($i = 0; $i < sizeof($tokens); $i++) { - @list($token, $data) = $tokens[$i]; - if (is_string($token)) { - var_dump($token); - } else { - print token_name($token) . ' '; - var_dump(rtrim($data)); + // validation + $info = $this->channelExists($param['channel']); + if (PEAR::isError($info)) { + return $info; + } + if (!$info) { + return PEAR::raiseError('unknown channel "' . $param['channel'] . + '" in "' . $saveparam . '"', 'channel', null, null, $param); + } + $chan = $this->getChannel($param['channel']); + if (PEAR::isError($chan)) { + return $chan; + } + if (!$chan) { + return PEAR::raiseError("Exception: corrupt registry, could not " . + "retrieve channel " . $param['channel'] . " information", + 'registry', null, null, $param); + } + $param['channel'] = $chan->getName(); + $validate = $chan->getValidationObject(); + $vpackage = $chan->getValidationPackage(); + // validate package name + if (!$validate->validPackageName($param['package'], $vpackage['_content'])) { + return PEAR::raiseError('parsePackageName(): invalid package name "' . + $param['package'] . '" in "' . $saveparam . '"', + 'package', null, null, $param); + } + if (isset($param['group'])) { + if (!PEAR_Validate::validGroupName($param['group'])) { + return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] . + '" is not a valid group name in "' . $saveparam . '"', 'group', null, null, + $param); } } -*/ - $look_for = 0; - $paren_level = 0; - $bracket_level = 0; - $brace_level = 0; - $lastphpdoc = ''; - $current_class = ''; - $current_interface = ''; - $current_class_level = -1; - $current_function = ''; - $current_function_level = -1; - $declared_classes = array(); - $declared_interfaces = array(); - $declared_functions = array(); - $declared_methods = array(); - $used_classes = array(); - $used_functions = array(); - $extends = array(); - $implements = array(); - $nodeps = array(); - $inquote = false; - $interface = false; - for ($i = 0; $i < sizeof($tokens); $i++) { - if (is_array($tokens[$i])) { - list($token, $data) = $tokens[$i]; - } else { - $token = $tokens[$i]; - $data = ''; + if (isset($param['state'])) { + if (!in_array(strtolower($param['state']), $validate->getValidStates())) { + return PEAR::raiseError('parsePackageName(): state "' . $param['state'] + . '" is not a valid state in "' . $saveparam . '"', + 'state', null, null, $param); } - - if ($inquote) { - if ($token != '"' && $token != T_END_HEREDOC) { - continue; - } else { - $inquote = false; - continue; + } + if (isset($param['version'])) { + if (isset($param['state'])) { + return PEAR::raiseError('parsePackageName(): cannot contain both ' . + 'a version and a stability (state) in "' . $saveparam . '"', + 'version/state', null, null, $param); + } + // check whether version is actually a state + if (in_array(strtolower($param['version']), $validate->getValidStates())) { + $param['state'] = strtolower($param['version']); + unset($param['version']); + } else { + if (!$validate->validVersion($param['version'])) { + return PEAR::raiseError('parsePackageName(): "' . $param['version'] . + '" is neither a valid version nor a valid state in "' . + $saveparam . '"', 'version/state', null, null, $param); } } - - switch ($token) { - case T_WHITESPACE : - continue; - case ';': - if ($interface) { - $current_function = ''; - $current_function_level = -1; - } - break; - case '"': - case T_START_HEREDOC: - $inquote = true; - break; - case T_CURLY_OPEN: - case T_DOLLAR_OPEN_CURLY_BRACES: - case '{': $brace_level++; continue 2; - case '}': - $brace_level--; - if ($current_class_level == $brace_level) { - $current_class = ''; - $current_class_level = -1; - } - if ($current_function_level == $brace_level) { - $current_function = ''; - $current_function_level = -1; - } - continue 2; - case '[': $bracket_level++; continue 2; - case ']': $bracket_level--; continue 2; - case '(': $paren_level++; continue 2; - case ')': $paren_level--; continue 2; - case T_INTERFACE: - $interface = true; - case T_CLASS: - if (($current_class_level != -1) || ($current_function_level != -1)) { - if (isset($this->_stack)) { - $this->_stack->push(__FUNCTION__, 'error', array('file' => $file), - 'Parser error: invalid PHP found in file "%file%"'); - } else { - PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"", - PEAR_COMMON_ERROR_INVALIDPHP); - } - - return false; - } - case T_FUNCTION: - case T_NEW: - case T_EXTENDS: - case T_IMPLEMENTS: - $look_for = $token; - continue 2; - case T_STRING: - if (version_compare(zend_version(), '2.0', '<')) { - if (in_array(strtolower($data), - array('public', 'private', 'protected', 'abstract', - 'interface', 'implements', 'throw') - ) - ) { - if (isset($this->_stack)) { - $this->_stack->push(__FUNCTION__, 'warning', array( - 'file' => $file), - 'Error, PHP5 token encountered in %file%,' . - ' analysis should be in PHP5'); - } else { - PEAR::raiseError('Error: PHP5 token encountered in ' . $file . - 'packaging should be done in PHP 5'); - return false; - } - } - } - - if ($look_for == T_CLASS) { - $current_class = $data; - $current_class_level = $brace_level; - $declared_classes[] = $current_class; - } elseif ($look_for == T_INTERFACE) { - $current_interface = $data; - $current_class_level = $brace_level; - $declared_interfaces[] = $current_interface; - } elseif ($look_for == T_IMPLEMENTS) { - $implements[$current_class] = $data; - } elseif ($look_for == T_EXTENDS) { - $extends[$current_class] = $data; - } elseif ($look_for == T_FUNCTION) { - if ($current_class) { - $current_function = "$current_class::$data"; - $declared_methods[$current_class][] = $data; - } elseif ($current_interface) { - $current_function = "$current_interface::$data"; - $declared_methods[$current_interface][] = $data; - } else { - $current_function = $data; - $declared_functions[] = $current_function; - } - - $current_function_level = $brace_level; - $m = array(); - } elseif ($look_for == T_NEW) { - $used_classes[$data] = true; - } - - $look_for = 0; - continue 2; - case T_VARIABLE: - $look_for = 0; - continue 2; - case T_DOC_COMMENT: - case T_COMMENT: - if (preg_match('!^/\*\*\s!', $data)) { - $lastphpdoc = $data; - if (preg_match_all('/@nodep\s+(\S+)/', $lastphpdoc, $m)) { - $nodeps = array_merge($nodeps, $m[1]); - } - } - continue 2; - case T_DOUBLE_COLON: - if (!($tokens[$i - 1][0] == T_WHITESPACE || $tokens[$i - 1][0] == T_STRING)) { - if (isset($this->_stack)) { - $this->_stack->push(__FUNCTION__, 'warning', array('file' => $file), - 'Parser error: invalid PHP found in file "%file%"'); - } else { - PEAR::raiseError("Parser error: invalid PHP found in file \"$file\"", - PEAR_COMMON_ERROR_INVALIDPHP); - } - - return false; - } - - $class = $tokens[$i - 1][1]; - if (strtolower($class) != 'parent') { - $used_classes[$class] = true; - } - - continue 2; - } } - - return array( - "source_file" => $file, - "declared_classes" => $declared_classes, - "declared_interfaces" => $declared_interfaces, - "declared_methods" => $declared_methods, - "declared_functions" => $declared_functions, - "used_classes" => array_diff(array_keys($used_classes), $nodeps), - "inheritance" => $extends, - "implements" => $implements, - ); + return $param; } /** - * Build a "provides" array from data returned by - * analyzeSourceCode(). The format of the built array is like - * this: - * - * array( - * 'class;MyClass' => 'array('type' => 'class', 'name' => 'MyClass'), - * ... - * ) - * - * - * @param array $srcinfo array with information about a source file - * as returned by the analyzeSourceCode() method. - * - * @return void - * - * @access private - * + * @param array + * @return string */ - function _buildProvidesArray($srcinfo) + function parsedPackageNameToString($parsed, $brief = false) { - if (!$this->_isValid) { - return array(); + if (is_string($parsed)) { + return $parsed; } - - $providesret = array(); - $file = basename($srcinfo['source_file']); - $pn = isset($this->_pf) ? $this->_pf->getPackage() : ''; - $pnl = strlen($pn); - foreach ($srcinfo['declared_classes'] as $class) { - $key = "class;$class"; - if (isset($providesret[$key])) { - continue; - } - - $providesret[$key] = - array('file'=> $file, 'type' => 'class', 'name' => $class); - if (isset($srcinfo['inheritance'][$class])) { - $providesret[$key]['extends'] = - $srcinfo['inheritance'][$class]; - } + if (is_object($parsed)) { + $p = $parsed; + $parsed = array( + 'package' => $p->getPackage(), + 'channel' => $p->getChannel(), + 'version' => $p->getVersion(), + ); } - - foreach ($srcinfo['declared_methods'] as $class => $methods) { - foreach ($methods as $method) { - $function = "$class::$method"; - $key = "function;$function"; - if ($method{0} == '_' || !strcasecmp($method, $class) || - isset($providesret[$key])) { - continue; - } - - $providesret[$key] = - array('file'=> $file, 'type' => 'function', 'name' => $function); + if (isset($parsed['uri'])) { + return $parsed['uri']; + } + if ($brief) { + if ($channel = $this->channelAlias($parsed['channel'])) { + return $channel . '/' . $parsed['package']; } } - - foreach ($srcinfo['declared_functions'] as $function) { - $key = "function;$function"; - if ($function{0} == '_' || isset($providesret[$key])) { - continue; + $upass = ''; + if (isset($parsed['user'])) { + $upass = $parsed['user']; + if (isset($parsed['pass'])) { + $upass .= ':' . $parsed['pass']; } - - if (!strstr($function, '::') && strncasecmp($function, $pn, $pnl)) { - $warnings[] = "in1 " . $file . ": function \"$function\" not prefixed with package name \"$pn\""; + $upass = "$upass@"; + } + $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package']; + if (isset($parsed['version']) || isset($parsed['state'])) { + $ver = isset($parsed['version']) ? $parsed['version'] : ''; + $ver .= isset($parsed['state']) ? $parsed['state'] : ''; + $ret .= '-' . $ver; + } + if (isset($parsed['extension'])) { + $ret .= '.' . $parsed['extension']; + } + if (isset($parsed['opts'])) { + $ret .= '?'; + foreach ($parsed['opts'] as $name => $value) { + $parsed['opts'][$name] = "$name=$value"; } - - $providesret[$key] = - array('file'=> $file, 'type' => 'function', 'name' => $function); + $ret .= implode('&', $parsed['opts']); } - - return $providesret; + if (isset($parsed['group'])) { + $ret .= '#' . $parsed['group']; + } + return $ret; } -} - * @author Tomas V. V. Cox - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Registry.php,v 1.179 2009/04/10 19:42:18 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 0.1 - */ - -/** - * for PEAR_Error - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/DependencyDB.php'; - -define('PEAR_REGISTRY_ERROR_LOCK', -2); -define('PEAR_REGISTRY_ERROR_FORMAT', -3); -define('PEAR_REGISTRY_ERROR_FILE', -4); -define('PEAR_REGISTRY_ERROR_CONFLICT', -5); -define('PEAR_REGISTRY_ERROR_CHANNEL_FILE', -6); - -/** - * Administration class used to maintain the installed package database. - * @category pear - * @package PEAR - * @author Stig Bakken - * @author Tomas V. V. Cox - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a1 - */ -class PEAR_Registry extends PEAR -{ - /** - * File containing all channel information. - * @var string - */ - var $channels = ''; - - /** Directory where registry files are stored. - * @var string - */ - var $statedir = ''; - - /** File where the file map is stored - * @var string - */ - var $filemap = ''; - - /** Directory where registry files for channels are stored. - * @var string - */ - var $channelsdir = ''; - - /** Name of file used for locking the registry - * @var string - */ - var $lockfile = ''; - - /** File descriptor used during locking - * @var resource - */ - var $lock_fp = null; - - /** Mode used during locking - * @var int - */ - var $lock_mode = 0; // XXX UNUSED - - /** Cache of package information. Structure: - * array( - * 'package' => array('id' => ... ), - * ... ) - * @var array - */ - var $pkginfo_cache = array(); - - /** Cache of file map. Structure: - * array( '/path/to/file' => 'package', ... ) - * @var array - */ - var $filemap_cache = array(); - - /** - * @var false|PEAR_ChannelFile - */ - var $_pearChannel; - - /** - * @var false|PEAR_ChannelFile - */ - var $_peclChannel; - - /** - * @var false|PEAR_ChannelFile - */ - var $_docChannel; - - /** - * @var PEAR_DependencyDB - */ - var $_dependencyDB; - - /** - * @var PEAR_Config - */ - var $_config; - - /** - * PEAR_Registry constructor. - * - * @param string (optional) PEAR install directory (for .php files) - * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PEAR channel, if - * default values are not desired. Only used the very first time a PEAR - * repository is initialized - * @param PEAR_ChannelFile PEAR_ChannelFile object representing the PECL channel, if - * default values are not desired. Only used the very first time a PEAR - * repository is initialized - * - * @access public - */ - function PEAR_Registry($pear_install_dir = PEAR_INSTALL_DIR, $pear_channel = false, - $pecl_channel = false) - { - parent::PEAR(); - $this->setInstallDir($pear_install_dir); - $this->_pearChannel = $pear_channel; - $this->_peclChannel = $pecl_channel; - $this->_config = false; - } - - function setInstallDir($pear_install_dir = PEAR_INSTALL_DIR) - { - $ds = DIRECTORY_SEPARATOR; - $this->install_dir = $pear_install_dir; - $this->channelsdir = $pear_install_dir.$ds.'.channels'; - $this->statedir = $pear_install_dir.$ds.'.registry'; - $this->filemap = $pear_install_dir.$ds.'.filemap'; - $this->lockfile = $pear_install_dir.$ds.'.lock'; - } - - function hasWriteAccess() - { - if (!file_exists($this->install_dir)) { - $dir = $this->install_dir; - while ($dir && $dir != '.') { - $olddir = $dir; - $dir = dirname($dir); - if ($dir != '.' && file_exists($dir)) { - if (is_writeable($dir)) { - return true; - } - - return false; - } - - if ($dir == $olddir) { // this can happen in safe mode - return @is_writable($dir); - } - } - - return false; - } - - return is_writeable($this->install_dir); - } - - function setConfig(&$config, $resetInstallDir = true) - { - $this->_config = &$config; - if ($resetInstallDir) { - $this->setInstallDir($config->get('php_dir')); - } - } - - function _initializeChannelDirs() - { - static $running = false; - if (!$running) { - $running = true; - $ds = DIRECTORY_SEPARATOR; - if (!is_dir($this->channelsdir) || - !file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || - !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || - !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || - !file_exists($this->channelsdir . $ds . '__uri.reg')) { - if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { - $pear_channel = $this->_pearChannel; - if (!is_a($pear_channel, 'PEAR_ChannelFile') || !$pear_channel->validate()) { - if (!class_exists('PEAR_ChannelFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; - } - - $pear_channel = new PEAR_ChannelFile; - $pear_channel->setName('pear.php.net'); - $pear_channel->setAlias('pear'); - $pear_channel->setServer('pear.php.net'); - $pear_channel->setSummary('PHP Extension and Application Repository'); - $pear_channel->setDefaultPEARProtocols(); - $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); - $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); - } else { - $pear_channel->setName('pear.php.net'); - $pear_channel->setAlias('pear'); - } - - $pear_channel->validate(); - $this->_addChannel($pear_channel); - } - - if (!file_exists($this->channelsdir . $ds . 'pecl.php.net.reg')) { - $pecl_channel = $this->_peclChannel; - if (!is_a($pecl_channel, 'PEAR_ChannelFile') || !$pecl_channel->validate()) { - if (!class_exists('PEAR_ChannelFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; - } - - $pecl_channel = new PEAR_ChannelFile; - $pecl_channel->setName('pecl.php.net'); - $pecl_channel->setAlias('pecl'); - $pecl_channel->setServer('pecl.php.net'); - $pecl_channel->setSummary('PHP Extension Community Library'); - $pecl_channel->setDefaultPEARProtocols(); - $pecl_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); - $pecl_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); - $pecl_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); - } else { - $pecl_channel->setName('pecl.php.net'); - $pecl_channel->setAlias('pecl'); - } - - $pecl_channel->validate(); - $this->_addChannel($pecl_channel); - } - - if (!file_exists($this->channelsdir . $ds . 'doc.php.net.reg')) { - $doc_channel = $this->_docChannel; - if (!is_a($doc_channel, 'PEAR_ChannelFile') || !$doc_channel->validate()) { - if (!class_exists('PEAR_ChannelFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; - } - - $doc_channel = new PEAR_ChannelFile; - $doc_channel->setName('doc.php.net'); - $doc_channel->setAlias('phpdocs'); - $doc_channel->setServer('doc.php.net'); - $doc_channel->setSummary('PHP Documentation Team'); - $doc_channel->setDefaultPEARProtocols(); - $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/Chiara_PEAR_Server_REST/'); - $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/Chiara_PEAR_Server_REST/'); - } else { - $doc_channel->setName('doc.php.net'); - $doc_channel->setAlias('doc'); - } - - $doc_channel->validate(); - $this->_addChannel($doc_channel); - } - - if (!file_exists($this->channelsdir . $ds . '__uri.reg')) { - if (!class_exists('PEAR_ChannelFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; - } - - $private = new PEAR_ChannelFile; - $private->setName('__uri'); - $private->setDefaultPEARProtocols(); - $private->setBaseURL('REST1.0', '****'); - $private->setSummary('Pseudo-channel for static packages'); - $this->_addChannel($private); - } - $this->_rebuildFileMap(); - } - - $running = false; - } - } - - function _initializeDirs() - { - $ds = DIRECTORY_SEPARATOR; - // XXX Compatibility code should be removed in the future - // rename all registry files if any to lowercase - if (!OS_WINDOWS && file_exists($this->statedir) && is_dir($this->statedir) && - $handle = opendir($this->statedir)) { - $dest = $this->statedir . $ds; - while (false !== ($file = readdir($handle))) { - if (preg_match('/^.*[A-Z].*\.reg\\z/', $file)) { - rename($dest . $file, $dest . strtolower($file)); - } - } - closedir($handle); - } - - $this->_initializeChannelDirs(); - if (!file_exists($this->filemap)) { - $this->_rebuildFileMap(); - } - $this->_initializeDepDB(); - } - - function _initializeDepDB() - { - if (!isset($this->_dependencyDB)) { - static $initializing = false; - if (!$initializing) { - $initializing = true; - if (!$this->_config) { // never used? - $file = OS_WINDOWS ? 'pear.ini' : '.pearrc'; - $this->_config = &new PEAR_Config($this->statedir . DIRECTORY_SEPARATOR . - $file); - $this->_config->setRegistry($this); - $this->_config->set('php_dir', $this->install_dir); - } - - $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); - if (PEAR::isError($this->_dependencyDB)) { - // attempt to recover by removing the dep db - if (file_exists($this->_config->get('php_dir', null, 'pear.php.net') . - DIRECTORY_SEPARATOR . '.depdb')) { - @unlink($this->_config->get('php_dir', null, 'pear.php.net') . - DIRECTORY_SEPARATOR . '.depdb'); - } - - $this->_dependencyDB = &PEAR_DependencyDB::singleton($this->_config); - if (PEAR::isError($this->_dependencyDB)) { - echo $this->_dependencyDB->getMessage(); - echo 'Unrecoverable error'; - exit(1); - } - } - - $initializing = false; - } - } - } - - /** - * PEAR_Registry destructor. Makes sure no locks are forgotten. - * - * @access private - */ - function _PEAR_Registry() - { - parent::_PEAR(); - if (is_resource($this->lock_fp)) { - $this->_unlock(); - } - } - - /** - * Make sure the directory where we keep registry files exists. - * - * @return bool TRUE if directory exists, FALSE if it could not be - * created - * - * @access private - */ - function _assertStateDir($channel = false) - { - if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { - return $this->_assertChannelStateDir($channel); - } - - static $init = false; - if (!file_exists($this->statedir)) { - if (!$this->hasWriteAccess()) { - return false; - } - - require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; - if (!System::mkdir(array('-p', $this->statedir))) { - return $this->raiseError("could not create directory '{$this->statedir}'"); - } - $init = true; - } elseif (!is_dir($this->statedir)) { - return $this->raiseError('Cannot create directory ' . $this->statedir . ', ' . - 'it already exists and is not a directory'); - } - - $ds = DIRECTORY_SEPARATOR; - if (!file_exists($this->channelsdir)) { - if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg') || - !file_exists($this->channelsdir . $ds . 'pecl.php.net.reg') || - !file_exists($this->channelsdir . $ds . 'doc.php.net.reg') || - !file_exists($this->channelsdir . $ds . '__uri.reg')) { - $init = true; - } - } elseif (!is_dir($this->channelsdir)) { - return $this->raiseError('Cannot create directory ' . $this->channelsdir . ', ' . - 'it already exists and is not a directory'); - } - - if ($init) { - static $running = false; - if (!$running) { - $running = true; - $this->_initializeDirs(); - $running = false; - $init = false; - } - } else { - $this->_initializeDepDB(); - } - - return true; - } - - /** - * Make sure the directory where we keep registry files exists for a non-standard channel. - * - * @param string channel name - * @return bool TRUE if directory exists, FALSE if it could not be - * created - * - * @access private - */ - function _assertChannelStateDir($channel) - { - $ds = DIRECTORY_SEPARATOR; - if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { - if (!file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { - $this->_initializeChannelDirs(); - } - return $this->_assertStateDir($channel); - } - - $channelDir = $this->_channelDirectoryName($channel); - if (!is_dir($this->channelsdir) || - !file_exists($this->channelsdir . $ds . 'pear.php.net.reg')) { - $this->_initializeChannelDirs(); - } - - if (!file_exists($channelDir)) { - if (!$this->hasWriteAccess()) { - return false; - } - - require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; - if (!System::mkdir(array('-p', $channelDir))) { - return $this->raiseError("could not create directory '" . $channelDir . - "'"); - } - } elseif (!is_dir($channelDir)) { - return $this->raiseError("could not create directory '" . $channelDir . - "', already exists and is not a directory"); - } - - return true; - } - - /** - * Make sure the directory where we keep registry files for channels exists - * - * @return bool TRUE if directory exists, FALSE if it could not be - * created - * - * @access private - */ - function _assertChannelDir() - { - if (!file_exists($this->channelsdir)) { - if (!$this->hasWriteAccess()) { - return false; - } - - require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; - if (!System::mkdir(array('-p', $this->channelsdir))) { - return $this->raiseError("could not create directory '{$this->channelsdir}'"); - } - } elseif (!is_dir($this->channelsdir)) { - return $this->raiseError("could not create directory '{$this->channelsdir}" . - "', it already exists and is not a directory"); - } - - if (!file_exists($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { - if (!$this->hasWriteAccess()) { - return false; - } - - require_once 'phar://install-pear-nozlib.phar/' . 'System.php'; - if (!System::mkdir(array('-p', $this->channelsdir . DIRECTORY_SEPARATOR . '.alias'))) { - return $this->raiseError("could not create directory '{$this->channelsdir}/.alias'"); - } - } elseif (!is_dir($this->channelsdir . DIRECTORY_SEPARATOR . '.alias')) { - return $this->raiseError("could not create directory '{$this->channelsdir}" . - "/.alias', it already exists and is not a directory"); - } - - return true; - } - - /** - * Get the name of the file where data for a given package is stored. - * - * @param string channel name, or false if this is a PEAR package - * @param string package name - * - * @return string registry file name - * - * @access public - */ - function _packageFileName($package, $channel = false) - { - if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { - return $this->_channelDirectoryName($channel) . DIRECTORY_SEPARATOR . - strtolower($package) . '.reg'; - } - - return $this->statedir . DIRECTORY_SEPARATOR . strtolower($package) . '.reg'; - } - - /** - * Get the name of the file where data for a given channel is stored. - * @param string channel name - * @return string registry file name - */ - function _channelFileName($channel, $noaliases = false) - { - if (!$noaliases) { - if (file_exists($this->_getChannelAliasFileName($channel))) { - $channel = implode('', file($this->_getChannelAliasFileName($channel))); - } - } - return $this->channelsdir . DIRECTORY_SEPARATOR . str_replace('/', '_', - strtolower($channel)) . '.reg'; - } - - /** - * @param string - * @return string - */ - function _getChannelAliasFileName($alias) - { - return $this->channelsdir . DIRECTORY_SEPARATOR . '.alias' . - DIRECTORY_SEPARATOR . str_replace('/', '_', strtolower($alias)) . '.txt'; - } - - /** - * Get the name of a channel from its alias - */ - function _getChannelFromAlias($channel) - { - if (!$this->_channelExists($channel)) { - if ($channel == 'pear.php.net') { - return 'pear.php.net'; - } - - if ($channel == 'pecl.php.net') { - return 'pecl.php.net'; - } - - if ($channel == 'doc.php.net') { - return 'doc.php.net'; - } - - if ($channel == '__uri') { - return '__uri'; - } - - return false; - } - - $channel = strtolower($channel); - if (file_exists($this->_getChannelAliasFileName($channel))) { - // translate an alias to an actual channel - return implode('', file($this->_getChannelAliasFileName($channel))); - } - - return $channel; - } - - /** - * Get the alias of a channel from its alias or its name - */ - function _getAlias($channel) - { - if (!$this->_channelExists($channel)) { - if ($channel == 'pear.php.net') { - return 'pear'; - } - - if ($channel == 'pecl.php.net') { - return 'pecl'; - } - - if ($channel == 'doc.php.net') { - return 'phpdocs'; - } - - return false; - } - - $channel = $this->_getChannel($channel); - if (PEAR::isError($channel)) { - return $channel; - } - - return $channel->getAlias(); - } - - /** - * Get the name of the file where data for a given package is stored. - * - * @param string channel name, or false if this is a PEAR package - * @param string package name - * - * @return string registry file name - * - * @access public - */ - function _channelDirectoryName($channel) - { - if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { - return $this->statedir; - } - - $ch = $this->_getChannelFromAlias($channel); - if (!$ch) { - $ch = $channel; - } - - return $this->statedir . DIRECTORY_SEPARATOR . strtolower('.channel.' . - str_replace('/', '_', $ch)); - } - - function _openPackageFile($package, $mode, $channel = false) - { - if (!$this->_assertStateDir($channel)) { - return null; - } - - if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { - return null; - } - - $file = $this->_packageFileName($package, $channel); - if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { - return null; - } - - $fp = @fopen($file, $mode); - if (!$fp) { - return null; - } - - return $fp; - } - - function _closePackageFile($fp) - { - fclose($fp); - } - - function _openChannelFile($channel, $mode) - { - if (!$this->_assertChannelDir()) { - return null; - } - - if (!in_array($mode, array('r', 'rb')) && !$this->hasWriteAccess()) { - return null; - } - - $file = $this->_channelFileName($channel); - if (!file_exists($file) && $mode == 'r' || $mode == 'rb') { - return null; - } - - $fp = @fopen($file, $mode); - if (!$fp) { - return null; - } - - return $fp; - } - - function _closeChannelFile($fp) - { - fclose($fp); - } - - function _rebuildFileMap() - { - if (!class_exists('PEAR_Installer_Role')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role.php'; - } - - $channels = $this->_listAllPackages(); - $files = array(); - foreach ($channels as $channel => $packages) { - foreach ($packages as $package) { - $version = $this->_packageInfo($package, 'version', $channel); - $filelist = $this->_packageInfo($package, 'filelist', $channel); - if (!is_array($filelist)) { - continue; - } - - foreach ($filelist as $name => $attrs) { - if (isset($attrs['attribs'])) { - $attrs = $attrs['attribs']; - } - - // it is possible for conflicting packages in different channels to - // conflict with data files/doc files - if ($name == 'dirtree') { - continue; - } - - if (isset($attrs['role']) && !in_array($attrs['role'], - PEAR_Installer_Role::getInstallableRoles())) { - // these are not installed - continue; - } - - if (isset($attrs['role']) && !in_array($attrs['role'], - PEAR_Installer_Role::getBaseinstallRoles())) { - $attrs['baseinstalldir'] = $package; - } - - if (isset($attrs['baseinstalldir'])) { - $file = $attrs['baseinstalldir'].DIRECTORY_SEPARATOR.$name; - } else { - $file = $name; - } - - $file = preg_replace(',^/+,', '', $file); - if ($channel != 'pear.php.net') { - if (!isset($files[$attrs['role']])) { - $files[$attrs['role']] = array(); - } - $files[$attrs['role']][$file] = array(strtolower($channel), - strtolower($package)); - } else { - if (!isset($files[$attrs['role']])) { - $files[$attrs['role']] = array(); - } - $files[$attrs['role']][$file] = strtolower($package); - } - } - } - } - - - $this->_assertStateDir(); - if (!$this->hasWriteAccess()) { - return false; - } - - $fp = @fopen($this->filemap, 'wb'); - if (!$fp) { - return false; - } - - $this->filemap_cache = $files; - fwrite($fp, serialize($files)); - fclose($fp); - return true; - } - - function _readFileMap() - { - if (!file_exists($this->filemap)) { - return array(); - } - - $fp = @fopen($this->filemap, 'r'); - if (!$fp) { - return $this->raiseError('PEAR_Registry: could not open filemap "' . $this->filemap . '"', PEAR_REGISTRY_ERROR_FILE, null, null, $php_errormsg); - } - - clearstatcache(); - $rt = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - $fsize = filesize($this->filemap); - fclose($fp); - $data = file_get_contents($this->filemap); - set_magic_quotes_runtime($rt); - $tmp = unserialize($data); - if (!$tmp && $fsize > 7) { - return $this->raiseError('PEAR_Registry: invalid filemap data', PEAR_REGISTRY_ERROR_FORMAT, null, null, $data); - } - - $this->filemap_cache = $tmp; - return true; - } - - /** - * Lock the registry. - * - * @param integer lock mode, one of LOCK_EX, LOCK_SH or LOCK_UN. - * See flock manual for more information. - * - * @return bool TRUE on success, FALSE if locking failed, or a - * PEAR error if some other error occurs (such as the - * lock file not being writable). - * - * @access private - */ - function _lock($mode = LOCK_EX) - { - if (stristr(php_uname(), 'Windows 9')) { - return true; - } - - if ($mode != LOCK_UN && is_resource($this->lock_fp)) { - // XXX does not check type of lock (LOCK_SH/LOCK_EX) - return true; - } - - if (!$this->_assertStateDir()) { - if ($mode == LOCK_EX) { - return $this->raiseError('Registry directory is not writeable by the current user'); - } - - return true; - } - - $open_mode = 'w'; - // XXX People reported problems with LOCK_SH and 'w' - if ($mode === LOCK_SH || $mode === LOCK_UN) { - if (!file_exists($this->lockfile)) { - touch($this->lockfile); - } - $open_mode = 'r'; - } - - if (!is_resource($this->lock_fp)) { - $this->lock_fp = @fopen($this->lockfile, $open_mode); - } - - if (!is_resource($this->lock_fp)) { - $this->lock_fp = null; - return $this->raiseError("could not create lock file" . - (isset($php_errormsg) ? ": " . $php_errormsg : "")); - } - - if (!(int)flock($this->lock_fp, $mode)) { - switch ($mode) { - case LOCK_SH: $str = 'shared'; break; - case LOCK_EX: $str = 'exclusive'; break; - case LOCK_UN: $str = 'unlock'; break; - default: $str = 'unknown'; break; - } - - //is resource at this point, close it on error. - fclose($this->lock_fp); - $this->lock_fp = null; - return $this->raiseError("could not acquire $str lock ($this->lockfile)", - PEAR_REGISTRY_ERROR_LOCK); - } - - return true; - } - - function _unlock() - { - $ret = $this->_lock(LOCK_UN); - if (is_resource($this->lock_fp)) { - fclose($this->lock_fp); - } - - $this->lock_fp = null; - return $ret; - } - - function _packageExists($package, $channel = false) - { - return file_exists($this->_packageFileName($package, $channel)); - } - - /** - * Determine whether a channel exists in the registry - * @param string Channel name - * @param bool if true, then aliases will be ignored - * @return boolean - */ - function _channelExists($channel, $noaliases = false) - { - $a = file_exists($this->_channelFileName($channel, $noaliases)); - if (!$a && $channel == 'pear.php.net') { - return true; - } - - if (!$a && $channel == 'pecl.php.net') { - return true; - } - - if (!$a && $channel == 'doc.php.net') { - return true; - } - - return $a; - } - - /** - * @param PEAR_ChannelFile Channel object - * @param donotuse - * @param string Last-Modified HTTP tag from remote request - * @return boolean|PEAR_Error True on creation, false if it already exists - */ - function _addChannel($channel, $update = false, $lastmodified = false) - { - if (!is_a($channel, 'PEAR_ChannelFile')) { - return false; - } - - if (!$channel->validate()) { - return false; - } - - if (file_exists($this->_channelFileName($channel->getName()))) { - if (!$update) { - return false; - } - - $checker = $this->_getChannel($channel->getName()); - if (PEAR::isError($checker)) { - return $checker; - } - - if ($channel->getAlias() != $checker->getAlias()) { - if (file_exists($this->_getChannelAliasFileName($checker->getAlias()))) { - @unlink($this->_getChannelAliasFileName($checker->getAlias())); - } - } - } else { - if ($update && !in_array($channel->getName(), array('pear.php.net', 'pecl.php.net', 'doc.php.net'))) { - return false; - } - } - - $ret = $this->_assertChannelDir(); - if (PEAR::isError($ret)) { - return $ret; - } - - $ret = $this->_assertChannelStateDir($channel->getName()); - if (PEAR::isError($ret)) { - return $ret; - } - - if ($channel->getAlias() != $channel->getName()) { - if (file_exists($this->_getChannelAliasFileName($channel->getAlias())) && - $this->_getChannelFromAlias($channel->getAlias()) != $channel->getName()) { - $channel->setAlias($channel->getName()); - } - - if (!$this->hasWriteAccess()) { - return false; - } - - $fp = @fopen($this->_getChannelAliasFileName($channel->getAlias()), 'w'); - if (!$fp) { - return false; - } - - fwrite($fp, $channel->getName()); - fclose($fp); - } - - if (!$this->hasWriteAccess()) { - return false; - } - - $fp = @fopen($this->_channelFileName($channel->getName()), 'wb'); - if (!$fp) { - return false; - } - - $info = $channel->toArray(); - if ($lastmodified) { - $info['_lastmodified'] = $lastmodified; - } else { - $info['_lastmodified'] = date('r'); - } - - fwrite($fp, serialize($info)); - fclose($fp); - return true; - } - - /** - * Deletion fails if there are any packages installed from the channel - * @param string|PEAR_ChannelFile channel name - * @return boolean|PEAR_Error True on deletion, false if it doesn't exist - */ - function _deleteChannel($channel) - { - if (!is_string($channel)) { - if (!is_a($channel, 'PEAR_ChannelFile')) { - return false; - } - - if (!$channel->validate()) { - return false; - } - $channel = $channel->getName(); - } - - if ($this->_getChannelFromAlias($channel) == '__uri') { - return false; - } - - if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { - return false; - } - - if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { - return false; - } - - if (!$this->_channelExists($channel)) { - return false; - } - - if (!$channel || $this->_getChannelFromAlias($channel) == 'pear.php.net') { - return false; - } - - $channel = $this->_getChannelFromAlias($channel); - if ($channel == 'pear.php.net') { - return false; - } - - $test = $this->_listChannelPackages($channel); - if (count($test)) { - return false; - } - - $test = @rmdir($this->_channelDirectoryName($channel)); - if (!$test) { - return false; - } - - $file = $this->_getChannelAliasFileName($this->_getAlias($channel)); - if (file_exists($file)) { - $test = @unlink($file); - if (!$test) { - return false; - } - } - - $file = $this->_channelFileName($channel); - $ret = true; - if (file_exists($file)) { - $ret = @unlink($file); - } - - return $ret; - } - - /** - * Determine whether a channel exists in the registry - * @param string Channel Alias - * @return boolean - */ - function _isChannelAlias($alias) - { - return file_exists($this->_getChannelAliasFileName($alias)); - } - - /** - * @param string|null - * @param string|null - * @param string|null - * @return array|null - * @access private - */ - function _packageInfo($package = null, $key = null, $channel = 'pear.php.net') - { - if ($package === null) { - if ($channel === null) { - $channels = $this->_listChannels(); - $ret = array(); - foreach ($channels as $channel) { - $channel = strtolower($channel); - $ret[$channel] = array(); - $packages = $this->_listPackages($channel); - foreach ($packages as $package) { - $ret[$channel][] = $this->_packageInfo($package, null, $channel); - } - } - - return $ret; - } - - $ps = $this->_listPackages($channel); - if (!count($ps)) { - return array(); - } - return array_map(array(&$this, '_packageInfo'), - $ps, array_fill(0, count($ps), null), - array_fill(0, count($ps), $channel)); - } - - $fp = $this->_openPackageFile($package, 'r', $channel); - if ($fp === null) { - return null; - } - - $rt = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - clearstatcache(); - $this->_closePackageFile($fp); - $data = file_get_contents($this->_packageFileName($package, $channel)); - set_magic_quotes_runtime($rt); - $data = unserialize($data); - if ($key === null) { - return $data; - } - - // compatibility for package.xml version 2.0 - if (isset($data['old'][$key])) { - return $data['old'][$key]; - } - - if (isset($data[$key])) { - return $data[$key]; - } - - return null; - } - - /** - * @param string Channel name - * @param bool whether to strictly retrieve info of channels, not just aliases - * @return array|null - */ - function _channelInfo($channel, $noaliases = false) - { - if (!$this->_channelExists($channel, $noaliases)) { - return null; - } - - $fp = $this->_openChannelFile($channel, 'r'); - if ($fp === null) { - return null; - } - - $rt = get_magic_quotes_runtime(); - set_magic_quotes_runtime(0); - clearstatcache(); - $this->_closeChannelFile($fp); - $data = file_get_contents($this->_channelFileName($channel)); - set_magic_quotes_runtime($rt); - $data = unserialize($data); - return $data; - } - - function _listChannels() - { - $channellist = array(); - if (!file_exists($this->channelsdir) || !is_dir($this->channelsdir)) { - return array('pear.php.net', 'pecl.php.net', 'doc.php.net', '__uri'); - } - - $dp = opendir($this->channelsdir); - while ($ent = readdir($dp)) { - if ($ent{0} == '.' || substr($ent, -4) != '.reg') { - continue; - } - - if ($ent == '__uri.reg') { - $channellist[] = '__uri'; - continue; - } - - $channellist[] = str_replace('_', '/', substr($ent, 0, -4)); - } - - closedir($dp); - if (!in_array('pear.php.net', $channellist)) { - $channellist[] = 'pear.php.net'; - } - - if (!in_array('pecl.php.net', $channellist)) { - $channellist[] = 'pecl.php.net'; - } - - if (!in_array('doc.php.net', $channellist)) { - $channellist[] = 'doc.php.net'; - } - - - if (!in_array('__uri', $channellist)) { - $channellist[] = '__uri'; - } - - natsort($channellist); - return $channellist; - } - - function _listPackages($channel = false) - { - if ($channel && $this->_getChannelFromAlias($channel) != 'pear.php.net') { - return $this->_listChannelPackages($channel); - } - - if (!file_exists($this->statedir) || !is_dir($this->statedir)) { - return array(); - } - - $pkglist = array(); - $dp = opendir($this->statedir); - if (!$dp) { - return $pkglist; - } - - while ($ent = readdir($dp)) { - if ($ent{0} == '.' || substr($ent, -4) != '.reg') { - continue; - } - - $pkglist[] = substr($ent, 0, -4); - } - closedir($dp); - return $pkglist; - } - - function _listChannelPackages($channel) - { - $pkglist = array(); - if (!file_exists($this->_channelDirectoryName($channel)) || - !is_dir($this->_channelDirectoryName($channel))) { - return array(); - } - - $dp = opendir($this->_channelDirectoryName($channel)); - if (!$dp) { - return $pkglist; - } - - while ($ent = readdir($dp)) { - if ($ent{0} == '.' || substr($ent, -4) != '.reg') { - continue; - } - $pkglist[] = substr($ent, 0, -4); - } - - closedir($dp); - return $pkglist; - } - - function _listAllPackages() - { - $ret = array(); - foreach ($this->_listChannels() as $channel) { - $ret[$channel] = $this->_listPackages($channel); - } - - return $ret; - } - - /** - * Add an installed package to the registry - * @param string package name - * @param array package info (parsed by PEAR_Common::infoFrom*() methods) - * @return bool success of saving - * @access private - */ - function _addPackage($package, $info) - { - if ($this->_packageExists($package)) { - return false; - } - - $fp = $this->_openPackageFile($package, 'wb'); - if ($fp === null) { - return false; - } - - $info['_lastmodified'] = time(); - fwrite($fp, serialize($info)); - $this->_closePackageFile($fp); - if (isset($info['filelist'])) { - $this->_rebuildFileMap(); - } - - return true; - } - - /** - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @return bool - * @access private - */ - function _addPackage2($info) - { - if (!is_a($info, 'PEAR_PackageFile_v1') && !is_a($info, 'PEAR_PackageFile_v2')) { - return false; - } - - if (!$info->validate()) { - if (class_exists('PEAR_Common')) { - $ui = PEAR_Frontend::singleton(); - if ($ui) { - foreach ($info->getValidationWarnings() as $err) { - $ui->log($err['message'], true); - } - } - } - return false; - } - - $channel = $info->getChannel(); - $package = $info->getPackage(); - $save = $info; - if ($this->_packageExists($package, $channel)) { - return false; - } - - if (!$this->_channelExists($channel, true)) { - return false; - } - - $info = $info->toArray(true); - if (!$info) { - return false; - } - - $fp = $this->_openPackageFile($package, 'wb', $channel); - if ($fp === null) { - return false; - } - - $info['_lastmodified'] = time(); - fwrite($fp, serialize($info)); - $this->_closePackageFile($fp); - $this->_rebuildFileMap(); - return true; - } - - /** - * @param string Package name - * @param array parsed package.xml 1.0 - * @param bool this parameter is only here for BC. Don't use it. - * @access private - */ - function _updatePackage($package, $info, $merge = true) - { - $oldinfo = $this->_packageInfo($package); - if (empty($oldinfo)) { - return false; - } - - $fp = $this->_openPackageFile($package, 'w'); - if ($fp === null) { - return false; - } - - if (is_object($info)) { - $info = $info->toArray(); - } - $info['_lastmodified'] = time(); - - $newinfo = $info; - if ($merge) { - $info = array_merge($oldinfo, $info); - } else { - $diff = $info; - } - - fwrite($fp, serialize($info)); - $this->_closePackageFile($fp); - if (isset($newinfo['filelist'])) { - $this->_rebuildFileMap(); - } - - return true; - } - - /** - * @param PEAR_PackageFile_v1|PEAR_PackageFile_v2 - * @return bool - * @access private - */ - function _updatePackage2($info) - { - if (!$this->_packageExists($info->getPackage(), $info->getChannel())) { - return false; - } - - $fp = $this->_openPackageFile($info->getPackage(), 'w', $info->getChannel()); - if ($fp === null) { - return false; - } - - $save = $info; - $info = $save->getArray(true); - $info['_lastmodified'] = time(); - fwrite($fp, serialize($info)); - $this->_closePackageFile($fp); - $this->_rebuildFileMap(); - return true; - } - - /** - * @param string Package name - * @param string Channel name - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null - * @access private - */ - function &_getPackage($package, $channel = 'pear.php.net') - { - $info = $this->_packageInfo($package, null, $channel); - if ($info === null) { - return $info; - } - - $a = $this->_config; - if (!$a) { - $this->_config = &new PEAR_Config; - $this->_config->set('php_dir', $this->statedir); - } - - if (!class_exists('PEAR_PackageFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile.php'; - } - - $pkg = &new PEAR_PackageFile($this->_config); - $pf = &$pkg->fromArray($info); - return $pf; - } - - /** - * @param string channel name - * @param bool whether to strictly retrieve channel names - * @return PEAR_ChannelFile|PEAR_Error - * @access private - */ - function &_getChannel($channel, $noaliases = false) - { - $ch = false; - if ($this->_channelExists($channel, $noaliases)) { - $chinfo = $this->_channelInfo($channel, $noaliases); - if ($chinfo) { - if (!class_exists('PEAR_ChannelFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; - } - - $ch = &PEAR_ChannelFile::fromArrayWithErrors($chinfo); - } - } - - if ($ch) { - if ($ch->validate()) { - return $ch; - } - - foreach ($ch->getErrors(true) as $err) { - $message = $err['message'] . "\n"; - } - - $ch = PEAR::raiseError($message); - return $ch; - } - - if ($this->_getChannelFromAlias($channel) == 'pear.php.net') { - // the registry is not properly set up, so use defaults - if (!class_exists('PEAR_ChannelFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; - } - - $pear_channel = new PEAR_ChannelFile; - $pear_channel->setName('pear.php.net'); - $pear_channel->setAlias('pear'); - $pear_channel->setSummary('PHP Extension and Application Repository'); - $pear_channel->setDefaultPEARProtocols(); - $pear_channel->setBaseURL('REST1.0', 'http://pear.php.net/rest/'); - $pear_channel->setBaseURL('REST1.1', 'http://pear.php.net/rest/'); - return $pear_channel; - } - - if ($this->_getChannelFromAlias($channel) == 'pecl.php.net') { - // the registry is not properly set up, so use defaults - if (!class_exists('PEAR_ChannelFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; - } - $pear_channel = new PEAR_ChannelFile; - $pear_channel->setName('pecl.php.net'); - $pear_channel->setAlias('pecl'); - $pear_channel->setSummary('PHP Extension Community Library'); - $pear_channel->setDefaultPEARProtocols(); - $pear_channel->setBaseURL('REST1.0', 'http://pecl.php.net/rest/'); - $pear_channel->setBaseURL('REST1.1', 'http://pecl.php.net/rest/'); - $pear_channel->setValidationPackage('PEAR_Validator_PECL', '1.0'); - return $pear_channel; - } - - if ($this->_getChannelFromAlias($channel) == 'doc.php.net') { - // the registry is not properly set up, so use defaults - if (!class_exists('PEAR_ChannelFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; - } - - $doc_channel = new PEAR_ChannelFile; - $doc_channel->setName('doc.php.net'); - $doc_channel->setAlias('phpdocs'); - $doc_channel->setSummary('PHP Documentation Team'); - $doc_channel->setDefaultPEARProtocols(); - $doc_channel->setBaseURL('REST1.0', 'http://doc.php.net/Chiara_PEAR_Server_REST/'); - $doc_channel->setBaseURL('REST1.1', 'http://doc.php.net/Chiara_PEAR_Server_REST/'); - return $doc_channel; - } - - - if ($this->_getChannelFromAlias($channel) == '__uri') { - // the registry is not properly set up, so use defaults - if (!class_exists('PEAR_ChannelFile')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/ChannelFile.php'; - } - - $private = new PEAR_ChannelFile; - $private->setName('__uri'); - $private->setDefaultPEARProtocols(); - $private->setBaseURL('REST1.0', '****'); - $private->setSummary('Pseudo-channel for static packages'); - return $private; - } - - return $ch; - } - - /** - * @param string Package name - * @param string Channel name - * @return bool - */ - function packageExists($package, $channel = 'pear.php.net') - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_packageExists($package, $channel); - $this->_unlock(); - return $ret; - } - - // }}} - - // {{{ channelExists() - - /** - * @param string channel name - * @param bool if true, then aliases will be ignored - * @return bool - */ - function channelExists($channel, $noaliases = false) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_channelExists($channel, $noaliases); - $this->_unlock(); - return $ret; - } - - // }}} - - // {{{ isAlias() - - /** - * Determines whether the parameter is an alias of a channel - * @param string - * @return bool - */ - function isAlias($alias) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_isChannelAlias($alias); - $this->_unlock(); - return $ret; - } - - // }}} - // {{{ packageInfo() - - /** - * @param string|null - * @param string|null - * @param string - * @return array|null - */ - function packageInfo($package = null, $key = null, $channel = 'pear.php.net') - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_packageInfo($package, $key, $channel); - $this->_unlock(); - return $ret; - } - - // }}} - // {{{ channelInfo() - - /** - * Retrieve a raw array of channel data. - * - * Do not use this, instead use {@link getChannel()} for normal - * operations. Array structure is undefined in this method - * @param string channel name - * @param bool whether to strictly retrieve information only on non-aliases - * @return array|null|PEAR_Error - */ - function channelInfo($channel = null, $noaliases = false) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_channelInfo($channel, $noaliases); - $this->_unlock(); - return $ret; - } - - // }}} - - /** - * @param string - */ - function channelName($channel) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_getChannelFromAlias($channel); - $this->_unlock(); - return $ret; - } - - /** - * @param string - */ - function channelAlias($channel) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_getAlias($channel); - $this->_unlock(); - return $ret; - } - // {{{ listPackages() - - function listPackages($channel = false) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_listPackages($channel); - $this->_unlock(); - return $ret; - } - - // }}} - // {{{ listAllPackages() - - function listAllPackages() - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_listAllPackages(); - $this->_unlock(); - return $ret; - } - - // }}} - // {{{ listChannel() - - function listChannels() - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = $this->_listChannels(); - $this->_unlock(); - return $ret; - } - - // }}} - // {{{ addPackage() - - /** - * Add an installed package to the registry - * @param string|PEAR_PackageFile_v1|PEAR_PackageFile_v2 package name or object - * that will be passed to {@link addPackage2()} - * @param array package info (parsed by PEAR_Common::infoFrom*() methods) - * @return bool success of saving - */ - function addPackage($package, $info) - { - if (is_object($info)) { - return $this->addPackage2($info); - } - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - $ret = $this->_addPackage($package, $info); - $this->_unlock(); - if ($ret) { - if (!class_exists('PEAR_PackageFile_v1')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; - } - $pf = new PEAR_PackageFile_v1; - $pf->setConfig($this->_config); - $pf->fromArray($info); - $this->_dependencyDB->uninstallPackage($pf); - $this->_dependencyDB->installPackage($pf); - } - return $ret; - } - - // }}} - // {{{ addPackage2() - - function addPackage2($info) - { - if (!is_object($info)) { - return $this->addPackage($info['package'], $info); - } - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - $ret = $this->_addPackage2($info); - $this->_unlock(); - if ($ret) { - $this->_dependencyDB->uninstallPackage($info); - $this->_dependencyDB->installPackage($info); - } - return $ret; - } - - // }}} - // {{{ updateChannel() - - /** - * For future expandibility purposes, separate this - * @param PEAR_ChannelFile - */ - function updateChannel($channel, $lastmodified = null) - { - if ($channel->getName() == '__uri') { - return false; - } - return $this->addChannel($channel, $lastmodified, true); - } - - // }}} - // {{{ deleteChannel() - - /** - * Deletion fails if there are any packages installed from the channel - * @param string|PEAR_ChannelFile channel name - * @return boolean|PEAR_Error True on deletion, false if it doesn't exist - */ - function deleteChannel($channel) - { - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - $ret = $this->_deleteChannel($channel); - $this->_unlock(); - if ($ret && is_a($this->_config, 'PEAR_Config')) { - $this->_config->setChannels($this->listChannels()); - } - return $ret; - } - - // }}} - // {{{ addChannel() - - /** - * @param PEAR_ChannelFile Channel object - * @param string Last-Modified header from HTTP for caching - * @return boolean|PEAR_Error True on creation, false if it already exists - */ - function addChannel($channel, $lastmodified = false, $update = false) - { - if (!is_a($channel, 'PEAR_ChannelFile')) { - return false; - } - if (!$channel->validate()) { - return false; - } - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - $ret = $this->_addChannel($channel, $update, $lastmodified); - $this->_unlock(); - if (!$update && $ret && is_a($this->_config, 'PEAR_Config')) { - $this->_config->setChannels($this->listChannels()); - } - return $ret; - } - - // }}} - // {{{ deletePackage() - - function deletePackage($package, $channel = 'pear.php.net') - { - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - $file = $this->_packageFileName($package, $channel); - if (file_exists($file)) { - $ret = @unlink($file); - } else { - $ret = false; - } - $this->_rebuildFileMap(); - $this->_unlock(); - $p = array('channel' => $channel, 'package' => $package); - $this->_dependencyDB->uninstallPackage($p); - return $ret; - } - - // }}} - // {{{ updatePackage() - - function updatePackage($package, $info, $merge = true) - { - if (is_object($info)) { - return $this->updatePackage2($info, $merge); - } - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - $ret = $this->_updatePackage($package, $info, $merge); - $this->_unlock(); - if ($ret) { - if (!class_exists('PEAR_PackageFile_v1')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/PackageFile/v1.php'; - } - $pf = new PEAR_PackageFile_v1; - $pf->setConfig($this->_config); - $pf->fromArray($this->packageInfo($package)); - $this->_dependencyDB->uninstallPackage($pf); - $this->_dependencyDB->installPackage($pf); - } - return $ret; - } - - // }}} - // {{{ updatePackage2() - - function updatePackage2($info) - { - - if (!is_object($info)) { - return $this->updatePackage($info['package'], $info, $merge); - } - - if (!$info->validate(PEAR_VALIDATE_DOWNLOADING)) { - return false; - } - - if (PEAR::isError($e = $this->_lock(LOCK_EX))) { - return $e; - } - - $ret = $this->_updatePackage2($info); - $this->_unlock(); - if ($ret) { - $this->_dependencyDB->uninstallPackage($info); - $this->_dependencyDB->installPackage($info); - } - - return $ret; - } - - // }}} - // {{{ getChannel() - /** - * @param string channel name - * @param bool whether to strictly return raw channels (no aliases) - * @return PEAR_ChannelFile|PEAR_Error - */ - function &getChannel($channel, $noaliases = false) - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $ret = &$this->_getChannel($channel, $noaliases); - $this->_unlock(); - if (!$ret) { - return PEAR::raiseError('Unknown channel: ' . $channel); - } - return $ret; - } - - // }}} - // {{{ getPackage() - /** - * @param string package name - * @param string channel name - * @return PEAR_PackageFile_v1|PEAR_PackageFile_v2|null - */ - function &getPackage($package, $channel = 'pear.php.net') - { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $pf = &$this->_getPackage($package, $channel); - $this->_unlock(); - return $pf; - } - - // }}} - - /** - * Get PEAR_PackageFile_v[1/2] objects representing the contents of - * a dependency group that are installed. - * - * This is used at uninstall-time - * @param array - * @return array|false - */ - function getInstalledGroup($group) - { - $ret = array(); - if (isset($group['package'])) { - if (!isset($group['package'][0])) { - $group['package'] = array($group['package']); - } - foreach ($group['package'] as $package) { - $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; - $p = &$this->getPackage($package['name'], $depchannel); - if ($p) { - $save = &$p; - $ret[] = &$save; - } - } - } - if (isset($group['subpackage'])) { - if (!isset($group['subpackage'][0])) { - $group['subpackage'] = array($group['subpackage']); - } - foreach ($group['subpackage'] as $package) { - $depchannel = isset($package['channel']) ? $package['channel'] : '__uri'; - $p = &$this->getPackage($package['name'], $depchannel); - if ($p) { - $save = &$p; - $ret[] = &$save; - } - } - } - if (!count($ret)) { - return false; - } - return $ret; - } - - // {{{ getChannelValidator() - /** - * @param string channel name - * @return PEAR_Validate|false - */ - function &getChannelValidator($channel) - { - $chan = $this->getChannel($channel); - if (PEAR::isError($chan)) { - return $chan; - } - $val = $chan->getValidationObject(); - return $val; - } - // }}} - // {{{ getChannels() - /** - * @param string channel name - * @return array an array of PEAR_ChannelFile objects representing every installed channel - */ - function &getChannels() - { - $ret = array(); - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - foreach ($this->_listChannels() as $channel) { - $e = &$this->_getChannel($channel); - if (!$e || PEAR::isError($e)) { - continue; - } - $ret[] = $e; - } - $this->_unlock(); - return $ret; - } - - // }}} - // {{{ checkFileMap() - - /** - * Test whether a file or set of files belongs to a package. - * - * If an array is passed in - * @param string|array file path, absolute or relative to the pear - * install dir - * @param string|array name of PEAR package or array('package' => name, 'channel' => - * channel) of a package that will be ignored - * @param string API version - 1.1 will exclude any files belonging to a package - * @param array private recursion variable - * @return array|false which package and channel the file belongs to, or an empty - * string if the file does not belong to an installed package, - * or belongs to the second parameter's package - */ - function checkFileMap($path, $package = false, $api = '1.0', $attrs = false) - { - if (is_array($path)) { - static $notempty; - if (empty($notempty)) { - if (!class_exists('PEAR_Installer_Role')) { - require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Installer/Role.php'; - } - $notempty = create_function('$a','return !empty($a);'); - } - $package = is_array($package) ? array(strtolower($package[0]), strtolower($package[1])) - : strtolower($package); - $pkgs = array(); - foreach ($path as $name => $attrs) { - if (is_array($attrs)) { - if (isset($attrs['install-as'])) { - $name = $attrs['install-as']; - } - if (!in_array($attrs['role'], PEAR_Installer_Role::getInstallableRoles())) { - // these are not installed - continue; - } - if (!in_array($attrs['role'], PEAR_Installer_Role::getBaseinstallRoles())) { - $attrs['baseinstalldir'] = is_array($package) ? $package[1] : $package; - } - if (isset($attrs['baseinstalldir'])) { - $name = $attrs['baseinstalldir'] . DIRECTORY_SEPARATOR . $name; - } - } - $pkgs[$name] = $this->checkFileMap($name, $package, $api, $attrs); - if (PEAR::isError($pkgs[$name])) { - return $pkgs[$name]; - } - } - return array_filter($pkgs, $notempty); - } - if (empty($this->filemap_cache)) { - if (PEAR::isError($e = $this->_lock(LOCK_SH))) { - return $e; - } - $err = $this->_readFileMap(); - $this->_unlock(); - if (PEAR::isError($err)) { - return $err; - } - } - if (!$attrs) { - $attrs = array('role' => 'php'); // any old call would be for PHP role only - } - if (isset($this->filemap_cache[$attrs['role']][$path])) { - if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { - return false; - } - return $this->filemap_cache[$attrs['role']][$path]; - } - $l = strlen($this->install_dir); - if (substr($path, 0, $l) == $this->install_dir) { - $path = preg_replace('!^'.DIRECTORY_SEPARATOR.'+!', '', substr($path, $l)); - } - if (isset($this->filemap_cache[$attrs['role']][$path])) { - if ($api >= '1.1' && $this->filemap_cache[$attrs['role']][$path] == $package) { - return false; - } - return $this->filemap_cache[$attrs['role']][$path]; - } - return false; - } - - // }}} - // {{{ flush() - /** - * Force a reload of the filemap - * @since 1.5.0RC3 - */ - function flushFileMap() - { - $this->filemap_cache = null; - clearstatcache(); // ensure that the next read gets the full, current filemap - } - - // }}} - // {{{ apiVersion() - /** - * Get the expected API version. Channels API is version 1.1, as it is backwards - * compatible with 1.0 - * @return string - */ - function apiVersion() - { - return '1.1'; - } - // }}} - - - /** - * Parse a package name, or validate a parsed package name array - * @param string|array pass in an array of format - * array( - * 'package' => 'pname', - * ['channel' => 'channame',] - * ['version' => 'version',] - * ['state' => 'state',] - * ['group' => 'groupname']) - * or a string of format - * [channel://][channame/]pname[-version|-state][/group=groupname] - * @return array|PEAR_Error - */ - function parsePackageName($param, $defaultchannel = 'pear.php.net') - { - $saveparam = $param; - if (is_array($param)) { - // convert to string for error messages - $saveparam = $this->parsedPackageNameToString($param); - // process the array - if (!isset($param['package'])) { - return PEAR::raiseError('parsePackageName(): array $param ' . - 'must contain a valid package name in index "param"', - 'package', null, null, $param); - } - if (!isset($param['uri'])) { - if (!isset($param['channel'])) { - $param['channel'] = $defaultchannel; - } - } else { - $param['channel'] = '__uri'; - } - } else { - $components = @parse_url((string) $param); - if (isset($components['scheme'])) { - if ($components['scheme'] == 'http') { - // uri package - $param = array('uri' => $param, 'channel' => '__uri'); - } elseif($components['scheme'] != 'channel') { - return PEAR::raiseError('parsePackageName(): only channel:// uris may ' . - 'be downloaded, not "' . $param . '"', 'invalid', null, null, $param); - } - } - if (!isset($components['path'])) { - return PEAR::raiseError('parsePackageName(): array $param ' . - 'must contain a valid package name in "' . $param . '"', - 'package', null, null, $param); - } - if (isset($components['host'])) { - // remove the leading "/" - $components['path'] = substr($components['path'], 1); - } - if (!isset($components['scheme'])) { - if (strpos($components['path'], '/') !== false) { - if ($components['path']{0} == '/') { - return PEAR::raiseError('parsePackageName(): this is not ' . - 'a package name, it begins with "/" in "' . $param . '"', - 'invalid', null, null, $param); - } - $parts = explode('/', $components['path']); - $components['host'] = array_shift($parts); - if (count($parts) > 1) { - $components['path'] = array_pop($parts); - $components['host'] .= '/' . implode('/', $parts); - } else { - $components['path'] = implode('/', $parts); - } - } else { - $components['host'] = $defaultchannel; - } - } else { - if (strpos($components['path'], '/')) { - $parts = explode('/', $components['path']); - $components['path'] = array_pop($parts); - $components['host'] .= '/' . implode('/', $parts); - } - } - - if (is_array($param)) { - $param['package'] = $components['path']; - } else { - $param = array( - 'package' => $components['path'] - ); - if (isset($components['host'])) { - $param['channel'] = $components['host']; - } - } - if (isset($components['fragment'])) { - $param['group'] = $components['fragment']; - } - if (isset($components['user'])) { - $param['user'] = $components['user']; - } - if (isset($components['pass'])) { - $param['pass'] = $components['pass']; - } - if (isset($components['query'])) { - parse_str($components['query'], $param['opts']); - } - // check for extension - $pathinfo = pathinfo($param['package']); - if (isset($pathinfo['extension']) && - in_array(strtolower($pathinfo['extension']), array('tgz', 'tar'))) { - $param['extension'] = $pathinfo['extension']; - $param['package'] = substr($pathinfo['basename'], 0, - strlen($pathinfo['basename']) - 4); - } - // check for version - if (strpos($param['package'], '-')) { - $test = explode('-', $param['package']); - if (count($test) != 2) { - return PEAR::raiseError('parsePackageName(): only one version/state ' . - 'delimiter "-" is allowed in "' . $saveparam . '"', - 'version', null, null, $param); - } - list($param['package'], $param['version']) = $test; - } - } - // validation - $info = $this->channelExists($param['channel']); - if (PEAR::isError($info)) { - return $info; - } - if (!$info) { - return PEAR::raiseError('unknown channel "' . $param['channel'] . - '" in "' . $saveparam . '"', 'channel', null, null, $param); - } - $chan = $this->getChannel($param['channel']); - if (PEAR::isError($chan)) { - return $chan; - } - if (!$chan) { - return PEAR::raiseError("Exception: corrupt registry, could not " . - "retrieve channel " . $param['channel'] . " information", - 'registry', null, null, $param); - } - $param['channel'] = $chan->getName(); - $validate = $chan->getValidationObject(); - $vpackage = $chan->getValidationPackage(); - // validate package name - if (!$validate->validPackageName($param['package'], $vpackage['_content'])) { - return PEAR::raiseError('parsePackageName(): invalid package name "' . - $param['package'] . '" in "' . $saveparam . '"', - 'package', null, null, $param); - } - if (isset($param['group'])) { - if (!PEAR_Validate::validGroupName($param['group'])) { - return PEAR::raiseError('parsePackageName(): dependency group "' . $param['group'] . - '" is not a valid group name in "' . $saveparam . '"', 'group', null, null, - $param); - } - } - if (isset($param['state'])) { - if (!in_array(strtolower($param['state']), $validate->getValidStates())) { - return PEAR::raiseError('parsePackageName(): state "' . $param['state'] - . '" is not a valid state in "' . $saveparam . '"', - 'state', null, null, $param); - } - } - if (isset($param['version'])) { - if (isset($param['state'])) { - return PEAR::raiseError('parsePackageName(): cannot contain both ' . - 'a version and a stability (state) in "' . $saveparam . '"', - 'version/state', null, null, $param); - } - // check whether version is actually a state - if (in_array(strtolower($param['version']), $validate->getValidStates())) { - $param['state'] = strtolower($param['version']); - unset($param['version']); - } else { - if (!$validate->validVersion($param['version'])) { - return PEAR::raiseError('parsePackageName(): "' . $param['version'] . - '" is neither a valid version nor a valid state in "' . - $saveparam . '"', 'version/state', null, null, $param); - } - } - } - return $param; - } - - /** - * @param array - * @return string - */ - function parsedPackageNameToString($parsed, $brief = false) - { - if (is_string($parsed)) { - return $parsed; - } - if (is_object($parsed)) { - $p = $parsed; - $parsed = array( - 'package' => $p->getPackage(), - 'channel' => $p->getChannel(), - 'version' => $p->getVersion(), - ); - } - if (isset($parsed['uri'])) { - return $parsed['uri']; - } - if ($brief) { - if ($channel = $this->channelAlias($parsed['channel'])) { - return $channel . '/' . $parsed['package']; - } - } - $upass = ''; - if (isset($parsed['user'])) { - $upass = $parsed['user']; - if (isset($parsed['pass'])) { - $upass .= ':' . $parsed['pass']; - } - $upass = "$upass@"; - } - $ret = 'channel://' . $upass . $parsed['channel'] . '/' . $parsed['package']; - if (isset($parsed['version']) || isset($parsed['state'])) { - $ver = isset($parsed['version']) ? $parsed['version'] : ''; - $ver .= isset($parsed['state']) ? $parsed['state'] : ''; - $ret .= '-' . $ver; - } - if (isset($parsed['extension'])) { - $ret .= '.' . $parsed['extension']; - } - if (isset($parsed['opts'])) { - $ret .= '?'; - foreach ($parsed['opts'] as $name => $value) { - $parsed['opts'][$name] = "$name=$value"; - } - $ret .= implode('&', $parsed['opts']); - } - if (isset($parsed['group'])) { - $ret .= '#' . $parsed['group']; - } - return $ret; - } } * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: REST.php,v 1.40 2009/03/26 23:12:46 dufuz Exp $ + * @version CVS: $Id: REST.php 286489 2009-07-29 05:59:08Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -83942,7 +84581,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/XMLParser.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -83953,7 +84592,7 @@ class PEAR_REST function PEAR_REST(&$config, $options = array()) { - $this->config = &$config; + $this->config = &$config; $this->_options = $options; } @@ -83970,7 +84609,6 @@ class PEAR_REST */ function retrieveCacheFirst($url, $accept = false, $forcestring = false, $channel = false) { - $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . md5($url) . 'rest.cachefile'; @@ -84127,11 +84765,9 @@ class PEAR_REST */ function saveCache($url, $contents, $lastmodified, $nochange = false, $cacheid = null) { - $cacheidfile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . - md5($url) . 'rest.cacheid'; - - $cachefile = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . - md5($url) . 'rest.cachefile'; + $cachedir = $this->config->get('cache_dir') . DIRECTORY_SEPARATOR . md5($url); + $cacheidfile = $cachedir . 'rest.cacheid'; + $cachefile = $cachedir . 'rest.cachefile'; if ($cacheid === null && $nochange) { $cacheid = unserialize(implode('', file($cacheidfile))); @@ -84265,7 +84901,7 @@ class PEAR_REST } $request .= $ifmodifiedsince . - "User-Agent: PEAR/1.8.0/PHP/" . PHP_VERSION . "\r\n"; + "User-Agent: PEAR/1.9.0/PHP/" . PHP_VERSION . "\r\n"; $username = $this->config->get('username', null, $channel); $password = $this->config->get('password', null, $channel); @@ -84373,7 +85009,7 @@ class PEAR_REST * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: 10.php,v 1.60 2009/03/07 23:09:56 dufuz Exp $ + * @version CVS: $Id: 10.php 287558 2009-08-21 22:21:28Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a12 */ @@ -84391,7 +85027,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/REST.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a12 */ @@ -84425,16 +85061,18 @@ class PEAR_REST_10 */ function getDownloadURL($base, $packageinfo, $prefstate, $installed, $channel = false) { - $channel = $packageinfo['channel']; - $package = $packageinfo['package']; $states = $this->betterStates($prefstate, true); if (!$states) { return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } - $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; - $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; - $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml', false, false, $channel); + $channel = $packageinfo['channel']; + $package = $packageinfo['package']; + $state = isset($packageinfo['state']) ? $packageinfo['state'] : null; + $version = isset($packageinfo['version']) ? $packageinfo['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); if (PEAR::isError($info)) { return PEAR::raiseError('No releases available for package "' . $channel . '/' . $package . '"'); @@ -84486,22 +85124,27 @@ class PEAR_REST_10 function getDepDownloadURL($base, $xsdversion, $dependency, $deppackage, $prefstate = 'stable', $installed = false, $channel = false) { - $channel = $dependency['channel']; - $package = $dependency['name']; $states = $this->betterStates($prefstate, true); if (!$states) { return PEAR::raiseError('"' . $prefstate . '" is not a valid state'); } - $state = isset($dependency['state']) ? $dependency['state'] : null; - $version = isset($dependency['version']) ? $dependency['version'] : null; - $info = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . '/allreleases.xml', false, false, $channel); + + $channel = $dependency['channel']; + $package = $dependency['name']; + $state = isset($dependency['state']) ? $dependency['state'] : null; + $version = isset($dependency['version']) ? $dependency['version'] : null; + $restFile = $base . 'r/' . strtolower($package) . '/allreleases.xml'; + + $info = $this->_rest->retrieveData($restFile, false, false, $channel); if (PEAR::isError($info)) { return PEAR::raiseError('Package "' . $deppackage['channel'] . '/' . $deppackage['package'] . '" dependency "' . $channel . '/' . $package . '" has no releases'); } + if (!is_array($info) || !isset($info['r'])) { return false; } + $exclude = array(); $min = $max = $recommended = false; if ($xsdversion == '1.0') { @@ -84619,19 +85262,23 @@ class PEAR_REST_10 if (!$found) { $release = $info['r'][0]; } - $pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . strtolower($package) . '/' . + + $packageLower = strtolower($package); + $pinfo = $this->_rest->retrieveCacheFirst($base . 'p/' . $packageLower . '/' . 'info.xml', false, false, $channel); if (PEAR::isError($pinfo)) { return PEAR::raiseError('Package "' . $package . '" does not have REST info xml available'); } - $releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . + + $releaseinfo = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' . $release['v'] . '.xml', false, false, $channel); if (PEAR::isError($releaseinfo)) { return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . '" does not have REST xml available'); } - $packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . strtolower($package) . '/' . + + $packagexml = $this->_rest->retrieveCacheFirst($base . 'r/' . $packageLower . '/' . 'deps.' . $release['v'] . '.txt', false, true, $channel); if (PEAR::isError($packagexml)) { return PEAR::raiseError('Package "' . $package . '" Version "' . $release['v'] . @@ -84642,39 +85289,49 @@ class PEAR_REST_10 if (!$packagexml) { $packagexml = array(); } - $allinfo = $this->_rest->retrieveData($base . 'r/' . strtolower($package) . + + $allinfo = $this->_rest->retrieveData($base . 'r/' . $packageLower . '/allreleases.xml', false, false, $channel); if (!is_array($allinfo['r']) || !isset($allinfo['r'][0])) { $allinfo['r'] = array($allinfo['r']); } + $compatible = false; foreach ($allinfo['r'] as $release) { if ($release['v'] != $releaseinfo['v']) { continue; } + if (!isset($release['co'])) { break; } + $compatible = array(); if (!is_array($release['co']) || !isset($release['co'][0])) { $release['co'] = array($release['co']); } + foreach ($release['co'] as $entry) { $comp = array(); - $comp['name'] = $entry['p']; + $comp['name'] = $entry['p']; $comp['channel'] = $entry['c']; - $comp['min'] = $entry['min']; - $comp['max'] = $entry['max']; + $comp['min'] = $entry['min']; + $comp['max'] = $entry['max']; if (isset($entry['x']) && !is_array($entry['x'])) { $comp['exclude'] = $entry['x']; } + $compatible[] = $comp; } + if (count($compatible) == 1) { $compatible = $compatible[0]; } + break; } + + $deprecated = false; if (isset($pinfo['dc']) && isset($pinfo['dp'])) { if (is_array($pinfo['dp'])) { $deprecated = array('channel' => (string) $pinfo['dc'], @@ -84683,30 +85340,24 @@ class PEAR_REST_10 $deprecated = array('channel' => (string) $pinfo['dc'], 'package' => trim($pinfo['dp'])); } - } else { - $deprecated = false; } + + $return = array( + 'version' => $releaseinfo['v'], + 'info' => $packagexml, + 'package' => $releaseinfo['p']['_content'], + 'stability' => $releaseinfo['st'], + 'compatible' => $compatible, + 'deprecated' => $deprecated, + ); + if ($found) { - return - array('version' => $releaseinfo['v'], - 'info' => $packagexml, - 'package' => $releaseinfo['p']['_content'], - 'stability' => $releaseinfo['st'], - 'url' => $releaseinfo['g'], - 'compatible' => $compatible, - 'deprecated' => $deprecated, - ); - } else { - return - array('version' => $releaseinfo['v'], - 'package' => $releaseinfo['p']['_content'], - 'stability' => $releaseinfo['st'], - 'info' => $packagexml, - 'compatible' => $compatible, - 'deprecated' => $deprecated, - 'php' => $phpversion - ); + $return['url'] = $releaseinfo['g']; + return $return; } + + $return['php'] = $phpversion; + return $return; } function listPackages($base, $channel = false) @@ -84715,12 +85366,15 @@ class PEAR_REST_10 if (PEAR::isError($packagelist)) { return $packagelist; } + if (!is_array($packagelist) || !isset($packagelist['p'])) { return array(); } + if (!is_array($packagelist['p'])) { $packagelist['p'] = array($packagelist['p']); } + return $packagelist['p']; } @@ -84741,10 +85395,12 @@ class PEAR_REST_10 if (PEAR::isError($packagelist)) { return $packagelist; } + if (!is_array($packagelist) || !isset($packagelist['p'])) { $ret = array(); return $ret; } + if (!is_array($packagelist['p'])) { $packagelist['p'] = array($packagelist['p']); } @@ -84761,6 +85417,7 @@ class PEAR_REST_10 $categories[$cat] = $inf['ca']; } } + return array_values($categories); } @@ -84779,9 +85436,11 @@ class PEAR_REST_10 if (PEAR::isError($packagelist)) { return $packagelist; } + if (!is_array($packagelist) || !isset($packagelist['p'])) { return array(); } + if (!is_array($packagelist['p']) || !isset($packagelist['p'][0])) { // only 1 pkg $packagelist = array($packagelist['p']); @@ -84825,7 +85484,7 @@ class PEAR_REST_10 } if ($this->_rest->config->get('verbose') > 0) { $ui = &PEAR_Frontend::singleton(); - $ui->log('Retrieving data...0%', false); + $ui->log('Retrieving data...0%', true); } $ret = array(); if (!is_array($packagelist) || !isset($packagelist['p'])) { @@ -86232,7 +86891,7 @@ Double-click this file to add it to the current user registry. * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Common.php,v 1.20 2009/02/25 00:15:49 dufuz Exp $ + * @version CVS: $Id: Common.php 276394 2009-02-25 00:15:49Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -86270,7 +86929,7 @@ define('PEAR_TASK_PACKAGEANDINSTALL', 3); * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 * @abstract @@ -86433,7 +87092,7 @@ class PEAR_Task_Common * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Postinstallscript.php,v 1.22 2009/02/24 23:45:56 dufuz Exp $ + * @version CVS: $Id: Postinstallscript.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -86451,7 +87110,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Common.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -86755,7 +87414,7 @@ class PEAR_Task_Postinstallscript extends PEAR_Task_Common * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: rw.php,v 1.14 2009/02/24 23:45:32 dufuz Exp $ + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a10 */ @@ -86770,7 +87429,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Postinstallscript.p * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a10 */ @@ -86923,7 +87582,7 @@ class PEAR_Task_Postinstallscript_rw extends PEAR_Task_Postinstallscript * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Replace.php,v 1.19 2009/02/25 00:15:49 dufuz Exp $ + * @version CVS: $Id: Replace.php 276394 2009-02-25 00:15:49Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -86938,7 +87597,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Common.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -87087,66 +87746,66 @@ class PEAR_Task_Replace extends PEAR_Task_Common return $contents; } } -?> - read/write version - * - * PHP versions 4 and 5 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: rw.php,v 1.5 2009/02/24 23:45:44 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a10 - */ -/** - * Base class - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Replace.php'; -/** - * Abstracts the replace task xml. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a10 - */ -class PEAR_Task_Replace_rw extends PEAR_Task_Replace -{ - function PEAR_Task_Replace_rw(&$pkg, &$config, &$logger, $fileXml) - { - parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); - $this->_contents = $fileXml; - $this->_pkg = &$pkg; - $this->_params = array(); - } - - function validate() - { - return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents); - } - - function setInfo($from, $to, $type) - { - $this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type)); - } - - function getName() - { - return 'replace'; - } - - function getXml() - { - return $this->_params; - } -} +?> - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Replace.php'; +/** + * Abstracts the replace task xml. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Replace_rw extends PEAR_Task_Replace +{ + function PEAR_Task_Replace_rw(&$pkg, &$config, &$logger, $fileXml) + { + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + function validate() + { + return $this->validateXml($this->_pkg, $this->_params, $this->config, $this->_contents); + } + + function setInfo($from, $to, $type) + { + $this->_params = array('attribs' => array('from' => $from, 'to' => $to, 'type' => $type)); + } + + function getName() + { + return 'replace'; + } + + function getXml() + { + return $this->_params; + } +} ?> @@ -87158,7 +87817,7 @@ class PEAR_Task_Replace_rw extends PEAR_Task_Replace * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Unixeol.php,v 1.12 2009/02/25 00:15:49 dufuz Exp $ + * @version CVS: $Id: Unixeol.php 276394 2009-02-25 00:15:49Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -87173,7 +87832,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Common.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -87223,61 +87882,61 @@ class PEAR_Task_Unixeol extends PEAR_Task_Common return preg_replace("/\r\n|\n\r|\r|\n/", "\n", $contents); } } -?> - read/write version - * - * PHP versions 4 and 5 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: rw.php,v 1.6 2009/02/24 23:45:30 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a10 - */ -/** - * Base class - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Unixeol.php'; -/** - * Abstracts the unixeol task xml. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a10 - */ -class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol -{ - function PEAR_Task_Unixeol_rw(&$pkg, &$config, &$logger, $fileXml) - { - parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); - $this->_contents = $fileXml; - $this->_pkg = &$pkg; - $this->_params = array(); - } - - function validate() - { - return true; - } - - function getName() - { - return 'unixeol'; - } - - function getXml() - { - return ''; - } -} +?> - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Unixeol.php'; +/** + * Abstracts the unixeol task xml. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol +{ + function PEAR_Task_Unixeol_rw(&$pkg, &$config, &$logger, $fileXml) + { + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + function validate() + { + return true; + } + + function getName() + { + return 'unixeol'; + } + + function getXml() + { + return ''; + } +} ?> @@ -87289,7 +87948,7 @@ class PEAR_Task_Unixeol_rw extends PEAR_Task_Unixeol * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Windowseol.php,v 1.11 2009/02/25 00:15:49 dufuz Exp $ + * @version CVS: $Id: Windowseol.php 276394 2009-02-25 00:15:49Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -87304,7 +87963,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Common.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -87354,61 +88013,61 @@ class PEAR_Task_Windowseol extends PEAR_Task_Common return preg_replace("/\r\n|\n\r|\r|\n/", "\r\n", $contents); } } -?> - read/write version - * - * PHP versions 4 and 5 - * - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: rw.php,v 1.6 2009/02/24 23:45:20 dufuz Exp $ - * @link http://pear.php.net/package/PEAR - * @since File available since Release 1.4.0a10 - */ -/** - * Base class - */ -require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Windowseol.php'; -/** - * Abstracts the windowseol task xml. - * @category pear - * @package PEAR - * @author Greg Beaver - * @copyright 1997-2009 The Authors - * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 - * @link http://pear.php.net/package/PEAR - * @since Class available since Release 1.4.0a10 - */ -class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol -{ - function PEAR_Task_Windowseol_rw(&$pkg, &$config, &$logger, $fileXml) - { - parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); - $this->_contents = $fileXml; - $this->_pkg = &$pkg; - $this->_params = array(); - } - - function validate() - { - return true; - } - - function getName() - { - return 'windowseol'; - } - - function getXml() - { - return ''; - } -} +?> - read/write version + * + * PHP versions 4 and 5 + * + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version CVS: $Id: rw.php 276385 2009-02-24 23:46:03Z dufuz $ + * @link http://pear.php.net/package/PEAR + * @since File available since Release 1.4.0a10 + */ +/** + * Base class + */ +require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Task/Windowseol.php'; +/** + * Abstracts the windowseol task xml. + * @category pear + * @package PEAR + * @author Greg Beaver + * @copyright 1997-2009 The Authors + * @license http://opensource.org/licenses/bsd-license.php New BSD License + * @version Release: 1.9.0 + * @link http://pear.php.net/package/PEAR + * @since Class available since Release 1.4.0a10 + */ +class PEAR_Task_Windowseol_rw extends PEAR_Task_Windowseol +{ + function PEAR_Task_Windowseol_rw(&$pkg, &$config, &$logger, $fileXml) + { + parent::PEAR_Task_Common($config, $logger, PEAR_TASK_PACKAGE); + $this->_contents = $fileXml; + $this->_pkg = &$pkg; + $this->_params = array(); + } + + function validate() + { + return true; + } + + function getName() + { + return 'windowseol'; + } + + function getXml() + { + return ''; + } +} ?> * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: Validate.php,v 1.54 2009/02/24 23:38:23 dufuz Exp $ + * @version CVS: $Id: Validate.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -87443,7 +88102,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validator/PECL.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -88048,7 +88707,7 @@ class PEAR_Validate * @author Greg Beaver * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: PECL.php,v 1.10 2009/02/24 23:39:19 dufuz Exp $ + * @version CVS: $Id: PECL.php 276383 2009-02-24 23:39:37Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a5 */ @@ -88063,7 +88722,7 @@ require_once 'phar://install-pear-nozlib.phar/' . 'PEAR/Validate.php'; * @author Greg Beaver * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a5 */ @@ -88111,7 +88770,7 @@ class PEAR_Validator_PECL extends PEAR_Validate * @author Stephan Schmidt (original XML_Unserializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license New BSD License - * @version CVS: $Id: XMLParser.php,v 1.22 2009/03/08 00:45:39 dufuz Exp $ + * @version CVS: $Id: XMLParser.php 282970 2009-06-28 23:10:07Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 1.4.0a1 */ @@ -88124,7 +88783,7 @@ class PEAR_Validator_PECL extends PEAR_Validate * @author Stephan Schmidt (original XML_Unserializer code) * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license New BSD License - * @version Release: 1.8.0 + * @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 1.4.0a1 */ @@ -88146,13 +88805,13 @@ class PEAR_XMLParser * stack for all data that is found * @var array $_dataStack */ - var $_dataStack = array(); + var $_dataStack = array(); /** * stack for all values that are generated * @var array $_valStack */ - var $_valStack = array(); + var $_valStack = array(); /** * current tag depth @@ -88184,8 +88843,7 @@ class PEAR_XMLParser include_once 'phar://install-pear-nozlib.phar/' . 'PEAR.php'; return PEAR::raiseError("XML Extension not found", 1); } - $this->_valStack = array(); - $this->_dataStack = array(); + $this->_dataStack = $this->_valStack = array(); $this->_depth = 0; if ( @@ -88199,6 +88857,7 @@ class PEAR_XMLParser if (version_compare(phpversion(), '5.0.0', 'lt') && $this->encoding == 'UTF-8') { $data = utf8_decode($data); + $this->encoding = 'ISO-8859-1'; } $xp = xml_parser_create($this->encoding); @@ -88228,25 +88887,21 @@ class PEAR_XMLParser */ function startHandler($parser, $element, $attribs) { - $type = 'string'; - $this->_depth++; $this->_dataStack[$this->_depth] = null; $val = array( - 'name' => $element, - 'value' => null, - 'type' => $type, - 'childrenKeys' => array(), - 'aggregKeys' => array() - ); + 'name' => $element, + 'value' => null, + 'type' => 'string', + 'childrenKeys' => array(), + 'aggregKeys' => array() + ); if (count($attribs) > 0) { $val['children'] = array(); $val['type'] = 'array'; - $val['children']['attribs'] = $attribs; - } array_push($this->_valStack, $val); @@ -88277,18 +88932,14 @@ class PEAR_XMLParser $data = $this->postProcess($this->_dataStack[$this->_depth], $element); // adjust type of the value - switch(strtolower($value['type'])) { - + switch (strtolower($value['type'])) { // unserialize an array case 'array': if ($data !== '') { $value['children']['_content'] = $data; } - if (isset($value['children'])) { - $value['value'] = $value['children']; - } else { - $value['value'] = array(); - } + + $value['value'] = isset($value['children']) ? $value['children'] : array(); break; /* @@ -88360,6 +89011,38 @@ class PEAR_XMLParser $this->_dataStack[$this->_depth] .= $cdata; } } * @copyright 1997-2009 The Authors * @license http://opensource.org/licenses/bsd-license.php New BSD License - * @version CVS: $Id: System.php,v 1.66 2009/02/24 23:52:56 dufuz Exp $ + * @version CVS: $Id: System.php 276386 2009-02-24 23:52:56Z dufuz $ * @link http://pear.php.net/package/PEAR * @since File available since Release 0.1 */ @@ -93602,7 +94285,7 @@ $GLOBALS['_System_temp_files'] = array(); * @author Tomas V.V. Cox * @copyright 1997-2006 The PHP Group * @license http://opensource.org/licenses/bsd-license.php New BSD License -* @version Release: 1.8.0 +* @version Release: 1.9.0 * @link http://pear.php.net/package/PEAR * @since Class available since Release 0.1 * @static @@ -94214,7 +94897,7 @@ class System * @author Stephan Schmidt * @copyright 2003-2008 Stephan Schmidt * @license http://opensource.org/licenses/bsd-license New BSD License - * @version CVS: $Id: Util.php,v 1.39 2009/02/09 14:23:42 ashnazg Exp $ + * @version CVS: $Id: Util.php 275418 2009-02-09 14:23:42Z ashnazg $ * @link http://pear.php.net/package/XML_Util */ @@ -98095,4 +98778,4 @@ iEYEABECAAYFAkk8e2QACgkQcqMhusJF8XULZgCg0iwVLWueraJzK5s1AesDkVzv GucAn22sSv3QiTSUWG9BmakiW9hFsb4V =g2mr -----END PGP SIGNATURE----- -G\$U D7TGBMB \ No newline at end of file +Z?Aj^1GBMB \ No newline at end of file diff --git a/php.ini-development b/php.ini-development index e861f86c2..2eecc139f 100644 --- a/php.ini-development +++ b/php.ini-development @@ -22,7 +22,7 @@ ; The syntax of the file is extremely simple. Whitespace and Lines ; beginning with a semicolon are silently ignored (as you probably guessed). ; Section headers (e.g. [Foo]) are also silently ignored, even though -; they might mean something in the future. +; they might mean something in the future. ; Directives following the section heading [PATH=/www/mysite] only ; apply to PHP files in the /www/mysite directory. Directives @@ -437,11 +437,11 @@ expose_php = On ; Maximum execution time of each script, in seconds ; http://php.net/max-execution-time ; Note: This directive is hardcoded to 0 for the CLI SAPI -max_execution_time = 30 +max_execution_time = 30 ; Maximum amount of time each script may spend parsing request data. It's a good ; idea to limit this time on productions servers in order to eliminate unexpectedly -; long running scripts. +; long running scripts. ; Note: This directive is hardcoded to -1 for the CLI SAPI ; Default Value: -1 (Unlimited) ; Development Value: 60 (60 seconds) @@ -521,8 +521,8 @@ error_reporting = E_ALL | E_STRICT ; It's recommended that errors be logged on production servers rather than ; having the errors sent to STDOUT. ; Possible Values: -; Off = Do not display any errors -; stderr = Display errors to STDERR (affects only CGI/CLI binaries!) +; Off = Do not display any errors +; stderr = Display errors to STDERR (affects only CGI/CLI binaries!) ; On or stdout = Display errors to STDOUT ; Default Value: On ; Development Value: On @@ -641,8 +641,6 @@ html_errors = On ; Data Handling ; ;;;;;;;;;;;;;;;;; -; Note - track_vars is ALWAYS enabled - ; The separator used in PHP generated URLs to separate arguments. ; PHP's default setting is "&". ; http://php.net/arg-separator.output @@ -674,7 +672,7 @@ variables_order = "GPCS" ; be registered into the super global array REQUEST. If so, it also determines ; the order in which that data is registered. The values for this directive are ; specified in the same manner as the variables_order directive, EXCEPT one. -; Leaving this value empty will cause PHP to use the value set in the +; Leaving this value empty will cause PHP to use the value set in the ; variables_order directive. It does not mean it will leave the super globals ; array REQUEST empty. ; Default Value: None @@ -685,9 +683,7 @@ request_order = "GP" ; Whether or not to register the EGPCS variables as global variables. You may ; want to turn this off if you don't want to clutter your scripts' global scope -; with user data. This makes most sense when coupled with track_vars - in which -; case you can access all of the GPC variables through the $HTTP_*_VARS[], -; variables. +; with user data. ; You should do your best to write your scripts so that they do not require ; register_globals to be on; Using form variables as globals can easily lead ; to possible security problems, if the code is not very well thought of. @@ -882,6 +878,9 @@ file_uploads = On ; http://php.net/upload-max-filesize upload_max_filesize = 2M +; Maximum number of files that can be uploaded via a single request +max_file_uploads = 20 + ;;;;;;;;;;;;;;;;;; ; Fopen wrappers ; ;;;;;;;;;;;;;;;;;; @@ -944,7 +943,7 @@ default_socket_timeout = 60 ; Note that many DLL files are located in the extensions/ (PHP 4) ext/ (PHP 5) ; extension folders as well as the separate PECL DLL download (PHP 5). ; Be sure to appropriately set the extension_dir directive. -; +; ;extension=php_bz2.dll ;extension=php_curl.dll ;extension=php_dba.dll @@ -1021,7 +1020,11 @@ default_socket_timeout = 60 ;iconv.output_encoding = ISO-8859-1 [intl] -;intl.default_locale = +;intl.default_locale = +; This directive allows you to produce PHP errors when some error +; happens within intl functions. The value is the level of the error produced. +; Default is 0, which does not produce any errors. +;intl.error_level = E_WARNING [sqlite] ; http://php.net/sqlite.assoc-case @@ -1035,9 +1038,9 @@ default_socket_timeout = 60 ; http://php.net/pcre.backtrack-limit ;pcre.backtrack_limit=100000 -;PCRE library recursion limit. -;Please note that if you set this value to a high number you may consume all -;the available process stack and eventually crash PHP (due to reaching the +;PCRE library recursion limit. +;Please note that if you set this value to a high number you may consume all +;the available process stack and eventually crash PHP (due to reaching the ;stack size limit imposed by the Operating System). ; http://php.net/pcre.recursion-limit ;pcre.recursion_limit=100000 @@ -1115,7 +1118,7 @@ sql.safe_mode = Off ; http://php.net/odbc.default-pw ;odbc.default_pw = Not yet implemented -; Controls the ODBC cursor model. +; Controls the ODBC cursor model. ; Default: SQL_CURSOR_STATIC (default). ;odbc.default_cursortype @@ -1501,7 +1504,7 @@ session.cookie_domain = ; Whether or not to add the httpOnly flag to the cookie, which makes it inaccessible to browser scripting languages such as JavaScript. ; http://php.net/session.cookie-httponly -session.cookie_httponly = +session.cookie_httponly = ; Handler used to serialize data. php is the standard serializer of PHP. ; http://php.net/session.serialize-handler @@ -1520,7 +1523,7 @@ session.serialize_handler = php session.gc_probability = 1 ; Defines the probability that the 'garbage collection' process is started on every -; session initialization. The probability is calculated by using the following equation: +; session initialization. The probability is calculated by using the following equation: ; gc_probability/gc_divisor. Where session.gc_probability is the numerator and ; session.gc_divisor is the denominator in the equation. Setting this value to 1 ; when the session.gc_divisor value is 100 will give you approximately a 1% chance @@ -1611,9 +1614,12 @@ session.cache_expire = 180 session.use_trans_sid = 0 ; Select a hash function for use in generating session ids. -; Possible Values +; Possible Values ; 0 (MD5 128 bits) ; 1 (SHA-1 160 bits) +; This option may also be set to the name of any hash function supported by +; the hash extension. A list of available hashes is returned by the hash_alogs() +; function. ; http://php.net/session.hash-function session.hash_function = 0 @@ -1687,7 +1693,7 @@ mssql.secure_connection = Off ; FreeTDS defaults to 4096 ;mssql.max_procs = -1 -; Specify client character set. +; Specify client character set. ; If empty or not set the client charset from freetds.comf is used ; This is only used when compiled with FreeTDS ;mssql.charset = "ISO-8859-1" @@ -1851,7 +1857,7 @@ soap.wsdl_cache_enabled=1 ; http://php.net/soap.wsdl-cache-dir soap.wsdl_cache_dir="/tmp" -; (time to live) Sets the number of second while cached file will be used +; (time to live) Sets the number of second while cached file will be used ; instead of original one. ; http://php.net/soap.wsdl-cache-ttl soap.wsdl_cache_ttl=86400 diff --git a/php.ini-production b/php.ini-production index 4a5403b7b..c84d83046 100644 --- a/php.ini-production +++ b/php.ini-production @@ -22,7 +22,7 @@ ; The syntax of the file is extremely simple. Whitespace and Lines ; beginning with a semicolon are silently ignored (as you probably guessed). ; Section headers (e.g. [Foo]) are also silently ignored, even though -; they might mean something in the future. +; they might mean something in the future. ; Directives following the section heading [PATH=/www/mysite] only ; apply to PHP files in the /www/mysite directory. Directives @@ -437,11 +437,11 @@ expose_php = On ; Maximum execution time of each script, in seconds ; http://php.net/max-execution-time ; Note: This directive is hardcoded to 0 for the CLI SAPI -max_execution_time = 30 +max_execution_time = 30 ; Maximum amount of time each script may spend parsing request data. It's a good ; idea to limit this time on productions servers in order to eliminate unexpectedly -; long running scripts. +; long running scripts. ; Note: This directive is hardcoded to -1 for the CLI SAPI ; Default Value: -1 (Unlimited) ; Development Value: 60 (60 seconds) @@ -521,8 +521,8 @@ error_reporting = E_ALL & ~E_DEPRECATED ; It's recommended that errors be logged on production servers rather than ; having the errors sent to STDOUT. ; Possible Values: -; Off = Do not display any errors -; stderr = Display errors to STDERR (affects only CGI/CLI binaries!) +; Off = Do not display any errors +; stderr = Display errors to STDERR (affects only CGI/CLI binaries!) ; On or stdout = Display errors to STDOUT ; Default Value: On ; Development Value: On @@ -641,8 +641,6 @@ html_errors = Off ; Data Handling ; ;;;;;;;;;;;;;;;;; -; Note - track_vars is ALWAYS enabled - ; The separator used in PHP generated URLs to separate arguments. ; PHP's default setting is "&". ; http://php.net/arg-separator.output @@ -674,7 +672,7 @@ variables_order = "GPCS" ; be registered into the super global array REQUEST. If so, it also determines ; the order in which that data is registered. The values for this directive are ; specified in the same manner as the variables_order directive, EXCEPT one. -; Leaving this value empty will cause PHP to use the value set in the +; Leaving this value empty will cause PHP to use the value set in the ; variables_order directive. It does not mean it will leave the super globals ; array REQUEST empty. ; Default Value: None @@ -685,9 +683,7 @@ request_order = "GP" ; Whether or not to register the EGPCS variables as global variables. You may ; want to turn this off if you don't want to clutter your scripts' global scope -; with user data. This makes most sense when coupled with track_vars - in which -; case you can access all of the GPC variables through the $HTTP_*_VARS[], -; variables. +; with user data. ; You should do your best to write your scripts so that they do not require ; register_globals to be on; Using form variables as globals can easily lead ; to possible security problems, if the code is not very well thought of. @@ -882,6 +878,9 @@ file_uploads = On ; http://php.net/upload-max-filesize upload_max_filesize = 2M +; Maximum number of files that can be uploaded via a single request +max_file_uploads = 20 + ;;;;;;;;;;;;;;;;;; ; Fopen wrappers ; ;;;;;;;;;;;;;;;;;; @@ -944,7 +943,7 @@ default_socket_timeout = 60 ; Note that many DLL files are located in the extensions/ (PHP 4) ext/ (PHP 5) ; extension folders as well as the separate PECL DLL download (PHP 5). ; Be sure to appropriately set the extension_dir directive. -; +; ;extension=php_bz2.dll ;extension=php_curl.dll ;extension=php_dba.dll @@ -1021,7 +1020,11 @@ default_socket_timeout = 60 ;iconv.output_encoding = ISO-8859-1 [intl] -;intl.default_locale = +;intl.default_locale = +; This directive allows you to produce PHP errors when some error +; happens within intl functions. The value is the level of the error produced. +; Default is 0, which does not produce any errors. +;intl.error_level = E_WARNING [sqlite] ; http://php.net/sqlite.assoc-case @@ -1035,9 +1038,9 @@ default_socket_timeout = 60 ; http://php.net/pcre.backtrack-limit ;pcre.backtrack_limit=100000 -;PCRE library recursion limit. -;Please note that if you set this value to a high number you may consume all -;the available process stack and eventually crash PHP (due to reaching the +;PCRE library recursion limit. +;Please note that if you set this value to a high number you may consume all +;the available process stack and eventually crash PHP (due to reaching the ;stack size limit imposed by the Operating System). ; http://php.net/pcre.recursion-limit ;pcre.recursion_limit=100000 @@ -1115,7 +1118,7 @@ sql.safe_mode = Off ; http://php.net/odbc.default-pw ;odbc.default_pw = Not yet implemented -; Controls the ODBC cursor model. +; Controls the ODBC cursor model. ; Default: SQL_CURSOR_STATIC (default). ;odbc.default_cursortype @@ -1509,7 +1512,7 @@ session.cookie_domain = ; Whether or not to add the httpOnly flag to the cookie, which makes it inaccessible to browser scripting languages such as JavaScript. ; http://php.net/session.cookie-httponly -session.cookie_httponly = +session.cookie_httponly = ; Handler used to serialize data. php is the standard serializer of PHP. ; http://php.net/session.serialize-handler @@ -1528,7 +1531,7 @@ session.serialize_handler = php session.gc_probability = 1 ; Defines the probability that the 'garbage collection' process is started on every -; session initialization. The probability is calculated by using the following equation: +; session initialization. The probability is calculated by using the following equation: ; gc_probability/gc_divisor. Where session.gc_probability is the numerator and ; session.gc_divisor is the denominator in the equation. Setting this value to 1 ; when the session.gc_divisor value is 100 will give you approximately a 1% chance @@ -1619,9 +1622,12 @@ session.cache_expire = 180 session.use_trans_sid = 0 ; Select a hash function for use in generating session ids. -; Possible Values +; Possible Values ; 0 (MD5 128 bits) ; 1 (SHA-1 160 bits) +; This option may also be set to the name of any hash function supported by +; the hash extension. A list of available hashes is returned by the hash_alogs() +; function. ; http://php.net/session.hash-function session.hash_function = 0 @@ -1695,7 +1701,7 @@ mssql.secure_connection = Off ; FreeTDS defaults to 4096 ;mssql.max_procs = -1 -; Specify client character set. +; Specify client character set. ; If empty or not set the client charset from freetds.comf is used ; This is only used when compiled with FreeTDS ;mssql.charset = "ISO-8859-1" @@ -1859,7 +1865,7 @@ soap.wsdl_cache_enabled=1 ; http://php.net/soap.wsdl-cache-dir soap.wsdl_cache_dir="/tmp" -; (time to live) Sets the number of second while cached file will be used +; (time to live) Sets the number of second while cached file will be used ; instead of original one. ; http://php.net/soap.wsdl-cache-ttl soap.wsdl_cache_ttl=86400 diff --git a/run-tests.php b/run-tests.php index c648e4e63..81f218b10 100755 --- a/run-tests.php +++ b/run-tests.php @@ -24,7 +24,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: run-tests.php,v 1.226.2.37.2.35.2.67 2009/05/20 09:22:50 lbarnaud Exp $ */ +/* $Id: run-tests.php 286503 2009-07-29 10:06:55Z cellog $ */ /* Sanity check to ensure that pcre extension needed by this script is available. * In the event it is not, print a nice error message indicating that this script will @@ -634,7 +634,7 @@ if (isset($argc) && $argc > 1) { $html_output = is_resource($html_file); break; case '--version': - echo '$Revision: 1.226.2.37.2.35.2.67 $' . "\n"; + echo '$Revision: 286503 $' . "\n"; exit(1); default: @@ -1023,7 +1023,7 @@ function system_with_timeout($commandline, $env = null, $stdin = null) { global $leak_check, $cwd; - $data = ''; + $data = b''; $bin_env = array(); foreach((array)$env as $key => $value) { @@ -1059,23 +1059,23 @@ function system_with_timeout($commandline, $env = null, $stdin = null) break; } else if ($n === 0) { /* timed out */ - $data .= "\n ** ERROR: process timed out **\n"; + $data .= b"\n ** ERROR: process timed out **\n"; proc_terminate($proc); return $data; } else if ($n > 0) { - $line = fread($pipes[1], 8192); + $line = (binary) fread($pipes[1], 8192); if (strlen($line) == 0) { /* EOF */ break; } - $data .= (binary) $line; + $data .= $line; } } $stat = proc_get_status($proc); if ($stat['signaled']) { - $data .= "\nTermsig=" . $stat['stopsig']; + $data .= b"\nTermsig=" . $stat['stopsig']; } $code = proc_close($proc); @@ -1140,7 +1140,6 @@ function run_test($php, $file, $env) global $leak_check, $temp_source, $temp_target, $cfg, $environment; global $no_clean; global $valgrind_version; - $temp_filenames = null; $org_file = $file; @@ -1379,6 +1378,7 @@ TEST $file $env['REQUEST_METHOD'] = ''; $env['CONTENT_TYPE'] = ''; $env['CONTENT_LENGTH'] = ''; + $env['TZ'] = ''; if (!empty($section_text['ENV'])) { @@ -1648,7 +1648,7 @@ HTTP_COOKIE = " . $env['HTTP_COOKIE'] . " COMMAND $cmd "; - $out = system_with_timeout($cmd, $env, isset($section_text['STDIN']) ? $section_text['STDIN'] : null); + $out = (binary) system_with_timeout($cmd, $env, isset($section_text['STDIN']) ? $section_text['STDIN'] : null); if (array_key_exists('CLEAN', $section_text) && (!$no_clean || $cfg['keep']['clean'])) { @@ -1685,19 +1685,19 @@ COMMAND $cmd } // Does the output match what is expected? - $output = preg_replace("/\r\n/", "\n", trim($out)); + $output = preg_replace(b"/\r\n/", b"\n", trim($out)); /* when using CGI, strip the headers from the output */ - $headers = ""; + $headers = b""; - if (isset($old_php) && preg_match("/^(.*?)\r?\n\r?\n(.*)/s", $out, $match)) { + if (isset($old_php) && preg_match(b"/^(.*?)\r?\n\r?\n(.*)/s", $out, $match)) { $output = trim($match[2]); - $rh = preg_split("/[\n\r]+/", $match[1]); + $rh = preg_split(b"/[\n\r]+/", $match[1]); $headers = array(); foreach ($rh as $line) { - if (strpos($line, ':') !== false) { - $line = explode(':', $line, 2); + if (strpos($line, b':') !== false) { + $line = explode(b':', $line, 2); $headers[trim($line[0])] = trim($line[1]); } } @@ -1708,13 +1708,13 @@ COMMAND $cmd if (isset($section_text['EXPECTHEADERS'])) { $want = array(); $wanted_headers = array(); - $lines = preg_split("/[\n\r]+/", $section_text['EXPECTHEADERS']); + $lines = preg_split(b"/[\n\r]+/", (binary) $section_text['EXPECTHEADERS']); foreach($lines as $line) { - if (strpos($line, ':') !== false) { - $line = explode(':', $line, 2); + if (strpos($line, b':') !== false) { + $line = explode(b':', $line, 2); $want[trim($line[0])] = trim($line[1]); - $wanted_headers[] = trim($line[0]) . ': ' . trim($line[1]); + $wanted_headers[] = trim($line[0]) . b': ' . trim($line[1]); } } @@ -1726,7 +1726,7 @@ COMMAND $cmd if (isset($org_headers[$k])) { $headers = $org_headers[$k]; - $output_headers[] = $k . ': ' . $org_headers[$k]; + $output_headers[] = $k . b': ' . $org_headers[$k]; } if (!isset($org_headers[$k]) || $org_headers[$k] != $v) { @@ -1735,9 +1735,9 @@ COMMAND $cmd } ksort($wanted_headers); - $wanted_headers = join("\n", $wanted_headers); + $wanted_headers = join(b"\n", $wanted_headers); ksort($output_headers); - $output_headers = join("\n", $output_headers); + $output_headers = join(b"\n", $output_headers); } show_file_block('out', $output); @@ -1751,13 +1751,13 @@ COMMAND $cmd } show_file_block('exp', $wanted); - $wanted_re = preg_replace('/\r\n/', "\n", $wanted); + $wanted_re = preg_replace(b'/\r\n/', b"\n", $wanted); if (isset($section_text['EXPECTF'])) { // do preg_quote, but miss out any %r delimited sections - $temp = ""; - $r = "%r"; + $temp = b""; + $r = b"%r"; $startOffset = 0; $length = strlen($wanted_re); while($startOffset < $length) { @@ -1774,45 +1774,45 @@ COMMAND $cmd $start = $end = $length; } // quote a non re portion of the string - $temp = $temp . preg_quote(substr($wanted_re, $startOffset, ($start - $startOffset)), '/'); + $temp = $temp . preg_quote(substr($wanted_re, $startOffset, ($start - $startOffset)), b'/'); // add the re unquoted. - $temp = $temp . '(' . substr($wanted_re, $start+2, ($end - $start-2)). ')'; + $temp = $temp . b'(' . substr($wanted_re, $start+2, ($end - $start-2)). b')'; $startOffset = $end + 2; } $wanted_re = $temp; $wanted_re = str_replace( - array('%binary_string_optional%'), - version_compare(PHP_VERSION, '6.0.0-dev') == -1 ? 'string' : 'binary string', + array(b'%binary_string_optional%'), + version_compare(PHP_VERSION, '6.0.0-dev') == -1 ? b'string' : b'binary string', $wanted_re ); $wanted_re = str_replace( - array('%unicode_string_optional%'), - version_compare(PHP_VERSION, '6.0.0-dev') == -1 ? 'string' : 'Unicode string', + array(b'%unicode_string_optional%'), + version_compare(PHP_VERSION, '6.0.0-dev') == -1 ? b'string' : b'Unicode string', $wanted_re ); $wanted_re = str_replace( - array('%unicode\|string%', '%string\|unicode%'), - version_compare(PHP_VERSION, '6.0.0-dev') == -1 ? 'string' : 'unicode', + array(b'%unicode\|string%', b'%string\|unicode%'), + version_compare(PHP_VERSION, '6.0.0-dev') == -1 ? b'string' : b'unicode', $wanted_re ); $wanted_re = str_replace( - array('%u\|b%', '%b\|u%'), - version_compare(PHP_VERSION, '6.0.0-dev') == -1 ? '' : 'u', + array(b'%u\|b%', b'%b\|u%'), + version_compare(PHP_VERSION, '6.0.0-dev') == -1 ? b'' : b'u', $wanted_re ); // Stick to basics - $wanted_re = str_replace('%e', '\\' . DIRECTORY_SEPARATOR, $wanted_re); - $wanted_re = str_replace('%s', '[^\r\n]+', $wanted_re); - $wanted_re = str_replace('%S', '[^\r\n]*', $wanted_re); - $wanted_re = str_replace('%a', '.+', $wanted_re); - $wanted_re = str_replace('%A', '.*', $wanted_re); - $wanted_re = str_replace('%w', '\s*', $wanted_re); - $wanted_re = str_replace('%i', '[+-]?\d+', $wanted_re); - $wanted_re = str_replace('%d', '\d+', $wanted_re); - $wanted_re = str_replace('%x', '[0-9a-fA-F]+', $wanted_re); - $wanted_re = str_replace('%f', '[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?', $wanted_re); - $wanted_re = str_replace('%c', '.', $wanted_re); + $wanted_re = str_replace(b'%e', b'\\' . DIRECTORY_SEPARATOR, $wanted_re); + $wanted_re = str_replace(b'%s', b'[^\r\n]+', $wanted_re); + $wanted_re = str_replace(b'%S', b'[^\r\n]*', $wanted_re); + $wanted_re = str_replace(b'%a', b'.+', $wanted_re); + $wanted_re = str_replace(b'%A', b'.*', $wanted_re); + $wanted_re = str_replace(b'%w', b'\s*', $wanted_re); + $wanted_re = str_replace(b'%i', b'[+-]?\d+', $wanted_re); + $wanted_re = str_replace(b'%d', b'\d+', $wanted_re); + $wanted_re = str_replace(b'%x', b'[0-9a-fA-F]+', $wanted_re); + $wanted_re = str_replace(b'%f', b'[+-]?\.?\d+\.?\d*(?:[Ee][+-]?\d+)?', $wanted_re); + $wanted_re = str_replace(b'%c', b'.', $wanted_re); // %f allows two points "-.0.0" but that is the best *simple* expression } /* DEBUG YOUR REGEX HERE @@ -1820,7 +1820,7 @@ COMMAND $cmd print(str_repeat('=', 80) . "\n"); var_dump($output); */ - if (preg_match((binary) "/^$wanted_re\$/s", $output)) { + if (preg_match(b"/^$wanted_re\$/s", $output)) { $passed = true; if (!$cfg['keep']['php']) { @unlink($test_file); @@ -1842,8 +1842,8 @@ COMMAND $cmd } else { - $wanted = trim($section_text['EXPECT']); - $wanted = preg_replace('/\r\n/',"\n", $wanted); + $wanted = (binary) trim($section_text['EXPECT']); + $wanted = preg_replace(b'/\r\n/',b"\n", $wanted); show_file_block('exp', $wanted); // compare and leave on success @@ -1875,8 +1875,8 @@ COMMAND $cmd // Test failed so we need to report details. if ($failed_headers) { $passed = false; - $wanted = $wanted_headers . "\n--HEADERS--\n" . $wanted; - $output = $output_headers . "\n--HEADERS--\n" . $output; + $wanted = (binary) $wanted_headers . b"\n--HEADERS--\n" . (binary) $wanted; + $output = (binary) $output_headers . b"\n--HEADERS--\n" . (binary) $output; if (isset($wanted_re)) { $wanted_re = preg_quote($wanted_headers . "\n--HEADERS--\n", '/') . $wanted_re; diff --git a/sapi/aolserver/README b/sapi/aolserver/README index 80559fac2..0d1c998e2 100644 --- a/sapi/aolserver/README +++ b/sapi/aolserver/README @@ -1,4 +1,4 @@ -AOLserver README ($Id: README,v 1.6 2004/01/17 13:00:03 sniper Exp $) +AOLserver README ($Id: README 149024 2004-01-17 13:00:38Z sniper $) To compile PHP 4.0 as a module for AOLserver, you need: diff --git a/sapi/aolserver/aolserver.c b/sapi/aolserver/aolserver.c index 5584ef745..2cb8048af 100644 --- a/sapi/aolserver/aolserver.c +++ b/sapi/aolserver/aolserver.c @@ -22,7 +22,7 @@ * - CGI/1.1 conformance */ -/* $Id: aolserver.c,v 1.81.2.2.2.1.2.8 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: aolserver.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* conflict between PHP and AOLserver headers */ #define Debug php_Debug @@ -205,7 +205,7 @@ static void php_info_aolserver(ZEND_MODULE_INFO_FUNC_ARGS) int i; php_info_print_table_start(); - php_info_print_table_row(2, "SAPI module version", "$Id: aolserver.c,v 1.81.2.2.2.1.2.8 2008/12/31 11:15:48 sebastian Exp $"); + php_info_print_table_row(2, "SAPI module version", "$Id: aolserver.c 272370 2008-12-31 11:15:49Z sebastian $"); php_info_print_table_row(2, "Build date", Ns_InfoBuildDate()); php_info_print_table_row(2, "Config file path", Ns_InfoConfigFile()); php_info_print_table_row(2, "Error Log path", Ns_InfoErrorLog()); diff --git a/sapi/aolserver/config.m4 b/sapi/aolserver/config.m4 index 003ec909d..efc0c8b3e 100644 --- a/sapi/aolserver/config.m4 +++ b/sapi/aolserver/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.15.22.1 2007/07/11 23:20:36 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(aolserver,, diff --git a/sapi/aolserver/config.w32 b/sapi/aolserver/config.w32 index 676d38ec5..5ffc49d6a 100644 --- a/sapi/aolserver/config.w32 +++ b/sapi/aolserver/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.1 2003/12/19 20:39:02 wez Exp $ +// $Id: config.w32 146950 2003-12-19 20:39:04Z wez $ ARG_WITH('aolserver', 'Build AOLserver support', 'no'); diff --git a/sapi/apache/config.m4 b/sapi/apache/config.m4 index 0f5ed6bac..2db1b68b9 100644 --- a/sapi/apache/config.m4 +++ b/sapi/apache/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.75.4.2 2007/07/11 23:20:36 jani Exp $ +dnl $Id: config.m4 239540 2007-07-11 23:20:37Z jani $ dnl AC_DEFUN([PHP_APACHE_FD_CHECK], [ AC_CACHE_CHECK([for member fd in BUFF *],ac_cv_php_fd_in_buff,[ diff --git a/sapi/apache/config.w32 b/sapi/apache/config.w32 index 36ae1411c..79e246655 100644 --- a/sapi/apache/config.w32 +++ b/sapi/apache/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.7.8.1 2008/04/15 16:55:53 auroraeosrose Exp $ +// $Id: config.w32 257603 2008-04-15 16:55:53Z auroraeosrose $ ARG_ENABLE('apache', 'Build Apache 1.3.x version of PHP', 'no'); diff --git a/sapi/apache/libpre.c b/sapi/apache/libpre.c index 48eebf7e0..2fc8c2ac4 100644 --- a/sapi/apache/libpre.c +++ b/sapi/apache/libpre.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: libpre.c,v 1.6.2.1.2.1.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: libpre.c 272370 2008-12-31 11:15:49Z sebastian $ */ #ifdef NETWARE diff --git a/sapi/apache/mod_php5.c b/sapi/apache/mod_php5.c index 9bb98ceba..ce0f81967 100644 --- a/sapi/apache/mod_php5.c +++ b/sapi/apache/mod_php5.c @@ -17,7 +17,7 @@ | PHP 4.0 patches by Zeev Suraski | +----------------------------------------------------------------------+ */ -/* $Id: mod_php5.c,v 1.19.2.7.2.13.2.11 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: mod_php5.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_apache_http.h" #include "http_conf_globals.h" diff --git a/sapi/apache/mod_php5.h b/sapi/apache/mod_php5.h index c5a4d1b10..7f7c159e1 100644 --- a/sapi/apache/mod_php5.h +++ b/sapi/apache/mod_php5.h @@ -15,7 +15,7 @@ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ */ -/* $Id: mod_php5.h,v 1.4.2.1.2.1.2.3 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: mod_php5.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef MOD_PHP5_H #define MOD_PHP5_H diff --git a/sapi/apache/php_apache.c b/sapi/apache/php_apache.c index 44d969a89..09e8a6519 100644 --- a/sapi/apache/php_apache.c +++ b/sapi/apache/php_apache.c @@ -17,7 +17,7 @@ | David Sklar | +----------------------------------------------------------------------+ */ -/* $Id: php_apache.c,v 1.89.2.4.2.6.2.10 2009/01/05 16:24:26 iliaa Exp $ */ +/* $Id: php_apache.c 272840 2009-01-05 16:24:26Z iliaa $ */ #include "php_apache_http.h" diff --git a/sapi/apache/php_apache_http.h b/sapi/apache/php_apache_http.h index 42e32adcd..936484a15 100644 --- a/sapi/apache/php_apache_http.h +++ b/sapi/apache/php_apache_http.h @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_apache_http.h,v 1.13.2.1.2.1.2.3 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: php_apache_http.h 272370 2008-12-31 11:15:49Z sebastian $ */ #define NO_REGEX_EXTRA_H diff --git a/sapi/apache/sapi_apache.c b/sapi/apache/sapi_apache.c index f736119ee..dce6e5bcc 100644 --- a/sapi/apache/sapi_apache.c +++ b/sapi/apache/sapi_apache.c @@ -19,7 +19,7 @@ | Stig Bakken | +----------------------------------------------------------------------+ */ -/* $Id: sapi_apache.c,v 1.47.2.1.2.1.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: sapi_apache.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_apache_http.h" diff --git a/sapi/apache2filter/apache_config.c b/sapi/apache2filter/apache_config.c index 0afd83d57..e06b16856 100644 --- a/sapi/apache2filter/apache_config.c +++ b/sapi/apache2filter/apache_config.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: apache_config.c,v 1.34.2.1.2.3.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: apache_config.c 272370 2008-12-31 11:15:49Z sebastian $ */ #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS diff --git a/sapi/apache2filter/config.m4 b/sapi/apache2filter/config.m4 index 1fa03d4a9..77823664f 100644 --- a/sapi/apache2filter/config.m4 +++ b/sapi/apache2filter/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.41.2.1.2.2.2.2 2008/03/09 12:35:56 lstrojny Exp $ +dnl $Id: config.m4 254692 2008-03-09 12:35:56Z lstrojny $ dnl PHP_ARG_WITH(apxs2filter,, diff --git a/sapi/apache2filter/config.w32 b/sapi/apache2filter/config.w32 index 5aa9078c6..6e7aab59c 100755 --- a/sapi/apache2filter/config.w32 +++ b/sapi/apache2filter/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.1.2.1.2.1 2008/05/14 03:13:17 auroraeosrose Exp $ +// $Id: config.w32 259731 2008-05-14 03:13:17Z auroraeosrose $ ARG_ENABLE('apache2filter', 'Build Apache 2.x filter', 'no'); diff --git a/sapi/apache2filter/php_apache.h b/sapi/apache2filter/php_apache.h index 49bd5f262..3f54fa714 100644 --- a/sapi/apache2filter/php_apache.h +++ b/sapi/apache2filter/php_apache.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_apache.h,v 1.25.2.1.2.2.2.4 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: php_apache.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_APACHE_H #define PHP_APACHE_H diff --git a/sapi/apache2filter/php_functions.c b/sapi/apache2filter/php_functions.c index 845f70dff..d0b662f6c 100644 --- a/sapi/apache2filter/php_functions.c +++ b/sapi/apache2filter/php_functions.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_functions.c,v 1.44.2.2.2.2.2.9 2009/01/05 16:24:26 iliaa Exp $ */ +/* $Id: php_functions.c 272840 2009-01-05 16:24:26Z iliaa $ */ #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS diff --git a/sapi/apache2filter/sapi_apache2.c b/sapi/apache2filter/sapi_apache2.c index d963c1c56..22f368edd 100644 --- a/sapi/apache2filter/sapi_apache2.c +++ b/sapi/apache2filter/sapi_apache2.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sapi_apache2.c,v 1.136.2.2.2.8.2.7 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: sapi_apache2.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include diff --git a/sapi/apache2handler/apache_config.c b/sapi/apache2handler/apache_config.c index 24358fa08..8057050e4 100644 --- a/sapi/apache2handler/apache_config.c +++ b/sapi/apache2handler/apache_config.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: apache_config.c,v 1.7.2.1.2.4.2.4 2008/12/31 14:45:14 bjori Exp $ */ +/* $Id: apache_config.c 272413 2008-12-31 14:45:14Z bjori $ */ #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS diff --git a/sapi/apache2handler/config.m4 b/sapi/apache2handler/config.m4 index 08ab1b909..2cb3313f7 100644 --- a/sapi/apache2handler/config.m4 +++ b/sapi/apache2handler/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.14.2.1.2.2.2.3 2008/03/11 22:47:39 lstrojny Exp $ +dnl $Id: config.m4 254930 2008-03-11 22:47:39Z lstrojny $ dnl PHP_ARG_WITH(apxs2,, diff --git a/sapi/apache2handler/config.w32 b/sapi/apache2handler/config.w32 index 70aee0b71..ad3191823 100644 --- a/sapi/apache2handler/config.w32 +++ b/sapi/apache2handler/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.1.6.2.2.1 2008/05/14 03:13:17 auroraeosrose Exp $ +// $Id: config.w32 259731 2008-05-14 03:13:17Z auroraeosrose $ ARG_ENABLE('apache2handler', 'Build Apache 2.x handler', 'no'); diff --git a/sapi/apache2handler/mod_php5.c b/sapi/apache2handler/mod_php5.c index 68082eca6..038a7122a 100644 --- a/sapi/apache2handler/mod_php5.c +++ b/sapi/apache2handler/mod_php5.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: mod_php5.c,v 1.5.2.1.2.1.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: mod_php5.c 272370 2008-12-31 11:15:49Z sebastian $ */ #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS diff --git a/sapi/apache2handler/php_apache.h b/sapi/apache2handler/php_apache.h index b0ac5464e..8573967a9 100644 --- a/sapi/apache2handler/php_apache.h +++ b/sapi/apache2handler/php_apache.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_apache.h,v 1.8.2.1.2.2.2.3 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: php_apache.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_APACHE_H #define PHP_APACHE_H diff --git a/sapi/apache2handler/php_functions.c b/sapi/apache2handler/php_functions.c index 65b280642..87bed1113 100644 --- a/sapi/apache2handler/php_functions.c +++ b/sapi/apache2handler/php_functions.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_functions.c,v 1.18.2.6.2.5.2.11 2009/01/19 19:32:40 scottmac Exp $ */ +/* $Id: php_functions.c 273971 2009-01-19 19:32:40Z scottmac $ */ #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS diff --git a/sapi/apache2handler/sapi_apache2.c b/sapi/apache2handler/sapi_apache2.c index 00ef1b28e..62504af42 100644 --- a/sapi/apache2handler/sapi_apache2.c +++ b/sapi/apache2handler/sapi_apache2.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sapi_apache2.c,v 1.57.2.10.2.15.2.6 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: sapi_apache2.c 272370 2008-12-31 11:15:49Z sebastian $ */ #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS diff --git a/sapi/apache_hooks/config.m4 b/sapi/apache_hooks/config.m4 index 12fc9fd50..12c568767 100644 --- a/sapi/apache_hooks/config.m4 +++ b/sapi/apache_hooks/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.7.4.2 2007/07/11 23:20:36 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl AC_DEFUN([PHP_APACHE_FD_CHECK], [ AC_CACHE_CHECK([for member fd in BUFF *],ac_cv_php_fd_in_buff,[ diff --git a/sapi/apache_hooks/config.w32 b/sapi/apache_hooks/config.w32 index 76869bd24..abc28c996 100644 --- a/sapi/apache_hooks/config.w32 +++ b/sapi/apache_hooks/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.2.8.1 2008/04/15 16:55:53 auroraeosrose Exp $ +// $Id: config.w32 257603 2008-04-15 16:55:53Z auroraeosrose $ ARG_WITH('apache-hooks', 'Build Apache 1.3.x (hooks) version of PHP', 'no'); diff --git a/sapi/apache_hooks/mod_php5.c b/sapi/apache_hooks/mod_php5.c index 4c2f346a7..53d38ec91 100644 --- a/sapi/apache_hooks/mod_php5.c +++ b/sapi/apache_hooks/mod_php5.c @@ -17,7 +17,7 @@ | PHP 4.0 patches by Zeev Suraski | +----------------------------------------------------------------------+ */ -/* $Id: mod_php5.c,v 1.11.2.1.2.5.2.5 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: mod_php5.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_apache_http.h" diff --git a/sapi/apache_hooks/mod_php5.h b/sapi/apache_hooks/mod_php5.h index 85767d196..4bb98ad04 100644 --- a/sapi/apache_hooks/mod_php5.h +++ b/sapi/apache_hooks/mod_php5.h @@ -15,7 +15,7 @@ | Author: Rasmus Lerdorf | +----------------------------------------------------------------------+ */ -/* $Id: mod_php5.h,v 1.2.2.1.2.1.2.3 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: mod_php5.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef MOD_PHP5_H #define MOD_PHP5_H diff --git a/sapi/apache_hooks/php_apache.c b/sapi/apache_hooks/php_apache.c index 1c9600537..f26328645 100644 --- a/sapi/apache_hooks/php_apache.c +++ b/sapi/apache_hooks/php_apache.c @@ -17,7 +17,7 @@ | David Sklar | +----------------------------------------------------------------------+ */ -/* $Id: php_apache.c,v 1.19.2.3.2.5.2.18 2009/03/16 10:13:18 pajoye Exp $ */ +/* $Id: php_apache.c 277250 2009-03-16 10:13:18Z pajoye $ */ #include "php_apache_http.h" diff --git a/sapi/apache_hooks/sapi_apache.c b/sapi/apache_hooks/sapi_apache.c index 6df3fc770..c4a26af07 100644 --- a/sapi/apache_hooks/sapi_apache.c +++ b/sapi/apache_hooks/sapi_apache.c @@ -19,7 +19,7 @@ | Stig Bakken | +----------------------------------------------------------------------+ */ -/* $Id: sapi_apache.c,v 1.9.2.1.2.1.2.2 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: sapi_apache.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php_apache_http.h" diff --git a/sapi/caudium/caudium.c b/sapi/caudium/caudium.c index 3ec0f4d8e..c1d89a3a7 100644 --- a/sapi/caudium/caudium.c +++ b/sapi/caudium/caudium.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: caudium.c,v 1.36.2.1.2.1.2.4 2008/12/31 11:15:48 sebastian Exp $ */ +/* $Id: caudium.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #ifdef HAVE_CAUDIUM @@ -444,7 +444,7 @@ static void php_info_caudium(ZEND_MODULE_INFO_FUNC_ARGS) { /* char buf[512]; */ php_info_print_table_start(); - php_info_print_table_row(2, "SAPI module version", "$Id: caudium.c,v 1.36.2.1.2.1.2.4 2008/12/31 11:15:48 sebastian Exp $"); + php_info_print_table_row(2, "SAPI module version", "$Id: caudium.c 272370 2008-12-31 11:15:49Z sebastian $"); /* php_info_print_table_row(2, "Build date", Ns_InfoBuildDate()); php_info_print_table_row(2, "Config file path", Ns_InfoConfigFile()); php_info_print_table_row(2, "Error Log path", Ns_InfoErrorLog()); diff --git a/sapi/caudium/config.m4 b/sapi/caudium/config.m4 index c1d32d8d7..b5d355538 100644 --- a/sapi/caudium/config.m4 +++ b/sapi/caudium/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.14.2.1.2.2 2007/07/11 23:20:36 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl RESULT=no diff --git a/sapi/cgi/CHANGES b/sapi/cgi/CHANGES index de0b36907..de029474e 100755 --- a/sapi/cgi/CHANGES +++ b/sapi/cgi/CHANGES @@ -1,34 +1,34 @@ -In PHP5.3 all additional configure options (except --enable-cgi) are removed: - - --enable-fastcgi CGI: If this is enabled, the cgi module will - be built with support for fastcgi also - - Now fastcgi is always enabled - - --disable-path-info-check CGI: If this is disabled, paths such as - /info.php/test?a=b will fail to work - - Now it is enabled by default, but can be disabled - with ini directive "cgi.fix_pathinfo=0" - - --enable-force-cgi-redirect - CGI: Enable the security check for internal server - redirects. You should use this if you are - running the CGI version with Apache - - Now it is enabled by default, but can be disabled - with ini directive "cgi.force_redirect=0" - - --enable-discard-path CGI: If this is enabled, the PHP CGI binary - can safely be placed outside of the - web tree and people will not be able - to circumvent .htaccess security - - This option had effect only with - --disable-path-info-check or "cgi.fix_pathinfo=0". - Seems it needs only for CGI configuration that - require each script start from "#! /usr/bin/php". - - Now it is disabled by default, but can be enabled - with ini directive "cgi.discard_path=1". - +In PHP5.3 all additional configure options (except --enable-cgi) are removed: + + --enable-fastcgi CGI: If this is enabled, the cgi module will + be built with support for fastcgi also + + Now fastcgi is always enabled + + --disable-path-info-check CGI: If this is disabled, paths such as + /info.php/test?a=b will fail to work + + Now it is enabled by default, but can be disabled + with ini directive "cgi.fix_pathinfo=0" + + --enable-force-cgi-redirect + CGI: Enable the security check for internal server + redirects. You should use this if you are + running the CGI version with Apache + + Now it is enabled by default, but can be disabled + with ini directive "cgi.force_redirect=0" + + --enable-discard-path CGI: If this is enabled, the PHP CGI binary + can safely be placed outside of the + web tree and people will not be able + to circumvent .htaccess security + + This option had effect only with + --disable-path-info-check or "cgi.fix_pathinfo=0". + Seems it needs only for CGI configuration that + require each script start from "#! /usr/bin/php". + + Now it is disabled by default, but can be enabled + with ini directive "cgi.discard_path=1". + diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c index 04d8cbbd8..c01dce1dd 100644 --- a/sapi/cgi/cgi_main.c +++ b/sapi/cgi/cgi_main.c @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: cgi_main.c,v 1.267.2.15.2.50.2.44 2009/06/22 14:10:40 pajoye Exp $ */ +/* $Id: cgi_main.c 289795 2009-10-20 12:57:44Z tony2001 $ */ #include "php.h" #include "php_globals.h" @@ -159,6 +159,7 @@ static const opt_struct OPTIONS[] = { typedef struct _php_cgi_globals_struct { zend_bool rfc2616_headers; zend_bool nph; + zend_bool check_shebang_line; zend_bool fix_pathinfo; zend_bool force_redirect; zend_bool discard_path; @@ -753,7 +754,11 @@ static void php_cgi_ini_activate_user_config(char *path, int path_len, const cha if it is inside the docroot, we scan the tree up to the docroot to find more user.ini, if not we only scan the current path. */ +#ifdef PHP_WIN32 + if (strnicmp(s1, s2, s_len) == 0) { +#else if (strncmp(s1, s2, s_len) == 0) { +#endif ptr = s2 + start; /* start is the point where doc_root ends! */ while ((ptr = strchr(ptr, DEFAULT_SLASH)) != NULL) { *ptr = 0; @@ -776,7 +781,7 @@ static void php_cgi_ini_activate_user_config(char *path, int path_len, const cha static int sapi_cgi_activate(TSRMLS_D) { char *path, *doc_root, *server_name; - uint path_len, doc_root_len; + uint path_len, doc_root_len, server_name_len; /* PATH_TRANSLATED should be defined at this stage but better safe than sorry :) */ if (!SG(request_info).path_translated) { @@ -788,7 +793,11 @@ static int sapi_cgi_activate(TSRMLS_D) server_name = sapi_cgibin_getenv("SERVER_NAME", sizeof("SERVER_NAME") - 1 TSRMLS_CC); /* SERVER_NAME should also be defined at this stage..but better check it anyway */ if (server_name) { - php_ini_activate_per_host_config(server_name, strlen(server_name) + 1 TSRMLS_CC); + server_name_len = strlen(server_name); + server_name = estrndup(server_name, server_name_len); + zend_str_tolower(server_name, server_name_len); + php_ini_activate_per_host_config(server_name, server_name_len + 1 TSRMLS_CC); + efree(server_name); } } @@ -819,13 +828,21 @@ static int sapi_cgi_activate(TSRMLS_D) /* DOCUMENT_ROOT should also be defined at this stage..but better check it anyway */ if (doc_root) { doc_root_len = strlen(doc_root); - if (IS_SLASH(doc_root[doc_root_len - 1])) { + if (doc_root_len > 0 && IS_SLASH(doc_root[doc_root_len - 1])) { --doc_root_len; } +#ifdef PHP_WIN32 + /* paths on windows should be case-insensitive */ + doc_root = estrndup(doc_root, doc_root_len); + zend_str_tolower(doc_root, doc_root_len); +#endif php_cgi_ini_activate_user_config(path, path_len, doc_root, doc_root_len, doc_root_len - 1 TSRMLS_CC); } } +#ifdef PHP_WIN32 + efree(doc_root); +#endif efree(path); } @@ -1279,9 +1296,6 @@ static void init_request_info(TSRMLS_D) if (pt) { efree(pt); } - if (is_valid_path(script_path_translated)) { - SG(request_info).path_translated = estrdup(script_path_translated); - } } else { /* make sure path_info/translated are empty */ if (!orig_script_filename || @@ -1310,9 +1324,6 @@ static void init_request_info(TSRMLS_D) } else { SG(request_info).request_uri = env_script_name; } - if (is_valid_path(script_path_translated)) { - SG(request_info).path_translated = estrdup(script_path_translated); - } free(real_path); } } else { @@ -1325,9 +1336,10 @@ static void init_request_info(TSRMLS_D) if (!CGIG(discard_path) && env_path_translated) { script_path_translated = env_path_translated; } - if (is_valid_path(script_path_translated)) { - SG(request_info).path_translated = estrdup(script_path_translated); - } + } + + if (is_valid_path(script_path_translated)) { + SG(request_info).path_translated = estrdup(script_path_translated); } SG(request_info).request_method = sapi_cgibin_getenv("REQUEST_METHOD", sizeof("REQUEST_METHOD")-1 TSRMLS_CC); @@ -1369,6 +1381,7 @@ void fastcgi_cleanup(int signal) PHP_INI_BEGIN() STD_PHP_INI_ENTRY("cgi.rfc2616_headers", "0", PHP_INI_ALL, OnUpdateBool, rfc2616_headers, php_cgi_globals_struct, php_cgi_globals) STD_PHP_INI_ENTRY("cgi.nph", "0", PHP_INI_ALL, OnUpdateBool, nph, php_cgi_globals_struct, php_cgi_globals) + STD_PHP_INI_ENTRY("cgi.check_shebang_line", "1", PHP_INI_SYSTEM, OnUpdateBool, check_shebang_line, php_cgi_globals_struct, php_cgi_globals) STD_PHP_INI_ENTRY("cgi.force_redirect", "1", PHP_INI_SYSTEM, OnUpdateBool, force_redirect, php_cgi_globals_struct, php_cgi_globals) STD_PHP_INI_ENTRY("cgi.redirect_status_env", NULL, PHP_INI_SYSTEM, OnUpdateString, redirect_status_env, php_cgi_globals_struct, php_cgi_globals) STD_PHP_INI_ENTRY("cgi.fix_pathinfo", "1", PHP_INI_SYSTEM, OnUpdateBool, fix_pathinfo, php_cgi_globals_struct, php_cgi_globals) @@ -1385,6 +1398,7 @@ static void php_cgi_globals_ctor(php_cgi_globals_struct *php_cgi_globals TSRMLS_ { php_cgi_globals->rfc2616_headers = 0; php_cgi_globals->nph = 0; + php_cgi_globals->check_shebang_line = 1; php_cgi_globals->force_redirect = 1; php_cgi_globals->redirect_status_env = NULL; php_cgi_globals->fix_pathinfo = 1; @@ -2024,7 +2038,7 @@ consult the installation file that came with this distribution, or visit \n\ 1. we are running from shell and got filename was there 2. we are running as cgi or fastcgi */ - if (cgi || SG(request_info).path_translated) { + if (cgi || fastcgi || SG(request_info).path_translated) { if (php_fopen_primary_script(&file_handle TSRMLS_CC) == FAILURE) { if (errno == EACCES) { SG(sapi_headers).http_response_code = 403; @@ -2058,6 +2072,26 @@ consult the installation file that came with this distribution, or visit \n\ } } + if (CGIG(check_shebang_line) && file_handle.handle.fp && (file_handle.handle.fp != stdin)) { + /* #!php support */ + c = fgetc(file_handle.handle.fp); + if (c == '#') { + while (c != '\n' && c != '\r' && c != EOF) { + c = fgetc(file_handle.handle.fp); /* skip to end of line */ + } + /* handle situations where line is terminated by \r\n */ + if (c == '\r') { + if (fgetc(file_handle.handle.fp) != '\n') { + long pos = ftell(file_handle.handle.fp); + fseek(file_handle.handle.fp, pos - 1, SEEK_SET); + } + } + CG(start_lineno) = 2; + } else { + rewind(file_handle.handle.fp); + } + } + switch (behavior) { case PHP_MODE_STANDARD: php_execute_script(&file_handle TSRMLS_CC); @@ -2108,26 +2142,14 @@ consult the installation file that came with this distribution, or visit \n\ fastcgi_request_done: { - char *path_translated; - - /* Go through this trouble so that the memory manager doesn't warn - * about SG(request_info).path_translated leaking - */ - if (SG(request_info).path_translated) { - path_translated = strdup(SG(request_info).path_translated); - STR_FREE(SG(request_info).path_translated); - SG(request_info).path_translated = path_translated; - } + STR_FREE(SG(request_info).path_translated); php_request_shutdown((void *) 0); + if (exit_status == 0) { exit_status = EG(exit_status); } - if (SG(request_info).path_translated) { - free(SG(request_info).path_translated); - SG(request_info).path_translated = NULL; - } if (free_query_string && SG(request_info).query_string) { free(SG(request_info).query_string); SG(request_info).query_string = NULL; diff --git a/sapi/cgi/config.w32 b/sapi/cgi/config.w32 index a6a54ad89..1e73e211f 100644 --- a/sapi/cgi/config.w32 +++ b/sapi/cgi/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.2.4.1.2.2.2.3 2007/10/05 16:00:30 rrichards Exp $ +// $Id: config.w32 243567 2007-10-05 16:00:30Z rrichards $ ARG_ENABLE('cgi', 'Build CGI version of PHP', 'yes'); diff --git a/sapi/cgi/config9.m4 b/sapi/cgi/config9.m4 index 7aae33bf7..5943c632b 100644 --- a/sapi/cgi/config9.m4 +++ b/sapi/cgi/config9.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config9.m4,v 1.17.2.2.2.6.2.2 2007/10/01 12:40:54 jani Exp $ +dnl $Id: config9.m4 243300 2007-10-01 12:40:54Z jani $ dnl PHP_ARG_ENABLE(cgi,, diff --git a/sapi/cgi/fastcgi.c b/sapi/cgi/fastcgi.c index ff8e880a8..156a689c5 100644 --- a/sapi/cgi/fastcgi.c +++ b/sapi/cgi/fastcgi.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: fastcgi.c,v 1.4.2.13.2.28.2.11 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: fastcgi.c 287777 2009-08-26 19:17:32Z pajoye $ */ #include "php.h" #include "fastcgi.h" @@ -398,20 +398,20 @@ int fcgi_listen(const char *path, int backlog) } else { #ifdef _WIN32 SECURITY_DESCRIPTOR sd; - SECURITY_ATTRIBUTES sa; + SECURITY_ATTRIBUTES saw; PACL acl; HANDLE namedPipe; - memset(&sa, 0, sizeof(sa)); - sa.nLength = sizeof(sa); - sa.bInheritHandle = FALSE; - acl = prepare_named_pipe_acl(&sd, &sa); + memset(&sa, 0, sizeof(saw)); + saw.nLength = sizeof(saw); + saw.bInheritHandle = FALSE; + acl = prepare_named_pipe_acl(&sd, &saw); namedPipe = CreateNamedPipe(path, PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, PIPE_TYPE_BYTE | PIPE_WAIT | PIPE_READMODE_BYTE, PIPE_UNLIMITED_INSTANCES, - 8192, 8192, 0, &sa); + 8192, 8192, 0, &saw); if (namedPipe == INVALID_HANDLE_VALUE) { return -1; } diff --git a/sapi/cgi/fastcgi.h b/sapi/cgi/fastcgi.h index a3570b7bd..c4f62b8da 100644 --- a/sapi/cgi/fastcgi.h +++ b/sapi/cgi/fastcgi.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: fastcgi.h,v 1.2.2.4.2.5.2.5 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: fastcgi.h 272370 2008-12-31 11:15:49Z sebastian $ */ /* FastCGI protocol */ diff --git a/sapi/cgi/tests/006.phpt b/sapi/cgi/tests/006.phpt index e183fea6b..a2b2b2903 100644 --- a/sapi/cgi/tests/006.phpt +++ b/sapi/cgi/tests/006.phpt @@ -2,6 +2,8 @@ syntax check --SKIPIF-- +--INI-- +display_errors=stdout --FILE-- /dev/null`); +var_dump(`"$php" -n -l "$filename" 2>/dev/null`); @unlink($filename); diff --git a/sapi/cli/config.m4 b/sapi/cli/config.m4 index e8043577e..882cab4ba 100644 --- a/sapi/cli/config.m4 +++ b/sapi/cli/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.22.2.1.2.1.2.1 2008/09/01 13:15:31 dmitry Exp $ +dnl $Id: config.m4 265790 2008-09-01 13:15:31Z dmitry $ dnl PHP_ARG_ENABLE(cli,, diff --git a/sapi/cli/config.w32 b/sapi/cli/config.w32 index f167828fc..cd106f197 100644 --- a/sapi/cli/config.w32 +++ b/sapi/cli/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.4.4.1.2.2 2007/10/05 16:00:30 rrichards Exp $ +// $Id: config.w32 243567 2007-10-05 16:00:30Z rrichards $ ARG_ENABLE('cli', 'Build CLI version of PHP', 'yes'); ARG_ENABLE('crt-debug', 'Extra CRT debugging', 'no'); diff --git a/sapi/cli/php_cli.c b/sapi/cli/php_cli.c index edc8f2953..aeade0940 100644 --- a/sapi/cli/php_cli.c +++ b/sapi/cli/php_cli.c @@ -20,7 +20,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_cli.c,v 1.129.2.13.2.22.2.26 2009/06/05 18:50:32 mattwil Exp $ */ +/* $Id: php_cli.c 287973 2009-09-02 20:02:17Z pajoye $ */ #include "php.h" #include "php_globals.h" @@ -298,7 +298,7 @@ static int sapi_cli_ub_write(const char *str, uint str_length TSRMLS_DC) /* {{{ remaining -= ret; } - return str_length; + return (ptr - str); } /* }}} */ @@ -672,10 +672,12 @@ int main(int argc, char *argv[]) #if defined(PHP_WIN32) && defined(_DEBUG) && defined(PHP_WIN32_DEBUG_HEAP) { int tmp_flag; - + _CrtSetReportMode(_CRT_WARN, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_WARN, _CRTDBG_FILE_STDERR); _CrtSetReportMode(_CRT_ERROR, _CRTDBG_MODE_FILE); _CrtSetReportFile(_CRT_ERROR, _CRTDBG_FILE_STDERR); - + _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_FILE); + _CrtSetReportFile(_CRT_ASSERT, _CRTDBG_FILE_STDERR); tmp_flag = _CrtSetDbgFlag(_CRTDBG_REPORT_FLAG); tmp_flag |= _CRTDBG_DELAY_FREE_MEM_DF; tmp_flag |= _CRTDBG_LEAK_CHECK_DF; diff --git a/sapi/cli/php_cli_readline.c b/sapi/cli/php_cli_readline.c index c79aa227c..66010d7b0 100644 --- a/sapi/cli/php_cli_readline.c +++ b/sapi/cli/php_cli_readline.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_cli_readline.c,v 1.3.2.5.2.3.2.3 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: php_cli_readline.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" diff --git a/sapi/cli/php_cli_readline.h b/sapi/cli/php_cli_readline.h index a200f656c..d2fd65935 100644 --- a/sapi/cli/php_cli_readline.h +++ b/sapi/cli/php_cli_readline.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_cli_readline.h,v 1.2.2.1.2.1.2.2 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: php_cli_readline.h 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" diff --git a/sapi/continuity/capi.c b/sapi/continuity/capi.c index 504739df3..250fa1424 100644 --- a/sapi/continuity/capi.c +++ b/sapi/continuity/capi.c @@ -110,7 +110,7 @@ PHP_MSHUTDOWN_FUNCTION(continuity) PHP_MINFO_FUNCTION(continuity) { php_info_print_table_start(); - php_info_print_table_row(2, "Continuity Module Revision", "$Revision: 1.11.2.2.2.1.2.5 $"); + php_info_print_table_row(2, "Continuity Module Revision", "$Revision: 272370 $"); php_info_print_table_row(2, "Server Version", conFget_build()); #ifdef CONTINUITY_CDPEXT php_info_print_table_row(2,"CDP Extensions", "enabled"); diff --git a/sapi/continuity/config.m4 b/sapi/continuity/config.m4 index b22ac5bd3..b91dd63eb 100644 --- a/sapi/continuity/config.m4 +++ b/sapi/continuity/config.m4 @@ -1,4 +1,4 @@ -dnl ## $Id: config.m4,v 1.3.4.1 2007/07/11 23:20:36 jani Exp $ -*- sh -*- +dnl ## $Id: config.m4 239540 2007-07-11 23:20:37Z jani $ -*- sh -*- PHP_ARG_WITH(continuity, for Continuity support, [ --with-continuity=DIR Build PHP as Continuity Server module. diff --git a/sapi/embed/config.m4 b/sapi/embed/config.m4 index a02cdd215..c9c9030ee 100644 --- a/sapi/embed/config.m4 +++ b/sapi/embed/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.9.4.2 2007/07/11 23:20:36 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_ENABLE(embed,, diff --git a/sapi/embed/config.w32 b/sapi/embed/config.w32 index 673c7e07b..8effedd25 100644 --- a/sapi/embed/config.w32 +++ b/sapi/embed/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.1 2003/12/19 23:19:19 wez Exp $ +// $Id: config.w32 146968 2003-12-19 23:19:19Z wez $ ARG_ENABLE('embed', 'Embedded SAPI library', 'no'); diff --git a/sapi/embed/php_embed.c b/sapi/embed/php_embed.c index d3df27ade..e32c3a387 100644 --- a/sapi/embed/php_embed.c +++ b/sapi/embed/php_embed.c @@ -15,7 +15,7 @@ | Author: Edin Kadribasic | +----------------------------------------------------------------------+ */ -/* $Id: php_embed.c,v 1.11.2.1.2.5.2.6 2009/01/04 20:18:57 pajoye Exp $ */ +/* $Id: php_embed.c 286569 2009-07-30 20:20:56Z garretts $ */ #include "php_embed.h" #include "ext/standard/php_standard.h" @@ -108,7 +108,7 @@ static int php_embed_startup(sapi_module_struct *sapi_module) return SUCCESS; } -sapi_module_struct php_embed_module = { +extern EMBED_SAPI_API sapi_module_struct php_embed_module = { "embed", /* name */ "PHP Embedded Library", /* pretty name */ @@ -152,7 +152,7 @@ static const zend_function_entry additional_functions[] = { {NULL, NULL, NULL} }; -int php_embed_init(int argc, char **argv PTSRMLS_DC) +EMBED_SAPI_API int php_embed_init(int argc, char **argv PTSRMLS_DC) { zend_llist global_vars; #ifdef ZTS @@ -217,7 +217,7 @@ int php_embed_init(int argc, char **argv PTSRMLS_DC) return SUCCESS; } -void php_embed_shutdown(TSRMLS_D) +EMBED_SAPI_API void php_embed_shutdown(TSRMLS_D) { php_request_shutdown((void *) 0); php_module_shutdown(TSRMLS_C); diff --git a/sapi/embed/php_embed.h b/sapi/embed/php_embed.h index 8c2fbb1e3..19d1c982e 100644 --- a/sapi/embed/php_embed.h +++ b/sapi/embed/php_embed.h @@ -15,7 +15,7 @@ | Author: Edin Kadribasic | +----------------------------------------------------------------------+ */ -/* $Id: php_embed.h,v 1.6.2.2.2.1.2.2 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: php_embed.h 286569 2009-07-30 20:20:56Z garretts $ */ #ifndef _PHP_EMBED_H_ #define _PHP_EMBED_H_ @@ -57,10 +57,16 @@ php_embed_shutdown(TSRMLS_C); \ } +#ifndef PHP_WIN32 + #define EMBED_SAPI_API SAPI_API +#else + #define EMBED_SAPI_API +#endif + BEGIN_EXTERN_C() -int php_embed_init(int argc, char **argv PTSRMLS_DC); -void php_embed_shutdown(TSRMLS_D); -extern sapi_module_struct php_embed_module; +EMBED_SAPI_API int php_embed_init(int argc, char **argv PTSRMLS_DC); +EMBED_SAPI_API void php_embed_shutdown(TSRMLS_D); +extern EMBED_SAPI_API sapi_module_struct php_embed_module; END_EXTERN_C() diff --git a/sapi/isapi/config.m4 b/sapi/isapi/config.m4 index acf383114..41a4f3f4a 100644 --- a/sapi/isapi/config.m4 +++ b/sapi/isapi/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.17.4.3 2007/07/11 23:20:36 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(isapi, for Zeus ISAPI support, diff --git a/sapi/isapi/config.w32 b/sapi/isapi/config.w32 index bb720fe39..30eef2c1e 100644 --- a/sapi/isapi/config.w32 +++ b/sapi/isapi/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.4.8.1 2008/05/14 03:13:17 auroraeosrose Exp $ +// $Id: config.w32 259731 2008-05-14 03:13:17Z auroraeosrose $ ARG_ENABLE('isapi', 'Build ISAPI version of PHP', 'no'); diff --git a/sapi/isapi/php5isapi.c b/sapi/isapi/php5isapi.c index 19d85874e..0f44efe4a 100644 --- a/sapi/isapi/php5isapi.c +++ b/sapi/isapi/php5isapi.c @@ -16,7 +16,7 @@ | Ben Mansell (Zeus Support) | +----------------------------------------------------------------------+ */ -/* $Id: php5isapi.c,v 1.8.2.2.2.3.2.5 2009/03/30 14:24:16 kalle Exp $ */ +/* $Id: php5isapi.c 278022 2009-03-30 14:24:16Z kalle $ */ #include "php.h" #include diff --git a/sapi/litespeed/README b/sapi/litespeed/README index ef3fe80ad..3f138c216 100644 --- a/sapi/litespeed/README +++ b/sapi/litespeed/README @@ -1,225 +1,225 @@ -Introduction -============ - -LiteSpeed SAPI module is a dedicated interface for PHP integration with -LiteSpeed Web Server. LiteSpeed SAPI has similar architecture to the -FastCGI SAPI with there major enhancements: better performance, dynamic -spawning and PHP configuration modification through web server -configuration and .htaccess files. - -Our simple benchmark test ("hello world") shows that PHP with -LiteSpeed SAPI has 30% better performance over PHP with FastCGI SAPI, -which is nearly twice the performance that Apache mod_php can deliver. - -A major drawback of FastCGI PHP comparing to Apache mod_php is lacking -the flexibilities in PHP configurations. PHP configurations cannot be -changed at runtime via configuration files like .htaccess files or web -server's virtual host configuration. In shared hosting environment, -each hosting account will has its own "open_basedir" overridden in -server configuration to enhance server security when mod_php is used. -usually, FastCGI PHP is not an option in shared hosting environment -due to lacking of this flexibility. LiteSpeed SAPI is carefully designed -to address this issue. PHP configurations can be modified the same way -as that in mod_php with the the same configuration directives. - -PHP with LiteSpeed SAPI is highly recommended over FastCGI PHP for -PHP scripting with LiteSpeed web server. - - -Building PHP with LiteSpeed SAPI -================================ - -You need to add "--with-litespeed" to the configure command to build -PHP with LiteSpeed SAPI, all other SAPI related configure options -should be removed. - -For example: - ./configure --with-litespeed - make - -You should find an executable called 'php' under sapi/litespeed/ -directory after the compilation succeeds. Copy it to -'lsws/fcgi-bin/lsphp' or wherever you prefer, if LiteSpeed web server -has been configured to run PHP with LiteSpeed SAPI already, you just -need to overwrite the old executable with this one and you are all -set. - -Start PHP from command line -=========================== - -Usually, lsphp is managed by LiteSpeed web server in a single server -installation. lsphp can be used in clustered environment with one -LiteSpeed web server at the front, load balancing lsphp processes -running on multiple backend servers. In such environment, lsphp can be -start manually from command with option "-b ", socket -address can be IPv4, IPv6 or Unix Domain Socket address. -for example: - - ./lsphp -b [::]:3000 - -have lsphp bind to port 3000 on all IPv4 and IPv6 address, - - ./lsphp -b *:3000 - -have lsphp bind to port 300 on all IPv4 address. - - ./lsphp -b 192.168.0.2:3000 - -have lsphp bind to address 192.168.0.2:3000. - - ./lsphp -b /tmp/lsphp_manual.sock - -have lsphp accept request on Unix domain socket "/tmp/lsphp_manual.sock" - - -Using LiteSpeed PHP with LiteSpeed Web Server -============================================= - -Detailed information about how to configure LiteSpeed web server with -PHP support is available from our website, at: - -http://www.litespeedtech.com/docs/HowTo_QA.html - -Usually, PHP support has been configured out of box, you don't need to -change it unless you want to change PHP interface from FastCGI to -LiteSpeed SAPI or vice versa. - -Brief instructions are as follow: - -1) Login to web administration interface, go to 'Server'->'Ext App' tab, - add an external application of type "LSAPI app", "Command" should be - set to a shell command that executes the PHP binary you just built. - "Instances" should be set to "1". Add "LSAPI_CHILDREN" environment - variable to match the value of "Max Connections". More tunable - environment variable described below can be added. - -2) Go to 'Server'->'Script Handler' tab, add a script handler - configuration: set 'suffix' to 'php', 'Handler Type' to 'LiteSpeed - API', 'Handler Name' should be the name of external application - just defined. - - -3) Click 'Apply Changes' link on the top left of the page, then click - 'graceful restart'. Now PHP is running with LiteSpeed SAPI. - -Tunings -------- - -There are a few environment variables that can be tweaked to control the -behavior of LSAPI application. - -* LSAPI_CHILDREN or PHP_LSAPI_CHILDREN (default: 0) - -There are two ways to let PHP handle multiple requests concurrently, -Server Managed Mode and Self Managed Mode. In Server Managed Mode, -LiteSpeed web server dynamically spawn/stop PHP processes, in this mode -"Instances" should match "Max Connections" configuration for PHP -external application. To start PHP in Self Managed Mode, "Instances" -should be set to "1", while "LSAPI_CHILDREN" environment variable should -be set to match the value of "Max Connections" and >1. Web Server will -start one PHP process, this process will start/stop children PHP processes -dynamically based on on demand. If "LSAPI_CHILDREN" <=1, PHP will be -started in server managed mode. - -Self Managed Mode is preferred because all PHP processes can share one -shared memory block for the opcode cache. - -Usually, there is no need to set value of LSAPI_CHILDREN over 100 in -most server environment. - - -* LSAPI_AVOID_FORK (default: 0) - -LSAPI_AVOID_FORK specifies the policy of the internal process manager in -"Self Managed Mode". When set to 0, the internal process manager will stop -and start children process on demand to save system resource. This is -preferred in a shared hosting environment. When set to 1, the internal -process manager will try to avoid freqently stopping and starting children -process. This might be preferred in a dedicate hosting environment. - - -* LSAPI_EXTRA_CHILDREN (default: 1/3 of LSAPI_CHILDREN or 0) - -LSAPI_EXTRA_CHILDREN controls the maximum number of extra children processes -can be started when some or all existing children processes are in -malfunctioning state. Total number of children processes will be reduced to -LSAPI_CHILDREN level as soon as service is back to normal. -When LSAPI_AVOID_FORK is set to 0, the default value is 1/3 of -LSAPI_CHIDLREN, When LSAPI_AVOID_FORK is set to 1, the default value is 0. - - -* LSAPI_MAX_REQS or PHP_LSAPI_MAX_REQUESTS (default value: 10000) - -This controls how many requests each child process will handle before -it exits automatically. Several PHP functions have been identified -having memory leaks. This parameter can help reducing memory usage -of leaky PHP functions. - - -* LSAPI_MAX_IDLE (default value: 300 seconds) - -In Self Managed Mode, LSAPI_MAX_IDLE controls how long a idle child -process will wait for a new request before it exits. This option help -releasing system resources taken by idle processes. - - -* LSAPI_MAX_IDLE_CHILDREN - (default value: 1/3 of LSAPI_CHILDREN or LSAPI_CHILDREN) - -In Self Managed Mode, LSAI_MAX_IDLE_CHILDREN controls how many idle -children processes are allowed. Excessive idle children processes -will be killed by the parent process immediately. -When LSAPI_AVOID_FORK is set to 0, the default value is 1/3 of -LSAPI_CHIDLREN, When LSAPI_AVOID_FORK is set to 1, the default value -is LSAPI_CHILDREN. - - -* LSAPI_MAX_PROCESS_TIME (default value: 300 seconds) - -In Self Managed Mode, LSAPI_MAX_PROCESS_TIME controls the maximum -processing time allowed when processing a request. If a child process -can not finish processing of a request in the given time period, it -will be killed by the parent process. This option can help getting rid -of dead or runaway child process. - - -* LSAPI_PGRP_MAX_IDLE (default value: FOREVER ) - -In Self Managed Mode, LSAPI_PGRP_MAX_IDLE controls how long the parent -process will wait before exiting when there is no child process. -This option help releasing system resources taken by an idle parent -process. - - -* LSAPI_PPID_NO_CHECK - -By default a LSAPI application check the existence of its parent process -and exits automatically if the parent process died. This is to reduce -orphan process when web server is restarted. However, it is desireable -to disable this feature, such as when a LSAPI process was started -manually from command line. LSAPI_PPID_NO_CHECK should be set when -you want to disable the checking of existence of parent process. -When PHP started by "-b" option, it is disabled automatically. - - -Compatibility with Apache mod_php -================================= - -LSAPI PHP supports PHP configuration overridden via web server configuration -as well as .htaccess. -Since 4.0 release "apache_response_headers" function is supported. - - - -Contact -======= - -For support questions, please post to our free support forum, at: - -http://www.litespeedtech.com/forum/ - -For bug report, please send bug report to bug [at] litespeedtech.com. - - - - +Introduction +============ + +LiteSpeed SAPI module is a dedicated interface for PHP integration with +LiteSpeed Web Server. LiteSpeed SAPI has similar architecture to the +FastCGI SAPI with there major enhancements: better performance, dynamic +spawning and PHP configuration modification through web server +configuration and .htaccess files. + +Our simple benchmark test ("hello world") shows that PHP with +LiteSpeed SAPI has 30% better performance over PHP with FastCGI SAPI, +which is nearly twice the performance that Apache mod_php can deliver. + +A major drawback of FastCGI PHP comparing to Apache mod_php is lacking +the flexibilities in PHP configurations. PHP configurations cannot be +changed at runtime via configuration files like .htaccess files or web +server's virtual host configuration. In shared hosting environment, +each hosting account will has its own "open_basedir" overridden in +server configuration to enhance server security when mod_php is used. +usually, FastCGI PHP is not an option in shared hosting environment +due to lacking of this flexibility. LiteSpeed SAPI is carefully designed +to address this issue. PHP configurations can be modified the same way +as that in mod_php with the the same configuration directives. + +PHP with LiteSpeed SAPI is highly recommended over FastCGI PHP for +PHP scripting with LiteSpeed web server. + + +Building PHP with LiteSpeed SAPI +================================ + +You need to add "--with-litespeed" to the configure command to build +PHP with LiteSpeed SAPI, all other SAPI related configure options +should be removed. + +For example: + ./configure --with-litespeed + make + +You should find an executable called 'php' under sapi/litespeed/ +directory after the compilation succeeds. Copy it to +'lsws/fcgi-bin/lsphp' or wherever you prefer, if LiteSpeed web server +has been configured to run PHP with LiteSpeed SAPI already, you just +need to overwrite the old executable with this one and you are all +set. + +Start PHP from command line +=========================== + +Usually, lsphp is managed by LiteSpeed web server in a single server +installation. lsphp can be used in clustered environment with one +LiteSpeed web server at the front, load balancing lsphp processes +running on multiple backend servers. In such environment, lsphp can be +start manually from command with option "-b ", socket +address can be IPv4, IPv6 or Unix Domain Socket address. +for example: + + ./lsphp -b [::]:3000 + +have lsphp bind to port 3000 on all IPv4 and IPv6 address, + + ./lsphp -b *:3000 + +have lsphp bind to port 300 on all IPv4 address. + + ./lsphp -b 192.168.0.2:3000 + +have lsphp bind to address 192.168.0.2:3000. + + ./lsphp -b /tmp/lsphp_manual.sock + +have lsphp accept request on Unix domain socket "/tmp/lsphp_manual.sock" + + +Using LiteSpeed PHP with LiteSpeed Web Server +============================================= + +Detailed information about how to configure LiteSpeed web server with +PHP support is available from our website, at: + +http://www.litespeedtech.com/docs/HowTo_QA.html + +Usually, PHP support has been configured out of box, you don't need to +change it unless you want to change PHP interface from FastCGI to +LiteSpeed SAPI or vice versa. + +Brief instructions are as follow: + +1) Login to web administration interface, go to 'Server'->'Ext App' tab, + add an external application of type "LSAPI app", "Command" should be + set to a shell command that executes the PHP binary you just built. + "Instances" should be set to "1". Add "LSAPI_CHILDREN" environment + variable to match the value of "Max Connections". More tunable + environment variable described below can be added. + +2) Go to 'Server'->'Script Handler' tab, add a script handler + configuration: set 'suffix' to 'php', 'Handler Type' to 'LiteSpeed + API', 'Handler Name' should be the name of external application + just defined. + + +3) Click 'Apply Changes' link on the top left of the page, then click + 'graceful restart'. Now PHP is running with LiteSpeed SAPI. + +Tunings +------- + +There are a few environment variables that can be tweaked to control the +behavior of LSAPI application. + +* LSAPI_CHILDREN or PHP_LSAPI_CHILDREN (default: 0) + +There are two ways to let PHP handle multiple requests concurrently, +Server Managed Mode and Self Managed Mode. In Server Managed Mode, +LiteSpeed web server dynamically spawn/stop PHP processes, in this mode +"Instances" should match "Max Connections" configuration for PHP +external application. To start PHP in Self Managed Mode, "Instances" +should be set to "1", while "LSAPI_CHILDREN" environment variable should +be set to match the value of "Max Connections" and >1. Web Server will +start one PHP process, this process will start/stop children PHP processes +dynamically based on on demand. If "LSAPI_CHILDREN" <=1, PHP will be +started in server managed mode. + +Self Managed Mode is preferred because all PHP processes can share one +shared memory block for the opcode cache. + +Usually, there is no need to set value of LSAPI_CHILDREN over 100 in +most server environment. + + +* LSAPI_AVOID_FORK (default: 0) + +LSAPI_AVOID_FORK specifies the policy of the internal process manager in +"Self Managed Mode". When set to 0, the internal process manager will stop +and start children process on demand to save system resource. This is +preferred in a shared hosting environment. When set to 1, the internal +process manager will try to avoid freqently stopping and starting children +process. This might be preferred in a dedicate hosting environment. + + +* LSAPI_EXTRA_CHILDREN (default: 1/3 of LSAPI_CHILDREN or 0) + +LSAPI_EXTRA_CHILDREN controls the maximum number of extra children processes +can be started when some or all existing children processes are in +malfunctioning state. Total number of children processes will be reduced to +LSAPI_CHILDREN level as soon as service is back to normal. +When LSAPI_AVOID_FORK is set to 0, the default value is 1/3 of +LSAPI_CHIDLREN, When LSAPI_AVOID_FORK is set to 1, the default value is 0. + + +* LSAPI_MAX_REQS or PHP_LSAPI_MAX_REQUESTS (default value: 10000) + +This controls how many requests each child process will handle before +it exits automatically. Several PHP functions have been identified +having memory leaks. This parameter can help reducing memory usage +of leaky PHP functions. + + +* LSAPI_MAX_IDLE (default value: 300 seconds) + +In Self Managed Mode, LSAPI_MAX_IDLE controls how long a idle child +process will wait for a new request before it exits. This option help +releasing system resources taken by idle processes. + + +* LSAPI_MAX_IDLE_CHILDREN + (default value: 1/3 of LSAPI_CHILDREN or LSAPI_CHILDREN) + +In Self Managed Mode, LSAI_MAX_IDLE_CHILDREN controls how many idle +children processes are allowed. Excessive idle children processes +will be killed by the parent process immediately. +When LSAPI_AVOID_FORK is set to 0, the default value is 1/3 of +LSAPI_CHIDLREN, When LSAPI_AVOID_FORK is set to 1, the default value +is LSAPI_CHILDREN. + + +* LSAPI_MAX_PROCESS_TIME (default value: 300 seconds) + +In Self Managed Mode, LSAPI_MAX_PROCESS_TIME controls the maximum +processing time allowed when processing a request. If a child process +can not finish processing of a request in the given time period, it +will be killed by the parent process. This option can help getting rid +of dead or runaway child process. + + +* LSAPI_PGRP_MAX_IDLE (default value: FOREVER ) + +In Self Managed Mode, LSAPI_PGRP_MAX_IDLE controls how long the parent +process will wait before exiting when there is no child process. +This option help releasing system resources taken by an idle parent +process. + + +* LSAPI_PPID_NO_CHECK + +By default a LSAPI application check the existence of its parent process +and exits automatically if the parent process died. This is to reduce +orphan process when web server is restarted. However, it is desireable +to disable this feature, such as when a LSAPI process was started +manually from command line. LSAPI_PPID_NO_CHECK should be set when +you want to disable the checking of existence of parent process. +When PHP started by "-b" option, it is disabled automatically. + + +Compatibility with Apache mod_php +================================= + +LSAPI PHP supports PHP configuration overridden via web server configuration +as well as .htaccess. +Since 4.0 release "apache_response_headers" function is supported. + + + +Contact +======= + +For support questions, please post to our free support forum, at: + +http://www.litespeedtech.com/forum/ + +For bug report, please send bug report to bug [at] litespeedtech.com. + + + + diff --git a/sapi/litespeed/config.m4 b/sapi/litespeed/config.m4 index 7d72a28cc..b4f3caa30 100644 --- a/sapi/litespeed/config.m4 +++ b/sapi/litespeed/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.2.2.4 2008/08/07 19:32:15 nlopess Exp $ +dnl $Id: config.m4 264419 2008-08-07 19:32:15Z nlopess $ dnl AC_MSG_CHECKING(for LiteSpeed support) diff --git a/sapi/litespeed/lsapi_main.c b/sapi/litespeed/lsapi_main.c index 70409c903..aed599e11 100644 --- a/sapi/litespeed/lsapi_main.c +++ b/sapi/litespeed/lsapi_main.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: lsapi_main.c,v 1.7.2.3 2008/08/26 22:05:17 gwang Exp $ */ +/* $Id: lsapi_main.c 265533 2008-08-26 22:05:17Z gwang $ */ #include "php.h" #include "SAPI.h" diff --git a/sapi/litespeed/lsapilib.c b/sapi/litespeed/lsapilib.c index 5d0e43aba..febe6b768 100644 --- a/sapi/litespeed/lsapilib.c +++ b/sapi/litespeed/lsapilib.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: lsapilib.c,v 1.5.2.6 2009/02/27 23:33:01 gwang Exp $ */ +/* $Id: lsapilib.c 276590 2009-02-27 23:33:01Z gwang $ */ /* Copyright (c) 2007, Lite Speed Technologies Inc. diff --git a/sapi/milter/config.m4 b/sapi/milter/config.m4 index a34563ae6..6c212dca4 100644 --- a/sapi/milter/config.m4 +++ b/sapi/milter/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.6.6.2 2007/07/11 23:20:36 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(milter, for Milter support, diff --git a/sapi/milter/php_milter.c b/sapi/milter/php_milter.c index c07e8c98b..baa62b2de 100644 --- a/sapi/milter/php_milter.c +++ b/sapi/milter/php_milter.c @@ -18,7 +18,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_milter.c,v 1.14.2.2.2.3.2.10 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: php_milter.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "php_globals.h" diff --git a/sapi/nsapi/config.m4 b/sapi/nsapi/config.m4 index a117438ab..6e2478bcd 100644 --- a/sapi/nsapi/config.m4 +++ b/sapi/nsapi/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.17.6.2 2007/07/11 23:20:37 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(nsapi, for NSAPI support, diff --git a/sapi/nsapi/config.w32 b/sapi/nsapi/config.w32 index f81825da5..f0e36ef2a 100644 --- a/sapi/nsapi/config.w32 +++ b/sapi/nsapi/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.4.8.1 2009/03/20 18:49:37 pajoye Exp $ +// $Id: config.w32 277527 2009-03-20 18:49:37Z pajoye $ ARG_ENABLE('nsapi', 'Build NSAPI for Netscape/iPlanet/SunONE webservers', 'no'); diff --git a/sapi/nsapi/nsapi-readme.txt b/sapi/nsapi/nsapi-readme.txt index a93d69ec6..a2590ac91 100644 --- a/sapi/nsapi/nsapi-readme.txt +++ b/sapi/nsapi/nsapi-readme.txt @@ -151,4 +151,4 @@ for the correct DLL name. The DLL with the biggest filesize is the right one. But be warned: SUPPORT FOR nsapi_virtual() IS EXPERIMENTAL !!! -$Id: nsapi-readme.txt,v 1.12.6.1 2006/10/27 07:29:51 thetaphi Exp $ +$Id: nsapi-readme.txt 242949 2007-09-26 15:44:16Z cvs2svn $ diff --git a/sapi/nsapi/nsapi.c b/sapi/nsapi/nsapi.c index 912a95ae6..cf088b1d6 100644 --- a/sapi/nsapi/nsapi.c +++ b/sapi/nsapi/nsapi.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: nsapi.c,v 1.69.2.3.2.6.2.19 2009/03/23 23:13:14 thetaphi Exp $ */ +/* $Id: nsapi.c 286722 2009-08-03 10:13:49Z thetaphi $ */ /* * PHP includes @@ -55,6 +55,13 @@ #define XP_UNIX #endif #endif + +/* + * The manual define of HPUX is to fix bug #46020, nsapi.h needs this to detect HPUX + */ +#ifdef __hpux +#define HPUX +#endif /* * NSAPI includes @@ -307,7 +314,7 @@ PHP_MSHUTDOWN_FUNCTION(nsapi) PHP_MINFO_FUNCTION(nsapi) { php_info_print_table_start(); - php_info_print_table_row(2, "NSAPI Module Revision", "$Revision: 1.69.2.3.2.6.2.19 $"); + php_info_print_table_row(2, "NSAPI Module Revision", "$Revision: 286722 $"); php_info_print_table_row(2, "Server Software", system_version()); php_info_print_table_row(2, "Sub-requests with nsapi_virtual()", (nsapi_servact_service)?((zend_ini_long("zlib.output_compression", sizeof("zlib.output_compression"), 0))?"not supported with zlib.output_compression":"enabled"):"not supported on this platform" ); diff --git a/sapi/phttpd/config.m4 b/sapi/phttpd/config.m4 index ca5cd80a5..935dbf3d6 100644 --- a/sapi/phttpd/config.m4 +++ b/sapi/phttpd/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.7.22.3 2007/07/11 23:20:37 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(phttpd, for PHTTPD support, diff --git a/sapi/pi3web/config.m4 b/sapi/pi3web/config.m4 index 633d7bb7a..bf8f59ad3 100644 --- a/sapi/pi3web/config.m4 +++ b/sapi/pi3web/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.10.6.2 2007/07/11 23:20:37 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(pi3web, for Pi3Web support, diff --git a/sapi/pi3web/config.w32 b/sapi/pi3web/config.w32 index b9bd29c6d..107a5d046 100644 --- a/sapi/pi3web/config.w32 +++ b/sapi/pi3web/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.3 2004/01/17 13:00:15 sniper Exp $ +// $Id: config.w32 149024 2004-01-17 13:00:38Z sniper $ ARG_WITH('pi3web', 'Pi3Web', 'no'); diff --git a/sapi/pi3web/pi3web_sapi.c b/sapi/pi3web/pi3web_sapi.c index 7f34858ca..7af5d5061 100644 --- a/sapi/pi3web/pi3web_sapi.c +++ b/sapi/pi3web/pi3web_sapi.c @@ -21,7 +21,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: pi3web_sapi.c,v 1.60.2.1.2.1.2.3 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: pi3web_sapi.c 272370 2008-12-31 11:15:49Z sebastian $ */ #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS @@ -57,7 +57,7 @@ static void php_info_pi3web(ZEND_MODULE_INFO_FUNC_ARGS) PUTS("\n"); PUTS("\n"); php_info_print_table_header(2, "Information Field", "Value"); - php_info_print_table_row(2, "Pi3Web SAPI module version", "$Id: pi3web_sapi.c,v 1.60.2.1.2.1.2.3 2008/12/31 11:15:49 sebastian Exp $"); + php_info_print_table_row(2, "Pi3Web SAPI module version", "$Id: pi3web_sapi.c 272370 2008-12-31 11:15:49Z sebastian $"); php_info_print_table_row(2, "Server Name Stamp", HTTPCore_getServerStamp()); snprintf(variable_buf, 511, "%d", HTTPCore_debugEnabled()); php_info_print_table_row(2, "Debug Enabled", variable_buf); diff --git a/sapi/roxen/config.m4 b/sapi/roxen/config.m4 index 1e32d94b7..f750e3582 100644 --- a/sapi/roxen/config.m4 +++ b/sapi/roxen/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.17.2.1.2.2 2007/07/11 23:20:37 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(roxen,, diff --git a/sapi/roxen/roxen.c b/sapi/roxen/roxen.c index 94a6f51ad..eabe14d63 100644 --- a/sapi/roxen/roxen.c +++ b/sapi/roxen/roxen.c @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: roxen.c,v 1.61.2.2.2.1.2.3 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: roxen.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #ifdef HAVE_ROXEN @@ -438,7 +438,7 @@ static void php_info_roxen(ZEND_MODULE_INFO_FUNC_ARGS) { /* char buf[512]; */ php_info_print_table_start(); - php_info_print_table_row(2, "SAPI module version", "$Id: roxen.c,v 1.61.2.2.2.1.2.3 2008/12/31 11:15:49 sebastian Exp $"); + php_info_print_table_row(2, "SAPI module version", "$Id: roxen.c 272370 2008-12-31 11:15:49Z sebastian $"); /* php_info_print_table_row(2, "Build date", Ns_InfoBuildDate()); php_info_print_table_row(2, "Config file path", Ns_InfoConfigFile()); php_info_print_table_row(2, "Error Log path", Ns_InfoErrorLog()); diff --git a/sapi/thttpd/README b/sapi/thttpd/README index 4be522f03..b0245841a 100644 --- a/sapi/thttpd/README +++ b/sapi/thttpd/README @@ -1,5 +1,5 @@ README FOR THTTPD MODULE (by Sascha Schumann) -($Date: 2003/02/19 10:57:21 $) +($Date: 2003-02-19 11:57:21 +0100 (Wed, 19 Feb 2003) $) This is a SAPI module for PHP 4.x supporting thttpd, the tiny, turbo, throttling HTTP server by Jef Poskanzer. diff --git a/sapi/thttpd/config.m4 b/sapi/thttpd/config.m4 index c0500b86e..9c3d4d7fb 100644 --- a/sapi/thttpd/config.m4 +++ b/sapi/thttpd/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.23.6.2 2007/07/11 23:20:37 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(thttpd,, diff --git a/sapi/thttpd/thttpd.c b/sapi/thttpd/thttpd.c index fd7a80fd5..187bddf65 100644 --- a/sapi/thttpd/thttpd.c +++ b/sapi/thttpd/thttpd.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: thttpd.c,v 1.95.2.1.2.1.2.3 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: thttpd.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "SAPI.h" diff --git a/sapi/tux/README b/sapi/tux/README index aac26ccb4..3a5294c77 100644 --- a/sapi/tux/README +++ b/sapi/tux/README @@ -1,5 +1,5 @@ README FOR THE TUX MODULE (by Sascha Schumann) -($Date: 2004/01/17 13:00:17 $) +($Date: 2004-01-17 14:00:38 +0100 (Sat, 17 Jan 2004) $) This is a SAPI module for the TUX web-server by Ingo Molnar. diff --git a/sapi/tux/config.m4 b/sapi/tux/config.m4 index 323318534..1933d3627 100644 --- a/sapi/tux/config.m4 +++ b/sapi/tux/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.4.6.2 2007/07/11 23:20:37 jani Exp $ +dnl $Id: config.m4 242949 2007-09-26 15:44:16Z cvs2svn $ dnl PHP_ARG_WITH(tux,, diff --git a/sapi/webjames/config.m4 b/sapi/webjames/config.m4 index 351781a61..cf019013d 100644 --- a/sapi/webjames/config.m4 +++ b/sapi/webjames/config.m4 @@ -1,5 +1,5 @@ dnl -dnl $Id: config.m4,v 1.5.22.2 2007/07/11 23:20:37 jani Exp $ +dnl $Id: config.m4 239540 2007-07-11 23:20:37Z jani $ dnl PHP_ARG_WITH(webjames,, diff --git a/scripts/apache/conffix.awk b/scripts/apache/conffix.awk index 30d488d6c..2b506e55c 100644 --- a/scripts/apache/conffix.awk +++ b/scripts/apache/conffix.awk @@ -1,4 +1,4 @@ -# $Id: conffix.awk,v 1.2 1999/08/07 15:31:57 zeev Exp $ +# $Id: conffix.awk 11765 1999-08-07 15:31:57Z zeev $ /^[ \t]*php3_*/ { phpcommand=substr($1,6) diff --git a/scripts/apache/htaccessfix.awk b/scripts/apache/htaccessfix.awk index 2523472c3..e43668c6d 100644 --- a/scripts/apache/htaccessfix.awk +++ b/scripts/apache/htaccessfix.awk @@ -1,4 +1,4 @@ -# $Id: htaccessfix.awk,v 1.2 1999/08/07 15:31:57 zeev Exp $ +# $Id: htaccessfix.awk 11765 1999-08-07 15:31:57Z zeev $ /^[ \t]*php3_*/ { phpcommand=substr($1,6) diff --git a/scripts/dev/check_parameters.php b/scripts/dev/check_parameters.php index c04d4b8d1..1cde038f9 100644 --- a/scripts/dev/check_parameters.php +++ b/scripts/dev/check_parameters.php @@ -17,7 +17,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: check_parameters.php,v 1.1.2.4 2007/01/01 19:32:09 iliaa Exp $ */ +/* $Id: check_parameters.php 226204 2007-01-01 19:32:10Z iliaa $ */ define('REPORT_LEVEL', 2); // 0 reports less false-positives. up to level 5. diff --git a/scripts/dev/conv_z_macros b/scripts/dev/conv_z_macros index fa1700568..100dd93aa 100755 --- a/scripts/dev/conv_z_macros +++ b/scripts/dev/conv_z_macros @@ -16,7 +16,7 @@ # | Author: Sascha Schumann | # +----------------------------------------------------------------------+ # -# $Id: conv_z_macros,v 1.4.2.1.2.1 2007/01/01 19:32:09 iliaa Exp $ +# $Id: conv_z_macros 226204 2007-01-01 19:32:10Z iliaa $ for i in $@; do echo -n "Processing $i... " diff --git a/svnclean.bat b/svnclean.bat new file mode 100755 index 000000000..4c0118d67 --- /dev/null +++ b/svnclean.bat @@ -0,0 +1,2 @@ +@echo off +cscript /nologo win32\build\cvsclean.js diff --git a/tests/basic/002.phpt b/tests/basic/002.phpt index e9330c8bf..25dc51303 100644 --- a/tests/basic/002.phpt +++ b/tests/basic/002.phpt @@ -1,7 +1,5 @@ --TEST-- Simple POST Method test ---SKIPIF-- - --POST-- a=Hello+World --FILE-- diff --git a/tests/basic/003.phpt b/tests/basic/003.phpt index ae6603f44..43d3be1d9 100644 --- a/tests/basic/003.phpt +++ b/tests/basic/003.phpt @@ -1,7 +1,5 @@ --TEST-- GET and POST Method combined ---SKIPIF-- - --POST-- a=Hello+World --GET-- diff --git a/tests/basic/004.phpt b/tests/basic/004.phpt index 86bf43186..c381e5009 100644 --- a/tests/basic/004.phpt +++ b/tests/basic/004.phpt @@ -1,7 +1,5 @@ --TEST-- Two variables in POST data ---SKIPIF-- - --POST-- a=Hello+World&b=Hello+Again+World --FILE-- diff --git a/tests/basic/005.phpt b/tests/basic/005.phpt index aa1d19982..742e0ca4b 100644 --- a/tests/basic/005.phpt +++ b/tests/basic/005.phpt @@ -1,7 +1,5 @@ --TEST-- Three variables in POST data ---SKIPIF-- - --POST-- a=Hello+World&b=Hello+Again+World&c=1 --FILE-- diff --git a/tests/basic/011.phpt b/tests/basic/011.phpt index 34eed7915..2ec7a6ed1 100644 --- a/tests/basic/011.phpt +++ b/tests/basic/011.phpt @@ -1,7 +1,5 @@ --TEST-- Testing $argc and $argv handling (GET) ---SKIPIF-- - --INI-- register_argc_argv=1 --GET-- diff --git a/tests/basic/013.phpt b/tests/basic/013.phpt index a4155dcf6..376cc06dd 100644 --- a/tests/basic/013.phpt +++ b/tests/basic/013.phpt @@ -1,7 +1,5 @@ --TEST-- POST Method test and arrays ---SKIPIF-- - --POST-- a[]=1 --FILE-- diff --git a/tests/basic/014.phpt b/tests/basic/014.phpt index 9b7e59f98..7288c44a9 100644 --- a/tests/basic/014.phpt +++ b/tests/basic/014.phpt @@ -1,7 +1,5 @@ --TEST-- POST Method test and arrays - 2 ---SKIPIF-- - --POST-- a[]=1&a[]=1 --FILE-- diff --git a/tests/basic/015.phpt b/tests/basic/015.phpt index b297265bb..eecbaf130 100644 --- a/tests/basic/015.phpt +++ b/tests/basic/015.phpt @@ -1,7 +1,5 @@ --TEST-- POST Method test and arrays - 3 ---SKIPIF-- - --POST-- a[]=1&a[0]=5 --FILE-- diff --git a/tests/basic/016.phpt b/tests/basic/016.phpt index 277253168..b34fd1b1d 100644 --- a/tests/basic/016.phpt +++ b/tests/basic/016.phpt @@ -1,7 +1,5 @@ --TEST-- POST Method test and arrays - 4 ---SKIPIF-- - --POST-- a[a]=1&a[b]=3 --FILE-- diff --git a/tests/basic/017.phpt b/tests/basic/017.phpt index 69424caa6..d514726d1 100644 --- a/tests/basic/017.phpt +++ b/tests/basic/017.phpt @@ -1,7 +1,5 @@ --TEST-- POST Method test and arrays - 5 ---SKIPIF-- - --POST-- a[]=1&a[a]=1&a[b]=3 --FILE-- diff --git a/tests/basic/018.phpt b/tests/basic/018.phpt index 5cae5e8a6..45996b2fe 100644 --- a/tests/basic/018.phpt +++ b/tests/basic/018.phpt @@ -1,7 +1,5 @@ --TEST-- POST Method test and arrays - 6 ---SKIPIF-- - --POST-- a[][]=1&a[][]=3&b[a][b][c]=1&b[a][b][d]=1 --FILE-- diff --git a/tests/basic/019.phpt b/tests/basic/019.phpt index 467d4e6bf..3bece247a 100644 --- a/tests/basic/019.phpt +++ b/tests/basic/019.phpt @@ -1,7 +1,5 @@ --TEST-- POST Method test and arrays - 7 ---SKIPIF-- - --POST-- a[]=1&a[]]=3&a[[]=4 --FILE-- diff --git a/tests/basic/020.phpt b/tests/basic/020.phpt index 0d4704e7f..c94a60407 100644 --- a/tests/basic/020.phpt +++ b/tests/basic/020.phpt @@ -1,7 +1,5 @@ --TEST-- POST Method test and arrays - 8 ---SKIPIF-- - --POST-- a[a[]]=1&a[b[]]=3 --FILE-- diff --git a/tests/basic/021.phpt b/tests/basic/021.phpt index 3010a1b62..bce6bb3c9 100644 --- a/tests/basic/021.phpt +++ b/tests/basic/021.phpt @@ -2,8 +2,6 @@ Bug #37276 (problems witch $_POST array) --INI-- file_upload=1 ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 diff --git a/tests/basic/024.phpt b/tests/basic/024.phpt index c3336c7ce..847eeac82 100644 --- a/tests/basic/024.phpt +++ b/tests/basic/024.phpt @@ -3,8 +3,6 @@ Test HTTP_RAW_POST_DATA creation --INI-- magic_quotes_gpc=0 always_populate_raw_post_data=1 ---SKIPIF-- - --POST-- a=ABC&y=XYZ&c[]=1&c[]=2&c[a]=3 --FILE-- diff --git a/tests/basic/025.phpt b/tests/basic/025.phpt index fea9468b4..bafcac809 100644 --- a/tests/basic/025.phpt +++ b/tests/basic/025.phpt @@ -4,8 +4,6 @@ Test HTTP_RAW_POST_DATA with excessive post length magic_quotes_gpc=0 always_populate_raw_post_data=1 post_max_size=1K ---SKIPIF-- - --POST-- a=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --FILE-- diff --git a/tests/basic/026.phpt b/tests/basic/026.phpt index 78a18a475..957aa1972 100644 --- a/tests/basic/026.phpt +++ b/tests/basic/026.phpt @@ -3,8 +3,6 @@ Registration of HTTP_RAW_POST_DATA due to unknown content-type --INI-- magic_quotes_gpc=0 always_populate_raw_post_data=0 ---SKIPIF-- - --POST_RAW-- Content-Type: unknown/type a=1&b=ZYX @@ -15,4 +13,4 @@ var_dump($_POST, $HTTP_RAW_POST_DATA); --EXPECT-- array(0) { } -string(9) "a=1&b=ZYX" \ No newline at end of file +string(9) "a=1&b=ZYX" diff --git a/tests/basic/027.phpt b/tests/basic/027.phpt index 248507b29..ae5d78d50 100644 --- a/tests/basic/027.phpt +++ b/tests/basic/027.phpt @@ -7,8 +7,6 @@ display_errors=0 max_input_nesting_level=10 track_errors=1 log_errors=0 ---SKIPIF-- - --POST-- a=1&b=ZYX&c[][][][][][][][][][][][][][][][][][][][][][]=123&d=123&e[][]][]=3 --FILE-- diff --git a/tests/basic/bug45986.phpt b/tests/basic/bug45986.phpt new file mode 100644 index 000000000..5745d272c --- /dev/null +++ b/tests/basic/bug45986.phpt @@ -0,0 +1,12 @@ +--TEST-- +Bug #45986 (wrong error messag for a non existant file on rename) +--CREDITS-- +Sebastian Schürmann +sebs@php.net +Testfest 2009 Munich +--FILE-- + +--EXPECTREGEX-- +.*No such.* diff --git a/tests/basic/bug46759.phpt b/tests/basic/bug46759.phpt index fdbd59554..c5db2b9bb 100644 --- a/tests/basic/bug46759.phpt +++ b/tests/basic/bug46759.phpt @@ -1,7 +1,5 @@ --TEST-- Testing magic_quotes_gpc ---SKIPIF-- - --INI-- magic_quotes_gpc=1 --GET-- diff --git a/tests/basic/php_egg_logo_guid.phpt b/tests/basic/php_egg_logo_guid.phpt new file mode 100644 index 000000000..b3c5d7bdf --- /dev/null +++ b/tests/basic/php_egg_logo_guid.phpt @@ -0,0 +1,13 @@ +--TEST-- +Testing php_egg_logo_guid() function +--FILE-- + +--EXPECT-- +PHPE9568F36-D428-11d2-A769-00AA001ACF42 + +--CREDITS-- +Jason Easter +PHPUG Würzburg +Testfest 2009 2009-06-20 \ No newline at end of file diff --git a/tests/basic/php_logo_guid.phpt b/tests/basic/php_logo_guid.phpt new file mode 100644 index 000000000..b5724a96a --- /dev/null +++ b/tests/basic/php_logo_guid.phpt @@ -0,0 +1,10 @@ +--TEST-- +Testing php_logo_guid() function +--FILE-- + +--EXPECT-- +PHPE9568F34-D428-11d2-A769-00AA001ACF42 +--CREDITS-- +Testfest 2009 2009-06-20 \ No newline at end of file diff --git a/tests/basic/php_real_logo_guid.phpt b/tests/basic/php_real_logo_guid.phpt new file mode 100644 index 000000000..2b9003a35 --- /dev/null +++ b/tests/basic/php_real_logo_guid.phpt @@ -0,0 +1,12 @@ +--TEST-- +Testing php_real_logo_guid() function +--FILE-- + +--EXPECT-- +PHPE9568F34-D428-11d2-A769-00AA001ACF42 +--CREDITS-- +Jason Easter +PHPUG Würzburg +Testfest 2009 2009-06-20 \ No newline at end of file diff --git a/tests/basic/rfc1867_anonymous_upload.phpt b/tests/basic/rfc1867_anonymous_upload.phpt index 0f58014a4..8a27e2e37 100644 --- a/tests/basic/rfc1867_anonymous_upload.phpt +++ b/tests/basic/rfc1867_anonymous_upload.phpt @@ -5,8 +5,6 @@ file_uploads=1 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors upload_max_filesize=1024 ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 diff --git a/tests/basic/rfc1867_array_upload.phpt b/tests/basic/rfc1867_array_upload.phpt index 7af670006..0b762c209 100644 --- a/tests/basic/rfc1867_array_upload.phpt +++ b/tests/basic/rfc1867_array_upload.phpt @@ -5,8 +5,6 @@ file_uploads=1 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors upload_max_filesize=1024 ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 diff --git a/tests/basic/rfc1867_boundary_1.phpt b/tests/basic/rfc1867_boundary_1.phpt index 35fe3a3f6..fe0a9f2f4 100644 --- a/tests/basic/rfc1867_boundary_1.phpt +++ b/tests/basic/rfc1867_boundary_1.phpt @@ -4,8 +4,6 @@ rfc1867 boundary 1 post_max_size=1024 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary="------------------------------------foobar" --------------------------------------foobar diff --git a/tests/basic/rfc1867_boundary_2.phpt b/tests/basic/rfc1867_boundary_2.phpt index 575853bb6..256ec4bf7 100644 --- a/tests/basic/rfc1867_boundary_2.phpt +++ b/tests/basic/rfc1867_boundary_2.phpt @@ -4,8 +4,6 @@ rfc1867 boundary 2 post_max_size=1024 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary=------------------------------------foo, bar --------------------------------------foo diff --git a/tests/basic/rfc1867_empty_upload.phpt b/tests/basic/rfc1867_empty_upload.phpt index 10ed419d4..12ab0fdf0 100644 --- a/tests/basic/rfc1867_empty_upload.phpt +++ b/tests/basic/rfc1867_empty_upload.phpt @@ -5,8 +5,6 @@ file_uploads=1 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors upload_max_filesize=1024 ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 diff --git a/tests/basic/rfc1867_file_upload_disabled.phpt b/tests/basic/rfc1867_file_upload_disabled.phpt index a0d5271d9..99dee9b83 100644 --- a/tests/basic/rfc1867_file_upload_disabled.phpt +++ b/tests/basic/rfc1867_file_upload_disabled.phpt @@ -4,8 +4,6 @@ rfc1867 file_upload disabled file_uploads=0 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 diff --git a/tests/basic/rfc1867_garbled_mime_headers.phpt b/tests/basic/rfc1867_garbled_mime_headers.phpt index 9bee926d9..4010f22ca 100644 --- a/tests/basic/rfc1867_garbled_mime_headers.phpt +++ b/tests/basic/rfc1867_garbled_mime_headers.phpt @@ -5,8 +5,6 @@ file_uploads=1 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors upload_max_filesize=1024 ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 diff --git a/tests/basic/rfc1867_invalid_boundary.phpt b/tests/basic/rfc1867_invalid_boundary.phpt index 3c6639016..cb27675a0 100644 --- a/tests/basic/rfc1867_invalid_boundary.phpt +++ b/tests/basic/rfc1867_invalid_boundary.phpt @@ -4,8 +4,6 @@ rfc1867 invalid boundary post_max_size=1024 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary="foobar -----------------------------20896060251896012921717172737 diff --git a/tests/basic/rfc1867_malicious_input.phpt b/tests/basic/rfc1867_malicious_input.phpt index 74c7ad0f7..40b43d277 100644 --- a/tests/basic/rfc1867_malicious_input.phpt +++ b/tests/basic/rfc1867_malicious_input.phpt @@ -5,8 +5,6 @@ file_uploads=1 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors upload_max_filesize=1024 ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 diff --git a/tests/basic/rfc1867_max_file_size.phpt b/tests/basic/rfc1867_max_file_size.phpt index 0671dc5f0..fa7876fd1 100644 --- a/tests/basic/rfc1867_max_file_size.phpt +++ b/tests/basic/rfc1867_max_file_size.phpt @@ -5,8 +5,6 @@ file_uploads=1 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors upload_max_filesize=1024 ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 diff --git a/tests/basic/rfc1867_missing_boundary.phpt b/tests/basic/rfc1867_missing_boundary.phpt index 9c8726cd6..6218b135f 100644 --- a/tests/basic/rfc1867_missing_boundary.phpt +++ b/tests/basic/rfc1867_missing_boundary.phpt @@ -4,8 +4,6 @@ rfc1867 missing boundary post_max_size=1024 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data -----------------------------20896060251896012921717172737 diff --git a/tests/basic/rfc1867_missing_boundary_2.phpt b/tests/basic/rfc1867_missing_boundary_2.phpt index cace44383..a8f38ae53 100644 --- a/tests/basic/rfc1867_missing_boundary_2.phpt +++ b/tests/basic/rfc1867_missing_boundary_2.phpt @@ -5,8 +5,6 @@ file_uploads=1 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors upload_max_filesize=1024 ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 diff --git a/tests/basic/rfc1867_post_max_filesize.phpt b/tests/basic/rfc1867_post_max_filesize.phpt index 4276d496b..62be6c299 100644 --- a/tests/basic/rfc1867_post_max_filesize.phpt +++ b/tests/basic/rfc1867_post_max_filesize.phpt @@ -5,8 +5,6 @@ file_uploads=1 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors upload_max_filesize=1 ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 diff --git a/tests/basic/rfc1867_post_max_size.phpt b/tests/basic/rfc1867_post_max_size.phpt index 5e40ccaf4..92281351d 100644 --- a/tests/basic/rfc1867_post_max_size.phpt +++ b/tests/basic/rfc1867_post_max_size.phpt @@ -4,8 +4,6 @@ rfc1867 post_max_size post_max_size=1 error_reporting=E_ALL&~E_NOTICE comment=debug builds show some additional E_NOTICE errors ---SKIPIF-- - --POST_RAW-- Content-Type: multipart/form-data; boundary=---------------------------20896060251896012921717172737 -----------------------------20896060251896012921717172737 diff --git a/tests/basic/zend_logo_guid.phpt b/tests/basic/zend_logo_guid.phpt new file mode 100644 index 000000000..23ca0165a --- /dev/null +++ b/tests/basic/zend_logo_guid.phpt @@ -0,0 +1,13 @@ +--TEST-- +Testing zend_logo_guid() function +--FILE-- + +--EXPECT-- +PHPE9568F35-D428-11d2-A769-00AA001ACF42 + +--CREDITS-- +Jason Easter +PHPUG Würzburg +Testfest 2009 2009-06-20 \ No newline at end of file diff --git a/tests/classes/arrayobject_001.phpt b/tests/classes/arrayobject_001.phpt index 51208f8c6..b75f8c7ab 100644 --- a/tests/classes/arrayobject_001.phpt +++ b/tests/classes/arrayobject_001.phpt @@ -1,6 +1,5 @@ --TEST-- Ensure that ArrayObject acts like an array ---SKIPIF-- --FILE-- \ No newline at end of file diff --git a/tests/classes/autoload_implements.p5c b/tests/classes/autoload_implements.p5c index 66c8f7e53..2c3479c86 100755 --- a/tests/classes/autoload_implements.p5c +++ b/tests/classes/autoload_implements.p5c @@ -1,10 +1,10 @@ - \ No newline at end of file diff --git a/tests/classes/autoload_interface.p5c b/tests/classes/autoload_interface.p5c index 3f9a4e70a..6908155e6 100755 --- a/tests/classes/autoload_interface.p5c +++ b/tests/classes/autoload_interface.p5c @@ -1,7 +1,7 @@ - \ No newline at end of file diff --git a/tests/classes/autoload_root.p5c b/tests/classes/autoload_root.p5c index ab0283851..9559d36d3 100755 --- a/tests/classes/autoload_root.p5c +++ b/tests/classes/autoload_root.p5c @@ -1,10 +1,10 @@ - \ No newline at end of file diff --git a/tests/lang/bug24054.phpt b/tests/lang/bug24054.phpt index 3c9d74620..9f027e426 100644 --- a/tests/lang/bug24054.phpt +++ b/tests/lang/bug24054.phpt @@ -1,7 +1,7 @@ --TEST-- Bug #24054 (Assignment operator *= broken) --FILE-- - --GET-- 123[]=SEGV --FILE-- diff --git a/tests/lang/bug38579.inc b/tests/lang/bug38579.inc index f822e6d84..8ecc55824 100755 --- a/tests/lang/bug38579.inc +++ b/tests/lang/bug38579.inc @@ -1,3 +1,3 @@ - + diff --git a/tests/lang/bug44827.phpt b/tests/lang/bug44827.phpt new file mode 100644 index 000000000..38e1d4569 --- /dev/null +++ b/tests/lang/bug44827.phpt @@ -0,0 +1,14 @@ +--TEST-- +Bug #44827 (Class error when trying to access :: as constant) +--CREDITS-- +Sebastian Schürmann +sebs@php.net +Testfest Munich 2009 +--FILE-- + +--EXPECTREGEX-- +.*Fatal.* + diff --git a/tests/lang/engine_assignExecutionOrder_001.phpt b/tests/lang/engine_assignExecutionOrder_001.phpt index 4507e8b28..1b85cb7e6 100644 --- a/tests/lang/engine_assignExecutionOrder_001.phpt +++ b/tests/lang/engine_assignExecutionOrder_001.phpt @@ -1,152 +1,152 @@ ---TEST-- -Evaluation order during assignments. ---FILE-- -${f()} = g(); -var_dump($oa); - -echo "\n\nOrder with nested object property assignment:\n"; -$ob = new stdClass; -$ob->o1 = new stdClass; -$ob->o1->o2 = new stdClass; -$ob->o1->o2->${f()} = g(); -var_dump($ob); - -echo "\n\nOrder with dim_list property assignment:\n"; -$oc = new stdClass; -$oc->a[${f()}] = g(); -var_dump($oc); - - -class C { - public static $name = "original"; - public static $a = array(); - public static $string = "hello"; -} -echo "\n\nOrder with static property assignment:\n"; -C::${f()} = g(); -var_dump(C::$name); - -echo "\n\nOrder with static array property assignment:\n"; -C::$a[f()] = g(); -var_dump(C::$a); - -echo "\n\nOrder with indexed string assignment:\n"; -$string = "hello"; -function getOffset() { - echo "in getOffset()\n"; - return 0; -} -function newChar() { - echo "in newChar()\n"; - return 'j'; -} -$string[getOffset()] = newChar(); -var_dump($string); - -echo "\n\nOrder with static string property assignment:\n"; -C::$string[getOffset()] = newChar(); -var_dump(C::$string); - -?> ---EXPECTF-- - - -Order with local assignment: -in f() -in g() -%string|unicode%(14) "assigned value" - - -Order with array assignment: -in f() -in g() -array(1) { - [%u|b%"name"]=> - %string|unicode%(14) "assigned value" -} - - -Order with object property assignment: -in f() -in g() -object(stdClass)#%d (1) { - [%u|b%"assigned value"]=> - %string|unicode%(14) "assigned value" -} - - -Order with nested object property assignment: -in f() -in g() -object(stdClass)#%d (1) { - [%u|b%"o1"]=> - object(stdClass)#%d (1) { - [%u|b%"o2"]=> - object(stdClass)#%d (1) { - [%u|b%"assigned value"]=> - %string|unicode%(14) "assigned value" - } - } -} - - -Order with dim_list property assignment: -in f() -in g() -object(stdClass)#%d (1) { - [%u|b%"a"]=> - array(1) { - [%u|b%"assigned value"]=> - %string|unicode%(14) "assigned value" - } -} - - -Order with static property assignment: -in f() -in g() -%string|unicode%(14) "assigned value" - - -Order with static array property assignment: -in f() -in g() -array(1) { - [%u|b%"name"]=> - %string|unicode%(14) "assigned value" -} - - -Order with indexed string assignment: -in getOffset() -in newChar() -%string|unicode%(5) "jello" - - -Order with static string property assignment: -in getOffset() -in newChar() -%string|unicode%(5) "jello" +--TEST-- +Evaluation order during assignments. +--FILE-- +${f()} = g(); +var_dump($oa); + +echo "\n\nOrder with nested object property assignment:\n"; +$ob = new stdClass; +$ob->o1 = new stdClass; +$ob->o1->o2 = new stdClass; +$ob->o1->o2->${f()} = g(); +var_dump($ob); + +echo "\n\nOrder with dim_list property assignment:\n"; +$oc = new stdClass; +$oc->a[${f()}] = g(); +var_dump($oc); + + +class C { + public static $name = "original"; + public static $a = array(); + public static $string = "hello"; +} +echo "\n\nOrder with static property assignment:\n"; +C::${f()} = g(); +var_dump(C::$name); + +echo "\n\nOrder with static array property assignment:\n"; +C::$a[f()] = g(); +var_dump(C::$a); + +echo "\n\nOrder with indexed string assignment:\n"; +$string = "hello"; +function getOffset() { + echo "in getOffset()\n"; + return 0; +} +function newChar() { + echo "in newChar()\n"; + return 'j'; +} +$string[getOffset()] = newChar(); +var_dump($string); + +echo "\n\nOrder with static string property assignment:\n"; +C::$string[getOffset()] = newChar(); +var_dump(C::$string); + +?> +--EXPECTF-- + + +Order with local assignment: +in f() +in g() +%string|unicode%(14) "assigned value" + + +Order with array assignment: +in f() +in g() +array(1) { + [%u|b%"name"]=> + %string|unicode%(14) "assigned value" +} + + +Order with object property assignment: +in f() +in g() +object(stdClass)#%d (1) { + [%u|b%"assigned value"]=> + %string|unicode%(14) "assigned value" +} + + +Order with nested object property assignment: +in f() +in g() +object(stdClass)#%d (1) { + [%u|b%"o1"]=> + object(stdClass)#%d (1) { + [%u|b%"o2"]=> + object(stdClass)#%d (1) { + [%u|b%"assigned value"]=> + %string|unicode%(14) "assigned value" + } + } +} + + +Order with dim_list property assignment: +in f() +in g() +object(stdClass)#%d (1) { + [%u|b%"a"]=> + array(1) { + [%u|b%"assigned value"]=> + %string|unicode%(14) "assigned value" + } +} + + +Order with static property assignment: +in f() +in g() +%string|unicode%(14) "assigned value" + + +Order with static array property assignment: +in f() +in g() +array(1) { + [%u|b%"name"]=> + %string|unicode%(14) "assigned value" +} + + +Order with indexed string assignment: +in getOffset() +in newChar() +%string|unicode%(5) "jello" + + +Order with static string property assignment: +in getOffset() +in newChar() +%string|unicode%(5) "jello" diff --git a/tests/lang/engine_assignExecutionOrder_002.phpt b/tests/lang/engine_assignExecutionOrder_002.phpt index 7830af294..ba88150dd 100644 --- a/tests/lang/engine_assignExecutionOrder_002.phpt +++ b/tests/lang/engine_assignExecutionOrder_002.phpt @@ -1,135 +1,135 @@ ---TEST-- -Evaluation order during assignments. ---FILE-- - ---EXPECTF-- -A=hello B=bye - -Warning: Cannot use a scalar value as an array in %s on line %d -array(2) { - [0]=> - int(10) - [1]=> - int(10) -} -array(2) { - [0]=> - int(30) - [1]=> - int(30) -} -array(3) { - [0]=> - int(1000) - [1]=> - int(2000) - [2]=> - int(3000) -} -L=100 M=200 N=300 -O= and P= -10 20 40 50 60 70 80 - -Notice: Undefined offset: 1 in %s on line %d - -Notice: Undefined offset: 0 in %s on line %d -Y=,Z= - -Notice: Undefined offset: 1 in %s on line %d -AA=10 -CC=10 DD=30 -Array -( - [0] => array created in f() - [array entry created after f()] => Array - ( - [1] => hello - ) - -) +--TEST-- +Evaluation order during assignments. +--FILE-- + +--EXPECTF-- +A=hello B=bye + +Warning: Cannot use a scalar value as an array in %s on line %d +array(2) { + [0]=> + int(10) + [1]=> + int(10) +} +array(2) { + [0]=> + int(30) + [1]=> + int(30) +} +array(3) { + [0]=> + int(1000) + [1]=> + int(2000) + [2]=> + int(3000) +} +L=100 M=200 N=300 +O= and P= +10 20 40 50 60 70 80 + +Notice: Undefined offset: 1 in %s on line %d + +Notice: Undefined offset: 0 in %s on line %d +Y=,Z= + +Notice: Undefined offset: 1 in %s on line %d +AA=10 +CC=10 DD=30 +Array +( + [0] => array created in f() + [array entry created after f()] => Array + ( + [1] => hello + ) + +) diff --git a/tests/lang/engine_assignExecutionOrder_003.phpt b/tests/lang/engine_assignExecutionOrder_003.phpt index 71c87c9d8..ae3ae787c 100644 --- a/tests/lang/engine_assignExecutionOrder_003.phpt +++ b/tests/lang/engine_assignExecutionOrder_003.phpt @@ -1,96 +1,96 @@ ---TEST-- -Evaluation order during assignments. ---FILE-- - ---EXPECT-- -Good call -Good call -Expect 15 and get...15 -array(2) { - [0]=> - array(1) { - [0]=> - int(10) - } - [1]=> - int(3) +--TEST-- +Evaluation order during assignments. +--FILE-- + +--EXPECT-- +Good call +Good call +Expect 15 and get...15 +array(2) { + [0]=> + array(1) { + [0]=> + int(10) + } + [1]=> + int(3) } \ No newline at end of file diff --git a/tests/lang/engine_assignExecutionOrder_004.phpt b/tests/lang/engine_assignExecutionOrder_004.phpt index 09ff8bd76..86bc87f9c 100644 --- a/tests/lang/engine_assignExecutionOrder_004.phpt +++ b/tests/lang/engine_assignExecutionOrder_004.phpt @@ -1,52 +1,52 @@ ---TEST-- -Evaluation order during assignments. ---FILE-- - ---EXPECT-- -i1 -i2 -i3 -i4 -array(6) { - [0]=> - int(10) - [1]=> - int(11) - [2]=> - int(0) - [3]=> - int(30) - [4]=> - int(40) - [5]=> - int(3) -} +--TEST-- +Evaluation order during assignments. +--FILE-- + +--EXPECT-- +i1 +i2 +i3 +i4 +array(6) { + [0]=> + int(10) + [1]=> + int(11) + [2]=> + int(0) + [3]=> + int(30) + [4]=> + int(40) + [5]=> + int(3) +} diff --git a/tests/lang/engine_assignExecutionOrder_005.phpt b/tests/lang/engine_assignExecutionOrder_005.phpt index 82715dbda..6ec03f17c 100644 --- a/tests/lang/engine_assignExecutionOrder_005.phpt +++ b/tests/lang/engine_assignExecutionOrder_005.phpt @@ -1,74 +1,74 @@ ---TEST-- -Evaluation order during assignments. ---FILE-- - ---EXPECT-- -i1 -i2 -i3 -i4 -i5 -i6 -array(1) { - [0]=> - array(1) { - [0]=> - int(2) - } -} -array(1) { - [0]=> - array(1) { - [0]=> - int(2) - } -} -array(1) { - [0]=> - array(1) { - [0]=> - int(2) - } -} +--TEST-- +Evaluation order during assignments. +--FILE-- + +--EXPECT-- +i1 +i2 +i3 +i4 +i5 +i6 +array(1) { + [0]=> + array(1) { + [0]=> + int(2) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(2) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(2) + } +} diff --git a/tests/lang/engine_assignExecutionOrder_006.phpt b/tests/lang/engine_assignExecutionOrder_006.phpt index ac90db8f1..faa34c387 100644 --- a/tests/lang/engine_assignExecutionOrder_006.phpt +++ b/tests/lang/engine_assignExecutionOrder_006.phpt @@ -1,138 +1,138 @@ ---TEST-- -Evaluation order during assignments. ---FILE-- - ---EXPECT-- -i1 -i2 -i3 -i4 -i5 -i6 -array(1) { - [0]=> - array(1) { - [0]=> - int(2) - } -} -array(1) { - [0]=> - array(1) { - [0]=> - int(2) - } -} -array(1) { - [0]=> - array(1) { - [0]=> - int(2) - } -} -i1 -i2 -i3 -i4 -i5 -i6 -array(1) { - [0]=> - array(1) { - [0]=> - int(-2) - } -} -array(1) { - [0]=> - array(1) { - [0]=> - int(-2) - } -} -array(1) { - [0]=> - array(1) { - [0]=> - int(2) - } -} -i1 -i2 -i3 -i4 -i5 -i6 -array(1) { - [0]=> - array(1) { - [0]=> - int(-2) - } -} -array(1) { - [0]=> - array(1) { - [0]=> - int(2) - } -} -array(1) { - [0]=> - array(1) { - [0]=> - int(2) - } -} +--TEST-- +Evaluation order during assignments. +--FILE-- + +--EXPECT-- +i1 +i2 +i3 +i4 +i5 +i6 +array(1) { + [0]=> + array(1) { + [0]=> + int(2) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(2) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(2) + } +} +i1 +i2 +i3 +i4 +i5 +i6 +array(1) { + [0]=> + array(1) { + [0]=> + int(-2) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(-2) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(2) + } +} +i1 +i2 +i3 +i4 +i5 +i6 +array(1) { + [0]=> + array(1) { + [0]=> + int(-2) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(2) + } +} +array(1) { + [0]=> + array(1) { + [0]=> + int(2) + } +} diff --git a/tests/lang/engine_assignExecutionOrder_007.phpt b/tests/lang/engine_assignExecutionOrder_007.phpt index a5270df82..56b729ed8 100644 --- a/tests/lang/engine_assignExecutionOrder_007.phpt +++ b/tests/lang/engine_assignExecutionOrder_007.phpt @@ -1,46 +1,46 @@ ---TEST-- -Check key execution order with &new. ---FILE-- -a =& new $a[$i=2][++$i]; -$o->a->b =& new $a[$i=2][++$i]; -print_r($o); -?> ---EXPECTF-- -Deprecated: Assigning the return value of new by reference is deprecated in %s.php on line 3 - -Deprecated: Assigning the return value of new by reference is deprecated in %s.php on line 7 - -Deprecated: Assigning the return value of new by reference is deprecated in %s.php on line 8 -Array -( - [2] => Array - ( - [3] => stdClass - ) - - [0] => Array - ( - [1] => stdClass Object - ( - ) - - ) - -) -stdClass Object -( - [a] => stdClass Object - ( - [b] => stdClass Object - ( - ) - - ) - -) +--TEST-- +Check key execution order with &new. +--FILE-- +a =& new $a[$i=2][++$i]; +$o->a->b =& new $a[$i=2][++$i]; +print_r($o); +?> +--EXPECTF-- +Deprecated: Assigning the return value of new by reference is deprecated in %s.php on line 3 + +Deprecated: Assigning the return value of new by reference is deprecated in %s.php on line 7 + +Deprecated: Assigning the return value of new by reference is deprecated in %s.php on line 8 +Array +( + [2] => Array + ( + [3] => stdClass + ) + + [0] => Array + ( + [1] => stdClass Object + ( + ) + + ) + +) +stdClass Object +( + [a] => stdClass Object + ( + [b] => stdClass Object + ( + ) + + ) + +) diff --git a/tests/lang/engine_assignExecutionOrder_008.phpt b/tests/lang/engine_assignExecutionOrder_008.phpt index 301fa541a..0d699bc64 100644 --- a/tests/lang/engine_assignExecutionOrder_008.phpt +++ b/tests/lang/engine_assignExecutionOrder_008.phpt @@ -1,75 +1,75 @@ ---TEST-- -Ensure by value assignments leave temporaries on the stack, for all sorts of assignees. ---FILE-- -p=f(): '; -echo $a[$i->p=f()][++$i->p]; -unset($i); - -echo "\n" . '$i->p->q=f(): '; -echo $a[$i->p->q=f()][++$i->p->q]; -unset($i); - -echo "\n" . '$i->p[0]=f(): '; -echo $a[$i->p[0]=f()][++$i->p[0]]; -unset($i); - -echo "\n" . '$i->p[0]->p=f(): '; -echo $a[$i->p[0]->p=f()][++$i->p[0]->p]; -unset($i); - -Class C { - static $p; -} - -echo "\n" . 'C::$p=f(): '; -echo $a[C::$p=f()][++C::$p]; - -echo "\n" . 'C::$p[0]=f(): '; -C::$p = array(); -echo $a[C::$p[0]=f()][++C::$p[0]]; - -echo "\n" . 'C::$p->q=f(): '; -C::$p = new stdclass; -echo $a[C::$p->q=f()][++C::$p->q]; -?> ---EXPECTF-- -$i=f(): good -$$x=f(): good -${'i'}=f(): good -$i[0]=f(): good -$i[0][0]=f(): good -$i->p=f(): good -$i->p->q=f(): good -$i->p[0]=f(): good -$i->p[0]->p=f(): good -C::$p=f(): good -C::$p[0]=f(): good +--TEST-- +Ensure by value assignments leave temporaries on the stack, for all sorts of assignees. +--FILE-- +p=f(): '; +echo $a[$i->p=f()][++$i->p]; +unset($i); + +echo "\n" . '$i->p->q=f(): '; +echo $a[$i->p->q=f()][++$i->p->q]; +unset($i); + +echo "\n" . '$i->p[0]=f(): '; +echo $a[$i->p[0]=f()][++$i->p[0]]; +unset($i); + +echo "\n" . '$i->p[0]->p=f(): '; +echo $a[$i->p[0]->p=f()][++$i->p[0]->p]; +unset($i); + +Class C { + static $p; +} + +echo "\n" . 'C::$p=f(): '; +echo $a[C::$p=f()][++C::$p]; + +echo "\n" . 'C::$p[0]=f(): '; +C::$p = array(); +echo $a[C::$p[0]=f()][++C::$p[0]]; + +echo "\n" . 'C::$p->q=f(): '; +C::$p = new stdclass; +echo $a[C::$p->q=f()][++C::$p->q]; +?> +--EXPECTF-- +$i=f(): good +$$x=f(): good +${'i'}=f(): good +$i[0]=f(): good +$i[0][0]=f(): good +$i->p=f(): good +$i->p->q=f(): good +$i->p[0]=f(): good +$i->p[0]->p=f(): good +C::$p=f(): good +C::$p[0]=f(): good C::$p->q=f(): good \ No newline at end of file diff --git a/tests/lang/engine_assignExecutionOrder_009.phpt b/tests/lang/engine_assignExecutionOrder_009.phpt index 58300a171..e1d5b71c6 100644 --- a/tests/lang/engine_assignExecutionOrder_009.phpt +++ b/tests/lang/engine_assignExecutionOrder_009.phpt @@ -1,36 +1,36 @@ ---TEST-- -Execution ordering with comparison operators. ---FILE-- - f(++$i)); -var_dump(f($i=0) >= f(++$i)); - -echo "\nArray indices:\n"; -$a[1][2] = 0; -$a[3][4] = 1; -$i=0; -var_dump($a[$i=1][++$i] < $a[++$i][++$i]); -var_dump($a[$i=1][++$i] <= $a[++$i][++$i]); -var_dump($a[$i=1][++$i] > $a[++$i][++$i]); -var_dump($a[$i=1][++$i] >= $a[++$i][++$i]); -?> ---EXPECTF-- -Function call args: -f(0) f(1) bool(true) -f(0) f(1) bool(true) -f(0) f(1) bool(false) -f(0) f(1) bool(false) - -Array indices: -bool(true) -bool(true) -bool(false) -bool(false) +--TEST-- +Execution ordering with comparison operators. +--FILE-- + f(++$i)); +var_dump(f($i=0) >= f(++$i)); + +echo "\nArray indices:\n"; +$a[1][2] = 0; +$a[3][4] = 1; +$i=0; +var_dump($a[$i=1][++$i] < $a[++$i][++$i]); +var_dump($a[$i=1][++$i] <= $a[++$i][++$i]); +var_dump($a[$i=1][++$i] > $a[++$i][++$i]); +var_dump($a[$i=1][++$i] >= $a[++$i][++$i]); +?> +--EXPECTF-- +Function call args: +f(0) f(1) bool(true) +f(0) f(1) bool(true) +f(0) f(1) bool(false) +f(0) f(1) bool(false) + +Array indices: +bool(true) +bool(true) +bool(false) +bool(false) diff --git a/tests/lang/execution_order.phpt b/tests/lang/execution_order.phpt index dc9279146..ca3feb32c 100644 --- a/tests/lang/execution_order.phpt +++ b/tests/lang/execution_order.phpt @@ -1,198 +1,198 @@ ---TEST-- -Execution order of variables ---FILE-- -str.($str->str="good"); -echo "3)"; -echo $c; -echo "\r\n"; - -$str->str = "bad"; - -$c = ($str->str="good").$str->str; -echo "4)"; -echo $c; -echo "\r\n"; - -$c = strclass::$statstr.(strclass::$statstr="good"); -echo "5)"; -echo $c; -echo "\r\n"; - -strclass::$statstr = "bad"; - -$c = (strclass::$statstr="good").strclass::$statstr; -echo "6)"; -echo $c; -echo "\r\n"; - - -function foo() { - global $a; - $a = "good"; - return $a; -} - - -$a = "bad"; -echo "7)"; -echo foo() . $a; -echo "\r\n"; - -$a = "bad"; -echo "8)"; -echo $a . foo(); -echo "\r\n"; - -/* other operators */ - -$x = 1; -$z = $x - ($x++); -echo "9)"; -echo $z; -echo "\r\n"; - -$x = 1; -$z = ($x++) - $x; -echo "10)"; -echo $z; -echo "\r\n"; - -$x = 1; -$z = $x - (++$x); -echo "11)"; -echo $z; -echo "\r\n"; - -$x = 1; -$z = (++$x) - $x; -echo "12)"; -echo $z; -echo "\r\n"; - - -$x = 1; -$y = 3; -$z = $x - ($x=$y); -echo "13)"; -echo $z; -echo "\r\n"; - -$x = 1; -$y = 3; -$z = ($x=$y) - $x; -echo "14)"; -echo $z; -echo "\r\n"; - - -$a = 100; -$b = 200; -echo "15)"; -echo $a + ($a=$b); -echo "\r\n"; - -$a = 100; -$b = 200; -echo "16)"; -echo ($a=$b) + $a; -echo "\r\n"; - - -$a = array(100,200); -$i = 0; - -echo "17)"; -echo $a[$i++] + $a[$i++]; -echo "\r\n"; - -$i = -1; -echo "18)"; -echo $a[++$i] + $a[++$i]; -echo "\r\n"; - -$i = 0; -echo "19)"; -echo $a[$i] + ($a[$i]=400); -echo "\r\n"; - - -$a[0] = 100; -echo "20)"; -echo ($a[$i]=400) + $a[$i]; -echo "\r\n"; - - -class c { - var $val = 10; - static $stat = 20; -} - -echo "21)"; -echo c::$stat + (c::$stat=200); -echo "\r\n"; - -echo "22)"; -echo (c::$stat=300) + c::$stat; -echo "\r\n"; - -$c = new c(); - -echo "23)"; -echo $c->val + ($c->val=200); -echo "\r\n"; - -echo "24)"; -echo ($c->val=300) + $c->val; -echo "\r\n"; - -?> ---EXPECT-- -1)goodgood -2)goodgood -3)badgood -4)goodgood -5)badgood -6)goodgood -7)goodgood -8)goodgood -9)1 -10)-1 -11)0 -12)0 -13)0 -14)0 -15)400 -16)400 -17)300 -18)300 -19)500 -20)800 -21)220 -22)600 -23)210 -24)600 +--TEST-- +Execution order of variables +--FILE-- +str.($str->str="good"); +echo "3)"; +echo $c; +echo "\r\n"; + +$str->str = "bad"; + +$c = ($str->str="good").$str->str; +echo "4)"; +echo $c; +echo "\r\n"; + +$c = strclass::$statstr.(strclass::$statstr="good"); +echo "5)"; +echo $c; +echo "\r\n"; + +strclass::$statstr = "bad"; + +$c = (strclass::$statstr="good").strclass::$statstr; +echo "6)"; +echo $c; +echo "\r\n"; + + +function foo() { + global $a; + $a = "good"; + return $a; +} + + +$a = "bad"; +echo "7)"; +echo foo() . $a; +echo "\r\n"; + +$a = "bad"; +echo "8)"; +echo $a . foo(); +echo "\r\n"; + +/* other operators */ + +$x = 1; +$z = $x - ($x++); +echo "9)"; +echo $z; +echo "\r\n"; + +$x = 1; +$z = ($x++) - $x; +echo "10)"; +echo $z; +echo "\r\n"; + +$x = 1; +$z = $x - (++$x); +echo "11)"; +echo $z; +echo "\r\n"; + +$x = 1; +$z = (++$x) - $x; +echo "12)"; +echo $z; +echo "\r\n"; + + +$x = 1; +$y = 3; +$z = $x - ($x=$y); +echo "13)"; +echo $z; +echo "\r\n"; + +$x = 1; +$y = 3; +$z = ($x=$y) - $x; +echo "14)"; +echo $z; +echo "\r\n"; + + +$a = 100; +$b = 200; +echo "15)"; +echo $a + ($a=$b); +echo "\r\n"; + +$a = 100; +$b = 200; +echo "16)"; +echo ($a=$b) + $a; +echo "\r\n"; + + +$a = array(100,200); +$i = 0; + +echo "17)"; +echo $a[$i++] + $a[$i++]; +echo "\r\n"; + +$i = -1; +echo "18)"; +echo $a[++$i] + $a[++$i]; +echo "\r\n"; + +$i = 0; +echo "19)"; +echo $a[$i] + ($a[$i]=400); +echo "\r\n"; + + +$a[0] = 100; +echo "20)"; +echo ($a[$i]=400) + $a[$i]; +echo "\r\n"; + + +class c { + var $val = 10; + static $stat = 20; +} + +echo "21)"; +echo c::$stat + (c::$stat=200); +echo "\r\n"; + +echo "22)"; +echo (c::$stat=300) + c::$stat; +echo "\r\n"; + +$c = new c(); + +echo "23)"; +echo $c->val + ($c->val=200); +echo "\r\n"; + +echo "24)"; +echo ($c->val=300) + $c->val; +echo "\r\n"; + +?> +--EXPECT-- +1)goodgood +2)goodgood +3)badgood +4)goodgood +5)badgood +6)goodgood +7)goodgood +8)goodgood +9)1 +10)-1 +11)0 +12)0 +13)0 +14)0 +15)400 +16)400 +17)300 +18)300 +19)500 +20)800 +21)220 +22)600 +23)210 +24)600 diff --git a/tests/security/open_basedir_parse_ini_file.phpt b/tests/security/open_basedir_parse_ini_file.phpt index ac740f073..926c07771 100644 --- a/tests/security/open_basedir_parse_ini_file.phpt +++ b/tests/security/open_basedir_parse_ini_file.phpt @@ -39,43 +39,43 @@ bool(true) Warning: parse_ini_file(): open_basedir restriction in effect. File(%s\test\bad) is not within the allowed path(s): (.) in %s on line %d -Warning: parse_ini_file(%s\test\bad): failed to open stream: Operation not permitted in %s on line %d +Warning: parse_ini_file(%s\test\bad): failed to open stream: %s in %s on line %d array(0) { } Warning: parse_ini_file(): open_basedir restriction in effect. File(%s\test\bad\bad.txt) is not within the allowed path(s): (.) in %s on line %d -Warning: parse_ini_file(%s\test\bad\bad.txt): failed to open stream: Operation not permitted in %s on line %d +Warning: parse_ini_file(%s\test\bad\bad.txt): failed to open stream: %s in %s on line %d array(0) { } Warning: parse_ini_file(): open_basedir restriction in effect. File(%s\test) is not within the allowed path(s): (.) in %s on line %d -Warning: parse_ini_file(%s\test): failed to open stream: Operation not permitted in %s on line %d +Warning: parse_ini_file(%s\test): failed to open stream: %s in %s on line %d array(0) { } Warning: parse_ini_file(): open_basedir restriction in effect. File(%s\test) is not within the allowed path(s): (.) in %s on line %d -Warning: parse_ini_file(%s\test): failed to open stream: Operation not permitted in %s on line %d +Warning: parse_ini_file(%s\test): failed to open stream: %s in %s on line %d array(0) { } Warning: parse_ini_file(): open_basedir restriction in effect. File(%s\test\bad) is not within the allowed path(s): (.) in %s on line %d -Warning: parse_ini_file(%s\test\bad): failed to open stream: Operation not permitted in %s on line %d +Warning: parse_ini_file(%s\test\bad): failed to open stream: %s in %s on line %d array(0) { } Warning: parse_ini_file(): open_basedir restriction in effect. File(%s\test\bad\bad.txt) is not within the allowed path(s): (.) in %s on line %d -Warning: parse_ini_file(%s\test\bad\bad.txt): failed to open stream: Operation not permitted in %s on line %d +Warning: parse_ini_file(%s\test\bad\bad.txt): failed to open stream: %s in %s on line %d array(0) { } Warning: parse_ini_file(): open_basedir restriction in effect. File(%s\test) is not within the allowed path(s): (.) in %s on line %d -Warning: parse_ini_file(%s\test): failed to open stream: Operation not permitted in %s on line %d +Warning: parse_ini_file(%s\test): failed to open stream: %s in %s on line %d array(0) { } *** Finished testing open_basedir configuration [parse_ini_file] *** diff --git a/vcsclean b/vcsclean new file mode 100755 index 000000000..e1004e434 --- /dev/null +++ b/vcsclean @@ -0,0 +1,11 @@ +#! /bin/sh + +if test -d 'CVS'; then + ${MAKE:-make} -f build/build.mk cvsclean-work +elif test -d '.svn'; then + ${MAKE:-make} -f build/build.mk svnclean-work +elif test -d '.git'; then + ${MAKE:-make} -f build/build.mk gitclean-work +else + echo "Can't figure out your VCS, not cleaning." +fi diff --git a/win32/build/Makefile b/win32/build/Makefile index f0cd9ead6..5f6338216 100644 --- a/win32/build/Makefile +++ b/win32/build/Makefile @@ -14,7 +14,7 @@ # | Author: Wez Furlong | # +----------------------------------------------------------------------+ # -# $Id: Makefile,v 1.35.2.1.2.6.2.14 2009/06/23 01:37:23 kalle Exp $ +# $Id: Makefile 289764 2009-10-19 19:05:58Z pajoye $ # This is the makefile template for the win32 build CC="$(CL)" @@ -128,7 +128,7 @@ build-dist: $(BUILD_DIR)\deplister.exe -del /f /q $(BUILD_DIR)\php-$(PHP_VERSION_STRING)$(PHP_ZTS_ARCHIVE_POSTFIX)-Win32-$(PHP_COMPILER_SHORT)-$(PHP_ARCHITECTURE).zip -del /f /q $(BUILD_DIR)\php-debug-pack-$(PHP_VERSION_STRING)$(PHP_ZTS_ARCHIVE_POSTFIX)-Win32-$(PHP_COMPILER_SHORT)-$(PHP_ARCHITECTURE).zip -del /f /q $(BUILD_DIR)\pecl-$(PHP_VERSION_STRING)$(PHP_ZTS_ARCHIVE_POSTFIX)-Win32-$(PHP_COMPILER_SHORT)-$(PHP_ARCHITECTURE).zip - $(BUILD_DIR)\php.exe -d date.timezone=UTC -n -dphar.readonly=0 win32/build/mkdist.php "$(BUILD_DIR)" "$(PHPDLL)" "$(SAPI_TARGETS)" "$(EXT_TARGETS) $(PHP_EXTRA_DIST_FILES)" "$(PECL_TARGETS) $(PECL_EXTRA_DIST_FILES)" "$(SNAPSHOT_TEMPLATE)" + $(BUILD_DIR)\php.exe -d date.timezone=UTC -n -dphar.readonly=0 win32/build/mkdist.php "$(BUILD_DIR)" "$(PHP_BUILD)" "$(PHPDLL)" "$(SAPI_TARGETS)" "$(EXT_TARGETS) $(PHP_EXTRA_DIST_FILES)" "$(PECL_TARGETS) $(PECL_EXTRA_DIST_FILES)" "$(SNAPSHOT_TEMPLATE)" cd $(BUILD_DIR)\php-$(PHP_VERSION_STRING) -$(ZIP) -9 -q -r ..\php-$(PHP_VERSION_STRING)$(PHP_ZTS_ARCHIVE_POSTFIX)-Win32-$(PHP_COMPILER_SHORT)-$(PHP_ARCHITECTURE).zip . cd ..\.. diff --git a/win32/build/block.template.dsw b/win32/build/block.template.dsw index 06f356b44..2f2682dc7 100644 --- a/win32/build/block.template.dsw +++ b/win32/build/block.template.dsw @@ -1,15 +1,15 @@ - -Project: "EXTNAME"=..\ADDRESS - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name php5ts - End Project Dependency -}}} - -############################################################################### + +Project: "EXTNAME"=..\ADDRESS - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name php5ts + End Project Dependency +}}} + +############################################################################### diff --git a/win32/build/buildconf.js b/win32/build/buildconf.js index 6efe3d708..d26b4c740 100644 --- a/win32/build/buildconf.js +++ b/win32/build/buildconf.js @@ -1,280 +1,273 @@ -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2008 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.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: Wez Furlong | - +----------------------------------------------------------------------+ -*/ - -/* $Id: buildconf.js,v 1.13.2.2.2.1.2.5 2009/01/02 12:18:21 kalle Exp $ */ -// This generates a configure script for win32 build - -WScript.StdOut.WriteLine("Rebuilding configure.js"); -var FSO = WScript.CreateObject("Scripting.FileSystemObject"); -var C = FSO.CreateTextFile("configure.js", true); -var B = FSO.CreateTextFile("configure.bat", true); -var DSP = false; - -var modules = ""; -var MODULES = WScript.CreateObject("Scripting.Dictionary"); -var module_dirs = new Array(); - -function file_get_contents(filename) -{ - var F = FSO.OpenTextFile(filename, 1); - var t = F.ReadAll(); - F.Close(); - return t; -} - -function Module_Item(module_name, config_path, dir_line, deps, content) -{ - this.module_name = module_name; - this.config_path = config_path; - this.dir_line = dir_line; - this.deps = deps; - this.content = content; -} - -function find_config_w32(dirname) -{ - if (!FSO.FolderExists(dirname)) { - return; - } - - var f = FSO.GetFolder(dirname); - var fc = new Enumerator(f.SubFolders); - var c, i, ok, n; - var item = null; - var re_dep_line = new RegExp("ADD_EXTENSION_DEP\\([^,]*\\s*,\\s*['\"]([^'\"]+)['\"].*\\)", "gm"); - - for (; !fc.atEnd(); fc.moveNext()) - { - ok = true; - /* check if we already picked up a module with the same dirname; - * if we have, don't include it here */ - n = FSO.GetFileName(fc.item()); - - if (n == 'CVS' || n == 'tests') - continue; - - // WScript.StdOut.WriteLine("checking " + dirname + "/" + n); - if (MODULES.Exists(n)) { - WScript.StdOut.WriteLine("Skipping " + dirname + "/" + n + " -- already have a module with that name"); - continue; - } - - c = FSO.BuildPath(fc.item(), "config.w32"); - if (FSO.FileExists(c)) { -// WScript.StdOut.WriteLine(c); - - var dir_line = "configure_module_dirname = condense_path(FSO.GetParentFolderName('" - + c.replace(new RegExp('(["\\\\])', "g"), '\\$1') + "'));\r\n"; - var contents = file_get_contents(c); - var deps = new Array(); - - // parse out any deps from the file - var calls = contents.match(re_dep_line); - if (calls != null) { - for (i = 0; i < calls.length; i++) { - // now we need the extension name out of this thing - if (calls[i].match(re_dep_line)) { -// WScript.StdOut.WriteLine("n depends on " + RegExp.$1); - deps[deps.length] = RegExp.$1; - - } - } - } - - item = new Module_Item(n, c, dir_line, deps, contents); - MODULES.Add(n, item); - } - } -} - -// Emit core modules array. This is used by a snapshot -// build to override a default "yes" value so that external -// modules don't break the build by becoming statically compiled -function emit_core_module_list() -{ - var module_names = (new VBArray(MODULES.Keys())).toArray(); - var i, mod_name, j; - var item; - var output = ""; - - C.WriteLine("core_module_list = new Array("); - - // first, look for modules with empty deps; emit those first - for (i in module_names) { - mod_name = module_names[i]; - C.WriteLine("\"" + mod_name.replace(/_/g, "-") + "\","); - } - - C.WriteLine("false // dummy"); - - C.WriteLine(");"); -} - - -function emit_module(item) -{ - return item.dir_line + item.content; -} - -function emit_dep_modules(module_names) -{ - var i, mod_name, j; - var output = ""; - var item = null; - - for (i in module_names) { - mod_name = module_names[i]; - - if (MODULES.Exists(mod_name)) { - item = MODULES.Item(mod_name); - MODULES.Remove(mod_name); - if (item.deps.length) { - output += emit_dep_modules(item.deps); - } - output += emit_module(item); - } - } - - return output; -} - -function gen_modules() -{ - var module_names = (new VBArray(MODULES.Keys())).toArray(); - var i, mod_name, j; - var item; - var output = ""; - - // first, look for modules with empty deps; emit those first - for (i in module_names) { - mod_name = module_names[i]; - item = MODULES.Item(mod_name); - if (item.deps.length == 0) { - MODULES.Remove(mod_name); - output += emit_module(item); - } - } - - // now we are left with modules that have dependencies on other modules - module_names = (new VBArray(MODULES.Keys())).toArray(); - output += emit_dep_modules(module_names); - - return output; -} - -if (FSO.FileExists("ZendEngine2\\OBJECTS2_HOWTO")) { - if (FSO.FolderExists("Zend")) { - FSO.MoveFolder("Zend", "ZendEngine1"); - } - FSO.MoveFolder("ZendEngine2", "Zend"); -} - -// Process buildconf arguments -function buildconf_process_args() -{ - args = WScript.Arguments; - - for (i = 0; i < args.length; i++) { - arg = args(i); - // If it is --foo=bar, split on the equals sign - arg = arg.split("=", 2); - argname = arg[0]; - if (arg.length > 1) { - argval = arg[1]; - } else { - argval = null; - } - - if (argname == '--add-modules-dir' && argval != null) { - WScript.StdOut.WriteLine("Adding " + argval + " to the module search path"); - module_dirs[module_dirs.length] = argval; - } - - if (argname == '--add-project-files') { - WScript.StdOut.WriteLine("Adding dsp templates into the mix"); - DSP = true; - } - } -} - -buildconf_process_args(); - -// Write the head of the configure script -C.WriteLine("/* This file automatically generated from win32/build/confutils.js */"); -C.Write(file_get_contents("win32/build/confutils.js")); - -// If project files were requested, pull in the code to generate them -if (DSP == true) { - C.WriteLine('PHP_DSP="yes"'); - C.WriteBlankLines(1); - C.Write(file_get_contents("win32/build/projectgen.js")); -} else { - C.WriteLine('PHP_DSP="no"'); - C.WriteBlankLines(1); -} - -// Pull in code from sapi and extensions -modules = file_get_contents("win32/build/config.w32"); - -// Pick up confs from TSRM and Zend if present -find_config_w32("."); -find_config_w32("sapi"); -find_config_w32("ext"); -emit_core_module_list(); - -// If we have not specified any module dirs let's add some defaults -if (module_dirs.length == 0) { - find_config_w32("pecl"); - find_config_w32("..\\pecl"); - find_config_w32("pecl\\rpc"); - find_config_w32("..\\pecl\\rpc"); -} else { - for (i = 0; i < module_dirs.length; i++) { - find_config_w32(module_dirs[i]); - } -} - -// Now generate contents of module based on MODULES, chasing dependencies -// to ensure that dependent modules are emitted first -modules += gen_modules(); - -// Look for ARG_ENABLE or ARG_WITH calls -re = new RegExp("(ARG_(ENABLE|WITH)\([^;]+\);)", "gm"); -calls = modules.match(re); -for (i = 0; i < calls.length; i++) { - item = calls[i]; - C.WriteLine("try {"); - C.WriteLine(item); - C.WriteLine("} catch (e) {"); - C.WriteLine('\tSTDOUT.WriteLine("problem: " + e);'); - C.WriteLine("}"); -} - -C.WriteBlankLines(1); -C.WriteLine("conf_process_args();"); -C.WriteBlankLines(1); - -// Comment out the calls from their original positions -modules = modules.replace(re, "/* $1 */"); -C.Write(modules); - -C.WriteBlankLines(1); -C.Write(file_get_contents("win32/build/configure.tail")); - -B.WriteLine("@echo off"); -B.WriteLine("cscript /nologo configure.js %*"); +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2008 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.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: Wez Furlong | + +----------------------------------------------------------------------+ +*/ + +/* $Id: buildconf.js,v 1.13.2.2.2.1.2.5 2009-01-02 12:18:21 kalle Exp $ */ +// This generates a configure script for win32 build + +WScript.StdOut.WriteLine("Rebuilding configure.js"); +var FSO = WScript.CreateObject("Scripting.FileSystemObject"); +var C = FSO.CreateTextFile("configure.js", true); +var B = FSO.CreateTextFile("configure.bat", true); +var DSP = false; + +var modules = ""; +var MODULES = WScript.CreateObject("Scripting.Dictionary"); +var module_dirs = new Array(); + +function file_get_contents(filename) +{ + var F = FSO.OpenTextFile(filename, 1); + var t = F.ReadAll(); + F.Close(); + return t; +} + +function Module_Item(module_name, config_path, dir_line, deps, content) +{ + this.module_name = module_name; + this.config_path = config_path; + this.dir_line = dir_line; + this.deps = deps; + this.content = content; +} + +function find_config_w32(dirname) +{ + if (!FSO.FolderExists(dirname)) { + return; + } + + var f = FSO.GetFolder(dirname); + var fc = new Enumerator(f.SubFolders); + var c, i, ok, n; + var item = null; + var re_dep_line = new RegExp("ADD_EXTENSION_DEP\\([^,]*\\s*,\\s*['\"]([^'\"]+)['\"].*\\)", "gm"); + + for (; !fc.atEnd(); fc.moveNext()) + { + ok = true; + /* check if we already picked up a module with the same dirname; + * if we have, don't include it here */ + n = FSO.GetFileName(fc.item()); + + if (n == '.svn' || n == 'tests') + continue; + + // WScript.StdOut.WriteLine("checking " + dirname + "/" + n); + if (MODULES.Exists(n)) { + WScript.StdOut.WriteLine("Skipping " + dirname + "/" + n + " -- already have a module with that name"); + continue; + } + + c = FSO.BuildPath(fc.item(), "config.w32"); + if (FSO.FileExists(c)) { +// WScript.StdOut.WriteLine(c); + + var dir_line = "configure_module_dirname = condense_path(FSO.GetParentFolderName('" + + c.replace(new RegExp('(["\\\\])', "g"), '\\$1') + "'));\r\n"; + var contents = file_get_contents(c); + var deps = new Array(); + + // parse out any deps from the file + var calls = contents.match(re_dep_line); + if (calls != null) { + for (i = 0; i < calls.length; i++) { + // now we need the extension name out of this thing + if (calls[i].match(re_dep_line)) { +// WScript.StdOut.WriteLine("n depends on " + RegExp.$1); + deps[deps.length] = RegExp.$1; + + } + } + } + + item = new Module_Item(n, c, dir_line, deps, contents); + MODULES.Add(n, item); + } + } +} + +// Emit core modules array. This is used by a snapshot +// build to override a default "yes" value so that external +// modules don't break the build by becoming statically compiled +function emit_core_module_list() +{ + var module_names = (new VBArray(MODULES.Keys())).toArray(); + var i, mod_name, j; + var item; + var output = ""; + + C.WriteLine("core_module_list = new Array("); + + // first, look for modules with empty deps; emit those first + for (i in module_names) { + mod_name = module_names[i]; + C.WriteLine("\"" + mod_name.replace(/_/g, "-") + "\","); + } + + C.WriteLine("false // dummy"); + + C.WriteLine(");"); +} + + +function emit_module(item) +{ + return item.dir_line + item.content; +} + +function emit_dep_modules(module_names) +{ + var i, mod_name, j; + var output = ""; + var item = null; + + for (i in module_names) { + mod_name = module_names[i]; + + if (MODULES.Exists(mod_name)) { + item = MODULES.Item(mod_name); + MODULES.Remove(mod_name); + if (item.deps.length) { + output += emit_dep_modules(item.deps); + } + output += emit_module(item); + } + } + + return output; +} + +function gen_modules() +{ + var module_names = (new VBArray(MODULES.Keys())).toArray(); + var i, mod_name, j; + var item; + var output = ""; + + // first, look for modules with empty deps; emit those first + for (i in module_names) { + mod_name = module_names[i]; + item = MODULES.Item(mod_name); + if (item.deps.length == 0) { + MODULES.Remove(mod_name); + output += emit_module(item); + } + } + + // now we are left with modules that have dependencies on other modules + module_names = (new VBArray(MODULES.Keys())).toArray(); + output += emit_dep_modules(module_names); + + return output; +} + +// Process buildconf arguments +function buildconf_process_args() +{ + args = WScript.Arguments; + + for (i = 0; i < args.length; i++) { + arg = args(i); + // If it is --foo=bar, split on the equals sign + arg = arg.split("=", 2); + argname = arg[0]; + if (arg.length > 1) { + argval = arg[1]; + } else { + argval = null; + } + + if (argname == '--add-modules-dir' && argval != null) { + WScript.StdOut.WriteLine("Adding " + argval + " to the module search path"); + module_dirs[module_dirs.length] = argval; + } + + if (argname == '--add-project-files') { + WScript.StdOut.WriteLine("Adding dsp templates into the mix"); + DSP = true; + } + } +} + +buildconf_process_args(); + +// Write the head of the configure script +C.WriteLine("/* This file automatically generated from win32/build/confutils.js */"); +C.Write(file_get_contents("win32/build/confutils.js")); + +// If project files were requested, pull in the code to generate them +if (DSP == true) { + C.WriteLine('PHP_DSP="yes"'); + C.WriteBlankLines(1); + C.Write(file_get_contents("win32/build/projectgen.js")); +} else { + C.WriteLine('PHP_DSP="no"'); + C.WriteBlankLines(1); +} + +// Pull in code from sapi and extensions +modules = file_get_contents("win32/build/config.w32"); + +// Pick up confs from TSRM and Zend if present +find_config_w32("."); +find_config_w32("sapi"); +find_config_w32("ext"); +emit_core_module_list(); + +// If we have not specified any module dirs let's add some defaults +if (module_dirs.length == 0) { + find_config_w32("pecl"); + find_config_w32("..\\pecl"); + find_config_w32("pecl\\rpc"); + find_config_w32("..\\pecl\\rpc"); +} else { + for (i = 0; i < module_dirs.length; i++) { + find_config_w32(module_dirs[i]); + } +} + +// Now generate contents of module based on MODULES, chasing dependencies +// to ensure that dependent modules are emitted first +modules += gen_modules(); + +// Look for ARG_ENABLE or ARG_WITH calls +re = new RegExp("(ARG_(ENABLE|WITH)\([^;]+\);)", "gm"); +calls = modules.match(re); +for (i = 0; i < calls.length; i++) { + item = calls[i]; + C.WriteLine("try {"); + C.WriteLine(item); + C.WriteLine("} catch (e) {"); + C.WriteLine('\tSTDOUT.WriteLine("problem: " + e);'); + C.WriteLine("}"); +} + +C.WriteBlankLines(1); +C.WriteLine("conf_process_args();"); +C.WriteBlankLines(1); + +// Comment out the calls from their original positions +modules = modules.replace(re, "/* $1 */"); +C.Write(modules); + +C.WriteBlankLines(1); +C.Write(file_get_contents("win32/build/configure.tail")); + +B.WriteLine("@echo off"); +B.WriteLine("cscript /nologo configure.js %*"); diff --git a/win32/build/config.w32 b/win32/build/config.w32 index 72b4c0447..67b9fe6fd 100644 --- a/win32/build/config.w32 +++ b/win32/build/config.w32 @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: config.w32,v 1.40.2.8.2.10.2.49 2009/06/04 18:20:45 mattwil Exp $ +// $Id: config.w32 289764 2009-10-19 19:05:58Z pajoye $ // "Master" config file; think of it as a configure.in // equivalent. @@ -82,6 +82,7 @@ if (VCVERS > 1200) { // stick objects somewhere outside of the source tree ARG_ENABLE('object-out-dir', 'Alternate location for binary objects during build', ''); if (PHP_OBJECT_OUT_DIR.length) { + PHP_OBJECT_OUT_DIR = FSO.GetAbsolutePathName(PHP_OBJECT_OUT_DIR); if (!FSO.FolderExists(PHP_OBJECT_OUT_DIR)) { ERROR('you chosen output directory ' + PHP_OBJECT_OUT_DIR + ' does not exist'); } @@ -250,6 +251,7 @@ if (PHP_PHP_BUILD == 'no') { } } } + PHP_PHP_BUILD = FSO.GetAbsolutePathName(PHP_PHP_BUILD); } DEFINE("PHP_BUILD", PHP_PHP_BUILD); diff --git a/win32/build/config.w32.h.in b/win32/build/config.w32.h.in index f3459bdac..e585e0ab5 100644 --- a/win32/build/config.w32.h.in +++ b/win32/build/config.w32.h.in @@ -1,6 +1,6 @@ /* Build Configuration Template for Win32. - $Id: config.w32.h.in,v 1.7.2.4.2.3.2.14 2009/06/23 06:56:45 kalle Exp $ + $Id: config.w32.h.in 282624 2009-06-23 06:56:45Z kalle $ */ /* Define the minimum supported version */ diff --git a/win32/build/configure.tail b/win32/build/configure.tail index ad81c3349..c904bf44e 100644 --- a/win32/build/configure.tail +++ b/win32/build/configure.tail @@ -1,5 +1,5 @@ // vim:ft=javascript -// $Id: configure.tail,v 1.1.8.1 2008/12/25 00:09:49 pajoye Exp $ +// $Id: configure.tail 271838 2008-12-25 00:09:49Z pajoye $ // tail end of configure if (sapi_enabled.length < 1) { diff --git a/win32/build/confutils.js b/win32/build/confutils.js index 63bfd85bf..28b5e0d86 100644 --- a/win32/build/confutils.js +++ b/win32/build/confutils.js @@ -1,1861 +1,1861 @@ -// Utils for configure script -/* - +----------------------------------------------------------------------+ - | PHP Version 5 | - +----------------------------------------------------------------------+ - | Copyright (c) 1997-2008 The PHP Group | - +----------------------------------------------------------------------+ - | This source file is subject to version 3.01 of the PHP license, | - | that is bundled with this package in the file LICENSE, and is | - | available through the world-wide-web at the following url: | - | http://www.php.net/license/3_01.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: Wez Furlong | - +----------------------------------------------------------------------+ -*/ - -// $Id: confutils.js,v 1.60.2.1.2.8.2.33 2009/05/29 07:43:07 kalle Exp $ - -var STDOUT = WScript.StdOut; -var STDERR = WScript.StdErr; -var WshShell = WScript.CreateObject("WScript.Shell"); -var FSO = WScript.CreateObject("Scripting.FileSystemObject"); -var MFO = null; -var SYSTEM_DRIVE = WshShell.Environment("Process").Item("SystemDrive"); -var PROGRAM_FILES = WshShell.Environment("Process").Item("ProgramFiles"); -var DSP_FLAGS = new Array(); - -/* Store the enabled extensions (summary + QA check) */ -var extensions_enabled = new Array(); - -/* Store the SAPI enabled (summary + QA check) */ -var sapi_enabled = new Array(); - -/* Mapping CL version > human readable name */ -var VC_VERSIONS = new Array(); -VC_VERSIONS[1200] = 'MSVC6 (Visual C++ 6.0)'; -VC_VERSIONS[1300] = 'MSVC7 (Visual C++ 2002)'; -VC_VERSIONS[1310] = 'MSVC7.1 (Visual C++ 2003)'; -VC_VERSIONS[1400] = 'MSVC8 (Visual C++ 2005)'; -VC_VERSIONS[1500] = 'MSVC9 (Visual C++ 2008)'; - -var VC_VERSIONS_SHORT = new Array(); -VC_VERSIONS_SHORT[1200] = 'VC6'; -VC_VERSIONS_SHORT[1300] = 'VC7'; -VC_VERSIONS_SHORT[1310] = 'VC7.1'; -VC_VERSIONS_SHORT[1400] = 'VC8'; -VC_VERSIONS_SHORT[1500] = 'VC9'; - -if (PROGRAM_FILES == null) { - PROGRAM_FILES = "C:\\Program Files"; -} - -if (!FSO.FileExists("README.CVS-RULES")) { - STDERR.WriteLine("Must be run from the root of the php source"); - WScript.Quit(10); -} - -var CWD = WshShell.CurrentDirectory; - -if (typeof(CWD) == "undefined") { - CWD = FSO.GetParentFolderName(FSO.GetAbsolutePathName("README.CVS-RULES")); -} - -/* defaults; we pick up the precise versions from configure.in */ -var PHP_VERSION = 5; -var PHP_MINOR_VERSION = 0; -var PHP_RELEASE_VERSION = 0; -var PHP_EXTRA_VERSION = ""; -var PHP_VERSION_STRING = "5.0.0"; - -function get_version_numbers() -{ - var cin = file_get_contents("configure.in"); - - if (cin.match(new RegExp("PHP_MAJOR_VERSION=(\\d+)"))) { - PHP_VERSION = RegExp.$1; - } - if (cin.match(new RegExp("PHP_MINOR_VERSION=(\\d+)"))) { - PHP_MINOR_VERSION = RegExp.$1; - } - if (cin.match(new RegExp("PHP_RELEASE_VERSION=(\\d+)"))) { - PHP_RELEASE_VERSION = RegExp.$1; - } - PHP_VERSION_STRING = PHP_VERSION + "." + PHP_MINOR_VERSION + "." + PHP_RELEASE_VERSION; - - if (cin.match(new RegExp("PHP_EXTRA_VERSION=\"([^\"]+)\""))) { - PHP_EXTRA_VERSION = RegExp.$1; - if (PHP_EXTRA_VERSION.length) { - PHP_VERSION_STRING += PHP_EXTRA_VERSION; - } - } - DEFINE('PHP_VERSION_STRING', PHP_VERSION_STRING); -} - -configure_args = new Array(); -configure_subst = WScript.CreateObject("Scripting.Dictionary"); - -configure_hdr = WScript.CreateObject("Scripting.Dictionary"); -build_dirs = new Array(); - -extension_include_code = ""; -extension_module_ptrs = ""; - -get_version_numbers(); - -/* execute a command and return the output as a string */ -function execute(command_line) -{ - var e = WshShell.Exec(command_line); - var ret = ""; - - ret = e.StdOut.ReadAll(); - -//STDOUT.WriteLine("command " + command_line); -//STDOUT.WriteLine(ret); - - return ret; -} - -function probe_binary(EXE, what) -{ - // tricky escapes to get stderr redirection to work - var command = 'cmd /c ""' + EXE; - if (what == "version") { - command = command + '" -v"'; - } - var version = execute(command + '" 2>&1"'); - - if (what == "64") { - if (version.match(/x64/)) { - return 1; - } - } else { - if (version.match(/(\d+\.\d+(\.\d+)?(\.\d+)?)/)) { - return RegExp.$1; - } - } - return 0; -} - -function condense_path(path) -{ - path = FSO.GetAbsolutePathName(path); - - if (path.substr(0, CWD.length).toLowerCase() - == CWD.toLowerCase() && - (path.charCodeAt(CWD.length) == 92 || path.charCodeAt(CWD.length) == 47)) { - return path.substr(CWD.length + 1); - } - - var a = CWD.split("\\"); - var b = path.split("\\"); - var i, j; - - for (i = 0; i < b.length; i++) { - if (a[i].toLowerCase() == b[i].toLowerCase()) - continue; - if (i > 0) { - /* first difference found */ - path = ""; - for (j = 0; j < a.length - i; j++) { - path += "..\\"; - } - for (j = i; j < b.length; j++) { - path += b[j]; - if (j < b.length - 1) - path += "\\"; - } - return path; - } - /* on a different drive */ - break; - } - - return path; -} - -function ConfigureArg(type, optname, helptext, defval) -{ - var opptype = type == "enable" ? "disable" : "without"; - - if (defval == "yes" || defval == "yes,shared") { - this.arg = "--" + opptype + "-" + optname; - this.imparg = "--" + type + "-" + optname; - } else { - this.arg = "--" + type + "-" + optname; - this.imparg = "--" + opptype + "-" + optname; - } - - this.optname = optname; - this.helptext = helptext; - this.defval = defval; - this.symval = optname.toUpperCase().replace(new RegExp("-", "g"), "_"); - this.seen = false; - this.argval = defval; -} - -function ARG_WITH(optname, helptext, defval) -{ - configure_args[configure_args.length] = new ConfigureArg("with", optname, helptext, defval); -} - -function ARG_ENABLE(optname, helptext, defval) -{ - configure_args[configure_args.length] = new ConfigureArg("enable", optname, helptext, defval); -} - -function analyze_arg(argval) -{ - var ret = new Array(); - var shared = false; - - if (argval == "shared") { - shared = true; - argval = "yes"; - } else if (argval == null) { - /* nothing */ - } else if (arg_match = argval.match(new RegExp("^shared,(.*)"))) { - shared = true; - argval = arg_match[1]; - } else if (arg_match = argval.match(new RegExp("^(.*),shared$"))) { - shared = true; - argval = arg_match[1]; - } - - ret[0] = shared; - ret[1] = argval; - return ret; -} - -function word_wrap_and_indent(indent, text, line_suffix, indent_char) -{ - if (text == null) { - return ""; - } - - var words = text.split(new RegExp("\\s+", "g")); - var i = 0; - var ret_text = ""; - var this_line = ""; - var t; - var space = ""; - var lines = 0; - - if (line_suffix == null) { - line_suffix = ""; - } - - if (indent_char == null) { - indent_char = " "; - } - - for (i = 0; i < indent; i++) { - space += indent_char; - } - - for (i = 0; i < words.length; i++) { - if (this_line.length) { - t = this_line + " " + words[i]; - } else { - t = words[i]; - } - - if (t.length + indent > 78) { - if (lines++) { - ret_text += space; - } - ret_text += this_line + line_suffix + "\r\n"; - this_line = ""; - } - - if (this_line.length) { - this_line += " " + words[i]; - } else { - this_line = words[i]; - } - } - - if (this_line.length) { - if (lines) - ret_text += space; - ret_text += this_line; - } - - return ret_text; -} - -function conf_process_args() -{ - var i, j; - var configure_help_mode = false; - var analyzed = false; - var nice = "cscript /nologo configure.js "; - var disable_all = false; - - args = WScript.Arguments; - for (i = 0; i < args.length; i++) { - arg = args(i); - nice += ' "' + arg + '"'; - if (arg == "--help") { - configure_help_mode = true; - break; - } - if (arg == "--disable-all") { - disable_all = true; - continue; - } - - // If it is --foo=bar, split on the equals sign - arg = arg.split("=", 2); - argname = arg[0]; - if (arg.length > 1) { - argval = arg[1]; - } else { - argval = null; - } - - // Find the arg - found = false; - for (j = 0; j < configure_args.length; j++) { - if (argname == configure_args[j].imparg || argname == configure_args[j].arg) { - found = true; - - arg = configure_args[j]; - arg.seen = true; - - analyzed = analyze_arg(argval); - shared = analyzed[0]; - argval = analyzed[1]; - - if (argname == arg.imparg) { - /* we matched the implicit, or default arg */ - if (argval == null) { - argval = arg.defval; - } - } else { - /* we matched the non-default arg */ - if (argval == null) { - argval = arg.defval == "no" ? "yes" : "no"; - } - } - - arg.argval = argval; - eval("PHP_" + arg.symval + " = argval;"); - eval("PHP_" + arg.symval + "_SHARED = shared;"); - break; - } - } - if (!found) { - STDERR.WriteLine("Unknown option " + argname + "; please try configure.js --help for a list of valid options"); - WScript.Quit(2); - } - } - - if (configure_help_mode) { - STDOUT.WriteLine(word_wrap_and_indent(0, -"Options that enable extensions and SAPI will accept \ -'yes' or 'no' as a parameter. They also accept 'shared' \ -as a synonym for 'yes' and request a shared build of that \ -module. Not all modules can be built as shared modules; \ -configure will display [shared] after the module name if \ -can be built that way. \ -" - )); - STDOUT.WriteBlankLines(1); - - // Measure width to pretty-print the output - max_width = 0; - for (i = 0; i < configure_args.length; i++) { - arg = configure_args[i]; - if (arg.arg.length > max_width) - max_width = arg.arg.length; - } - - for (i = 0; i < configure_args.length; i++) { - arg = configure_args[i]; - - n = max_width - arg.arg.length; - pad = " "; - for (j = 0; j < n; j++) { - pad += " "; - } - STDOUT.WriteLine(" " + arg.arg + pad + word_wrap_and_indent(max_width + 5, arg.helptext)); - } - WScript.Quit(1); - } - - var snapshot_build_exclusions = new Array( - 'debug', 'crt-debug', 'lzf-better-compression', - 'php-build', 'snapshot-template', 'ereg', - 'pcre-regex', 'fastcgi', 'force-cgi-redirect', - 'path-info-check', 'zts', 'ipv6', 'memory-limit', - 'zend-multibyte', 'fd-setsize', 'memory-manager', 't1lib' - ); - var force; - - // Now set any defaults we might have missed out earlier - for (i = 0; i < configure_args.length; i++) { - arg = configure_args[i]; - if (arg.seen) - continue; - analyzed = analyze_arg(arg.defval); - shared = analyzed[0]; - argval = analyzed[1]; - - // Don't trust a default "yes" answer for a non-core module - // in a snapshot build - if (PHP_SNAPSHOT_BUILD != "no" && argval == "yes" && !shared) { - - force = true; - for (j = 0; j < snapshot_build_exclusions.length; j++) { - if (snapshot_build_exclusions[j] == arg.optname) { - force = false; - break; - } - } - - if (force) { - /* now check if it is a core module */ - force = false; - for (j = 0; j < core_module_list.length; j++) { - if (core_module_list[j] == arg.optname) { - force = true; - break; - } - } - - if (!force) { - STDOUT.WriteLine("snapshot: forcing " + arg.arg + " shared"); - shared = true; - } - } - } - - if (PHP_SNAPSHOT_BUILD != "no" && argval == "no") { - force = true; - for (j = 0; j < snapshot_build_exclusions.length; j++) { - if (snapshot_build_exclusions[j] == arg.optname) { - force = false; - break; - } - } - if (force) { - STDOUT.WriteLine("snapshot: forcing " + arg.optname + " on"); - argval = "yes"; - shared = true; - } - } - - if (disable_all) { - force = true; - for (j = 0; j < snapshot_build_exclusions.length; j++) { - if (snapshot_build_exclusions[j] == arg.optname) { - force = false; - break; - } - } - if (force) { - if (arg.defval == '') { - argval = ''; - } else { - argval = "no"; - } - shared = false; - } - } - - eval("PHP_" + arg.symval + " = argval;"); - eval("PHP_" + arg.symval + "_SHARED = shared;"); - } - - MFO = FSO.CreateTextFile("Makefile.objects", true); - - STDOUT.WriteLine("Saving configure options to config.nice.bat"); - var nicefile = FSO.CreateTextFile("config.nice.bat", true); - nicefile.WriteLine(nice + " %*"); - nicefile.Close(); - - AC_DEFINE('CONFIGURE_COMMAND', nice, "Configure line"); -} - -function DEFINE(name, value) -{ - if (configure_subst.Exists(name)) { - configure_subst.Remove(name); - } - configure_subst.Add(name, value); -} - -// Searches a set of paths for a file; -// returns the dir in which the file was found, -// true if it was found in the default env path, -// or false if it was not found at all. -// env_name is the optional name of an env var -// specifying the default path to search -function search_paths(thing_to_find, explicit_path, env_name) -{ - var i, found = false, place = false, file, env; - - STDOUT.Write("Checking for " + thing_to_find + " ... "); - - thing_to_find = thing_to_find.replace(new RegExp("/", "g"), "\\"); - - if (explicit_path != null) { - if (typeof(explicit_path) == "string") { - explicit_path = explicit_path.split(";"); - } - - for (i = 0; i < explicit_path.length; i++) { - file = glob(explicit_path[i] + "\\" + thing_to_find); - if (file) { - found = true; - place = file[0]; - place = place.substr(0, place.length - thing_to_find.length - 1); - break; - } - } - } - - if (!found && env_name != null) { - env = WshShell.Environment("Process").Item(env_name); - env = env.split(";"); - for (i = 0; i < env.length; i++) { - file = glob(env[i] + "\\" + thing_to_find); - if (file) { - found = true; - place = true; - break; - } - } - } - - if (found && place == true) { - STDOUT.WriteLine(" "); - } else if (found) { - STDOUT.WriteLine(" " + place); - } else { - STDOUT.WriteLine(" "); - } - return place; -} - -function PATH_PROG(progname, additional_paths, symbol) -{ - var exe; - var place; - var cyg_path = PHP_CYGWIN + "\\bin;" + PHP_CYGWIN + "\\usr\\local\\bin"; - var php_build_bin_path = PHP_PHP_BUILD + "\\bin" - - exe = progname + ".exe"; - - if (additional_paths == null) { - additional_paths = cyg_path; - } else { - additional_paths += ";" + cyg_path; - } - - additional_paths = additional_paths + ";" + php_build_bin_path; - - place = search_paths(exe, additional_paths, "PATH"); - - if (place == true) { - place = exe; - } else if (place != false) { - place = place + "\\" + exe; - } - - if (place) { - if (symbol == null) { - symbol = progname.toUpperCase(); - } - DEFINE(symbol, place); - } - return place; -} - -function find_pattern_in_path(pattern, path) -{ - if (path == null) { - return false; - } - - var dirs = path.split(';'); - var i; - var items; - - for (i = 0; i < dirs.length; i++) { - items = glob(dirs[i] + "\\" + pattern); - if (items) { - return condense_path(items[0]); - } - } - return false; -} - -function CHECK_LIB(libnames, target, path_to_check, common_name) -{ - STDOUT.Write("Checking for library " + libnames + " ... "); - - if (common_name == null && target != null) { - common_name = target; - } - - if (path_to_check == null) { - path_to_check = ""; - } - - // if they specified a common name for the package that contains - // the library, tag some useful defaults on to the end of the - // path to be searched - if (common_name != null) { - path_to_check += ";" + PHP_PHP_BUILD + "\\" + common_name + "*"; - path_to_check += ";" + PHP_PHP_BUILD + "\\lib\\" + common_name + "*"; - path_to_check += ";..\\" + common_name + "*"; - } - - // Determine target for build flags - if (target == null) { - target = ""; - } else { - target = "_" + target.toUpperCase(); - } - - // Expand path to include general dirs - path_to_check += ";" + php_usual_lib_suspects; - - // It is common practice to put libs under one of these dir names - var subdirs = new Array(PHP_DEBUG == "yes" ? "Debug" : (PHP_DEBUG_PACK == "yes"?"Release_Dbg":"Release"), "lib", "libs", "libexec"); - - // libnames can be ; separated list of accepted library names - libnames = libnames.split(';'); - - // for debug builds, lib may have _debug appended, we want that first - if (PHP_DEBUG == "yes") { - var length = libnames.length; - for (var i = 0; i < length; i++) { - var name = new String(libnames[i]); - rExp = /.lib$/i; - name = name.replace(rExp,"_debug.lib"); - libnames.unshift(name); - } - } - - var i, j, k, libname; - var location = false; - var path = path_to_check.split(';'); - - for (i = 0; i < libnames.length; i++) { - libname = libnames[i]; - - for (k = 0; k < path.length; k++) { - location = glob(path[k] + "\\" + libname); - if (location) { - location = location[0]; - break; - } - for (j = 0; j < subdirs.length; j++) { - location = glob(path[k] + "\\" + subdirs[j] + "\\" + libname); - if (location) { - location = location[0]; - break; - } - } - if (location) - break; - } - - if (location) { - location = condense_path(location); - var libdir = FSO.GetParentFolderName(location); - libname = FSO.GetFileName(location); - ADD_FLAG("LDFLAGS" + target, '/libpath:"' + libdir + '" '); - ADD_FLAG("LIBS" + target, libname); - - STDOUT.WriteLine(location); - - return location; - } - - // Check in their standard lib path - location = find_pattern_in_path(libname, WshShell.Environment("Process").Item("LIB")); - - if (location) { - location = condense_path(location); - libname = FSO.GetFileName(location); - ADD_FLAG("LIBS" + target, libname); - - STDOUT.WriteLine(" " + libname); - return location; - } - - // Check in their general extra libs path - location = find_pattern_in_path(libname, PHP_EXTRA_LIBS); - if (location) { - location = condense_path(location); - libname = FSO.GetFileName(location); - ADD_FLAG("LIBS" + target, libname); - STDOUT.WriteLine(""); - return location; - } - } - - STDOUT.WriteLine(""); - - return false; -} - -function OLD_CHECK_LIB(libnames, target, path_to_check) -{ - if (target == null) { - target = ""; - } else { - target = "_" + target.toUpperCase(); - } - - if (path_to_check == null) { - path_to_check = php_usual_lib_suspects; - } else { - path_to_check += ";" + php_usual_lib_suspects; - } - var have = 0; - var p; - var i; - var libname; - - var subdir = PHP_DEBUG == "yes" ? "Debug" : (PHP_DEBUG_PACK == "yes"?"Release_Dbg":"Release"); - - libnames = libnames.split(';'); - for (i = 0; i < libnames.length; i++) { - libname = libnames[i]; - p = search_paths(libname, path_to_check, "LIB"); - - if (!p) { - p = search_paths(subdir + "\\" + libname, path_to_check, "LIB"); - if (p) { - p += "\\" + subdir; - } - } - - if (typeof(p) == "string") { - ADD_FLAG("LDFLAGS" + target, '/libpath:"' + p + '" '); - ADD_FLAG("LIBS" + target, libname); - have = 1; - } else if (p == true) { - ADD_FLAG("LIBS" + target, libname); - have = 1; - } else { - /* not found in the defaults or the explicit paths, - * so check the general extra libs; if we find - * it here, no need to add another /libpath: for it as we - * already have it covered, but we need to add the lib - * to LIBS_XXX */ - if (false != search_paths(libname, PHP_EXTRA_LIBS, null)) { - ADD_FLAG("LIBS" + target, libname); - have = 1; - } - } - - if (have) { - break; - } - } - -// AC_DEFINE("HAVE_" + header_name.toUpperCase().replace(new RegExp("/\\\\-\.", "g"), "_"), have); - - return have; - -} - -function CHECK_FUNC_IN_HEADER(header_name, func_name, path_to_check, add_to_flag) -{ - var c = false; - var sym; - - STDOUT.Write("Checking for " + func_name + " in " + header_name + " ... "); - - c = GREP_HEADER(header_name, func_name, path_to_check); - - sym = func_name.toUpperCase(); - sym = sym.replace(new RegExp("[\\\\/\.-]", "g"), "_"); - - if (typeof(add_to_flag) == "undefined") { - AC_DEFINE("HAVE_" + sym, c ? 1 : 0); - } else { - ADD_FLAG(add_to_flag, "/DHAVE_" + sym + "=" + (c ? "1" : "0")); - } - - if (c) { - STDOUT.WriteLine("OK"); - return c; - } - STDOUT.WriteLine("No"); - return false; -} - -function GREP_HEADER(header_name, regex, path_to_check) -{ - var c = false; - - if (FSO.FileExists(path_to_check + "\\" + header_name)) { - c = file_get_contents(path_to_check + "\\" + header_name); - } - - if (!c) { - /* look in the include path */ - - var p = search_paths(header_name, path_to_check, "INCLUDE"); - if (typeof(p) == "string") { - c = file_get_contents(p); - } else if (p == false) { - p = search_paths(header_name, PHP_EXTRA_INCLUDES, null); - if (typeof(p) == "string") { - c = file_get_contents(p); - } - } - if (!c) { - return false; - } - } - - if (typeof(regex) == "string") { - regex = new RegExp(regex); - } - - if (c.match(regex)) { - /* caller can now use RegExp.$1 etc. to get at patterns */ - return true; - } - return false; -} - -function CHECK_HEADER_ADD_INCLUDE(header_name, flag_name, path_to_check, use_env, add_dir_part, add_to_flag_only) -{ - var dir_part_to_add = ""; - - if (use_env == null) { - use_env = true; - } - - // if true, add the dir part of the header_name to the include path - if (add_dir_part == null) { - add_dir_part = false; - } else if (add_dir_part) { - var basename = FSO.GetFileName(header_name); - dir_part_to_add = "\\" + header_name.substr(0, header_name.length - basename.length - 1); - } - - if (path_to_check == null) { - path_to_check = php_usual_include_suspects; - } else { - path_to_check += ";" + php_usual_include_suspects; - } - - var p = search_paths(header_name, path_to_check, use_env ? "INCLUDE" : null); - var have = 0; - var sym; - - if (typeof(p) == "string") { - ADD_FLAG(flag_name, '/I "' + p + dir_part_to_add + '" '); - } else if (p == false) { - /* not found in the defaults or the explicit paths, - * so check the general extra includes; if we find - * it here, no need to add another /I for it as we - * already have it covered, unless we are adding - * the dir part.... */ - p = search_paths(header_name, PHP_EXTRA_INCLUDES, null); - if (typeof(p) == "string" && add_dir_part) { - ADD_FLAG(flag_name, '/I "' + p + dir_part_to_add + '" '); - } - } - have = p ? 1 : 0 - - sym = header_name.toUpperCase(); - sym = sym.replace(new RegExp("[\\\\/\.-]", "g"), "_"); - - if (typeof(add_to_flag_only) == "undefined" && - flag_name.match(new RegExp("^CFLAGS_(.*)$"))) { - add_to_flag_only = true; - } - - if (typeof(add_to_flag_only) != "undefined") { - ADD_FLAG(flag_name, "/DHAVE_" + sym + "=" + have); - } else { - AC_DEFINE("HAVE_" + sym, have, "have the " + header_name + " header file"); - } - - return p; -} - -/* emits rule to generate version info for a SAPI - * or extension. Returns the name of the .res file - * that will be generated */ -function generate_version_info_resource(makefiletarget, basename, creditspath, sapi) -{ - var resname = makefiletarget + ".res"; - var res_desc = makefiletarget; - var res_prod_name = "PHP " + makefiletarget; - var credits; - var thanks = ""; - var logo = ""; - var debug = ""; - var project_url = "http://www.php.net"; - var project_header = creditspath + "/php_" + basename + ".h"; - var versioning = ""; - - if (sapi) { - var internal_name = basename.toUpperCase() + " SAPI"; - } else { - var internal_name = basename.toUpperCase() + " extension"; - } - - if (FSO.FileExists(creditspath + '/CREDITS')) { - credits = FSO.OpenTextFile(creditspath + '/CREDITS', 1); - res_desc = credits.ReadLine(); - try { - thanks = credits.ReadLine(); - } catch (e) { - thanks = null; - } - if (thanks == null) { - thanks = ""; - } else { - thanks = "Thanks to " + thanks; - } - credits.Close(); - } - - if (creditspath.match(new RegExp("pecl"))) { - /* PECL project url - this will eventually work correctly for all */ - project_url = "http://pecl.php.net/" + basename; - - /* keep independent versioning PECL-specific for now */ - if (FSO.FileExists(project_header)) { - if (header = FSO.OpenTextFile(project_header, 1)) { - contents = header.ReadAll(); - /* allowed: x.x.x[a|b|-alpha|-beta][RCx][-dev] */ - if (contents.match(new RegExp('PHP_' + basename.toUpperCase() + '_VERSION(\\s+)"((\\d+\.\\d+(\.\\d+)?)((a|b)(\\d)?|\-[a-z]{3,5})?(RC\\d+)?(\-dev)?)'))) { - project_version = RegExp.$2; - file_version = RegExp.$3.split('.'); - if (!file_version[2]) { - file_version[2] = 0; - } - versioning = '\\"" /d EXT_FILE_VERSION=' + file_version[0] + ',' + file_version[1] + ',' + file_version[2] + ' /d EXT_VERSION="\\"' + project_version; - } - header.Close(); - } - } - } - - if (makefiletarget.match(new RegExp("\\.exe$"))) { - logo = " /d WANT_LOGO "; - } - - if (PHP_DEBUG != "no") { - debug = " /d _DEBUG"; - } - - /** - * Use user supplied template.rc if it exists - */ - if (FSO.FileExists(creditspath + '\\template.rc')) { - MFO.WriteLine("$(BUILD_DIR)\\" + resname + ": " + creditspath + "\\template.rc"); - MFO.WriteLine("\t$(RC) /fo $(BUILD_DIR)\\" + resname + logo + debug + - ' /d FILE_DESCRIPTION="\\"' + res_desc + '\\"" /d FILE_NAME="\\"' + - makefiletarget + '\\"" /d PRODUCT_NAME="\\"' + res_prod_name + - versioning + '\\"" /d THANKS_GUYS="\\"' + thanks + '\\"" ' + - creditspath + '\\template.rc'); - return resname; - } - - MFO.WriteLine("$(BUILD_DIR)\\" + resname + ": win32\\build\\template.rc"); - MFO.WriteLine("\t$(RC) /n /fo $(BUILD_DIR)\\" + resname + logo + debug + - ' /d FILE_DESCRIPTION="\\"' + res_desc + '\\"" /d FILE_NAME="\\"' - + makefiletarget + '\\"" /d URL="\\"' + project_url + - '\\"" /d INTERNAL_NAME="\\"' + internal_name + versioning + - '\\"" /d THANKS_GUYS="\\"' + thanks + '\\"" win32\\build\\template.rc'); - MFO.WriteBlankLines(1); - return resname; -} - -function SAPI(sapiname, file_list, makefiletarget, cflags, obj_dir) -{ - var SAPI = sapiname.toUpperCase(); - var ldflags; - var resname; - var ld; - var manifest; - - if (typeof(obj_dir) == "undefined") { - sapiname_for_printing = configure_module_dirname; - } else { - sapiname_for_printing = configure_module_dirname + " (via " + obj_dir + ")"; - } - - STDOUT.WriteLine("Enabling SAPI " + sapiname_for_printing); - - MFO.WriteBlankLines(1); - MFO.WriteLine("# objects for SAPI " + sapiname); - MFO.WriteBlankLines(1); - - if (cflags) { - ADD_FLAG('CFLAGS_' + SAPI, cflags); - } - - ADD_SOURCES(configure_module_dirname, file_list, sapiname, obj_dir); - MFO.WriteBlankLines(1); - MFO.WriteLine("# SAPI " + sapiname); - MFO.WriteBlankLines(1); - - /* generate a .res file containing version information */ - resname = generate_version_info_resource(makefiletarget, sapiname, configure_module_dirname, true); - - MFO.WriteLine(makefiletarget + ": $(BUILD_DIR)\\" + makefiletarget); - MFO.WriteLine("\t@echo SAPI " + sapiname_for_printing + " build complete"); - MFO.WriteLine("$(BUILD_DIR)\\" + makefiletarget + ": $(DEPS_" + SAPI + ") $(" + SAPI + "_GLOBAL_OBJS) $(BUILD_DIR)\\$(PHPLIB) $(BUILD_DIR)\\" + resname); - - if (makefiletarget.match(new RegExp("\\.dll$"))) { - ldflags = "/dll $(LDFLAGS)"; - manifest = "-@$(_VC_MANIFEST_EMBED_DLL)"; - } else if (makefiletarget.match(new RegExp("\\.lib$"))) { - ldflags = "$(LDFLAGS)"; - ld = "$(MAKE_LIB)"; - } else { - ldflags = "$(LDFLAGS)"; - manifest = "-@$(_VC_MANIFEST_EMBED_EXE)"; - } - - if (ld) { - MFO.WriteLine("\t" + ld + " /nologo /out:$(BUILD_DIR)\\" + makefiletarget + " " + ldflags + " $(" + SAPI + "_GLOBAL_OBJS) $(BUILD_DIR)\\$(PHPLIB) $(LDFLAGS_" + SAPI + ") $(LIBS_" + SAPI + ") $(BUILD_DIR)\\" + resname); - } else { - ld = "@$(CC)"; - MFO.WriteLine("\t" + ld + " /nologo " + " $(" + SAPI + "_GLOBAL_OBJS) $(BUILD_DIR)\\$(PHPLIB) $(LIBS_" + SAPI + ") $(BUILD_DIR)\\" + resname + " /link /out:$(BUILD_DIR)\\" + makefiletarget + " " + ldflags + " $(LDFLAGS_" + SAPI + ")"); - } - - if (manifest) { - MFO.WriteLine("\t" + manifest); - } - - DEFINE('CFLAGS_' + SAPI + '_OBJ', '$(CFLAGS_' + SAPI + ')'); - - if (configure_module_dirname.match("pecl")) { - ADD_FLAG("PECL_TARGETS", makefiletarget); - } else { - ADD_FLAG("SAPI_TARGETS", makefiletarget); - } - - if (PHP_DSP != "no") { - generate_dsp_file(sapiname, configure_module_dirname, file_list, false); - } - - MFO.WriteBlankLines(1); - sapi_enabled[sapi_enabled.length] = [sapiname]; -} - -function ADD_DIST_FILE(filename) -{ - if (configure_module_dirname.match("pecl")) { - ADD_FLAG("PECL_EXTRA_DIST_FILES", filename); - } else { - ADD_FLAG("PHP_EXTRA_DIST_FILES", filename); - } -} - -function file_get_contents(filename) -{ - var f, c; - try { - f = FSO.OpenTextFile(filename, 1); - c = f.ReadAll(); - f.Close(); - return c; - } catch (e) { - STDOUT.WriteLine("Problem reading " + filename); - return false; - } -} - -// Add a dependency on another extension, so that -// the dependencies are built before extname -function ADD_EXTENSION_DEP(extname, dependson, optional) -{ - var EXT = extname.toUpperCase(); - var DEP = dependson.toUpperCase(); - var dep_present = false; - var dep_shared = false; - - try { - dep_present = eval("PHP_" + DEP); - - if (dep_present != "no") { - try { - dep_shared = eval("PHP_" + DEP + "_SHARED"); - } catch (e) { - dep_shared = false; - } - } - - } catch (e) { - dep_present = "no"; - } - - if (optional) { - if (dep_present == "no") { - MESSAGE("\t" + dependson + " not found: " + dependson + " support in " + extname + " disabled"); - return false; - } - } - - var ext_shared = eval("PHP_" + EXT + "_SHARED"); - - if (dep_shared) { - if (!ext_shared) { - if (optional) { - MESSAGE("\tstatic " + extname + " cannot depend on shared " + dependson + ": " + dependson + "support disabled"); - return false; - } - ERROR("static " + extname + " cannot depend on shared " + dependson); - } - - ADD_FLAG("LDFLAGS_" + EXT, "/libpath:$(BUILD_DIR)"); - ADD_FLAG("LIBS_" + EXT, "php_" + dependson + ".lib"); - ADD_FLAG("DEPS_" + EXT, "$(BUILD_DIR)\\php_" + dependson + ".lib"); - - } else { - - if (dep_present == "no") { - if (ext_shared) { - WARNING(extname + " cannot be built: missing dependency, " + dependson + " not found"); - - var dllname = ' php_' + extname + '.dll'; - - if (!REMOVE_TARGET(dllname, 'EXT_TARGETS')) { - REMOVE_TARGET(dllname, 'PECL_TARGETS'); - } - - return false; - - } - - ERROR("Cannot build " + extname + "; " + dependson + " not enabled"); - return false; - } - } // dependency is statically built-in to PHP - return true; -} - -function EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir) -{ - var objs = null; - var EXT = extname.toUpperCase(); - var extname_for_printing; - - if (shared == null) { - eval("shared = PHP_" + EXT + "_SHARED;"); - } else { - eval("PHP_" + EXT + "_SHARED = shared;"); - } - - if (cflags == null) { - cflags = ""; - } - - if (typeof(obj_dir) == "undefined") { - extname_for_printing = configure_module_dirname; - } else { - extname_for_printing = configure_module_dirname + " (via " + obj_dir + ")"; - } - - if (shared) { - STDOUT.WriteLine("Enabling extension " + extname_for_printing + " [shared]"); - cflags = "/D COMPILE_DL_" + EXT + " /D " + EXT + "_EXPORTS=1 " + cflags; - ADD_FLAG("CFLAGS_PHP", "/D COMPILE_DL_" + EXT); - } else { - STDOUT.WriteLine("Enabling extension " + extname_for_printing); - } - - MFO.WriteBlankLines(1); - MFO.WriteLine("# objects for EXT " + extname); - MFO.WriteBlankLines(1); - - - ADD_SOURCES(configure_module_dirname, file_list, extname, obj_dir); - - MFO.WriteBlankLines(1); - - if (shared) { - if (dllname == null) { - dllname = "php_" + extname + ".dll"; - } - var libname = dllname.substring(0, dllname.length-4) + ".lib"; - - var resname = generate_version_info_resource(dllname, extname, configure_module_dirname, false); - var ld = "@$(CC)"; - - MFO.WriteLine("$(BUILD_DIR)\\" + libname + ": $(BUILD_DIR)\\" + dllname); - MFO.WriteBlankLines(1); - MFO.WriteLine("$(BUILD_DIR)\\" + dllname + ": $(DEPS_" + EXT + ") $(" + EXT + "_GLOBAL_OBJS) $(BUILD_DIR)\\$(PHPLIB) $(BUILD_DIR)\\" + resname); - MFO.WriteLine("\t" + ld + " $(" + EXT + "_GLOBAL_OBJS) $(BUILD_DIR)\\$(PHPLIB) $(LIBS_" + EXT + ") $(LIBS) $(BUILD_DIR)\\" + resname + " /link /out:$(BUILD_DIR)\\" + dllname + " $(DLL_LDFLAGS) $(LDFLAGS) $(LDFLAGS_" + EXT + ")"); - MFO.WriteLine("\t-@$(_VC_MANIFEST_EMBED_DLL)"); - MFO.WriteBlankLines(1); - - if (configure_module_dirname.match("pecl")) { - ADD_FLAG("PECL_TARGETS", dllname); - } else { - ADD_FLAG("EXT_TARGETS", dllname); - } - MFO.WriteLine(dllname + ": $(BUILD_DIR)\\" + dllname); - MFO.WriteLine("\t@echo EXT " + extname + " build complete"); - MFO.WriteBlankLines(1); - - DEFINE('CFLAGS_' + EXT + '_OBJ', '$(CFLAGS_' + EXT + ')'); - } else { - ADD_FLAG("STATIC_EXT_OBJS", "$(" + EXT + "_GLOBAL_OBJS)"); - ADD_FLAG("STATIC_EXT_LIBS", "$(LIBS_" + EXT + ")"); - ADD_FLAG("STATIC_EXT_LDFLAGS", "$(LDFLAGS_" + EXT + ")"); - ADD_FLAG("STATIC_EXT_CFLAGS", "$(CFLAGS_" + EXT + ")"); - - /* find the header that declares the module pointer, - * so we can include it in internal_functions.c */ - var ext_dir = FSO.GetFolder(configure_module_dirname); - var fc = new Enumerator(ext_dir.Files); - var re = /\.h$/; - var s, c; - for (; !fc.atEnd(); fc.moveNext()) { - s = fc.item() + ""; - if (s.match(re)) { - c = file_get_contents(s); - if (c.match("phpext_")) { - extension_include_code += '#include "' + configure_module_dirname + '/' + FSO.GetFileName(s) + '"\r\n'; - } - } - } - - extension_module_ptrs += '\tphpext_' + extname + '_ptr,\r\n'; - - DEFINE('CFLAGS_' + EXT + '_OBJ', '$(CFLAGS_PHP) $(CFLAGS_' + EXT + ')'); - } - ADD_FLAG("CFLAGS_" + EXT, cflags); - - if (PHP_DSP != "no") { - generate_dsp_file(extname, configure_module_dirname, file_list, shared); - } - - extensions_enabled[extensions_enabled.length] = [extname, shared ? 'shared' : 'static']; -} - -function ADD_SOURCES(dir, file_list, target, obj_dir) -{ - var i; - var tv; - var src, obj, sym, flags; - - if (target == null) { - target = "php"; - } - - sym = target.toUpperCase() + "_GLOBAL_OBJS"; - flags = "CFLAGS_" + target.toUpperCase() + '_OBJ'; - - if (configure_subst.Exists(sym)) { - tv = configure_subst.Item(sym); - } else { - tv = ""; - } - - file_list = file_list.split(new RegExp("\\s+")); - file_list.sort(); - - var re = new RegExp("\.[a-z0-9A-Z]+$"); - - dir = dir.replace(new RegExp("/", "g"), "\\"); - var objs_line = ""; - var srcs_line = ""; - - var sub_build = "$(BUILD_DIR)\\"; - - /* if module dir is not a child of the main source dir, - * we need to tweak it; we should have detected such a - * case in condense_path and rewritten the path to - * be relative. - * This probably breaks for non-sibling dirs, but that - * is not a problem as buildconf only checks for pecl - * as either a child or a sibling */ - if (obj_dir == null) { - var build_dir = dir.replace(new RegExp("^..\\\\"), ""); - var mangle_dir = build_dir.replace(new RegExp("[\\\\/.]", "g"), "_"); - var bd_flags_name = "CFLAGS_BD_" + mangle_dir.toUpperCase(); - } - else { - var build_dir = obj_dir.replace(new RegExp("^..\\\\"), ""); - var mangle_dir = build_dir.replace(new RegExp("[\\\\/.]", "g"), "_"); - var bd_flags_name = "CFLAGS_BD_" + mangle_dir.toUpperCase(); - } - - var dirs = build_dir.split("\\"); - var i, d = ""; - for (i = 0; i < dirs.length; i++) { - d += dirs[i]; - build_dirs[build_dirs.length] = d; - d += "\\"; - } - sub_build += d; - - - DEFINE(bd_flags_name, " /Fd" + sub_build + " /Fp" + sub_build + " /FR" + sub_build + " "); - - for (i in file_list) { - src = file_list[i]; - obj = src.replace(re, ".obj"); - tv += " " + sub_build + obj; - - if (PHP_ONE_SHOT == "yes") { - if (i > 0) { - objs_line += " " + sub_build + obj; - srcs_line += " " + dir + "\\" + src; - } else { - objs_line = sub_build + obj; - srcs_line = dir + "\\" + src; - } - } else { - MFO.WriteLine(sub_build + obj + ": " + dir + "\\" + src); - MFO.WriteLine("\t@$(CC) $(" + flags + ") $(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " /Fo" + sub_build + obj); - } - } - - if (PHP_ONE_SHOT == "yes") { - MFO.WriteLine(objs_line + ": " + srcs_line); - MFO.WriteLine("\t$(CC) $(" + flags + ") $(CFLAGS) /Fo" + sub_build + " $(" + bd_flags_name + ") /c " + srcs_line); - } - - DEFINE(sym, tv); -} - -function REMOVE_TARGET(dllname, flag) -{ - var dllname = dllname.replace(/\s/g, ""); - var EXT = dllname.replace(/php_(\S+)\.dll/, "$1").toUpperCase(); - var php_flags = configure_subst.Item("CFLAGS_PHP"); - - if (configure_subst.Exists(flag)) { - var targets = configure_subst.Item(flag); - - if (targets.match(dllname)) { - configure_subst.Remove(flag); - targets = targets.replace(dllname, ""); - targets = targets.replace(/\s+/, " "); - targets = targets.replace(/\s$/, ""); - configure_subst.Add(flag, targets); - configure_hdr.Add("HAVE_" + EXT, new Array(0, "")); - configure_subst.Item("CFLAGS_PHP") = php_flags.replace(" /D COMPILE_DL_" + EXT, ""); - extensions_enabled.pop(); - return true; - } - } - return false; -} - -function generate_internal_functions() -{ - var infile, outfile; - var indata; - - STDOUT.WriteLine("Generating main/internal_functions.c"); - - infile = FSO.OpenTextFile("main/internal_functions.c.in", 1); - indata = infile.ReadAll(); - infile.Close(); - - indata = indata.replace("@EXT_INCLUDE_CODE@", extension_include_code); - indata = indata.replace("@EXT_MODULE_PTRS@", extension_module_ptrs); - - if (FSO.FileExists("main/internal_functions.c")) { - var origdata = file_get_contents("main/internal_functions.c"); - - if (origdata == indata) { - STDOUT.WriteLine("\t[content unchanged; skipping]"); - return; - } - } - - outfile = FSO.CreateTextFile("main/internal_functions.c", true); - outfile.Write(indata); - outfile.Close(); -} - -function output_as_table(header, ar_out) -{ - var l = header.length; - var cols = 80; - var fixedlenght = ""; - var t = 0; - var i,j,k,m; - var out = "| "; - var min = new Array(l); - var max = new Array(l); - - if (l != ar_out[0].length) { - STDOUT.WriteLine("Invalid header argument, can't output the table " + l + " " + ar_out[0].length ); - return; - } - - for (j=0; j < l; j++) { - var tmax, tmin; - - /*Figure out the max length per column */ - tmin = 0; - tmax = 0; - for (k = 0; k < ar_out.length; k++) { - var t = ar_out[k][j].length; - if (t > tmax) tmax = t; - else if (t < tmin) tmin = t; - } - if (tmax > header[j].length) { - max[j] = tmax; - } else { - max[j] = header[j].length; - } - if (tmin < header[j].length) { - min[j] = header[j].length; - } - } - - sep = ""; - k = 0; - for (i = 0; i < l; i++) { - k += max[i] + 3; - } - k++; - - for (j=0; j < k; j++) { - sep += "-"; - } - - STDOUT.WriteLine(sep); - out = "|"; - for (j=0; j < l; j++) { - out += " " + header[j]; - for (var i = 0; i < (max[j] - header[j].length); i++){ - out += " "; - } - out += " |"; - } - STDOUT.WriteLine(out); - - STDOUT.WriteLine(sep); - - out = "|"; - for (i=0; i < ar_out.length; i++) { - line = ar_out[i]; - for (j=0; j < l; j++) { - out += " " + line[j]; - for (var k = 0; k < (max[j] - line[j].length); k++){ - out += " "; - } - out += " |"; - } - STDOUT.WriteLine(out); - out = "|"; - } - - STDOUT.WriteLine(sep); -} - -function write_summary() -{ - var ar = new Array(); - - STDOUT.WriteBlankLines(2); - - STDOUT.WriteLine("Enabled extensions:"); - output_as_table(["Extension", "Mode"], extensions_enabled.sort()); - STDOUT.WriteBlankLines(2); - - STDOUT.WriteLine("Enabled SAPI:"); - output_as_table(["Sapi Name"], sapi_enabled); - STDOUT.WriteBlankLines(2); - - ar[0] = ['Build type', PHP_DEBUG == "yes" ? "Debug" : "Release"]; - ar[1] = ['Thread Safety', PHP_ZTS == "yes" ? "Yes" : "No"]; - ar[2] = ['Compiler', VC_VERSIONS[VCVERS]]; - ar[3] = ['Architecture', X64 ? 'x64' : 'x86']; - - output_as_table(["",""], ar); - STDOUT.WriteBlankLines(2); -} - -function generate_files() -{ - var i, dir, bd, last; - - STDOUT.WriteBlankLines(1); - STDOUT.WriteLine("Creating build dirs..."); - dir = get_define("BUILD_DIR"); - build_dirs.sort(); - last = null; - - if (!FSO.FolderExists(dir)) { - FSO.CreateFolder(dir); - } - - for (i = 0; i < build_dirs.length; i++) { - bd = FSO.BuildPath(dir, build_dirs[i]); - if (bd == last) { - continue; - } - last = bd; - ADD_FLAG("BUILD_DIRS_SUB", bd.replace(new RegExp('^'+dir+'\\\\'), '$(BUILD_DIR)\\')); - if (!FSO.FolderExists(bd)) { - FSO.CreateFolder(bd); - } - } - - if (PHP_DSP != "no") { - generate_dsp_file("TSRM", "TSRM", null, false); - generate_dsp_file("Zend", "Zend", null, false); - generate_dsp_file("win32", "win32", null, false); - generate_dsp_file("main", "main", null, false); - generate_dsp_file("streams", "main\\streams", null, false); - copy_dsp_files(); - } - - STDOUT.WriteLine("Generating files..."); - generate_makefile(); - generate_internal_functions(); - generate_config_h(); - - STDOUT.WriteLine("Done."); - STDOUT.WriteBlankLines(1); - write_summary(); - - if (PHP_SNAPSHOT_BUILD != "no") { - STDOUT.WriteLine("Type 'nmake snap' to build a PHP snapshot"); - } else { - STDOUT.WriteLine("Type 'nmake' to build PHP"); - } -} - -function generate_config_h() -{ - var infile, outfile; - var indata; - var prefix; - - prefix = PHP_PREFIX.replace(new RegExp("\\\\", "g"), "\\\\"); - - STDOUT.WriteLine("Generating main/config.w32.h"); - - infile = FSO.OpenTextFile("win32/build/config.w32.h.in", 1); - indata = infile.ReadAll(); - infile.Close(); - - outfile = FSO.CreateTextFile("main/config.w32.h", true); - - indata = indata.replace(new RegExp("@PREFIX@", "g"), prefix); - outfile.Write(indata); - - var keys = (new VBArray(configure_hdr.Keys())).toArray(); - var i, j; - var item; - var pieces, stuff_to_crack, chunk; - - outfile.WriteBlankLines(1); - outfile.WriteLine("/* values determined by configure.js */"); - - for (i in keys) { - item = configure_hdr.Item(keys[i]); - outfile.WriteBlankLines(1); - pieces = item[0]; - - if (item[1] != undefined) { - outfile.WriteLine("/* " + item[1] + " */"); - } - - if (typeof(pieces) == "string" && pieces.charCodeAt(0) == 34) { - /* quoted string have a maximal length of 2k under vc. - * solution is to crack them and let the compiler concat - * them implicitly */ - stuff_to_crack = pieces; - pieces = ""; - - while (stuff_to_crack.length) { - j = 65; - while (stuff_to_crack.charCodeAt(j) != 32 && j < stuff_to_crack.length) - j++; - - chunk = stuff_to_crack.substr(0, j); - pieces += chunk; - stuff_to_crack = stuff_to_crack.substr(chunk.length); - if (stuff_to_crack.length) - pieces += '" "'; - } - } - - outfile.WriteLine("#define " + keys[i] + " " + pieces); - } - - outfile.Close(); -} - -function generate_makefile() -{ - STDOUT.WriteLine("Generating Makefile"); - var MF = FSO.CreateTextFile("Makefile", true); - - MF.WriteLine("# Generated by configure.js"); - - /* spit out variable definitions */ - var keys = (new VBArray(configure_subst.Keys())).toArray(); - var i; - - for (i in keys) { - // The trailing space is needed to prevent the trailing backslash - // that is part of the build dir flags (CFLAGS_BD_XXX) from being - // seen as a line continuation character - MF.WriteLine(keys[i] + "=" + - //word_wrap_and_indent(1, configure_subst.Item(keys[i]), ' \\', '\t') + " " - configure_subst.Item(keys[i]) + " " - ); - MF.WriteBlankLines(1); - } - - MF.WriteBlankLines(1); - - var TF = FSO.OpenTextFile("win32/build/Makefile", 1); - MF.Write(TF.ReadAll()); - TF.Close(); - - MF.WriteBlankLines(2); - - MFO.Close(); - TF = FSO.OpenTextFile("Makefile.objects", 1); - MF.Write(TF.ReadAll()); - TF.Close(); - - MF.Close(); -} - -function ADD_FLAG(name, flags, target) -{ - if (target != null) { - name = target.toUpperCase() + "_" + name; - } - if (configure_subst.Exists(name)) { - var curr_flags = configure_subst.Item(name); - - if (curr_flags.indexOf(flags) >= 0) { - return; - } - - flags = curr_flags + " " + flags; - configure_subst.Remove(name); - } - configure_subst.Add(name, flags); - - if (PHP_DSP != "no") { - if (flags && (name.substr(name.length-3) != "PHP") && (name.substr(0, 7) == "CFLAGS_")) { - DSP_FLAGS[DSP_FLAGS.length] = new Array(name, flags); - } - } -} - -function get_define(name) -{ - if (configure_subst.Exists(name)) { - return configure_subst.Item(name); - } - return ""; -} - -// Add a .def to the core to export symbols -function ADD_DEF_FILE(name) -{ - if (!configure_subst.Exists("PHPDEF")) { - DEFINE("PHPDEF", "$(BUILD_DIR)\\$(PHPDLL).def"); - ADD_FLAG("PHP_LDFLAGS", "/def:$(PHPDEF)"); - } - ADD_FLAG("PHP_DLL_DEF_SOURCES", name); -} - -function AC_DEFINE(name, value, comment, quote) -{ - if (quote == null) { - quote = true; - } - if (quote && typeof(value) == "string") { - value = '"' + value.replace(new RegExp('(["\\\\])', "g"), '\\$1') + '"'; - } else if (value.length == 0) { - value = '""'; - } - var item = new Array(value, comment); - if (configure_hdr.Exists(name)) { - var orig_item = configure_hdr.Item(name); - STDOUT.WriteLine("AC_DEFINE[" + name + "]=" + value + ": is already defined to " + orig_item[0]); - } else { - configure_hdr.Add(name, item); - } -} - -function MESSAGE(msg) -{ - STDOUT.WriteLine("" + msg); -} - -function ERROR(msg) -{ - STDERR.WriteLine("ERROR: " + msg); - WScript.Quit(3); -} - -function WARNING(msg) -{ - STDERR.WriteLine("WARNING: " + msg); - STDERR.WriteBlankLines(1); -} - -function copy_and_subst(srcname, destname, subst_array) -{ - if (!FSO.FileExists(srcname)) { - srcname = configure_module_dirname + "\\" + srcname; - destname = configure_module_dirname + "\\" + destname; - } - - var content = file_get_contents(srcname); - var i; - - for (i = 0; i < subst_array.length; i+=2) { - var re = subst_array[i]; - var rep = subst_array[i+1]; - - content = content.replace(re, rep); - } - - var f = FSO.CreateTextFile(destname, true); - f.Write(content); - f.Close(); -} - -// glob using simple filename wildcards -// returns an array of matches that are found -// in the filesystem -function glob(path_pattern) -{ - var path_parts = path_pattern.replace(new RegExp("/", "g"), "\\").split("\\"); - var p; - var base = ""; - var is_pat_re = /\*/; - -//STDOUT.WriteLine("glob: " + path_pattern); - - if (FSO.FileExists(path_pattern)) { - return new Array(path_pattern); - } - - // first, build as much as possible that doesn't have a pattern - for (p = 0; p < path_parts.length; p++) { - if (path_parts[p].match(is_pat_re)) - break; - if (p) - base += "\\"; - base += path_parts[p]; - } - - return _inner_glob(base, p, path_parts); -} - -function _inner_glob(base, p, parts) -{ - var pat = parts[p]; - var full_name = base + "\\" + pat; - var re = null; - var items = null; - - if (p == parts.length) { - return false; - } - -//STDOUT.WriteLine("inner: base=" + base + " p=" + p + " pat=" + pat); - - if (FSO.FileExists(full_name)) { - if (p < parts.length - 1) { - // we didn't reach the full extent of the pattern - return false; - } - return new Array(full_name); - } - - if (FSO.FolderExists(full_name) && p == parts.length - 1) { - // we have reached the end of the pattern; no need to recurse - return new Array(full_name); - } - - // Convert the pattern into a regexp - re = new RegExp("^" + pat.replace(/\./g, '\\.').replace(/\*/g, '.*').replace(/\?/g, '.') + "$", "i"); - - items = new Array(); - - if (!FSO.FolderExists(base)) { - return false; - } - - var folder = FSO.GetFolder(base); - var fc = null; - var subitems = null; - var item_name = null; - var j; - - fc = new Enumerator(folder.SubFolders); - for (; !fc.atEnd(); fc.moveNext()) { - item_name = FSO.GetFileName(fc.item()); - - if (item_name.match(re)) { - // got a match; if we are at the end of the pattern, just add these - // things to the items array - if (p == parts.length - 1) { - items[items.length] = fc.item(); - } else { - // we should recurse and do more matches - subitems = _inner_glob(base + "\\" + item_name, p + 1, parts); - if (subitems) { - for (j = 0; j < subitems.length; j++) { - items[items.length] = subitems[j]; - } - } - } - } - } - - // if we are at the end of the pattern, we should match - // files too - if (p == parts.length - 1) { - fc = new Enumerator(folder.Files); - for (; !fc.atEnd(); fc.moveNext()) { - item_name = FSO.GetFileName(fc.item()); - if (item_name.match(re)) { - items[items.length] = fc.item(); - } - } - } - - if (items.length == 0) - return false; - - return items; -} - - -// for snapshot builders, this option will attempt to enable everything -// and you can then build everything, ignoring fatal errors within a module -// by running "nmake snap" -PHP_SNAPSHOT_BUILD = "no"; -ARG_ENABLE('snapshot-build', 'Build a snapshot; turns on everything it can and ignores build errors', 'no'); - -// one-shot build optimizes build by asking compiler to build -// several objects at once, reducing overhead of starting new -// compiler processes. -ARG_ENABLE('one-shot', 'Optimize for fast build - best for release and snapshot builders, not so hot for edit-and-rebuild hacking', 'no'); - - +// Utils for configure script +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2008 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.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: Wez Furlong | + +----------------------------------------------------------------------+ +*/ + +// $Id: confutils.js,v 1.60.2.1.2.8.2.33 2009-05-29 07:43:07 kalle Exp $ + +var STDOUT = WScript.StdOut; +var STDERR = WScript.StdErr; +var WshShell = WScript.CreateObject("WScript.Shell"); +var FSO = WScript.CreateObject("Scripting.FileSystemObject"); +var MFO = null; +var SYSTEM_DRIVE = WshShell.Environment("Process").Item("SystemDrive"); +var PROGRAM_FILES = WshShell.Environment("Process").Item("ProgramFiles"); +var DSP_FLAGS = new Array(); + +/* Store the enabled extensions (summary + QA check) */ +var extensions_enabled = new Array(); + +/* Store the SAPI enabled (summary + QA check) */ +var sapi_enabled = new Array(); + +/* Mapping CL version > human readable name */ +var VC_VERSIONS = new Array(); +VC_VERSIONS[1200] = 'MSVC6 (Visual C++ 6.0)'; +VC_VERSIONS[1300] = 'MSVC7 (Visual C++ 2002)'; +VC_VERSIONS[1310] = 'MSVC7.1 (Visual C++ 2003)'; +VC_VERSIONS[1400] = 'MSVC8 (Visual C++ 2005)'; +VC_VERSIONS[1500] = 'MSVC9 (Visual C++ 2008)'; + +var VC_VERSIONS_SHORT = new Array(); +VC_VERSIONS_SHORT[1200] = 'VC6'; +VC_VERSIONS_SHORT[1300] = 'VC7'; +VC_VERSIONS_SHORT[1310] = 'VC7.1'; +VC_VERSIONS_SHORT[1400] = 'VC8'; +VC_VERSIONS_SHORT[1500] = 'VC9'; + +if (PROGRAM_FILES == null) { + PROGRAM_FILES = "C:\\Program Files"; +} + +if (!FSO.FileExists("README.SVN-RULES")) { + STDERR.WriteLine("Must be run from the root of the php source"); + WScript.Quit(10); +} + +var CWD = WshShell.CurrentDirectory; + +if (typeof(CWD) == "undefined") { + CWD = FSO.GetParentFolderName(FSO.GetAbsolutePathName("README.SVN-RULES")); +} + +/* defaults; we pick up the precise versions from configure.in */ +var PHP_VERSION = 5; +var PHP_MINOR_VERSION = 0; +var PHP_RELEASE_VERSION = 0; +var PHP_EXTRA_VERSION = ""; +var PHP_VERSION_STRING = "5.0.0"; + +function get_version_numbers() +{ + var cin = file_get_contents("configure.in"); + + if (cin.match(new RegExp("PHP_MAJOR_VERSION=(\\d+)"))) { + PHP_VERSION = RegExp.$1; + } + if (cin.match(new RegExp("PHP_MINOR_VERSION=(\\d+)"))) { + PHP_MINOR_VERSION = RegExp.$1; + } + if (cin.match(new RegExp("PHP_RELEASE_VERSION=(\\d+)"))) { + PHP_RELEASE_VERSION = RegExp.$1; + } + PHP_VERSION_STRING = PHP_VERSION + "." + PHP_MINOR_VERSION + "." + PHP_RELEASE_VERSION; + + if (cin.match(new RegExp("PHP_EXTRA_VERSION=\"([^\"]+)\""))) { + PHP_EXTRA_VERSION = RegExp.$1; + if (PHP_EXTRA_VERSION.length) { + PHP_VERSION_STRING += PHP_EXTRA_VERSION; + } + } + DEFINE('PHP_VERSION_STRING', PHP_VERSION_STRING); +} + +configure_args = new Array(); +configure_subst = WScript.CreateObject("Scripting.Dictionary"); + +configure_hdr = WScript.CreateObject("Scripting.Dictionary"); +build_dirs = new Array(); + +extension_include_code = ""; +extension_module_ptrs = ""; + +get_version_numbers(); + +/* execute a command and return the output as a string */ +function execute(command_line) +{ + var e = WshShell.Exec(command_line); + var ret = ""; + + ret = e.StdOut.ReadAll(); + +//STDOUT.WriteLine("command " + command_line); +//STDOUT.WriteLine(ret); + + return ret; +} + +function probe_binary(EXE, what) +{ + // tricky escapes to get stderr redirection to work + var command = 'cmd /c ""' + EXE; + if (what == "version") { + command = command + '" -v"'; + } + var version = execute(command + '" 2>&1"'); + + if (what == "64") { + if (version.match(/x64/)) { + return 1; + } + } else { + if (version.match(/(\d+\.\d+(\.\d+)?(\.\d+)?)/)) { + return RegExp.$1; + } + } + return 0; +} + +function condense_path(path) +{ + path = FSO.GetAbsolutePathName(path); + + if (path.substr(0, CWD.length).toLowerCase() + == CWD.toLowerCase() && + (path.charCodeAt(CWD.length) == 92 || path.charCodeAt(CWD.length) == 47)) { + return path.substr(CWD.length + 1); + } + + var a = CWD.split("\\"); + var b = path.split("\\"); + var i, j; + + for (i = 0; i < b.length; i++) { + if (a[i].toLowerCase() == b[i].toLowerCase()) + continue; + if (i > 0) { + /* first difference found */ + path = ""; + for (j = 0; j < a.length - i; j++) { + path += "..\\"; + } + for (j = i; j < b.length; j++) { + path += b[j]; + if (j < b.length - 1) + path += "\\"; + } + return path; + } + /* on a different drive */ + break; + } + + return path; +} + +function ConfigureArg(type, optname, helptext, defval) +{ + var opptype = type == "enable" ? "disable" : "without"; + + if (defval == "yes" || defval == "yes,shared") { + this.arg = "--" + opptype + "-" + optname; + this.imparg = "--" + type + "-" + optname; + } else { + this.arg = "--" + type + "-" + optname; + this.imparg = "--" + opptype + "-" + optname; + } + + this.optname = optname; + this.helptext = helptext; + this.defval = defval; + this.symval = optname.toUpperCase().replace(new RegExp("-", "g"), "_"); + this.seen = false; + this.argval = defval; +} + +function ARG_WITH(optname, helptext, defval) +{ + configure_args[configure_args.length] = new ConfigureArg("with", optname, helptext, defval); +} + +function ARG_ENABLE(optname, helptext, defval) +{ + configure_args[configure_args.length] = new ConfigureArg("enable", optname, helptext, defval); +} + +function analyze_arg(argval) +{ + var ret = new Array(); + var shared = false; + + if (argval == "shared") { + shared = true; + argval = "yes"; + } else if (argval == null) { + /* nothing */ + } else if (arg_match = argval.match(new RegExp("^shared,(.*)"))) { + shared = true; + argval = arg_match[1]; + } else if (arg_match = argval.match(new RegExp("^(.*),shared$"))) { + shared = true; + argval = arg_match[1]; + } + + ret[0] = shared; + ret[1] = argval; + return ret; +} + +function word_wrap_and_indent(indent, text, line_suffix, indent_char) +{ + if (text == null) { + return ""; + } + + var words = text.split(new RegExp("\\s+", "g")); + var i = 0; + var ret_text = ""; + var this_line = ""; + var t; + var space = ""; + var lines = 0; + + if (line_suffix == null) { + line_suffix = ""; + } + + if (indent_char == null) { + indent_char = " "; + } + + for (i = 0; i < indent; i++) { + space += indent_char; + } + + for (i = 0; i < words.length; i++) { + if (this_line.length) { + t = this_line + " " + words[i]; + } else { + t = words[i]; + } + + if (t.length + indent > 78) { + if (lines++) { + ret_text += space; + } + ret_text += this_line + line_suffix + "\r\n"; + this_line = ""; + } + + if (this_line.length) { + this_line += " " + words[i]; + } else { + this_line = words[i]; + } + } + + if (this_line.length) { + if (lines) + ret_text += space; + ret_text += this_line; + } + + return ret_text; +} + +function conf_process_args() +{ + var i, j; + var configure_help_mode = false; + var analyzed = false; + var nice = "cscript /nologo configure.js "; + var disable_all = false; + + args = WScript.Arguments; + for (i = 0; i < args.length; i++) { + arg = args(i); + nice += ' "' + arg + '"'; + if (arg == "--help") { + configure_help_mode = true; + break; + } + if (arg == "--disable-all") { + disable_all = true; + continue; + } + + // If it is --foo=bar, split on the equals sign + arg = arg.split("=", 2); + argname = arg[0]; + if (arg.length > 1) { + argval = arg[1]; + } else { + argval = null; + } + + // Find the arg + found = false; + for (j = 0; j < configure_args.length; j++) { + if (argname == configure_args[j].imparg || argname == configure_args[j].arg) { + found = true; + + arg = configure_args[j]; + arg.seen = true; + + analyzed = analyze_arg(argval); + shared = analyzed[0]; + argval = analyzed[1]; + + if (argname == arg.imparg) { + /* we matched the implicit, or default arg */ + if (argval == null) { + argval = arg.defval; + } + } else { + /* we matched the non-default arg */ + if (argval == null) { + argval = arg.defval == "no" ? "yes" : "no"; + } + } + + arg.argval = argval; + eval("PHP_" + arg.symval + " = argval;"); + eval("PHP_" + arg.symval + "_SHARED = shared;"); + break; + } + } + if (!found) { + STDERR.WriteLine("Unknown option " + argname + "; please try configure.js --help for a list of valid options"); + WScript.Quit(2); + } + } + + if (configure_help_mode) { + STDOUT.WriteLine(word_wrap_and_indent(0, +"Options that enable extensions and SAPI will accept \ +'yes' or 'no' as a parameter. They also accept 'shared' \ +as a synonym for 'yes' and request a shared build of that \ +module. Not all modules can be built as shared modules; \ +configure will display [shared] after the module name if \ +can be built that way. \ +" + )); + STDOUT.WriteBlankLines(1); + + // Measure width to pretty-print the output + max_width = 0; + for (i = 0; i < configure_args.length; i++) { + arg = configure_args[i]; + if (arg.arg.length > max_width) + max_width = arg.arg.length; + } + + for (i = 0; i < configure_args.length; i++) { + arg = configure_args[i]; + + n = max_width - arg.arg.length; + pad = " "; + for (j = 0; j < n; j++) { + pad += " "; + } + STDOUT.WriteLine(" " + arg.arg + pad + word_wrap_and_indent(max_width + 5, arg.helptext)); + } + WScript.Quit(1); + } + + var snapshot_build_exclusions = new Array( + 'debug', 'crt-debug', 'lzf-better-compression', + 'php-build', 'snapshot-template', 'ereg', + 'pcre-regex', 'fastcgi', 'force-cgi-redirect', + 'path-info-check', 'zts', 'ipv6', 'memory-limit', + 'zend-multibyte', 'fd-setsize', 'memory-manager', 't1lib' + ); + var force; + + // Now set any defaults we might have missed out earlier + for (i = 0; i < configure_args.length; i++) { + arg = configure_args[i]; + if (arg.seen) + continue; + analyzed = analyze_arg(arg.defval); + shared = analyzed[0]; + argval = analyzed[1]; + + // Don't trust a default "yes" answer for a non-core module + // in a snapshot build + if (PHP_SNAPSHOT_BUILD != "no" && argval == "yes" && !shared) { + + force = true; + for (j = 0; j < snapshot_build_exclusions.length; j++) { + if (snapshot_build_exclusions[j] == arg.optname) { + force = false; + break; + } + } + + if (force) { + /* now check if it is a core module */ + force = false; + for (j = 0; j < core_module_list.length; j++) { + if (core_module_list[j] == arg.optname) { + force = true; + break; + } + } + + if (!force) { + STDOUT.WriteLine("snapshot: forcing " + arg.arg + " shared"); + shared = true; + } + } + } + + if (PHP_SNAPSHOT_BUILD != "no" && argval == "no") { + force = true; + for (j = 0; j < snapshot_build_exclusions.length; j++) { + if (snapshot_build_exclusions[j] == arg.optname) { + force = false; + break; + } + } + if (force) { + STDOUT.WriteLine("snapshot: forcing " + arg.optname + " on"); + argval = "yes"; + shared = true; + } + } + + if (disable_all) { + force = true; + for (j = 0; j < snapshot_build_exclusions.length; j++) { + if (snapshot_build_exclusions[j] == arg.optname) { + force = false; + break; + } + } + if (force) { + if (arg.defval == '') { + argval = ''; + } else { + argval = "no"; + } + shared = false; + } + } + + eval("PHP_" + arg.symval + " = argval;"); + eval("PHP_" + arg.symval + "_SHARED = shared;"); + } + + MFO = FSO.CreateTextFile("Makefile.objects", true); + + STDOUT.WriteLine("Saving configure options to config.nice.bat"); + var nicefile = FSO.CreateTextFile("config.nice.bat", true); + nicefile.WriteLine(nice + " %*"); + nicefile.Close(); + + AC_DEFINE('CONFIGURE_COMMAND', nice, "Configure line"); +} + +function DEFINE(name, value) +{ + if (configure_subst.Exists(name)) { + configure_subst.Remove(name); + } + configure_subst.Add(name, value); +} + +// Searches a set of paths for a file; +// returns the dir in which the file was found, +// true if it was found in the default env path, +// or false if it was not found at all. +// env_name is the optional name of an env var +// specifying the default path to search +function search_paths(thing_to_find, explicit_path, env_name) +{ + var i, found = false, place = false, file, env; + + STDOUT.Write("Checking for " + thing_to_find + " ... "); + + thing_to_find = thing_to_find.replace(new RegExp("/", "g"), "\\"); + + if (explicit_path != null) { + if (typeof(explicit_path) == "string") { + explicit_path = explicit_path.split(";"); + } + + for (i = 0; i < explicit_path.length; i++) { + file = glob(explicit_path[i] + "\\" + thing_to_find); + if (file) { + found = true; + place = file[0]; + place = place.substr(0, place.length - thing_to_find.length - 1); + break; + } + } + } + + if (!found && env_name != null) { + env = WshShell.Environment("Process").Item(env_name); + env = env.split(";"); + for (i = 0; i < env.length; i++) { + file = glob(env[i] + "\\" + thing_to_find); + if (file) { + found = true; + place = true; + break; + } + } + } + + if (found && place == true) { + STDOUT.WriteLine(" "); + } else if (found) { + STDOUT.WriteLine(" " + place); + } else { + STDOUT.WriteLine(" "); + } + return place; +} + +function PATH_PROG(progname, additional_paths, symbol) +{ + var exe; + var place; + var cyg_path = PHP_CYGWIN + "\\bin;" + PHP_CYGWIN + "\\usr\\local\\bin"; + var php_build_bin_path = PHP_PHP_BUILD + "\\bin" + + exe = progname + ".exe"; + + if (additional_paths == null) { + additional_paths = cyg_path; + } else { + additional_paths += ";" + cyg_path; + } + + additional_paths = additional_paths + ";" + php_build_bin_path; + + place = search_paths(exe, additional_paths, "PATH"); + + if (place == true) { + place = exe; + } else if (place != false) { + place = place + "\\" + exe; + } + + if (place) { + if (symbol == null) { + symbol = progname.toUpperCase(); + } + DEFINE(symbol, place); + } + return place; +} + +function find_pattern_in_path(pattern, path) +{ + if (path == null) { + return false; + } + + var dirs = path.split(';'); + var i; + var items; + + for (i = 0; i < dirs.length; i++) { + items = glob(dirs[i] + "\\" + pattern); + if (items) { + return condense_path(items[0]); + } + } + return false; +} + +function CHECK_LIB(libnames, target, path_to_check, common_name) +{ + STDOUT.Write("Checking for library " + libnames + " ... "); + + if (common_name == null && target != null) { + common_name = target; + } + + if (path_to_check == null) { + path_to_check = ""; + } + + // if they specified a common name for the package that contains + // the library, tag some useful defaults on to the end of the + // path to be searched + if (common_name != null) { + path_to_check += ";" + PHP_PHP_BUILD + "\\" + common_name + "*"; + path_to_check += ";" + PHP_PHP_BUILD + "\\lib\\" + common_name + "*"; + path_to_check += ";..\\" + common_name + "*"; + } + + // Determine target for build flags + if (target == null) { + target = ""; + } else { + target = "_" + target.toUpperCase(); + } + + // Expand path to include general dirs + path_to_check += ";" + php_usual_lib_suspects; + + // It is common practice to put libs under one of these dir names + var subdirs = new Array(PHP_DEBUG == "yes" ? "Debug" : (PHP_DEBUG_PACK == "yes"?"Release_Dbg":"Release"), "lib", "libs", "libexec"); + + // libnames can be ; separated list of accepted library names + libnames = libnames.split(';'); + + // for debug builds, lib may have _debug appended, we want that first + if (PHP_DEBUG == "yes") { + var length = libnames.length; + for (var i = 0; i < length; i++) { + var name = new String(libnames[i]); + rExp = /.lib$/i; + name = name.replace(rExp,"_debug.lib"); + libnames.unshift(name); + } + } + + var i, j, k, libname; + var location = false; + var path = path_to_check.split(';'); + + for (i = 0; i < libnames.length; i++) { + libname = libnames[i]; + + for (k = 0; k < path.length; k++) { + location = glob(path[k] + "\\" + libname); + if (location) { + location = location[0]; + break; + } + for (j = 0; j < subdirs.length; j++) { + location = glob(path[k] + "\\" + subdirs[j] + "\\" + libname); + if (location) { + location = location[0]; + break; + } + } + if (location) + break; + } + + if (location) { + location = condense_path(location); + var libdir = FSO.GetParentFolderName(location); + libname = FSO.GetFileName(location); + ADD_FLAG("LDFLAGS" + target, '/libpath:"' + libdir + '" '); + ADD_FLAG("LIBS" + target, libname); + + STDOUT.WriteLine(location); + + return location; + } + + // Check in their standard lib path + location = find_pattern_in_path(libname, WshShell.Environment("Process").Item("LIB")); + + if (location) { + location = condense_path(location); + libname = FSO.GetFileName(location); + ADD_FLAG("LIBS" + target, libname); + + STDOUT.WriteLine(" " + libname); + return location; + } + + // Check in their general extra libs path + location = find_pattern_in_path(libname, PHP_EXTRA_LIBS); + if (location) { + location = condense_path(location); + libname = FSO.GetFileName(location); + ADD_FLAG("LIBS" + target, libname); + STDOUT.WriteLine(""); + return location; + } + } + + STDOUT.WriteLine(""); + + return false; +} + +function OLD_CHECK_LIB(libnames, target, path_to_check) +{ + if (target == null) { + target = ""; + } else { + target = "_" + target.toUpperCase(); + } + + if (path_to_check == null) { + path_to_check = php_usual_lib_suspects; + } else { + path_to_check += ";" + php_usual_lib_suspects; + } + var have = 0; + var p; + var i; + var libname; + + var subdir = PHP_DEBUG == "yes" ? "Debug" : (PHP_DEBUG_PACK == "yes"?"Release_Dbg":"Release"); + + libnames = libnames.split(';'); + for (i = 0; i < libnames.length; i++) { + libname = libnames[i]; + p = search_paths(libname, path_to_check, "LIB"); + + if (!p) { + p = search_paths(subdir + "\\" + libname, path_to_check, "LIB"); + if (p) { + p += "\\" + subdir; + } + } + + if (typeof(p) == "string") { + ADD_FLAG("LDFLAGS" + target, '/libpath:"' + p + '" '); + ADD_FLAG("LIBS" + target, libname); + have = 1; + } else if (p == true) { + ADD_FLAG("LIBS" + target, libname); + have = 1; + } else { + /* not found in the defaults or the explicit paths, + * so check the general extra libs; if we find + * it here, no need to add another /libpath: for it as we + * already have it covered, but we need to add the lib + * to LIBS_XXX */ + if (false != search_paths(libname, PHP_EXTRA_LIBS, null)) { + ADD_FLAG("LIBS" + target, libname); + have = 1; + } + } + + if (have) { + break; + } + } + +// AC_DEFINE("HAVE_" + header_name.toUpperCase().replace(new RegExp("/\\\\-\.", "g"), "_"), have); + + return have; + +} + +function CHECK_FUNC_IN_HEADER(header_name, func_name, path_to_check, add_to_flag) +{ + var c = false; + var sym; + + STDOUT.Write("Checking for " + func_name + " in " + header_name + " ... "); + + c = GREP_HEADER(header_name, func_name, path_to_check); + + sym = func_name.toUpperCase(); + sym = sym.replace(new RegExp("[\\\\/\.-]", "g"), "_"); + + if (typeof(add_to_flag) == "undefined") { + AC_DEFINE("HAVE_" + sym, c ? 1 : 0); + } else { + ADD_FLAG(add_to_flag, "/DHAVE_" + sym + "=" + (c ? "1" : "0")); + } + + if (c) { + STDOUT.WriteLine("OK"); + return c; + } + STDOUT.WriteLine("No"); + return false; +} + +function GREP_HEADER(header_name, regex, path_to_check) +{ + var c = false; + + if (FSO.FileExists(path_to_check + "\\" + header_name)) { + c = file_get_contents(path_to_check + "\\" + header_name); + } + + if (!c) { + /* look in the include path */ + + var p = search_paths(header_name, path_to_check, "INCLUDE"); + if (typeof(p) == "string") { + c = file_get_contents(p); + } else if (p == false) { + p = search_paths(header_name, PHP_EXTRA_INCLUDES, null); + if (typeof(p) == "string") { + c = file_get_contents(p); + } + } + if (!c) { + return false; + } + } + + if (typeof(regex) == "string") { + regex = new RegExp(regex); + } + + if (c.match(regex)) { + /* caller can now use RegExp.$1 etc. to get at patterns */ + return true; + } + return false; +} + +function CHECK_HEADER_ADD_INCLUDE(header_name, flag_name, path_to_check, use_env, add_dir_part, add_to_flag_only) +{ + var dir_part_to_add = ""; + + if (use_env == null) { + use_env = true; + } + + // if true, add the dir part of the header_name to the include path + if (add_dir_part == null) { + add_dir_part = false; + } else if (add_dir_part) { + var basename = FSO.GetFileName(header_name); + dir_part_to_add = "\\" + header_name.substr(0, header_name.length - basename.length - 1); + } + + if (path_to_check == null) { + path_to_check = php_usual_include_suspects; + } else { + path_to_check += ";" + php_usual_include_suspects; + } + + var p = search_paths(header_name, path_to_check, use_env ? "INCLUDE" : null); + var have = 0; + var sym; + + if (typeof(p) == "string") { + ADD_FLAG(flag_name, '/I "' + p + dir_part_to_add + '" '); + } else if (p == false) { + /* not found in the defaults or the explicit paths, + * so check the general extra includes; if we find + * it here, no need to add another /I for it as we + * already have it covered, unless we are adding + * the dir part.... */ + p = search_paths(header_name, PHP_EXTRA_INCLUDES, null); + if (typeof(p) == "string" && add_dir_part) { + ADD_FLAG(flag_name, '/I "' + p + dir_part_to_add + '" '); + } + } + have = p ? 1 : 0 + + sym = header_name.toUpperCase(); + sym = sym.replace(new RegExp("[\\\\/\.-]", "g"), "_"); + + if (typeof(add_to_flag_only) == "undefined" && + flag_name.match(new RegExp("^CFLAGS_(.*)$"))) { + add_to_flag_only = true; + } + + if (typeof(add_to_flag_only) != "undefined") { + ADD_FLAG(flag_name, "/DHAVE_" + sym + "=" + have); + } else { + AC_DEFINE("HAVE_" + sym, have, "have the " + header_name + " header file"); + } + + return p; +} + +/* emits rule to generate version info for a SAPI + * or extension. Returns the name of the .res file + * that will be generated */ +function generate_version_info_resource(makefiletarget, basename, creditspath, sapi) +{ + var resname = makefiletarget + ".res"; + var res_desc = makefiletarget; + var res_prod_name = "PHP " + makefiletarget; + var credits; + var thanks = ""; + var logo = ""; + var debug = ""; + var project_url = "http://www.php.net"; + var project_header = creditspath + "/php_" + basename + ".h"; + var versioning = ""; + + if (sapi) { + var internal_name = basename.toUpperCase() + " SAPI"; + } else { + var internal_name = basename.toUpperCase() + " extension"; + } + + if (FSO.FileExists(creditspath + '/CREDITS')) { + credits = FSO.OpenTextFile(creditspath + '/CREDITS', 1); + res_desc = credits.ReadLine(); + try { + thanks = credits.ReadLine(); + } catch (e) { + thanks = null; + } + if (thanks == null) { + thanks = ""; + } else { + thanks = "Thanks to " + thanks; + } + credits.Close(); + } + + if (creditspath.match(new RegExp("pecl"))) { + /* PECL project url - this will eventually work correctly for all */ + project_url = "http://pecl.php.net/" + basename; + + /* keep independent versioning PECL-specific for now */ + if (FSO.FileExists(project_header)) { + if (header = FSO.OpenTextFile(project_header, 1)) { + contents = header.ReadAll(); + /* allowed: x.x.x[a|b|-alpha|-beta][RCx][-dev] */ + if (contents.match(new RegExp('PHP_' + basename.toUpperCase() + '_VERSION(\\s+)"((\\d+\.\\d+(\.\\d+)?)((a|b)(\\d)?|\-[a-z]{3,5})?(RC\\d+)?(\-dev)?)'))) { + project_version = RegExp.$2; + file_version = RegExp.$3.split('.'); + if (!file_version[2]) { + file_version[2] = 0; + } + versioning = '\\"" /d EXT_FILE_VERSION=' + file_version[0] + ',' + file_version[1] + ',' + file_version[2] + ' /d EXT_VERSION="\\"' + project_version; + } + header.Close(); + } + } + } + + if (makefiletarget.match(new RegExp("\\.exe$"))) { + logo = " /d WANT_LOGO "; + } + + if (PHP_DEBUG != "no") { + debug = " /d _DEBUG"; + } + + /** + * Use user supplied template.rc if it exists + */ + if (FSO.FileExists(creditspath + '\\template.rc')) { + MFO.WriteLine("$(BUILD_DIR)\\" + resname + ": " + creditspath + "\\template.rc"); + MFO.WriteLine("\t$(RC) /fo $(BUILD_DIR)\\" + resname + logo + debug + + ' /d FILE_DESCRIPTION="\\"' + res_desc + '\\"" /d FILE_NAME="\\"' + + makefiletarget + '\\"" /d PRODUCT_NAME="\\"' + res_prod_name + + versioning + '\\"" /d THANKS_GUYS="\\"' + thanks + '\\"" ' + + creditspath + '\\template.rc'); + return resname; + } + + MFO.WriteLine("$(BUILD_DIR)\\" + resname + ": win32\\build\\template.rc"); + MFO.WriteLine("\t$(RC) /n /fo $(BUILD_DIR)\\" + resname + logo + debug + + ' /d FILE_DESCRIPTION="\\"' + res_desc + '\\"" /d FILE_NAME="\\"' + + makefiletarget + '\\"" /d URL="\\"' + project_url + + '\\"" /d INTERNAL_NAME="\\"' + internal_name + versioning + + '\\"" /d THANKS_GUYS="\\"' + thanks + '\\"" win32\\build\\template.rc'); + MFO.WriteBlankLines(1); + return resname; +} + +function SAPI(sapiname, file_list, makefiletarget, cflags, obj_dir) +{ + var SAPI = sapiname.toUpperCase(); + var ldflags; + var resname; + var ld; + var manifest; + + if (typeof(obj_dir) == "undefined") { + sapiname_for_printing = configure_module_dirname; + } else { + sapiname_for_printing = configure_module_dirname + " (via " + obj_dir + ")"; + } + + STDOUT.WriteLine("Enabling SAPI " + sapiname_for_printing); + + MFO.WriteBlankLines(1); + MFO.WriteLine("# objects for SAPI " + sapiname); + MFO.WriteBlankLines(1); + + if (cflags) { + ADD_FLAG('CFLAGS_' + SAPI, cflags); + } + + ADD_SOURCES(configure_module_dirname, file_list, sapiname, obj_dir); + MFO.WriteBlankLines(1); + MFO.WriteLine("# SAPI " + sapiname); + MFO.WriteBlankLines(1); + + /* generate a .res file containing version information */ + resname = generate_version_info_resource(makefiletarget, sapiname, configure_module_dirname, true); + + MFO.WriteLine(makefiletarget + ": $(BUILD_DIR)\\" + makefiletarget); + MFO.WriteLine("\t@echo SAPI " + sapiname_for_printing + " build complete"); + MFO.WriteLine("$(BUILD_DIR)\\" + makefiletarget + ": $(DEPS_" + SAPI + ") $(" + SAPI + "_GLOBAL_OBJS) $(BUILD_DIR)\\$(PHPLIB) $(BUILD_DIR)\\" + resname); + + if (makefiletarget.match(new RegExp("\\.dll$"))) { + ldflags = "/dll $(LDFLAGS)"; + manifest = "-@$(_VC_MANIFEST_EMBED_DLL)"; + } else if (makefiletarget.match(new RegExp("\\.lib$"))) { + ldflags = "$(LDFLAGS)"; + ld = "$(MAKE_LIB)"; + } else { + ldflags = "$(LDFLAGS)"; + manifest = "-@$(_VC_MANIFEST_EMBED_EXE)"; + } + + if (ld) { + MFO.WriteLine("\t" + ld + " /nologo /out:$(BUILD_DIR)\\" + makefiletarget + " " + ldflags + " $(" + SAPI + "_GLOBAL_OBJS) $(BUILD_DIR)\\$(PHPLIB) $(LDFLAGS_" + SAPI + ") $(LIBS_" + SAPI + ") $(BUILD_DIR)\\" + resname); + } else { + ld = "@$(CC)"; + MFO.WriteLine("\t" + ld + " /nologo " + " $(" + SAPI + "_GLOBAL_OBJS) $(BUILD_DIR)\\$(PHPLIB) $(LIBS_" + SAPI + ") $(BUILD_DIR)\\" + resname + " /link /out:$(BUILD_DIR)\\" + makefiletarget + " " + ldflags + " $(LDFLAGS_" + SAPI + ")"); + } + + if (manifest) { + MFO.WriteLine("\t" + manifest); + } + + DEFINE('CFLAGS_' + SAPI + '_OBJ', '$(CFLAGS_' + SAPI + ')'); + + if (configure_module_dirname.match("pecl")) { + ADD_FLAG("PECL_TARGETS", makefiletarget); + } else { + ADD_FLAG("SAPI_TARGETS", makefiletarget); + } + + if (PHP_DSP != "no") { + generate_dsp_file(sapiname, configure_module_dirname, file_list, false); + } + + MFO.WriteBlankLines(1); + sapi_enabled[sapi_enabled.length] = [sapiname]; +} + +function ADD_DIST_FILE(filename) +{ + if (configure_module_dirname.match("pecl")) { + ADD_FLAG("PECL_EXTRA_DIST_FILES", filename); + } else { + ADD_FLAG("PHP_EXTRA_DIST_FILES", filename); + } +} + +function file_get_contents(filename) +{ + var f, c; + try { + f = FSO.OpenTextFile(filename, 1); + c = f.ReadAll(); + f.Close(); + return c; + } catch (e) { + STDOUT.WriteLine("Problem reading " + filename); + return false; + } +} + +// Add a dependency on another extension, so that +// the dependencies are built before extname +function ADD_EXTENSION_DEP(extname, dependson, optional) +{ + var EXT = extname.toUpperCase(); + var DEP = dependson.toUpperCase(); + var dep_present = false; + var dep_shared = false; + + try { + dep_present = eval("PHP_" + DEP); + + if (dep_present != "no") { + try { + dep_shared = eval("PHP_" + DEP + "_SHARED"); + } catch (e) { + dep_shared = false; + } + } + + } catch (e) { + dep_present = "no"; + } + + if (optional) { + if (dep_present == "no") { + MESSAGE("\t" + dependson + " not found: " + dependson + " support in " + extname + " disabled"); + return false; + } + } + + var ext_shared = eval("PHP_" + EXT + "_SHARED"); + + if (dep_shared) { + if (!ext_shared) { + if (optional) { + MESSAGE("\tstatic " + extname + " cannot depend on shared " + dependson + ": " + dependson + "support disabled"); + return false; + } + ERROR("static " + extname + " cannot depend on shared " + dependson); + } + + ADD_FLAG("LDFLAGS_" + EXT, "/libpath:$(BUILD_DIR)"); + ADD_FLAG("LIBS_" + EXT, "php_" + dependson + ".lib"); + ADD_FLAG("DEPS_" + EXT, "$(BUILD_DIR)\\php_" + dependson + ".lib"); + + } else { + + if (dep_present == "no") { + if (ext_shared) { + WARNING(extname + " cannot be built: missing dependency, " + dependson + " not found"); + + var dllname = ' php_' + extname + '.dll'; + + if (!REMOVE_TARGET(dllname, 'EXT_TARGETS')) { + REMOVE_TARGET(dllname, 'PECL_TARGETS'); + } + + return false; + + } + + ERROR("Cannot build " + extname + "; " + dependson + " not enabled"); + return false; + } + } // dependency is statically built-in to PHP + return true; +} + +function EXTENSION(extname, file_list, shared, cflags, dllname, obj_dir) +{ + var objs = null; + var EXT = extname.toUpperCase(); + var extname_for_printing; + + if (shared == null) { + eval("shared = PHP_" + EXT + "_SHARED;"); + } else { + eval("PHP_" + EXT + "_SHARED = shared;"); + } + + if (cflags == null) { + cflags = ""; + } + + if (typeof(obj_dir) == "undefined") { + extname_for_printing = configure_module_dirname; + } else { + extname_for_printing = configure_module_dirname + " (via " + obj_dir + ")"; + } + + if (shared) { + STDOUT.WriteLine("Enabling extension " + extname_for_printing + " [shared]"); + cflags = "/D COMPILE_DL_" + EXT + " /D " + EXT + "_EXPORTS=1 " + cflags; + ADD_FLAG("CFLAGS_PHP", "/D COMPILE_DL_" + EXT); + } else { + STDOUT.WriteLine("Enabling extension " + extname_for_printing); + } + + MFO.WriteBlankLines(1); + MFO.WriteLine("# objects for EXT " + extname); + MFO.WriteBlankLines(1); + + + ADD_SOURCES(configure_module_dirname, file_list, extname, obj_dir); + + MFO.WriteBlankLines(1); + + if (shared) { + if (dllname == null) { + dllname = "php_" + extname + ".dll"; + } + var libname = dllname.substring(0, dllname.length-4) + ".lib"; + + var resname = generate_version_info_resource(dllname, extname, configure_module_dirname, false); + var ld = "@$(CC)"; + + MFO.WriteLine("$(BUILD_DIR)\\" + libname + ": $(BUILD_DIR)\\" + dllname); + MFO.WriteBlankLines(1); + MFO.WriteLine("$(BUILD_DIR)\\" + dllname + ": $(DEPS_" + EXT + ") $(" + EXT + "_GLOBAL_OBJS) $(BUILD_DIR)\\$(PHPLIB) $(BUILD_DIR)\\" + resname); + MFO.WriteLine("\t" + ld + " $(" + EXT + "_GLOBAL_OBJS) $(BUILD_DIR)\\$(PHPLIB) $(LIBS_" + EXT + ") $(LIBS) $(BUILD_DIR)\\" + resname + " /link /out:$(BUILD_DIR)\\" + dllname + " $(DLL_LDFLAGS) $(LDFLAGS) $(LDFLAGS_" + EXT + ")"); + MFO.WriteLine("\t-@$(_VC_MANIFEST_EMBED_DLL)"); + MFO.WriteBlankLines(1); + + if (configure_module_dirname.match("pecl")) { + ADD_FLAG("PECL_TARGETS", dllname); + } else { + ADD_FLAG("EXT_TARGETS", dllname); + } + MFO.WriteLine(dllname + ": $(BUILD_DIR)\\" + dllname); + MFO.WriteLine("\t@echo EXT " + extname + " build complete"); + MFO.WriteBlankLines(1); + + DEFINE('CFLAGS_' + EXT + '_OBJ', '$(CFLAGS_' + EXT + ')'); + } else { + ADD_FLAG("STATIC_EXT_OBJS", "$(" + EXT + "_GLOBAL_OBJS)"); + ADD_FLAG("STATIC_EXT_LIBS", "$(LIBS_" + EXT + ")"); + ADD_FLAG("STATIC_EXT_LDFLAGS", "$(LDFLAGS_" + EXT + ")"); + ADD_FLAG("STATIC_EXT_CFLAGS", "$(CFLAGS_" + EXT + ")"); + + /* find the header that declares the module pointer, + * so we can include it in internal_functions.c */ + var ext_dir = FSO.GetFolder(configure_module_dirname); + var fc = new Enumerator(ext_dir.Files); + var re = /\.h$/; + var s, c; + for (; !fc.atEnd(); fc.moveNext()) { + s = fc.item() + ""; + if (s.match(re)) { + c = file_get_contents(s); + if (c.match("phpext_")) { + extension_include_code += '#include "' + configure_module_dirname + '/' + FSO.GetFileName(s) + '"\r\n'; + } + } + } + + extension_module_ptrs += '\tphpext_' + extname + '_ptr,\r\n'; + + DEFINE('CFLAGS_' + EXT + '_OBJ', '$(CFLAGS_PHP) $(CFLAGS_' + EXT + ')'); + } + ADD_FLAG("CFLAGS_" + EXT, cflags); + + if (PHP_DSP != "no") { + generate_dsp_file(extname, configure_module_dirname, file_list, shared); + } + + extensions_enabled[extensions_enabled.length] = [extname, shared ? 'shared' : 'static']; +} + +function ADD_SOURCES(dir, file_list, target, obj_dir) +{ + var i; + var tv; + var src, obj, sym, flags; + + if (target == null) { + target = "php"; + } + + sym = target.toUpperCase() + "_GLOBAL_OBJS"; + flags = "CFLAGS_" + target.toUpperCase() + '_OBJ'; + + if (configure_subst.Exists(sym)) { + tv = configure_subst.Item(sym); + } else { + tv = ""; + } + + file_list = file_list.split(new RegExp("\\s+")); + file_list.sort(); + + var re = new RegExp("\.[a-z0-9A-Z]+$"); + + dir = dir.replace(new RegExp("/", "g"), "\\"); + var objs_line = ""; + var srcs_line = ""; + + var sub_build = "$(BUILD_DIR)\\"; + + /* if module dir is not a child of the main source dir, + * we need to tweak it; we should have detected such a + * case in condense_path and rewritten the path to + * be relative. + * This probably breaks for non-sibling dirs, but that + * is not a problem as buildconf only checks for pecl + * as either a child or a sibling */ + if (obj_dir == null) { + var build_dir = dir.replace(new RegExp("^..\\\\"), ""); + var mangle_dir = build_dir.replace(new RegExp("[\\\\/.-]", "g"), "_"); + var bd_flags_name = "CFLAGS_BD_" + mangle_dir.toUpperCase(); + } + else { + var build_dir = obj_dir.replace(new RegExp("^..\\\\"), ""); + var mangle_dir = build_dir.replace(new RegExp("[\\\\/.-]", "g"), "_"); + var bd_flags_name = "CFLAGS_BD_" + mangle_dir.toUpperCase(); + } + + var dirs = build_dir.split("\\"); + var i, d = ""; + for (i = 0; i < dirs.length; i++) { + d += dirs[i]; + build_dirs[build_dirs.length] = d; + d += "\\"; + } + sub_build += d; + + + DEFINE(bd_flags_name, " /Fd" + sub_build + " /Fp" + sub_build + " /FR" + sub_build + " "); + + for (i in file_list) { + src = file_list[i]; + obj = src.replace(re, ".obj"); + tv += " " + sub_build + obj; + + if (PHP_ONE_SHOT == "yes") { + if (i > 0) { + objs_line += " " + sub_build + obj; + srcs_line += " " + dir + "\\" + src; + } else { + objs_line = sub_build + obj; + srcs_line = dir + "\\" + src; + } + } else { + MFO.WriteLine(sub_build + obj + ": " + dir + "\\" + src); + MFO.WriteLine("\t@$(CC) $(" + flags + ") $(CFLAGS) $(" + bd_flags_name + ") /c " + dir + "\\" + src + " /Fo" + sub_build + obj); + } + } + + if (PHP_ONE_SHOT == "yes") { + MFO.WriteLine(objs_line + ": " + srcs_line); + MFO.WriteLine("\t$(CC) $(" + flags + ") $(CFLAGS) /Fo" + sub_build + " $(" + bd_flags_name + ") /c " + srcs_line); + } + + DEFINE(sym, tv); +} + +function REMOVE_TARGET(dllname, flag) +{ + var dllname = dllname.replace(/\s/g, ""); + var EXT = dllname.replace(/php_(\S+)\.dll/, "$1").toUpperCase(); + var php_flags = configure_subst.Item("CFLAGS_PHP"); + + if (configure_subst.Exists(flag)) { + var targets = configure_subst.Item(flag); + + if (targets.match(dllname)) { + configure_subst.Remove(flag); + targets = targets.replace(dllname, ""); + targets = targets.replace(/\s+/, " "); + targets = targets.replace(/\s$/, ""); + configure_subst.Add(flag, targets); + configure_hdr.Add("HAVE_" + EXT, new Array(0, "")); + configure_subst.Item("CFLAGS_PHP") = php_flags.replace(" /D COMPILE_DL_" + EXT, ""); + extensions_enabled.pop(); + return true; + } + } + return false; +} + +function generate_internal_functions() +{ + var infile, outfile; + var indata; + + STDOUT.WriteLine("Generating main/internal_functions.c"); + + infile = FSO.OpenTextFile("main/internal_functions.c.in", 1); + indata = infile.ReadAll(); + infile.Close(); + + indata = indata.replace("@EXT_INCLUDE_CODE@", extension_include_code); + indata = indata.replace("@EXT_MODULE_PTRS@", extension_module_ptrs); + + if (FSO.FileExists("main/internal_functions.c")) { + var origdata = file_get_contents("main/internal_functions.c"); + + if (origdata == indata) { + STDOUT.WriteLine("\t[content unchanged; skipping]"); + return; + } + } + + outfile = FSO.CreateTextFile("main/internal_functions.c", true); + outfile.Write(indata); + outfile.Close(); +} + +function output_as_table(header, ar_out) +{ + var l = header.length; + var cols = 80; + var fixedlenght = ""; + var t = 0; + var i,j,k,m; + var out = "| "; + var min = new Array(l); + var max = new Array(l); + + if (l != ar_out[0].length) { + STDOUT.WriteLine("Invalid header argument, can't output the table " + l + " " + ar_out[0].length ); + return; + } + + for (j=0; j < l; j++) { + var tmax, tmin; + + /*Figure out the max length per column */ + tmin = 0; + tmax = 0; + for (k = 0; k < ar_out.length; k++) { + var t = ar_out[k][j].length; + if (t > tmax) tmax = t; + else if (t < tmin) tmin = t; + } + if (tmax > header[j].length) { + max[j] = tmax; + } else { + max[j] = header[j].length; + } + if (tmin < header[j].length) { + min[j] = header[j].length; + } + } + + sep = ""; + k = 0; + for (i = 0; i < l; i++) { + k += max[i] + 3; + } + k++; + + for (j=0; j < k; j++) { + sep += "-"; + } + + STDOUT.WriteLine(sep); + out = "|"; + for (j=0; j < l; j++) { + out += " " + header[j]; + for (var i = 0; i < (max[j] - header[j].length); i++){ + out += " "; + } + out += " |"; + } + STDOUT.WriteLine(out); + + STDOUT.WriteLine(sep); + + out = "|"; + for (i=0; i < ar_out.length; i++) { + line = ar_out[i]; + for (j=0; j < l; j++) { + out += " " + line[j]; + for (var k = 0; k < (max[j] - line[j].length); k++){ + out += " "; + } + out += " |"; + } + STDOUT.WriteLine(out); + out = "|"; + } + + STDOUT.WriteLine(sep); +} + +function write_summary() +{ + var ar = new Array(); + + STDOUT.WriteBlankLines(2); + + STDOUT.WriteLine("Enabled extensions:"); + output_as_table(["Extension", "Mode"], extensions_enabled.sort()); + STDOUT.WriteBlankLines(2); + + STDOUT.WriteLine("Enabled SAPI:"); + output_as_table(["Sapi Name"], sapi_enabled); + STDOUT.WriteBlankLines(2); + + ar[0] = ['Build type', PHP_DEBUG == "yes" ? "Debug" : "Release"]; + ar[1] = ['Thread Safety', PHP_ZTS == "yes" ? "Yes" : "No"]; + ar[2] = ['Compiler', VC_VERSIONS[VCVERS]]; + ar[3] = ['Architecture', X64 ? 'x64' : 'x86']; + + output_as_table(["",""], ar); + STDOUT.WriteBlankLines(2); +} + +function generate_files() +{ + var i, dir, bd, last; + + STDOUT.WriteBlankLines(1); + STDOUT.WriteLine("Creating build dirs..."); + dir = get_define("BUILD_DIR"); + build_dirs.sort(); + last = null; + + if (!FSO.FolderExists(dir)) { + FSO.CreateFolder(dir); + } + + for (i = 0; i < build_dirs.length; i++) { + bd = FSO.BuildPath(dir, build_dirs[i]); + if (bd == last) { + continue; + } + last = bd; + ADD_FLAG("BUILD_DIRS_SUB", bd.replace(new RegExp('^'+dir+'\\\\'), '$(BUILD_DIR)\\')); + if (!FSO.FolderExists(bd)) { + FSO.CreateFolder(bd); + } + } + + if (PHP_DSP != "no") { + generate_dsp_file("TSRM", "TSRM", null, false); + generate_dsp_file("Zend", "Zend", null, false); + generate_dsp_file("win32", "win32", null, false); + generate_dsp_file("main", "main", null, false); + generate_dsp_file("streams", "main\\streams", null, false); + copy_dsp_files(); + } + + STDOUT.WriteLine("Generating files..."); + generate_makefile(); + generate_internal_functions(); + generate_config_h(); + + STDOUT.WriteLine("Done."); + STDOUT.WriteBlankLines(1); + write_summary(); + + if (PHP_SNAPSHOT_BUILD != "no") { + STDOUT.WriteLine("Type 'nmake snap' to build a PHP snapshot"); + } else { + STDOUT.WriteLine("Type 'nmake' to build PHP"); + } +} + +function generate_config_h() +{ + var infile, outfile; + var indata; + var prefix; + + prefix = PHP_PREFIX.replace(new RegExp("\\\\", "g"), "\\\\"); + + STDOUT.WriteLine("Generating main/config.w32.h"); + + infile = FSO.OpenTextFile("win32/build/config.w32.h.in", 1); + indata = infile.ReadAll(); + infile.Close(); + + outfile = FSO.CreateTextFile("main/config.w32.h", true); + + indata = indata.replace(new RegExp("@PREFIX@", "g"), prefix); + outfile.Write(indata); + + var keys = (new VBArray(configure_hdr.Keys())).toArray(); + var i, j; + var item; + var pieces, stuff_to_crack, chunk; + + outfile.WriteBlankLines(1); + outfile.WriteLine("/* values determined by configure.js */"); + + for (i in keys) { + item = configure_hdr.Item(keys[i]); + outfile.WriteBlankLines(1); + pieces = item[0]; + + if (item[1] != undefined) { + outfile.WriteLine("/* " + item[1] + " */"); + } + + if (typeof(pieces) == "string" && pieces.charCodeAt(0) == 34) { + /* quoted string have a maximal length of 2k under vc. + * solution is to crack them and let the compiler concat + * them implicitly */ + stuff_to_crack = pieces; + pieces = ""; + + while (stuff_to_crack.length) { + j = 65; + while (stuff_to_crack.charCodeAt(j) != 32 && j < stuff_to_crack.length) + j++; + + chunk = stuff_to_crack.substr(0, j); + pieces += chunk; + stuff_to_crack = stuff_to_crack.substr(chunk.length); + if (stuff_to_crack.length) + pieces += '" "'; + } + } + + outfile.WriteLine("#define " + keys[i] + " " + pieces); + } + + outfile.Close(); +} + +function generate_makefile() +{ + STDOUT.WriteLine("Generating Makefile"); + var MF = FSO.CreateTextFile("Makefile", true); + + MF.WriteLine("# Generated by configure.js"); + + /* spit out variable definitions */ + var keys = (new VBArray(configure_subst.Keys())).toArray(); + var i; + + for (i in keys) { + // The trailing space is needed to prevent the trailing backslash + // that is part of the build dir flags (CFLAGS_BD_XXX) from being + // seen as a line continuation character + MF.WriteLine(keys[i] + "=" + + //word_wrap_and_indent(1, configure_subst.Item(keys[i]), ' \\', '\t') + " " + configure_subst.Item(keys[i]) + " " + ); + MF.WriteBlankLines(1); + } + + MF.WriteBlankLines(1); + + var TF = FSO.OpenTextFile("win32/build/Makefile", 1); + MF.Write(TF.ReadAll()); + TF.Close(); + + MF.WriteBlankLines(2); + + MFO.Close(); + TF = FSO.OpenTextFile("Makefile.objects", 1); + MF.Write(TF.ReadAll()); + TF.Close(); + + MF.Close(); +} + +function ADD_FLAG(name, flags, target) +{ + if (target != null) { + name = target.toUpperCase() + "_" + name; + } + if (configure_subst.Exists(name)) { + var curr_flags = configure_subst.Item(name); + + if (curr_flags.indexOf(flags) >= 0) { + return; + } + + flags = curr_flags + " " + flags; + configure_subst.Remove(name); + } + configure_subst.Add(name, flags); + + if (PHP_DSP != "no") { + if (flags && (name.substr(name.length-3) != "PHP") && (name.substr(0, 7) == "CFLAGS_")) { + DSP_FLAGS[DSP_FLAGS.length] = new Array(name, flags); + } + } +} + +function get_define(name) +{ + if (configure_subst.Exists(name)) { + return configure_subst.Item(name); + } + return ""; +} + +// Add a .def to the core to export symbols +function ADD_DEF_FILE(name) +{ + if (!configure_subst.Exists("PHPDEF")) { + DEFINE("PHPDEF", "$(BUILD_DIR)\\$(PHPDLL).def"); + ADD_FLAG("PHP_LDFLAGS", "/def:$(PHPDEF)"); + } + ADD_FLAG("PHP_DLL_DEF_SOURCES", name); +} + +function AC_DEFINE(name, value, comment, quote) +{ + if (quote == null) { + quote = true; + } + if (quote && typeof(value) == "string") { + value = '"' + value.replace(new RegExp('(["\\\\])', "g"), '\\$1') + '"'; + } else if (value.length == 0) { + value = '""'; + } + var item = new Array(value, comment); + if (configure_hdr.Exists(name)) { + var orig_item = configure_hdr.Item(name); + STDOUT.WriteLine("AC_DEFINE[" + name + "]=" + value + ": is already defined to " + orig_item[0]); + } else { + configure_hdr.Add(name, item); + } +} + +function MESSAGE(msg) +{ + STDOUT.WriteLine("" + msg); +} + +function ERROR(msg) +{ + STDERR.WriteLine("ERROR: " + msg); + WScript.Quit(3); +} + +function WARNING(msg) +{ + STDERR.WriteLine("WARNING: " + msg); + STDERR.WriteBlankLines(1); +} + +function copy_and_subst(srcname, destname, subst_array) +{ + if (!FSO.FileExists(srcname)) { + srcname = configure_module_dirname + "\\" + srcname; + destname = configure_module_dirname + "\\" + destname; + } + + var content = file_get_contents(srcname); + var i; + + for (i = 0; i < subst_array.length; i+=2) { + var re = subst_array[i]; + var rep = subst_array[i+1]; + + content = content.replace(re, rep); + } + + var f = FSO.CreateTextFile(destname, true); + f.Write(content); + f.Close(); +} + +// glob using simple filename wildcards +// returns an array of matches that are found +// in the filesystem +function glob(path_pattern) +{ + var path_parts = path_pattern.replace(new RegExp("/", "g"), "\\").split("\\"); + var p; + var base = ""; + var is_pat_re = /\*/; + +//STDOUT.WriteLine("glob: " + path_pattern); + + if (FSO.FileExists(path_pattern)) { + return new Array(path_pattern); + } + + // first, build as much as possible that doesn't have a pattern + for (p = 0; p < path_parts.length; p++) { + if (path_parts[p].match(is_pat_re)) + break; + if (p) + base += "\\"; + base += path_parts[p]; + } + + return _inner_glob(base, p, path_parts); +} + +function _inner_glob(base, p, parts) +{ + var pat = parts[p]; + var full_name = base + "\\" + pat; + var re = null; + var items = null; + + if (p == parts.length) { + return false; + } + +//STDOUT.WriteLine("inner: base=" + base + " p=" + p + " pat=" + pat); + + if (FSO.FileExists(full_name)) { + if (p < parts.length - 1) { + // we didn't reach the full extent of the pattern + return false; + } + return new Array(full_name); + } + + if (FSO.FolderExists(full_name) && p == parts.length - 1) { + // we have reached the end of the pattern; no need to recurse + return new Array(full_name); + } + + // Convert the pattern into a regexp + re = new RegExp("^" + pat.replace(/\./g, '\\.').replace(/\*/g, '.*').replace(/\?/g, '.') + "$", "i"); + + items = new Array(); + + if (!FSO.FolderExists(base)) { + return false; + } + + var folder = FSO.GetFolder(base); + var fc = null; + var subitems = null; + var item_name = null; + var j; + + fc = new Enumerator(folder.SubFolders); + for (; !fc.atEnd(); fc.moveNext()) { + item_name = FSO.GetFileName(fc.item()); + + if (item_name.match(re)) { + // got a match; if we are at the end of the pattern, just add these + // things to the items array + if (p == parts.length - 1) { + items[items.length] = fc.item(); + } else { + // we should recurse and do more matches + subitems = _inner_glob(base + "\\" + item_name, p + 1, parts); + if (subitems) { + for (j = 0; j < subitems.length; j++) { + items[items.length] = subitems[j]; + } + } + } + } + } + + // if we are at the end of the pattern, we should match + // files too + if (p == parts.length - 1) { + fc = new Enumerator(folder.Files); + for (; !fc.atEnd(); fc.moveNext()) { + item_name = FSO.GetFileName(fc.item()); + if (item_name.match(re)) { + items[items.length] = fc.item(); + } + } + } + + if (items.length == 0) + return false; + + return items; +} + + +// for snapshot builders, this option will attempt to enable everything +// and you can then build everything, ignoring fatal errors within a module +// by running "nmake snap" +PHP_SNAPSHOT_BUILD = "no"; +ARG_ENABLE('snapshot-build', 'Build a snapshot; turns on everything it can and ignores build errors', 'no'); + +// one-shot build optimizes build by asking compiler to build +// several objects at once, reducing overhead of starting new +// compiler processes. +ARG_ENABLE('one-shot', 'Optimize for fast build - best for release and snapshot builders, not so hot for edit-and-rebuild hacking', 'no'); + + diff --git a/win32/build/cvsclean.js b/win32/build/cvsclean.js index c654bbc6a..c5f92a388 100644 --- a/win32/build/cvsclean.js +++ b/win32/build/cvsclean.js @@ -2,7 +2,7 @@ +----------------------------------------------------------------------+ | PHP Version 5 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2008 The PHP Group | + | Copyright (c) 1997-2009 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -13,32 +13,39 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Author: Wez Furlong | + | Pierre A. Joye | +----------------------------------------------------------------------+ */ -/* $Id: cvsclean.js,v 1.5.2.1.2.1.2.1 2008/07/20 02:20:31 sfox Exp $ */ -// Cleans up files that do not belong in CVS +/* $Id$ */ +// Cleans up files that do not belong in the repository var FSO = WScript.CreateObject("Scripting.FileSystemObject"); +var WshShell = WScript.CreateObject("WScript.Shell"); +var STDOUT = WScript.StdOut; -function find_cvsignore(dirname) +/* svn propget svn:ignore dirname */ +function find_ignore(dirname) { - if (!FSO.FolderExists(dirname)) + dirname = "" + dirname; + dirname_len = dirname.length; + + if (!FSO.FolderExists(dirname) || (dirname_len >= 4 && + dirname.substring(dirname_len - 4) == ".svn")) { return; + } var f = FSO.GetFolder(dirname); var fc = new Enumerator(f.SubFolders); - + for (; !fc.atEnd(); fc.moveNext()) { - find_cvsignore(fc.item()); + find_ignore(fc.item()); } - if (FSO.FileExists(dirname + "\\.cvsignore")) { - kill_from_cvsignore(dirname + "\\.cvsignore"); - } + kill_from_ignore(dirname); } -/* recursive remove using cvsignore style wildcard matching; +/* recursive remove using ignore props style wildcard matching; * note that FSO.DeleteFolder and FSO.DeleteFile methods both * accept wildcards, but that they are dangerous to use eg: * "*.php" will match "*.phpt" */ @@ -66,7 +73,7 @@ function rm_r(filename) if (foldername == "") foldername = "."; - + var filename = FSO.GetFileName(filename); var retext = filename.replace(/\./g, '\\.'); @@ -94,27 +101,20 @@ function rm_r(filename) } } -function kill_from_cvsignore(igfile) +function kill_from_ignore(dirname) { - var dir = FSO.GetParentFolderName(igfile) + "\\"; - var t = FSO.OpenTextFile(igfile, 1); var l; - - if (dir == ".\\") { - dir = ""; - } - - while (!t.atEndOfStream) { - l = t.ReadLine(); - // don't kill their config.nice file(s) - if (l.match("config\.nice.*") || - l.match("") || - l.match("*")) + var e = WshShell.Exec("svn propget svn:ignore " + dirname); + var re = /^(config\.nice.*)|(\*)$/i; + + while (!e.StdOut.atEndOfStream) { + l = e.StdOut.ReadLine(); + if (l.length == 0 || re.test(l)) { continue; - rm_r(dir + l); + } + rm_r(dirname + l); } } -find_cvsignore("."); - +find_ignore("."); diff --git a/win32/build/deplister.c b/win32/build/deplister.c index 6d90aa49c..f6f1ce5ad 100644 --- a/win32/build/deplister.c +++ b/win32/build/deplister.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: deplister.c,v 1.3.2.1.2.1.2.2 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: deplister.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* This little application will list the DLL dependencies for a PE * module to it's stdout for use by distro/installer building tools */ diff --git a/win32/build/mkdist.php b/win32/build/mkdist.php index 37b46b305..7e3eeee6e 100644 --- a/win32/build/mkdist.php +++ b/win32/build/mkdist.php @@ -1,12 +1,13 @@ - $dest) { } /* include a snapshot identifier */ -$branch = "HEAD"; // TODO - determine this from CVS/Entries +$branch = "HEAD"; // TODO - determine this from SVN branche name $fp = fopen("$dist_dir/snapshot.txt", "w"); $now = date("r"); $version = phpversion(); @@ -295,7 +297,7 @@ foreach ($extra_dll_deps as $dll) { /* try template dir */ $tdll = $snapshot_template . "/dlls/" . basename($dll); if (!file_exists($tdll)) { - $tdll = '../deps/bin/' . basename($dll); + $tdll = $php_build_dir . '/bin/' . basename($dll); if (!file_exists($tdll)) { echo "WARNING: distro depends on $dll, but could not find it on your system\n"; continue; @@ -309,11 +311,23 @@ foreach ($extra_dll_deps as $dll) { /* TODO: add sanity check and test if all required DLLs are present, per version This version works at least for 3.6, 3.8 and 4.0 (5.3-vc6, 5.3-vc9 and HEAD). +Add ADD_DLLS to add extra DLLs like dynamic dependencies for standard +deps. For example, libenchant.dll loads libenchant_myspell.dll or +libenchant_ispell.dll */ -$ICU_DLLS = '../deps/bin/' . 'icu*.dll'; +$ICU_DLLS = $php_build_dir . '/bin/icu*.dll'; foreach (glob($ICU_DLLS) as $filename) { copy($filename, "$dist_dir/" . basename($filename)); } +$ENCHANT_DLLS = array( + 'glib-2.dll', + 'gmodule-2.dll', + 'libenchant_myspell.dll', + 'libenchant_ispell.dll', +); +foreach ($ENCHANT_DLLS as $filename) { + copy($php_build_dir . '/bin/' . $filename, "$dist_dir/" . basename($filename)); +} /* and those for pecl */ foreach ($pecl_dll_deps as $dll) { @@ -332,6 +346,7 @@ foreach ($pecl_dll_deps as $dll) { } copy($dll, "$pecl_dir/" . basename($dll)); } + function copy_dir($source, $dest) { if (!is_dir($dest)) { @@ -342,7 +357,7 @@ function copy_dir($source, $dest) $d = opendir($source); while (($f = readdir($d)) !== false) { - if ($f == '.' || $f == '..' || $f == 'CVS' || $f == '.cvsignore') { + if ($f == '.' || $f == '..' || $f == '.svn') { continue; } $fs = $source . '/' . $f; @@ -365,7 +380,9 @@ function copy_test_dir($directory, $dest) } if ($directory == 'tests') { - mkdir($dest . '/tests', 0775, true); + if (!is_dir($dest . '/tests')) { + mkdir($dest . '/tests', 0775, true); + } copy_dir($directory, $dest . '/tests/'); return false; @@ -380,7 +397,7 @@ function copy_test_dir($directory, $dest) while (FALSE !== ($file = readdir($directory_list))) { $full_path = $directory . '/' . $file; - if($file != '.' && $file != '..' && $file != 'CVS' && is_dir($full_path)) { + if($file != '.' && $file != '..' && $file != '.svn' && is_dir($full_path)) { if ($file == 'tests') { if (!is_dir($dest . '/' . $full_path)) { mkdir($dest . '/' . $full_path , 0775, true); @@ -439,6 +456,7 @@ $dirs = array( foreach ($dirs as $dir) { copy_test_dir($dir, $test_dir); } + /* change this next line to true to use good-old * hand-assembled go-pear-bundle from the snapshot template */ $use_pear_template = true; diff --git a/win32/build/svnclean.js b/win32/build/svnclean.js new file mode 100644 index 000000000..c5f92a388 --- /dev/null +++ b/win32/build/svnclean.js @@ -0,0 +1,120 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2009 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.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: Wez Furlong | + | Pierre A. Joye | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ +// Cleans up files that do not belong in the repository + +var FSO = WScript.CreateObject("Scripting.FileSystemObject"); +var WshShell = WScript.CreateObject("WScript.Shell"); +var STDOUT = WScript.StdOut; + +/* svn propget svn:ignore dirname */ +function find_ignore(dirname) +{ + dirname = "" + dirname; + dirname_len = dirname.length; + + if (!FSO.FolderExists(dirname) || (dirname_len >= 4 && + dirname.substring(dirname_len - 4) == ".svn")) { + return; + } + + var f = FSO.GetFolder(dirname); + var fc = new Enumerator(f.SubFolders); + + for (; !fc.atEnd(); fc.moveNext()) { + find_ignore(fc.item()); + } + + kill_from_ignore(dirname); +} + +/* recursive remove using ignore props style wildcard matching; + * note that FSO.DeleteFolder and FSO.DeleteFile methods both + * accept wildcards, but that they are dangerous to use eg: + * "*.php" will match "*.phpt" */ +function rm_r(filename) +{ + if (FSO.FolderExists(filename)) { + var fc = new Enumerator(FSO.GetFolder(filename).SubFolders); + + for (; !fc.atEnd(); fc.moveNext()) { + rm_r(fc.item()); + } + + fc = new Enumerator(FSO.GetFolder(filename).Files); + + for (; !fc.atEnd(); fc.moveNext()) { + FSO.DeleteFile(fc.item(), true); + } + + FSO.DeleteFolder(filename, true); + } else if (FSO.FileExists(filename)) { + FSO.DeleteFile(filename, true); + } else { + /* we need to handle wildcards here */ + var foldername = FSO.GetParentFolderName(filename); + + if (foldername == "") + foldername = "."; + + var filename = FSO.GetFileName(filename); + + var retext = filename.replace(/\./g, '\\.'); + retext = '^' + retext.replace(/\*/g, '.*') + "$"; + var re = new RegExp(retext); + + var folder = FSO.GetFolder(foldername); + var fc = new Enumerator(folder.SubFolders); + for (; !fc.atEnd(); fc.moveNext()) { + + var item = FSO.GetFileName(fc.item()); + + if (item.match(re)) { + rm_r(fc.item()); + } + } + var fc = new Enumerator(folder.Files); + for (; !fc.atEnd(); fc.moveNext()) { + item = FSO.GetFileName(fc.item()); + + if (item.match(re)) { + FSO.DeleteFile(fc.item(), true); + } + } + } +} + +function kill_from_ignore(dirname) +{ + var l; + var e = WshShell.Exec("svn propget svn:ignore " + dirname); + var re = /^(config\.nice.*)|(\*)$/i; + + while (!e.StdOut.atEndOfStream) { + l = e.StdOut.ReadLine(); + if (l.length == 0 || re.test(l)) { + continue; + } + rm_r(dirname + l); + } + +} + +find_ignore("."); diff --git a/win32/build/template.dsw b/win32/build/template.dsw index a627d028d..ac781664f 100644 --- a/win32/build/template.dsw +++ b/win32/build/template.dsw @@ -1,63 +1,63 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "TSRM"=..\TSRM\TSRM.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "Zend"=..\Zend\Zend.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name TSRM - End Project Dependency -}}} - -############################################################################### - -Project: "php5ts"=..\win32\php5ts.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name TSRM - End Project Dependency - Begin Project Dependency - Project_Dep_Name Zend - End Project Dependency -}}} - -############################################################################### -INSERT - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "TSRM"=..\TSRM\TSRM.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "Zend"=..\Zend\Zend.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name TSRM + End Project Dependency +}}} + +############################################################################### + +Project: "php5ts"=..\win32\php5ts.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name TSRM + End Project Dependency + Begin Project Dependency + Project_Dep_Name Zend + End Project Dependency +}}} + +############################################################################### +INSERT + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/win32/build/template.rc b/win32/build/template.rc index 40160ac6f..98c2bcb4f 100644 --- a/win32/build/template.rc +++ b/win32/build/template.rc @@ -1,5 +1,5 @@ /* This is a template RC file. - * $Id: template.rc,v 1.7.2.2.2.1.2.3 2009/06/03 01:14:58 kalle Exp $ + * $Id: template.rc 281570 2009-06-03 01:14:58Z kalle $ * Do not edit with MSVC */ #ifdef APSTUDIO_INVOKED # error dont edit with MSVC diff --git a/win32/builddef.bat b/win32/builddef.bat index 09c1adc8e..f204812ac 100644 --- a/win32/builddef.bat +++ b/win32/builddef.bat @@ -2,6 +2,6 @@ rem Generate phpts.def file, which exports symbols from our dll that rem are present in some of the libraries which are compiled statically rem into PHP -rem $Id: builddef.bat,v 1.4 2003/12/08 12:56:47 rrichards Exp $ +rem $Id: builddef.bat,v 1.4 2003-12-08 12:56:47 rrichards Exp $ type ..\ext\sqlite\php_sqlite.def type ..\ext\libxml\php_libxml2.def diff --git a/win32/fnmatch.c b/win32/fnmatch.c index 4d3bc3486..568d5843b 100644 --- a/win32/fnmatch.c +++ b/win32/fnmatch.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. * * From FreeBSD fnmatch.c 1.11 - * $Id: fnmatch.c,v 1.1.2.2 2009/01/20 01:37:48 pajoye Exp $ + * $Id: fnmatch.c 273994 2009-01-20 01:37:48Z pajoye $ */ #if defined(LIBC_SCCS) && !defined(lint) diff --git a/win32/fnmatch.h b/win32/fnmatch.h index 1e13c3b49..530c7c09f 100644 --- a/win32/fnmatch.h +++ b/win32/fnmatch.h @@ -33,7 +33,7 @@ * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93 * * From FreeBSD fnmatch.h 1.7 - * $Id: fnmatch.h,v 1.1.2.2 2009/01/20 01:37:48 pajoye Exp $ + * $Id: fnmatch.h 273994 2009-01-20 01:37:48Z pajoye $ */ #ifndef _FNMATCH_H_ diff --git a/win32/glob.c b/win32/glob.c index f4c469990..0d290c667 100644 --- a/win32/glob.c +++ b/win32/glob.c @@ -34,7 +34,7 @@ * SUCH DAMAGE. */ -/* $Id: glob.c,v 1.6.6.1.2.1 2009/01/01 12:32:48 pajoye Exp $ */ +/* $Id: glob.c 272473 2009-01-01 12:32:49Z pajoye $ */ /* * glob(3) -- a superset of the one defined in POSIX 1003.2. diff --git a/win32/glob.h b/win32/glob.h index 8dc146470..8548eec25 100644 --- a/win32/glob.h +++ b/win32/glob.h @@ -1,4 +1,4 @@ -/* $Id: glob.h,v 1.1.24.2 2009/01/01 12:32:49 pajoye Exp $ */ +/* $Id: glob.h 272473 2009-01-01 12:32:49Z pajoye $ */ /* OpenBSD: glob.h,v 1.7 2002/02/17 19:42:21 millert Exp */ /* NetBSD: glob.h,v 1.5 1994/10/26 00:55:56 cgd Exp */ diff --git a/win32/globals.c b/win32/globals.c index 741d7ed41..f14380aeb 100755 --- a/win32/globals.c +++ b/win32/globals.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: globals.c,v 1.5.2.1.2.3.2.2 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: globals.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" #include "php_win32_globals.h" diff --git a/win32/grp.h b/win32/grp.h index 520a5b536..2d9c014f0 100644 --- a/win32/grp.h +++ b/win32/grp.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: grp.h,v 1.7.2.1.2.1.2.2 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: grp.h 272370 2008-12-31 11:15:49Z sebastian $ */ struct group { char *gr_name; diff --git a/win32/install.txt b/win32/install.txt index d77e4f186..c1fc9c20a 100644 --- a/win32/install.txt +++ b/win32/install.txt @@ -742,7 +742,7 @@ Apache 2.0.x on Microsoft Windows http://snaps.php.net/php5-latest.tar.gz or download binaries for Windows http://snaps.php.net/win32/php5-win32-latest.zip. * a prerelease version downloadable from http://qa.php.net/. - * you have always the option to obtain PHP through anonymous CVS. + * you have always the option to obtain PHP through SVN. These versions of PHP are compatible to Apache 2.0.40 and later. @@ -1211,8 +1211,8 @@ Introduction to PECL Installations When building PHP modules, it's important to have known-good versions of the required tools (autoconf, automake, libtool, etc.) See the - Anonymous CVS Instructions for details on the required tools, and - required versions. + SVN Instructions for details on the required tools, and required + versions. __________________________________________________________________ Downloading PECL extensions @@ -1228,14 +1228,12 @@ Downloading PECL extensions PECL extensions that have releases listed on the PECL web site are available for download and installation using the pecl command. Specific revisions may also be specified. - * CVS - Most PECL extensions also reside in CVS. A web-based view may be - seen at http://cvs.php.net/pecl/. To download straight from CVS, - the following sequence of commands may be used. Note that phpfi is - the password for user cvsread: + * SVN + Most PECL extensions also reside in SVN. A web-based view may be + seen at http://svn.php.net/pecl/. To download straight from SVN, + the following sequence of commands may be used. -$ cvs -d:pserver:cvsread@cvs.php.net:/repository login -$ cvs -d:pserver:cvsread@cvs.php.net:/repository co pecl/extname +$ svn co http://svn.php.net/repository/pecl//trunk * Windows downloads Windows users may find compiled PECL binaries by downloading the @@ -1283,7 +1281,7 @@ Compiling shared PECL extensions with phpize Sometimes, using the pecl installer is not an option. This could be because you're behind a firewall, or it could be because the extension you want to install is not available as a PECL compatible package, such - as unreleased extensions from CVS. If you need to build such an + as unreleased extensions from SVN. If you need to build such an extension, you can use the lower-level build tools to perform the build manually. @@ -1430,7 +1428,7 @@ The configuration file directives are documented in the manual though. For a complete list of directives available in your PHP version, please read your well commented php.ini file. Alternatively, you may find the the latest - php.ini from CVS helpful too. + php.ini from SVN helpful too. Example 5-1. php.ini example ; any text on a line after an unquoted semicolon (;) is ignored diff --git a/win32/php5.dsw b/win32/php5.dsw index 2e7d26672..d6efc98ee 100644 --- a/win32/php5.dsw +++ b/win32/php5.dsw @@ -1,107 +1,107 @@ -Microsoft Developer Studio Workspace File, Format Version 6.00 -# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! - -############################################################################### - -Project: "TSRM"=..\TSRM\TSRM.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ -}}} - -############################################################################### - -Project: "Zend"=..\Zend\Zend.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name TSRM - End Project Dependency -}}} - -############################################################################### - -Project: "fastcgi"=..\sapi\fastcgi\fastcgi.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name php5dll - End Project Dependency - Begin Project Dependency - Project_Dep_Name TSRM - End Project Dependency - Begin Project Dependency - Project_Dep_Name Zend - End Project Dependency -}}} - -############################################################################### - -Project: "php5"=.\php5.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name php5dll - End Project Dependency - Begin Project Dependency - Project_Dep_Name Zend - End Project Dependency - Begin Project Dependency - Project_Dep_Name TSRM - End Project Dependency -}}} - -############################################################################### - -Project: "php5dll"=.\php5dll.dsp - Package Owner=<4> - -Package=<5> -{{{ -}}} - -Package=<4> -{{{ - Begin Project Dependency - Project_Dep_Name Zend - End Project Dependency - Begin Project Dependency - Project_Dep_Name libmysql - End Project Dependency - Begin Project Dependency - Project_Dep_Name TSRM - End Project Dependency -}}} - -############################################################################### - -Global: - -Package=<5> -{{{ -}}} - -Package=<3> -{{{ -}}} - -############################################################################### - +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "TSRM"=..\TSRM\TSRM.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Project: "Zend"=..\Zend\Zend.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name TSRM + End Project Dependency +}}} + +############################################################################### + +Project: "fastcgi"=..\sapi\fastcgi\fastcgi.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name php5dll + End Project Dependency + Begin Project Dependency + Project_Dep_Name TSRM + End Project Dependency + Begin Project Dependency + Project_Dep_Name Zend + End Project Dependency +}}} + +############################################################################### + +Project: "php5"=.\php5.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name php5dll + End Project Dependency + Begin Project Dependency + Project_Dep_Name Zend + End Project Dependency + Begin Project Dependency + Project_Dep_Name TSRM + End Project Dependency +}}} + +############################################################################### + +Project: "php5dll"=.\php5dll.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name Zend + End Project Dependency + Begin Project Dependency + Project_Dep_Name libmysql + End Project Dependency + Begin Project Dependency + Project_Dep_Name TSRM + End Project Dependency +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/win32/php5dll.dsp b/win32/php5dll.dsp index b0a26bcfc..b0fad66c2 100644 --- a/win32/php5dll.dsp +++ b/win32/php5dll.dsp @@ -567,10 +567,6 @@ SOURCE=..\ext\standard\url.c # End Source File # Begin Source File -SOURCE=..\ext\standard\url_scanner.c -# End Source File -# Begin Source File - SOURCE=..\ext\standard\url_scanner_ex.c # ADD CPP /W2 # End Source File @@ -729,10 +725,6 @@ SOURCE=..\ext\standard\url.h # End Source File # Begin Source File -SOURCE=..\ext\standard\url_scanner.h -# End Source File -# Begin Source File - SOURCE=..\ext\standard\url_scanner_ex.h # End Source File # End Group diff --git a/win32/php5dllts.dsp b/win32/php5dllts.dsp index 0faddf954..250d450e3 100644 --- a/win32/php5dllts.dsp +++ b/win32/php5dllts.dsp @@ -2001,10 +2001,6 @@ SOURCE=..\ext\standard\url.c # End Source File # Begin Source File -SOURCE=..\ext\standard\url_scanner.c -# End Source File -# Begin Source File - SOURCE=..\ext\standard\url_scanner_ex.c # ADD CPP /W2 # End Source File @@ -2199,10 +2195,6 @@ SOURCE=..\ext\standard\url.h # End Source File # Begin Source File -SOURCE=..\ext\standard\url_scanner.h -# End Source File -# Begin Source File - SOURCE=..\ext\standard\url_scanner_ex.h # End Source File # End Group diff --git a/win32/php5dllts.rc2 b/win32/php5dllts.rc2 index af098b089..b05f0af0d 100644 --- a/win32/php5dllts.rc2 +++ b/win32/php5dllts.rc2 @@ -1,61 +1,61 @@ -// -// php5dllts.RC2 - resources Microsoft Visual C++ does not edit directly -// - -#ifdef APSTUDIO_INVOKED - #error this file is not editable by Microsoft Visual C++ -#endif //APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// Add manually edited resources here... -#include "../main/php_version.h" - -#define XSTRVER4(maj, min, rel, build) #maj "." #min "." #rel "." #build -#define XSTRVER3(maj, min, rel) #maj "." #min "." #rel -#define STRVER4(maj, min, rel, build) XSTRVER4(maj, min, rel, build) -#define STRVER3(maj, min, rel) XSTRVER3(maj, min, rel) - -#ifndef _MAC -//Version -VS_VERSION_INFO VERSIONINFO - FILEVERSION PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,PHP_RELEASE_VERSION - PRODUCTVERSION PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_DLL - FILESUBTYPE VFT2_UNKNOWN -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "The PHP Group\0" - VALUE "FileDescription", "PHP Script Interpreter\0" - VALUE "FileVersion", STRVER4(PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION, PHP_RELEASE_VERSION) - VALUE "InternalName", "php\0" - VALUE "LegalCopyright", "Copyright 1997-2007 The PHP Group\0" - VALUE "LegalTrademarks", "php\0" - VALUE "OriginalFilename", "php5ts.dll\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "PHP Thread Safe\0" - VALUE "ProductVersion", STRVER3(PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION) - VALUE "SpecialBuild", PHP_EXTRA_VERSION "\0" - VALUE "URL", "http://www.php.net" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // !_MAC - -///////////////////////////////////////////////////////////////////////////// +// +// php5dllts.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... +#include "../main/php_version.h" + +#define XSTRVER4(maj, min, rel, build) #maj "." #min "." #rel "." #build +#define XSTRVER3(maj, min, rel) #maj "." #min "." #rel +#define STRVER4(maj, min, rel, build) XSTRVER4(maj, min, rel, build) +#define STRVER3(maj, min, rel) XSTRVER3(maj, min, rel) + +#ifndef _MAC +//Version +VS_VERSION_INFO VERSIONINFO + FILEVERSION PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,PHP_RELEASE_VERSION + PRODUCTVERSION PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_DLL + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "The PHP Group\0" + VALUE "FileDescription", "PHP Script Interpreter\0" + VALUE "FileVersion", STRVER4(PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION, PHP_RELEASE_VERSION) + VALUE "InternalName", "php\0" + VALUE "LegalCopyright", "Copyright 1997-2007 The PHP Group\0" + VALUE "LegalTrademarks", "php\0" + VALUE "OriginalFilename", "php5ts.dll\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "PHP Thread Safe\0" + VALUE "ProductVersion", STRVER3(PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION) + VALUE "SpecialBuild", PHP_EXTRA_VERSION "\0" + VALUE "URL", "http://www.php.net" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +///////////////////////////////////////////////////////////////////////////// diff --git a/win32/php5ts_cli.rc2 b/win32/php5ts_cli.rc2 index 130759ab6..517bd4ab3 100644 --- a/win32/php5ts_cli.rc2 +++ b/win32/php5ts_cli.rc2 @@ -1,61 +1,61 @@ -// -// php5dllts.RC2 - resources Microsoft Visual C++ does not edit directly -// - -#ifdef APSTUDIO_INVOKED - #error this file is not editable by Microsoft Visual C++ -#endif //APSTUDIO_INVOKED - - -///////////////////////////////////////////////////////////////////////////// -// Add manually edited resources here... -#include "../main/php_version.h" - -#define XSTRVER4(maj, min, rel, build) #maj "." #min "." #rel "." #build -#define XSTRVER3(maj, min, rel) #maj "." #min "." #rel -#define STRVER4(maj, min, rel, build) XSTRVER4(maj, min, rel, build) -#define STRVER3(maj, min, rel) XSTRVER3(maj, min, rel) - -#ifndef _MAC -//Version -VS_VERSION_INFO VERSIONINFO - FILEVERSION PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,PHP_RELEASE_VERSION - PRODUCTVERSION PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,0 - FILEFLAGSMASK 0x3fL -#ifdef _DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0x0L -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_APP - FILESUBTYPE VFT2_UNKNOWN -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "040904b0" - BEGIN - VALUE "Comments", "\0" - VALUE "CompanyName", "The PHP Group\0" - VALUE "FileDescription", "PHP Script Interpreter\0" - VALUE "FileVersion", STRVER4(PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION, PHP_RELEASE_VERSION) - VALUE "InternalName", "php-cli\0" - VALUE "LegalCopyright", "Copyright 1997-2006 The PHP Group\0" - VALUE "LegalTrademarks", "php\0" - VALUE "OriginalFilename", "php.exe\0" - VALUE "PrivateBuild", "\0" - VALUE "ProductName", "PHP Thread Safe Command Line Interface\0" - VALUE "ProductVersion", STRVER3(PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION) - VALUE "SpecialBuild", PHP_EXTRA_VERSION "\0" - VALUE "URL", "http://www.php.net" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x409, 1200 - END -END - -#endif // !_MAC - -///////////////////////////////////////////////////////////////////////////// +// +// php5dllts.RC2 - resources Microsoft Visual C++ does not edit directly +// + +#ifdef APSTUDIO_INVOKED + #error this file is not editable by Microsoft Visual C++ +#endif //APSTUDIO_INVOKED + + +///////////////////////////////////////////////////////////////////////////// +// Add manually edited resources here... +#include "../main/php_version.h" + +#define XSTRVER4(maj, min, rel, build) #maj "." #min "." #rel "." #build +#define XSTRVER3(maj, min, rel) #maj "." #min "." #rel +#define STRVER4(maj, min, rel, build) XSTRVER4(maj, min, rel, build) +#define STRVER3(maj, min, rel) XSTRVER3(maj, min, rel) + +#ifndef _MAC +//Version +VS_VERSION_INFO VERSIONINFO + FILEVERSION PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,PHP_RELEASE_VERSION + PRODUCTVERSION PHP_MAJOR_VERSION,PHP_MINOR_VERSION,PHP_RELEASE_VERSION,0 + FILEFLAGSMASK 0x3fL +#ifdef _DEBUG + FILEFLAGS VS_FF_DEBUG +#else + FILEFLAGS 0x0L +#endif + FILEOS VOS__WINDOWS32 + FILETYPE VFT_APP + FILESUBTYPE VFT2_UNKNOWN +BEGIN + BLOCK "StringFileInfo" + BEGIN + BLOCK "040904b0" + BEGIN + VALUE "Comments", "\0" + VALUE "CompanyName", "The PHP Group\0" + VALUE "FileDescription", "PHP Script Interpreter\0" + VALUE "FileVersion", STRVER4(PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION, PHP_RELEASE_VERSION) + VALUE "InternalName", "php-cli\0" + VALUE "LegalCopyright", "Copyright 1997-2006 The PHP Group\0" + VALUE "LegalTrademarks", "php\0" + VALUE "OriginalFilename", "php.exe\0" + VALUE "PrivateBuild", "\0" + VALUE "ProductName", "PHP Thread Safe Command Line Interface\0" + VALUE "ProductVersion", STRVER3(PHP_MAJOR_VERSION, PHP_MINOR_VERSION, PHP_RELEASE_VERSION) + VALUE "SpecialBuild", PHP_EXTRA_VERSION "\0" + VALUE "URL", "http://www.php.net" + END + END + BLOCK "VarFileInfo" + BEGIN + VALUE "Translation", 0x409, 1200 + END +END + +#endif // !_MAC + +///////////////////////////////////////////////////////////////////////////// diff --git a/win32/php_win32_globals.h b/win32/php_win32_globals.h index a7cb068f5..9d0d653b1 100755 --- a/win32/php_win32_globals.h +++ b/win32/php_win32_globals.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: php_win32_globals.h,v 1.4.2.1.2.3.2.2 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: php_win32_globals.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef PHP_WIN32_GLOBALS_H #define PHP_WIN32_GLOBALS_H diff --git a/win32/readdir.c b/win32/readdir.c index 67bb8ee73..52ebe2fd0 100644 --- a/win32/readdir.c +++ b/win32/readdir.c @@ -4,7 +4,7 @@ #include "php.h" #include "readdir.h" - +#include "TSRM.h" /********************************************************************** * Implement dirent-style opendir/readdir/rewinddir/closedir on Win32 * @@ -25,14 +25,20 @@ DIR *opendir(const char *dir) char *filespec; HANDLE handle; int index; + char resolved_path_buff[MAXPATHLEN]; + TSRMLS_FETCH(); + + if (!VCWD_REALPATH(dir, resolved_path_buff)) { + return NULL; + } - filespec = (char *)malloc(strlen(dir) + 2 + 1); - strcpy(filespec, dir); + filespec = (char *)malloc(strlen(resolved_path_buff) + 2 + 1); + strcpy(filespec, resolved_path_buff); index = strlen(filespec) - 1; if (index >= 0 && (filespec[index] == '/' || (filespec[index] == '\\' && (index == 0 || !IsDBCSLeadByte(filespec[index-1]))))) filespec[index] = '\0'; - strcat(filespec, "/*"); + strcat(filespec, "\\*"); dp = (DIR *) malloc(sizeof(DIR)); dp->offset = 0; @@ -40,7 +46,7 @@ DIR *opendir(const char *dir) if ((handle = FindFirstFile(filespec, &(dp->fileinfo))) == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); - if (err == ERROR_NO_MORE_FILES) { + if (err == ERROR_NO_MORE_FILES || err == ERROR_FILE_NOT_FOUND) { dp->finished = 1; } else { free(dp); @@ -48,7 +54,7 @@ DIR *opendir(const char *dir) return NULL; } } - dp->dir = strdup(dir); + dp->dir = strdup(resolved_path_buff); dp->handle = handle; free(filespec); @@ -108,7 +114,11 @@ int closedir(DIR *dp) { if (!dp) return 0; - FindClose(dp->handle); + /* It is valid to scan an empty directory but we have an invalid + handle in this case (no first file found). */ + if (dp->handle != INVALID_HANDLE_VALUE) { + FindClose(dp->handle); + } if (dp->dir) free(dp->dir); if (dp) diff --git a/win32/registry.c b/win32/registry.c index d5f84af59..77089ba6a 100644 --- a/win32/registry.c +++ b/win32/registry.c @@ -168,6 +168,10 @@ void UpdateIniFromRegistry(char *path TSRMLS_DC) int path_len; HashTable **pht; + if(!path) { + return; + } + if (!PW32G(registry_directories)) { PW32G(registry_directories) = (HashTable*)malloc(sizeof(HashTable)); zend_hash_init(PW32G(registry_directories), 0, NULL, delete_internal_hashtable, 1); diff --git a/win32/resource.h b/win32/resource.h index 0c58f6908..3e7e4c0ed 100644 --- a/win32/resource.h +++ b/win32/resource.h @@ -1,15 +1,15 @@ -//{{NO_DEPENDENCIES}} -// Microsoft Developer Studio generated include file. -// Used by php5dllts.rc -// - -// Next default values for new objects -// -#ifdef APSTUDIO_INVOKED -#ifndef APSTUDIO_READONLY_SYMBOLS -#define _APS_NEXT_RESOURCE_VALUE 101 -#define _APS_NEXT_COMMAND_VALUE 40001 -#define _APS_NEXT_CONTROL_VALUE 1000 -#define _APS_NEXT_SYMED_VALUE 101 -#endif -#endif +//{{NO_DEPENDENCIES}} +// Microsoft Developer Studio generated include file. +// Used by php5dllts.rc +// + +// Next default values for new objects +// +#ifdef APSTUDIO_INVOKED +#ifndef APSTUDIO_READONLY_SYMBOLS +#define _APS_NEXT_RESOURCE_VALUE 101 +#define _APS_NEXT_COMMAND_VALUE 40001 +#define _APS_NEXT_CONTROL_VALUE 1000 +#define _APS_NEXT_SYMED_VALUE 101 +#endif +#endif diff --git a/win32/select.c b/win32/select.c index 073e1b0ce..26f729462 100644 --- a/win32/select.c +++ b/win32/select.c @@ -21,7 +21,7 @@ #ifdef PHP_WIN32 -/* $Id: select.c,v 1.10.2.2.2.2.2.2 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: select.c 272370 2008-12-31 11:15:49Z sebastian $ */ /* Win32 select() will only work with sockets, so we roll our own implementation here. * - If you supply only sockets, this simply passes through to winsock select(). diff --git a/win32/select.h b/win32/select.h index b6d632d1a..7670f57ea 100644 --- a/win32/select.h +++ b/win32/select.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: select.h,v 1.4.2.1.2.1.2.2 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: select.h 272370 2008-12-31 11:15:49Z sebastian $ */ PHPAPI int php_select(int max_fd, fd_set *rfds, fd_set *wfds, fd_set *efds, struct timeval *tv); diff --git a/win32/sendmail.c b/win32/sendmail.c index 4109d57cf..13d425d17 100644 --- a/win32/sendmail.c +++ b/win32/sendmail.c @@ -17,7 +17,7 @@ * */ -/* $Id: sendmail.c,v 1.65.2.2.2.1 2007/02/24 02:17:28 helly Exp $ */ +/* $Id: sendmail.c 287783 2009-08-26 21:59:54Z pajoye $ */ #include "php.h" /*php specific */ #include @@ -37,6 +37,7 @@ #endif /* NETWARE */ #include "sendmail.h" #include "php_ini.h" +#include "inet.h" #if HAVE_PCRE || HAVE_BUNDLED_PCRE #include "ext/pcre/php_pcre.h" @@ -421,7 +422,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char } SMTP_SKIP_SPACE(RPath); - snprintf(Buffer, MAIL_BUFFER_SIZE, "MAIL FROM:<%s>\r\n", RPath); + FormatEmailAddress(Buffer, RPath, "MAIL FROM:<%s>\r\n"); if ((res = Post(Buffer)) != SUCCESS) { return (res); } @@ -436,7 +437,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char while (token != NULL) { SMTP_SKIP_SPACE(token); - snprintf(Buffer, MAIL_BUFFER_SIZE, "RCPT TO:<%s>\r\n", token); + FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n"); if ((res = Post(Buffer)) != SUCCESS) { efree(tempMailTo); return (res); @@ -457,7 +458,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char while (token != NULL) { SMTP_SKIP_SPACE(token); - snprintf(Buffer, MAIL_BUFFER_SIZE, "RCPT TO:<%s>\r\n", token); + FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n"); if ((res = Post(Buffer)) != SUCCESS) { efree(tempMailTo); return (res); @@ -487,7 +488,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char while (token != NULL) { SMTP_SKIP_SPACE(token); - snprintf(Buffer, MAIL_BUFFER_SIZE, "RCPT TO:<%s>\r\n", token); + FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n"); if ((res = Post(Buffer)) != SUCCESS) { efree(tempMailTo); return (res); @@ -512,7 +513,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char while (token != NULL) { SMTP_SKIP_SPACE(token); - snprintf(Buffer, MAIL_BUFFER_SIZE, "RCPT TO:<%s>\r\n", token); + FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n"); if ((res = Post(Buffer)) != SUCCESS) { efree(tempMailTo); return (res); @@ -545,7 +546,7 @@ static int SendText(char *RPath, char *Subject, char *mailTo, char *mailCc, char while (token != NULL) { SMTP_SKIP_SPACE(token); - snprintf(Buffer, MAIL_BUFFER_SIZE, "RCPT TO:<%s>\r\n", token); + FormatEmailAddress(Buffer, token, "RCPT TO:<%s>\r\n"); if ((res = Post(Buffer)) != SUCCESS) { efree(tempMailTo); return (res); @@ -765,16 +766,52 @@ PostHeader_outofmem: static int MailConnect() { - int res; + int res, namelen; short portnum; + struct hostent *ent; + IN_ADDR addr; +#ifdef HAVE_IPV6 + IN6_ADDR addr6; +#endif /* Create Socket */ - if ((sc = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) + if ((sc = socket(PF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) { return (FAILED_TO_OBTAIN_SOCKET_HANDLE); + } /* Get our own host name */ - if (gethostname(LocalHost, HOST_NAME_LEN)) + if (gethostname(LocalHost, HOST_NAME_LEN)) { + return (FAILED_TO_GET_HOSTNAME); + } + + ent = gethostbyname(LocalHost); + + if (!ent) { return (FAILED_TO_GET_HOSTNAME); + } + + namelen = strlen(ent->h_name); + +#ifdef HAVE_IPV6 + if (inet_pton(AF_INET, ent->h_name, &addr) == 1 || inet_pton(AF_INET6, ent->h_name, &addr6) == 1) +#else + if (inet_pton(AF_INET, ent->h_name, &addr) == 1) +#endif + { + if (namelen + 2 >= HOST_NAME_LEN) { + return (FAILED_TO_GET_HOSTNAME); + } + + strcpy(LocalHost, "["); + strcpy(LocalHost + 1, ent->h_name); + strcpy(LocalHost + namelen + 1, "]"); + } else { + if (namelen >= HOST_NAME_LEN) { + return (FAILED_TO_GET_HOSTNAME); + } + + strcpy(LocalHost, ent->h_name); + } /* Resolve the servers IP */ /* @@ -794,8 +831,9 @@ static int MailConnect() sock_in.sin_port = htons(portnum); sock_in.sin_addr.S_un.S_addr = GetAddr(MailHost); - if (connect(sc, (LPSOCKADDR) & sock_in, sizeof(sock_in))) + if (connect(sc, (LPSOCKADDR) & sock_in, sizeof(sock_in))) { return (FAILED_TO_CONNECT); + } /* receive Server welcome message */ res = Ack(NULL); @@ -922,3 +960,30 @@ static unsigned long GetAddr(LPSTR szHost) } return (lAddr); } /* end GetAddr() */ + + +/********************************************************************* +// Name: int FormatEmailAddress +// Input: +// Output: +// Description: Formats the email address to remove any content ouside +// of the angle brackets < > as per RFC 2821. +// +// Returns the invalidly formatted mail address if the < > are +// unbalanced (the SMTP server should reject it if it's out of spec.) +// +// Author/Date: garretts 08/18/2009 +// History: +//********************************************************************/ +static int FormatEmailAddress(char* Buf, char* EmailAddress, char* FormatString) { + char *tmpAddress1, *tmpAddress2; + int result; + + if( (tmpAddress1 = strchr(EmailAddress, '<')) && (tmpAddress2 = strchr(tmpAddress1, '>')) ) { + *tmpAddress2 = 0; // terminate the string temporarily. + result = snprintf(Buf, MAIL_BUFFER_SIZE, FormatString , tmpAddress1+1); + *tmpAddress2 = '>'; // put it back the way it was. + return result; + } + return snprintf(Buf, MAIL_BUFFER_SIZE , FormatString , EmailAddress ); +} /* end FormatEmailAddress() */ diff --git a/win32/sendmail.h b/win32/sendmail.h index 0ec916d6c..0a7698e2f 100644 --- a/win32/sendmail.h +++ b/win32/sendmail.h @@ -47,4 +47,5 @@ static int PostHeader(char *RPath, char *Subject, char *mailTo, char *xheaders T static int Post(LPCSTR msg); static int Ack(char **server_response); static unsigned long GetAddr(LPSTR szHost); +static int FormatEmailAddress(char* Buf, char* EmailAddress, char* FormatString); #endif /* sendmail_h */ diff --git a/win32/sockets.c b/win32/sockets.c index 003f25baf..4b3d274e0 100644 --- a/win32/sockets.c +++ b/win32/sockets.c @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sockets.c,v 1.1.2.2 2009/01/23 15:49:49 kalle Exp $ */ +/* $Id: sockets.c 274392 2009-01-23 15:49:49Z kalle $ */ /* Code originally from ext/sockets */ diff --git a/win32/sockets.h b/win32/sockets.h index 8614614f3..633137dd9 100644 --- a/win32/sockets.h +++ b/win32/sockets.h @@ -19,7 +19,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: sockets.h,v 1.1.2.2 2009/01/23 15:49:49 kalle Exp $ */ +/* $Id: sockets.h 274392 2009-01-23 15:49:49Z kalle $ */ /* Code originally from ext/sockets */ diff --git a/win32/syslog.h b/win32/syslog.h index 05ef02f41..1270a9524 100644 --- a/win32/syslog.h +++ b/win32/syslog.h @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: syslog.h,v 1.10.2.1.2.1.2.2 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: syslog.h 272370 2008-12-31 11:15:49Z sebastian $ */ #ifndef SYSLOG_H #define SYSLOG_H diff --git a/win32/time.c b/win32/time.c index b89064e03..cfd4394d1 100644 --- a/win32/time.c +++ b/win32/time.c @@ -11,7 +11,7 @@ * *****************************************************************************/ -/* $Id: time.c,v 1.10.6.3 2009/01/19 02:35:21 pajoye Exp $ */ +/* $Id: time.c 273823 2009-01-19 02:35:22Z pajoye $ */ /** * diff --git a/win32/winutil.c b/win32/winutil.c index ee1e700ce..244ecff3d 100644 --- a/win32/winutil.c +++ b/win32/winutil.c @@ -16,7 +16,7 @@ +----------------------------------------------------------------------+ */ -/* $Id: winutil.c,v 1.16.2.1.2.1.2.2 2008/12/31 11:15:49 sebastian Exp $ */ +/* $Id: winutil.c 272370 2008-12-31 11:15:49Z sebastian $ */ #include "php.h" -- cgit v1.2.3
    Pi3Web Server Information